aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-10-15 11:20:54 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-10-15 11:20:54 -0400
commitdf9b42963f2d010ae3163a894ce22cf6b27cd344 (patch)
treef42f826d9bb975766c1a79986c39e64c9a900908 /sound
parent33766368f6532313571534f9112b1796d6651bbe (diff)
parentc3e7724b6bc2f25e46c38dbe68f09d71fafeafb8 (diff)
Merge remote-tracking branch 'wireless/master' into mac80211
Diffstat (limited to 'sound')
-rw-r--r--sound/arm/pxa2xx-ac97.c13
-rw-r--r--sound/atmel/abdac.c21
-rw-r--r--sound/atmel/ac97c.c32
-rw-r--r--sound/core/compress_offload.c8
-rw-r--r--sound/core/misc.c13
-rw-r--r--sound/core/pcm_lib.c4
-rw-r--r--sound/core/pcm_misc.c18
-rw-r--r--sound/core/sgbuf.c2
-rw-r--r--sound/drivers/aloop.c24
-rw-r--r--sound/drivers/dummy.c23
-rw-r--r--sound/drivers/mpu401/mpu401.c3
-rw-r--r--sound/drivers/mpu401/mpu401_uart.c1
-rw-r--r--sound/drivers/mtpav.c3
-rw-r--r--sound/drivers/mts64.c3
-rw-r--r--sound/drivers/pcsp/pcsp.c15
-rw-r--r--sound/drivers/portman2x4.c3
-rw-r--r--sound/drivers/serial-u16550.c3
-rw-r--r--sound/drivers/virmidi.c3
-rw-r--r--sound/drivers/vx/vx_core.c2
-rw-r--r--sound/i2c/other/ak4113.c2
-rw-r--r--sound/i2c/other/ak4114.c2
-rw-r--r--sound/i2c/other/tea575x-tuner.c45
-rw-r--r--sound/isa/als100.c2
-rw-r--r--sound/isa/es1688/es1688_lib.c34
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c86
-rw-r--r--sound/isa/wss/wss_lib.c5
-rw-r--r--sound/oss/.gitignore1
-rw-r--r--sound/oss/sb_audio.c4
-rw-r--r--sound/oss/swarm_cs4297a.c17
-rw-r--r--sound/oss/vwsnd.c2
-rw-r--r--sound/pci/ali5451/ali5451.c24
-rw-r--r--sound/pci/als300.c24
-rw-r--r--sound/pci/als4000.c25
-rw-r--r--sound/pci/atiixp.c24
-rw-r--r--sound/pci/atiixp_modem.c25
-rw-r--r--sound/pci/au88x0/au88x0_mixer.c11
-rw-r--r--sound/pci/azt3328.c25
-rw-r--r--sound/pci/ca0106/ca0106_main.c24
-rw-r--r--sound/pci/cmipci.c24
-rw-r--r--sound/pci/cs4281.c24
-rw-r--r--sound/pci/cs46xx/cs46xx.c7
-rw-r--r--sound/pci/cs46xx/cs46xx.h1744
-rw-r--r--sound/pci/cs46xx/cs46xx_dsp_scb_types.h1213
-rw-r--r--sound/pci/cs46xx/cs46xx_dsp_spos.h234
-rw-r--r--sound/pci/cs46xx/cs46xx_dsp_task_types.h252
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c18
-rw-r--r--sound/pci/cs46xx/dsp_spos.c2
-rw-r--r--sound/pci/cs46xx/dsp_spos_scb_lib.c2
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c5
-rw-r--r--sound/pci/cs5535audio/cs5535audio.h5
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pm.c13
-rw-r--r--sound/pci/ctxfi/ctatc.c8
-rw-r--r--sound/pci/ctxfi/ctatc.h2
-rw-r--r--sound/pci/ctxfi/cthardware.h2
-rw-r--r--sound/pci/ctxfi/cthw20k1.c4
-rw-r--r--sound/pci/ctxfi/cthw20k2.c4
-rw-r--r--sound/pci/ctxfi/xfi.c22
-rw-r--r--sound/pci/echoaudio/echoaudio.c22
-rw-r--r--sound/pci/emu10k1/emu10k1.c26
-rw-r--r--sound/pci/emu10k1/memory.c5
-rw-r--r--sound/pci/ens1370.c25
-rw-r--r--sound/pci/es1938.c49
-rw-r--r--sound/pci/es1968.c24
-rw-r--r--sound/pci/fm801.c26
-rw-r--r--sound/pci/hda/Kconfig7
-rw-r--r--sound/pci/hda/hda_auto_parser.c9
-rw-r--r--sound/pci/hda/hda_beep.c99
-rw-r--r--sound/pci/hda/hda_beep.h5
-rw-r--r--sound/pci/hda/hda_codec.c147
-rw-r--r--sound/pci/hda/hda_codec.h7
-rw-r--r--sound/pci/hda/hda_intel.c66
-rw-r--r--sound/pci/hda/hda_jack.c102
-rw-r--r--sound/pci/hda/hda_jack.h1
-rw-r--r--sound/pci/hda/hda_local.h4
-rw-r--r--sound/pci/hda/hda_proc.c19
-rw-r--r--sound/pci/hda/patch_analog.c2
-rw-r--r--sound/pci/hda/patch_ca0132.c174
-rw-r--r--sound/pci/hda/patch_cirrus.c2
-rw-r--r--sound/pci/hda/patch_conexant.c8
-rw-r--r--sound/pci/hda/patch_hdmi.c322
-rw-r--r--sound/pci/hda/patch_realtek.c343
-rw-r--r--sound/pci/hda/patch_sigmatel.c39
-rw-r--r--sound/pci/hda/patch_via.c17
-rw-r--r--sound/pci/ice1712/ice1724.c26
-rw-r--r--sound/pci/ice1712/prodigy_hifi.c3
-rw-r--r--sound/pci/intel8x0.c24
-rw-r--r--sound/pci/intel8x0m.c24
-rw-r--r--sound/pci/lx6464es/lx6464es.c2
-rw-r--r--sound/pci/maestro3.c92
-rw-r--r--sound/pci/nm256/nm256.c24
-rw-r--r--sound/pci/oxygen/oxygen.c5
-rw-r--r--sound/pci/oxygen/oxygen.h3
-rw-r--r--sound/pci/oxygen/oxygen_lib.c25
-rw-r--r--sound/pci/oxygen/virtuoso.c5
-rw-r--r--sound/pci/pcxhr/pcxhr.c63
-rw-r--r--sound/pci/pcxhr/pcxhr.h1
-rw-r--r--sound/pci/pcxhr/pcxhr_core.c27
-rw-r--r--sound/pci/pcxhr/pcxhr_core.h4
-rw-r--r--sound/pci/pcxhr/pcxhr_mix22.c11
-rw-r--r--sound/pci/pcxhr/pcxhr_mix22.h1
-rw-r--r--sound/pci/riptide/riptide.c26
-rw-r--r--sound/pci/rme9652/hdspm.c2
-rw-r--r--sound/pci/sis7019.c30
-rw-r--r--sound/pci/trident/trident.c7
-rw-r--r--sound/pci/trident/trident.h444
-rw-r--r--sound/pci/trident/trident_main.c16
-rw-r--r--sound/pci/trident/trident_memory.c2
-rw-r--r--sound/pci/via82xx.c24
-rw-r--r--sound/pci/via82xx_modem.c24
-rw-r--r--sound/pci/vx222/vx222.c26
-rw-r--r--sound/pci/ymfpci/ymfpci.c7
-rw-r--r--sound/pci/ymfpci/ymfpci.h389
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c16
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.h2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_core.c2
-rw-r--r--sound/pcmcia/vx/vxpocket.c2
-rw-r--r--sound/ppc/powermac.c23
-rw-r--r--sound/ppc/snd_ps3.c1
-rw-r--r--sound/sh/aica.c4
-rw-r--r--sound/sh/sh_dac_audio.c1
-rw-r--r--sound/soc/Kconfig1
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/blackfin/Kconfig21
-rw-r--r--sound/soc/blackfin/Makefile4
-rw-r--r--sound/soc/blackfin/bf6xx-i2s.c234
-rw-r--r--sound/soc/blackfin/bf6xx-sport.c429
-rw-r--r--sound/soc/blackfin/bf6xx-sport.h82
-rw-r--r--sound/soc/codecs/Kconfig31
-rw-r--r--sound/soc/codecs/Makefile19
-rw-r--r--sound/soc/codecs/ab8500-codec.c2607
-rw-r--r--sound/soc/codecs/ab8500-codec.h590
-rw-r--r--sound/soc/codecs/ac97.c6
-rw-r--r--sound/soc/codecs/ad1980.c1
-rw-r--r--sound/soc/codecs/arizona.c937
-rw-r--r--sound/soc/codecs/arizona.h159
-rw-r--r--sound/soc/codecs/cs42l52.c19
-rw-r--r--sound/soc/codecs/cs42l73.c20
-rw-r--r--sound/soc/codecs/da732x.c1627
-rw-r--r--sound/soc/codecs/da732x.h133
-rw-r--r--sound/soc/codecs/da732x_reg.h654
-rw-r--r--sound/soc/codecs/isabelle.c1176
-rw-r--r--sound/soc/codecs/isabelle.h143
-rw-r--r--sound/soc/codecs/lm49453.c3
-rw-r--r--sound/soc/codecs/max98095.c5
-rw-r--r--sound/soc/codecs/mc13783.c10
-rw-r--r--sound/soc/codecs/ml26124.c5
-rw-r--r--sound/soc/codecs/sgtl5000.c3
-rw-r--r--sound/soc/codecs/spdif_receiver.c67
-rw-r--r--sound/soc/codecs/sta529.c442
-rw-r--r--sound/soc/codecs/stac9766.c1
-rw-r--r--sound/soc/codecs/tlv320aic3x.c40
-rw-r--r--sound/soc/codecs/tlv320aic3x.h27
-rw-r--r--sound/soc/codecs/twl6040.c4
-rw-r--r--sound/soc/codecs/wm1250-ev1.c7
-rw-r--r--sound/soc/codecs/wm2000.c34
-rw-r--r--sound/soc/codecs/wm5100-tables.c2
-rw-r--r--sound/soc/codecs/wm5100.c11
-rw-r--r--sound/soc/codecs/wm5102.c896
-rw-r--r--sound/soc/codecs/wm5102.h21
-rw-r--r--sound/soc/codecs/wm5110.c962
-rw-r--r--sound/soc/codecs/wm5110.h21
-rw-r--r--sound/soc/codecs/wm8350.c24
-rw-r--r--sound/soc/codecs/wm8400.c2
-rw-r--r--sound/soc/codecs/wm8580.c2
-rw-r--r--sound/soc/codecs/wm8731.c1
-rw-r--r--sound/soc/codecs/wm8741.c2
-rw-r--r--sound/soc/codecs/wm8753.c4
-rw-r--r--sound/soc/codecs/wm8776.c2
-rw-r--r--sound/soc/codecs/wm8804.c2
-rw-r--r--sound/soc/codecs/wm8903.c316
-rw-r--r--sound/soc/codecs/wm8904.c274
-rw-r--r--sound/soc/codecs/wm8960.c2
-rw-r--r--sound/soc/codecs/wm8961.c2
-rw-r--r--sound/soc/codecs/wm8962.c24
-rw-r--r--sound/soc/codecs/wm8993.c2
-rw-r--r--sound/soc/codecs/wm8994.c63
-rw-r--r--sound/soc/codecs/wm8996.c587
-rw-r--r--sound/soc/codecs/wm9081.c2
-rw-r--r--sound/soc/codecs/wm9090.c2
-rw-r--r--sound/soc/codecs/wm9712.c24
-rw-r--r--sound/soc/codecs/wm9713.c3
-rw-r--r--sound/soc/codecs/wm_hubs.c2
-rw-r--r--sound/soc/davinci/davinci-mcasp.c10
-rw-r--r--sound/soc/dwc/Kconfig9
-rw-r--r--sound/soc/dwc/Makefile3
-rw-r--r--sound/soc/dwc/designware_i2s.c455
-rw-r--r--sound/soc/ep93xx/ep93xx-ac97.c2
-rw-r--r--sound/soc/ep93xx/ep93xx-i2s.c2
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c4
-rw-r--r--sound/soc/fsl/imx-audmux.c2
-rw-r--r--sound/soc/fsl/imx-audmux.h1
-rw-r--r--sound/soc/fsl/imx-mc13783.c49
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c4
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c2
-rw-r--r--sound/soc/fsl/imx-sgtl5000.c5
-rw-r--r--sound/soc/fsl/imx-ssi.c7
-rw-r--r--sound/soc/fsl/imx-ssi.h2
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c10
-rw-r--r--sound/soc/kirkwood/kirkwood-openrd.c2
-rw-r--r--sound/soc/kirkwood/kirkwood-t5325.c2
-rw-r--r--sound/soc/mxs/Kconfig2
-rw-r--r--sound/soc/mxs/mxs-pcm.c2
-rw-r--r--sound/soc/mxs/mxs-saif.c24
-rw-r--r--sound/soc/mxs/mxs-sgtl5000.c2
-rw-r--r--sound/soc/omap/am3517evm.c4
-rw-r--r--sound/soc/omap/ams-delta.c4
-rw-r--r--sound/soc/omap/igep0020.c2
-rw-r--r--sound/soc/omap/mcbsp.c6
-rw-r--r--sound/soc/omap/n810.c2
-rw-r--r--sound/soc/omap/omap-abe-twl6040.c4
-rw-r--r--sound/soc/omap/omap-mcbsp.c4
-rw-r--r--sound/soc/omap/omap-mcpdm.c3
-rw-r--r--sound/soc/omap/omap-pcm.c2
-rw-r--r--sound/soc/omap/omap3beagle.c2
-rw-r--r--sound/soc/omap/omap3evm.c2
-rw-r--r--sound/soc/omap/omap3pandora.c2
-rw-r--r--sound/soc/omap/osk5912.c2
-rw-r--r--sound/soc/omap/overo.c2
-rw-r--r--sound/soc/omap/rx51.c2
-rw-r--r--sound/soc/omap/sdp3430.c3
-rw-r--r--sound/soc/omap/zoom2.c2
-rw-r--r--sound/soc/pxa/Kconfig42
-rw-r--r--sound/soc/pxa/Makefile8
-rw-r--r--sound/soc/pxa/brownstone.c174
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c33
-rw-r--r--sound/soc/pxa/mmp-pcm.c297
-rw-r--r--sound/soc/pxa/mmp-sspa.c480
-rw-r--r--sound/soc/pxa/mmp-sspa.h92
-rw-r--r--sound/soc/pxa/palm27x.c2
-rw-r--r--sound/soc/pxa/ttc-dkb.c173
-rw-r--r--sound/soc/samsung/ac97.c2
-rw-r--r--sound/soc/samsung/dma.c8
-rw-r--r--sound/soc/samsung/i2s.c2
-rw-r--r--sound/soc/samsung/littlemill.c7
-rw-r--r--sound/soc/samsung/pcm.c4
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c10
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c10
-rw-r--r--sound/soc/samsung/s3c24xx_simtec.c2
-rw-r--r--sound/soc/samsung/smdk_wm8994.c36
-rw-r--r--sound/soc/samsung/spdif.c2
-rw-r--r--sound/soc/sh/fsi.c52
-rw-r--r--sound/soc/sh/siu_pcm.c12
-rw-r--r--sound/soc/soc-core.c344
-rw-r--r--sound/soc/soc-dapm.c191
-rw-r--r--sound/soc/soc-dmaengine-pcm.c33
-rw-r--r--sound/soc/soc-io.c15
-rw-r--r--sound/soc/soc-jack.c2
-rw-r--r--sound/soc/soc-pcm.c12
-rw-r--r--sound/soc/spear/spdif_in.c297
-rw-r--r--sound/soc/spear/spdif_in_regs.h60
-rw-r--r--sound/soc/spear/spdif_out.c389
-rw-r--r--sound/soc/spear/spdif_out_regs.h79
-rw-r--r--sound/soc/spear/spear_pcm.c214
-rw-r--r--sound/soc/tegra/Kconfig3
-rw-r--r--sound/soc/tegra/tegra20_i2s.c94
-rw-r--r--sound/soc/tegra/tegra20_i2s.h1
-rw-r--r--sound/soc/tegra/tegra20_spdif.c36
-rw-r--r--sound/soc/tegra/tegra20_spdif.h1
-rw-r--r--sound/soc/tegra/tegra30_i2s.c85
-rw-r--r--sound/soc/tegra/tegra30_i2s.h1
-rw-r--r--sound/soc/tegra/tegra_alc5632.c33
-rw-r--r--sound/soc/tegra/tegra_pcm.c209
-rw-r--r--sound/soc/tegra/tegra_pcm.h12
-rw-r--r--sound/soc/tegra/tegra_wm8753.c8
-rw-r--r--sound/soc/tegra/tegra_wm8903.c259
-rw-r--r--sound/soc/tegra/trimslice.c30
-rw-r--r--sound/soc/ux500/Kconfig18
-rw-r--r--sound/soc/ux500/Makefile6
-rw-r--r--sound/soc/ux500/mop500.c150
-rw-r--r--sound/soc/ux500/mop500_ab8500.c431
-rw-r--r--sound/soc/ux500/mop500_ab8500.h22
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c10
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.c118
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.h10
-rw-r--r--sound/soc/ux500/ux500_pcm.c318
-rw-r--r--sound/soc/ux500/ux500_pcm.h35
-rw-r--r--sound/sound_firmware.c8
-rw-r--r--sound/usb/caiaq/device.c2
-rw-r--r--sound/usb/card.c4
-rw-r--r--sound/usb/clock.c3
-rw-r--r--sound/usb/endpoint.c32
-rw-r--r--sound/usb/endpoint.h3
-rw-r--r--sound/usb/mixer_quirks.c159
-rw-r--r--sound/usb/pcm.c67
285 files changed, 22963 insertions, 2836 deletions
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index afef72c4f0d3..4e1fda75c1c9 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -106,9 +106,9 @@ static struct pxa2xx_pcm_client pxa2xx_ac97_pcm_client = {
106 .prepare = pxa2xx_ac97_pcm_prepare, 106 .prepare = pxa2xx_ac97_pcm_prepare,
107}; 107};
108 108
109#ifdef CONFIG_PM 109#ifdef CONFIG_PM_SLEEP
110 110
111static int pxa2xx_ac97_do_suspend(struct snd_card *card, pm_message_t state) 111static int pxa2xx_ac97_do_suspend(struct snd_card *card)
112{ 112{
113 pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data; 113 pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
114 114
@@ -144,7 +144,7 @@ static int pxa2xx_ac97_suspend(struct device *dev)
144 int ret = 0; 144 int ret = 0;
145 145
146 if (card) 146 if (card)
147 ret = pxa2xx_ac97_do_suspend(card, PMSG_SUSPEND); 147 ret = pxa2xx_ac97_do_suspend(card);
148 148
149 return ret; 149 return ret;
150} 150}
@@ -160,10 +160,7 @@ static int pxa2xx_ac97_resume(struct device *dev)
160 return ret; 160 return ret;
161} 161}
162 162
163static const struct dev_pm_ops pxa2xx_ac97_pm_ops = { 163static SIMPLE_DEV_PM_OPS(pxa2xx_ac97_pm_ops, pxa2xx_ac97_suspend, pxa2xx_ac97_resume);
164 .suspend = pxa2xx_ac97_suspend,
165 .resume = pxa2xx_ac97_resume,
166};
167#endif 164#endif
168 165
169static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) 166static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
@@ -246,7 +243,7 @@ static struct platform_driver pxa2xx_ac97_driver = {
246 .driver = { 243 .driver = {
247 .name = "pxa2xx-ac97", 244 .name = "pxa2xx-ac97",
248 .owner = THIS_MODULE, 245 .owner = THIS_MODULE,
249#ifdef CONFIG_PM 246#ifdef CONFIG_PM_SLEEP
250 .pm = &pxa2xx_ac97_pm_ops, 247 .pm = &pxa2xx_ac97_pm_ops,
251#endif 248#endif
252 }, 249 },
diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c
index f7c2bb08055d..277ebce23a45 100644
--- a/sound/atmel/abdac.c
+++ b/sound/atmel/abdac.c
@@ -452,6 +452,7 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev)
452 dac->regs = ioremap(regs->start, resource_size(regs)); 452 dac->regs = ioremap(regs->start, resource_size(regs));
453 if (!dac->regs) { 453 if (!dac->regs) {
454 dev_dbg(&pdev->dev, "could not remap register memory\n"); 454 dev_dbg(&pdev->dev, "could not remap register memory\n");
455 retval = -ENOMEM;
455 goto out_free_card; 456 goto out_free_card;
456 } 457 }
457 458
@@ -534,10 +535,10 @@ out_put_pclk:
534 return retval; 535 return retval;
535} 536}
536 537
537#ifdef CONFIG_PM 538#ifdef CONFIG_PM_SLEEP
538static int atmel_abdac_suspend(struct platform_device *pdev, pm_message_t msg) 539static int atmel_abdac_suspend(struct device *pdev)
539{ 540{
540 struct snd_card *card = platform_get_drvdata(pdev); 541 struct snd_card *card = dev_get_drvdata(pdev);
541 struct atmel_abdac *dac = card->private_data; 542 struct atmel_abdac *dac = card->private_data;
542 543
543 dw_dma_cyclic_stop(dac->dma.chan); 544 dw_dma_cyclic_stop(dac->dma.chan);
@@ -547,9 +548,9 @@ static int atmel_abdac_suspend(struct platform_device *pdev, pm_message_t msg)
547 return 0; 548 return 0;
548} 549}
549 550
550static int atmel_abdac_resume(struct platform_device *pdev) 551static int atmel_abdac_resume(struct device *pdev)
551{ 552{
552 struct snd_card *card = platform_get_drvdata(pdev); 553 struct snd_card *card = dev_get_drvdata(pdev);
553 struct atmel_abdac *dac = card->private_data; 554 struct atmel_abdac *dac = card->private_data;
554 555
555 clk_enable(dac->pclk); 556 clk_enable(dac->pclk);
@@ -559,9 +560,11 @@ static int atmel_abdac_resume(struct platform_device *pdev)
559 560
560 return 0; 561 return 0;
561} 562}
563
564static SIMPLE_DEV_PM_OPS(atmel_abdac_pm, atmel_abdac_suspend, atmel_abdac_resume);
565#define ATMEL_ABDAC_PM_OPS &atmel_abdac_pm
562#else 566#else
563#define atmel_abdac_suspend NULL 567#define ATMEL_ABDAC_PM_OPS NULL
564#define atmel_abdac_resume NULL
565#endif 568#endif
566 569
567static int __devexit atmel_abdac_remove(struct platform_device *pdev) 570static int __devexit atmel_abdac_remove(struct platform_device *pdev)
@@ -589,9 +592,9 @@ static struct platform_driver atmel_abdac_driver = {
589 .remove = __devexit_p(atmel_abdac_remove), 592 .remove = __devexit_p(atmel_abdac_remove),
590 .driver = { 593 .driver = {
591 .name = "atmel_abdac", 594 .name = "atmel_abdac",
595 .owner = THIS_MODULE,
596 .pm = ATMEL_ABDAC_PM_OPS,
592 }, 597 },
593 .suspend = atmel_abdac_suspend,
594 .resume = atmel_abdac_resume,
595}; 598};
596 599
597static int __init atmel_abdac_init(void) 600static int __init atmel_abdac_init(void)
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
index f5ded640b395..9052aff37f64 100644
--- a/sound/atmel/ac97c.c
+++ b/sound/atmel/ac97c.c
@@ -278,14 +278,9 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream,
278 if (retval < 0) 278 if (retval < 0)
279 return retval; 279 return retval;
280 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ 280 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
281 if (cpu_is_at32ap7000()) { 281 if (cpu_is_at32ap7000() && retval == 1)
282 if (retval < 0) 282 if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
283 return retval; 283 dw_dma_cyclic_free(chip->dma.rx_chan);
284 /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
285 if (retval == 1)
286 if (test_and_clear_bit(DMA_RX_READY, &chip->flags))
287 dw_dma_cyclic_free(chip->dma.rx_chan);
288 }
289 284
290 /* Set restrictions to params. */ 285 /* Set restrictions to params. */
291 mutex_lock(&opened_mutex); 286 mutex_lock(&opened_mutex);
@@ -980,6 +975,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
980 975
981 if (!chip->regs) { 976 if (!chip->regs) {
982 dev_dbg(&pdev->dev, "could not remap register memory\n"); 977 dev_dbg(&pdev->dev, "could not remap register memory\n");
978 retval = -ENOMEM;
983 goto err_ioremap; 979 goto err_ioremap;
984 } 980 }
985 981
@@ -1134,10 +1130,10 @@ err_snd_card_new:
1134 return retval; 1130 return retval;
1135} 1131}
1136 1132
1137#ifdef CONFIG_PM 1133#ifdef CONFIG_PM_SLEEP
1138static int atmel_ac97c_suspend(struct platform_device *pdev, pm_message_t msg) 1134static int atmel_ac97c_suspend(struct device *pdev)
1139{ 1135{
1140 struct snd_card *card = platform_get_drvdata(pdev); 1136 struct snd_card *card = dev_get_drvdata(pdev);
1141 struct atmel_ac97c *chip = card->private_data; 1137 struct atmel_ac97c *chip = card->private_data;
1142 1138
1143 if (cpu_is_at32ap7000()) { 1139 if (cpu_is_at32ap7000()) {
@@ -1151,9 +1147,9 @@ static int atmel_ac97c_suspend(struct platform_device *pdev, pm_message_t msg)
1151 return 0; 1147 return 0;
1152} 1148}
1153 1149
1154static int atmel_ac97c_resume(struct platform_device *pdev) 1150static int atmel_ac97c_resume(struct device *pdev)
1155{ 1151{
1156 struct snd_card *card = platform_get_drvdata(pdev); 1152 struct snd_card *card = dev_get_drvdata(pdev);
1157 struct atmel_ac97c *chip = card->private_data; 1153 struct atmel_ac97c *chip = card->private_data;
1158 1154
1159 clk_enable(chip->pclk); 1155 clk_enable(chip->pclk);
@@ -1165,9 +1161,11 @@ static int atmel_ac97c_resume(struct platform_device *pdev)
1165 } 1161 }
1166 return 0; 1162 return 0;
1167} 1163}
1164
1165static SIMPLE_DEV_PM_OPS(atmel_ac97c_pm, atmel_ac97c_suspend, atmel_ac97c_resume);
1166#define ATMEL_AC97C_PM_OPS &atmel_ac97c_pm
1168#else 1167#else
1169#define atmel_ac97c_suspend NULL 1168#define ATMEL_AC97C_PM_OPS NULL
1170#define atmel_ac97c_resume NULL
1171#endif 1169#endif
1172 1170
1173static int __devexit atmel_ac97c_remove(struct platform_device *pdev) 1171static int __devexit atmel_ac97c_remove(struct platform_device *pdev)
@@ -1210,9 +1208,9 @@ static struct platform_driver atmel_ac97c_driver = {
1210 .remove = __devexit_p(atmel_ac97c_remove), 1208 .remove = __devexit_p(atmel_ac97c_remove),
1211 .driver = { 1209 .driver = {
1212 .name = "atmel_ac97c", 1210 .name = "atmel_ac97c",
1211 .owner = THIS_MODULE,
1212 .pm = ATMEL_AC97C_PM_OPS,
1213 }, 1213 },
1214 .suspend = atmel_ac97c_suspend,
1215 .resume = atmel_ac97c_resume,
1216}; 1214};
1217 1215
1218static int __init atmel_ac97c_init(void) 1216static int __init atmel_ac97c_init(void)
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index ec2118d0e27a..eb60cb8dbb8a 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -80,14 +80,12 @@ static int snd_compr_open(struct inode *inode, struct file *f)
80 int maj = imajor(inode); 80 int maj = imajor(inode);
81 int ret; 81 int ret;
82 82
83 if (f->f_flags & O_WRONLY) 83 if ((f->f_flags & O_ACCMODE) == O_WRONLY)
84 dirn = SND_COMPRESS_PLAYBACK; 84 dirn = SND_COMPRESS_PLAYBACK;
85 else if (f->f_flags & O_RDONLY) 85 else if ((f->f_flags & O_ACCMODE) == O_RDONLY)
86 dirn = SND_COMPRESS_CAPTURE; 86 dirn = SND_COMPRESS_CAPTURE;
87 else { 87 else
88 pr_err("invalid direction\n");
89 return -EINVAL; 88 return -EINVAL;
90 }
91 89
92 if (maj == snd_major) 90 if (maj == snd_major)
93 compr = snd_lookup_minor_data(iminor(inode), 91 compr = snd_lookup_minor_data(iminor(inode),
diff --git a/sound/core/misc.c b/sound/core/misc.c
index 768167925409..30e027ecf4da 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -68,6 +68,7 @@ void __snd_printk(unsigned int level, const char *path, int line,
68{ 68{
69 va_list args; 69 va_list args;
70#ifdef CONFIG_SND_VERBOSE_PRINTK 70#ifdef CONFIG_SND_VERBOSE_PRINTK
71 int kern_level;
71 struct va_format vaf; 72 struct va_format vaf;
72 char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV"; 73 char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV";
73#endif 74#endif
@@ -81,12 +82,16 @@ void __snd_printk(unsigned int level, const char *path, int line,
81#ifdef CONFIG_SND_VERBOSE_PRINTK 82#ifdef CONFIG_SND_VERBOSE_PRINTK
82 vaf.fmt = format; 83 vaf.fmt = format;
83 vaf.va = &args; 84 vaf.va = &args;
84 if (format[0] == '<' && format[2] == '>') { 85
85 memcpy(verbose_fmt, format, 3); 86 kern_level = printk_get_level(format);
86 vaf.fmt = format + 3; 87 if (kern_level) {
88 const char *end_of_header = printk_skip_level(format);
89 memcpy(verbose_fmt, format, end_of_header - format);
90 vaf.fmt = end_of_header;
87 } else if (level) 91 } else if (level)
88 memcpy(verbose_fmt, KERN_DEBUG, 3); 92 memcpy(verbose_fmt, KERN_DEBUG, sizeof(KERN_DEBUG) - 1);
89 printk(verbose_fmt, sanity_file_name(path), line, &vaf); 93 printk(verbose_fmt, sanity_file_name(path), line, &vaf);
94
90#else 95#else
91 vprintk(format, args); 96 vprintk(format, args);
92#endif 97#endif
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 8f312fa6c282..7ae671923393 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1250,10 +1250,10 @@ static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params,
1250int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime, 1250int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime,
1251 unsigned int cond, 1251 unsigned int cond,
1252 snd_pcm_hw_param_t var, 1252 snd_pcm_hw_param_t var,
1253 struct snd_pcm_hw_constraint_list *l) 1253 const struct snd_pcm_hw_constraint_list *l)
1254{ 1254{
1255 return snd_pcm_hw_rule_add(runtime, cond, var, 1255 return snd_pcm_hw_rule_add(runtime, cond, var,
1256 snd_pcm_hw_rule_list, l, 1256 snd_pcm_hw_rule_list, (void *)l,
1257 var, -1); 1257 var, -1);
1258} 1258}
1259 1259
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
index 9c9eff9afbac..d4fc1bfbe457 100644
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -488,3 +488,21 @@ unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate)
488 return SNDRV_PCM_RATE_KNOT; 488 return SNDRV_PCM_RATE_KNOT;
489} 489}
490EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit); 490EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit);
491
492/**
493 * snd_pcm_rate_bit_to_rate - converts SNDRV_PCM_RATE_xxx bit to sample rate
494 * @rate_bit: the rate bit to convert
495 *
496 * Returns the sample rate that corresponds to the given SNDRV_PCM_RATE_xxx flag
497 * or 0 for an unknown rate bit
498 */
499unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit)
500{
501 unsigned int i;
502
503 for (i = 0; i < snd_pcm_known_rates.count; i++)
504 if ((1u << i) == rate_bit)
505 return snd_pcm_known_rates.list[i];
506 return 0;
507}
508EXPORT_SYMBOL(snd_pcm_rate_bit_to_rate);
diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c
index 4e7ec2b49873..d0f00356fc11 100644
--- a/sound/core/sgbuf.c
+++ b/sound/core/sgbuf.c
@@ -101,7 +101,7 @@ void *snd_malloc_sgbuf_pages(struct device *device,
101 if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, device, 101 if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, device,
102 chunk, &tmpb) < 0) { 102 chunk, &tmpb) < 0) {
103 if (!sgbuf->pages) 103 if (!sgbuf->pages)
104 return NULL; 104 goto _failed;
105 if (!res_size) 105 if (!res_size)
106 goto _failed; 106 goto _failed;
107 size = sgbuf->pages * PAGE_SIZE; 107 size = sgbuf->pages * PAGE_SIZE;
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index 8b5c36f4d303..5a34355e78e8 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -1176,11 +1176,10 @@ static int __devexit loopback_remove(struct platform_device *devptr)
1176 return 0; 1176 return 0;
1177} 1177}
1178 1178
1179#ifdef CONFIG_PM 1179#ifdef CONFIG_PM_SLEEP
1180static int loopback_suspend(struct platform_device *pdev, 1180static int loopback_suspend(struct device *pdev)
1181 pm_message_t state)
1182{ 1181{
1183 struct snd_card *card = platform_get_drvdata(pdev); 1182 struct snd_card *card = dev_get_drvdata(pdev);
1184 struct loopback *loopback = card->private_data; 1183 struct loopback *loopback = card->private_data;
1185 1184
1186 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 1185 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -1190,13 +1189,18 @@ static int loopback_suspend(struct platform_device *pdev,
1190 return 0; 1189 return 0;
1191} 1190}
1192 1191
1193static int loopback_resume(struct platform_device *pdev) 1192static int loopback_resume(struct device *pdev)
1194{ 1193{
1195 struct snd_card *card = platform_get_drvdata(pdev); 1194 struct snd_card *card = dev_get_drvdata(pdev);
1196 1195
1197 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1196 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1198 return 0; 1197 return 0;
1199} 1198}
1199
1200static SIMPLE_DEV_PM_OPS(loopback_pm, loopback_suspend, loopback_resume);
1201#define LOOPBACK_PM_OPS &loopback_pm
1202#else
1203#define LOOPBACK_PM_OPS NULL
1200#endif 1204#endif
1201 1205
1202#define SND_LOOPBACK_DRIVER "snd_aloop" 1206#define SND_LOOPBACK_DRIVER "snd_aloop"
@@ -1204,12 +1208,10 @@ static int loopback_resume(struct platform_device *pdev)
1204static struct platform_driver loopback_driver = { 1208static struct platform_driver loopback_driver = {
1205 .probe = loopback_probe, 1209 .probe = loopback_probe,
1206 .remove = __devexit_p(loopback_remove), 1210 .remove = __devexit_p(loopback_remove),
1207#ifdef CONFIG_PM
1208 .suspend = loopback_suspend,
1209 .resume = loopback_resume,
1210#endif
1211 .driver = { 1211 .driver = {
1212 .name = SND_LOOPBACK_DRIVER 1212 .name = SND_LOOPBACK_DRIVER,
1213 .owner = THIS_MODULE,
1214 .pm = LOOPBACK_PM_OPS,
1213 }, 1215 },
1214}; 1216};
1215 1217
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index ad9434fd6370..54bb6644a598 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -1064,10 +1064,10 @@ static int __devexit snd_dummy_remove(struct platform_device *devptr)
1064 return 0; 1064 return 0;
1065} 1065}
1066 1066
1067#ifdef CONFIG_PM 1067#ifdef CONFIG_PM_SLEEP
1068static int snd_dummy_suspend(struct platform_device *pdev, pm_message_t state) 1068static int snd_dummy_suspend(struct device *pdev)
1069{ 1069{
1070 struct snd_card *card = platform_get_drvdata(pdev); 1070 struct snd_card *card = dev_get_drvdata(pdev);
1071 struct snd_dummy *dummy = card->private_data; 1071 struct snd_dummy *dummy = card->private_data;
1072 1072
1073 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 1073 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -1075,13 +1075,18 @@ static int snd_dummy_suspend(struct platform_device *pdev, pm_message_t state)
1075 return 0; 1075 return 0;
1076} 1076}
1077 1077
1078static int snd_dummy_resume(struct platform_device *pdev) 1078static int snd_dummy_resume(struct device *pdev)
1079{ 1079{
1080 struct snd_card *card = platform_get_drvdata(pdev); 1080 struct snd_card *card = dev_get_drvdata(pdev);
1081 1081
1082 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1082 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1083 return 0; 1083 return 0;
1084} 1084}
1085
1086static SIMPLE_DEV_PM_OPS(snd_dummy_pm, snd_dummy_suspend, snd_dummy_resume);
1087#define SND_DUMMY_PM_OPS &snd_dummy_pm
1088#else
1089#define SND_DUMMY_PM_OPS NULL
1085#endif 1090#endif
1086 1091
1087#define SND_DUMMY_DRIVER "snd_dummy" 1092#define SND_DUMMY_DRIVER "snd_dummy"
@@ -1089,12 +1094,10 @@ static int snd_dummy_resume(struct platform_device *pdev)
1089static struct platform_driver snd_dummy_driver = { 1094static struct platform_driver snd_dummy_driver = {
1090 .probe = snd_dummy_probe, 1095 .probe = snd_dummy_probe,
1091 .remove = __devexit_p(snd_dummy_remove), 1096 .remove = __devexit_p(snd_dummy_remove),
1092#ifdef CONFIG_PM
1093 .suspend = snd_dummy_suspend,
1094 .resume = snd_dummy_resume,
1095#endif
1096 .driver = { 1097 .driver = {
1097 .name = SND_DUMMY_DRIVER 1098 .name = SND_DUMMY_DRIVER,
1099 .owner = THIS_MODULE,
1100 .pm = SND_DUMMY_PM_OPS,
1098 }, 1101 },
1099}; 1102};
1100 1103
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index 86f5fbc2da72..bc03a2046c9c 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -139,7 +139,8 @@ static struct platform_driver snd_mpu401_driver = {
139 .probe = snd_mpu401_probe, 139 .probe = snd_mpu401_probe,
140 .remove = __devexit_p(snd_mpu401_remove), 140 .remove = __devexit_p(snd_mpu401_remove),
141 .driver = { 141 .driver = {
142 .name = SND_MPU401_DRIVER 142 .name = SND_MPU401_DRIVER,
143 .owner = THIS_MODULE,
143 }, 144 },
144}; 145};
145 146
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index 1cff331a228e..4608c2ca43f8 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -554,6 +554,7 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
554 spin_lock_init(&mpu->output_lock); 554 spin_lock_init(&mpu->output_lock);
555 spin_lock_init(&mpu->timer_lock); 555 spin_lock_init(&mpu->timer_lock);
556 mpu->hardware = hardware; 556 mpu->hardware = hardware;
557 mpu->irq = -1;
557 if (! (info_flags & MPU401_INFO_INTEGRATED)) { 558 if (! (info_flags & MPU401_INFO_INTEGRATED)) {
558 int res_size = hardware == MPU401_HW_PC98II ? 4 : 2; 559 int res_size = hardware == MPU401_HW_PC98II ? 4 : 2;
559 mpu->res = request_region(port, res_size, "MPU401 UART"); 560 mpu->res = request_region(port, res_size, "MPU401 UART");
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index 76930793fb69..cad73af3860c 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -759,7 +759,8 @@ static struct platform_driver snd_mtpav_driver = {
759 .probe = snd_mtpav_probe, 759 .probe = snd_mtpav_probe,
760 .remove = __devexit_p(snd_mtpav_remove), 760 .remove = __devexit_p(snd_mtpav_remove),
761 .driver = { 761 .driver = {
762 .name = SND_MTPAV_DRIVER 762 .name = SND_MTPAV_DRIVER,
763 .owner = THIS_MODULE,
763 }, 764 },
764}; 765};
765 766
diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c
index 621e60e2029f..2d5514b0a290 100644
--- a/sound/drivers/mts64.c
+++ b/sound/drivers/mts64.c
@@ -1040,7 +1040,8 @@ static struct platform_driver snd_mts64_driver = {
1040 .probe = snd_mts64_probe, 1040 .probe = snd_mts64_probe,
1041 .remove = __devexit_p(snd_mts64_remove), 1041 .remove = __devexit_p(snd_mts64_remove),
1042 .driver = { 1042 .driver = {
1043 .name = PLATFORM_DRIVER 1043 .name = PLATFORM_DRIVER,
1044 .owner = THIS_MODULE,
1044 } 1045 }
1045}; 1046};
1046 1047
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c
index 99704e6a2e26..ef171295f6d4 100644
--- a/sound/drivers/pcsp/pcsp.c
+++ b/sound/drivers/pcsp/pcsp.c
@@ -199,17 +199,20 @@ static void pcsp_stop_beep(struct snd_pcsp *chip)
199 pcspkr_stop_sound(); 199 pcspkr_stop_sound();
200} 200}
201 201
202#ifdef CONFIG_PM 202#ifdef CONFIG_PM_SLEEP
203static int pcsp_suspend(struct platform_device *dev, pm_message_t state) 203static int pcsp_suspend(struct device *dev)
204{ 204{
205 struct snd_pcsp *chip = platform_get_drvdata(dev); 205 struct snd_pcsp *chip = dev_get_drvdata(dev);
206 pcsp_stop_beep(chip); 206 pcsp_stop_beep(chip);
207 snd_pcm_suspend_all(chip->pcm); 207 snd_pcm_suspend_all(chip->pcm);
208 return 0; 208 return 0;
209} 209}
210
211static SIMPLE_DEV_PM_OPS(pcsp_pm, pcsp_suspend, NULL);
212#define PCSP_PM_OPS &pcsp_pm
210#else 213#else
211#define pcsp_suspend NULL 214#define PCSP_PM_OPS NULL
212#endif /* CONFIG_PM */ 215#endif /* CONFIG_PM_SLEEP */
213 216
214static void pcsp_shutdown(struct platform_device *dev) 217static void pcsp_shutdown(struct platform_device *dev)
215{ 218{
@@ -221,10 +224,10 @@ static struct platform_driver pcsp_platform_driver = {
221 .driver = { 224 .driver = {
222 .name = "pcspkr", 225 .name = "pcspkr",
223 .owner = THIS_MODULE, 226 .owner = THIS_MODULE,
227 .pm = PCSP_PM_OPS,
224 }, 228 },
225 .probe = pcsp_probe, 229 .probe = pcsp_probe,
226 .remove = __devexit_p(pcsp_remove), 230 .remove = __devexit_p(pcsp_remove),
227 .suspend = pcsp_suspend,
228 .shutdown = pcsp_shutdown, 231 .shutdown = pcsp_shutdown,
229}; 232};
230 233
diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c
index 3e32bd3d95d9..8364855ed14f 100644
--- a/sound/drivers/portman2x4.c
+++ b/sound/drivers/portman2x4.c
@@ -829,7 +829,8 @@ static struct platform_driver snd_portman_driver = {
829 .probe = snd_portman_probe, 829 .probe = snd_portman_probe,
830 .remove = __devexit_p(snd_portman_remove), 830 .remove = __devexit_p(snd_portman_remove),
831 .driver = { 831 .driver = {
832 .name = PLATFORM_DRIVER 832 .name = PLATFORM_DRIVER,
833 .owner = THIS_MODULE,
833 } 834 }
834}; 835};
835 836
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index b2d0e8e49bed..86700671d1ac 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -995,7 +995,8 @@ static struct platform_driver snd_serial_driver = {
995 .probe = snd_serial_probe, 995 .probe = snd_serial_probe,
996 .remove = __devexit_p( snd_serial_remove), 996 .remove = __devexit_p( snd_serial_remove),
997 .driver = { 997 .driver = {
998 .name = SND_SERIAL_DRIVER 998 .name = SND_SERIAL_DRIVER,
999 .owner = THIS_MODULE,
999 }, 1000 },
1000}; 1001};
1001 1002
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index 9d97478a18b3..d7d514df9058 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -142,7 +142,8 @@ static struct platform_driver snd_virmidi_driver = {
142 .probe = snd_virmidi_probe, 142 .probe = snd_virmidi_probe,
143 .remove = __devexit_p(snd_virmidi_remove), 143 .remove = __devexit_p(snd_virmidi_remove),
144 .driver = { 144 .driver = {
145 .name = SND_VIRMIDI_DRIVER 145 .name = SND_VIRMIDI_DRIVER,
146 .owner = THIS_MODULE,
146 }, 147 },
147}; 148};
148 149
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index b8e515999bc2..de5055a3b0d0 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -725,7 +725,7 @@ EXPORT_SYMBOL(snd_vx_dsp_load);
725/* 725/*
726 * suspend 726 * suspend
727 */ 727 */
728int snd_vx_suspend(struct vx_core *chip, pm_message_t state) 728int snd_vx_suspend(struct vx_core *chip)
729{ 729{
730 unsigned int i; 730 unsigned int i;
731 731
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c
index dde5c9c92132..ef68d710d08c 100644
--- a/sound/i2c/other/ak4113.c
+++ b/sound/i2c/other/ak4113.c
@@ -141,7 +141,7 @@ void snd_ak4113_reinit(struct ak4113 *chip)
141{ 141{
142 chip->init = 1; 142 chip->init = 1;
143 mb(); 143 mb();
144 flush_delayed_work_sync(&chip->work); 144 flush_delayed_work(&chip->work);
145 ak4113_init_regs(chip); 145 ak4113_init_regs(chip);
146 /* bring up statistics / event queing */ 146 /* bring up statistics / event queing */
147 chip->init = 0; 147 chip->init = 0;
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index fdf3c1b65e38..816e7d225fb0 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -154,7 +154,7 @@ void snd_ak4114_reinit(struct ak4114 *chip)
154{ 154{
155 chip->init = 1; 155 chip->init = 1;
156 mb(); 156 mb();
157 flush_delayed_work_sync(&chip->work); 157 flush_delayed_work(&chip->work);
158 ak4114_init_regs(chip); 158 ak4114_init_regs(chip);
159 /* bring up statistics / event queing */ 159 /* bring up statistics / event queing */
160 chip->init = 0; 160 chip->init = 0;
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index 7eca25fae413..d14edb7d6484 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -71,6 +71,9 @@ static void snd_tea575x_write(struct snd_tea575x *tea, unsigned int val)
71 u16 l; 71 u16 l;
72 u8 data; 72 u8 data;
73 73
74 if (tea->ops->write_val)
75 return tea->ops->write_val(tea, val);
76
74 tea->ops->set_direction(tea, 1); 77 tea->ops->set_direction(tea, 1);
75 udelay(16); 78 udelay(16);
76 79
@@ -94,6 +97,9 @@ static u32 snd_tea575x_read(struct snd_tea575x *tea)
94 u16 l, rdata; 97 u16 l, rdata;
95 u32 data = 0; 98 u32 data = 0;
96 99
100 if (tea->ops->read_val)
101 return tea->ops->read_val(tea);
102
97 tea->ops->set_direction(tea, 0); 103 tea->ops->set_direction(tea, 0);
98 tea->ops->set_pins(tea, 0); 104 tea->ops->set_pins(tea, 0);
99 udelay(16); 105 udelay(16);
@@ -197,6 +203,8 @@ static int vidioc_g_tuner(struct file *file, void *priv,
197 strcpy(v->name, "FM"); 203 strcpy(v->name, "FM");
198 v->type = V4L2_TUNER_RADIO; 204 v->type = V4L2_TUNER_RADIO;
199 v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; 205 v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
206 if (!tea->cannot_read_data)
207 v->capability |= V4L2_TUNER_CAP_HWSEEK_BOUNDED;
200 v->rangelow = FREQ_LO; 208 v->rangelow = FREQ_LO;
201 v->rangehigh = FREQ_HI; 209 v->rangehigh = FREQ_HI;
202 v->rxsubchans = tea->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; 210 v->rxsubchans = tea->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
@@ -305,7 +313,7 @@ static int vidioc_s_hw_freq_seek(struct file *file, void *fh,
305 } 313 }
306 tea->val &= ~TEA575X_BIT_SEARCH; 314 tea->val &= ~TEA575X_BIT_SEARCH;
307 snd_tea575x_set_freq(tea); 315 snd_tea575x_set_freq(tea);
308 return -EAGAIN; 316 return -ENODATA;
309} 317}
310 318
311static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl) 319static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl)
@@ -377,7 +385,6 @@ int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner)
377 strlcpy(tea->vd.name, tea->v4l2_dev->name, sizeof(tea->vd.name)); 385 strlcpy(tea->vd.name, tea->v4l2_dev->name, sizeof(tea->vd.name));
378 tea->vd.lock = &tea->mutex; 386 tea->vd.lock = &tea->mutex;
379 tea->vd.v4l2_dev = tea->v4l2_dev; 387 tea->vd.v4l2_dev = tea->v4l2_dev;
380 tea->vd.ctrl_handler = &tea->ctrl_handler;
381 tea->fops = tea575x_fops; 388 tea->fops = tea575x_fops;
382 tea->fops.owner = owner; 389 tea->fops.owner = owner;
383 tea->vd.fops = &tea->fops; 390 tea->vd.fops = &tea->fops;
@@ -386,29 +393,33 @@ int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner)
386 if (tea->cannot_read_data) 393 if (tea->cannot_read_data)
387 v4l2_disable_ioctl(&tea->vd, VIDIOC_S_HW_FREQ_SEEK); 394 v4l2_disable_ioctl(&tea->vd, VIDIOC_S_HW_FREQ_SEEK);
388 395
389 v4l2_ctrl_handler_init(&tea->ctrl_handler, 1); 396 if (!tea->cannot_mute) {
390 v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); 397 tea->vd.ctrl_handler = &tea->ctrl_handler;
391 retval = tea->ctrl_handler.error; 398 v4l2_ctrl_handler_init(&tea->ctrl_handler, 1);
392 if (retval) { 399 v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops,
393 v4l2_err(tea->v4l2_dev, "can't initialize controls\n"); 400 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
394 v4l2_ctrl_handler_free(&tea->ctrl_handler); 401 retval = tea->ctrl_handler.error;
395 return retval;
396 }
397
398 if (tea->ext_init) {
399 retval = tea->ext_init(tea);
400 if (retval) { 402 if (retval) {
403 v4l2_err(tea->v4l2_dev, "can't initialize controls\n");
401 v4l2_ctrl_handler_free(&tea->ctrl_handler); 404 v4l2_ctrl_handler_free(&tea->ctrl_handler);
402 return retval; 405 return retval;
403 } 406 }
404 }
405 407
406 v4l2_ctrl_handler_setup(&tea->ctrl_handler); 408 if (tea->ext_init) {
409 retval = tea->ext_init(tea);
410 if (retval) {
411 v4l2_ctrl_handler_free(&tea->ctrl_handler);
412 return retval;
413 }
414 }
415
416 v4l2_ctrl_handler_setup(&tea->ctrl_handler);
417 }
407 418
408 retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->radio_nr); 419 retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->radio_nr);
409 if (retval) { 420 if (retval) {
410 v4l2_err(tea->v4l2_dev, "can't register video device!\n"); 421 v4l2_err(tea->v4l2_dev, "can't register video device!\n");
411 v4l2_ctrl_handler_free(&tea->ctrl_handler); 422 v4l2_ctrl_handler_free(tea->vd.ctrl_handler);
412 return retval; 423 return retval;
413 } 424 }
414 425
@@ -418,7 +429,7 @@ int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner)
418void snd_tea575x_exit(struct snd_tea575x *tea) 429void snd_tea575x_exit(struct snd_tea575x *tea)
419{ 430{
420 video_unregister_device(&tea->vd); 431 video_unregister_device(&tea->vd);
421 v4l2_ctrl_handler_free(&tea->ctrl_handler); 432 v4l2_ctrl_handler_free(tea->vd.ctrl_handler);
422} 433}
423 434
424static int __init alsa_tea575x_module_init(void) 435static int __init alsa_tea575x_module_init(void)
diff --git a/sound/isa/als100.c b/sound/isa/als100.c
index 2d67c78c9f4b..f7cdaf51512d 100644
--- a/sound/isa/als100.c
+++ b/sound/isa/als100.c
@@ -233,7 +233,7 @@ static int __devinit snd_card_als100_probe(int dev,
233 irq[dev], dma8[dev], dma16[dev]); 233 irq[dev], dma8[dev], dma16[dev]);
234 } 234 }
235 235
236 if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) { 236 if ((error = snd_sb16dsp_pcm(chip, 0, &chip->pcm)) < 0) {
237 snd_card_free(card); 237 snd_card_free(card);
238 return error; 238 return error;
239 } 239 }
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index 1d47be8170b5..b3b4f15e45ba 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -612,10 +612,10 @@ static int snd_es1688_capture_close(struct snd_pcm_substream *substream)
612 612
613static int snd_es1688_free(struct snd_es1688 *chip) 613static int snd_es1688_free(struct snd_es1688 *chip)
614{ 614{
615 if (chip->res_port) { 615 if (chip->hardware != ES1688_HW_UNDEF)
616 snd_es1688_init(chip, 0); 616 snd_es1688_init(chip, 0);
617 if (chip->res_port)
617 release_and_free_resource(chip->res_port); 618 release_and_free_resource(chip->res_port);
618 }
619 if (chip->irq >= 0) 619 if (chip->irq >= 0)
620 free_irq(chip->irq, (void *) chip); 620 free_irq(chip->irq, (void *) chip);
621 if (chip->dma8 >= 0) { 621 if (chip->dma8 >= 0) {
@@ -657,19 +657,27 @@ int snd_es1688_create(struct snd_card *card,
657 return -ENOMEM; 657 return -ENOMEM;
658 chip->irq = -1; 658 chip->irq = -1;
659 chip->dma8 = -1; 659 chip->dma8 = -1;
660 chip->hardware = ES1688_HW_UNDEF;
660 661
661 if ((chip->res_port = request_region(port + 4, 12, "ES1688")) == NULL) { 662 chip->res_port = request_region(port + 4, 12, "ES1688");
663 if (chip->res_port == NULL) {
662 snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4); 664 snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4);
663 return -EBUSY; 665 err = -EBUSY;
666 goto exit;
664 } 667 }
665 if (request_irq(irq, snd_es1688_interrupt, 0, "ES1688", (void *) chip)) { 668
669 err = request_irq(irq, snd_es1688_interrupt, 0, "ES1688", (void *) chip);
670 if (err < 0) {
666 snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq); 671 snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq);
667 return -EBUSY; 672 goto exit;
668 } 673 }
674
669 chip->irq = irq; 675 chip->irq = irq;
670 if (request_dma(dma8, "ES1688")) { 676 err = request_dma(dma8, "ES1688");
677
678 if (err < 0) {
671 snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8); 679 snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8);
672 return -EBUSY; 680 goto exit;
673 } 681 }
674 chip->dma8 = dma8; 682 chip->dma8 = dma8;
675 683
@@ -685,14 +693,18 @@ int snd_es1688_create(struct snd_card *card,
685 693
686 err = snd_es1688_probe(chip); 694 err = snd_es1688_probe(chip);
687 if (err < 0) 695 if (err < 0)
688 return err; 696 goto exit;
689 697
690 err = snd_es1688_init(chip, 1); 698 err = snd_es1688_init(chip, 1);
691 if (err < 0) 699 if (err < 0)
692 return err; 700 goto exit;
693 701
694 /* Register device */ 702 /* Register device */
695 return snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); 703 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
704exit:
705 if (err)
706 snd_es1688_free(chip);
707 return err;
696} 708}
697 709
698static struct snd_pcm_ops snd_es1688_playback_ops = { 710static struct snd_pcm_ops snd_es1688_playback_ops = {
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index d7ccf28bd66a..f8fbe22515c9 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -135,10 +135,9 @@ struct snd_opti9xx {
135 unsigned long mc_base_size; 135 unsigned long mc_base_size;
136#ifdef OPTi93X 136#ifdef OPTi93X
137 unsigned long mc_indir_index; 137 unsigned long mc_indir_index;
138 unsigned long mc_indir_size;
139 struct resource *res_mc_indir; 138 struct resource *res_mc_indir;
140 struct snd_wss *codec;
141#endif /* OPTi93X */ 139#endif /* OPTi93X */
140 struct snd_wss *codec;
142 unsigned long pwd_reg; 141 unsigned long pwd_reg;
143 142
144 spinlock_t lock; 143 spinlock_t lock;
@@ -245,10 +244,8 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
245 case OPTi9XX_HW_82C931: 244 case OPTi9XX_HW_82C931:
246 case OPTi9XX_HW_82C933: 245 case OPTi9XX_HW_82C933:
247 chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d; 246 chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d;
248 if (!chip->mc_indir_index) { 247 if (!chip->mc_indir_index)
249 chip->mc_indir_index = 0xe0e; 248 chip->mc_indir_index = 0xe0e;
250 chip->mc_indir_size = 2;
251 }
252 chip->password = 0xe4; 249 chip->password = 0xe4;
253 chip->pwd_reg = 0; 250 chip->pwd_reg = 0;
254 break; 251 break;
@@ -351,7 +348,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
351 (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask))) 348 (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))
352 349
353 350
354static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, 351static int snd_opti9xx_configure(struct snd_opti9xx *chip,
355 long port, 352 long port,
356 int irq, int dma1, int dma2, 353 int irq, int dma1, int dma2,
357 long mpu_port, int mpu_irq) 354 long mpu_port, int mpu_irq)
@@ -403,7 +400,9 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
403 400
404#else /* OPTi93X */ 401#else /* OPTi93X */
405 case OPTi9XX_HW_82C931: 402 case OPTi9XX_HW_82C931:
406 case OPTi9XX_HW_82C933: 403 /* disable 3D sound (set GPIO1 as output, low) */
404 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(20), 0x04, 0x0c);
405 case OPTi9XX_HW_82C933: /* FALL THROUGH */
407 /* 406 /*
408 * The BTC 1817DW has QS1000 wavetable which is connected 407 * The BTC 1817DW has QS1000 wavetable which is connected
409 * to the serial digital input of the OPTI931. 408 * to the serial digital input of the OPTI931.
@@ -696,8 +695,7 @@ static int __devinit snd_opti9xx_read_check(struct snd_opti9xx *chip)
696 if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1))) 695 if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
697 return 0; 696 return 0;
698#else /* OPTi93X */ 697#else /* OPTi93X */
699 chip->res_mc_indir = request_region(chip->mc_indir_index, 698 chip->res_mc_indir = request_region(chip->mc_indir_index, 2,
700 chip->mc_indir_size,
701 "OPTi93x MC"); 699 "OPTi93x MC");
702 if (chip->res_mc_indir == NULL) 700 if (chip->res_mc_indir == NULL)
703 return -EBUSY; 701 return -EBUSY;
@@ -770,8 +768,9 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
770#ifdef OPTi93X 768#ifdef OPTi93X
771 port = pnp_port_start(pdev, 0) - 4; 769 port = pnp_port_start(pdev, 0) - 4;
772 fm_port = pnp_port_start(pdev, 1) + 8; 770 fm_port = pnp_port_start(pdev, 1) + 8;
773 chip->mc_indir_index = pnp_port_start(pdev, 3) + 2; 771 /* adjust mc_indir_index - some cards report it at 0xe?d,
774 chip->mc_indir_size = pnp_port_len(pdev, 3) - 2; 772 other at 0xe?c but it really is always at 0xe?e */
773 chip->mc_indir_index = (pnp_port_start(pdev, 3) & ~0xf) | 0xe;
775#else 774#else
776 devmc = pnp_request_card_device(card, pid->devs[2].id, NULL); 775 devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
777 if (devmc == NULL) 776 if (devmc == NULL)
@@ -871,9 +870,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
871 &codec); 870 &codec);
872 if (error < 0) 871 if (error < 0)
873 return error; 872 return error;
874#ifdef OPTi93X
875 chip->codec = codec; 873 chip->codec = codec;
876#endif
877 error = snd_wss_pcm(codec, 0, &pcm); 874 error = snd_wss_pcm(codec, 0, &pcm);
878 if (error < 0) 875 if (error < 0)
879 return error; 876 return error;
@@ -1054,11 +1051,55 @@ static int __devexit snd_opti9xx_isa_remove(struct device *devptr,
1054 return 0; 1051 return 0;
1055} 1052}
1056 1053
1054#ifdef CONFIG_PM
1055static int snd_opti9xx_suspend(struct snd_card *card)
1056{
1057 struct snd_opti9xx *chip = card->private_data;
1058
1059 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1060 chip->codec->suspend(chip->codec);
1061 return 0;
1062}
1063
1064static int snd_opti9xx_resume(struct snd_card *card)
1065{
1066 struct snd_opti9xx *chip = card->private_data;
1067 int error, xdma2;
1068#if defined(CS4231) || defined(OPTi93X)
1069 xdma2 = dma2;
1070#else
1071 xdma2 = -1;
1072#endif
1073
1074 error = snd_opti9xx_configure(chip, port, irq, dma1, xdma2,
1075 mpu_port, mpu_irq);
1076 if (error)
1077 return error;
1078 chip->codec->resume(chip->codec);
1079 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1080 return 0;
1081}
1082
1083static int snd_opti9xx_isa_suspend(struct device *dev, unsigned int n,
1084 pm_message_t state)
1085{
1086 return snd_opti9xx_suspend(dev_get_drvdata(dev));
1087}
1088
1089static int snd_opti9xx_isa_resume(struct device *dev, unsigned int n)
1090{
1091 return snd_opti9xx_resume(dev_get_drvdata(dev));
1092}
1093#endif
1094
1057static struct isa_driver snd_opti9xx_driver = { 1095static struct isa_driver snd_opti9xx_driver = {
1058 .match = snd_opti9xx_isa_match, 1096 .match = snd_opti9xx_isa_match,
1059 .probe = snd_opti9xx_isa_probe, 1097 .probe = snd_opti9xx_isa_probe,
1060 .remove = __devexit_p(snd_opti9xx_isa_remove), 1098 .remove = __devexit_p(snd_opti9xx_isa_remove),
1061 /* FIXME: suspend/resume */ 1099#ifdef CONFIG_PM
1100 .suspend = snd_opti9xx_isa_suspend,
1101 .resume = snd_opti9xx_isa_resume,
1102#endif
1062 .driver = { 1103 .driver = {
1063 .name = DEV_NAME 1104 .name = DEV_NAME
1064 }, 1105 },
@@ -1124,12 +1165,29 @@ static void __devexit snd_opti9xx_pnp_remove(struct pnp_card_link * pcard)
1124 snd_opti9xx_pnp_is_probed = 0; 1165 snd_opti9xx_pnp_is_probed = 0;
1125} 1166}
1126 1167
1168#ifdef CONFIG_PM
1169static int snd_opti9xx_pnp_suspend(struct pnp_card_link *pcard,
1170 pm_message_t state)
1171{
1172 return snd_opti9xx_suspend(pnp_get_card_drvdata(pcard));
1173}
1174
1175static int snd_opti9xx_pnp_resume(struct pnp_card_link *pcard)
1176{
1177 return snd_opti9xx_resume(pnp_get_card_drvdata(pcard));
1178}
1179#endif
1180
1127static struct pnp_card_driver opti9xx_pnpc_driver = { 1181static struct pnp_card_driver opti9xx_pnpc_driver = {
1128 .flags = PNP_DRIVER_RES_DISABLE, 1182 .flags = PNP_DRIVER_RES_DISABLE,
1129 .name = "opti9xx", 1183 .name = "opti9xx",
1130 .id_table = snd_opti9xx_pnpids, 1184 .id_table = snd_opti9xx_pnpids,
1131 .probe = snd_opti9xx_pnp_probe, 1185 .probe = snd_opti9xx_pnp_probe,
1132 .remove = __devexit_p(snd_opti9xx_pnp_remove), 1186 .remove = __devexit_p(snd_opti9xx_pnp_remove),
1187#ifdef CONFIG_PM
1188 .suspend = snd_opti9xx_pnp_suspend,
1189 .resume = snd_opti9xx_pnp_resume,
1190#endif
1133}; 1191};
1134#endif 1192#endif
1135 1193
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c
index 49c8a0c2442c..360b08b03e1d 100644
--- a/sound/isa/wss/wss_lib.c
+++ b/sound/isa/wss/wss_lib.c
@@ -1456,7 +1456,6 @@ static struct snd_pcm_hardware snd_wss_playback =
1456{ 1456{
1457 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 1457 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1458 SNDRV_PCM_INFO_MMAP_VALID | 1458 SNDRV_PCM_INFO_MMAP_VALID |
1459 SNDRV_PCM_INFO_RESUME |
1460 SNDRV_PCM_INFO_SYNC_START), 1459 SNDRV_PCM_INFO_SYNC_START),
1461 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM | 1460 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1462 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE), 1461 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
@@ -1657,6 +1656,10 @@ static void snd_wss_resume(struct snd_wss *chip)
1657 break; 1656 break;
1658 } 1657 }
1659 } 1658 }
1659 /* Yamaha needs this to resume properly */
1660 if (chip->hardware == WSS_HW_OPL3SA2)
1661 snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
1662 chip->image[CS4231_PLAYBK_FORMAT]);
1660 spin_unlock_irqrestore(&chip->reg_lock, flags); 1663 spin_unlock_irqrestore(&chip->reg_lock, flags);
1661#if 1 1664#if 1
1662 snd_wss_mce_down(chip); 1665 snd_wss_mce_down(chip);
diff --git a/sound/oss/.gitignore b/sound/oss/.gitignore
index 7efb12b45502..12a3920d6fb6 100644
--- a/sound/oss/.gitignore
+++ b/sound/oss/.gitignore
@@ -1,4 +1,3 @@
1#Ignore generated files 1#Ignore generated files
2maui_boot.h
3pss_boot.h 2pss_boot.h
4trix_boot.h 3trix_boot.h
diff --git a/sound/oss/sb_audio.c b/sound/oss/sb_audio.c
index 733b014ec7d1..b2b3c014221a 100644
--- a/sound/oss/sb_audio.c
+++ b/sound/oss/sb_audio.c
@@ -575,13 +575,15 @@ static int jazz16_audio_set_speed(int dev, int speed)
575 if (speed > 0) 575 if (speed > 0)
576 { 576 {
577 int tmp; 577 int tmp;
578 int s = speed * devc->channels; 578 int s;
579 579
580 if (speed < 5000) 580 if (speed < 5000)
581 speed = 5000; 581 speed = 5000;
582 if (speed > 44100) 582 if (speed > 44100)
583 speed = 44100; 583 speed = 44100;
584 584
585 s = speed * devc->channels;
586
585 devc->tconst = (256 - ((1000000 + s / 2) / s)) & 0xff; 587 devc->tconst = (256 - ((1000000 + s / 2) / s)) & 0xff;
586 588
587 tmp = 256 - devc->tconst; 589 tmp = 256 - devc->tconst;
diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c
index 09d46484bc1a..7d8803a00b79 100644
--- a/sound/oss/swarm_cs4297a.c
+++ b/sound/oss/swarm_cs4297a.c
@@ -69,7 +69,6 @@
69#include <linux/sound.h> 69#include <linux/sound.h>
70#include <linux/slab.h> 70#include <linux/slab.h>
71#include <linux/soundcard.h> 71#include <linux/soundcard.h>
72#include <linux/ac97_codec.h>
73#include <linux/pci.h> 72#include <linux/pci.h>
74#include <linux/bitops.h> 73#include <linux/bitops.h>
75#include <linux/interrupt.h> 74#include <linux/interrupt.h>
@@ -199,6 +198,22 @@ static const char invalid_magic[] =
199 } \ 198 } \
200}) 199})
201 200
201/* AC97 registers */
202#define AC97_MASTER_VOL_STEREO 0x0002 /* Line Out */
203#define AC97_PCBEEP_VOL 0x000a /* none */
204#define AC97_PHONE_VOL 0x000c /* TAD Input (mono) */
205#define AC97_MIC_VOL 0x000e /* MIC Input (mono) */
206#define AC97_LINEIN_VOL 0x0010 /* Line Input (stereo) */
207#define AC97_CD_VOL 0x0012 /* CD Input (stereo) */
208#define AC97_AUX_VOL 0x0016 /* Aux Input (stereo) */
209#define AC97_PCMOUT_VOL 0x0018 /* Wave Output (stereo) */
210#define AC97_RECORD_SELECT 0x001a /* */
211#define AC97_RECORD_GAIN 0x001c
212#define AC97_GENERAL_PURPOSE 0x0020
213#define AC97_3D_CONTROL 0x0022
214#define AC97_POWER_CONTROL 0x0026
215#define AC97_VENDOR_ID1 0x007c
216
202struct list_head cs4297a_devs = { &cs4297a_devs, &cs4297a_devs }; 217struct list_head cs4297a_devs = { &cs4297a_devs, &cs4297a_devs };
203 218
204typedef struct serdma_descr_s { 219typedef struct serdma_descr_s {
diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
index 643f1113b1d8..7e814a5c3677 100644
--- a/sound/oss/vwsnd.c
+++ b/sound/oss/vwsnd.c
@@ -438,7 +438,7 @@ static __inline__ void li_writeb(lithium_t *lith, int off, unsigned char val)
438 * 438 *
439 * Observe that (mask & -mask) is (1 << low_set_bit_of(mask)). 439 * Observe that (mask & -mask) is (1 << low_set_bit_of(mask)).
440 * As long as mask is constant, we trust the compiler will change the 440 * As long as mask is constant, we trust the compiler will change the
441 * multipy and divide into shifts. 441 * multiply and divide into shifts.
442 */ 442 */
443 443
444#define SHIFT_FIELD(val, mask) (((val) * ((mask) & -(mask))) & (mask)) 444#define SHIFT_FIELD(val, mask) (((val) * ((mask) & -(mask))) & (mask))
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 9dfc27bf6cc6..ee895f3c8605 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -1884,9 +1884,10 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec)
1884} 1884}
1885 1885
1886#ifdef CONFIG_PM 1886#ifdef CONFIG_PM
1887static int ali_suspend(struct pci_dev *pci, pm_message_t state) 1887static int ali_suspend(struct device *dev)
1888{ 1888{
1889 struct snd_card *card = pci_get_drvdata(pci); 1889 struct pci_dev *pci = to_pci_dev(dev);
1890 struct snd_card *card = dev_get_drvdata(dev);
1890 struct snd_ali *chip = card->private_data; 1891 struct snd_ali *chip = card->private_data;
1891 struct snd_ali_image *im; 1892 struct snd_ali_image *im;
1892 int i, j; 1893 int i, j;
@@ -1929,13 +1930,14 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state)
1929 1930
1930 pci_disable_device(pci); 1931 pci_disable_device(pci);
1931 pci_save_state(pci); 1932 pci_save_state(pci);
1932 pci_set_power_state(pci, pci_choose_state(pci, state)); 1933 pci_set_power_state(pci, PCI_D3hot);
1933 return 0; 1934 return 0;
1934} 1935}
1935 1936
1936static int ali_resume(struct pci_dev *pci) 1937static int ali_resume(struct device *dev)
1937{ 1938{
1938 struct snd_card *card = pci_get_drvdata(pci); 1939 struct pci_dev *pci = to_pci_dev(dev);
1940 struct snd_card *card = dev_get_drvdata(dev);
1939 struct snd_ali *chip = card->private_data; 1941 struct snd_ali *chip = card->private_data;
1940 struct snd_ali_image *im; 1942 struct snd_ali_image *im;
1941 int i, j; 1943 int i, j;
@@ -1982,6 +1984,11 @@ static int ali_resume(struct pci_dev *pci)
1982 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1984 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1983 return 0; 1985 return 0;
1984} 1986}
1987
1988static SIMPLE_DEV_PM_OPS(ali_pm, ali_suspend, ali_resume);
1989#define ALI_PM_OPS &ali_pm
1990#else
1991#define ALI_PM_OPS NULL
1985#endif /* CONFIG_PM */ 1992#endif /* CONFIG_PM */
1986 1993
1987static int snd_ali_free(struct snd_ali * codec) 1994static int snd_ali_free(struct snd_ali * codec)
@@ -2299,10 +2306,9 @@ static struct pci_driver ali5451_driver = {
2299 .id_table = snd_ali_ids, 2306 .id_table = snd_ali_ids,
2300 .probe = snd_ali_probe, 2307 .probe = snd_ali_probe,
2301 .remove = __devexit_p(snd_ali_remove), 2308 .remove = __devexit_p(snd_ali_remove),
2302#ifdef CONFIG_PM 2309 .driver = {
2303 .suspend = ali_suspend, 2310 .pm = ALI_PM_OPS,
2304 .resume = ali_resume, 2311 },
2305#endif
2306}; 2312};
2307 2313
2308module_pci_driver(ali5451_driver); 2314module_pci_driver(ali5451_driver);
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 59d65388faf5..68c4469c6d19 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -766,9 +766,10 @@ static int __devinit snd_als300_create(struct snd_card *card,
766} 766}
767 767
768#ifdef CONFIG_PM 768#ifdef CONFIG_PM
769static int snd_als300_suspend(struct pci_dev *pci, pm_message_t state) 769static int snd_als300_suspend(struct device *dev)
770{ 770{
771 struct snd_card *card = pci_get_drvdata(pci); 771 struct pci_dev *pci = to_pci_dev(dev);
772 struct snd_card *card = dev_get_drvdata(dev);
772 struct snd_als300 *chip = card->private_data; 773 struct snd_als300 *chip = card->private_data;
773 774
774 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 775 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -777,13 +778,14 @@ static int snd_als300_suspend(struct pci_dev *pci, pm_message_t state)
777 778
778 pci_disable_device(pci); 779 pci_disable_device(pci);
779 pci_save_state(pci); 780 pci_save_state(pci);
780 pci_set_power_state(pci, pci_choose_state(pci, state)); 781 pci_set_power_state(pci, PCI_D3hot);
781 return 0; 782 return 0;
782} 783}
783 784
784static int snd_als300_resume(struct pci_dev *pci) 785static int snd_als300_resume(struct device *dev)
785{ 786{
786 struct snd_card *card = pci_get_drvdata(pci); 787 struct pci_dev *pci = to_pci_dev(dev);
788 struct snd_card *card = dev_get_drvdata(dev);
787 struct snd_als300 *chip = card->private_data; 789 struct snd_als300 *chip = card->private_data;
788 790
789 pci_set_power_state(pci, PCI_D0); 791 pci_set_power_state(pci, PCI_D0);
@@ -802,6 +804,11 @@ static int snd_als300_resume(struct pci_dev *pci)
802 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 804 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
803 return 0; 805 return 0;
804} 806}
807
808static SIMPLE_DEV_PM_OPS(snd_als300_pm, snd_als300_suspend, snd_als300_resume);
809#define SND_ALS300_PM_OPS &snd_als300_pm
810#else
811#define SND_ALS300_PM_OPS NULL
805#endif 812#endif
806 813
807static int __devinit snd_als300_probe(struct pci_dev *pci, 814static int __devinit snd_als300_probe(struct pci_dev *pci,
@@ -857,10 +864,9 @@ static struct pci_driver als300_driver = {
857 .id_table = snd_als300_ids, 864 .id_table = snd_als300_ids,
858 .probe = snd_als300_probe, 865 .probe = snd_als300_probe,
859 .remove = __devexit_p(snd_als300_remove), 866 .remove = __devexit_p(snd_als300_remove),
860#ifdef CONFIG_PM 867 .driver = {
861 .suspend = snd_als300_suspend, 868 .pm = SND_ALS300_PM_OPS,
862 .resume = snd_als300_resume, 869 },
863#endif
864}; 870};
865 871
866module_pci_driver(als300_driver); 872module_pci_driver(als300_driver);
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 7d7f2598c748..0eeca49c5754 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -988,9 +988,10 @@ static void __devexit snd_card_als4000_remove(struct pci_dev *pci)
988} 988}
989 989
990#ifdef CONFIG_PM 990#ifdef CONFIG_PM
991static int snd_als4000_suspend(struct pci_dev *pci, pm_message_t state) 991static int snd_als4000_suspend(struct device *dev)
992{ 992{
993 struct snd_card *card = pci_get_drvdata(pci); 993 struct pci_dev *pci = to_pci_dev(dev);
994 struct snd_card *card = dev_get_drvdata(dev);
994 struct snd_card_als4000 *acard = card->private_data; 995 struct snd_card_als4000 *acard = card->private_data;
995 struct snd_sb *chip = acard->chip; 996 struct snd_sb *chip = acard->chip;
996 997
@@ -1001,13 +1002,14 @@ static int snd_als4000_suspend(struct pci_dev *pci, pm_message_t state)
1001 1002
1002 pci_disable_device(pci); 1003 pci_disable_device(pci);
1003 pci_save_state(pci); 1004 pci_save_state(pci);
1004 pci_set_power_state(pci, pci_choose_state(pci, state)); 1005 pci_set_power_state(pci, PCI_D3hot);
1005 return 0; 1006 return 0;
1006} 1007}
1007 1008
1008static int snd_als4000_resume(struct pci_dev *pci) 1009static int snd_als4000_resume(struct device *dev)
1009{ 1010{
1010 struct snd_card *card = pci_get_drvdata(pci); 1011 struct pci_dev *pci = to_pci_dev(dev);
1012 struct snd_card *card = dev_get_drvdata(dev);
1011 struct snd_card_als4000 *acard = card->private_data; 1013 struct snd_card_als4000 *acard = card->private_data;
1012 struct snd_sb *chip = acard->chip; 1014 struct snd_sb *chip = acard->chip;
1013 1015
@@ -1033,18 +1035,21 @@ static int snd_als4000_resume(struct pci_dev *pci)
1033 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1035 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1034 return 0; 1036 return 0;
1035} 1037}
1036#endif /* CONFIG_PM */
1037 1038
1039static SIMPLE_DEV_PM_OPS(snd_als4000_pm, snd_als4000_suspend, snd_als4000_resume);
1040#define SND_ALS4000_PM_OPS &snd_als4000_pm
1041#else
1042#define SND_ALS4000_PM_OPS NULL
1043#endif /* CONFIG_PM */
1038 1044
1039static struct pci_driver als4000_driver = { 1045static struct pci_driver als4000_driver = {
1040 .name = KBUILD_MODNAME, 1046 .name = KBUILD_MODNAME,
1041 .id_table = snd_als4000_ids, 1047 .id_table = snd_als4000_ids,
1042 .probe = snd_card_als4000_probe, 1048 .probe = snd_card_als4000_probe,
1043 .remove = __devexit_p(snd_card_als4000_remove), 1049 .remove = __devexit_p(snd_card_als4000_remove),
1044#ifdef CONFIG_PM 1050 .driver = {
1045 .suspend = snd_als4000_suspend, 1051 .pm = SND_ALS4000_PM_OPS,
1046 .resume = snd_als4000_resume, 1052 },
1047#endif
1048}; 1053};
1049 1054
1050module_pci_driver(als4000_driver); 1055module_pci_driver(als4000_driver);
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 156a94f8a123..31020d2a868b 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1462,9 +1462,10 @@ static int __devinit snd_atiixp_mixer_new(struct atiixp *chip, int clock,
1462/* 1462/*
1463 * power management 1463 * power management
1464 */ 1464 */
1465static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state) 1465static int snd_atiixp_suspend(struct device *dev)
1466{ 1466{
1467 struct snd_card *card = pci_get_drvdata(pci); 1467 struct pci_dev *pci = to_pci_dev(dev);
1468 struct snd_card *card = dev_get_drvdata(dev);
1468 struct atiixp *chip = card->private_data; 1469 struct atiixp *chip = card->private_data;
1469 int i; 1470 int i;
1470 1471
@@ -1484,13 +1485,14 @@ static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state)
1484 1485
1485 pci_disable_device(pci); 1486 pci_disable_device(pci);
1486 pci_save_state(pci); 1487 pci_save_state(pci);
1487 pci_set_power_state(pci, pci_choose_state(pci, state)); 1488 pci_set_power_state(pci, PCI_D3hot);
1488 return 0; 1489 return 0;
1489} 1490}
1490 1491
1491static int snd_atiixp_resume(struct pci_dev *pci) 1492static int snd_atiixp_resume(struct device *dev)
1492{ 1493{
1493 struct snd_card *card = pci_get_drvdata(pci); 1494 struct pci_dev *pci = to_pci_dev(dev);
1495 struct snd_card *card = dev_get_drvdata(dev);
1494 struct atiixp *chip = card->private_data; 1496 struct atiixp *chip = card->private_data;
1495 int i; 1497 int i;
1496 1498
@@ -1526,6 +1528,11 @@ static int snd_atiixp_resume(struct pci_dev *pci)
1526 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1528 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1527 return 0; 1529 return 0;
1528} 1530}
1531
1532static SIMPLE_DEV_PM_OPS(snd_atiixp_pm, snd_atiixp_suspend, snd_atiixp_resume);
1533#define SND_ATIIXP_PM_OPS &snd_atiixp_pm
1534#else
1535#define SND_ATIIXP_PM_OPS NULL
1529#endif /* CONFIG_PM */ 1536#endif /* CONFIG_PM */
1530 1537
1531 1538
@@ -1705,10 +1712,9 @@ static struct pci_driver atiixp_driver = {
1705 .id_table = snd_atiixp_ids, 1712 .id_table = snd_atiixp_ids,
1706 .probe = snd_atiixp_probe, 1713 .probe = snd_atiixp_probe,
1707 .remove = __devexit_p(snd_atiixp_remove), 1714 .remove = __devexit_p(snd_atiixp_remove),
1708#ifdef CONFIG_PM 1715 .driver = {
1709 .suspend = snd_atiixp_suspend, 1716 .pm = SND_ATIIXP_PM_OPS,
1710 .resume = snd_atiixp_resume, 1717 },
1711#endif
1712}; 1718};
1713 1719
1714module_pci_driver(atiixp_driver); 1720module_pci_driver(atiixp_driver);
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 30a4fd96ce73..79e204ec623f 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1117,9 +1117,10 @@ static int __devinit snd_atiixp_mixer_new(struct atiixp_modem *chip, int clock)
1117/* 1117/*
1118 * power management 1118 * power management
1119 */ 1119 */
1120static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state) 1120static int snd_atiixp_suspend(struct device *dev)
1121{ 1121{
1122 struct snd_card *card = pci_get_drvdata(pci); 1122 struct pci_dev *pci = to_pci_dev(dev);
1123 struct snd_card *card = dev_get_drvdata(dev);
1123 struct atiixp_modem *chip = card->private_data; 1124 struct atiixp_modem *chip = card->private_data;
1124 int i; 1125 int i;
1125 1126
@@ -1133,13 +1134,14 @@ static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state)
1133 1134
1134 pci_disable_device(pci); 1135 pci_disable_device(pci);
1135 pci_save_state(pci); 1136 pci_save_state(pci);
1136 pci_set_power_state(pci, pci_choose_state(pci, state)); 1137 pci_set_power_state(pci, PCI_D3hot);
1137 return 0; 1138 return 0;
1138} 1139}
1139 1140
1140static int snd_atiixp_resume(struct pci_dev *pci) 1141static int snd_atiixp_resume(struct device *dev)
1141{ 1142{
1142 struct snd_card *card = pci_get_drvdata(pci); 1143 struct pci_dev *pci = to_pci_dev(dev);
1144 struct snd_card *card = dev_get_drvdata(dev);
1143 struct atiixp_modem *chip = card->private_data; 1145 struct atiixp_modem *chip = card->private_data;
1144 int i; 1146 int i;
1145 1147
@@ -1162,8 +1164,12 @@ static int snd_atiixp_resume(struct pci_dev *pci)
1162 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1164 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1163 return 0; 1165 return 0;
1164} 1166}
1165#endif /* CONFIG_PM */
1166 1167
1168static SIMPLE_DEV_PM_OPS(snd_atiixp_pm, snd_atiixp_suspend, snd_atiixp_resume);
1169#define SND_ATIIXP_PM_OPS &snd_atiixp_pm
1170#else
1171#define SND_ATIIXP_PM_OPS NULL
1172#endif /* CONFIG_PM */
1167 1173
1168#ifdef CONFIG_PROC_FS 1174#ifdef CONFIG_PROC_FS
1169/* 1175/*
@@ -1336,10 +1342,9 @@ static struct pci_driver atiixp_modem_driver = {
1336 .id_table = snd_atiixp_ids, 1342 .id_table = snd_atiixp_ids,
1337 .probe = snd_atiixp_probe, 1343 .probe = snd_atiixp_probe,
1338 .remove = __devexit_p(snd_atiixp_remove), 1344 .remove = __devexit_p(snd_atiixp_remove),
1339#ifdef CONFIG_PM 1345 .driver = {
1340 .suspend = snd_atiixp_suspend, 1346 .pm = SND_ATIIXP_PM_OPS,
1341 .resume = snd_atiixp_resume, 1347 },
1342#endif
1343}; 1348};
1344 1349
1345module_pci_driver(atiixp_modem_driver); 1350module_pci_driver(atiixp_modem_driver);
diff --git a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c
index 557c782ae4fc..fa13efbebdaf 100644
--- a/sound/pci/au88x0/au88x0_mixer.c
+++ b/sound/pci/au88x0/au88x0_mixer.c
@@ -10,6 +10,15 @@
10#include <sound/core.h> 10#include <sound/core.h>
11#include "au88x0.h" 11#include "au88x0.h"
12 12
13static int remove_ctl(struct snd_card *card, const char *name)
14{
15 struct snd_ctl_elem_id id;
16 memset(&id, 0, sizeof(id));
17 strcpy(id.name, name);
18 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
19 return snd_ctl_remove_id(card, &id);
20}
21
13static int __devinit snd_vortex_mixer(vortex_t * vortex) 22static int __devinit snd_vortex_mixer(vortex_t * vortex)
14{ 23{
15 struct snd_ac97_bus *pbus; 24 struct snd_ac97_bus *pbus;
@@ -28,5 +37,7 @@ static int __devinit snd_vortex_mixer(vortex_t * vortex)
28 ac97.scaps = AC97_SCAP_NO_SPDIF; 37 ac97.scaps = AC97_SCAP_NO_SPDIF;
29 err = snd_ac97_mixer(pbus, &ac97, &vortex->codec); 38 err = snd_ac97_mixer(pbus, &ac97, &vortex->codec);
30 vortex->isquad = ((vortex->codec == NULL) ? 0 : (vortex->codec->ext_id&0x80)); 39 vortex->isquad = ((vortex->codec == NULL) ? 0 : (vortex->codec->ext_id&0x80));
40 remove_ctl(vortex->card, "Master Mono Playback Volume");
41 remove_ctl(vortex->card, "Master Mono Playback Switch");
31 return err; 42 return err;
32} 43}
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index f0b4d7493af5..4dddd871548b 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -2794,9 +2794,10 @@ snd_azf3328_resume_ac97(const struct snd_azf3328 *chip)
2794} 2794}
2795 2795
2796static int 2796static int
2797snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state) 2797snd_azf3328_suspend(struct device *dev)
2798{ 2798{
2799 struct snd_card *card = pci_get_drvdata(pci); 2799 struct pci_dev *pci = to_pci_dev(dev);
2800 struct snd_card *card = dev_get_drvdata(dev);
2800 struct snd_azf3328 *chip = card->private_data; 2801 struct snd_azf3328 *chip = card->private_data;
2801 u16 *saved_regs_ctrl_u16; 2802 u16 *saved_regs_ctrl_u16;
2802 2803
@@ -2824,14 +2825,15 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2824 2825
2825 pci_disable_device(pci); 2826 pci_disable_device(pci);
2826 pci_save_state(pci); 2827 pci_save_state(pci);
2827 pci_set_power_state(pci, pci_choose_state(pci, state)); 2828 pci_set_power_state(pci, PCI_D3hot);
2828 return 0; 2829 return 0;
2829} 2830}
2830 2831
2831static int 2832static int
2832snd_azf3328_resume(struct pci_dev *pci) 2833snd_azf3328_resume(struct device *dev)
2833{ 2834{
2834 struct snd_card *card = pci_get_drvdata(pci); 2835 struct pci_dev *pci = to_pci_dev(dev);
2836 struct snd_card *card = dev_get_drvdata(dev);
2835 const struct snd_azf3328 *chip = card->private_data; 2837 const struct snd_azf3328 *chip = card->private_data;
2836 2838
2837 pci_set_power_state(pci, PCI_D0); 2839 pci_set_power_state(pci, PCI_D0);
@@ -2859,18 +2861,21 @@ snd_azf3328_resume(struct pci_dev *pci)
2859 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2861 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2860 return 0; 2862 return 0;
2861} 2863}
2862#endif /* CONFIG_PM */
2863 2864
2865static SIMPLE_DEV_PM_OPS(snd_azf3328_pm, snd_azf3328_suspend, snd_azf3328_resume);
2866#define SND_AZF3328_PM_OPS &snd_azf3328_pm
2867#else
2868#define SND_AZF3328_PM_OPS NULL
2869#endif /* CONFIG_PM */
2864 2870
2865static struct pci_driver azf3328_driver = { 2871static struct pci_driver azf3328_driver = {
2866 .name = KBUILD_MODNAME, 2872 .name = KBUILD_MODNAME,
2867 .id_table = snd_azf3328_ids, 2873 .id_table = snd_azf3328_ids,
2868 .probe = snd_azf3328_probe, 2874 .probe = snd_azf3328_probe,
2869 .remove = __devexit_p(snd_azf3328_remove), 2875 .remove = __devexit_p(snd_azf3328_remove),
2870#ifdef CONFIG_PM 2876 .driver = {
2871 .suspend = snd_azf3328_suspend, 2877 .pm = SND_AZF3328_PM_OPS,
2872 .resume = snd_azf3328_resume, 2878 },
2873#endif
2874}; 2879};
2875 2880
2876module_pci_driver(azf3328_driver); 2881module_pci_driver(azf3328_driver);
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index e76d68a7081f..83277b747b36 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1872,9 +1872,10 @@ static void __devexit snd_ca0106_remove(struct pci_dev *pci)
1872} 1872}
1873 1873
1874#ifdef CONFIG_PM 1874#ifdef CONFIG_PM
1875static int snd_ca0106_suspend(struct pci_dev *pci, pm_message_t state) 1875static int snd_ca0106_suspend(struct device *dev)
1876{ 1876{
1877 struct snd_card *card = pci_get_drvdata(pci); 1877 struct pci_dev *pci = to_pci_dev(dev);
1878 struct snd_card *card = dev_get_drvdata(dev);
1878 struct snd_ca0106 *chip = card->private_data; 1879 struct snd_ca0106 *chip = card->private_data;
1879 int i; 1880 int i;
1880 1881
@@ -1889,13 +1890,14 @@ static int snd_ca0106_suspend(struct pci_dev *pci, pm_message_t state)
1889 1890
1890 pci_disable_device(pci); 1891 pci_disable_device(pci);
1891 pci_save_state(pci); 1892 pci_save_state(pci);
1892 pci_set_power_state(pci, pci_choose_state(pci, state)); 1893 pci_set_power_state(pci, PCI_D3hot);
1893 return 0; 1894 return 0;
1894} 1895}
1895 1896
1896static int snd_ca0106_resume(struct pci_dev *pci) 1897static int snd_ca0106_resume(struct device *dev)
1897{ 1898{
1898 struct snd_card *card = pci_get_drvdata(pci); 1899 struct pci_dev *pci = to_pci_dev(dev);
1900 struct snd_card *card = dev_get_drvdata(dev);
1899 struct snd_ca0106 *chip = card->private_data; 1901 struct snd_ca0106 *chip = card->private_data;
1900 int i; 1902 int i;
1901 1903
@@ -1922,6 +1924,11 @@ static int snd_ca0106_resume(struct pci_dev *pci)
1922 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1924 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1923 return 0; 1925 return 0;
1924} 1926}
1927
1928static SIMPLE_DEV_PM_OPS(snd_ca0106_pm, snd_ca0106_suspend, snd_ca0106_resume);
1929#define SND_CA0106_PM_OPS &snd_ca0106_pm
1930#else
1931#define SND_CA0106_PM_OPS NULL
1925#endif 1932#endif
1926 1933
1927// PCI IDs 1934// PCI IDs
@@ -1937,10 +1944,9 @@ static struct pci_driver ca0106_driver = {
1937 .id_table = snd_ca0106_ids, 1944 .id_table = snd_ca0106_ids,
1938 .probe = snd_ca0106_probe, 1945 .probe = snd_ca0106_probe,
1939 .remove = __devexit_p(snd_ca0106_remove), 1946 .remove = __devexit_p(snd_ca0106_remove),
1940#ifdef CONFIG_PM 1947 .driver = {
1941 .suspend = snd_ca0106_suspend, 1948 .pm = SND_CA0106_PM_OPS,
1942 .resume = snd_ca0106_resume, 1949 },
1943#endif
1944}; 1950};
1945 1951
1946module_pci_driver(ca0106_driver); 1952module_pci_driver(ca0106_driver);
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 3815bd4c6779..b7d6f2b886ef 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -3338,9 +3338,10 @@ static unsigned char saved_mixers[] = {
3338 SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 3338 SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT,
3339}; 3339};
3340 3340
3341static int snd_cmipci_suspend(struct pci_dev *pci, pm_message_t state) 3341static int snd_cmipci_suspend(struct device *dev)
3342{ 3342{
3343 struct snd_card *card = pci_get_drvdata(pci); 3343 struct pci_dev *pci = to_pci_dev(dev);
3344 struct snd_card *card = dev_get_drvdata(dev);
3344 struct cmipci *cm = card->private_data; 3345 struct cmipci *cm = card->private_data;
3345 int i; 3346 int i;
3346 3347
@@ -3361,13 +3362,14 @@ static int snd_cmipci_suspend(struct pci_dev *pci, pm_message_t state)
3361 3362
3362 pci_disable_device(pci); 3363 pci_disable_device(pci);
3363 pci_save_state(pci); 3364 pci_save_state(pci);
3364 pci_set_power_state(pci, pci_choose_state(pci, state)); 3365 pci_set_power_state(pci, PCI_D3hot);
3365 return 0; 3366 return 0;
3366} 3367}
3367 3368
3368static int snd_cmipci_resume(struct pci_dev *pci) 3369static int snd_cmipci_resume(struct device *dev)
3369{ 3370{
3370 struct snd_card *card = pci_get_drvdata(pci); 3371 struct pci_dev *pci = to_pci_dev(dev);
3372 struct snd_card *card = dev_get_drvdata(dev);
3371 struct cmipci *cm = card->private_data; 3373 struct cmipci *cm = card->private_data;
3372 int i; 3374 int i;
3373 3375
@@ -3396,6 +3398,11 @@ static int snd_cmipci_resume(struct pci_dev *pci)
3396 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 3398 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
3397 return 0; 3399 return 0;
3398} 3400}
3401
3402static SIMPLE_DEV_PM_OPS(snd_cmipci_pm, snd_cmipci_suspend, snd_cmipci_resume);
3403#define SND_CMIPCI_PM_OPS &snd_cmipci_pm
3404#else
3405#define SND_CMIPCI_PM_OPS NULL
3399#endif /* CONFIG_PM */ 3406#endif /* CONFIG_PM */
3400 3407
3401static struct pci_driver cmipci_driver = { 3408static struct pci_driver cmipci_driver = {
@@ -3403,10 +3410,9 @@ static struct pci_driver cmipci_driver = {
3403 .id_table = snd_cmipci_ids, 3410 .id_table = snd_cmipci_ids,
3404 .probe = snd_cmipci_probe, 3411 .probe = snd_cmipci_probe,
3405 .remove = __devexit_p(snd_cmipci_remove), 3412 .remove = __devexit_p(snd_cmipci_remove),
3406#ifdef CONFIG_PM 3413 .driver = {
3407 .suspend = snd_cmipci_suspend, 3414 .pm = SND_CMIPCI_PM_OPS,
3408 .resume = snd_cmipci_resume, 3415 },
3409#endif
3410}; 3416};
3411 3417
3412module_pci_driver(cmipci_driver); 3418module_pci_driver(cmipci_driver);
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 33506ee569bd..45a8317085f4 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1997,9 +1997,10 @@ static int saved_regs[SUSPEND_REGISTERS] = {
1997 1997
1998#define CLKCR1_CKRA 0x00010000L 1998#define CLKCR1_CKRA 0x00010000L
1999 1999
2000static int cs4281_suspend(struct pci_dev *pci, pm_message_t state) 2000static int cs4281_suspend(struct device *dev)
2001{ 2001{
2002 struct snd_card *card = pci_get_drvdata(pci); 2002 struct pci_dev *pci = to_pci_dev(dev);
2003 struct snd_card *card = dev_get_drvdata(dev);
2003 struct cs4281 *chip = card->private_data; 2004 struct cs4281 *chip = card->private_data;
2004 u32 ulCLK; 2005 u32 ulCLK;
2005 unsigned int i; 2006 unsigned int i;
@@ -2040,13 +2041,14 @@ static int cs4281_suspend(struct pci_dev *pci, pm_message_t state)
2040 2041
2041 pci_disable_device(pci); 2042 pci_disable_device(pci);
2042 pci_save_state(pci); 2043 pci_save_state(pci);
2043 pci_set_power_state(pci, pci_choose_state(pci, state)); 2044 pci_set_power_state(pci, PCI_D3hot);
2044 return 0; 2045 return 0;
2045} 2046}
2046 2047
2047static int cs4281_resume(struct pci_dev *pci) 2048static int cs4281_resume(struct device *dev)
2048{ 2049{
2049 struct snd_card *card = pci_get_drvdata(pci); 2050 struct pci_dev *pci = to_pci_dev(dev);
2051 struct snd_card *card = dev_get_drvdata(dev);
2050 struct cs4281 *chip = card->private_data; 2052 struct cs4281 *chip = card->private_data;
2051 unsigned int i; 2053 unsigned int i;
2052 u32 ulCLK; 2054 u32 ulCLK;
@@ -2082,6 +2084,11 @@ static int cs4281_resume(struct pci_dev *pci)
2082 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2084 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2083 return 0; 2085 return 0;
2084} 2086}
2087
2088static SIMPLE_DEV_PM_OPS(cs4281_pm, cs4281_suspend, cs4281_resume);
2089#define CS4281_PM_OPS &cs4281_pm
2090#else
2091#define CS4281_PM_OPS NULL
2085#endif /* CONFIG_PM */ 2092#endif /* CONFIG_PM */
2086 2093
2087static struct pci_driver cs4281_driver = { 2094static struct pci_driver cs4281_driver = {
@@ -2089,10 +2096,9 @@ static struct pci_driver cs4281_driver = {
2089 .id_table = snd_cs4281_ids, 2096 .id_table = snd_cs4281_ids,
2090 .probe = snd_cs4281_probe, 2097 .probe = snd_cs4281_probe,
2091 .remove = __devexit_p(snd_cs4281_remove), 2098 .remove = __devexit_p(snd_cs4281_remove),
2092#ifdef CONFIG_PM 2099 .driver = {
2093 .suspend = cs4281_suspend, 2100 .pm = CS4281_PM_OPS,
2094 .resume = cs4281_resume, 2101 },
2095#endif
2096}; 2102};
2097 2103
2098module_pci_driver(cs4281_driver); 2104module_pci_driver(cs4281_driver);
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index 6cc7404e0e8f..1e007c736a8b 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -30,7 +30,7 @@
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <sound/core.h> 32#include <sound/core.h>
33#include <sound/cs46xx.h> 33#include "cs46xx.h"
34#include <sound/initval.h> 34#include <sound/initval.h>
35 35
36MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 36MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
@@ -167,8 +167,9 @@ static struct pci_driver cs46xx_driver = {
167 .probe = snd_card_cs46xx_probe, 167 .probe = snd_card_cs46xx_probe,
168 .remove = __devexit_p(snd_card_cs46xx_remove), 168 .remove = __devexit_p(snd_card_cs46xx_remove),
169#ifdef CONFIG_PM 169#ifdef CONFIG_PM
170 .suspend = snd_cs46xx_suspend, 170 .driver = {
171 .resume = snd_cs46xx_resume, 171 .pm = &snd_cs46xx_pm,
172 },
172#endif 173#endif
173}; 174};
174 175
diff --git a/sound/pci/cs46xx/cs46xx.h b/sound/pci/cs46xx/cs46xx.h
new file mode 100644
index 000000000000..29d8a8da1ba7
--- /dev/null
+++ b/sound/pci/cs46xx/cs46xx.h
@@ -0,0 +1,1744 @@
1#ifndef __SOUND_CS46XX_H
2#define __SOUND_CS46XX_H
3
4/*
5 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
6 * Cirrus Logic, Inc.
7 * Definitions for Cirrus Logic CS46xx chips
8 *
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 as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26#include <sound/pcm.h>
27#include <sound/pcm-indirect.h>
28#include <sound/rawmidi.h>
29#include <sound/ac97_codec.h>
30#include "cs46xx_dsp_spos.h"
31
32/*
33 * Direct registers
34 */
35
36/*
37 * The following define the offsets of the registers accessed via base address
38 * register zero on the CS46xx part.
39 */
40#define BA0_HISR 0x00000000
41#define BA0_HSR0 0x00000004
42#define BA0_HICR 0x00000008
43#define BA0_DMSR 0x00000100
44#define BA0_HSAR 0x00000110
45#define BA0_HDAR 0x00000114
46#define BA0_HDMR 0x00000118
47#define BA0_HDCR 0x0000011C
48#define BA0_PFMC 0x00000200
49#define BA0_PFCV1 0x00000204
50#define BA0_PFCV2 0x00000208
51#define BA0_PCICFG00 0x00000300
52#define BA0_PCICFG04 0x00000304
53#define BA0_PCICFG08 0x00000308
54#define BA0_PCICFG0C 0x0000030C
55#define BA0_PCICFG10 0x00000310
56#define BA0_PCICFG14 0x00000314
57#define BA0_PCICFG18 0x00000318
58#define BA0_PCICFG1C 0x0000031C
59#define BA0_PCICFG20 0x00000320
60#define BA0_PCICFG24 0x00000324
61#define BA0_PCICFG28 0x00000328
62#define BA0_PCICFG2C 0x0000032C
63#define BA0_PCICFG30 0x00000330
64#define BA0_PCICFG34 0x00000334
65#define BA0_PCICFG38 0x00000338
66#define BA0_PCICFG3C 0x0000033C
67#define BA0_CLKCR1 0x00000400
68#define BA0_CLKCR2 0x00000404
69#define BA0_PLLM 0x00000408
70#define BA0_PLLCC 0x0000040C
71#define BA0_FRR 0x00000410
72#define BA0_CFL1 0x00000414
73#define BA0_CFL2 0x00000418
74#define BA0_SERMC1 0x00000420
75#define BA0_SERMC2 0x00000424
76#define BA0_SERC1 0x00000428
77#define BA0_SERC2 0x0000042C
78#define BA0_SERC3 0x00000430
79#define BA0_SERC4 0x00000434
80#define BA0_SERC5 0x00000438
81#define BA0_SERBSP 0x0000043C
82#define BA0_SERBST 0x00000440
83#define BA0_SERBCM 0x00000444
84#define BA0_SERBAD 0x00000448
85#define BA0_SERBCF 0x0000044C
86#define BA0_SERBWP 0x00000450
87#define BA0_SERBRP 0x00000454
88#ifndef NO_CS4612
89#define BA0_ASER_FADDR 0x00000458
90#endif
91#define BA0_ACCTL 0x00000460
92#define BA0_ACSTS 0x00000464
93#define BA0_ACOSV 0x00000468
94#define BA0_ACCAD 0x0000046C
95#define BA0_ACCDA 0x00000470
96#define BA0_ACISV 0x00000474
97#define BA0_ACSAD 0x00000478
98#define BA0_ACSDA 0x0000047C
99#define BA0_JSPT 0x00000480
100#define BA0_JSCTL 0x00000484
101#define BA0_JSC1 0x00000488
102#define BA0_JSC2 0x0000048C
103#define BA0_MIDCR 0x00000490
104#define BA0_MIDSR 0x00000494
105#define BA0_MIDWP 0x00000498
106#define BA0_MIDRP 0x0000049C
107#define BA0_JSIO 0x000004A0
108#ifndef NO_CS4612
109#define BA0_ASER_MASTER 0x000004A4
110#endif
111#define BA0_CFGI 0x000004B0
112#define BA0_SSVID 0x000004B4
113#define BA0_GPIOR 0x000004B8
114#ifndef NO_CS4612
115#define BA0_EGPIODR 0x000004BC
116#define BA0_EGPIOPTR 0x000004C0
117#define BA0_EGPIOTR 0x000004C4
118#define BA0_EGPIOWR 0x000004C8
119#define BA0_EGPIOSR 0x000004CC
120#define BA0_SERC6 0x000004D0
121#define BA0_SERC7 0x000004D4
122#define BA0_SERACC 0x000004D8
123#define BA0_ACCTL2 0x000004E0
124#define BA0_ACSTS2 0x000004E4
125#define BA0_ACOSV2 0x000004E8
126#define BA0_ACCAD2 0x000004EC
127#define BA0_ACCDA2 0x000004F0
128#define BA0_ACISV2 0x000004F4
129#define BA0_ACSAD2 0x000004F8
130#define BA0_ACSDA2 0x000004FC
131#define BA0_IOTAC0 0x00000500
132#define BA0_IOTAC1 0x00000504
133#define BA0_IOTAC2 0x00000508
134#define BA0_IOTAC3 0x0000050C
135#define BA0_IOTAC4 0x00000510
136#define BA0_IOTAC5 0x00000514
137#define BA0_IOTAC6 0x00000518
138#define BA0_IOTAC7 0x0000051C
139#define BA0_IOTAC8 0x00000520
140#define BA0_IOTAC9 0x00000524
141#define BA0_IOTAC10 0x00000528
142#define BA0_IOTAC11 0x0000052C
143#define BA0_IOTFR0 0x00000540
144#define BA0_IOTFR1 0x00000544
145#define BA0_IOTFR2 0x00000548
146#define BA0_IOTFR3 0x0000054C
147#define BA0_IOTFR4 0x00000550
148#define BA0_IOTFR5 0x00000554
149#define BA0_IOTFR6 0x00000558
150#define BA0_IOTFR7 0x0000055C
151#define BA0_IOTFIFO 0x00000580
152#define BA0_IOTRRD 0x00000584
153#define BA0_IOTFP 0x00000588
154#define BA0_IOTCR 0x0000058C
155#define BA0_DPCID 0x00000590
156#define BA0_DPCIA 0x00000594
157#define BA0_DPCIC 0x00000598
158#define BA0_PCPCIR 0x00000600
159#define BA0_PCPCIG 0x00000604
160#define BA0_PCPCIEN 0x00000608
161#define BA0_EPCIPMC 0x00000610
162#endif
163
164/*
165 * The following define the offsets of the registers and memories accessed via
166 * base address register one on the CS46xx part.
167 */
168#define BA1_SP_DMEM0 0x00000000
169#define BA1_SP_DMEM1 0x00010000
170#define BA1_SP_PMEM 0x00020000
171#define BA1_SP_REG 0x00030000
172#define BA1_SPCR 0x00030000
173#define BA1_DREG 0x00030004
174#define BA1_DSRWP 0x00030008
175#define BA1_TWPR 0x0003000C
176#define BA1_SPWR 0x00030010
177#define BA1_SPIR 0x00030014
178#define BA1_FGR1 0x00030020
179#define BA1_SPCS 0x00030028
180#define BA1_SDSR 0x0003002C
181#define BA1_FRMT 0x00030030
182#define BA1_FRCC 0x00030034
183#define BA1_FRSC 0x00030038
184#define BA1_OMNI_MEM 0x000E0000
185
186
187/*
188 * The following defines are for the flags in the host interrupt status
189 * register.
190 */
191#define HISR_VC_MASK 0x0000FFFF
192#define HISR_VC0 0x00000001
193#define HISR_VC1 0x00000002
194#define HISR_VC2 0x00000004
195#define HISR_VC3 0x00000008
196#define HISR_VC4 0x00000010
197#define HISR_VC5 0x00000020
198#define HISR_VC6 0x00000040
199#define HISR_VC7 0x00000080
200#define HISR_VC8 0x00000100
201#define HISR_VC9 0x00000200
202#define HISR_VC10 0x00000400
203#define HISR_VC11 0x00000800
204#define HISR_VC12 0x00001000
205#define HISR_VC13 0x00002000
206#define HISR_VC14 0x00004000
207#define HISR_VC15 0x00008000
208#define HISR_INT0 0x00010000
209#define HISR_INT1 0x00020000
210#define HISR_DMAI 0x00040000
211#define HISR_FROVR 0x00080000
212#define HISR_MIDI 0x00100000
213#ifdef NO_CS4612
214#define HISR_RESERVED 0x0FE00000
215#else
216#define HISR_SBINT 0x00200000
217#define HISR_RESERVED 0x0FC00000
218#endif
219#define HISR_H0P 0x40000000
220#define HISR_INTENA 0x80000000
221
222/*
223 * The following defines are for the flags in the host signal register 0.
224 */
225#define HSR0_VC_MASK 0xFFFFFFFF
226#define HSR0_VC16 0x00000001
227#define HSR0_VC17 0x00000002
228#define HSR0_VC18 0x00000004
229#define HSR0_VC19 0x00000008
230#define HSR0_VC20 0x00000010
231#define HSR0_VC21 0x00000020
232#define HSR0_VC22 0x00000040
233#define HSR0_VC23 0x00000080
234#define HSR0_VC24 0x00000100
235#define HSR0_VC25 0x00000200
236#define HSR0_VC26 0x00000400
237#define HSR0_VC27 0x00000800
238#define HSR0_VC28 0x00001000
239#define HSR0_VC29 0x00002000
240#define HSR0_VC30 0x00004000
241#define HSR0_VC31 0x00008000
242#define HSR0_VC32 0x00010000
243#define HSR0_VC33 0x00020000
244#define HSR0_VC34 0x00040000
245#define HSR0_VC35 0x00080000
246#define HSR0_VC36 0x00100000
247#define HSR0_VC37 0x00200000
248#define HSR0_VC38 0x00400000
249#define HSR0_VC39 0x00800000
250#define HSR0_VC40 0x01000000
251#define HSR0_VC41 0x02000000
252#define HSR0_VC42 0x04000000
253#define HSR0_VC43 0x08000000
254#define HSR0_VC44 0x10000000
255#define HSR0_VC45 0x20000000
256#define HSR0_VC46 0x40000000
257#define HSR0_VC47 0x80000000
258
259/*
260 * The following defines are for the flags in the host interrupt control
261 * register.
262 */
263#define HICR_IEV 0x00000001
264#define HICR_CHGM 0x00000002
265
266/*
267 * The following defines are for the flags in the DMA status register.
268 */
269#define DMSR_HP 0x00000001
270#define DMSR_HR 0x00000002
271#define DMSR_SP 0x00000004
272#define DMSR_SR 0x00000008
273
274/*
275 * The following defines are for the flags in the host DMA source address
276 * register.
277 */
278#define HSAR_HOST_ADDR_MASK 0xFFFFFFFF
279#define HSAR_DSP_ADDR_MASK 0x0000FFFF
280#define HSAR_MEMID_MASK 0x000F0000
281#define HSAR_MEMID_SP_DMEM0 0x00000000
282#define HSAR_MEMID_SP_DMEM1 0x00010000
283#define HSAR_MEMID_SP_PMEM 0x00020000
284#define HSAR_MEMID_SP_DEBUG 0x00030000
285#define HSAR_MEMID_OMNI_MEM 0x000E0000
286#define HSAR_END 0x40000000
287#define HSAR_ERR 0x80000000
288
289/*
290 * The following defines are for the flags in the host DMA destination address
291 * register.
292 */
293#define HDAR_HOST_ADDR_MASK 0xFFFFFFFF
294#define HDAR_DSP_ADDR_MASK 0x0000FFFF
295#define HDAR_MEMID_MASK 0x000F0000
296#define HDAR_MEMID_SP_DMEM0 0x00000000
297#define HDAR_MEMID_SP_DMEM1 0x00010000
298#define HDAR_MEMID_SP_PMEM 0x00020000
299#define HDAR_MEMID_SP_DEBUG 0x00030000
300#define HDAR_MEMID_OMNI_MEM 0x000E0000
301#define HDAR_END 0x40000000
302#define HDAR_ERR 0x80000000
303
304/*
305 * The following defines are for the flags in the host DMA control register.
306 */
307#define HDMR_AC_MASK 0x0000F000
308#define HDMR_AC_8_16 0x00001000
309#define HDMR_AC_M_S 0x00002000
310#define HDMR_AC_B_L 0x00004000
311#define HDMR_AC_S_U 0x00008000
312
313/*
314 * The following defines are for the flags in the host DMA control register.
315 */
316#define HDCR_COUNT_MASK 0x000003FF
317#define HDCR_DONE 0x00004000
318#define HDCR_OPT 0x00008000
319#define HDCR_WBD 0x00400000
320#define HDCR_WBS 0x00800000
321#define HDCR_DMS_MASK 0x07000000
322#define HDCR_DMS_LINEAR 0x00000000
323#define HDCR_DMS_16_DWORDS 0x01000000
324#define HDCR_DMS_32_DWORDS 0x02000000
325#define HDCR_DMS_64_DWORDS 0x03000000
326#define HDCR_DMS_128_DWORDS 0x04000000
327#define HDCR_DMS_256_DWORDS 0x05000000
328#define HDCR_DMS_512_DWORDS 0x06000000
329#define HDCR_DMS_1024_DWORDS 0x07000000
330#define HDCR_DH 0x08000000
331#define HDCR_SMS_MASK 0x70000000
332#define HDCR_SMS_LINEAR 0x00000000
333#define HDCR_SMS_16_DWORDS 0x10000000
334#define HDCR_SMS_32_DWORDS 0x20000000
335#define HDCR_SMS_64_DWORDS 0x30000000
336#define HDCR_SMS_128_DWORDS 0x40000000
337#define HDCR_SMS_256_DWORDS 0x50000000
338#define HDCR_SMS_512_DWORDS 0x60000000
339#define HDCR_SMS_1024_DWORDS 0x70000000
340#define HDCR_SH 0x80000000
341#define HDCR_COUNT_SHIFT 0
342
343/*
344 * The following defines are for the flags in the performance monitor control
345 * register.
346 */
347#define PFMC_C1SS_MASK 0x0000001F
348#define PFMC_C1EV 0x00000020
349#define PFMC_C1RS 0x00008000
350#define PFMC_C2SS_MASK 0x001F0000
351#define PFMC_C2EV 0x00200000
352#define PFMC_C2RS 0x80000000
353#define PFMC_C1SS_SHIFT 0
354#define PFMC_C2SS_SHIFT 16
355#define PFMC_BUS_GRANT 0
356#define PFMC_GRANT_AFTER_REQ 1
357#define PFMC_TRANSACTION 2
358#define PFMC_DWORD_TRANSFER 3
359#define PFMC_SLAVE_READ 4
360#define PFMC_SLAVE_WRITE 5
361#define PFMC_PREEMPTION 6
362#define PFMC_DISCONNECT_RETRY 7
363#define PFMC_INTERRUPT 8
364#define PFMC_BUS_OWNERSHIP 9
365#define PFMC_TRANSACTION_LAG 10
366#define PFMC_PCI_CLOCK 11
367#define PFMC_SERIAL_CLOCK 12
368#define PFMC_SP_CLOCK 13
369
370/*
371 * The following defines are for the flags in the performance counter value 1
372 * register.
373 */
374#define PFCV1_PC1V_MASK 0xFFFFFFFF
375#define PFCV1_PC1V_SHIFT 0
376
377/*
378 * The following defines are for the flags in the performance counter value 2
379 * register.
380 */
381#define PFCV2_PC2V_MASK 0xFFFFFFFF
382#define PFCV2_PC2V_SHIFT 0
383
384/*
385 * The following defines are for the flags in the clock control register 1.
386 */
387#define CLKCR1_OSCS 0x00000001
388#define CLKCR1_OSCP 0x00000002
389#define CLKCR1_PLLSS_MASK 0x0000000C
390#define CLKCR1_PLLSS_SERIAL 0x00000000
391#define CLKCR1_PLLSS_CRYSTAL 0x00000004
392#define CLKCR1_PLLSS_PCI 0x00000008
393#define CLKCR1_PLLSS_RESERVED 0x0000000C
394#define CLKCR1_PLLP 0x00000010
395#define CLKCR1_SWCE 0x00000020
396#define CLKCR1_PLLOS 0x00000040
397
398/*
399 * The following defines are for the flags in the clock control register 2.
400 */
401#define CLKCR2_PDIVS_MASK 0x0000000F
402#define CLKCR2_PDIVS_1 0x00000001
403#define CLKCR2_PDIVS_2 0x00000002
404#define CLKCR2_PDIVS_4 0x00000004
405#define CLKCR2_PDIVS_7 0x00000007
406#define CLKCR2_PDIVS_8 0x00000008
407#define CLKCR2_PDIVS_16 0x00000000
408
409/*
410 * The following defines are for the flags in the PLL multiplier register.
411 */
412#define PLLM_MASK 0x000000FF
413#define PLLM_SHIFT 0
414
415/*
416 * The following defines are for the flags in the PLL capacitor coefficient
417 * register.
418 */
419#define PLLCC_CDR_MASK 0x00000007
420#ifndef NO_CS4610
421#define PLLCC_CDR_240_350_MHZ 0x00000000
422#define PLLCC_CDR_184_265_MHZ 0x00000001
423#define PLLCC_CDR_144_205_MHZ 0x00000002
424#define PLLCC_CDR_111_160_MHZ 0x00000003
425#define PLLCC_CDR_87_123_MHZ 0x00000004
426#define PLLCC_CDR_67_96_MHZ 0x00000005
427#define PLLCC_CDR_52_74_MHZ 0x00000006
428#define PLLCC_CDR_45_58_MHZ 0x00000007
429#endif
430#ifndef NO_CS4612
431#define PLLCC_CDR_271_398_MHZ 0x00000000
432#define PLLCC_CDR_227_330_MHZ 0x00000001
433#define PLLCC_CDR_167_239_MHZ 0x00000002
434#define PLLCC_CDR_150_215_MHZ 0x00000003
435#define PLLCC_CDR_107_154_MHZ 0x00000004
436#define PLLCC_CDR_98_140_MHZ 0x00000005
437#define PLLCC_CDR_73_104_MHZ 0x00000006
438#define PLLCC_CDR_63_90_MHZ 0x00000007
439#endif
440#define PLLCC_LPF_MASK 0x000000F8
441#ifndef NO_CS4610
442#define PLLCC_LPF_23850_60000_KHZ 0x00000000
443#define PLLCC_LPF_7960_26290_KHZ 0x00000008
444#define PLLCC_LPF_4160_10980_KHZ 0x00000018
445#define PLLCC_LPF_1740_4580_KHZ 0x00000038
446#define PLLCC_LPF_724_1910_KHZ 0x00000078
447#define PLLCC_LPF_317_798_KHZ 0x000000F8
448#endif
449#ifndef NO_CS4612
450#define PLLCC_LPF_25580_64530_KHZ 0x00000000
451#define PLLCC_LPF_14360_37270_KHZ 0x00000008
452#define PLLCC_LPF_6100_16020_KHZ 0x00000018
453#define PLLCC_LPF_2540_6690_KHZ 0x00000038
454#define PLLCC_LPF_1050_2780_KHZ 0x00000078
455#define PLLCC_LPF_450_1160_KHZ 0x000000F8
456#endif
457
458/*
459 * The following defines are for the flags in the feature reporting register.
460 */
461#define FRR_FAB_MASK 0x00000003
462#define FRR_MASK_MASK 0x0000001C
463#ifdef NO_CS4612
464#define FRR_CFOP_MASK 0x000000E0
465#else
466#define FRR_CFOP_MASK 0x00000FE0
467#endif
468#define FRR_CFOP_NOT_DVD 0x00000020
469#define FRR_CFOP_A3D 0x00000040
470#define FRR_CFOP_128_PIN 0x00000080
471#ifndef NO_CS4612
472#define FRR_CFOP_CS4280 0x00000800
473#endif
474#define FRR_FAB_SHIFT 0
475#define FRR_MASK_SHIFT 2
476#define FRR_CFOP_SHIFT 5
477
478/*
479 * The following defines are for the flags in the configuration load 1
480 * register.
481 */
482#define CFL1_CLOCK_SOURCE_MASK 0x00000003
483#define CFL1_CLOCK_SOURCE_CS423X 0x00000000
484#define CFL1_CLOCK_SOURCE_AC97 0x00000001
485#define CFL1_CLOCK_SOURCE_CRYSTAL 0x00000002
486#define CFL1_CLOCK_SOURCE_DUAL_AC97 0x00000003
487#define CFL1_VALID_DATA_MASK 0x000000FF
488
489/*
490 * The following defines are for the flags in the configuration load 2
491 * register.
492 */
493#define CFL2_VALID_DATA_MASK 0x000000FF
494
495/*
496 * The following defines are for the flags in the serial port master control
497 * register 1.
498 */
499#define SERMC1_MSPE 0x00000001
500#define SERMC1_PTC_MASK 0x0000000E
501#define SERMC1_PTC_CS423X 0x00000000
502#define SERMC1_PTC_AC97 0x00000002
503#define SERMC1_PTC_DAC 0x00000004
504#define SERMC1_PLB 0x00000010
505#define SERMC1_XLB 0x00000020
506
507/*
508 * The following defines are for the flags in the serial port master control
509 * register 2.
510 */
511#define SERMC2_LROE 0x00000001
512#define SERMC2_MCOE 0x00000002
513#define SERMC2_MCDIV 0x00000004
514
515/*
516 * The following defines are for the flags in the serial port 1 configuration
517 * register.
518 */
519#define SERC1_SO1EN 0x00000001
520#define SERC1_SO1F_MASK 0x0000000E
521#define SERC1_SO1F_CS423X 0x00000000
522#define SERC1_SO1F_AC97 0x00000002
523#define SERC1_SO1F_DAC 0x00000004
524#define SERC1_SO1F_SPDIF 0x00000006
525
526/*
527 * The following defines are for the flags in the serial port 2 configuration
528 * register.
529 */
530#define SERC2_SI1EN 0x00000001
531#define SERC2_SI1F_MASK 0x0000000E
532#define SERC2_SI1F_CS423X 0x00000000
533#define SERC2_SI1F_AC97 0x00000002
534#define SERC2_SI1F_ADC 0x00000004
535#define SERC2_SI1F_SPDIF 0x00000006
536
537/*
538 * The following defines are for the flags in the serial port 3 configuration
539 * register.
540 */
541#define SERC3_SO2EN 0x00000001
542#define SERC3_SO2F_MASK 0x00000006
543#define SERC3_SO2F_DAC 0x00000000
544#define SERC3_SO2F_SPDIF 0x00000002
545
546/*
547 * The following defines are for the flags in the serial port 4 configuration
548 * register.
549 */
550#define SERC4_SO3EN 0x00000001
551#define SERC4_SO3F_MASK 0x00000006
552#define SERC4_SO3F_DAC 0x00000000
553#define SERC4_SO3F_SPDIF 0x00000002
554
555/*
556 * The following defines are for the flags in the serial port 5 configuration
557 * register.
558 */
559#define SERC5_SI2EN 0x00000001
560#define SERC5_SI2F_MASK 0x00000006
561#define SERC5_SI2F_ADC 0x00000000
562#define SERC5_SI2F_SPDIF 0x00000002
563
564/*
565 * The following defines are for the flags in the serial port backdoor sample
566 * pointer register.
567 */
568#define SERBSP_FSP_MASK 0x0000000F
569#define SERBSP_FSP_SHIFT 0
570
571/*
572 * The following defines are for the flags in the serial port backdoor status
573 * register.
574 */
575#define SERBST_RRDY 0x00000001
576#define SERBST_WBSY 0x00000002
577
578/*
579 * The following defines are for the flags in the serial port backdoor command
580 * register.
581 */
582#define SERBCM_RDC 0x00000001
583#define SERBCM_WRC 0x00000002
584
585/*
586 * The following defines are for the flags in the serial port backdoor address
587 * register.
588 */
589#ifdef NO_CS4612
590#define SERBAD_FAD_MASK 0x000000FF
591#else
592#define SERBAD_FAD_MASK 0x000001FF
593#endif
594#define SERBAD_FAD_SHIFT 0
595
596/*
597 * The following defines are for the flags in the serial port backdoor
598 * configuration register.
599 */
600#define SERBCF_HBP 0x00000001
601
602/*
603 * The following defines are for the flags in the serial port backdoor write
604 * port register.
605 */
606#define SERBWP_FWD_MASK 0x000FFFFF
607#define SERBWP_FWD_SHIFT 0
608
609/*
610 * The following defines are for the flags in the serial port backdoor read
611 * port register.
612 */
613#define SERBRP_FRD_MASK 0x000FFFFF
614#define SERBRP_FRD_SHIFT 0
615
616/*
617 * The following defines are for the flags in the async FIFO address register.
618 */
619#ifndef NO_CS4612
620#define ASER_FADDR_A1_MASK 0x000001FF
621#define ASER_FADDR_EN1 0x00008000
622#define ASER_FADDR_A2_MASK 0x01FF0000
623#define ASER_FADDR_EN2 0x80000000
624#define ASER_FADDR_A1_SHIFT 0
625#define ASER_FADDR_A2_SHIFT 16
626#endif
627
628/*
629 * The following defines are for the flags in the AC97 control register.
630 */
631#define ACCTL_RSTN 0x00000001
632#define ACCTL_ESYN 0x00000002
633#define ACCTL_VFRM 0x00000004
634#define ACCTL_DCV 0x00000008
635#define ACCTL_CRW 0x00000010
636#define ACCTL_ASYN 0x00000020
637#ifndef NO_CS4612
638#define ACCTL_TC 0x00000040
639#endif
640
641/*
642 * The following defines are for the flags in the AC97 status register.
643 */
644#define ACSTS_CRDY 0x00000001
645#define ACSTS_VSTS 0x00000002
646#ifndef NO_CS4612
647#define ACSTS_WKUP 0x00000004
648#endif
649
650/*
651 * The following defines are for the flags in the AC97 output slot valid
652 * register.
653 */
654#define ACOSV_SLV3 0x00000001
655#define ACOSV_SLV4 0x00000002
656#define ACOSV_SLV5 0x00000004
657#define ACOSV_SLV6 0x00000008
658#define ACOSV_SLV7 0x00000010
659#define ACOSV_SLV8 0x00000020
660#define ACOSV_SLV9 0x00000040
661#define ACOSV_SLV10 0x00000080
662#define ACOSV_SLV11 0x00000100
663#define ACOSV_SLV12 0x00000200
664
665/*
666 * The following defines are for the flags in the AC97 command address
667 * register.
668 */
669#define ACCAD_CI_MASK 0x0000007F
670#define ACCAD_CI_SHIFT 0
671
672/*
673 * The following defines are for the flags in the AC97 command data register.
674 */
675#define ACCDA_CD_MASK 0x0000FFFF
676#define ACCDA_CD_SHIFT 0
677
678/*
679 * The following defines are for the flags in the AC97 input slot valid
680 * register.
681 */
682#define ACISV_ISV3 0x00000001
683#define ACISV_ISV4 0x00000002
684#define ACISV_ISV5 0x00000004
685#define ACISV_ISV6 0x00000008
686#define ACISV_ISV7 0x00000010
687#define ACISV_ISV8 0x00000020
688#define ACISV_ISV9 0x00000040
689#define ACISV_ISV10 0x00000080
690#define ACISV_ISV11 0x00000100
691#define ACISV_ISV12 0x00000200
692
693/*
694 * The following defines are for the flags in the AC97 status address
695 * register.
696 */
697#define ACSAD_SI_MASK 0x0000007F
698#define ACSAD_SI_SHIFT 0
699
700/*
701 * The following defines are for the flags in the AC97 status data register.
702 */
703#define ACSDA_SD_MASK 0x0000FFFF
704#define ACSDA_SD_SHIFT 0
705
706/*
707 * The following defines are for the flags in the joystick poll/trigger
708 * register.
709 */
710#define JSPT_CAX 0x00000001
711#define JSPT_CAY 0x00000002
712#define JSPT_CBX 0x00000004
713#define JSPT_CBY 0x00000008
714#define JSPT_BA1 0x00000010
715#define JSPT_BA2 0x00000020
716#define JSPT_BB1 0x00000040
717#define JSPT_BB2 0x00000080
718
719/*
720 * The following defines are for the flags in the joystick control register.
721 */
722#define JSCTL_SP_MASK 0x00000003
723#define JSCTL_SP_SLOW 0x00000000
724#define JSCTL_SP_MEDIUM_SLOW 0x00000001
725#define JSCTL_SP_MEDIUM_FAST 0x00000002
726#define JSCTL_SP_FAST 0x00000003
727#define JSCTL_ARE 0x00000004
728
729/*
730 * The following defines are for the flags in the joystick coordinate pair 1
731 * readback register.
732 */
733#define JSC1_Y1V_MASK 0x0000FFFF
734#define JSC1_X1V_MASK 0xFFFF0000
735#define JSC1_Y1V_SHIFT 0
736#define JSC1_X1V_SHIFT 16
737
738/*
739 * The following defines are for the flags in the joystick coordinate pair 2
740 * readback register.
741 */
742#define JSC2_Y2V_MASK 0x0000FFFF
743#define JSC2_X2V_MASK 0xFFFF0000
744#define JSC2_Y2V_SHIFT 0
745#define JSC2_X2V_SHIFT 16
746
747/*
748 * The following defines are for the flags in the MIDI control register.
749 */
750#define MIDCR_TXE 0x00000001 /* Enable transmitting. */
751#define MIDCR_RXE 0x00000002 /* Enable receiving. */
752#define MIDCR_RIE 0x00000004 /* Interrupt upon tx ready. */
753#define MIDCR_TIE 0x00000008 /* Interrupt upon rx ready. */
754#define MIDCR_MLB 0x00000010 /* Enable midi loopback. */
755#define MIDCR_MRST 0x00000020 /* Reset interface. */
756
757/*
758 * The following defines are for the flags in the MIDI status register.
759 */
760#define MIDSR_TBF 0x00000001 /* Tx FIFO is full. */
761#define MIDSR_RBE 0x00000002 /* Rx FIFO is empty. */
762
763/*
764 * The following defines are for the flags in the MIDI write port register.
765 */
766#define MIDWP_MWD_MASK 0x000000FF
767#define MIDWP_MWD_SHIFT 0
768
769/*
770 * The following defines are for the flags in the MIDI read port register.
771 */
772#define MIDRP_MRD_MASK 0x000000FF
773#define MIDRP_MRD_SHIFT 0
774
775/*
776 * The following defines are for the flags in the joystick GPIO register.
777 */
778#define JSIO_DAX 0x00000001
779#define JSIO_DAY 0x00000002
780#define JSIO_DBX 0x00000004
781#define JSIO_DBY 0x00000008
782#define JSIO_AXOE 0x00000010
783#define JSIO_AYOE 0x00000020
784#define JSIO_BXOE 0x00000040
785#define JSIO_BYOE 0x00000080
786
787/*
788 * The following defines are for the flags in the master async/sync serial
789 * port enable register.
790 */
791#ifndef NO_CS4612
792#define ASER_MASTER_ME 0x00000001
793#endif
794
795/*
796 * The following defines are for the flags in the configuration interface
797 * register.
798 */
799#define CFGI_CLK 0x00000001
800#define CFGI_DOUT 0x00000002
801#define CFGI_DIN_EEN 0x00000004
802#define CFGI_EELD 0x00000008
803
804/*
805 * The following defines are for the flags in the subsystem ID and vendor ID
806 * register.
807 */
808#define SSVID_VID_MASK 0x0000FFFF
809#define SSVID_SID_MASK 0xFFFF0000
810#define SSVID_VID_SHIFT 0
811#define SSVID_SID_SHIFT 16
812
813/*
814 * The following defines are for the flags in the GPIO pin interface register.
815 */
816#define GPIOR_VOLDN 0x00000001
817#define GPIOR_VOLUP 0x00000002
818#define GPIOR_SI2D 0x00000004
819#define GPIOR_SI2OE 0x00000008
820
821/*
822 * The following defines are for the flags in the extended GPIO pin direction
823 * register.
824 */
825#ifndef NO_CS4612
826#define EGPIODR_GPOE0 0x00000001
827#define EGPIODR_GPOE1 0x00000002
828#define EGPIODR_GPOE2 0x00000004
829#define EGPIODR_GPOE3 0x00000008
830#define EGPIODR_GPOE4 0x00000010
831#define EGPIODR_GPOE5 0x00000020
832#define EGPIODR_GPOE6 0x00000040
833#define EGPIODR_GPOE7 0x00000080
834#define EGPIODR_GPOE8 0x00000100
835#endif
836
837/*
838 * The following defines are for the flags in the extended GPIO pin polarity/
839 * type register.
840 */
841#ifndef NO_CS4612
842#define EGPIOPTR_GPPT0 0x00000001
843#define EGPIOPTR_GPPT1 0x00000002
844#define EGPIOPTR_GPPT2 0x00000004
845#define EGPIOPTR_GPPT3 0x00000008
846#define EGPIOPTR_GPPT4 0x00000010
847#define EGPIOPTR_GPPT5 0x00000020
848#define EGPIOPTR_GPPT6 0x00000040
849#define EGPIOPTR_GPPT7 0x00000080
850#define EGPIOPTR_GPPT8 0x00000100
851#endif
852
853/*
854 * The following defines are for the flags in the extended GPIO pin sticky
855 * register.
856 */
857#ifndef NO_CS4612
858#define EGPIOTR_GPS0 0x00000001
859#define EGPIOTR_GPS1 0x00000002
860#define EGPIOTR_GPS2 0x00000004
861#define EGPIOTR_GPS3 0x00000008
862#define EGPIOTR_GPS4 0x00000010
863#define EGPIOTR_GPS5 0x00000020
864#define EGPIOTR_GPS6 0x00000040
865#define EGPIOTR_GPS7 0x00000080
866#define EGPIOTR_GPS8 0x00000100
867#endif
868
869/*
870 * The following defines are for the flags in the extended GPIO ping wakeup
871 * register.
872 */
873#ifndef NO_CS4612
874#define EGPIOWR_GPW0 0x00000001
875#define EGPIOWR_GPW1 0x00000002
876#define EGPIOWR_GPW2 0x00000004
877#define EGPIOWR_GPW3 0x00000008
878#define EGPIOWR_GPW4 0x00000010
879#define EGPIOWR_GPW5 0x00000020
880#define EGPIOWR_GPW6 0x00000040
881#define EGPIOWR_GPW7 0x00000080
882#define EGPIOWR_GPW8 0x00000100
883#endif
884
885/*
886 * The following defines are for the flags in the extended GPIO pin status
887 * register.
888 */
889#ifndef NO_CS4612
890#define EGPIOSR_GPS0 0x00000001
891#define EGPIOSR_GPS1 0x00000002
892#define EGPIOSR_GPS2 0x00000004
893#define EGPIOSR_GPS3 0x00000008
894#define EGPIOSR_GPS4 0x00000010
895#define EGPIOSR_GPS5 0x00000020
896#define EGPIOSR_GPS6 0x00000040
897#define EGPIOSR_GPS7 0x00000080
898#define EGPIOSR_GPS8 0x00000100
899#endif
900
901/*
902 * The following defines are for the flags in the serial port 6 configuration
903 * register.
904 */
905#ifndef NO_CS4612
906#define SERC6_ASDO2EN 0x00000001
907#endif
908
909/*
910 * The following defines are for the flags in the serial port 7 configuration
911 * register.
912 */
913#ifndef NO_CS4612
914#define SERC7_ASDI2EN 0x00000001
915#define SERC7_POSILB 0x00000002
916#define SERC7_SIPOLB 0x00000004
917#define SERC7_SOSILB 0x00000008
918#define SERC7_SISOLB 0x00000010
919#endif
920
921/*
922 * The following defines are for the flags in the serial port AC link
923 * configuration register.
924 */
925#ifndef NO_CS4612
926#define SERACC_CHIP_TYPE_MASK 0x00000001
927#define SERACC_CHIP_TYPE_1_03 0x00000000
928#define SERACC_CHIP_TYPE_2_0 0x00000001
929#define SERACC_TWO_CODECS 0x00000002
930#define SERACC_MDM 0x00000004
931#define SERACC_HSP 0x00000008
932#define SERACC_ODT 0x00000010 /* only CS4630 */
933#endif
934
935/*
936 * The following defines are for the flags in the AC97 control register 2.
937 */
938#ifndef NO_CS4612
939#define ACCTL2_RSTN 0x00000001
940#define ACCTL2_ESYN 0x00000002
941#define ACCTL2_VFRM 0x00000004
942#define ACCTL2_DCV 0x00000008
943#define ACCTL2_CRW 0x00000010
944#define ACCTL2_ASYN 0x00000020
945#endif
946
947/*
948 * The following defines are for the flags in the AC97 status register 2.
949 */
950#ifndef NO_CS4612
951#define ACSTS2_CRDY 0x00000001
952#define ACSTS2_VSTS 0x00000002
953#endif
954
955/*
956 * The following defines are for the flags in the AC97 output slot valid
957 * register 2.
958 */
959#ifndef NO_CS4612
960#define ACOSV2_SLV3 0x00000001
961#define ACOSV2_SLV4 0x00000002
962#define ACOSV2_SLV5 0x00000004
963#define ACOSV2_SLV6 0x00000008
964#define ACOSV2_SLV7 0x00000010
965#define ACOSV2_SLV8 0x00000020
966#define ACOSV2_SLV9 0x00000040
967#define ACOSV2_SLV10 0x00000080
968#define ACOSV2_SLV11 0x00000100
969#define ACOSV2_SLV12 0x00000200
970#endif
971
972/*
973 * The following defines are for the flags in the AC97 command address
974 * register 2.
975 */
976#ifndef NO_CS4612
977#define ACCAD2_CI_MASK 0x0000007F
978#define ACCAD2_CI_SHIFT 0
979#endif
980
981/*
982 * The following defines are for the flags in the AC97 command data register
983 * 2.
984 */
985#ifndef NO_CS4612
986#define ACCDA2_CD_MASK 0x0000FFFF
987#define ACCDA2_CD_SHIFT 0
988#endif
989
990/*
991 * The following defines are for the flags in the AC97 input slot valid
992 * register 2.
993 */
994#ifndef NO_CS4612
995#define ACISV2_ISV3 0x00000001
996#define ACISV2_ISV4 0x00000002
997#define ACISV2_ISV5 0x00000004
998#define ACISV2_ISV6 0x00000008
999#define ACISV2_ISV7 0x00000010
1000#define ACISV2_ISV8 0x00000020
1001#define ACISV2_ISV9 0x00000040
1002#define ACISV2_ISV10 0x00000080
1003#define ACISV2_ISV11 0x00000100
1004#define ACISV2_ISV12 0x00000200
1005#endif
1006
1007/*
1008 * The following defines are for the flags in the AC97 status address
1009 * register 2.
1010 */
1011#ifndef NO_CS4612
1012#define ACSAD2_SI_MASK 0x0000007F
1013#define ACSAD2_SI_SHIFT 0
1014#endif
1015
1016/*
1017 * The following defines are for the flags in the AC97 status data register 2.
1018 */
1019#ifndef NO_CS4612
1020#define ACSDA2_SD_MASK 0x0000FFFF
1021#define ACSDA2_SD_SHIFT 0
1022#endif
1023
1024/*
1025 * The following defines are for the flags in the I/O trap address and control
1026 * registers (all 12).
1027 */
1028#ifndef NO_CS4612
1029#define IOTAC_SA_MASK 0x0000FFFF
1030#define IOTAC_MSK_MASK 0x000F0000
1031#define IOTAC_IODC_MASK 0x06000000
1032#define IOTAC_IODC_16_BIT 0x00000000
1033#define IOTAC_IODC_10_BIT 0x02000000
1034#define IOTAC_IODC_12_BIT 0x04000000
1035#define IOTAC_WSPI 0x08000000
1036#define IOTAC_RSPI 0x10000000
1037#define IOTAC_WSE 0x20000000
1038#define IOTAC_WE 0x40000000
1039#define IOTAC_RE 0x80000000
1040#define IOTAC_SA_SHIFT 0
1041#define IOTAC_MSK_SHIFT 16
1042#endif
1043
1044/*
1045 * The following defines are for the flags in the I/O trap fast read registers
1046 * (all 8).
1047 */
1048#ifndef NO_CS4612
1049#define IOTFR_D_MASK 0x0000FFFF
1050#define IOTFR_A_MASK 0x000F0000
1051#define IOTFR_R_MASK 0x0F000000
1052#define IOTFR_ALL 0x40000000
1053#define IOTFR_VL 0x80000000
1054#define IOTFR_D_SHIFT 0
1055#define IOTFR_A_SHIFT 16
1056#define IOTFR_R_SHIFT 24
1057#endif
1058
1059/*
1060 * The following defines are for the flags in the I/O trap FIFO register.
1061 */
1062#ifndef NO_CS4612
1063#define IOTFIFO_BA_MASK 0x00003FFF
1064#define IOTFIFO_S_MASK 0x00FF0000
1065#define IOTFIFO_OF 0x40000000
1066#define IOTFIFO_SPIOF 0x80000000
1067#define IOTFIFO_BA_SHIFT 0
1068#define IOTFIFO_S_SHIFT 16
1069#endif
1070
1071/*
1072 * The following defines are for the flags in the I/O trap retry read data
1073 * register.
1074 */
1075#ifndef NO_CS4612
1076#define IOTRRD_D_MASK 0x0000FFFF
1077#define IOTRRD_RDV 0x80000000
1078#define IOTRRD_D_SHIFT 0
1079#endif
1080
1081/*
1082 * The following defines are for the flags in the I/O trap FIFO pointer
1083 * register.
1084 */
1085#ifndef NO_CS4612
1086#define IOTFP_CA_MASK 0x00003FFF
1087#define IOTFP_PA_MASK 0x3FFF0000
1088#define IOTFP_CA_SHIFT 0
1089#define IOTFP_PA_SHIFT 16
1090#endif
1091
1092/*
1093 * The following defines are for the flags in the I/O trap control register.
1094 */
1095#ifndef NO_CS4612
1096#define IOTCR_ITD 0x00000001
1097#define IOTCR_HRV 0x00000002
1098#define IOTCR_SRV 0x00000004
1099#define IOTCR_DTI 0x00000008
1100#define IOTCR_DFI 0x00000010
1101#define IOTCR_DDP 0x00000020
1102#define IOTCR_JTE 0x00000040
1103#define IOTCR_PPE 0x00000080
1104#endif
1105
1106/*
1107 * The following defines are for the flags in the direct PCI data register.
1108 */
1109#ifndef NO_CS4612
1110#define DPCID_D_MASK 0xFFFFFFFF
1111#define DPCID_D_SHIFT 0
1112#endif
1113
1114/*
1115 * The following defines are for the flags in the direct PCI address register.
1116 */
1117#ifndef NO_CS4612
1118#define DPCIA_A_MASK 0xFFFFFFFF
1119#define DPCIA_A_SHIFT 0
1120#endif
1121
1122/*
1123 * The following defines are for the flags in the direct PCI command register.
1124 */
1125#ifndef NO_CS4612
1126#define DPCIC_C_MASK 0x0000000F
1127#define DPCIC_C_IOREAD 0x00000002
1128#define DPCIC_C_IOWRITE 0x00000003
1129#define DPCIC_BE_MASK 0x000000F0
1130#endif
1131
1132/*
1133 * The following defines are for the flags in the PC/PCI request register.
1134 */
1135#ifndef NO_CS4612
1136#define PCPCIR_RDC_MASK 0x00000007
1137#define PCPCIR_C_MASK 0x00007000
1138#define PCPCIR_REQ 0x00008000
1139#define PCPCIR_RDC_SHIFT 0
1140#define PCPCIR_C_SHIFT 12
1141#endif
1142
1143/*
1144 * The following defines are for the flags in the PC/PCI grant register.
1145 */
1146#ifndef NO_CS4612
1147#define PCPCIG_GDC_MASK 0x00000007
1148#define PCPCIG_VL 0x00008000
1149#define PCPCIG_GDC_SHIFT 0
1150#endif
1151
1152/*
1153 * The following defines are for the flags in the PC/PCI master enable
1154 * register.
1155 */
1156#ifndef NO_CS4612
1157#define PCPCIEN_EN 0x00000001
1158#endif
1159
1160/*
1161 * The following defines are for the flags in the extended PCI power
1162 * management control register.
1163 */
1164#ifndef NO_CS4612
1165#define EPCIPMC_GWU 0x00000001
1166#define EPCIPMC_FSPC 0x00000002
1167#endif
1168
1169/*
1170 * The following defines are for the flags in the SP control register.
1171 */
1172#define SPCR_RUN 0x00000001
1173#define SPCR_STPFR 0x00000002
1174#define SPCR_RUNFR 0x00000004
1175#define SPCR_TICK 0x00000008
1176#define SPCR_DRQEN 0x00000020
1177#define SPCR_RSTSP 0x00000040
1178#define SPCR_OREN 0x00000080
1179#ifndef NO_CS4612
1180#define SPCR_PCIINT 0x00000100
1181#define SPCR_OINTD 0x00000200
1182#define SPCR_CRE 0x00008000
1183#endif
1184
1185/*
1186 * The following defines are for the flags in the debug index register.
1187 */
1188#define DREG_REGID_MASK 0x0000007F
1189#define DREG_DEBUG 0x00000080
1190#define DREG_RGBK_MASK 0x00000700
1191#define DREG_TRAP 0x00000800
1192#if !defined(NO_CS4612)
1193#if !defined(NO_CS4615)
1194#define DREG_TRAPX 0x00001000
1195#endif
1196#endif
1197#define DREG_REGID_SHIFT 0
1198#define DREG_RGBK_SHIFT 8
1199#define DREG_RGBK_REGID_MASK 0x0000077F
1200#define DREG_REGID_R0 0x00000010
1201#define DREG_REGID_R1 0x00000011
1202#define DREG_REGID_R2 0x00000012
1203#define DREG_REGID_R3 0x00000013
1204#define DREG_REGID_R4 0x00000014
1205#define DREG_REGID_R5 0x00000015
1206#define DREG_REGID_R6 0x00000016
1207#define DREG_REGID_R7 0x00000017
1208#define DREG_REGID_R8 0x00000018
1209#define DREG_REGID_R9 0x00000019
1210#define DREG_REGID_RA 0x0000001A
1211#define DREG_REGID_RB 0x0000001B
1212#define DREG_REGID_RC 0x0000001C
1213#define DREG_REGID_RD 0x0000001D
1214#define DREG_REGID_RE 0x0000001E
1215#define DREG_REGID_RF 0x0000001F
1216#define DREG_REGID_RA_BUS_LOW 0x00000020
1217#define DREG_REGID_RA_BUS_HIGH 0x00000038
1218#define DREG_REGID_YBUS_LOW 0x00000050
1219#define DREG_REGID_YBUS_HIGH 0x00000058
1220#define DREG_REGID_TRAP_0 0x00000100
1221#define DREG_REGID_TRAP_1 0x00000101
1222#define DREG_REGID_TRAP_2 0x00000102
1223#define DREG_REGID_TRAP_3 0x00000103
1224#define DREG_REGID_TRAP_4 0x00000104
1225#define DREG_REGID_TRAP_5 0x00000105
1226#define DREG_REGID_TRAP_6 0x00000106
1227#define DREG_REGID_TRAP_7 0x00000107
1228#define DREG_REGID_INDIRECT_ADDRESS 0x0000010E
1229#define DREG_REGID_TOP_OF_STACK 0x0000010F
1230#if !defined(NO_CS4612)
1231#if !defined(NO_CS4615)
1232#define DREG_REGID_TRAP_8 0x00000110
1233#define DREG_REGID_TRAP_9 0x00000111
1234#define DREG_REGID_TRAP_10 0x00000112
1235#define DREG_REGID_TRAP_11 0x00000113
1236#define DREG_REGID_TRAP_12 0x00000114
1237#define DREG_REGID_TRAP_13 0x00000115
1238#define DREG_REGID_TRAP_14 0x00000116
1239#define DREG_REGID_TRAP_15 0x00000117
1240#define DREG_REGID_TRAP_16 0x00000118
1241#define DREG_REGID_TRAP_17 0x00000119
1242#define DREG_REGID_TRAP_18 0x0000011A
1243#define DREG_REGID_TRAP_19 0x0000011B
1244#define DREG_REGID_TRAP_20 0x0000011C
1245#define DREG_REGID_TRAP_21 0x0000011D
1246#define DREG_REGID_TRAP_22 0x0000011E
1247#define DREG_REGID_TRAP_23 0x0000011F
1248#endif
1249#endif
1250#define DREG_REGID_RSA0_LOW 0x00000200
1251#define DREG_REGID_RSA0_HIGH 0x00000201
1252#define DREG_REGID_RSA1_LOW 0x00000202
1253#define DREG_REGID_RSA1_HIGH 0x00000203
1254#define DREG_REGID_RSA2 0x00000204
1255#define DREG_REGID_RSA3 0x00000205
1256#define DREG_REGID_RSI0_LOW 0x00000206
1257#define DREG_REGID_RSI0_HIGH 0x00000207
1258#define DREG_REGID_RSI1 0x00000208
1259#define DREG_REGID_RSI2 0x00000209
1260#define DREG_REGID_SAGUSTATUS 0x0000020A
1261#define DREG_REGID_RSCONFIG01_LOW 0x0000020B
1262#define DREG_REGID_RSCONFIG01_HIGH 0x0000020C
1263#define DREG_REGID_RSCONFIG23_LOW 0x0000020D
1264#define DREG_REGID_RSCONFIG23_HIGH 0x0000020E
1265#define DREG_REGID_RSDMA01E 0x0000020F
1266#define DREG_REGID_RSDMA23E 0x00000210
1267#define DREG_REGID_RSD0_LOW 0x00000211
1268#define DREG_REGID_RSD0_HIGH 0x00000212
1269#define DREG_REGID_RSD1_LOW 0x00000213
1270#define DREG_REGID_RSD1_HIGH 0x00000214
1271#define DREG_REGID_RSD2_LOW 0x00000215
1272#define DREG_REGID_RSD2_HIGH 0x00000216
1273#define DREG_REGID_RSD3_LOW 0x00000217
1274#define DREG_REGID_RSD3_HIGH 0x00000218
1275#define DREG_REGID_SRAR_HIGH 0x0000021A
1276#define DREG_REGID_SRAR_LOW 0x0000021B
1277#define DREG_REGID_DMA_STATE 0x0000021C
1278#define DREG_REGID_CURRENT_DMA_STREAM 0x0000021D
1279#define DREG_REGID_NEXT_DMA_STREAM 0x0000021E
1280#define DREG_REGID_CPU_STATUS 0x00000300
1281#define DREG_REGID_MAC_MODE 0x00000301
1282#define DREG_REGID_STACK_AND_REPEAT 0x00000302
1283#define DREG_REGID_INDEX0 0x00000304
1284#define DREG_REGID_INDEX1 0x00000305
1285#define DREG_REGID_DMA_STATE_0_3 0x00000400
1286#define DREG_REGID_DMA_STATE_4_7 0x00000404
1287#define DREG_REGID_DMA_STATE_8_11 0x00000408
1288#define DREG_REGID_DMA_STATE_12_15 0x0000040C
1289#define DREG_REGID_DMA_STATE_16_19 0x00000410
1290#define DREG_REGID_DMA_STATE_20_23 0x00000414
1291#define DREG_REGID_DMA_STATE_24_27 0x00000418
1292#define DREG_REGID_DMA_STATE_28_31 0x0000041C
1293#define DREG_REGID_DMA_STATE_32_35 0x00000420
1294#define DREG_REGID_DMA_STATE_36_39 0x00000424
1295#define DREG_REGID_DMA_STATE_40_43 0x00000428
1296#define DREG_REGID_DMA_STATE_44_47 0x0000042C
1297#define DREG_REGID_DMA_STATE_48_51 0x00000430
1298#define DREG_REGID_DMA_STATE_52_55 0x00000434
1299#define DREG_REGID_DMA_STATE_56_59 0x00000438
1300#define DREG_REGID_DMA_STATE_60_63 0x0000043C
1301#define DREG_REGID_DMA_STATE_64_67 0x00000440
1302#define DREG_REGID_DMA_STATE_68_71 0x00000444
1303#define DREG_REGID_DMA_STATE_72_75 0x00000448
1304#define DREG_REGID_DMA_STATE_76_79 0x0000044C
1305#define DREG_REGID_DMA_STATE_80_83 0x00000450
1306#define DREG_REGID_DMA_STATE_84_87 0x00000454
1307#define DREG_REGID_DMA_STATE_88_91 0x00000458
1308#define DREG_REGID_DMA_STATE_92_95 0x0000045C
1309#define DREG_REGID_TRAP_SELECT 0x00000500
1310#define DREG_REGID_TRAP_WRITE_0 0x00000500
1311#define DREG_REGID_TRAP_WRITE_1 0x00000501
1312#define DREG_REGID_TRAP_WRITE_2 0x00000502
1313#define DREG_REGID_TRAP_WRITE_3 0x00000503
1314#define DREG_REGID_TRAP_WRITE_4 0x00000504
1315#define DREG_REGID_TRAP_WRITE_5 0x00000505
1316#define DREG_REGID_TRAP_WRITE_6 0x00000506
1317#define DREG_REGID_TRAP_WRITE_7 0x00000507
1318#if !defined(NO_CS4612)
1319#if !defined(NO_CS4615)
1320#define DREG_REGID_TRAP_WRITE_8 0x00000510
1321#define DREG_REGID_TRAP_WRITE_9 0x00000511
1322#define DREG_REGID_TRAP_WRITE_10 0x00000512
1323#define DREG_REGID_TRAP_WRITE_11 0x00000513
1324#define DREG_REGID_TRAP_WRITE_12 0x00000514
1325#define DREG_REGID_TRAP_WRITE_13 0x00000515
1326#define DREG_REGID_TRAP_WRITE_14 0x00000516
1327#define DREG_REGID_TRAP_WRITE_15 0x00000517
1328#define DREG_REGID_TRAP_WRITE_16 0x00000518
1329#define DREG_REGID_TRAP_WRITE_17 0x00000519
1330#define DREG_REGID_TRAP_WRITE_18 0x0000051A
1331#define DREG_REGID_TRAP_WRITE_19 0x0000051B
1332#define DREG_REGID_TRAP_WRITE_20 0x0000051C
1333#define DREG_REGID_TRAP_WRITE_21 0x0000051D
1334#define DREG_REGID_TRAP_WRITE_22 0x0000051E
1335#define DREG_REGID_TRAP_WRITE_23 0x0000051F
1336#endif
1337#endif
1338#define DREG_REGID_MAC0_ACC0_LOW 0x00000600
1339#define DREG_REGID_MAC0_ACC1_LOW 0x00000601
1340#define DREG_REGID_MAC0_ACC2_LOW 0x00000602
1341#define DREG_REGID_MAC0_ACC3_LOW 0x00000603
1342#define DREG_REGID_MAC1_ACC0_LOW 0x00000604
1343#define DREG_REGID_MAC1_ACC1_LOW 0x00000605
1344#define DREG_REGID_MAC1_ACC2_LOW 0x00000606
1345#define DREG_REGID_MAC1_ACC3_LOW 0x00000607
1346#define DREG_REGID_MAC0_ACC0_MID 0x00000608
1347#define DREG_REGID_MAC0_ACC1_MID 0x00000609
1348#define DREG_REGID_MAC0_ACC2_MID 0x0000060A
1349#define DREG_REGID_MAC0_ACC3_MID 0x0000060B
1350#define DREG_REGID_MAC1_ACC0_MID 0x0000060C
1351#define DREG_REGID_MAC1_ACC1_MID 0x0000060D
1352#define DREG_REGID_MAC1_ACC2_MID 0x0000060E
1353#define DREG_REGID_MAC1_ACC3_MID 0x0000060F
1354#define DREG_REGID_MAC0_ACC0_HIGH 0x00000610
1355#define DREG_REGID_MAC0_ACC1_HIGH 0x00000611
1356#define DREG_REGID_MAC0_ACC2_HIGH 0x00000612
1357#define DREG_REGID_MAC0_ACC3_HIGH 0x00000613
1358#define DREG_REGID_MAC1_ACC0_HIGH 0x00000614
1359#define DREG_REGID_MAC1_ACC1_HIGH 0x00000615
1360#define DREG_REGID_MAC1_ACC2_HIGH 0x00000616
1361#define DREG_REGID_MAC1_ACC3_HIGH 0x00000617
1362#define DREG_REGID_RSHOUT_LOW 0x00000620
1363#define DREG_REGID_RSHOUT_MID 0x00000628
1364#define DREG_REGID_RSHOUT_HIGH 0x00000630
1365
1366/*
1367 * The following defines are for the flags in the DMA stream requestor write
1368 */
1369#define DSRWP_DSR_MASK 0x0000000F
1370#define DSRWP_DSR_BG_RQ 0x00000001
1371#define DSRWP_DSR_PRIORITY_MASK 0x00000006
1372#define DSRWP_DSR_PRIORITY_0 0x00000000
1373#define DSRWP_DSR_PRIORITY_1 0x00000002
1374#define DSRWP_DSR_PRIORITY_2 0x00000004
1375#define DSRWP_DSR_PRIORITY_3 0x00000006
1376#define DSRWP_DSR_RQ_PENDING 0x00000008
1377
1378/*
1379 * The following defines are for the flags in the trap write port register.
1380 */
1381#define TWPR_TW_MASK 0x0000FFFF
1382#define TWPR_TW_SHIFT 0
1383
1384/*
1385 * The following defines are for the flags in the stack pointer write
1386 * register.
1387 */
1388#define SPWR_STKP_MASK 0x0000000F
1389#define SPWR_STKP_SHIFT 0
1390
1391/*
1392 * The following defines are for the flags in the SP interrupt register.
1393 */
1394#define SPIR_FRI 0x00000001
1395#define SPIR_DOI 0x00000002
1396#define SPIR_GPI2 0x00000004
1397#define SPIR_GPI3 0x00000008
1398#define SPIR_IP0 0x00000010
1399#define SPIR_IP1 0x00000020
1400#define SPIR_IP2 0x00000040
1401#define SPIR_IP3 0x00000080
1402
1403/*
1404 * The following defines are for the flags in the functional group 1 register.
1405 */
1406#define FGR1_F1S_MASK 0x0000FFFF
1407#define FGR1_F1S_SHIFT 0
1408
1409/*
1410 * The following defines are for the flags in the SP clock status register.
1411 */
1412#define SPCS_FRI 0x00000001
1413#define SPCS_DOI 0x00000002
1414#define SPCS_GPI2 0x00000004
1415#define SPCS_GPI3 0x00000008
1416#define SPCS_IP0 0x00000010
1417#define SPCS_IP1 0x00000020
1418#define SPCS_IP2 0x00000040
1419#define SPCS_IP3 0x00000080
1420#define SPCS_SPRUN 0x00000100
1421#define SPCS_SLEEP 0x00000200
1422#define SPCS_FG 0x00000400
1423#define SPCS_ORUN 0x00000800
1424#define SPCS_IRQ 0x00001000
1425#define SPCS_FGN_MASK 0x0000E000
1426#define SPCS_FGN_SHIFT 13
1427
1428/*
1429 * The following defines are for the flags in the SP DMA requestor status
1430 * register.
1431 */
1432#define SDSR_DCS_MASK 0x000000FF
1433#define SDSR_DCS_SHIFT 0
1434#define SDSR_DCS_NONE 0x00000007
1435
1436/*
1437 * The following defines are for the flags in the frame timer register.
1438 */
1439#define FRMT_FTV_MASK 0x0000FFFF
1440#define FRMT_FTV_SHIFT 0
1441
1442/*
1443 * The following defines are for the flags in the frame timer current count
1444 * register.
1445 */
1446#define FRCC_FCC_MASK 0x0000FFFF
1447#define FRCC_FCC_SHIFT 0
1448
1449/*
1450 * The following defines are for the flags in the frame timer save count
1451 * register.
1452 */
1453#define FRSC_FCS_MASK 0x0000FFFF
1454#define FRSC_FCS_SHIFT 0
1455
1456/*
1457 * The following define the various flags stored in the scatter/gather
1458 * descriptors.
1459 */
1460#define DMA_SG_NEXT_ENTRY_MASK 0x00000FF8
1461#define DMA_SG_SAMPLE_END_MASK 0x0FFF0000
1462#define DMA_SG_SAMPLE_END_FLAG 0x10000000
1463#define DMA_SG_LOOP_END_FLAG 0x20000000
1464#define DMA_SG_SIGNAL_END_FLAG 0x40000000
1465#define DMA_SG_SIGNAL_PAGE_FLAG 0x80000000
1466#define DMA_SG_NEXT_ENTRY_SHIFT 3
1467#define DMA_SG_SAMPLE_END_SHIFT 16
1468
1469/*
1470 * The following define the offsets of the fields within the on-chip generic
1471 * DMA requestor.
1472 */
1473#define DMA_RQ_CONTROL1 0x00000000
1474#define DMA_RQ_CONTROL2 0x00000004
1475#define DMA_RQ_SOURCE_ADDR 0x00000008
1476#define DMA_RQ_DESTINATION_ADDR 0x0000000C
1477#define DMA_RQ_NEXT_PAGE_ADDR 0x00000010
1478#define DMA_RQ_NEXT_PAGE_SGDESC 0x00000014
1479#define DMA_RQ_LOOP_START_ADDR 0x00000018
1480#define DMA_RQ_POST_LOOP_ADDR 0x0000001C
1481#define DMA_RQ_PAGE_MAP_ADDR 0x00000020
1482
1483/*
1484 * The following defines are for the flags in the first control word of the
1485 * on-chip generic DMA requestor.
1486 */
1487#define DMA_RQ_C1_COUNT_MASK 0x000003FF
1488#define DMA_RQ_C1_DESTINATION_SCATTER 0x00001000
1489#define DMA_RQ_C1_SOURCE_GATHER 0x00002000
1490#define DMA_RQ_C1_DONE_FLAG 0x00004000
1491#define DMA_RQ_C1_OPTIMIZE_STATE 0x00008000
1492#define DMA_RQ_C1_SAMPLE_END_STATE_MASK 0x00030000
1493#define DMA_RQ_C1_FULL_PAGE 0x00000000
1494#define DMA_RQ_C1_BEFORE_SAMPLE_END 0x00010000
1495#define DMA_RQ_C1_PAGE_MAP_ERROR 0x00020000
1496#define DMA_RQ_C1_AT_SAMPLE_END 0x00030000
1497#define DMA_RQ_C1_LOOP_END_STATE_MASK 0x000C0000
1498#define DMA_RQ_C1_NOT_LOOP_END 0x00000000
1499#define DMA_RQ_C1_BEFORE_LOOP_END 0x00040000
1500#define DMA_RQ_C1_2PAGE_LOOP_BEGIN 0x00080000
1501#define DMA_RQ_C1_LOOP_BEGIN 0x000C0000
1502#define DMA_RQ_C1_PAGE_MAP_MASK 0x00300000
1503#define DMA_RQ_C1_PM_NONE_PENDING 0x00000000
1504#define DMA_RQ_C1_PM_NEXT_PENDING 0x00100000
1505#define DMA_RQ_C1_PM_RESERVED 0x00200000
1506#define DMA_RQ_C1_PM_LOOP_NEXT_PENDING 0x00300000
1507#define DMA_RQ_C1_WRITEBACK_DEST_FLAG 0x00400000
1508#define DMA_RQ_C1_WRITEBACK_SRC_FLAG 0x00800000
1509#define DMA_RQ_C1_DEST_SIZE_MASK 0x07000000
1510#define DMA_RQ_C1_DEST_LINEAR 0x00000000
1511#define DMA_RQ_C1_DEST_MOD16 0x01000000
1512#define DMA_RQ_C1_DEST_MOD32 0x02000000
1513#define DMA_RQ_C1_DEST_MOD64 0x03000000
1514#define DMA_RQ_C1_DEST_MOD128 0x04000000
1515#define DMA_RQ_C1_DEST_MOD256 0x05000000
1516#define DMA_RQ_C1_DEST_MOD512 0x06000000
1517#define DMA_RQ_C1_DEST_MOD1024 0x07000000
1518#define DMA_RQ_C1_DEST_ON_HOST 0x08000000
1519#define DMA_RQ_C1_SOURCE_SIZE_MASK 0x70000000
1520#define DMA_RQ_C1_SOURCE_LINEAR 0x00000000
1521#define DMA_RQ_C1_SOURCE_MOD16 0x10000000
1522#define DMA_RQ_C1_SOURCE_MOD32 0x20000000
1523#define DMA_RQ_C1_SOURCE_MOD64 0x30000000
1524#define DMA_RQ_C1_SOURCE_MOD128 0x40000000
1525#define DMA_RQ_C1_SOURCE_MOD256 0x50000000
1526#define DMA_RQ_C1_SOURCE_MOD512 0x60000000
1527#define DMA_RQ_C1_SOURCE_MOD1024 0x70000000
1528#define DMA_RQ_C1_SOURCE_ON_HOST 0x80000000
1529#define DMA_RQ_C1_COUNT_SHIFT 0
1530
1531/*
1532 * The following defines are for the flags in the second control word of the
1533 * on-chip generic DMA requestor.
1534 */
1535#define DMA_RQ_C2_VIRTUAL_CHANNEL_MASK 0x0000003F
1536#define DMA_RQ_C2_VIRTUAL_SIGNAL_MASK 0x00000300
1537#define DMA_RQ_C2_NO_VIRTUAL_SIGNAL 0x00000000
1538#define DMA_RQ_C2_SIGNAL_EVERY_DMA 0x00000100
1539#define DMA_RQ_C2_SIGNAL_SOURCE_PINGPONG 0x00000200
1540#define DMA_RQ_C2_SIGNAL_DEST_PINGPONG 0x00000300
1541#define DMA_RQ_C2_AUDIO_CONVERT_MASK 0x0000F000
1542#define DMA_RQ_C2_AC_NONE 0x00000000
1543#define DMA_RQ_C2_AC_8_TO_16_BIT 0x00001000
1544#define DMA_RQ_C2_AC_MONO_TO_STEREO 0x00002000
1545#define DMA_RQ_C2_AC_ENDIAN_CONVERT 0x00004000
1546#define DMA_RQ_C2_AC_SIGNED_CONVERT 0x00008000
1547#define DMA_RQ_C2_LOOP_END_MASK 0x0FFF0000
1548#define DMA_RQ_C2_LOOP_MASK 0x30000000
1549#define DMA_RQ_C2_NO_LOOP 0x00000000
1550#define DMA_RQ_C2_ONE_PAGE_LOOP 0x10000000
1551#define DMA_RQ_C2_TWO_PAGE_LOOP 0x20000000
1552#define DMA_RQ_C2_MULTI_PAGE_LOOP 0x30000000
1553#define DMA_RQ_C2_SIGNAL_LOOP_BACK 0x40000000
1554#define DMA_RQ_C2_SIGNAL_POST_BEGIN_PAGE 0x80000000
1555#define DMA_RQ_C2_VIRTUAL_CHANNEL_SHIFT 0
1556#define DMA_RQ_C2_LOOP_END_SHIFT 16
1557
1558/*
1559 * The following defines are for the flags in the source and destination words
1560 * of the on-chip generic DMA requestor.
1561 */
1562#define DMA_RQ_SD_ADDRESS_MASK 0x0000FFFF
1563#define DMA_RQ_SD_MEMORY_ID_MASK 0x000F0000
1564#define DMA_RQ_SD_SP_PARAM_ADDR 0x00000000
1565#define DMA_RQ_SD_SP_SAMPLE_ADDR 0x00010000
1566#define DMA_RQ_SD_SP_PROGRAM_ADDR 0x00020000
1567#define DMA_RQ_SD_SP_DEBUG_ADDR 0x00030000
1568#define DMA_RQ_SD_OMNIMEM_ADDR 0x000E0000
1569#define DMA_RQ_SD_END_FLAG 0x40000000
1570#define DMA_RQ_SD_ERROR_FLAG 0x80000000
1571#define DMA_RQ_SD_ADDRESS_SHIFT 0
1572
1573/*
1574 * The following defines are for the flags in the page map address word of the
1575 * on-chip generic DMA requestor.
1576 */
1577#define DMA_RQ_PMA_LOOP_THIRD_PAGE_ENTRY_MASK 0x00000FF8
1578#define DMA_RQ_PMA_PAGE_TABLE_MASK 0xFFFFF000
1579#define DMA_RQ_PMA_LOOP_THIRD_PAGE_ENTRY_SHIFT 3
1580#define DMA_RQ_PMA_PAGE_TABLE_SHIFT 12
1581
1582#define BA1_VARIDEC_BUF_1 0x000
1583
1584#define BA1_PDTC 0x0c0 /* BA1_PLAY_DMA_TRANSACTION_COUNT_REG */
1585#define BA1_PFIE 0x0c4 /* BA1_PLAY_FORMAT_&_INTERRUPT_ENABLE_REG */
1586#define BA1_PBA 0x0c8 /* BA1_PLAY_BUFFER_ADDRESS */
1587#define BA1_PVOL 0x0f8 /* BA1_PLAY_VOLUME_REG */
1588#define BA1_PSRC 0x288 /* BA1_PLAY_SAMPLE_RATE_CORRECTION_REG */
1589#define BA1_PCTL 0x2a4 /* BA1_PLAY_CONTROL_REG */
1590#define BA1_PPI 0x2b4 /* BA1_PLAY_PHASE_INCREMENT_REG */
1591
1592#define BA1_CCTL 0x064 /* BA1_CAPTURE_CONTROL_REG */
1593#define BA1_CIE 0x104 /* BA1_CAPTURE_INTERRUPT_ENABLE_REG */
1594#define BA1_CBA 0x10c /* BA1_CAPTURE_BUFFER_ADDRESS */
1595#define BA1_CSRC 0x2c8 /* BA1_CAPTURE_SAMPLE_RATE_CORRECTION_REG */
1596#define BA1_CCI 0x2d8 /* BA1_CAPTURE_COEFFICIENT_INCREMENT_REG */
1597#define BA1_CD 0x2e0 /* BA1_CAPTURE_DELAY_REG */
1598#define BA1_CPI 0x2f4 /* BA1_CAPTURE_PHASE_INCREMENT_REG */
1599#define BA1_CVOL 0x2f8 /* BA1_CAPTURE_VOLUME_REG */
1600
1601#define BA1_CFG1 0x134 /* BA1_CAPTURE_FRAME_GROUP_1_REG */
1602#define BA1_CFG2 0x138 /* BA1_CAPTURE_FRAME_GROUP_2_REG */
1603#define BA1_CCST 0x13c /* BA1_CAPTURE_CONSTANT_REG */
1604#define BA1_CSPB 0x340 /* BA1_CAPTURE_SPB_ADDRESS */
1605
1606/*
1607 *
1608 */
1609
1610#define CS46XX_MODE_OUTPUT (1<<0) /* MIDI UART - output */
1611#define CS46XX_MODE_INPUT (1<<1) /* MIDI UART - input */
1612
1613/*
1614 *
1615 */
1616
1617#define SAVE_REG_MAX 0x10
1618#define POWER_DOWN_ALL 0x7f0f
1619
1620/* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */
1621#define MAX_NR_AC97 4
1622#define CS46XX_PRIMARY_CODEC_INDEX 0
1623#define CS46XX_SECONDARY_CODEC_INDEX 1
1624#define CS46XX_SECONDARY_CODEC_OFFSET 0x80
1625#define CS46XX_DSP_CAPTURE_CHANNEL 1
1626
1627/* capture */
1628#define CS46XX_DSP_CAPTURE_CHANNEL 1
1629
1630/* mixer */
1631#define CS46XX_MIXER_SPDIF_INPUT_ELEMENT 1
1632#define CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT 2
1633
1634
1635struct snd_cs46xx_pcm {
1636 struct snd_dma_buffer hw_buf;
1637
1638 unsigned int ctl;
1639 unsigned int shift; /* Shift count to trasform frames in bytes */
1640 struct snd_pcm_indirect pcm_rec;
1641 struct snd_pcm_substream *substream;
1642
1643 struct dsp_pcm_channel_descriptor * pcm_channel;
1644
1645 int pcm_channel_id; /* Fron Rear, Center Lfe ... */
1646};
1647
1648struct snd_cs46xx_region {
1649 char name[24];
1650 unsigned long base;
1651 void __iomem *remap_addr;
1652 unsigned long size;
1653 struct resource *resource;
1654};
1655
1656struct snd_cs46xx {
1657 int irq;
1658 unsigned long ba0_addr;
1659 unsigned long ba1_addr;
1660 union {
1661 struct {
1662 struct snd_cs46xx_region ba0;
1663 struct snd_cs46xx_region data0;
1664 struct snd_cs46xx_region data1;
1665 struct snd_cs46xx_region pmem;
1666 struct snd_cs46xx_region reg;
1667 } name;
1668 struct snd_cs46xx_region idx[5];
1669 } region;
1670
1671 unsigned int mode;
1672
1673 struct {
1674 struct snd_dma_buffer hw_buf;
1675
1676 unsigned int ctl;
1677 unsigned int shift; /* Shift count to trasform frames in bytes */
1678 struct snd_pcm_indirect pcm_rec;
1679 struct snd_pcm_substream *substream;
1680 } capt;
1681
1682
1683 int nr_ac97_codecs;
1684 struct snd_ac97_bus *ac97_bus;
1685 struct snd_ac97 *ac97[MAX_NR_AC97];
1686
1687 struct pci_dev *pci;
1688 struct snd_card *card;
1689 struct snd_pcm *pcm;
1690
1691 struct snd_rawmidi *rmidi;
1692 struct snd_rawmidi_substream *midi_input;
1693 struct snd_rawmidi_substream *midi_output;
1694
1695 spinlock_t reg_lock;
1696 unsigned int midcr;
1697 unsigned int uartm;
1698
1699 int amplifier;
1700 void (*amplifier_ctrl)(struct snd_cs46xx *, int);
1701 void (*active_ctrl)(struct snd_cs46xx *, int);
1702 void (*mixer_init)(struct snd_cs46xx *);
1703
1704 int acpi_port;
1705 struct snd_kcontrol *eapd_switch; /* for amplifier hack */
1706 int accept_valid; /* accept mmap valid (for OSS) */
1707 int in_suspend;
1708
1709 struct gameport *gameport;
1710
1711#ifdef CONFIG_SND_CS46XX_NEW_DSP
1712 struct mutex spos_mutex;
1713
1714 struct dsp_spos_instance * dsp_spos_instance;
1715
1716 struct snd_pcm *pcm_rear;
1717 struct snd_pcm *pcm_center_lfe;
1718 struct snd_pcm *pcm_iec958;
1719#else /* for compatibility */
1720 struct snd_cs46xx_pcm *playback_pcm;
1721 unsigned int play_ctl;
1722#endif
1723
1724#ifdef CONFIG_PM
1725 u32 *saved_regs;
1726#endif
1727};
1728
1729int snd_cs46xx_create(struct snd_card *card,
1730 struct pci_dev *pci,
1731 int external_amp, int thinkpad,
1732 struct snd_cs46xx **rcodec);
1733extern const struct dev_pm_ops snd_cs46xx_pm;
1734
1735int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
1736int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
1737int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
1738int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
1739int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device);
1740int snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rmidi);
1741int snd_cs46xx_start_dsp(struct snd_cs46xx *chip);
1742int snd_cs46xx_gameport(struct snd_cs46xx *chip);
1743
1744#endif /* __SOUND_CS46XX_H */
diff --git a/sound/pci/cs46xx/cs46xx_dsp_scb_types.h b/sound/pci/cs46xx/cs46xx_dsp_scb_types.h
new file mode 100644
index 000000000000..080857ad0ca2
--- /dev/null
+++ b/sound/pci/cs46xx/cs46xx_dsp_scb_types.h
@@ -0,0 +1,1213 @@
1/*
2 * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 *
21 * NOTE: comments are copy/paste from cwcemb80.lst
22 * provided by Tom Woller at Cirrus (my only
23 * documentation about the SP OS running inside
24 * the DSP)
25 */
26
27#ifndef __CS46XX_DSP_SCB_TYPES_H__
28#define __CS46XX_DSP_SCB_TYPES_H__
29
30#include <asm/byteorder.h>
31
32#ifndef ___DSP_DUAL_16BIT_ALLOC
33#if defined(__LITTLE_ENDIAN)
34#define ___DSP_DUAL_16BIT_ALLOC(a,b) u16 a; u16 b;
35#elif defined(__BIG_ENDIAN)
36#define ___DSP_DUAL_16BIT_ALLOC(a,b) u16 b; u16 a;
37#else
38#error Not __LITTLE_ENDIAN and not __BIG_ENDIAN, then what ???
39#endif
40#endif
41
42/* This structs are used internally by the SP */
43
44struct dsp_basic_dma_req {
45 /* DMA Requestor Word 0 (DCW) fields:
46
47 31 [30-28]27 [26:24] 23 22 21 20 [19:18] [17:16] 15 14 13 12 11 10 9 8 7 6 [5:0]
48 _______________________________________________________________________________________
49 |S| SBT |D| DBT |wb|wb| | | LS | SS |Opt|Do|SSG|DSG| | | | | | | Dword |
50 |H|_____ |H|_________|S_|D |__|__|______|_______|___|ne|__ |__ |__|__|_|_|_|_|_Count -1|
51 */
52 u32 dcw; /* DMA Control Word */
53 u32 dmw; /* DMA Mode Word */
54 u32 saw; /* Source Address Word */
55 u32 daw; /* Destination Address Word */
56};
57
58struct dsp_scatter_gather_ext {
59 u32 npaw; /* Next-Page Address Word */
60
61 /* DMA Requestor Word 5 (NPCW) fields:
62
63 31-30 29 28 [27:16] [15:12] [11:3] [2:0]
64 _________________________________________________________________________________________
65 |SV |LE|SE| Sample-end byte offset | | Page-map entry offset for next | |
66 |page|__|__| ___________________________|_________|__page, if !sample-end___________|____|
67 */
68 u32 npcw; /* Next-Page Control Word */
69 u32 lbaw; /* Loop-Begin Address Word */
70 u32 nplbaw; /* Next-Page after Loop-Begin Address Word */
71 u32 sgaw; /* Scatter/Gather Address Word */
72};
73
74struct dsp_volume_control {
75 ___DSP_DUAL_16BIT_ALLOC(
76 rightTarg, /* Target volume for left & right channels */
77 leftTarg
78 )
79 ___DSP_DUAL_16BIT_ALLOC(
80 rightVol, /* Current left & right channel volumes */
81 leftVol
82 )
83};
84
85/* Generic stream control block (SCB) structure definition */
86struct dsp_generic_scb {
87 /* For streaming I/O, the DSP should never alter any words in the DMA
88 requestor or the scatter/gather extension. Only ad hoc DMA request
89 streams are free to alter the requestor (currently only occur in the
90 DOS-based MIDI controller and in debugger-inserted code).
91
92 If an SCB does not have any associated DMA requestor, these 9 ints
93 may be freed for use by other tasks, but the pointer to the SCB must
94 still be such that the insOrd:nextSCB appear at offset 9 from the
95 SCB pointer.
96
97 Basic (non scatter/gather) DMA requestor (4 ints)
98 */
99
100 /* Initialized by the host, only modified by DMA
101 R/O for the DSP task */
102 struct dsp_basic_dma_req basic_req; /* Optional */
103
104 /* Scatter/gather DMA requestor extension (5 ints)
105 Initialized by the host, only modified by DMA
106 DSP task never needs to even read these.
107 */
108 struct dsp_scatter_gather_ext sg_ext; /* Optional */
109
110 /* Sublist pointer & next stream control block (SCB) link.
111 Initialized & modified by the host R/O for the DSP task
112 */
113 ___DSP_DUAL_16BIT_ALLOC(
114 next_scb, /* REQUIRED */
115 sub_list_ptr /* REQUIRED */
116 )
117
118 /* Pointer to this tasks parameter block & stream function pointer
119 Initialized by the host R/O for the DSP task */
120 ___DSP_DUAL_16BIT_ALLOC(
121 entry_point, /* REQUIRED */
122 this_spb /* REQUIRED */
123 )
124
125 /* rsConfig register for stream buffer (rsDMA reg.
126 is loaded from basicReq.daw for incoming streams, or
127 basicReq.saw, for outgoing streams)
128
129 31 30 29 [28:24] [23:16] 15 14 13 12 11 10 9 8 7 6 5 4 [3:0]
130 ______________________________________________________________________________
131 |DMA |D|maxDMAsize| streamNum|dir|p| | | | | | |ds |shr 1|rev Cy | mod |
132 |prio |_|__________|__________|___|_|__|__|__|__|_|_|___|_____|_______|_______|
133 31 30 29 [28:24] [23:16] 15 14 13 12 11 10 9 8 7 6 5 4 [3:0]
134
135
136 Initialized by the host R/O for the DSP task
137 */
138 u32 strm_rs_config; /* REQUIRED */
139 //
140 /* On mixer input streams: indicates mixer input stream configuration
141 On Tees, this is copied from the stream being snooped
142
143 Stream sample pointer & MAC-unit mode for this stream
144
145 Initialized by the host Updated by the DSP task
146 */
147 u32 strm_buf_ptr; /* REQUIRED */
148
149 /* On mixer input streams: points to next mixer input and is updated by the
150 mixer subroutine in the "parent" DSP task
151 (least-significant 16 bits are preserved, unused)
152
153 On Tees, the pointer is copied from the stream being snooped on
154 initialization, and, subsequently, it is copied into the
155 stream being snooped.
156
157 On wavetable/3D voices: the strmBufPtr will use all 32 bits to allow for
158 fractional phase accumulation
159
160 Fractional increment per output sample in the input sample buffer
161
162 (Not used on mixer input streams & redefined on Tees)
163 On wavetable/3D voices: this 32-bit word specifies the integer.fractional
164 increment per output sample.
165 */
166 u32 strmPhiIncr;
167
168
169 /* Standard stereo volume control
170 Initialized by the host (host updates target volumes)
171
172 Current volumes update by the DSP task
173 On mixer input streams: required & updated by the mixer subroutine in the
174 "parent" DSP task
175
176 On Tees, both current & target volumes are copied up on initialization,
177 and, subsequently, the target volume is copied up while the current
178 volume is copied down.
179
180 These two 32-bit words are redefined for wavetable & 3-D voices.
181 */
182 struct dsp_volume_control vol_ctrl_t; /* Optional */
183};
184
185
186struct dsp_spos_control_block {
187 /* WARNING: Certain items in this structure are modified by the host
188 Any dword that can be modified by the host, must not be
189 modified by the SP as the host can only do atomic dword
190 writes, and to do otherwise, even a read modify write,
191 may lead to corrupted data on the SP.
192
193 This rule does not apply to one off boot time initialisation prior to starting the SP
194 */
195
196
197 ___DSP_DUAL_16BIT_ALLOC(
198 /* First element on the Hyper forground task tree */
199 hfg_tree_root_ptr, /* HOST */
200 /* First 3 dwords are written by the host and read-only on the DSP */
201 hfg_stack_base /* HOST */
202 )
203
204 ___DSP_DUAL_16BIT_ALLOC(
205 /* Point to this data structure to enable easy access */
206 spos_cb_ptr, /* SP */
207 prev_task_tree_ptr /* SP && HOST */
208 )
209
210 ___DSP_DUAL_16BIT_ALLOC(
211 /* Currently Unused */
212 xxinterval_timer_period,
213 /* Enable extension of SPOS data structure */
214 HFGSPB_ptr
215 )
216
217
218 ___DSP_DUAL_16BIT_ALLOC(
219 xxnum_HFG_ticks_thisInterval,
220 /* Modified by the DSP */
221 xxnum_tntervals
222 )
223
224
225 /* Set by DSP upon encountering a trap (breakpoint) or a spurious
226 interrupt. The host must clear this dword after reading it
227 upon receiving spInt1. */
228 ___DSP_DUAL_16BIT_ALLOC(
229 spurious_int_flag, /* (Host & SP) Nature of the spurious interrupt */
230 trap_flag /* (Host & SP) Nature of detected Trap */
231 )
232
233 ___DSP_DUAL_16BIT_ALLOC(
234 unused2,
235 invalid_IP_flag /* (Host & SP ) Indicate detection of invalid instruction pointer */
236 )
237
238 ___DSP_DUAL_16BIT_ALLOC(
239 /* pointer to forground task tree header for use in next task search */
240 fg_task_tree_hdr_ptr, /* HOST */
241 /* Data structure for controlling synchronous link update */
242 hfg_sync_update_ptr /* HOST */
243 )
244
245 ___DSP_DUAL_16BIT_ALLOC(
246 begin_foreground_FCNT, /* SP */
247 /* Place holder for holding sleep timing */
248 last_FCNT_before_sleep /* SP */
249 )
250
251 ___DSP_DUAL_16BIT_ALLOC(
252 unused7, /* SP */
253 next_task_treePtr /* SP */
254 )
255
256 u32 unused5;
257
258 ___DSP_DUAL_16BIT_ALLOC(
259 active_flags, /* SP */
260 /* State flags, used to assist control of execution of Hyper Forground */
261 HFG_flags /* SP */
262 )
263
264 ___DSP_DUAL_16BIT_ALLOC(
265 unused9,
266 unused8
267 )
268
269 /* Space for saving enough context so that we can set up enough
270 to save some more context.
271 */
272 u32 rFE_save_for_invalid_IP;
273 u32 r32_save_for_spurious_int;
274 u32 r32_save_for_trap;
275 u32 r32_save_for_HFG;
276};
277
278/* SPB for MIX_TO_OSTREAM algorithm family */
279struct dsp_mix2_ostream_spb
280{
281 /* 16b.16b integer.frac approximation to the
282 number of 3 sample triplets to output each
283 frame. (approximation must be floor, to
284 insure that the fractional error is always
285 positive)
286 */
287 u32 outTripletsPerFrame;
288
289 /* 16b.16b integer.frac accumulated number of
290 output triplets since the start of group
291 */
292 u32 accumOutTriplets;
293};
294
295/* SCB for Timing master algorithm */
296struct dsp_timing_master_scb {
297 /* First 12 dwords from generic_scb_t */
298 struct dsp_basic_dma_req basic_req; /* Optional */
299 struct dsp_scatter_gather_ext sg_ext; /* Optional */
300 ___DSP_DUAL_16BIT_ALLOC(
301 next_scb, /* REQUIRED */
302 sub_list_ptr /* REQUIRED */
303 )
304
305 ___DSP_DUAL_16BIT_ALLOC(
306 entry_point, /* REQUIRED */
307 this_spb /* REQUIRED */
308 )
309
310 ___DSP_DUAL_16BIT_ALLOC(
311 /* Initial values are 0000:xxxx */
312 reserved,
313 extra_sample_accum
314 )
315
316
317 /* Initial values are xxxx:0000
318 hi: Current CODEC output FIFO pointer
319 (0 to 0x0f)
320 lo: Flag indicating that the CODEC
321 FIFO is sync'd (host clears to
322 resynchronize the FIFO pointer
323 upon start/restart)
324 */
325 ___DSP_DUAL_16BIT_ALLOC(
326 codec_FIFO_syncd,
327 codec_FIFO_ptr
328 )
329
330 /* Init. 8000:0005 for 44.1k
331 8000:0001 for 48k
332 hi: Fractional sample accumulator 0.16b
333 lo: Number of frames remaining to be
334 processed in the current group of
335 frames
336 */
337 ___DSP_DUAL_16BIT_ALLOC(
338 frac_samp_accum_qm1,
339 TM_frms_left_in_group
340 )
341
342 /* Init. 0001:0005 for 44.1k
343 0000:0001 for 48k
344 hi: Fractional sample correction factor 0.16b
345 to be added every frameGroupLength frames
346 to correct for truncation error in
347 nsamp_per_frm_q15
348 lo: Number of frames in the group
349 */
350 ___DSP_DUAL_16BIT_ALLOC(
351 frac_samp_correction_qm1,
352 TM_frm_group_length
353 )
354
355 /* Init. 44.1k*65536/8k = 0x00058333 for 44.1k
356 48k*65536/8k = 0x00060000 for 48k
357 16b.16b integer.frac approximation to the
358 number of samples to output each frame.
359 (approximation must be floor, to insure */
360 u32 nsamp_per_frm_q15;
361};
362
363/* SCB for CODEC output algorithm */
364struct dsp_codec_output_scb {
365 /* First 13 dwords from generic_scb_t */
366 struct dsp_basic_dma_req basic_req; /* Optional */
367 struct dsp_scatter_gather_ext sg_ext; /* Optional */
368 ___DSP_DUAL_16BIT_ALLOC(
369 next_scb, /* REQUIRED */
370 sub_list_ptr /* REQUIRED */
371 )
372
373 ___DSP_DUAL_16BIT_ALLOC(
374 entry_point, /* REQUIRED */
375 this_spb /* REQUIRED */
376 )
377
378 u32 strm_rs_config; /* REQUIRED */
379
380 u32 strm_buf_ptr; /* REQUIRED */
381
382 /* NOTE: The CODEC output task reads samples from the first task on its
383 sublist at the stream buffer pointer (init. to lag DMA destination
384 address word). After the required number of samples is transferred,
385 the CODEC output task advances sub_list_ptr->strm_buf_ptr past the samples
386 consumed.
387 */
388
389 /* Init. 0000:0010 for SDout
390 0060:0010 for SDout2
391 0080:0010 for SDout3
392 hi: Base IO address of FIFO to which
393 the left-channel samples are to
394 be written.
395 lo: Displacement for the base IO
396 address for left-channel to obtain
397 the base IO address for the FIFO
398 to which the right-channel samples
399 are to be written.
400 */
401 ___DSP_DUAL_16BIT_ALLOC(
402 left_chan_base_IO_addr,
403 right_chan_IO_disp
404 )
405
406
407 /* Init: 0x0080:0004 for non-AC-97
408 Init: 0x0080:0000 for AC-97
409 hi: Exponential volume change rate
410 for input stream
411 lo: Positive shift count to shift the
412 16-bit input sample to obtain the
413 32-bit output word
414 */
415 ___DSP_DUAL_16BIT_ALLOC(
416 CO_scale_shift_count,
417 CO_exp_vol_change_rate
418 )
419
420 /* Pointer to SCB at end of input chain */
421 ___DSP_DUAL_16BIT_ALLOC(
422 reserved,
423 last_sub_ptr
424 )
425};
426
427/* SCB for CODEC input algorithm */
428struct dsp_codec_input_scb {
429 /* First 13 dwords from generic_scb_t */
430 struct dsp_basic_dma_req basic_req; /* Optional */
431 struct dsp_scatter_gather_ext sg_ext; /* Optional */
432 ___DSP_DUAL_16BIT_ALLOC(
433 next_scb, /* REQUIRED */
434 sub_list_ptr /* REQUIRED */
435 )
436
437 ___DSP_DUAL_16BIT_ALLOC(
438 entry_point, /* REQUIRED */
439 this_spb /* REQUIRED */
440 )
441
442 u32 strm_rs_config; /* REQUIRED */
443 u32 strm_buf_ptr; /* REQUIRED */
444
445 /* NOTE: The CODEC input task reads samples from the hardware FIFO
446 sublist at the DMA source address word (sub_list_ptr->basic_req.saw).
447 After the required number of samples is transferred, the CODEC
448 output task advances sub_list_ptr->basic_req.saw past the samples
449 consumed. SPuD must initialize the sub_list_ptr->basic_req.saw
450 to point half-way around from the initial sub_list_ptr->strm_nuf_ptr
451 to allow for lag/lead.
452 */
453
454 /* Init. 0000:0010 for SDout
455 0060:0010 for SDout2
456 0080:0010 for SDout3
457 hi: Base IO address of FIFO to which
458 the left-channel samples are to
459 be written.
460 lo: Displacement for the base IO
461 address for left-channel to obtain
462 the base IO address for the FIFO
463 to which the right-channel samples
464 are to be written.
465 */
466 ___DSP_DUAL_16BIT_ALLOC(
467 rightChanINdisp,
468 left_chan_base_IN_addr
469 )
470 /* Init. ?:fffc
471 lo: Negative shift count to shift the
472 32-bit input dword to obtain the
473 16-bit sample msb-aligned (count
474 is negative to shift left)
475 */
476 ___DSP_DUAL_16BIT_ALLOC(
477 scaleShiftCount,
478 reserver1
479 )
480
481 u32 reserved2;
482};
483
484
485struct dsp_pcm_serial_input_scb {
486 /* First 13 dwords from generic_scb_t */
487 struct dsp_basic_dma_req basic_req; /* Optional */
488 struct dsp_scatter_gather_ext sg_ext; /* Optional */
489 ___DSP_DUAL_16BIT_ALLOC(
490 next_scb, /* REQUIRED */
491 sub_list_ptr /* REQUIRED */
492 )
493
494 ___DSP_DUAL_16BIT_ALLOC(
495 entry_point, /* REQUIRED */
496 this_spb /* REQUIRED */
497 )
498
499 u32 strm_buf_ptr; /* REQUIRED */
500 u32 strm_rs_config; /* REQUIRED */
501
502 /* Init. Ptr to CODEC input SCB
503 hi: Pointer to the SCB containing the
504 input buffer to which CODEC input
505 samples are written
506 lo: Flag indicating the link to the CODEC
507 input task is to be initialized
508 */
509 ___DSP_DUAL_16BIT_ALLOC(
510 init_codec_input_link,
511 codec_input_buf_scb
512 )
513
514 /* Initialized by the host (host updates target volumes) */
515 struct dsp_volume_control psi_vol_ctrl;
516
517};
518
519struct dsp_src_task_scb {
520 ___DSP_DUAL_16BIT_ALLOC(
521 frames_left_in_gof,
522 gofs_left_in_sec
523 )
524
525 ___DSP_DUAL_16BIT_ALLOC(
526 const2_thirds,
527 num_extra_tnput_samples
528 )
529
530 ___DSP_DUAL_16BIT_ALLOC(
531 cor_per_gof,
532 correction_per_sec
533 )
534
535 ___DSP_DUAL_16BIT_ALLOC(
536 output_buf_producer_ptr,
537 junk_DMA_MID
538 )
539
540 ___DSP_DUAL_16BIT_ALLOC(
541 gof_length,
542 gofs_per_sec
543 )
544
545 u32 input_buf_strm_config;
546
547 ___DSP_DUAL_16BIT_ALLOC(
548 reserved_for_SRC_use,
549 input_buf_consumer_ptr
550 )
551
552 u32 accum_phi;
553
554 ___DSP_DUAL_16BIT_ALLOC(
555 exp_src_vol_change_rate,
556 input_buf_producer_ptr
557 )
558
559 ___DSP_DUAL_16BIT_ALLOC(
560 src_next_scb,
561 src_sub_list_ptr
562 )
563
564 ___DSP_DUAL_16BIT_ALLOC(
565 src_entry_point,
566 src_this_sbp
567 )
568
569 u32 src_strm_rs_config;
570 u32 src_strm_buf_ptr;
571
572 u32 phiIncr6int_26frac;
573
574 struct dsp_volume_control src_vol_ctrl;
575};
576
577struct dsp_decimate_by_pow2_scb {
578 /* decimationFactor = 2, 4, or 8 (larger factors waste too much memory
579 when compared to cascading decimators)
580 */
581 ___DSP_DUAL_16BIT_ALLOC(
582 dec2_coef_base_ptr,
583 dec2_coef_increment
584 )
585
586 /* coefIncrement = 128 / decimationFactor (for our ROM filter)
587 coefBasePtr = 0x8000 (for our ROM filter)
588 */
589 ___DSP_DUAL_16BIT_ALLOC(
590 dec2_in_samples_per_out_triplet,
591 dec2_extra_in_samples
592 )
593 /* extraInSamples: # of accumulated, unused input samples (init. to 0)
594 inSamplesPerOutTriplet = 3 * decimationFactor
595 */
596
597 ___DSP_DUAL_16BIT_ALLOC(
598 dec2_const2_thirds,
599 dec2_half_num_taps_mp5
600 )
601 /* halfNumTapsM5: (1/2 number of taps in decimation filter) minus 5
602 const2thirds: constant 2/3 in 16Q0 format (sign.15)
603 */
604
605 ___DSP_DUAL_16BIT_ALLOC(
606 dec2_output_buf_producer_ptr,
607 dec2_junkdma_mid
608 )
609
610 u32 dec2_reserved2;
611
612 u32 dec2_input_nuf_strm_config;
613 /* inputBufStrmConfig: rsConfig for the input buffer to the decimator
614 (buffer size = decimationFactor * 32 dwords)
615 */
616
617 ___DSP_DUAL_16BIT_ALLOC(
618 dec2_phi_incr,
619 dec2_input_buf_consumer_ptr
620 )
621 /* inputBufConsumerPtr: Input buffer read pointer (into SRC filter)
622 phiIncr = decimationFactor * 4
623 */
624
625 u32 dec2_reserved3;
626
627 ___DSP_DUAL_16BIT_ALLOC(
628 dec2_exp_vol_change_rate,
629 dec2_input_buf_producer_ptr
630 )
631 /* inputBufProducerPtr: Input buffer write pointer
632 expVolChangeRate: Exponential volume change rate for possible
633 future mixer on input streams
634 */
635
636 ___DSP_DUAL_16BIT_ALLOC(
637 dec2_next_scb,
638 dec2_sub_list_ptr
639 )
640
641 ___DSP_DUAL_16BIT_ALLOC(
642 dec2_entry_point,
643 dec2_this_spb
644 )
645
646 u32 dec2_strm_rs_config;
647 u32 dec2_strm_buf_ptr;
648
649 u32 dec2_reserved4;
650
651 struct dsp_volume_control dec2_vol_ctrl; /* Not used! */
652};
653
654struct dsp_vari_decimate_scb {
655 ___DSP_DUAL_16BIT_ALLOC(
656 vdec_frames_left_in_gof,
657 vdec_gofs_left_in_sec
658 )
659
660 ___DSP_DUAL_16BIT_ALLOC(
661 vdec_const2_thirds,
662 vdec_extra_in_samples
663 )
664 /* extraInSamples: # of accumulated, unused input samples (init. to 0)
665 const2thirds: constant 2/3 in 16Q0 format (sign.15) */
666
667 ___DSP_DUAL_16BIT_ALLOC(
668 vdec_cor_per_gof,
669 vdec_correction_per_sec
670 )
671
672 ___DSP_DUAL_16BIT_ALLOC(
673 vdec_output_buf_producer_ptr,
674 vdec_input_buf_consumer_ptr
675 )
676 /* inputBufConsumerPtr: Input buffer read pointer (into SRC filter) */
677 ___DSP_DUAL_16BIT_ALLOC(
678 vdec_gof_length,
679 vdec_gofs_per_sec
680 )
681
682 u32 vdec_input_buf_strm_config;
683 /* inputBufStrmConfig: rsConfig for the input buffer to the decimator
684 (buffer size = 64 dwords) */
685 u32 vdec_coef_increment;
686 /* coefIncrement = - 128.0 / decimationFactor (as a 32Q15 number) */
687
688 u32 vdec_accumphi;
689 /* accumPhi: accumulated fractional phase increment (6.26) */
690
691 ___DSP_DUAL_16BIT_ALLOC(
692 vdec_exp_vol_change_rate,
693 vdec_input_buf_producer_ptr
694 )
695 /* inputBufProducerPtr: Input buffer write pointer
696 expVolChangeRate: Exponential volume change rate for possible
697 future mixer on input streams */
698
699 ___DSP_DUAL_16BIT_ALLOC(
700 vdec_next_scb,
701 vdec_sub_list_ptr
702 )
703
704 ___DSP_DUAL_16BIT_ALLOC(
705 vdec_entry_point,
706 vdec_this_spb
707 )
708
709 u32 vdec_strm_rs_config;
710 u32 vdec_strm_buf_ptr;
711
712 u32 vdec_phi_incr_6int_26frac;
713
714 struct dsp_volume_control vdec_vol_ctrl;
715};
716
717
718/* SCB for MIX_TO_OSTREAM algorithm family */
719struct dsp_mix2_ostream_scb {
720 /* First 13 dwords from generic_scb_t */
721 struct dsp_basic_dma_req basic_req; /* Optional */
722 struct dsp_scatter_gather_ext sg_ext; /* Optional */
723 ___DSP_DUAL_16BIT_ALLOC(
724 next_scb, /* REQUIRED */
725 sub_list_ptr /* REQUIRED */
726 )
727
728 ___DSP_DUAL_16BIT_ALLOC(
729 entry_point, /* REQUIRED */
730 this_spb /* REQUIRED */
731 )
732
733 u32 strm_rs_config; /* REQUIRED */
734 u32 strm_buf_ptr; /* REQUIRED */
735
736
737 /* hi: Number of mixed-down input triplets
738 computed since start of group
739 lo: Number of frames remaining to be
740 processed in the current group of
741 frames
742 */
743 ___DSP_DUAL_16BIT_ALLOC(
744 frames_left_in_group,
745 accum_input_triplets
746 )
747
748 /* hi: Exponential volume change rate
749 for mixer on input streams
750 lo: Number of frames in the group
751 */
752 ___DSP_DUAL_16BIT_ALLOC(
753 frame_group_length,
754 exp_vol_change_rate
755 )
756
757 ___DSP_DUAL_16BIT_ALLOC(
758 const_FFFF,
759 const_zero
760 )
761};
762
763
764/* SCB for S16_MIX algorithm */
765struct dsp_mix_only_scb {
766 /* First 13 dwords from generic_scb_t */
767 struct dsp_basic_dma_req basic_req; /* Optional */
768 struct dsp_scatter_gather_ext sg_ext; /* Optional */
769 ___DSP_DUAL_16BIT_ALLOC(
770 next_scb, /* REQUIRED */
771 sub_list_ptr /* REQUIRED */
772 )
773
774 ___DSP_DUAL_16BIT_ALLOC(
775 entry_point, /* REQUIRED */
776 this_spb /* REQUIRED */
777 )
778
779 u32 strm_rs_config; /* REQUIRED */
780 u32 strm_buf_ptr; /* REQUIRED */
781
782 u32 reserved;
783 struct dsp_volume_control vol_ctrl;
784};
785
786/* SCB for the async. CODEC input algorithm */
787struct dsp_async_codec_input_scb {
788 u32 io_free2;
789
790 u32 io_current_total;
791 u32 io_previous_total;
792
793 u16 io_count;
794 u16 io_count_limit;
795
796 u16 o_fifo_base_addr;
797 u16 ost_mo_format;
798 /* 1 = stereo; 0 = mono
799 xxx for ASER 1 (not allowed); 118 for ASER2 */
800
801 u32 ostrm_rs_config;
802 u32 ostrm_buf_ptr;
803
804 ___DSP_DUAL_16BIT_ALLOC(
805 io_sclks_per_lr_clk,
806 io_io_enable
807 )
808
809 u32 io_free4;
810
811 ___DSP_DUAL_16BIT_ALLOC(
812 io_next_scb,
813 io_sub_list_ptr
814 )
815
816 ___DSP_DUAL_16BIT_ALLOC(
817 io_entry_point,
818 io_this_spb
819 )
820
821 u32 istrm_rs_config;
822 u32 istrm_buf_ptr;
823
824 /* Init. 0000:8042: for ASER1
825 0000:8044: for ASER2 */
826 ___DSP_DUAL_16BIT_ALLOC(
827 io_stat_reg_addr,
828 iofifo_pointer
829 )
830
831 /* Init 1 stero:100 ASER1
832 Init 0 mono:110 ASER2
833 */
834 ___DSP_DUAL_16BIT_ALLOC(
835 ififo_base_addr,
836 ist_mo_format
837 )
838
839 u32 i_free;
840};
841
842
843/* SCB for the SP/DIF CODEC input and output */
844struct dsp_spdifiscb {
845 ___DSP_DUAL_16BIT_ALLOC(
846 status_ptr,
847 status_start_ptr
848 )
849
850 u32 current_total;
851 u32 previous_total;
852
853 ___DSP_DUAL_16BIT_ALLOC(
854 count,
855 count_limit
856 )
857
858 u32 status_data;
859
860 ___DSP_DUAL_16BIT_ALLOC(
861 status,
862 free4
863 )
864
865 u32 free3;
866
867 ___DSP_DUAL_16BIT_ALLOC(
868 free2,
869 bit_count
870 )
871
872 u32 temp_status;
873
874 ___DSP_DUAL_16BIT_ALLOC(
875 next_SCB,
876 sub_list_ptr
877 )
878
879 ___DSP_DUAL_16BIT_ALLOC(
880 entry_point,
881 this_spb
882 )
883
884 u32 strm_rs_config;
885 u32 strm_buf_ptr;
886
887 ___DSP_DUAL_16BIT_ALLOC(
888 stat_reg_addr,
889 fifo_pointer
890 )
891
892 ___DSP_DUAL_16BIT_ALLOC(
893 fifo_base_addr,
894 st_mo_format
895 )
896
897 u32 free1;
898};
899
900
901/* SCB for the SP/DIF CODEC input and output */
902struct dsp_spdifoscb {
903
904 u32 free2;
905
906 u32 free3[4];
907
908 /* Need to be here for compatibility with AsynchFGTxCode */
909 u32 strm_rs_config;
910
911 u32 strm_buf_ptr;
912
913 ___DSP_DUAL_16BIT_ALLOC(
914 status,
915 free5
916 )
917
918 u32 free4;
919
920 ___DSP_DUAL_16BIT_ALLOC(
921 next_scb,
922 sub_list_ptr
923 )
924
925 ___DSP_DUAL_16BIT_ALLOC(
926 entry_point,
927 this_spb
928 )
929
930 u32 free6[2];
931
932 ___DSP_DUAL_16BIT_ALLOC(
933 stat_reg_addr,
934 fifo_pointer
935 )
936
937 ___DSP_DUAL_16BIT_ALLOC(
938 fifo_base_addr,
939 st_mo_format
940 )
941
942 u32 free1;
943};
944
945
946struct dsp_asynch_fg_rx_scb {
947 ___DSP_DUAL_16BIT_ALLOC(
948 bot_buf_mask,
949 buf_Mask
950 )
951
952 ___DSP_DUAL_16BIT_ALLOC(
953 max,
954 min
955 )
956
957 ___DSP_DUAL_16BIT_ALLOC(
958 old_producer_pointer,
959 hfg_scb_ptr
960 )
961
962 ___DSP_DUAL_16BIT_ALLOC(
963 delta,
964 adjust_count
965 )
966
967 u32 unused2[5];
968
969 ___DSP_DUAL_16BIT_ALLOC(
970 sibling_ptr,
971 child_ptr
972 )
973
974 ___DSP_DUAL_16BIT_ALLOC(
975 code_ptr,
976 this_ptr
977 )
978
979 u32 strm_rs_config;
980
981 u32 strm_buf_ptr;
982
983 u32 unused_phi_incr;
984
985 ___DSP_DUAL_16BIT_ALLOC(
986 right_targ,
987 left_targ
988 )
989
990 ___DSP_DUAL_16BIT_ALLOC(
991 right_vol,
992 left_vol
993 )
994};
995
996
997struct dsp_asynch_fg_tx_scb {
998 ___DSP_DUAL_16BIT_ALLOC(
999 not_buf_mask,
1000 buf_mask
1001 )
1002
1003 ___DSP_DUAL_16BIT_ALLOC(
1004 max,
1005 min
1006 )
1007
1008 ___DSP_DUAL_16BIT_ALLOC(
1009 unused1,
1010 hfg_scb_ptr
1011 )
1012
1013 ___DSP_DUAL_16BIT_ALLOC(
1014 delta,
1015 adjust_count
1016 )
1017
1018 u32 accum_phi;
1019
1020 ___DSP_DUAL_16BIT_ALLOC(
1021 unused2,
1022 const_one_third
1023 )
1024
1025 u32 unused3[3];
1026
1027 ___DSP_DUAL_16BIT_ALLOC(
1028 sibling_ptr,
1029 child_ptr
1030 )
1031
1032 ___DSP_DUAL_16BIT_ALLOC(
1033 codePtr,
1034 this_ptr
1035 )
1036
1037 u32 strm_rs_config;
1038
1039 u32 strm_buf_ptr;
1040
1041 u32 phi_incr;
1042
1043 ___DSP_DUAL_16BIT_ALLOC(
1044 unused_right_targ,
1045 unused_left_targ
1046 )
1047
1048 ___DSP_DUAL_16BIT_ALLOC(
1049 unused_right_vol,
1050 unused_left_vol
1051 )
1052};
1053
1054
1055struct dsp_output_snoop_scb {
1056 /* First 13 dwords from generic_scb_t */
1057 struct dsp_basic_dma_req basic_req; /* Optional */
1058 struct dsp_scatter_gather_ext sg_ext; /* Optional */
1059 ___DSP_DUAL_16BIT_ALLOC(
1060 next_scb, /* REQUIRED */
1061 sub_list_ptr /* REQUIRED */
1062 )
1063
1064 ___DSP_DUAL_16BIT_ALLOC(
1065 entry_point, /* REQUIRED */
1066 this_spb /* REQUIRED */
1067 )
1068
1069 u32 strm_rs_config; /* REQUIRED */
1070 u32 strm_buf_ptr; /* REQUIRED */
1071
1072 ___DSP_DUAL_16BIT_ALLOC(
1073 init_snoop_input_link,
1074 snoop_child_input_scb
1075 )
1076
1077 u32 snoop_input_buf_ptr;
1078
1079 ___DSP_DUAL_16BIT_ALLOC(
1080 reserved,
1081 input_scb
1082 )
1083};
1084
1085struct dsp_spio_write_scb {
1086 ___DSP_DUAL_16BIT_ALLOC(
1087 address1,
1088 address2
1089 )
1090
1091 u32 data1;
1092
1093 u32 data2;
1094
1095 ___DSP_DUAL_16BIT_ALLOC(
1096 address3,
1097 address4
1098 )
1099
1100 u32 data3;
1101
1102 u32 data4;
1103
1104 ___DSP_DUAL_16BIT_ALLOC(
1105 unused1,
1106 data_ptr
1107 )
1108
1109 u32 unused2[2];
1110
1111 ___DSP_DUAL_16BIT_ALLOC(
1112 sibling_ptr,
1113 child_ptr
1114 )
1115
1116 ___DSP_DUAL_16BIT_ALLOC(
1117 entry_point,
1118 this_ptr
1119 )
1120
1121 u32 unused3[5];
1122};
1123
1124struct dsp_magic_snoop_task {
1125 u32 i0;
1126 u32 i1;
1127
1128 u32 strm_buf_ptr1;
1129
1130 u16 i2;
1131 u16 snoop_scb;
1132
1133 u32 i3;
1134 u32 i4;
1135 u32 i5;
1136 u32 i6;
1137
1138 u32 i7;
1139
1140 ___DSP_DUAL_16BIT_ALLOC(
1141 next_scb,
1142 sub_list_ptr
1143 )
1144
1145 ___DSP_DUAL_16BIT_ALLOC(
1146 entry_point,
1147 this_ptr
1148 )
1149
1150 u32 strm_buf_config;
1151 u32 strm_buf_ptr2;
1152
1153 u32 i8;
1154
1155 struct dsp_volume_control vdec_vol_ctrl;
1156};
1157
1158
1159struct dsp_filter_scb {
1160 ___DSP_DUAL_16BIT_ALLOC(
1161 a0_right, /* 0x00 */
1162 a0_left
1163 )
1164 ___DSP_DUAL_16BIT_ALLOC(
1165 a1_right, /* 0x01 */
1166 a1_left
1167 )
1168 ___DSP_DUAL_16BIT_ALLOC(
1169 a2_right, /* 0x02 */
1170 a2_left
1171 )
1172 ___DSP_DUAL_16BIT_ALLOC(
1173 output_buf_ptr, /* 0x03 */
1174 init
1175 )
1176
1177 ___DSP_DUAL_16BIT_ALLOC(
1178 filter_unused3, /* 0x04 */
1179 filter_unused2
1180 )
1181
1182 u32 prev_sample_output1; /* 0x05 */
1183 u32 prev_sample_output2; /* 0x06 */
1184 u32 prev_sample_input1; /* 0x07 */
1185 u32 prev_sample_input2; /* 0x08 */
1186
1187 ___DSP_DUAL_16BIT_ALLOC(
1188 next_scb_ptr, /* 0x09 */
1189 sub_list_ptr
1190 )
1191
1192 ___DSP_DUAL_16BIT_ALLOC(
1193 entry_point, /* 0x0A */
1194 spb_ptr
1195 )
1196
1197 u32 strm_rs_config; /* 0x0B */
1198 u32 strm_buf_ptr; /* 0x0C */
1199
1200 ___DSP_DUAL_16BIT_ALLOC(
1201 b0_right, /* 0x0D */
1202 b0_left
1203 )
1204 ___DSP_DUAL_16BIT_ALLOC(
1205 b1_right, /* 0x0E */
1206 b1_left
1207 )
1208 ___DSP_DUAL_16BIT_ALLOC(
1209 b2_right, /* 0x0F */
1210 b2_left
1211 )
1212};
1213#endif /* __DSP_SCB_TYPES_H__ */
diff --git a/sound/pci/cs46xx/cs46xx_dsp_spos.h b/sound/pci/cs46xx/cs46xx_dsp_spos.h
new file mode 100644
index 000000000000..8008c59288a6
--- /dev/null
+++ b/sound/pci/cs46xx/cs46xx_dsp_spos.h
@@ -0,0 +1,234 @@
1/*
2 * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#ifndef __CS46XX_DSP_SPOS_H__
23#define __CS46XX_DSP_SPOS_H__
24
25#include "cs46xx_dsp_scb_types.h"
26#include "cs46xx_dsp_task_types.h"
27
28#define SYMBOL_CONSTANT 0x0
29#define SYMBOL_SAMPLE 0x1
30#define SYMBOL_PARAMETER 0x2
31#define SYMBOL_CODE 0x3
32
33#define SEGTYPE_SP_PROGRAM 0x00000001
34#define SEGTYPE_SP_PARAMETER 0x00000002
35#define SEGTYPE_SP_SAMPLE 0x00000003
36#define SEGTYPE_SP_COEFFICIENT 0x00000004
37
38#define DSP_SPOS_UU 0x0deadul /* unused */
39#define DSP_SPOS_DC 0x0badul /* don't care */
40#define DSP_SPOS_DC_DC 0x0bad0badul /* don't care */
41#define DSP_SPOS_UUUU 0xdeadc0edul /* unused */
42#define DSP_SPOS_UUHI 0xdeadul
43#define DSP_SPOS_UULO 0xc0edul
44#define DSP_SPOS_DCDC 0x0badf1d0ul /* don't care */
45#define DSP_SPOS_DCDCHI 0x0badul
46#define DSP_SPOS_DCDCLO 0xf1d0ul
47
48#define DSP_MAX_TASK_NAME 60
49#define DSP_MAX_SYMBOL_NAME 100
50#define DSP_MAX_SCB_NAME 60
51#define DSP_MAX_SCB_DESC 200
52#define DSP_MAX_TASK_DESC 50
53
54#define DSP_MAX_PCM_CHANNELS 32
55#define DSP_MAX_SRC_NR 14
56
57#define DSP_PCM_MAIN_CHANNEL 1
58#define DSP_PCM_REAR_CHANNEL 2
59#define DSP_PCM_CENTER_LFE_CHANNEL 3
60#define DSP_PCM_S71_CHANNEL 4 /* surround 7.1 */
61#define DSP_IEC958_CHANNEL 5
62
63#define DSP_SPDIF_STATUS_OUTPUT_ENABLED 1
64#define DSP_SPDIF_STATUS_PLAYBACK_OPEN 2
65#define DSP_SPDIF_STATUS_HW_ENABLED 4
66#define DSP_SPDIF_STATUS_INPUT_CTRL_ENABLED 8
67
68struct dsp_symbol_entry {
69 u32 address;
70 char symbol_name[DSP_MAX_SYMBOL_NAME];
71 int symbol_type;
72
73 /* initialized by driver */
74 struct dsp_module_desc * module;
75 int deleted;
76};
77
78struct dsp_symbol_desc {
79 int nsymbols;
80
81 struct dsp_symbol_entry *symbols;
82
83 /* initialized by driver */
84 int highest_frag_index;
85};
86
87struct dsp_segment_desc {
88 int segment_type;
89 u32 offset;
90 u32 size;
91 u32 * data;
92};
93
94struct dsp_module_desc {
95 char * module_name;
96 struct dsp_symbol_desc symbol_table;
97 int nsegments;
98 struct dsp_segment_desc * segments;
99
100 /* initialized by driver */
101 u32 overlay_begin_address;
102 u32 load_address;
103 int nfixups;
104};
105
106struct dsp_scb_descriptor {
107 char scb_name[DSP_MAX_SCB_NAME];
108 u32 address;
109 int index;
110 u32 *data;
111
112 struct dsp_scb_descriptor * sub_list_ptr;
113 struct dsp_scb_descriptor * next_scb_ptr;
114 struct dsp_scb_descriptor * parent_scb_ptr;
115
116 struct dsp_symbol_entry * task_entry;
117 struct dsp_symbol_entry * scb_symbol;
118
119 struct snd_info_entry *proc_info;
120 int ref_count;
121
122 u16 volume[2];
123 unsigned int deleted :1;
124 unsigned int updated :1;
125 unsigned int volume_set :1;
126};
127
128struct dsp_task_descriptor {
129 char task_name[DSP_MAX_TASK_NAME];
130 int size;
131 u32 address;
132 int index;
133 u32 *data;
134};
135
136struct dsp_pcm_channel_descriptor {
137 int active;
138 int src_slot;
139 int pcm_slot;
140 u32 sample_rate;
141 u32 unlinked;
142 struct dsp_scb_descriptor * pcm_reader_scb;
143 struct dsp_scb_descriptor * src_scb;
144 struct dsp_scb_descriptor * mixer_scb;
145
146 void * private_data;
147};
148
149struct dsp_spos_instance {
150 struct dsp_symbol_desc symbol_table; /* currently available loaded symbols in SP */
151
152 int nmodules;
153 struct dsp_module_desc * modules; /* modules loaded into SP */
154
155 struct dsp_segment_desc code;
156
157 /* Main PCM playback mixer */
158 struct dsp_scb_descriptor * master_mix_scb;
159 u16 dac_volume_right;
160 u16 dac_volume_left;
161
162 /* Rear/surround PCM playback mixer */
163 struct dsp_scb_descriptor * rear_mix_scb;
164
165 /* Center/LFE mixer */
166 struct dsp_scb_descriptor * center_lfe_mix_scb;
167
168 int npcm_channels;
169 int nsrc_scb;
170 struct dsp_pcm_channel_descriptor pcm_channels[DSP_MAX_PCM_CHANNELS];
171 int src_scb_slots[DSP_MAX_SRC_NR];
172
173 /* cache this symbols */
174 struct dsp_symbol_entry * null_algorithm; /* used by PCMreaderSCB's */
175 struct dsp_symbol_entry * s16_up; /* used by SRCtaskSCB's */
176
177 /* proc fs */
178 struct snd_card *snd_card;
179 struct snd_info_entry * proc_dsp_dir;
180 struct snd_info_entry * proc_sym_info_entry;
181 struct snd_info_entry * proc_modules_info_entry;
182 struct snd_info_entry * proc_parameter_dump_info_entry;
183 struct snd_info_entry * proc_sample_dump_info_entry;
184
185 /* SCB's descriptors */
186 int nscb;
187 int scb_highest_frag_index;
188 struct dsp_scb_descriptor scbs[DSP_MAX_SCB_DESC];
189 struct snd_info_entry * proc_scb_info_entry;
190 struct dsp_scb_descriptor * the_null_scb;
191
192 /* Task's descriptors */
193 int ntask;
194 struct dsp_task_descriptor tasks[DSP_MAX_TASK_DESC];
195 struct snd_info_entry * proc_task_info_entry;
196
197 /* SPDIF status */
198 int spdif_status_out;
199 int spdif_status_in;
200 u16 spdif_input_volume_right;
201 u16 spdif_input_volume_left;
202 /* spdif channel status,
203 left right and user validity bits */
204 unsigned int spdif_csuv_default;
205 unsigned int spdif_csuv_stream;
206
207 /* SPDIF input sample rate converter */
208 struct dsp_scb_descriptor * spdif_in_src;
209 /* SPDIF input asynch. receiver */
210 struct dsp_scb_descriptor * asynch_rx_scb;
211
212 /* Capture record mixer SCB */
213 struct dsp_scb_descriptor * record_mixer_scb;
214
215 /* CODEC input SCB */
216 struct dsp_scb_descriptor * codec_in_scb;
217
218 /* reference snooper */
219 struct dsp_scb_descriptor * ref_snoop_scb;
220
221 /* SPDIF output PCM reference */
222 struct dsp_scb_descriptor * spdif_pcm_input_scb;
223
224 /* asynch TX task */
225 struct dsp_scb_descriptor * asynch_tx_scb;
226
227 /* record sources */
228 struct dsp_scb_descriptor * pcm_input;
229 struct dsp_scb_descriptor * adc_input;
230
231 int spdif_in_sample_rate;
232};
233
234#endif /* __DSP_SPOS_H__ */
diff --git a/sound/pci/cs46xx/cs46xx_dsp_task_types.h b/sound/pci/cs46xx/cs46xx_dsp_task_types.h
new file mode 100644
index 000000000000..5cf920bfda27
--- /dev/null
+++ b/sound/pci/cs46xx/cs46xx_dsp_task_types.h
@@ -0,0 +1,252 @@
1/*
2 * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 *
21 * NOTE: comments are copy/paste from cwcemb80.lst
22 * provided by Tom Woller at Cirrus (my only
23 * documentation about the SP OS running inside
24 * the DSP)
25 */
26
27#ifndef __CS46XX_DSP_TASK_TYPES_H__
28#define __CS46XX_DSP_TASK_TYPES_H__
29
30#include "cs46xx_dsp_scb_types.h"
31
32/*********************************************************************************************
33Example hierarchy of stream control blocks in the SP
34
35hfgTree
36Ptr____Call (c)
37 \
38 -------+------ ------------- ------------- ------------- -----
39| SBlaster IF |______\| Foreground |___\| Middlegr'nd |___\| Background |___\| Nul |
40| |Goto /| tree header |g /| tree header |g /| tree header |g /| SCB |r
41 -------------- (g) ------------- ------------- ------------- -----
42 |c |c |c |c
43 | | | |
44 \/ ------------- ------------- -------------
45 | Foreground |_\ | Middlegr'nd |_\ | Background |_\
46 | tree |g/ | tree |g/ | tree |g/
47 ------------- ------------- -------------
48 |c |c |c
49 | | |
50 \/ \/ \/
51
52*********************************************************************************************/
53
54#define HFG_FIRST_EXECUTE_MODE 0x0001
55#define HFG_FIRST_EXECUTE_MODE_BIT 0
56#define HFG_CONTEXT_SWITCH_MODE 0x0002
57#define HFG_CONTEXT_SWITCH_MODE_BIT 1
58
59#define MAX_FG_STACK_SIZE 32 /* THESE NEED TO BE COMPUTED PROPERLY */
60#define MAX_MG_STACK_SIZE 16
61#define MAX_BG_STACK_SIZE 9
62#define MAX_HFG_STACK_SIZE 4
63
64#define SLEEP_ACTIVE_INCREMENT 0 /* Enable task tree thread to go to sleep
65 This should only ever be used on the Background thread */
66#define STANDARD_ACTIVE_INCREMENT 1 /* Task tree thread normal operation */
67#define SUSPEND_ACTIVE_INCREMENT 2 /* Cause execution to suspend in the task tree thread
68 This should only ever be used on the Background thread */
69
70#define HOSTFLAGS_DISABLE_BG_SLEEP 0 /* Host-controlled flag that determines whether we go to sleep
71 at the end of BG */
72
73/* Minimal context save area for Hyper Forground */
74struct dsp_hf_save_area {
75 u32 r10_save;
76 u32 r54_save;
77 u32 r98_save;
78
79 ___DSP_DUAL_16BIT_ALLOC(
80 status_save,
81 ind_save
82 )
83
84 ___DSP_DUAL_16BIT_ALLOC(
85 rci1_save,
86 rci0_save
87 )
88
89 u32 r32_save;
90 u32 r76_save;
91 u32 rsd2_save;
92
93 ___DSP_DUAL_16BIT_ALLOC(
94 rsi2_save, /* See TaskTreeParameterBlock for
95 remainder of registers */
96 rsa2Save
97 )
98 /* saved as part of HFG context */
99};
100
101
102/* Task link data structure */
103struct dsp_tree_link {
104 ___DSP_DUAL_16BIT_ALLOC(
105 /* Pointer to sibling task control block */
106 next_scb,
107 /* Pointer to child task control block */
108 sub_ptr
109 )
110
111 ___DSP_DUAL_16BIT_ALLOC(
112 /* Pointer to code entry point */
113 entry_point,
114 /* Pointer to local data */
115 this_spb
116 )
117};
118
119
120struct dsp_task_tree_data {
121 ___DSP_DUAL_16BIT_ALLOC(
122 /* Initial tock count; controls task tree execution rate */
123 tock_count_limit,
124 /* Tock down counter */
125 tock_count
126 )
127
128 /* Add to ActiveCount when TockCountLimit reached:
129 Subtract on task tree termination */
130 ___DSP_DUAL_16BIT_ALLOC(
131 active_tncrement,
132 /* Number of pending activations for task tree */
133 active_count
134 )
135
136 ___DSP_DUAL_16BIT_ALLOC(
137 /* BitNumber to enable modification of correct bit in ActiveTaskFlags */
138 active_bit,
139 /* Pointer to OS location for indicating current activity on task level */
140 active_task_flags_ptr
141 )
142
143 /* Data structure for controlling movement of memory blocks:-
144 currently unused */
145 ___DSP_DUAL_16BIT_ALLOC(
146 mem_upd_ptr,
147 /* Data structure for controlling synchronous link update */
148 link_upd_ptr
149 )
150
151 ___DSP_DUAL_16BIT_ALLOC(
152 /* Save area for remainder of full context. */
153 save_area,
154 /* Address of start of local stack for data storage */
155 data_stack_base_ptr
156 )
157
158};
159
160
161struct dsp_interval_timer_data
162{
163 /* These data items have the same relative locations to those */
164 ___DSP_DUAL_16BIT_ALLOC(
165 interval_timer_period,
166 itd_unused
167 )
168
169 /* used for this data in the SPOS control block for SPOS 1.0 */
170 ___DSP_DUAL_16BIT_ALLOC(
171 num_FG_ticks_this_interval,
172 num_intervals
173 )
174};
175
176
177/* This structure contains extra storage for the task tree
178 Currently, this additional data is related only to a full context save */
179struct dsp_task_tree_context_block {
180 /* Up to 10 values are saved onto the stack. 8 for the task tree, 1 for
181 The access to the context switch (call or interrupt), and 1 spare that
182 users should never use. This last may be required by the system */
183 ___DSP_DUAL_16BIT_ALLOC(
184 stack1,
185 stack0
186 )
187 ___DSP_DUAL_16BIT_ALLOC(
188 stack3,
189 stack2
190 )
191 ___DSP_DUAL_16BIT_ALLOC(
192 stack5,
193 stack4
194 )
195 ___DSP_DUAL_16BIT_ALLOC(
196 stack7,
197 stack6
198 )
199 ___DSP_DUAL_16BIT_ALLOC(
200 stack9,
201 stack8
202 )
203
204 u32 saverfe;
205
206 /* Value may be overwriten by stack save algorithm.
207 Retain the size of the stack data saved here if used */
208 ___DSP_DUAL_16BIT_ALLOC(
209 reserved1,
210 stack_size
211 )
212 u32 saverba; /* (HFG) */
213 u32 saverdc;
214 u32 savers_config_23; /* (HFG) */
215 u32 savers_DMA23; /* (HFG) */
216 u32 saversa0;
217 u32 saversi0;
218 u32 saversa1;
219 u32 saversi1;
220 u32 saversa3;
221 u32 saversd0;
222 u32 saversd1;
223 u32 saversd3;
224 u32 savers_config01;
225 u32 savers_DMA01;
226 u32 saveacc0hl;
227 u32 saveacc1hl;
228 u32 saveacc0xacc1x;
229 u32 saveacc2hl;
230 u32 saveacc3hl;
231 u32 saveacc2xacc3x;
232 u32 saveaux0hl;
233 u32 saveaux1hl;
234 u32 saveaux0xaux1x;
235 u32 saveaux2hl;
236 u32 saveaux3hl;
237 u32 saveaux2xaux3x;
238 u32 savershouthl;
239 u32 savershoutxmacmode;
240};
241
242
243struct dsp_task_tree_control_block {
244 struct dsp_hf_save_area context;
245 struct dsp_tree_link links;
246 struct dsp_task_tree_data data;
247 struct dsp_task_tree_context_block context_blk;
248 struct dsp_interval_timer_data int_timer;
249};
250
251
252#endif /* __DSP_TASK_TYPES_H__ */
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 4fa53161b094..a71d1c14a0f6 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -61,7 +61,7 @@
61#include <sound/info.h> 61#include <sound/info.h>
62#include <sound/pcm.h> 62#include <sound/pcm.h>
63#include <sound/pcm_params.h> 63#include <sound/pcm_params.h>
64#include <sound/cs46xx.h> 64#include "cs46xx.h"
65 65
66#include <asm/io.h> 66#include <asm/io.h>
67 67
@@ -94,7 +94,7 @@ static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip,
94 94
95 if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX && 95 if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX &&
96 codec_index != CS46XX_SECONDARY_CODEC_INDEX)) 96 codec_index != CS46XX_SECONDARY_CODEC_INDEX))
97 return -EINVAL; 97 return 0xffff;
98 98
99 chip->active_ctrl(chip, 1); 99 chip->active_ctrl(chip, 1);
100 100
@@ -3599,9 +3599,10 @@ static unsigned int saved_regs[] = {
3599 BA1_CVOL, 3599 BA1_CVOL,
3600}; 3600};
3601 3601
3602int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) 3602static int snd_cs46xx_suspend(struct device *dev)
3603{ 3603{
3604 struct snd_card *card = pci_get_drvdata(pci); 3604 struct pci_dev *pci = to_pci_dev(dev);
3605 struct snd_card *card = dev_get_drvdata(dev);
3605 struct snd_cs46xx *chip = card->private_data; 3606 struct snd_cs46xx *chip = card->private_data;
3606 int i, amp_saved; 3607 int i, amp_saved;
3607 3608
@@ -3628,13 +3629,14 @@ int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state)
3628 3629
3629 pci_disable_device(pci); 3630 pci_disable_device(pci);
3630 pci_save_state(pci); 3631 pci_save_state(pci);
3631 pci_set_power_state(pci, pci_choose_state(pci, state)); 3632 pci_set_power_state(pci, PCI_D3hot);
3632 return 0; 3633 return 0;
3633} 3634}
3634 3635
3635int snd_cs46xx_resume(struct pci_dev *pci) 3636static int snd_cs46xx_resume(struct device *dev)
3636{ 3637{
3637 struct snd_card *card = pci_get_drvdata(pci); 3638 struct pci_dev *pci = to_pci_dev(dev);
3639 struct snd_card *card = dev_get_drvdata(dev);
3638 struct snd_cs46xx *chip = card->private_data; 3640 struct snd_cs46xx *chip = card->private_data;
3639 int amp_saved; 3641 int amp_saved;
3640#ifdef CONFIG_SND_CS46XX_NEW_DSP 3642#ifdef CONFIG_SND_CS46XX_NEW_DSP
@@ -3707,6 +3709,8 @@ int snd_cs46xx_resume(struct pci_dev *pci)
3707 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 3709 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
3708 return 0; 3710 return 0;
3709} 3711}
3712
3713SIMPLE_DEV_PM_OPS(snd_cs46xx_pm, snd_cs46xx_suspend, snd_cs46xx_resume);
3710#endif /* CONFIG_PM */ 3714#endif /* CONFIG_PM */
3711 3715
3712 3716
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index e377287192aa..56fec0bc0efb 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -32,7 +32,7 @@
32#include <sound/control.h> 32#include <sound/control.h>
33#include <sound/info.h> 33#include <sound/info.h>
34#include <sound/asoundef.h> 34#include <sound/asoundef.h>
35#include <sound/cs46xx.h> 35#include "cs46xx.h"
36 36
37#include "cs46xx_lib.h" 37#include "cs46xx_lib.h"
38#include "dsp_spos.h" 38#include "dsp_spos.h"
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
index 00b148a10239..c2c695b07f8c 100644
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -31,7 +31,7 @@
31#include <sound/core.h> 31#include <sound/core.h>
32#include <sound/control.h> 32#include <sound/control.h>
33#include <sound/info.h> 33#include <sound/info.h>
34#include <sound/cs46xx.h> 34#include "cs46xx.h"
35 35
36#include "cs46xx_lib.h" 36#include "cs46xx_lib.h"
37#include "dsp_spos.h" 37#include "dsp_spos.h"
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 2c9697cf0a1a..51f64ba5facf 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -400,8 +400,9 @@ static struct pci_driver cs5535audio_driver = {
400 .probe = snd_cs5535audio_probe, 400 .probe = snd_cs5535audio_probe,
401 .remove = __devexit_p(snd_cs5535audio_remove), 401 .remove = __devexit_p(snd_cs5535audio_remove),
402#ifdef CONFIG_PM 402#ifdef CONFIG_PM
403 .suspend = snd_cs5535audio_suspend, 403 .driver = {
404 .resume = snd_cs5535audio_resume, 404 .pm = &snd_cs5535audio_pm,
405 },
405#endif 406#endif
406}; 407};
407 408
diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h
index 51966d782a3c..bb3cc641130c 100644
--- a/sound/pci/cs5535audio/cs5535audio.h
+++ b/sound/pci/cs5535audio/cs5535audio.h
@@ -94,10 +94,7 @@ struct cs5535audio {
94 struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS]; 94 struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS];
95}; 95};
96 96
97#ifdef CONFIG_PM 97extern const struct dev_pm_ops snd_cs5535audio_pm;
98int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state);
99int snd_cs5535audio_resume(struct pci_dev *pci);
100#endif
101 98
102#ifdef CONFIG_OLPC 99#ifdef CONFIG_OLPC
103void __devinit olpc_prequirks(struct snd_card *card, 100void __devinit olpc_prequirks(struct snd_card *card,
diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c
index 185b00088320..6c34def5986d 100644
--- a/sound/pci/cs5535audio/cs5535audio_pm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pm.c
@@ -55,9 +55,10 @@ static void snd_cs5535audio_stop_hardware(struct cs5535audio *cs5535au)
55 55
56} 56}
57 57
58int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state) 58static int snd_cs5535audio_suspend(struct device *dev)
59{ 59{
60 struct snd_card *card = pci_get_drvdata(pci); 60 struct pci_dev *pci = to_pci_dev(dev);
61 struct snd_card *card = dev_get_drvdata(dev);
61 struct cs5535audio *cs5535au = card->private_data; 62 struct cs5535audio *cs5535au = card->private_data;
62 int i; 63 int i;
63 64
@@ -77,13 +78,14 @@ int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state)
77 return -EIO; 78 return -EIO;
78 } 79 }
79 pci_disable_device(pci); 80 pci_disable_device(pci);
80 pci_set_power_state(pci, pci_choose_state(pci, state)); 81 pci_set_power_state(pci, PCI_D3hot);
81 return 0; 82 return 0;
82} 83}
83 84
84int snd_cs5535audio_resume(struct pci_dev *pci) 85static int snd_cs5535audio_resume(struct device *dev)
85{ 86{
86 struct snd_card *card = pci_get_drvdata(pci); 87 struct pci_dev *pci = to_pci_dev(dev);
88 struct snd_card *card = dev_get_drvdata(dev);
87 struct cs5535audio *cs5535au = card->private_data; 89 struct cs5535audio *cs5535au = card->private_data;
88 u32 tmp; 90 u32 tmp;
89 int timeout; 91 int timeout;
@@ -129,3 +131,4 @@ int snd_cs5535audio_resume(struct pci_dev *pci)
129 return 0; 131 return 0;
130} 132}
131 133
134SIMPLE_DEV_PM_OPS(snd_cs5535audio_pm, snd_cs5535audio_suspend, snd_cs5535audio_resume);
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index d8a4423539ce..2f6e9c762d3f 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -1537,7 +1537,7 @@ static void atc_connect_resources(struct ct_atc *atc)
1537} 1537}
1538 1538
1539#ifdef CONFIG_PM 1539#ifdef CONFIG_PM
1540static int atc_suspend(struct ct_atc *atc, pm_message_t state) 1540static int atc_suspend(struct ct_atc *atc)
1541{ 1541{
1542 int i; 1542 int i;
1543 struct hw *hw = atc->hw; 1543 struct hw *hw = atc->hw;
@@ -1553,7 +1553,7 @@ static int atc_suspend(struct ct_atc *atc, pm_message_t state)
1553 1553
1554 atc_release_resources(atc); 1554 atc_release_resources(atc);
1555 1555
1556 hw->suspend(hw, state); 1556 hw->suspend(hw);
1557 1557
1558 return 0; 1558 return 0;
1559} 1559}
@@ -1725,8 +1725,10 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
1725 atc_connect_resources(atc); 1725 atc_connect_resources(atc);
1726 1726
1727 atc->timer = ct_timer_new(atc); 1727 atc->timer = ct_timer_new(atc);
1728 if (!atc->timer) 1728 if (!atc->timer) {
1729 err = -ENOMEM;
1729 goto error1; 1730 goto error1;
1731 }
1730 1732
1731 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, atc, &ops); 1733 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, atc, &ops);
1732 if (err < 0) 1734 if (err < 0)
diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h
index 3a0def656af0..653e813ad142 100644
--- a/sound/pci/ctxfi/ctatc.h
+++ b/sound/pci/ctxfi/ctatc.h
@@ -144,7 +144,7 @@ struct ct_atc {
144 struct ct_timer *timer; 144 struct ct_timer *timer;
145 145
146#ifdef CONFIG_PM 146#ifdef CONFIG_PM
147 int (*suspend)(struct ct_atc *atc, pm_message_t state); 147 int (*suspend)(struct ct_atc *atc);
148 int (*resume)(struct ct_atc *atc); 148 int (*resume)(struct ct_atc *atc);
149#define NUM_PCMS (NUM_CTALSADEVS - 1) 149#define NUM_PCMS (NUM_CTALSADEVS - 1)
150 struct snd_pcm *pcms[NUM_PCMS]; 150 struct snd_pcm *pcms[NUM_PCMS];
diff --git a/sound/pci/ctxfi/cthardware.h b/sound/pci/ctxfi/cthardware.h
index 908315bec3b4..c56fe533b3f3 100644
--- a/sound/pci/ctxfi/cthardware.h
+++ b/sound/pci/ctxfi/cthardware.h
@@ -73,7 +73,7 @@ struct hw {
73 int (*card_stop)(struct hw *hw); 73 int (*card_stop)(struct hw *hw);
74 int (*pll_init)(struct hw *hw, unsigned int rsr); 74 int (*pll_init)(struct hw *hw, unsigned int rsr);
75#ifdef CONFIG_PM 75#ifdef CONFIG_PM
76 int (*suspend)(struct hw *hw, pm_message_t state); 76 int (*suspend)(struct hw *hw);
77 int (*resume)(struct hw *hw, struct card_conf *info); 77 int (*resume)(struct hw *hw, struct card_conf *info);
78#endif 78#endif
79 int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source); 79 int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source);
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index a7df19791f5a..dc1969bc67d4 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -2086,7 +2086,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
2086} 2086}
2087 2087
2088#ifdef CONFIG_PM 2088#ifdef CONFIG_PM
2089static int hw_suspend(struct hw *hw, pm_message_t state) 2089static int hw_suspend(struct hw *hw)
2090{ 2090{
2091 struct pci_dev *pci = hw->pci; 2091 struct pci_dev *pci = hw->pci;
2092 2092
@@ -2099,7 +2099,7 @@ static int hw_suspend(struct hw *hw, pm_message_t state)
2099 2099
2100 pci_disable_device(pci); 2100 pci_disable_device(pci);
2101 pci_save_state(pci); 2101 pci_save_state(pci);
2102 pci_set_power_state(pci, pci_choose_state(pci, state)); 2102 pci_set_power_state(pci, PCI_D3hot);
2103 2103
2104 return 0; 2104 return 0;
2105} 2105}
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c
index d6c54b524bfa..9d1231dc4ae2 100644
--- a/sound/pci/ctxfi/cthw20k2.c
+++ b/sound/pci/ctxfi/cthw20k2.c
@@ -2202,7 +2202,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
2202} 2202}
2203 2203
2204#ifdef CONFIG_PM 2204#ifdef CONFIG_PM
2205static int hw_suspend(struct hw *hw, pm_message_t state) 2205static int hw_suspend(struct hw *hw)
2206{ 2206{
2207 struct pci_dev *pci = hw->pci; 2207 struct pci_dev *pci = hw->pci;
2208 2208
@@ -2210,7 +2210,7 @@ static int hw_suspend(struct hw *hw, pm_message_t state)
2210 2210
2211 pci_disable_device(pci); 2211 pci_disable_device(pci);
2212 pci_save_state(pci); 2212 pci_save_state(pci);
2213 pci_set_power_state(pci, pci_choose_state(pci, state)); 2213 pci_set_power_state(pci, PCI_D3hot);
2214 2214
2215 return 0; 2215 return 0;
2216} 2216}
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c
index 75aa2c338410..e002183ef8b2 100644
--- a/sound/pci/ctxfi/xfi.c
+++ b/sound/pci/ctxfi/xfi.c
@@ -126,21 +126,26 @@ static void __devexit ct_card_remove(struct pci_dev *pci)
126} 126}
127 127
128#ifdef CONFIG_PM 128#ifdef CONFIG_PM
129static int ct_card_suspend(struct pci_dev *pci, pm_message_t state) 129static int ct_card_suspend(struct device *dev)
130{ 130{
131 struct snd_card *card = pci_get_drvdata(pci); 131 struct snd_card *card = dev_get_drvdata(dev);
132 struct ct_atc *atc = card->private_data; 132 struct ct_atc *atc = card->private_data;
133 133
134 return atc->suspend(atc, state); 134 return atc->suspend(atc);
135} 135}
136 136
137static int ct_card_resume(struct pci_dev *pci) 137static int ct_card_resume(struct device *dev)
138{ 138{
139 struct snd_card *card = pci_get_drvdata(pci); 139 struct snd_card *card = dev_get_drvdata(dev);
140 struct ct_atc *atc = card->private_data; 140 struct ct_atc *atc = card->private_data;
141 141
142 return atc->resume(atc); 142 return atc->resume(atc);
143} 143}
144
145static SIMPLE_DEV_PM_OPS(ct_card_pm, ct_card_suspend, ct_card_resume);
146#define CT_CARD_PM_OPS &ct_card_pm
147#else
148#define CT_CARD_PM_OPS NULL
144#endif 149#endif
145 150
146static struct pci_driver ct_driver = { 151static struct pci_driver ct_driver = {
@@ -148,10 +153,9 @@ static struct pci_driver ct_driver = {
148 .id_table = ct_pci_dev_ids, 153 .id_table = ct_pci_dev_ids,
149 .probe = ct_card_probe, 154 .probe = ct_card_probe,
150 .remove = __devexit_p(ct_card_remove), 155 .remove = __devexit_p(ct_card_remove),
151#ifdef CONFIG_PM 156 .driver = {
152 .suspend = ct_card_suspend, 157 .pm = CT_CARD_PM_OPS,
153 .resume = ct_card_resume, 158 },
154#endif
155}; 159};
156 160
157module_pci_driver(ct_driver); 161module_pci_driver(ct_driver);
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 0f8eda1dafdb..0ff754f180d0 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -2205,9 +2205,10 @@ ctl_error:
2205 2205
2206#if defined(CONFIG_PM) 2206#if defined(CONFIG_PM)
2207 2207
2208static int snd_echo_suspend(struct pci_dev *pci, pm_message_t state) 2208static int snd_echo_suspend(struct device *dev)
2209{ 2209{
2210 struct echoaudio *chip = pci_get_drvdata(pci); 2210 struct pci_dev *pci = to_pci_dev(dev);
2211 struct echoaudio *chip = dev_get_drvdata(dev);
2211 2212
2212 DE_INIT(("suspend start\n")); 2213 DE_INIT(("suspend start\n"));
2213 snd_pcm_suspend_all(chip->analog_pcm); 2214 snd_pcm_suspend_all(chip->analog_pcm);
@@ -2242,9 +2243,10 @@ static int snd_echo_suspend(struct pci_dev *pci, pm_message_t state)
2242 2243
2243 2244
2244 2245
2245static int snd_echo_resume(struct pci_dev *pci) 2246static int snd_echo_resume(struct device *dev)
2246{ 2247{
2247 struct echoaudio *chip = pci_get_drvdata(pci); 2248 struct pci_dev *pci = to_pci_dev(dev);
2249 struct echoaudio *chip = dev_get_drvdata(dev);
2248 struct comm_page *commpage, *commpage_bak; 2250 struct comm_page *commpage, *commpage_bak;
2249 u32 pipe_alloc_mask; 2251 u32 pipe_alloc_mask;
2250 int err; 2252 int err;
@@ -2307,10 +2309,13 @@ static int snd_echo_resume(struct pci_dev *pci)
2307 return 0; 2309 return 0;
2308} 2310}
2309 2311
2312static SIMPLE_DEV_PM_OPS(snd_echo_pm, snd_echo_suspend, snd_echo_resume);
2313#define SND_ECHO_PM_OPS &snd_echo_pm
2314#else
2315#define SND_ECHO_PM_OPS NULL
2310#endif /* CONFIG_PM */ 2316#endif /* CONFIG_PM */
2311 2317
2312 2318
2313
2314static void __devexit snd_echo_remove(struct pci_dev *pci) 2319static void __devexit snd_echo_remove(struct pci_dev *pci)
2315{ 2320{
2316 struct echoaudio *chip; 2321 struct echoaudio *chip;
@@ -2333,10 +2338,9 @@ static struct pci_driver echo_driver = {
2333 .id_table = snd_echo_ids, 2338 .id_table = snd_echo_ids,
2334 .probe = snd_echo_probe, 2339 .probe = snd_echo_probe,
2335 .remove = __devexit_p(snd_echo_remove), 2340 .remove = __devexit_p(snd_echo_remove),
2336#ifdef CONFIG_PM 2341 .driver = {
2337 .suspend = snd_echo_suspend, 2342 .pm = SND_ECHO_PM_OPS,
2338 .resume = snd_echo_resume, 2343 },
2339#endif /* CONFIG_PM */
2340}; 2344};
2341 2345
2342module_pci_driver(echo_driver); 2346module_pci_driver(echo_driver);
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 7fdbbe4d9965..ddac4e6d660d 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -207,9 +207,10 @@ static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci)
207 207
208 208
209#ifdef CONFIG_PM 209#ifdef CONFIG_PM
210static int snd_emu10k1_suspend(struct pci_dev *pci, pm_message_t state) 210static int snd_emu10k1_suspend(struct device *dev)
211{ 211{
212 struct snd_card *card = pci_get_drvdata(pci); 212 struct pci_dev *pci = to_pci_dev(dev);
213 struct snd_card *card = dev_get_drvdata(dev);
213 struct snd_emu10k1 *emu = card->private_data; 214 struct snd_emu10k1 *emu = card->private_data;
214 215
215 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 216 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -231,13 +232,14 @@ static int snd_emu10k1_suspend(struct pci_dev *pci, pm_message_t state)
231 232
232 pci_disable_device(pci); 233 pci_disable_device(pci);
233 pci_save_state(pci); 234 pci_save_state(pci);
234 pci_set_power_state(pci, pci_choose_state(pci, state)); 235 pci_set_power_state(pci, PCI_D3hot);
235 return 0; 236 return 0;
236} 237}
237 238
238static int snd_emu10k1_resume(struct pci_dev *pci) 239static int snd_emu10k1_resume(struct device *dev)
239{ 240{
240 struct snd_card *card = pci_get_drvdata(pci); 241 struct pci_dev *pci = to_pci_dev(dev);
242 struct snd_card *card = dev_get_drvdata(dev);
241 struct snd_emu10k1 *emu = card->private_data; 243 struct snd_emu10k1 *emu = card->private_data;
242 244
243 pci_set_power_state(pci, PCI_D0); 245 pci_set_power_state(pci, PCI_D0);
@@ -261,17 +263,21 @@ static int snd_emu10k1_resume(struct pci_dev *pci)
261 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 263 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
262 return 0; 264 return 0;
263} 265}
264#endif 266
267static SIMPLE_DEV_PM_OPS(snd_emu10k1_pm, snd_emu10k1_suspend, snd_emu10k1_resume);
268#define SND_EMU10K1_PM_OPS &snd_emu10k1_pm
269#else
270#define SND_EMU10K1_PM_OPS NULL
271#endif /* CONFIG_PM */
265 272
266static struct pci_driver emu10k1_driver = { 273static struct pci_driver emu10k1_driver = {
267 .name = KBUILD_MODNAME, 274 .name = KBUILD_MODNAME,
268 .id_table = snd_emu10k1_ids, 275 .id_table = snd_emu10k1_ids,
269 .probe = snd_card_emu10k1_probe, 276 .probe = snd_card_emu10k1_probe,
270 .remove = __devexit_p(snd_card_emu10k1_remove), 277 .remove = __devexit_p(snd_card_emu10k1_remove),
271#ifdef CONFIG_PM 278 .driver = {
272 .suspend = snd_emu10k1_suspend, 279 .pm = SND_EMU10K1_PM_OPS,
273 .resume = snd_emu10k1_resume, 280 },
274#endif
275}; 281};
276 282
277module_pci_driver(emu10k1_driver); 283module_pci_driver(emu10k1_driver);
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 4f502a2bdc3c..0a436626182b 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -326,7 +326,10 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
326 for (page = blk->first_page; page <= blk->last_page; page++, idx++) { 326 for (page = blk->first_page; page <= blk->last_page; page++, idx++) {
327 unsigned long ofs = idx << PAGE_SHIFT; 327 unsigned long ofs = idx << PAGE_SHIFT;
328 dma_addr_t addr; 328 dma_addr_t addr;
329 addr = snd_pcm_sgbuf_get_addr(substream, ofs); 329 if (ofs >= runtime->dma_bytes)
330 addr = emu->silent_page.addr;
331 else
332 addr = snd_pcm_sgbuf_get_addr(substream, ofs);
330 if (! is_valid_page(emu, addr)) { 333 if (! is_valid_page(emu, addr)) {
331 printk(KERN_ERR "emu: failure page = %d\n", idx); 334 printk(KERN_ERR "emu: failure page = %d\n", idx);
332 mutex_unlock(&hdr->block_mutex); 335 mutex_unlock(&hdr->block_mutex);
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 3821c81d1c99..f7e6f73186e1 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -2033,9 +2033,10 @@ static void snd_ensoniq_chip_init(struct ensoniq *ensoniq)
2033} 2033}
2034 2034
2035#ifdef CONFIG_PM 2035#ifdef CONFIG_PM
2036static int snd_ensoniq_suspend(struct pci_dev *pci, pm_message_t state) 2036static int snd_ensoniq_suspend(struct device *dev)
2037{ 2037{
2038 struct snd_card *card = pci_get_drvdata(pci); 2038 struct pci_dev *pci = to_pci_dev(dev);
2039 struct snd_card *card = dev_get_drvdata(dev);
2039 struct ensoniq *ensoniq = card->private_data; 2040 struct ensoniq *ensoniq = card->private_data;
2040 2041
2041 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2042 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -2058,13 +2059,14 @@ static int snd_ensoniq_suspend(struct pci_dev *pci, pm_message_t state)
2058 2059
2059 pci_disable_device(pci); 2060 pci_disable_device(pci);
2060 pci_save_state(pci); 2061 pci_save_state(pci);
2061 pci_set_power_state(pci, pci_choose_state(pci, state)); 2062 pci_set_power_state(pci, PCI_D3hot);
2062 return 0; 2063 return 0;
2063} 2064}
2064 2065
2065static int snd_ensoniq_resume(struct pci_dev *pci) 2066static int snd_ensoniq_resume(struct device *dev)
2066{ 2067{
2067 struct snd_card *card = pci_get_drvdata(pci); 2068 struct pci_dev *pci = to_pci_dev(dev);
2069 struct snd_card *card = dev_get_drvdata(dev);
2068 struct ensoniq *ensoniq = card->private_data; 2070 struct ensoniq *ensoniq = card->private_data;
2069 2071
2070 pci_set_power_state(pci, PCI_D0); 2072 pci_set_power_state(pci, PCI_D0);
@@ -2087,8 +2089,12 @@ static int snd_ensoniq_resume(struct pci_dev *pci)
2087 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2089 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2088 return 0; 2090 return 0;
2089} 2091}
2090#endif /* CONFIG_PM */
2091 2092
2093static SIMPLE_DEV_PM_OPS(snd_ensoniq_pm, snd_ensoniq_suspend, snd_ensoniq_resume);
2094#define SND_ENSONIQ_PM_OPS &snd_ensoniq_pm
2095#else
2096#define SND_ENSONIQ_PM_OPS NULL
2097#endif /* CONFIG_PM */
2092 2098
2093static int __devinit snd_ensoniq_create(struct snd_card *card, 2099static int __devinit snd_ensoniq_create(struct snd_card *card,
2094 struct pci_dev *pci, 2100 struct pci_dev *pci,
@@ -2493,10 +2499,9 @@ static struct pci_driver ens137x_driver = {
2493 .id_table = snd_audiopci_ids, 2499 .id_table = snd_audiopci_ids,
2494 .probe = snd_audiopci_probe, 2500 .probe = snd_audiopci_probe,
2495 .remove = __devexit_p(snd_audiopci_remove), 2501 .remove = __devexit_p(snd_audiopci_remove),
2496#ifdef CONFIG_PM 2502 .driver = {
2497 .suspend = snd_ensoniq_suspend, 2503 .pm = SND_ENSONIQ_PM_OPS,
2498 .resume = snd_ensoniq_resume, 2504 },
2499#endif
2500}; 2505};
2501 2506
2502module_pci_driver(ens137x_driver); 2507module_pci_driver(ens137x_driver);
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 82c8d8c5c52a..dbb81807bc1a 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1321,35 +1321,30 @@ static int snd_es1938_put_double(struct snd_kcontrol *kcontrol,
1321 return change; 1321 return change;
1322} 1322}
1323 1323
1324static unsigned int db_scale_master[] = { 1324static const DECLARE_TLV_DB_RANGE(db_scale_master,
1325 TLV_DB_RANGE_HEAD(2),
1326 0, 54, TLV_DB_SCALE_ITEM(-3600, 50, 1), 1325 0, 54, TLV_DB_SCALE_ITEM(-3600, 50, 1),
1327 54, 63, TLV_DB_SCALE_ITEM(-900, 100, 0), 1326 54, 63, TLV_DB_SCALE_ITEM(-900, 100, 0),
1328}; 1327);
1329 1328
1330static unsigned int db_scale_audio1[] = { 1329static const DECLARE_TLV_DB_RANGE(db_scale_audio1,
1331 TLV_DB_RANGE_HEAD(2),
1332 0, 8, TLV_DB_SCALE_ITEM(-3300, 300, 1), 1330 0, 8, TLV_DB_SCALE_ITEM(-3300, 300, 1),
1333 8, 15, TLV_DB_SCALE_ITEM(-900, 150, 0), 1331 8, 15, TLV_DB_SCALE_ITEM(-900, 150, 0),
1334}; 1332);
1335 1333
1336static unsigned int db_scale_audio2[] = { 1334static const DECLARE_TLV_DB_RANGE(db_scale_audio2,
1337 TLV_DB_RANGE_HEAD(2),
1338 0, 8, TLV_DB_SCALE_ITEM(-3450, 300, 1), 1335 0, 8, TLV_DB_SCALE_ITEM(-3450, 300, 1),
1339 8, 15, TLV_DB_SCALE_ITEM(-1050, 150, 0), 1336 8, 15, TLV_DB_SCALE_ITEM(-1050, 150, 0),
1340}; 1337);
1341 1338
1342static unsigned int db_scale_mic[] = { 1339static const DECLARE_TLV_DB_RANGE(db_scale_mic,
1343 TLV_DB_RANGE_HEAD(2),
1344 0, 8, TLV_DB_SCALE_ITEM(-2400, 300, 1), 1340 0, 8, TLV_DB_SCALE_ITEM(-2400, 300, 1),
1345 8, 15, TLV_DB_SCALE_ITEM(0, 150, 0), 1341 8, 15, TLV_DB_SCALE_ITEM(0, 150, 0),
1346}; 1342);
1347 1343
1348static unsigned int db_scale_line[] = { 1344static const DECLARE_TLV_DB_RANGE(db_scale_line,
1349 TLV_DB_RANGE_HEAD(2),
1350 0, 8, TLV_DB_SCALE_ITEM(-3150, 300, 1), 1345 0, 8, TLV_DB_SCALE_ITEM(-3150, 300, 1),
1351 8, 15, TLV_DB_SCALE_ITEM(-750, 150, 0), 1346 8, 15, TLV_DB_SCALE_ITEM(-750, 150, 0),
1352}; 1347);
1353 1348
1354static const DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0); 1349static const DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0);
1355 1350
@@ -1474,9 +1469,10 @@ static unsigned char saved_regs[SAVED_REG_SIZE+1] = {
1474}; 1469};
1475 1470
1476 1471
1477static int es1938_suspend(struct pci_dev *pci, pm_message_t state) 1472static int es1938_suspend(struct device *dev)
1478{ 1473{
1479 struct snd_card *card = pci_get_drvdata(pci); 1474 struct pci_dev *pci = to_pci_dev(dev);
1475 struct snd_card *card = dev_get_drvdata(dev);
1480 struct es1938 *chip = card->private_data; 1476 struct es1938 *chip = card->private_data;
1481 unsigned char *s, *d; 1477 unsigned char *s, *d;
1482 1478
@@ -1494,13 +1490,14 @@ static int es1938_suspend(struct pci_dev *pci, pm_message_t state)
1494 } 1490 }
1495 pci_disable_device(pci); 1491 pci_disable_device(pci);
1496 pci_save_state(pci); 1492 pci_save_state(pci);
1497 pci_set_power_state(pci, pci_choose_state(pci, state)); 1493 pci_set_power_state(pci, PCI_D3hot);
1498 return 0; 1494 return 0;
1499} 1495}
1500 1496
1501static int es1938_resume(struct pci_dev *pci) 1497static int es1938_resume(struct device *dev)
1502{ 1498{
1503 struct snd_card *card = pci_get_drvdata(pci); 1499 struct pci_dev *pci = to_pci_dev(dev);
1500 struct snd_card *card = dev_get_drvdata(dev);
1504 struct es1938 *chip = card->private_data; 1501 struct es1938 *chip = card->private_data;
1505 unsigned char *s, *d; 1502 unsigned char *s, *d;
1506 1503
@@ -1534,6 +1531,11 @@ static int es1938_resume(struct pci_dev *pci)
1534 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1531 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1535 return 0; 1532 return 0;
1536} 1533}
1534
1535static SIMPLE_DEV_PM_OPS(es1938_pm, es1938_suspend, es1938_resume);
1536#define ES1938_PM_OPS &es1938_pm
1537#else
1538#define ES1938_PM_OPS NULL
1537#endif /* CONFIG_PM */ 1539#endif /* CONFIG_PM */
1538 1540
1539#ifdef SUPPORT_JOYSTICK 1541#ifdef SUPPORT_JOYSTICK
@@ -1887,10 +1889,9 @@ static struct pci_driver es1938_driver = {
1887 .id_table = snd_es1938_ids, 1889 .id_table = snd_es1938_ids,
1888 .probe = snd_es1938_probe, 1890 .probe = snd_es1938_probe,
1889 .remove = __devexit_p(snd_es1938_remove), 1891 .remove = __devexit_p(snd_es1938_remove),
1890#ifdef CONFIG_PM 1892 .driver = {
1891 .suspend = es1938_suspend, 1893 .pm = ES1938_PM_OPS,
1892 .resume = es1938_resume, 1894 },
1893#endif
1894}; 1895};
1895 1896
1896module_pci_driver(es1938_driver); 1897module_pci_driver(es1938_driver);
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 52b5c0bf90c1..fb4c90b99c00 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -2381,9 +2381,10 @@ static void snd_es1968_start_irq(struct es1968 *chip)
2381/* 2381/*
2382 * PM support 2382 * PM support
2383 */ 2383 */
2384static int es1968_suspend(struct pci_dev *pci, pm_message_t state) 2384static int es1968_suspend(struct device *dev)
2385{ 2385{
2386 struct snd_card *card = pci_get_drvdata(pci); 2386 struct pci_dev *pci = to_pci_dev(dev);
2387 struct snd_card *card = dev_get_drvdata(dev);
2387 struct es1968 *chip = card->private_data; 2388 struct es1968 *chip = card->private_data;
2388 2389
2389 if (! chip->do_pm) 2390 if (! chip->do_pm)
@@ -2398,13 +2399,14 @@ static int es1968_suspend(struct pci_dev *pci, pm_message_t state)
2398 2399
2399 pci_disable_device(pci); 2400 pci_disable_device(pci);
2400 pci_save_state(pci); 2401 pci_save_state(pci);
2401 pci_set_power_state(pci, pci_choose_state(pci, state)); 2402 pci_set_power_state(pci, PCI_D3hot);
2402 return 0; 2403 return 0;
2403} 2404}
2404 2405
2405static int es1968_resume(struct pci_dev *pci) 2406static int es1968_resume(struct device *dev)
2406{ 2407{
2407 struct snd_card *card = pci_get_drvdata(pci); 2408 struct pci_dev *pci = to_pci_dev(dev);
2409 struct snd_card *card = dev_get_drvdata(dev);
2408 struct es1968 *chip = card->private_data; 2410 struct es1968 *chip = card->private_data;
2409 struct esschan *es; 2411 struct esschan *es;
2410 2412
@@ -2454,6 +2456,11 @@ static int es1968_resume(struct pci_dev *pci)
2454 chip->in_suspend = 0; 2456 chip->in_suspend = 0;
2455 return 0; 2457 return 0;
2456} 2458}
2459
2460static SIMPLE_DEV_PM_OPS(es1968_pm, es1968_suspend, es1968_resume);
2461#define ES1968_PM_OPS &es1968_pm
2462#else
2463#define ES1968_PM_OPS NULL
2457#endif /* CONFIG_PM */ 2464#endif /* CONFIG_PM */
2458 2465
2459#ifdef SUPPORT_JOYSTICK 2466#ifdef SUPPORT_JOYSTICK
@@ -2903,10 +2910,9 @@ static struct pci_driver es1968_driver = {
2903 .id_table = snd_es1968_ids, 2910 .id_table = snd_es1968_ids,
2904 .probe = snd_es1968_probe, 2911 .probe = snd_es1968_probe,
2905 .remove = __devexit_p(snd_es1968_remove), 2912 .remove = __devexit_p(snd_es1968_remove),
2906#ifdef CONFIG_PM 2913 .driver = {
2907 .suspend = es1968_suspend, 2914 .pm = ES1968_PM_OPS,
2908 .resume = es1968_resume, 2915 },
2909#endif
2910}; 2916};
2911 2917
2912module_pci_driver(es1968_driver); 2918module_pci_driver(es1968_driver);
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index b32e8024ea86..522c8706f244 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -1369,9 +1369,10 @@ static unsigned char saved_regs[] = {
1369 FM801_CODEC_CTRL, FM801_I2S_MODE, FM801_VOLUME, FM801_GEN_CTRL, 1369 FM801_CODEC_CTRL, FM801_I2S_MODE, FM801_VOLUME, FM801_GEN_CTRL,
1370}; 1370};
1371 1371
1372static int snd_fm801_suspend(struct pci_dev *pci, pm_message_t state) 1372static int snd_fm801_suspend(struct device *dev)
1373{ 1373{
1374 struct snd_card *card = pci_get_drvdata(pci); 1374 struct pci_dev *pci = to_pci_dev(dev);
1375 struct snd_card *card = dev_get_drvdata(dev);
1375 struct fm801 *chip = card->private_data; 1376 struct fm801 *chip = card->private_data;
1376 int i; 1377 int i;
1377 1378
@@ -1385,13 +1386,14 @@ static int snd_fm801_suspend(struct pci_dev *pci, pm_message_t state)
1385 1386
1386 pci_disable_device(pci); 1387 pci_disable_device(pci);
1387 pci_save_state(pci); 1388 pci_save_state(pci);
1388 pci_set_power_state(pci, pci_choose_state(pci, state)); 1389 pci_set_power_state(pci, PCI_D3hot);
1389 return 0; 1390 return 0;
1390} 1391}
1391 1392
1392static int snd_fm801_resume(struct pci_dev *pci) 1393static int snd_fm801_resume(struct device *dev)
1393{ 1394{
1394 struct snd_card *card = pci_get_drvdata(pci); 1395 struct pci_dev *pci = to_pci_dev(dev);
1396 struct snd_card *card = dev_get_drvdata(dev);
1395 struct fm801 *chip = card->private_data; 1397 struct fm801 *chip = card->private_data;
1396 int i; 1398 int i;
1397 1399
@@ -1414,17 +1416,21 @@ static int snd_fm801_resume(struct pci_dev *pci)
1414 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1416 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1415 return 0; 1417 return 0;
1416} 1418}
1417#endif 1419
1420static SIMPLE_DEV_PM_OPS(snd_fm801_pm, snd_fm801_suspend, snd_fm801_resume);
1421#define SND_FM801_PM_OPS &snd_fm801_pm
1422#else
1423#define SND_FM801_PM_OPS NULL
1424#endif /* CONFIG_PM */
1418 1425
1419static struct pci_driver fm801_driver = { 1426static struct pci_driver fm801_driver = {
1420 .name = KBUILD_MODNAME, 1427 .name = KBUILD_MODNAME,
1421 .id_table = snd_fm801_ids, 1428 .id_table = snd_fm801_ids,
1422 .probe = snd_card_fm801_probe, 1429 .probe = snd_card_fm801_probe,
1423 .remove = __devexit_p(snd_card_fm801_remove), 1430 .remove = __devexit_p(snd_card_fm801_remove),
1424#ifdef CONFIG_PM 1431 .driver = {
1425 .suspend = snd_fm801_suspend, 1432 .pm = SND_FM801_PM_OPS,
1426 .resume = snd_fm801_resume, 1433 },
1427#endif
1428}; 1434};
1429 1435
1430module_pci_driver(fm801_driver); 1436module_pci_driver(fm801_driver);
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index d03079764189..194d625c1f83 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -53,15 +53,14 @@ config SND_HDA_INPUT_BEEP
53 driver. This interface is used to generate digital beeps. 53 driver. This interface is used to generate digital beeps.
54 54
55config SND_HDA_INPUT_BEEP_MODE 55config SND_HDA_INPUT_BEEP_MODE
56 int "Digital beep registration mode (0=off, 1=on, 2=mute sw on/off)" 56 int "Digital beep registration mode (0=off, 1=on)"
57 depends on SND_HDA_INPUT_BEEP=y 57 depends on SND_HDA_INPUT_BEEP=y
58 default "1" 58 default "1"
59 range 0 2 59 range 0 1
60 help 60 help
61 Set 0 to disable the digital beep interface for HD-audio by default. 61 Set 0 to disable the digital beep interface for HD-audio by default.
62 Set 1 to always enable the digital beep interface for HD-audio by 62 Set 1 to always enable the digital beep interface for HD-audio by
63 default. Set 2 to control the beep device registration to input 63 default.
64 layer using a "Beep Switch" in mixer applications.
65 64
66config SND_HDA_INPUT_JACK 65config SND_HDA_INPUT_JACK
67 bool "Support jack plugging notification via input layer" 66 bool "Support jack plugging notification via input layer"
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
index f7520b9f909c..4f7d2dfcef7b 100644
--- a/sound/pci/hda/hda_auto_parser.c
+++ b/sound/pci/hda/hda_auto_parser.c
@@ -332,13 +332,12 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
332 if (cfg->dig_outs) 332 if (cfg->dig_outs)
333 snd_printd(" dig-out=0x%x/0x%x\n", 333 snd_printd(" dig-out=0x%x/0x%x\n",
334 cfg->dig_out_pins[0], cfg->dig_out_pins[1]); 334 cfg->dig_out_pins[0], cfg->dig_out_pins[1]);
335 snd_printd(" inputs:"); 335 snd_printd(" inputs:\n");
336 for (i = 0; i < cfg->num_inputs; i++) { 336 for (i = 0; i < cfg->num_inputs; i++) {
337 snd_printd(" %s=0x%x", 337 snd_printd(" %s=0x%x\n",
338 hda_get_autocfg_input_label(codec, cfg, i), 338 hda_get_autocfg_input_label(codec, cfg, i),
339 cfg->inputs[i].pin); 339 cfg->inputs[i].pin);
340 } 340 }
341 snd_printd("\n");
342 if (cfg->dig_in_pin) 341 if (cfg->dig_in_pin)
343 snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin); 342 snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin);
344 343
@@ -727,7 +726,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
727 models++; 726 models++;
728 } 727 }
729 } 728 }
730 if (id < 0) { 729 if (id < 0 && quirk) {
731 q = snd_pci_quirk_lookup(codec->bus->pci, quirk); 730 q = snd_pci_quirk_lookup(codec->bus->pci, quirk);
732 if (q) { 731 if (q) {
733 id = q->value; 732 id = q->value;
@@ -736,7 +735,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
736#endif 735#endif
737 } 736 }
738 } 737 }
739 if (id < 0) { 738 if (id < 0 && quirk) {
740 for (q = quirk; q->subvendor; q++) { 739 for (q = quirk; q->subvendor; q++) {
741 unsigned int vendorid = 740 unsigned int vendorid =
742 q->subdevice | (q->subvendor << 16); 741 q->subdevice | (q->subvendor << 16);
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index 60738e52b8f9..0849aac449f2 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -162,50 +162,20 @@ static int snd_hda_do_attach(struct hda_beep *beep)
162 return 0; 162 return 0;
163} 163}
164 164
165static void snd_hda_do_register(struct work_struct *work)
166{
167 struct hda_beep *beep =
168 container_of(work, struct hda_beep, register_work);
169
170 mutex_lock(&beep->mutex);
171 if (beep->enabled && !beep->dev)
172 snd_hda_do_attach(beep);
173 mutex_unlock(&beep->mutex);
174}
175
176static void snd_hda_do_unregister(struct work_struct *work)
177{
178 struct hda_beep *beep =
179 container_of(work, struct hda_beep, unregister_work.work);
180
181 mutex_lock(&beep->mutex);
182 if (!beep->enabled && beep->dev)
183 snd_hda_do_detach(beep);
184 mutex_unlock(&beep->mutex);
185}
186
187int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) 165int snd_hda_enable_beep_device(struct hda_codec *codec, int enable)
188{ 166{
189 struct hda_beep *beep = codec->beep; 167 struct hda_beep *beep = codec->beep;
190 enable = !!enable; 168 if (!beep)
191 if (beep == NULL)
192 return 0; 169 return 0;
170 enable = !!enable;
193 if (beep->enabled != enable) { 171 if (beep->enabled != enable) {
194 beep->enabled = enable; 172 beep->enabled = enable;
195 if (!enable) { 173 if (!enable) {
174 cancel_work_sync(&beep->beep_work);
196 /* turn off beep */ 175 /* turn off beep */
197 snd_hda_codec_write(beep->codec, beep->nid, 0, 176 snd_hda_codec_write(beep->codec, beep->nid, 0,
198 AC_VERB_SET_BEEP_CONTROL, 0); 177 AC_VERB_SET_BEEP_CONTROL, 0);
199 } 178 }
200 if (beep->mode == HDA_BEEP_MODE_SWREG) {
201 if (enable) {
202 cancel_delayed_work(&beep->unregister_work);
203 schedule_work(&beep->register_work);
204 } else {
205 schedule_delayed_work(&beep->unregister_work,
206 HZ);
207 }
208 }
209 return 1; 179 return 1;
210 } 180 }
211 return 0; 181 return 0;
@@ -215,6 +185,7 @@ EXPORT_SYMBOL_HDA(snd_hda_enable_beep_device);
215int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) 185int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
216{ 186{
217 struct hda_beep *beep; 187 struct hda_beep *beep;
188 int err;
218 189
219 if (!snd_hda_get_bool_hint(codec, "beep")) 190 if (!snd_hda_get_bool_hint(codec, "beep"))
220 return 0; /* disabled explicitly by hints */ 191 return 0; /* disabled explicitly by hints */
@@ -232,21 +203,16 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
232 203
233 beep->nid = nid; 204 beep->nid = nid;
234 beep->codec = codec; 205 beep->codec = codec;
235 beep->mode = codec->beep_mode;
236 codec->beep = beep; 206 codec->beep = beep;
237 207
238 INIT_WORK(&beep->register_work, &snd_hda_do_register);
239 INIT_DELAYED_WORK(&beep->unregister_work, &snd_hda_do_unregister);
240 INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); 208 INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
241 mutex_init(&beep->mutex); 209 mutex_init(&beep->mutex);
242 210
243 if (beep->mode == HDA_BEEP_MODE_ON) { 211 err = snd_hda_do_attach(beep);
244 int err = snd_hda_do_attach(beep); 212 if (err < 0) {
245 if (err < 0) { 213 kfree(beep);
246 kfree(beep); 214 codec->beep = NULL;
247 codec->beep = NULL; 215 return err;
248 return err;
249 }
250 } 216 }
251 217
252 return 0; 218 return 0;
@@ -257,8 +223,6 @@ void snd_hda_detach_beep_device(struct hda_codec *codec)
257{ 223{
258 struct hda_beep *beep = codec->beep; 224 struct hda_beep *beep = codec->beep;
259 if (beep) { 225 if (beep) {
260 cancel_work_sync(&beep->register_work);
261 cancel_delayed_work(&beep->unregister_work);
262 if (beep->dev) 226 if (beep->dev)
263 snd_hda_do_detach(beep); 227 snd_hda_do_detach(beep);
264 codec->beep = NULL; 228 codec->beep = NULL;
@@ -266,3 +230,48 @@ void snd_hda_detach_beep_device(struct hda_codec *codec)
266 } 230 }
267} 231}
268EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device); 232EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device);
233
234static bool ctl_has_mute(struct snd_kcontrol *kcontrol)
235{
236 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
237 return query_amp_caps(codec, get_amp_nid(kcontrol),
238 get_amp_direction(kcontrol)) & AC_AMPCAP_MUTE;
239}
240
241/* get/put callbacks for beep mute mixer switches */
242int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol,
243 struct snd_ctl_elem_value *ucontrol)
244{
245 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
246 struct hda_beep *beep = codec->beep;
247 if (beep && (!beep->enabled || !ctl_has_mute(kcontrol))) {
248 ucontrol->value.integer.value[0] =
249 ucontrol->value.integer.value[1] = beep->enabled;
250 return 0;
251 }
252 return snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
253}
254EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get_beep);
255
256int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
257 struct snd_ctl_elem_value *ucontrol)
258{
259 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
260 struct hda_beep *beep = codec->beep;
261 if (beep) {
262 u8 chs = get_amp_channels(kcontrol);
263 int enable = 0;
264 long *valp = ucontrol->value.integer.value;
265 if (chs & 1) {
266 enable |= *valp;
267 valp++;
268 }
269 if (chs & 2)
270 enable |= *valp;
271 snd_hda_enable_beep_device(codec, enable);
272 }
273 if (!ctl_has_mute(kcontrol))
274 return 0;
275 return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
276}
277EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep);
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h
index 55f0647458c7..4dc6933bc655 100644
--- a/sound/pci/hda/hda_beep.h
+++ b/sound/pci/hda/hda_beep.h
@@ -26,21 +26,16 @@
26 26
27#define HDA_BEEP_MODE_OFF 0 27#define HDA_BEEP_MODE_OFF 0
28#define HDA_BEEP_MODE_ON 1 28#define HDA_BEEP_MODE_ON 1
29#define HDA_BEEP_MODE_SWREG 2
30 29
31/* beep information */ 30/* beep information */
32struct hda_beep { 31struct hda_beep {
33 struct input_dev *dev; 32 struct input_dev *dev;
34 struct hda_codec *codec; 33 struct hda_codec *codec;
35 unsigned int mode;
36 char phys[32]; 34 char phys[32];
37 int tone; 35 int tone;
38 hda_nid_t nid; 36 hda_nid_t nid;
39 unsigned int enabled:1; 37 unsigned int enabled:1;
40 unsigned int request_enable:1;
41 unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ 38 unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */
42 struct work_struct register_work; /* registration work */
43 struct delayed_work unregister_work; /* unregistration work */
44 struct work_struct beep_work; /* scheduled task for beep event */ 39 struct work_struct beep_work; /* scheduled task for beep event */
45 struct mutex mutex; 40 struct mutex mutex;
46}; 41};
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 51cb2a2e4fce..1c65cc5e3a31 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1209,6 +1209,9 @@ static void snd_hda_codec_free(struct hda_codec *codec)
1209 kfree(codec); 1209 kfree(codec);
1210} 1210}
1211 1211
1212static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec,
1213 hda_nid_t fg, unsigned int power_state);
1214
1212static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, 1215static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
1213 unsigned int power_state); 1216 unsigned int power_state);
1214 1217
@@ -1317,6 +1320,10 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
1317 AC_VERB_GET_SUBSYSTEM_ID, 0); 1320 AC_VERB_GET_SUBSYSTEM_ID, 0);
1318 } 1321 }
1319 1322
1323 codec->epss = snd_hda_codec_get_supported_ps(codec,
1324 codec->afg ? codec->afg : codec->mfg,
1325 AC_PWRST_EPSS);
1326
1320 /* power-up all before initialization */ 1327 /* power-up all before initialization */
1321 hda_set_power_state(codec, 1328 hda_set_power_state(codec,
1322 codec->afg ? codec->afg : codec->mfg, 1329 codec->afg ? codec->afg : codec->mfg,
@@ -1386,6 +1393,44 @@ int snd_hda_codec_configure(struct hda_codec *codec)
1386} 1393}
1387EXPORT_SYMBOL_HDA(snd_hda_codec_configure); 1394EXPORT_SYMBOL_HDA(snd_hda_codec_configure);
1388 1395
1396/* update the stream-id if changed */
1397static void update_pcm_stream_id(struct hda_codec *codec,
1398 struct hda_cvt_setup *p, hda_nid_t nid,
1399 u32 stream_tag, int channel_id)
1400{
1401 unsigned int oldval, newval;
1402
1403 if (p->stream_tag != stream_tag || p->channel_id != channel_id) {
1404 oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
1405 newval = (stream_tag << 4) | channel_id;
1406 if (oldval != newval)
1407 snd_hda_codec_write(codec, nid, 0,
1408 AC_VERB_SET_CHANNEL_STREAMID,
1409 newval);
1410 p->stream_tag = stream_tag;
1411 p->channel_id = channel_id;
1412 }
1413}
1414
1415/* update the format-id if changed */
1416static void update_pcm_format(struct hda_codec *codec, struct hda_cvt_setup *p,
1417 hda_nid_t nid, int format)
1418{
1419 unsigned int oldval;
1420
1421 if (p->format_id != format) {
1422 oldval = snd_hda_codec_read(codec, nid, 0,
1423 AC_VERB_GET_STREAM_FORMAT, 0);
1424 if (oldval != format) {
1425 msleep(1);
1426 snd_hda_codec_write(codec, nid, 0,
1427 AC_VERB_SET_STREAM_FORMAT,
1428 format);
1429 }
1430 p->format_id = format;
1431 }
1432}
1433
1389/** 1434/**
1390 * snd_hda_codec_setup_stream - set up the codec for streaming 1435 * snd_hda_codec_setup_stream - set up the codec for streaming
1391 * @codec: the CODEC to set up 1436 * @codec: the CODEC to set up
@@ -1400,7 +1445,6 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
1400{ 1445{
1401 struct hda_codec *c; 1446 struct hda_codec *c;
1402 struct hda_cvt_setup *p; 1447 struct hda_cvt_setup *p;
1403 unsigned int oldval, newval;
1404 int type; 1448 int type;
1405 int i; 1449 int i;
1406 1450
@@ -1413,29 +1457,13 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
1413 p = get_hda_cvt_setup(codec, nid); 1457 p = get_hda_cvt_setup(codec, nid);
1414 if (!p) 1458 if (!p)
1415 return; 1459 return;
1416 /* update the stream-id if changed */ 1460
1417 if (p->stream_tag != stream_tag || p->channel_id != channel_id) { 1461 if (codec->pcm_format_first)
1418 oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); 1462 update_pcm_format(codec, p, nid, format);
1419 newval = (stream_tag << 4) | channel_id; 1463 update_pcm_stream_id(codec, p, nid, stream_tag, channel_id);
1420 if (oldval != newval) 1464 if (!codec->pcm_format_first)
1421 snd_hda_codec_write(codec, nid, 0, 1465 update_pcm_format(codec, p, nid, format);
1422 AC_VERB_SET_CHANNEL_STREAMID, 1466
1423 newval);
1424 p->stream_tag = stream_tag;
1425 p->channel_id = channel_id;
1426 }
1427 /* update the format-id if changed */
1428 if (p->format_id != format) {
1429 oldval = snd_hda_codec_read(codec, nid, 0,
1430 AC_VERB_GET_STREAM_FORMAT, 0);
1431 if (oldval != format) {
1432 msleep(1);
1433 snd_hda_codec_write(codec, nid, 0,
1434 AC_VERB_SET_STREAM_FORMAT,
1435 format);
1436 }
1437 p->format_id = format;
1438 }
1439 p->active = 1; 1467 p->active = 1;
1440 p->dirty = 0; 1468 p->dirty = 0;
1441 1469
@@ -2325,6 +2353,7 @@ int snd_hda_codec_reset(struct hda_codec *codec)
2325 } 2353 }
2326 if (codec->patch_ops.free) 2354 if (codec->patch_ops.free)
2327 codec->patch_ops.free(codec); 2355 codec->patch_ops.free(codec);
2356 memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));
2328 snd_hda_jack_tbl_clear(codec); 2357 snd_hda_jack_tbl_clear(codec);
2329 codec->proc_widget_hook = NULL; 2358 codec->proc_widget_hook = NULL;
2330 codec->spec = NULL; 2359 codec->spec = NULL;
@@ -2340,7 +2369,6 @@ int snd_hda_codec_reset(struct hda_codec *codec)
2340 codec->num_pcms = 0; 2369 codec->num_pcms = 0;
2341 codec->pcm_info = NULL; 2370 codec->pcm_info = NULL;
2342 codec->preset = NULL; 2371 codec->preset = NULL;
2343 memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));
2344 codec->slave_dig_outs = NULL; 2372 codec->slave_dig_outs = NULL;
2345 codec->spdif_status_reset = 0; 2373 codec->spdif_status_reset = 0;
2346 module_put(codec->owner); 2374 module_put(codec->owner);
@@ -2676,25 +2704,6 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
2676} 2704}
2677EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put); 2705EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put);
2678 2706
2679#ifdef CONFIG_SND_HDA_INPUT_BEEP
2680/**
2681 * snd_hda_mixer_amp_switch_put_beep - Put callback for a beep AMP switch
2682 *
2683 * This function calls snd_hda_enable_beep_device(), which behaves differently
2684 * depending on beep_mode option.
2685 */
2686int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
2687 struct snd_ctl_elem_value *ucontrol)
2688{
2689 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2690 long *valp = ucontrol->value.integer.value;
2691
2692 snd_hda_enable_beep_device(codec, *valp);
2693 return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2694}
2695EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep);
2696#endif /* CONFIG_SND_HDA_INPUT_BEEP */
2697
2698/* 2707/*
2699 * bound volume controls 2708 * bound volume controls
2700 * 2709 *
@@ -3509,22 +3518,51 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
3509EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all); 3518EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all);
3510 3519
3511/* 3520/*
3521 * supported power states check
3522 */
3523static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, hda_nid_t fg,
3524 unsigned int power_state)
3525{
3526 int sup = snd_hda_param_read(codec, fg, AC_PAR_POWER_STATE);
3527
3528 if (sup == -1)
3529 return false;
3530 if (sup & power_state)
3531 return true;
3532 else
3533 return false;
3534}
3535
3536/*
3512 * set power state of the codec 3537 * set power state of the codec
3513 */ 3538 */
3514static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, 3539static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3515 unsigned int power_state) 3540 unsigned int power_state)
3516{ 3541{
3542 int count;
3543 unsigned int state;
3544
3517 if (codec->patch_ops.set_power_state) { 3545 if (codec->patch_ops.set_power_state) {
3518 codec->patch_ops.set_power_state(codec, fg, power_state); 3546 codec->patch_ops.set_power_state(codec, fg, power_state);
3519 return; 3547 return;
3520 } 3548 }
3521 3549
3522 /* this delay seems necessary to avoid click noise at power-down */ 3550 /* this delay seems necessary to avoid click noise at power-down */
3523 if (power_state == AC_PWRST_D3) 3551 if (power_state == AC_PWRST_D3) {
3524 msleep(100); 3552 /* transition time less than 10ms for power down */
3525 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, 3553 msleep(codec->epss ? 10 : 100);
3526 power_state); 3554 }
3527 snd_hda_codec_set_power_to_all(codec, fg, power_state, true); 3555
3556 /* repeat power states setting at most 10 times*/
3557 for (count = 0; count < 10; count++) {
3558 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
3559 power_state);
3560 snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
3561 state = snd_hda_codec_read(codec, fg, 0,
3562 AC_VERB_GET_POWER_STATE, 0);
3563 if (!(state & AC_PWRST_ERROR))
3564 break;
3565 }
3528} 3566}
3529 3567
3530#ifdef CONFIG_SND_HDA_HWDEP 3568#ifdef CONFIG_SND_HDA_HWDEP
@@ -3545,7 +3583,7 @@ static inline void hda_exec_init_verbs(struct hda_codec *codec) {}
3545static void hda_call_codec_suspend(struct hda_codec *codec) 3583static void hda_call_codec_suspend(struct hda_codec *codec)
3546{ 3584{
3547 if (codec->patch_ops.suspend) 3585 if (codec->patch_ops.suspend)
3548 codec->patch_ops.suspend(codec, PMSG_SUSPEND); 3586 codec->patch_ops.suspend(codec);
3549 hda_cleanup_all_streams(codec); 3587 hda_cleanup_all_streams(codec);
3550 hda_set_power_state(codec, 3588 hda_set_power_state(codec,
3551 codec->afg ? codec->afg : codec->mfg, 3589 codec->afg ? codec->afg : codec->mfg,
@@ -4418,6 +4456,15 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
4418 cancel_delayed_work_sync(&codec->power_work); 4456 cancel_delayed_work_sync(&codec->power_work);
4419 4457
4420 spin_lock(&codec->power_lock); 4458 spin_lock(&codec->power_lock);
4459 /* If the power down delayed work was cancelled above before starting,
4460 * then there is no need to go through power up here.
4461 */
4462 if (codec->power_on) {
4463 if (codec->power_transition < 0)
4464 codec->power_transition = 0;
4465 spin_unlock(&codec->power_lock);
4466 return;
4467 }
4421 trace_hda_power_up(codec); 4468 trace_hda_power_up(codec);
4422 snd_hda_update_power_acct(codec); 4469 snd_hda_update_power_acct(codec);
4423 codec->power_on = 1; 4470 codec->power_on = 1;
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 2fdaadbb4326..e5a7e19a8071 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -323,6 +323,9 @@ enum {
323#define AC_PWRST_D1 0x01 323#define AC_PWRST_D1 0x01
324#define AC_PWRST_D2 0x02 324#define AC_PWRST_D2 0x02
325#define AC_PWRST_D3 0x03 325#define AC_PWRST_D3 0x03
326#define AC_PWRST_ERROR (1<<8)
327#define AC_PWRST_CLK_STOP_OK (1<<9)
328#define AC_PWRST_SETTING_RESET (1<<10)
326 329
327/* Processing capabilies */ 330/* Processing capabilies */
328#define AC_PCAP_BENIGN (1<<0) 331#define AC_PCAP_BENIGN (1<<0)
@@ -703,7 +706,7 @@ struct hda_codec_ops {
703 void (*set_power_state)(struct hda_codec *codec, hda_nid_t fg, 706 void (*set_power_state)(struct hda_codec *codec, hda_nid_t fg,
704 unsigned int power_state); 707 unsigned int power_state);
705#ifdef CONFIG_PM 708#ifdef CONFIG_PM
706 int (*suspend)(struct hda_codec *codec, pm_message_t state); 709 int (*suspend)(struct hda_codec *codec);
707 int (*resume)(struct hda_codec *codec); 710 int (*resume)(struct hda_codec *codec);
708#endif 711#endif
709#ifdef CONFIG_SND_HDA_POWER_SAVE 712#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -858,6 +861,8 @@ struct hda_codec {
858 unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ 861 unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
859 unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ 862 unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */
860 unsigned int no_jack_detect:1; /* Machine has no jack-detection */ 863 unsigned int no_jack_detect:1; /* Machine has no jack-detection */
864 unsigned int pcm_format_first:1; /* PCM format must be set first */
865 unsigned int epss:1; /* supporting EPSS? */
861#ifdef CONFIG_SND_HDA_POWER_SAVE 866#ifdef CONFIG_SND_HDA_POWER_SAVE
862 unsigned int power_on :1; /* current (global) power-state */ 867 unsigned int power_on :1; /* current (global) power-state */
863 int power_transition; /* power-state in transition */ 868 int power_transition; /* power-state in transition */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 7757536b9d5f..c4763c52eaf6 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -72,7 +72,7 @@ static int enable_msi = -1;
72static char *patch[SNDRV_CARDS]; 72static char *patch[SNDRV_CARDS];
73#endif 73#endif
74#ifdef CONFIG_SND_HDA_INPUT_BEEP 74#ifdef CONFIG_SND_HDA_INPUT_BEEP
75static int beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 75static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] =
76 CONFIG_SND_HDA_INPUT_BEEP_MODE}; 76 CONFIG_SND_HDA_INPUT_BEEP_MODE};
77#endif 77#endif
78 78
@@ -103,9 +103,9 @@ module_param_array(patch, charp, NULL, 0444);
103MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface."); 103MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface.");
104#endif 104#endif
105#ifdef CONFIG_SND_HDA_INPUT_BEEP 105#ifdef CONFIG_SND_HDA_INPUT_BEEP
106module_param_array(beep_mode, int, NULL, 0444); 106module_param_array(beep_mode, bool, NULL, 0444);
107MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " 107MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode "
108 "(0=off, 1=on, 2=mute switch on/off) (default=1)."); 108 "(0=off, 1=on) (default=1).");
109#endif 109#endif
110 110
111#ifdef CONFIG_SND_HDA_POWER_SAVE 111#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -151,6 +151,8 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
151 "{Intel, CPT}," 151 "{Intel, CPT},"
152 "{Intel, PPT}," 152 "{Intel, PPT},"
153 "{Intel, LPT}," 153 "{Intel, LPT},"
154 "{Intel, LPT_LP},"
155 "{Intel, HPT},"
154 "{Intel, PBG}," 156 "{Intel, PBG},"
155 "{Intel, SCH}," 157 "{Intel, SCH},"
156 "{ATI, SB450}," 158 "{ATI, SB450},"
@@ -535,6 +537,7 @@ enum {
535#define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ 537#define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */
536#define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ 538#define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */
537#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ 539#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */
540#define AZX_DCAPS_POSFIX_COMBO (1 << 24) /* Use COMBO as default */
538 541
539/* quirks for ATI SB / AMD Hudson */ 542/* quirks for ATI SB / AMD Hudson */
540#define AZX_DCAPS_PRESET_ATI_SB \ 543#define AZX_DCAPS_PRESET_ATI_SB \
@@ -2403,9 +2406,10 @@ static void azx_power_notify(struct hda_bus *bus)
2403 * power management 2406 * power management
2404 */ 2407 */
2405 2408
2406static int azx_suspend(struct pci_dev *pci, pm_message_t state) 2409static int azx_suspend(struct device *dev)
2407{ 2410{
2408 struct snd_card *card = pci_get_drvdata(pci); 2411 struct pci_dev *pci = to_pci_dev(dev);
2412 struct snd_card *card = dev_get_drvdata(dev);
2409 struct azx *chip = card->private_data; 2413 struct azx *chip = card->private_data;
2410 struct azx_pcm *p; 2414 struct azx_pcm *p;
2411 2415
@@ -2424,13 +2428,14 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
2424 pci_disable_msi(chip->pci); 2428 pci_disable_msi(chip->pci);
2425 pci_disable_device(pci); 2429 pci_disable_device(pci);
2426 pci_save_state(pci); 2430 pci_save_state(pci);
2427 pci_set_power_state(pci, pci_choose_state(pci, state)); 2431 pci_set_power_state(pci, PCI_D3hot);
2428 return 0; 2432 return 0;
2429} 2433}
2430 2434
2431static int azx_resume(struct pci_dev *pci) 2435static int azx_resume(struct device *dev)
2432{ 2436{
2433 struct snd_card *card = pci_get_drvdata(pci); 2437 struct pci_dev *pci = to_pci_dev(dev);
2438 struct snd_card *card = dev_get_drvdata(dev);
2434 struct azx *chip = card->private_data; 2439 struct azx *chip = card->private_data;
2435 2440
2436 pci_set_power_state(pci, PCI_D0); 2441 pci_set_power_state(pci, PCI_D0);
@@ -2455,6 +2460,12 @@ static int azx_resume(struct pci_dev *pci)
2455 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2460 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2456 return 0; 2461 return 0;
2457} 2462}
2463static SIMPLE_DEV_PM_OPS(azx_pm, azx_suspend, azx_resume);
2464#define AZX_PM_OPS &azx_pm
2465#else
2466#define azx_suspend(dev)
2467#define azx_resume(dev)
2468#define AZX_PM_OPS NULL
2458#endif /* CONFIG_PM */ 2469#endif /* CONFIG_PM */
2459 2470
2460 2471
@@ -2521,13 +2532,13 @@ static void azx_vs_set_state(struct pci_dev *pci,
2521 disabled ? "Disabling" : "Enabling", 2532 disabled ? "Disabling" : "Enabling",
2522 pci_name(chip->pci)); 2533 pci_name(chip->pci));
2523 if (disabled) { 2534 if (disabled) {
2524 azx_suspend(pci, PMSG_FREEZE); 2535 azx_suspend(&pci->dev);
2525 chip->disabled = true; 2536 chip->disabled = true;
2526 snd_hda_lock_devices(chip->bus); 2537 snd_hda_lock_devices(chip->bus);
2527 } else { 2538 } else {
2528 snd_hda_unlock_devices(chip->bus); 2539 snd_hda_unlock_devices(chip->bus);
2529 chip->disabled = false; 2540 chip->disabled = false;
2530 azx_resume(pci); 2541 azx_resume(&pci->dev);
2531 } 2542 }
2532 } 2543 }
2533} 2544}
@@ -2690,6 +2701,8 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
2690 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), 2701 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
2691 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), 2702 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
2692 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), 2703 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
2704 SND_PCI_QUIRK(0x1043, 0x1ac3, "ASUS X53S", POS_FIX_POSBUF),
2705 SND_PCI_QUIRK(0x1043, 0x1b43, "ASUS K53E", POS_FIX_POSBUF),
2693 SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), 2706 SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
2694 SND_PCI_QUIRK(0x10de, 0xcb89, "Macbook Pro 7,1", POS_FIX_LPIB), 2707 SND_PCI_QUIRK(0x10de, 0xcb89, "Macbook Pro 7,1", POS_FIX_LPIB),
2695 SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB), 2708 SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB),
@@ -2731,6 +2744,10 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
2731 snd_printd(SFX "Using LPIB position fix\n"); 2744 snd_printd(SFX "Using LPIB position fix\n");
2732 return POS_FIX_LPIB; 2745 return POS_FIX_LPIB;
2733 } 2746 }
2747 if (chip->driver_caps & AZX_DCAPS_POSFIX_COMBO) {
2748 snd_printd(SFX "Using COMBO position fix\n");
2749 return POS_FIX_COMBO;
2750 }
2734 return POS_FIX_AUTO; 2751 return POS_FIX_AUTO;
2735} 2752}
2736 2753
@@ -3243,7 +3260,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
3243 /* CPT */ 3260 /* CPT */
3244 { PCI_DEVICE(0x8086, 0x1c20), 3261 { PCI_DEVICE(0x8086, 0x1c20),
3245 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 3262 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3246 AZX_DCAPS_BUFSIZE }, 3263 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
3247 /* PBG */ 3264 /* PBG */
3248 { PCI_DEVICE(0x8086, 0x1d20), 3265 { PCI_DEVICE(0x8086, 0x1d20),
3249 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 3266 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
@@ -3251,11 +3268,23 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
3251 /* Panther Point */ 3268 /* Panther Point */
3252 { PCI_DEVICE(0x8086, 0x1e20), 3269 { PCI_DEVICE(0x8086, 0x1e20),
3253 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 3270 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3254 AZX_DCAPS_BUFSIZE}, 3271 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
3255 /* Lynx Point */ 3272 /* Lynx Point */
3256 { PCI_DEVICE(0x8086, 0x8c20), 3273 { PCI_DEVICE(0x8086, 0x8c20),
3257 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 3274 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3258 AZX_DCAPS_BUFSIZE}, 3275 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
3276 /* Lynx Point-LP */
3277 { PCI_DEVICE(0x8086, 0x9c20),
3278 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3279 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
3280 /* Lynx Point-LP */
3281 { PCI_DEVICE(0x8086, 0x9c21),
3282 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3283 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
3284 /* Haswell */
3285 { PCI_DEVICE(0x8086, 0x0c0c),
3286 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
3287 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
3259 /* SCH */ 3288 /* SCH */
3260 { PCI_DEVICE(0x8086, 0x811b), 3289 { PCI_DEVICE(0x8086, 0x811b),
3261 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | 3290 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
@@ -3341,6 +3370,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
3341 /* VIA VT8251/VT8237A */ 3370 /* VIA VT8251/VT8237A */
3342 { PCI_DEVICE(0x1106, 0x3288), 3371 { PCI_DEVICE(0x1106, 0x3288),
3343 .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, 3372 .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA },
3373 /* VIA GFX VT7122/VX900 */
3374 { PCI_DEVICE(0x1106, 0x9170), .driver_data = AZX_DRIVER_GENERIC },
3375 /* VIA GFX VT6122/VX11 */
3376 { PCI_DEVICE(0x1106, 0x9140), .driver_data = AZX_DRIVER_GENERIC },
3344 /* SIS966 */ 3377 /* SIS966 */
3345 { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS }, 3378 { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS },
3346 /* ULI M5461 */ 3379 /* ULI M5461 */
@@ -3398,10 +3431,9 @@ static struct pci_driver azx_driver = {
3398 .id_table = azx_ids, 3431 .id_table = azx_ids,
3399 .probe = azx_probe, 3432 .probe = azx_probe,
3400 .remove = __devexit_p(azx_remove), 3433 .remove = __devexit_p(azx_remove),
3401#ifdef CONFIG_PM 3434 .driver = {
3402 .suspend = azx_suspend, 3435 .pm = AZX_PM_OPS,
3403 .resume = azx_resume, 3436 },
3404#endif
3405}; 3437};
3406 3438
3407module_pci_driver(azx_driver); 3439module_pci_driver(azx_driver);
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 2dd1c113a4c1..aaccc0236bda 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -127,10 +127,15 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec)
127static void jack_detect_update(struct hda_codec *codec, 127static void jack_detect_update(struct hda_codec *codec,
128 struct hda_jack_tbl *jack) 128 struct hda_jack_tbl *jack)
129{ 129{
130 if (jack->jack_dirty || !jack->jack_detect) { 130 if (!jack->jack_dirty)
131 return;
132
133 if (jack->phantom_jack)
134 jack->pin_sense = AC_PINSENSE_PRESENCE;
135 else
131 jack->pin_sense = read_pin_sense(codec, jack->nid); 136 jack->pin_sense = read_pin_sense(codec, jack->nid);
132 jack->jack_dirty = 0; 137
133 } 138 jack->jack_dirty = 0;
134} 139}
135 140
136/** 141/**
@@ -264,8 +269,8 @@ static void hda_free_jack_priv(struct snd_jack *jack)
264 * This assigns a jack-detection kctl to the given pin. The kcontrol 269 * This assigns a jack-detection kctl to the given pin. The kcontrol
265 * will have the given name and index. 270 * will have the given name and index.
266 */ 271 */
267int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, 272static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
268 const char *name, int idx) 273 const char *name, int idx, bool phantom_jack)
269{ 274{
270 struct hda_jack_tbl *jack; 275 struct hda_jack_tbl *jack;
271 struct snd_kcontrol *kctl; 276 struct snd_kcontrol *kctl;
@@ -283,47 +288,81 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
283 if (err < 0) 288 if (err < 0)
284 return err; 289 return err;
285 jack->kctl = kctl; 290 jack->kctl = kctl;
291 jack->phantom_jack = !!phantom_jack;
292
286 state = snd_hda_jack_detect(codec, nid); 293 state = snd_hda_jack_detect(codec, nid);
287 snd_kctl_jack_report(codec->bus->card, kctl, state); 294 snd_kctl_jack_report(codec->bus->card, kctl, state);
288#ifdef CONFIG_SND_HDA_INPUT_JACK 295#ifdef CONFIG_SND_HDA_INPUT_JACK
289 jack->type = get_input_jack_type(codec, nid); 296 if (!phantom_jack) {
290 err = snd_jack_new(codec->bus->card, name, jack->type, &jack->jack); 297 jack->type = get_input_jack_type(codec, nid);
291 if (err < 0) 298 err = snd_jack_new(codec->bus->card, name, jack->type,
292 return err; 299 &jack->jack);
293 jack->jack->private_data = jack; 300 if (err < 0)
294 jack->jack->private_free = hda_free_jack_priv; 301 return err;
295 snd_jack_report(jack->jack, state ? jack->type : 0); 302 jack->jack->private_data = jack;
303 jack->jack->private_free = hda_free_jack_priv;
304 snd_jack_report(jack->jack, state ? jack->type : 0);
305 }
296#endif 306#endif
297 return 0; 307 return 0;
298} 308}
309
310int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
311 const char *name, int idx)
312{
313 return __snd_hda_jack_add_kctl(codec, nid, name, idx, false);
314}
299EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); 315EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl);
300 316
317/* get the unique index number for the given kctl name */
318static int get_unique_index(struct hda_codec *codec, const char *name, int idx)
319{
320 struct hda_jack_tbl *jack;
321 int i, len = strlen(name);
322 again:
323 jack = codec->jacktbl.list;
324 for (i = 0; i < codec->jacktbl.used; i++, jack++) {
325 /* jack->kctl.id contains "XXX Jack" name string with index */
326 if (jack->kctl &&
327 !strncmp(name, jack->kctl->id.name, len) &&
328 !strcmp(" Jack", jack->kctl->id.name + len) &&
329 jack->kctl->id.index == idx) {
330 idx++;
331 goto again;
332 }
333 }
334 return idx;
335}
336
301static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, 337static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
302 const struct auto_pin_cfg *cfg, 338 const struct auto_pin_cfg *cfg)
303 char *lastname, int *lastidx)
304{ 339{
305 unsigned int def_conf, conn; 340 unsigned int def_conf, conn;
306 char name[44]; 341 char name[44];
307 int idx, err; 342 int idx, err;
343 bool phantom_jack;
308 344
309 if (!nid) 345 if (!nid)
310 return 0; 346 return 0;
311 if (!is_jack_detectable(codec, nid))
312 return 0;
313 def_conf = snd_hda_codec_get_pincfg(codec, nid); 347 def_conf = snd_hda_codec_get_pincfg(codec, nid);
314 conn = get_defcfg_connect(def_conf); 348 conn = get_defcfg_connect(def_conf);
315 if (conn != AC_JACK_PORT_COMPLEX) 349 if (conn == AC_JACK_PORT_NONE)
316 return 0; 350 return 0;
351 phantom_jack = (conn != AC_JACK_PORT_COMPLEX) ||
352 !is_jack_detectable(codec, nid);
317 353
318 snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); 354 snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx);
319 if (!strcmp(name, lastname) && idx == *lastidx) 355 if (phantom_jack)
320 idx++; 356 /* Example final name: "Internal Mic Phantom Jack" */
321 strncpy(lastname, name, 44); 357 strncat(name, " Phantom", sizeof(name) - strlen(name) - 1);
322 *lastidx = idx; 358 idx = get_unique_index(codec, name, idx);
323 err = snd_hda_jack_add_kctl(codec, nid, name, idx); 359 err = __snd_hda_jack_add_kctl(codec, nid, name, idx, phantom_jack);
324 if (err < 0) 360 if (err < 0)
325 return err; 361 return err;
326 return snd_hda_jack_detect_enable(codec, nid, 0); 362
363 if (!phantom_jack)
364 return snd_hda_jack_detect_enable(codec, nid, 0);
365 return 0;
327} 366}
328 367
329/** 368/**
@@ -333,42 +372,41 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,
333 const struct auto_pin_cfg *cfg) 372 const struct auto_pin_cfg *cfg)
334{ 373{
335 const hda_nid_t *p; 374 const hda_nid_t *p;
336 int i, err, lastidx = 0; 375 int i, err;
337 char lastname[44] = "";
338 376
339 for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { 377 for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
340 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); 378 err = add_jack_kctl(codec, *p, cfg);
341 if (err < 0) 379 if (err < 0)
342 return err; 380 return err;
343 } 381 }
344 for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { 382 for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) {
345 if (*p == *cfg->line_out_pins) /* might be duplicated */ 383 if (*p == *cfg->line_out_pins) /* might be duplicated */
346 break; 384 break;
347 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); 385 err = add_jack_kctl(codec, *p, cfg);
348 if (err < 0) 386 if (err < 0)
349 return err; 387 return err;
350 } 388 }
351 for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { 389 for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) {
352 if (*p == *cfg->line_out_pins) /* might be duplicated */ 390 if (*p == *cfg->line_out_pins) /* might be duplicated */
353 break; 391 break;
354 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); 392 err = add_jack_kctl(codec, *p, cfg);
355 if (err < 0) 393 if (err < 0)
356 return err; 394 return err;
357 } 395 }
358 for (i = 0; i < cfg->num_inputs; i++) { 396 for (i = 0; i < cfg->num_inputs; i++) {
359 err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, lastname, &lastidx); 397 err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg);
360 if (err < 0) 398 if (err < 0)
361 return err; 399 return err;
362 } 400 }
363 for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { 401 for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) {
364 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); 402 err = add_jack_kctl(codec, *p, cfg);
365 if (err < 0) 403 if (err < 0)
366 return err; 404 return err;
367 } 405 }
368 err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, lastname, &lastidx); 406 err = add_jack_kctl(codec, cfg->dig_in_pin, cfg);
369 if (err < 0) 407 if (err < 0)
370 return err; 408 return err;
371 err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, lastname, &lastidx); 409 err = add_jack_kctl(codec, cfg->mono_out_pin, cfg);
372 if (err < 0) 410 if (err < 0)
373 return err; 411 return err;
374 return 0; 412 return 0;
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index 8ae52465ec5d..a9803da633c0 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -23,6 +23,7 @@ struct hda_jack_tbl {
23 unsigned int pin_sense; /* cached pin-sense value */ 23 unsigned int pin_sense; /* cached pin-sense value */
24 unsigned int jack_detect:1; /* capable of jack-detection? */ 24 unsigned int jack_detect:1; /* capable of jack-detection? */
25 unsigned int jack_dirty:1; /* needs to update? */ 25 unsigned int jack_dirty:1; /* needs to update? */
26 unsigned int phantom_jack:1; /* a fixed, always present port? */
26 struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */ 27 struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */
27#ifdef CONFIG_SND_HDA_INPUT_JACK 28#ifdef CONFIG_SND_HDA_INPUT_JACK
28 int type; 29 int type;
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 9a096a8e0fc5..1b4c12941baa 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -89,7 +89,7 @@
89 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 89 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
90 .subdevice = HDA_SUBDEV_AMP_FLAG, \ 90 .subdevice = HDA_SUBDEV_AMP_FLAG, \
91 .info = snd_hda_mixer_amp_switch_info, \ 91 .info = snd_hda_mixer_amp_switch_info, \
92 .get = snd_hda_mixer_amp_switch_get, \ 92 .get = snd_hda_mixer_amp_switch_get_beep, \
93 .put = snd_hda_mixer_amp_switch_put_beep, \ 93 .put = snd_hda_mixer_amp_switch_put_beep, \
94 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } 94 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
95#else 95#else
@@ -121,6 +121,8 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
121int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, 121int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
122 struct snd_ctl_elem_value *ucontrol); 122 struct snd_ctl_elem_value *ucontrol);
123#ifdef CONFIG_SND_HDA_INPUT_BEEP 123#ifdef CONFIG_SND_HDA_INPUT_BEEP
124int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol,
125 struct snd_ctl_elem_value *ucontrol);
124int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, 126int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
125 struct snd_ctl_elem_value *ucontrol); 127 struct snd_ctl_elem_value *ucontrol);
126#endif 128#endif
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index e59e2f059b6e..6894ec66258c 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -412,7 +412,7 @@ static void print_digital_conv(struct snd_info_buffer *buffer,
412 if (digi1 & AC_DIG1_EMPHASIS) 412 if (digi1 & AC_DIG1_EMPHASIS)
413 snd_iprintf(buffer, " Preemphasis"); 413 snd_iprintf(buffer, " Preemphasis");
414 if (digi1 & AC_DIG1_COPYRIGHT) 414 if (digi1 & AC_DIG1_COPYRIGHT)
415 snd_iprintf(buffer, " Copyright"); 415 snd_iprintf(buffer, " Non-Copyright");
416 if (digi1 & AC_DIG1_NONAUDIO) 416 if (digi1 & AC_DIG1_NONAUDIO)
417 snd_iprintf(buffer, " Non-Audio"); 417 snd_iprintf(buffer, " Non-Audio");
418 if (digi1 & AC_DIG1_PROFESSIONAL) 418 if (digi1 & AC_DIG1_PROFESSIONAL)
@@ -426,10 +426,10 @@ static void print_digital_conv(struct snd_info_buffer *buffer,
426 426
427static const char *get_pwr_state(u32 state) 427static const char *get_pwr_state(u32 state)
428{ 428{
429 static const char * const buf[4] = { 429 static const char * const buf[] = {
430 "D0", "D1", "D2", "D3" 430 "D0", "D1", "D2", "D3", "D3cold"
431 }; 431 };
432 if (state < 4) 432 if (state < ARRAY_SIZE(buf))
433 return buf[state]; 433 return buf[state];
434 return "UNKNOWN"; 434 return "UNKNOWN";
435} 435}
@@ -451,14 +451,21 @@ static void print_power_state(struct snd_info_buffer *buffer,
451 int sup = snd_hda_param_read(codec, nid, AC_PAR_POWER_STATE); 451 int sup = snd_hda_param_read(codec, nid, AC_PAR_POWER_STATE);
452 int pwr = snd_hda_codec_read(codec, nid, 0, 452 int pwr = snd_hda_codec_read(codec, nid, 0,
453 AC_VERB_GET_POWER_STATE, 0); 453 AC_VERB_GET_POWER_STATE, 0);
454 if (sup) 454 if (sup != -1)
455 snd_iprintf(buffer, " Power states: %s\n", 455 snd_iprintf(buffer, " Power states: %s\n",
456 bits_names(sup, names, ARRAY_SIZE(names))); 456 bits_names(sup, names, ARRAY_SIZE(names)));
457 457
458 snd_iprintf(buffer, " Power: setting=%s, actual=%s\n", 458 snd_iprintf(buffer, " Power: setting=%s, actual=%s",
459 get_pwr_state(pwr & AC_PWRST_SETTING), 459 get_pwr_state(pwr & AC_PWRST_SETTING),
460 get_pwr_state((pwr & AC_PWRST_ACTUAL) >> 460 get_pwr_state((pwr & AC_PWRST_ACTUAL) >>
461 AC_PWRST_ACTUAL_SHIFT)); 461 AC_PWRST_ACTUAL_SHIFT));
462 if (pwr & AC_PWRST_ERROR)
463 snd_iprintf(buffer, ", Error");
464 if (pwr & AC_PWRST_CLK_STOP_OK)
465 snd_iprintf(buffer, ", Clock-stop-OK");
466 if (pwr & AC_PWRST_SETTING_RESET)
467 snd_iprintf(buffer, ", Setting-reset");
468 snd_iprintf(buffer, "\n");
462} 469}
463 470
464static void print_unsol_cap(struct snd_info_buffer *buffer, 471static void print_unsol_cap(struct snd_info_buffer *buffer,
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index d8b2d6dee986..0208fa121e5a 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -642,7 +642,7 @@ static void ad198x_free(struct hda_codec *codec)
642} 642}
643 643
644#ifdef CONFIG_PM 644#ifdef CONFIG_PM
645static int ad198x_suspend(struct hda_codec *codec, pm_message_t state) 645static int ad198x_suspend(struct hda_codec *codec)
646{ 646{
647 ad198x_shutup(codec); 647 ad198x_shutup(codec);
648 return 0; 648 return 0;
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index d0d3540e39e7..49750a96d649 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -246,7 +246,7 @@ static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
246 AC_VERB_SET_AMP_GAIN_MUTE, 246 AC_VERB_SET_AMP_GAIN_MUTE,
247 AMP_OUT_UNMUTE); 247 AMP_OUT_UNMUTE);
248 } 248 }
249 if (dac) 249 if (dac && (get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
250 snd_hda_codec_write(codec, dac, 0, 250 snd_hda_codec_write(codec, dac, 0,
251 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO); 251 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO);
252} 252}
@@ -261,7 +261,7 @@ static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
261 AC_VERB_SET_AMP_GAIN_MUTE, 261 AC_VERB_SET_AMP_GAIN_MUTE,
262 AMP_IN_UNMUTE(0)); 262 AMP_IN_UNMUTE(0));
263 } 263 }
264 if (adc) 264 if (adc && (get_wcaps(codec, adc) & AC_WCAP_IN_AMP))
265 snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE, 265 snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE,
266 AMP_IN_UNMUTE(0)); 266 AMP_IN_UNMUTE(0));
267} 267}
@@ -275,6 +275,10 @@ static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
275 int type = dir ? HDA_INPUT : HDA_OUTPUT; 275 int type = dir ? HDA_INPUT : HDA_OUTPUT;
276 struct snd_kcontrol_new knew = 276 struct snd_kcontrol_new knew =
277 HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type); 277 HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type);
278 if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_MUTE) == 0) {
279 snd_printdd("Skipping '%s %s Switch' (no mute on node 0x%x)\n", pfx, dirstr[dir], nid);
280 return 0;
281 }
278 sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); 282 sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]);
279 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); 283 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
280} 284}
@@ -286,6 +290,10 @@ static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
286 int type = dir ? HDA_INPUT : HDA_OUTPUT; 290 int type = dir ? HDA_INPUT : HDA_OUTPUT;
287 struct snd_kcontrol_new knew = 291 struct snd_kcontrol_new knew =
288 HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); 292 HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type);
293 if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_NUM_STEPS) == 0) {
294 snd_printdd("Skipping '%s %s Volume' (no amp on node 0x%x)\n", pfx, dirstr[dir], nid);
295 return 0;
296 }
289 sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); 297 sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]);
290 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); 298 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
291} 299}
@@ -464,50 +472,17 @@ exit:
464} 472}
465 473
466/* 474/*
467 * PCM stuffs 475 * PCM callbacks
468 */ 476 */
469static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid, 477static int ca0132_playback_pcm_open(struct hda_pcm_stream *hinfo,
470 u32 stream_tag, 478 struct hda_codec *codec,
471 int channel_id, int format) 479 struct snd_pcm_substream *substream)
472{ 480{
473 unsigned int oldval, newval; 481 struct ca0132_spec *spec = codec->spec;
474 482 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
475 if (!nid) 483 hinfo);
476 return;
477
478 snd_printdd("ca0132_setup_stream: "
479 "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
480 nid, stream_tag, channel_id, format);
481
482 /* update the format-id if changed */
483 oldval = snd_hda_codec_read(codec, nid, 0,
484 AC_VERB_GET_STREAM_FORMAT,
485 0);
486 if (oldval != format) {
487 msleep(20);
488 snd_hda_codec_write(codec, nid, 0,
489 AC_VERB_SET_STREAM_FORMAT,
490 format);
491 }
492
493 oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
494 newval = (stream_tag << 4) | channel_id;
495 if (oldval != newval) {
496 snd_hda_codec_write(codec, nid, 0,
497 AC_VERB_SET_CHANNEL_STREAMID,
498 newval);
499 }
500}
501
502static void ca0132_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
503{
504 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0);
505 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
506} 484}
507 485
508/*
509 * PCM callbacks
510 */
511static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 486static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
512 struct hda_codec *codec, 487 struct hda_codec *codec,
513 unsigned int stream_tag, 488 unsigned int stream_tag,
@@ -515,10 +490,8 @@ static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
515 struct snd_pcm_substream *substream) 490 struct snd_pcm_substream *substream)
516{ 491{
517 struct ca0132_spec *spec = codec->spec; 492 struct ca0132_spec *spec = codec->spec;
518 493 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
519 ca0132_setup_stream(codec, spec->dacs[0], stream_tag, 0, format); 494 stream_tag, format, substream);
520
521 return 0;
522} 495}
523 496
524static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 497static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
@@ -526,92 +499,45 @@ static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
526 struct snd_pcm_substream *substream) 499 struct snd_pcm_substream *substream)
527{ 500{
528 struct ca0132_spec *spec = codec->spec; 501 struct ca0132_spec *spec = codec->spec;
529 502 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
530 ca0132_cleanup_stream(codec, spec->dacs[0]);
531
532 return 0;
533} 503}
534 504
535/* 505/*
536 * Digital out 506 * Digital out
537 */ 507 */
538static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 508static int ca0132_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
539 struct hda_codec *codec, 509 struct hda_codec *codec,
540 unsigned int stream_tag, 510 struct snd_pcm_substream *substream)
541 unsigned int format,
542 struct snd_pcm_substream *substream)
543{ 511{
544 struct ca0132_spec *spec = codec->spec; 512 struct ca0132_spec *spec = codec->spec;
545 513 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
546 ca0132_setup_stream(codec, spec->dig_out, stream_tag, 0, format);
547
548 return 0;
549} 514}
550 515
551static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 516static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
552 struct hda_codec *codec,
553 struct snd_pcm_substream *substream)
554{
555 struct ca0132_spec *spec = codec->spec;
556
557 ca0132_cleanup_stream(codec, spec->dig_out);
558
559 return 0;
560}
561
562/*
563 * Analog capture
564 */
565static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
566 struct hda_codec *codec, 517 struct hda_codec *codec,
567 unsigned int stream_tag, 518 unsigned int stream_tag,
568 unsigned int format, 519 unsigned int format,
569 struct snd_pcm_substream *substream) 520 struct snd_pcm_substream *substream)
570{ 521{
571 struct ca0132_spec *spec = codec->spec; 522 struct ca0132_spec *spec = codec->spec;
572 523 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
573 ca0132_setup_stream(codec, spec->adcs[substream->number], 524 stream_tag, format, substream);
574 stream_tag, 0, format);
575
576 return 0;
577} 525}
578 526
579static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 527static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
580 struct hda_codec *codec, 528 struct hda_codec *codec,
581 struct snd_pcm_substream *substream) 529 struct snd_pcm_substream *substream)
582{ 530{
583 struct ca0132_spec *spec = codec->spec; 531 struct ca0132_spec *spec = codec->spec;
584 532 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
585 ca0132_cleanup_stream(codec, spec->adcs[substream->number]);
586
587 return 0;
588} 533}
589 534
590/* 535static int ca0132_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
591 * Digital capture 536 struct hda_codec *codec,
592 */ 537 struct snd_pcm_substream *substream)
593static int ca0132_dig_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
594 struct hda_codec *codec,
595 unsigned int stream_tag,
596 unsigned int format,
597 struct snd_pcm_substream *substream)
598{ 538{
599 struct ca0132_spec *spec = codec->spec; 539 struct ca0132_spec *spec = codec->spec;
600 540 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
601 ca0132_setup_stream(codec, spec->dig_in, stream_tag, 0, format);
602
603 return 0;
604}
605
606static int ca0132_dig_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
607 struct hda_codec *codec,
608 struct snd_pcm_substream *substream)
609{
610 struct ca0132_spec *spec = codec->spec;
611
612 ca0132_cleanup_stream(codec, spec->dig_in);
613
614 return 0;
615} 541}
616 542
617/* 543/*
@@ -621,6 +547,7 @@ static struct hda_pcm_stream ca0132_pcm_analog_playback = {
621 .channels_min = 2, 547 .channels_min = 2,
622 .channels_max = 2, 548 .channels_max = 2,
623 .ops = { 549 .ops = {
550 .open = ca0132_playback_pcm_open,
624 .prepare = ca0132_playback_pcm_prepare, 551 .prepare = ca0132_playback_pcm_prepare,
625 .cleanup = ca0132_playback_pcm_cleanup 552 .cleanup = ca0132_playback_pcm_cleanup
626 }, 553 },
@@ -630,10 +557,6 @@ static struct hda_pcm_stream ca0132_pcm_analog_capture = {
630 .substreams = 1, 557 .substreams = 1,
631 .channels_min = 2, 558 .channels_min = 2,
632 .channels_max = 2, 559 .channels_max = 2,
633 .ops = {
634 .prepare = ca0132_capture_pcm_prepare,
635 .cleanup = ca0132_capture_pcm_cleanup
636 },
637}; 560};
638 561
639static struct hda_pcm_stream ca0132_pcm_digital_playback = { 562static struct hda_pcm_stream ca0132_pcm_digital_playback = {
@@ -641,6 +564,8 @@ static struct hda_pcm_stream ca0132_pcm_digital_playback = {
641 .channels_min = 2, 564 .channels_min = 2,
642 .channels_max = 2, 565 .channels_max = 2,
643 .ops = { 566 .ops = {
567 .open = ca0132_dig_playback_pcm_open,
568 .close = ca0132_dig_playback_pcm_close,
644 .prepare = ca0132_dig_playback_pcm_prepare, 569 .prepare = ca0132_dig_playback_pcm_prepare,
645 .cleanup = ca0132_dig_playback_pcm_cleanup 570 .cleanup = ca0132_dig_playback_pcm_cleanup
646 }, 571 },
@@ -650,10 +575,6 @@ static struct hda_pcm_stream ca0132_pcm_digital_capture = {
650 .substreams = 1, 575 .substreams = 1,
651 .channels_min = 2, 576 .channels_min = 2,
652 .channels_max = 2, 577 .channels_max = 2,
653 .ops = {
654 .prepare = ca0132_dig_capture_pcm_prepare,
655 .cleanup = ca0132_dig_capture_pcm_cleanup
656 },
657}; 578};
658 579
659static int ca0132_build_pcms(struct hda_codec *codec) 580static int ca0132_build_pcms(struct hda_codec *codec)
@@ -928,18 +849,16 @@ static int ca0132_build_controls(struct hda_codec *codec)
928 spec->dig_out); 849 spec->dig_out);
929 if (err < 0) 850 if (err < 0)
930 return err; 851 return err;
931 err = add_out_volume(codec, spec->dig_out, "IEC958"); 852 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
932 if (err < 0) 853 if (err < 0)
933 return err; 854 return err;
855 /* spec->multiout.share_spdif = 1; */
934 } 856 }
935 857
936 if (spec->dig_in) { 858 if (spec->dig_in) {
937 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in); 859 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
938 if (err < 0) 860 if (err < 0)
939 return err; 861 return err;
940 err = add_in_volume(codec, spec->dig_in, "IEC958");
941 if (err < 0)
942 return err;
943 } 862 }
944 return 0; 863 return 0;
945} 864}
@@ -961,6 +880,9 @@ static void ca0132_config(struct hda_codec *codec)
961 struct ca0132_spec *spec = codec->spec; 880 struct ca0132_spec *spec = codec->spec;
962 struct auto_pin_cfg *cfg = &spec->autocfg; 881 struct auto_pin_cfg *cfg = &spec->autocfg;
963 882
883 codec->pcm_format_first = 1;
884 codec->no_sticky_stream = 1;
885
964 /* line-outs */ 886 /* line-outs */
965 cfg->line_outs = 1; 887 cfg->line_outs = 1;
966 cfg->line_out_pins[0] = 0x0b; /* front */ 888 cfg->line_out_pins[0] = 0x0b; /* front */
@@ -988,14 +910,24 @@ static void ca0132_config(struct hda_codec *codec)
988 910
989 /* Mic-in */ 911 /* Mic-in */
990 spec->input_pins[0] = 0x12; 912 spec->input_pins[0] = 0x12;
991 spec->input_labels[0] = "Mic-In"; 913 spec->input_labels[0] = "Mic";
992 spec->adcs[0] = 0x07; 914 spec->adcs[0] = 0x07;
993 915
994 /* Line-In */ 916 /* Line-In */
995 spec->input_pins[1] = 0x11; 917 spec->input_pins[1] = 0x11;
996 spec->input_labels[1] = "Line-In"; 918 spec->input_labels[1] = "Line";
997 spec->adcs[1] = 0x08; 919 spec->adcs[1] = 0x08;
998 spec->num_inputs = 2; 920 spec->num_inputs = 2;
921
922 /* SPDIF I/O */
923 spec->dig_out = 0x05;
924 spec->multiout.dig_out_nid = spec->dig_out;
925 cfg->dig_out_pins[0] = 0x0c;
926 cfg->dig_outs = 1;
927 cfg->dig_out_type[0] = HDA_PCM_TYPE_SPDIF;
928 spec->dig_in = 0x09;
929 cfg->dig_in_pin = 0x0e;
930 cfg->dig_in_type = HDA_PCM_TYPE_SPDIF;
999} 931}
1000 932
1001static void ca0132_init_chip(struct hda_codec *codec) 933static void ca0132_init_chip(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 9647ed4d7929..0c4c1a61b378 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -1892,7 +1892,7 @@ static int cs421x_parse_auto_config(struct hda_codec *codec)
1892 Manage PDREF, when transitioning to D3hot 1892 Manage PDREF, when transitioning to D3hot
1893 (DAC,ADC) -> D3, PDREF=1, AFG->D3 1893 (DAC,ADC) -> D3, PDREF=1, AFG->D3
1894*/ 1894*/
1895static int cs421x_suspend(struct hda_codec *codec, pm_message_t state) 1895static int cs421x_suspend(struct hda_codec *codec)
1896{ 1896{
1897 struct cs_spec *spec = codec->spec; 1897 struct cs_spec *spec = codec->spec;
1898 unsigned int coef; 1898 unsigned int coef;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 2bf99fc1cbf2..5e22a8f43d2e 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -554,7 +554,7 @@ static int conexant_build_controls(struct hda_codec *codec)
554} 554}
555 555
556#ifdef CONFIG_SND_HDA_POWER_SAVE 556#ifdef CONFIG_SND_HDA_POWER_SAVE
557static int conexant_suspend(struct hda_codec *codec, pm_message_t state) 557static int conexant_suspend(struct hda_codec *codec)
558{ 558{
559 snd_hda_shutup_pins(codec); 559 snd_hda_shutup_pins(codec);
560 return 0; 560 return 0;
@@ -2967,12 +2967,10 @@ static const char * const cxt5066_models[CXT5066_MODELS] = {
2967}; 2967};
2968 2968
2969static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { 2969static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2970 SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT5066_AUTO),
2971 SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), 2970 SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
2972 SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), 2971 SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
2973 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), 2972 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
2974 SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO), 2973 SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO),
2975 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
2976 SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), 2974 SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
2977 SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD), 2975 SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD),
2978 SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD), 2976 SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD),
@@ -2988,14 +2986,10 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2988 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), 2986 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
2989 SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), 2987 SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
2990 SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), 2988 SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
2991 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T510", CXT5066_AUTO),
2992 SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO),
2993 SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), 2989 SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD),
2994 SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), 2990 SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD),
2995 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), 2991 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
2996 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), 2992 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
2997 SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO),
2998 SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO),
2999 {} 2993 {}
3000}; 2994};
3001 2995
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index ad319d4dc32f..8f23374fa642 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -85,7 +85,7 @@ struct hdmi_spec {
85 * Non-generic ATI/NVIDIA specific 85 * Non-generic ATI/NVIDIA specific
86 */ 86 */
87 struct hda_multi_out multiout; 87 struct hda_multi_out multiout;
88 const struct hda_pcm_stream *pcm_playback; 88 struct hda_pcm_stream pcm_playback;
89}; 89};
90 90
91 91
@@ -787,7 +787,7 @@ static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
787 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY); 787 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
788 788
789 printk(KERN_INFO 789 printk(KERN_INFO
790 "HDMI CP event: CODEC=%d PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n", 790 "HDMI CP event: CODEC=%d TAG=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
791 codec->addr, 791 codec->addr,
792 tag, 792 tag,
793 subtag, 793 subtag,
@@ -876,7 +876,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
876 struct hdmi_spec_per_pin *per_pin; 876 struct hdmi_spec_per_pin *per_pin;
877 struct hdmi_eld *eld; 877 struct hdmi_eld *eld;
878 struct hdmi_spec_per_cvt *per_cvt = NULL; 878 struct hdmi_spec_per_cvt *per_cvt = NULL;
879 int pinctl;
880 879
881 /* Validate hinfo */ 880 /* Validate hinfo */
882 pin_idx = hinfo_to_pin_index(spec, hinfo); 881 pin_idx = hinfo_to_pin_index(spec, hinfo);
@@ -912,11 +911,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
912 snd_hda_codec_write(codec, per_pin->pin_nid, 0, 911 snd_hda_codec_write(codec, per_pin->pin_nid, 0,
913 AC_VERB_SET_CONNECT_SEL, 912 AC_VERB_SET_CONNECT_SEL,
914 mux_idx); 913 mux_idx);
915 pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
916 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
917 snd_hda_codec_write(codec, per_pin->pin_nid, 0,
918 AC_VERB_SET_PIN_WIDGET_CONTROL,
919 pinctl | PIN_OUT);
920 snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid); 914 snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
921 915
922 /* Initially set the converter's capabilities */ 916 /* Initially set the converter's capabilities */
@@ -1153,11 +1147,17 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1153 struct hdmi_spec *spec = codec->spec; 1147 struct hdmi_spec *spec = codec->spec;
1154 int pin_idx = hinfo_to_pin_index(spec, hinfo); 1148 int pin_idx = hinfo_to_pin_index(spec, hinfo);
1155 hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid; 1149 hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid;
1150 int pinctl;
1156 1151
1157 hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels); 1152 hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
1158 1153
1159 hdmi_setup_audio_infoframe(codec, pin_idx, substream); 1154 hdmi_setup_audio_infoframe(codec, pin_idx, substream);
1160 1155
1156 pinctl = snd_hda_codec_read(codec, pin_nid, 0,
1157 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1158 snd_hda_codec_write(codec, pin_nid, 0,
1159 AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl | PIN_OUT);
1160
1161 return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); 1161 return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
1162} 1162}
1163 1163
@@ -1165,14 +1165,20 @@ static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1165 struct hda_codec *codec, 1165 struct hda_codec *codec,
1166 struct snd_pcm_substream *substream) 1166 struct snd_pcm_substream *substream)
1167{ 1167{
1168 snd_hda_codec_cleanup_stream(codec, hinfo->nid);
1169 return 0;
1170}
1171
1172static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
1173 struct hda_codec *codec,
1174 struct snd_pcm_substream *substream)
1175{
1168 struct hdmi_spec *spec = codec->spec; 1176 struct hdmi_spec *spec = codec->spec;
1169 int cvt_idx, pin_idx; 1177 int cvt_idx, pin_idx;
1170 struct hdmi_spec_per_cvt *per_cvt; 1178 struct hdmi_spec_per_cvt *per_cvt;
1171 struct hdmi_spec_per_pin *per_pin; 1179 struct hdmi_spec_per_pin *per_pin;
1172 int pinctl; 1180 int pinctl;
1173 1181
1174 snd_hda_codec_cleanup_stream(codec, hinfo->nid);
1175
1176 if (hinfo->nid) { 1182 if (hinfo->nid) {
1177 cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid); 1183 cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid);
1178 if (snd_BUG_ON(cvt_idx < 0)) 1184 if (snd_BUG_ON(cvt_idx < 0))
@@ -1195,12 +1201,12 @@ static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1195 pinctl & ~PIN_OUT); 1201 pinctl & ~PIN_OUT);
1196 snd_hda_spdif_ctls_unassign(codec, pin_idx); 1202 snd_hda_spdif_ctls_unassign(codec, pin_idx);
1197 } 1203 }
1198
1199 return 0; 1204 return 0;
1200} 1205}
1201 1206
1202static const struct hda_pcm_ops generic_ops = { 1207static const struct hda_pcm_ops generic_ops = {
1203 .open = hdmi_pcm_open, 1208 .open = hdmi_pcm_open,
1209 .close = hdmi_pcm_close,
1204 .prepare = generic_hdmi_playback_pcm_prepare, 1210 .prepare = generic_hdmi_playback_pcm_prepare,
1205 .cleanup = generic_hdmi_playback_pcm_cleanup, 1211 .cleanup = generic_hdmi_playback_pcm_cleanup,
1206}; 1212};
@@ -1277,23 +1283,34 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
1277 return 0; 1283 return 0;
1278} 1284}
1279 1285
1280static int generic_hdmi_init(struct hda_codec *codec) 1286static int generic_hdmi_init_per_pins(struct hda_codec *codec)
1281{ 1287{
1282 struct hdmi_spec *spec = codec->spec; 1288 struct hdmi_spec *spec = codec->spec;
1283 int pin_idx; 1289 int pin_idx;
1284 1290
1285 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 1291 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1286 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 1292 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1287 hda_nid_t pin_nid = per_pin->pin_nid;
1288 struct hdmi_eld *eld = &per_pin->sink_eld; 1293 struct hdmi_eld *eld = &per_pin->sink_eld;
1289 1294
1290 hdmi_init_pin(codec, pin_nid);
1291 snd_hda_jack_detect_enable(codec, pin_nid, pin_nid);
1292
1293 per_pin->codec = codec; 1295 per_pin->codec = codec;
1294 INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); 1296 INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld);
1295 snd_hda_eld_proc_new(codec, eld, pin_idx); 1297 snd_hda_eld_proc_new(codec, eld, pin_idx);
1296 } 1298 }
1299 return 0;
1300}
1301
1302static int generic_hdmi_init(struct hda_codec *codec)
1303{
1304 struct hdmi_spec *spec = codec->spec;
1305 int pin_idx;
1306
1307 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1308 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1309 hda_nid_t pin_nid = per_pin->pin_nid;
1310
1311 hdmi_init_pin(codec, pin_nid);
1312 snd_hda_jack_detect_enable(codec, pin_nid, pin_nid);
1313 }
1297 snd_hda_jack_report_sync(codec); 1314 snd_hda_jack_report_sync(codec);
1298 return 0; 1315 return 0;
1299} 1316}
@@ -1338,6 +1355,7 @@ static int patch_generic_hdmi(struct hda_codec *codec)
1338 return -EINVAL; 1355 return -EINVAL;
1339 } 1356 }
1340 codec->patch_ops = generic_hdmi_patch_ops; 1357 codec->patch_ops = generic_hdmi_patch_ops;
1358 generic_hdmi_init_per_pins(codec);
1341 1359
1342 init_channel_allocations(); 1360 init_channel_allocations();
1343 1361
@@ -1352,45 +1370,65 @@ static int simple_playback_build_pcms(struct hda_codec *codec)
1352{ 1370{
1353 struct hdmi_spec *spec = codec->spec; 1371 struct hdmi_spec *spec = codec->spec;
1354 struct hda_pcm *info = spec->pcm_rec; 1372 struct hda_pcm *info = spec->pcm_rec;
1355 int i; 1373 unsigned int chans;
1374 struct hda_pcm_stream *pstr;
1356 1375
1357 codec->num_pcms = spec->num_cvts; 1376 codec->num_pcms = 1;
1358 codec->pcm_info = info; 1377 codec->pcm_info = info;
1359 1378
1360 for (i = 0; i < codec->num_pcms; i++, info++) { 1379 chans = get_wcaps(codec, spec->cvts[0].cvt_nid);
1361 unsigned int chans; 1380 chans = get_wcaps_channels(chans);
1362 struct hda_pcm_stream *pstr;
1363 1381
1364 chans = get_wcaps(codec, spec->cvts[i].cvt_nid); 1382 info->name = get_hdmi_pcm_name(0);
1365 chans = get_wcaps_channels(chans); 1383 info->pcm_type = HDA_PCM_TYPE_HDMI;
1366 1384 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
1367 info->name = get_hdmi_pcm_name(i); 1385 *pstr = spec->pcm_playback;
1368 info->pcm_type = HDA_PCM_TYPE_HDMI; 1386 pstr->nid = spec->cvts[0].cvt_nid;
1369 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; 1387 if (pstr->channels_max <= 2 && chans && chans <= 16)
1370 snd_BUG_ON(!spec->pcm_playback); 1388 pstr->channels_max = chans;
1371 *pstr = *spec->pcm_playback;
1372 pstr->nid = spec->cvts[i].cvt_nid;
1373 if (pstr->channels_max <= 2 && chans && chans <= 16)
1374 pstr->channels_max = chans;
1375 }
1376 1389
1377 return 0; 1390 return 0;
1378} 1391}
1379 1392
1393/* unsolicited event for jack sensing */
1394static void simple_hdmi_unsol_event(struct hda_codec *codec,
1395 unsigned int res)
1396{
1397 snd_hda_jack_set_dirty_all(codec);
1398 snd_hda_jack_report_sync(codec);
1399}
1400
1401/* generic_hdmi_build_jack can be used for simple_hdmi, too,
1402 * as long as spec->pins[] is set correctly
1403 */
1404#define simple_hdmi_build_jack generic_hdmi_build_jack
1405
1380static int simple_playback_build_controls(struct hda_codec *codec) 1406static int simple_playback_build_controls(struct hda_codec *codec)
1381{ 1407{
1382 struct hdmi_spec *spec = codec->spec; 1408 struct hdmi_spec *spec = codec->spec;
1383 int err; 1409 int err;
1384 int i;
1385 1410
1386 for (i = 0; i < codec->num_pcms; i++) { 1411 err = snd_hda_create_spdif_out_ctls(codec,
1387 err = snd_hda_create_spdif_out_ctls(codec, 1412 spec->cvts[0].cvt_nid,
1388 spec->cvts[i].cvt_nid, 1413 spec->cvts[0].cvt_nid);
1389 spec->cvts[i].cvt_nid); 1414 if (err < 0)
1390 if (err < 0) 1415 return err;
1391 return err; 1416 return simple_hdmi_build_jack(codec, 0);
1392 } 1417}
1393 1418
1419static int simple_playback_init(struct hda_codec *codec)
1420{
1421 struct hdmi_spec *spec = codec->spec;
1422 hda_nid_t pin = spec->pins[0].pin_nid;
1423
1424 snd_hda_codec_write(codec, pin, 0,
1425 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
1426 /* some codecs require to unmute the pin */
1427 if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
1428 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1429 AMP_OUT_UNMUTE);
1430 snd_hda_jack_detect_enable(codec, pin, pin);
1431 snd_hda_jack_report_sync(codec);
1394 return 0; 1432 return 0;
1395} 1433}
1396 1434
@@ -1418,7 +1456,15 @@ static const hda_nid_t nvhdmi_con_nids_7x[4] = {
1418 0x6, 0x8, 0xa, 0xc, 1456 0x6, 0x8, 0xa, 0xc,
1419}; 1457};
1420 1458
1421static const struct hda_verb nvhdmi_basic_init_7x[] = { 1459static const struct hda_verb nvhdmi_basic_init_7x_2ch[] = {
1460 /* set audio protect on */
1461 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
1462 /* enable digital output on pin widget */
1463 { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
1464 {} /* terminator */
1465};
1466
1467static const struct hda_verb nvhdmi_basic_init_7x_8ch[] = {
1422 /* set audio protect on */ 1468 /* set audio protect on */
1423 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, 1469 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
1424 /* enable digital output on pin widget */ 1470 /* enable digital output on pin widget */
@@ -1446,9 +1492,15 @@ static const struct hda_verb nvhdmi_basic_init_7x[] = {
1446 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) 1492 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
1447#endif 1493#endif
1448 1494
1449static int nvhdmi_7x_init(struct hda_codec *codec) 1495static int nvhdmi_7x_init_2ch(struct hda_codec *codec)
1450{ 1496{
1451 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x); 1497 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_2ch);
1498 return 0;
1499}
1500
1501static int nvhdmi_7x_init_8ch(struct hda_codec *codec)
1502{
1503 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_8ch);
1452 return 0; 1504 return 0;
1453} 1505}
1454 1506
@@ -1524,6 +1576,50 @@ static int simple_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1524 stream_tag, format, substream); 1576 stream_tag, format, substream);
1525} 1577}
1526 1578
1579static const struct hda_pcm_stream simple_pcm_playback = {
1580 .substreams = 1,
1581 .channels_min = 2,
1582 .channels_max = 2,
1583 .ops = {
1584 .open = simple_playback_pcm_open,
1585 .close = simple_playback_pcm_close,
1586 .prepare = simple_playback_pcm_prepare
1587 },
1588};
1589
1590static const struct hda_codec_ops simple_hdmi_patch_ops = {
1591 .build_controls = simple_playback_build_controls,
1592 .build_pcms = simple_playback_build_pcms,
1593 .init = simple_playback_init,
1594 .free = simple_playback_free,
1595 .unsol_event = simple_hdmi_unsol_event,
1596};
1597
1598static int patch_simple_hdmi(struct hda_codec *codec,
1599 hda_nid_t cvt_nid, hda_nid_t pin_nid)
1600{
1601 struct hdmi_spec *spec;
1602
1603 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1604 if (!spec)
1605 return -ENOMEM;
1606
1607 codec->spec = spec;
1608
1609 spec->multiout.num_dacs = 0; /* no analog */
1610 spec->multiout.max_channels = 2;
1611 spec->multiout.dig_out_nid = cvt_nid;
1612 spec->num_cvts = 1;
1613 spec->num_pins = 1;
1614 spec->cvts[0].cvt_nid = cvt_nid;
1615 spec->pins[0].pin_nid = pin_nid;
1616 spec->pcm_playback = simple_pcm_playback;
1617
1618 codec->patch_ops = simple_hdmi_patch_ops;
1619
1620 return 0;
1621}
1622
1527static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec, 1623static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec,
1528 int channels) 1624 int channels)
1529{ 1625{
@@ -1696,54 +1792,20 @@ static const struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = {
1696 }, 1792 },
1697}; 1793};
1698 1794
1699static const struct hda_pcm_stream nvhdmi_pcm_playback_2ch = {
1700 .substreams = 1,
1701 .channels_min = 2,
1702 .channels_max = 2,
1703 .nid = nvhdmi_master_con_nid_7x,
1704 .rates = SUPPORTED_RATES,
1705 .maxbps = SUPPORTED_MAXBPS,
1706 .formats = SUPPORTED_FORMATS,
1707 .ops = {
1708 .open = simple_playback_pcm_open,
1709 .close = simple_playback_pcm_close,
1710 .prepare = simple_playback_pcm_prepare
1711 },
1712};
1713
1714static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
1715 .build_controls = simple_playback_build_controls,
1716 .build_pcms = simple_playback_build_pcms,
1717 .init = nvhdmi_7x_init,
1718 .free = simple_playback_free,
1719};
1720
1721static const struct hda_codec_ops nvhdmi_patch_ops_2ch = {
1722 .build_controls = simple_playback_build_controls,
1723 .build_pcms = simple_playback_build_pcms,
1724 .init = nvhdmi_7x_init,
1725 .free = simple_playback_free,
1726};
1727
1728static int patch_nvhdmi_2ch(struct hda_codec *codec) 1795static int patch_nvhdmi_2ch(struct hda_codec *codec)
1729{ 1796{
1730 struct hdmi_spec *spec; 1797 struct hdmi_spec *spec;
1798 int err = patch_simple_hdmi(codec, nvhdmi_master_con_nid_7x,
1799 nvhdmi_master_pin_nid_7x);
1800 if (err < 0)
1801 return err;
1731 1802
1732 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1803 codec->patch_ops.init = nvhdmi_7x_init_2ch;
1733 if (spec == NULL) 1804 /* override the PCM rates, etc, as the codec doesn't give full list */
1734 return -ENOMEM; 1805 spec = codec->spec;
1735 1806 spec->pcm_playback.rates = SUPPORTED_RATES;
1736 codec->spec = spec; 1807 spec->pcm_playback.maxbps = SUPPORTED_MAXBPS;
1737 1808 spec->pcm_playback.formats = SUPPORTED_FORMATS;
1738 spec->multiout.num_dacs = 0; /* no analog */
1739 spec->multiout.max_channels = 2;
1740 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
1741 spec->num_cvts = 1;
1742 spec->cvts[0].cvt_nid = nvhdmi_master_con_nid_7x;
1743 spec->pcm_playback = &nvhdmi_pcm_playback_2ch;
1744
1745 codec->patch_ops = nvhdmi_patch_ops_2ch;
1746
1747 return 0; 1809 return 0;
1748} 1810}
1749 1811
@@ -1751,13 +1813,12 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
1751{ 1813{
1752 struct hdmi_spec *spec; 1814 struct hdmi_spec *spec;
1753 int err = patch_nvhdmi_2ch(codec); 1815 int err = patch_nvhdmi_2ch(codec);
1754
1755 if (err < 0) 1816 if (err < 0)
1756 return err; 1817 return err;
1757 spec = codec->spec; 1818 spec = codec->spec;
1758 spec->multiout.max_channels = 8; 1819 spec->multiout.max_channels = 8;
1759 spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x; 1820 spec->pcm_playback = nvhdmi_pcm_playback_8ch_7x;
1760 codec->patch_ops = nvhdmi_patch_ops_8ch_7x; 1821 codec->patch_ops.init = nvhdmi_7x_init_8ch;
1761 1822
1762 /* Initialize the audio infoframe channel mask and checksum to something 1823 /* Initialize the audio infoframe channel mask and checksum to something
1763 * valid */ 1824 * valid */
@@ -1801,69 +1862,26 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1801 return 0; 1862 return 0;
1802} 1863}
1803 1864
1804static const struct hda_pcm_stream atihdmi_pcm_digital_playback = { 1865static int patch_atihdmi(struct hda_codec *codec)
1805 .substreams = 1,
1806 .channels_min = 2,
1807 .channels_max = 2,
1808 .nid = ATIHDMI_CVT_NID,
1809 .ops = {
1810 .open = simple_playback_pcm_open,
1811 .close = simple_playback_pcm_close,
1812 .prepare = atihdmi_playback_pcm_prepare
1813 },
1814};
1815
1816static const struct hda_verb atihdmi_basic_init[] = {
1817 /* enable digital output on pin widget */
1818 { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1819 {} /* terminator */
1820};
1821
1822static int atihdmi_init(struct hda_codec *codec)
1823{ 1866{
1824 struct hdmi_spec *spec = codec->spec; 1867 struct hdmi_spec *spec;
1825 1868 int err = patch_simple_hdmi(codec, ATIHDMI_CVT_NID, ATIHDMI_PIN_NID);
1826 snd_hda_sequence_write(codec, atihdmi_basic_init); 1869 if (err < 0)
1827 /* SI codec requires to unmute the pin */ 1870 return err;
1828 if (get_wcaps(codec, spec->pins[0].pin_nid) & AC_WCAP_OUT_AMP) 1871 spec = codec->spec;
1829 snd_hda_codec_write(codec, spec->pins[0].pin_nid, 0, 1872 spec->pcm_playback.ops.prepare = atihdmi_playback_pcm_prepare;
1830 AC_VERB_SET_AMP_GAIN_MUTE,
1831 AMP_OUT_UNMUTE);
1832 return 0; 1873 return 0;
1833} 1874}
1834 1875
1835static const struct hda_codec_ops atihdmi_patch_ops = { 1876/* VIA HDMI Implementation */
1836 .build_controls = simple_playback_build_controls, 1877#define VIAHDMI_CVT_NID 0x02 /* audio converter1 */
1837 .build_pcms = simple_playback_build_pcms, 1878#define VIAHDMI_PIN_NID 0x03 /* HDMI output pin1 */
1838 .init = atihdmi_init,
1839 .free = simple_playback_free,
1840};
1841
1842 1879
1843static int patch_atihdmi(struct hda_codec *codec) 1880static int patch_via_hdmi(struct hda_codec *codec)
1844{ 1881{
1845 struct hdmi_spec *spec; 1882 return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID);
1846
1847 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1848 if (spec == NULL)
1849 return -ENOMEM;
1850
1851 codec->spec = spec;
1852
1853 spec->multiout.num_dacs = 0; /* no analog */
1854 spec->multiout.max_channels = 2;
1855 spec->multiout.dig_out_nid = ATIHDMI_CVT_NID;
1856 spec->num_cvts = 1;
1857 spec->cvts[0].cvt_nid = ATIHDMI_CVT_NID;
1858 spec->pins[0].pin_nid = ATIHDMI_PIN_NID;
1859 spec->pcm_playback = &atihdmi_pcm_digital_playback;
1860
1861 codec->patch_ops = atihdmi_patch_ops;
1862
1863 return 0;
1864} 1883}
1865 1884
1866
1867/* 1885/*
1868 * patch entries 1886 * patch entries
1869 */ 1887 */
@@ -1902,8 +1920,13 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
1902{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi }, 1920{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi },
1903{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi }, 1921{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi },
1904{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi }, 1922{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi },
1923{ .id = 0x10de0051, .name = "GPU 51 HDMI/DP", .patch = patch_generic_hdmi },
1905{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, 1924{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
1906{ .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, 1925{ .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
1926{ .id = 0x11069f80, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi },
1927{ .id = 0x11069f81, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi },
1928{ .id = 0x11069f84, .name = "VX11 HDMI/DP", .patch = patch_generic_hdmi },
1929{ .id = 0x11069f85, .name = "VX11 HDMI/DP", .patch = patch_generic_hdmi },
1907{ .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, 1930{ .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi },
1908{ .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_generic_hdmi }, 1931{ .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_generic_hdmi },
1909{ .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_generic_hdmi }, 1932{ .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_generic_hdmi },
@@ -1911,6 +1934,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
1911{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, 1934{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi },
1912{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, 1935{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi },
1913{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi }, 1936{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi },
1937{ .id = 0x80862807, .name = "Haswell HDMI", .patch = patch_generic_hdmi },
1914{ .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi }, 1938{ .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi },
1915{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, 1939{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi },
1916{} /* terminator */ 1940{} /* terminator */
@@ -1948,8 +1972,13 @@ MODULE_ALIAS("snd-hda-codec-id:10de0041");
1948MODULE_ALIAS("snd-hda-codec-id:10de0042"); 1972MODULE_ALIAS("snd-hda-codec-id:10de0042");
1949MODULE_ALIAS("snd-hda-codec-id:10de0043"); 1973MODULE_ALIAS("snd-hda-codec-id:10de0043");
1950MODULE_ALIAS("snd-hda-codec-id:10de0044"); 1974MODULE_ALIAS("snd-hda-codec-id:10de0044");
1975MODULE_ALIAS("snd-hda-codec-id:10de0051");
1951MODULE_ALIAS("snd-hda-codec-id:10de0067"); 1976MODULE_ALIAS("snd-hda-codec-id:10de0067");
1952MODULE_ALIAS("snd-hda-codec-id:10de8001"); 1977MODULE_ALIAS("snd-hda-codec-id:10de8001");
1978MODULE_ALIAS("snd-hda-codec-id:11069f80");
1979MODULE_ALIAS("snd-hda-codec-id:11069f81");
1980MODULE_ALIAS("snd-hda-codec-id:11069f84");
1981MODULE_ALIAS("snd-hda-codec-id:11069f85");
1953MODULE_ALIAS("snd-hda-codec-id:17e80047"); 1982MODULE_ALIAS("snd-hda-codec-id:17e80047");
1954MODULE_ALIAS("snd-hda-codec-id:80860054"); 1983MODULE_ALIAS("snd-hda-codec-id:80860054");
1955MODULE_ALIAS("snd-hda-codec-id:80862801"); 1984MODULE_ALIAS("snd-hda-codec-id:80862801");
@@ -1958,6 +1987,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862803");
1958MODULE_ALIAS("snd-hda-codec-id:80862804"); 1987MODULE_ALIAS("snd-hda-codec-id:80862804");
1959MODULE_ALIAS("snd-hda-codec-id:80862805"); 1988MODULE_ALIAS("snd-hda-codec-id:80862805");
1960MODULE_ALIAS("snd-hda-codec-id:80862806"); 1989MODULE_ALIAS("snd-hda-codec-id:80862806");
1990MODULE_ALIAS("snd-hda-codec-id:80862807");
1961MODULE_ALIAS("snd-hda-codec-id:80862880"); 1991MODULE_ALIAS("snd-hda-codec-id:80862880");
1962MODULE_ALIAS("snd-hda-codec-id:808629fb"); 1992MODULE_ALIAS("snd-hda-codec-id:808629fb");
1963 1993
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index aa4c25e0f327..4f81dd44c837 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -170,10 +170,10 @@ struct alc_spec {
170 hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS]; 170 hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS];
171 unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS]; 171 unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS];
172 int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */ 172 int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */
173 hda_nid_t inv_dmic_pin;
173 174
174 /* hooks */ 175 /* hooks */
175 void (*init_hook)(struct hda_codec *codec); 176 void (*init_hook)(struct hda_codec *codec);
176 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
177#ifdef CONFIG_SND_HDA_POWER_SAVE 177#ifdef CONFIG_SND_HDA_POWER_SAVE
178 void (*power_hook)(struct hda_codec *codec); 178 void (*power_hook)(struct hda_codec *codec);
179#endif 179#endif
@@ -201,6 +201,9 @@ struct alc_spec {
201 unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ 201 unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */
202 unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ 202 unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */
203 unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ 203 unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */
204 unsigned int inv_dmic_fixup:1; /* has inverted digital-mic workaround */
205 unsigned int inv_dmic_muted:1; /* R-ch of inv d-mic is muted? */
206 unsigned int no_primary_hp:1; /* Don't prefer HP pins to speaker pins */
204 207
205 /* auto-mute control */ 208 /* auto-mute control */
206 int automute_mode; 209 int automute_mode;
@@ -298,6 +301,39 @@ static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx)
298} 301}
299 302
300static void call_update_outputs(struct hda_codec *codec); 303static void call_update_outputs(struct hda_codec *codec);
304static void alc_inv_dmic_sync(struct hda_codec *codec, bool force);
305
306/* for shared I/O, change the pin-control accordingly */
307static void update_shared_mic_hp(struct hda_codec *codec, bool set_as_mic)
308{
309 struct alc_spec *spec = codec->spec;
310 unsigned int val;
311 hda_nid_t pin = spec->autocfg.inputs[1].pin;
312 /* NOTE: this assumes that there are only two inputs, the
313 * first is the real internal mic and the second is HP/mic jack.
314 */
315
316 val = snd_hda_get_default_vref(codec, pin);
317
318 /* This pin does not have vref caps - let's enable vref on pin 0x18
319 instead, as suggested by Realtek */
320 if (val == AC_PINCTL_VREF_HIZ) {
321 const hda_nid_t vref_pin = 0x18;
322 /* Sanity check pin 0x18 */
323 if (get_wcaps_type(get_wcaps(codec, vref_pin)) == AC_WID_PIN &&
324 get_defcfg_connect(snd_hda_codec_get_pincfg(codec, vref_pin)) == AC_JACK_PORT_NONE) {
325 unsigned int vref_val = snd_hda_get_default_vref(codec, vref_pin);
326 if (vref_val != AC_PINCTL_VREF_HIZ)
327 snd_hda_set_pin_ctl(codec, vref_pin, PIN_IN | (set_as_mic ? vref_val : 0));
328 }
329 }
330
331 val = set_as_mic ? val | PIN_IN : PIN_HP;
332 snd_hda_set_pin_ctl(codec, pin, val);
333
334 spec->automute_speaker = !set_as_mic;
335 call_update_outputs(codec);
336}
301 337
302/* select the given imux item; either unmute exclusively or select the route */ 338/* select the given imux item; either unmute exclusively or select the route */
303static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, 339static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
@@ -325,21 +361,8 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
325 return 0; 361 return 0;
326 spec->cur_mux[adc_idx] = idx; 362 spec->cur_mux[adc_idx] = idx;
327 363
328 /* for shared I/O, change the pin-control accordingly */ 364 if (spec->shared_mic_hp)
329 if (spec->shared_mic_hp) { 365 update_shared_mic_hp(codec, spec->cur_mux[adc_idx]);
330 unsigned int val;
331 hda_nid_t pin = spec->autocfg.inputs[1].pin;
332 /* NOTE: this assumes that there are only two inputs, the
333 * first is the real internal mic and the second is HP jack.
334 */
335 if (spec->cur_mux[adc_idx])
336 val = snd_hda_get_default_vref(codec, pin) | PIN_IN;
337 else
338 val = PIN_HP;
339 snd_hda_set_pin_ctl(codec, pin, val);
340 spec->automute_speaker = !spec->cur_mux[adc_idx];
341 call_update_outputs(codec);
342 }
343 366
344 if (spec->dyn_adc_switch) { 367 if (spec->dyn_adc_switch) {
345 alc_dyn_adc_pcm_resetup(codec, idx); 368 alc_dyn_adc_pcm_resetup(codec, idx);
@@ -368,6 +391,7 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
368 AC_VERB_SET_CONNECT_SEL, 391 AC_VERB_SET_CONNECT_SEL,
369 imux->items[idx].index); 392 imux->items[idx].index);
370 } 393 }
394 alc_inv_dmic_sync(codec, true);
371 return 1; 395 return 1;
372} 396}
373 397
@@ -664,7 +688,7 @@ static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
664} 688}
665 689
666/* unsolicited event for HP jack sensing */ 690/* unsolicited event for HP jack sensing */
667static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 691static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
668{ 692{
669 int action; 693 int action;
670 694
@@ -1000,11 +1024,9 @@ static void alc_init_automute(struct hda_codec *codec)
1000 spec->automute_lo = spec->automute_lo_possible; 1024 spec->automute_lo = spec->automute_lo_possible;
1001 spec->automute_speaker = spec->automute_speaker_possible; 1025 spec->automute_speaker = spec->automute_speaker_possible;
1002 1026
1003 if (spec->automute_speaker_possible || spec->automute_lo_possible) { 1027 if (spec->automute_speaker_possible || spec->automute_lo_possible)
1004 /* create a control for automute mode */ 1028 /* create a control for automute mode */
1005 alc_add_automute_mode_enum(codec); 1029 alc_add_automute_mode_enum(codec);
1006 spec->unsol_event = alc_sku_unsol_event;
1007 }
1008} 1030}
1009 1031
1010/* return the position of NID in the list, or -1 if not found */ 1032/* return the position of NID in the list, or -1 if not found */
@@ -1167,7 +1189,6 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1167 1189
1168 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", 1190 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1169 ext, fixed, dock); 1191 ext, fixed, dock);
1170 spec->unsol_event = alc_sku_unsol_event;
1171} 1192}
1172 1193
1173/* check the availabilities of auto-mute and auto-mic switches */ 1194/* check the availabilities of auto-mute and auto-mic switches */
@@ -1556,14 +1577,14 @@ typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1556 1577
1557static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, 1578static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1558 struct snd_ctl_elem_value *ucontrol, 1579 struct snd_ctl_elem_value *ucontrol,
1559 getput_call_t func, bool check_adc_switch) 1580 getput_call_t func, bool is_put)
1560{ 1581{
1561 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1582 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1562 struct alc_spec *spec = codec->spec; 1583 struct alc_spec *spec = codec->spec;
1563 int i, err = 0; 1584 int i, err = 0;
1564 1585
1565 mutex_lock(&codec->control_mutex); 1586 mutex_lock(&codec->control_mutex);
1566 if (check_adc_switch && spec->dyn_adc_switch) { 1587 if (is_put && spec->dyn_adc_switch) {
1567 for (i = 0; i < spec->num_adc_nids; i++) { 1588 for (i = 0; i < spec->num_adc_nids; i++) {
1568 kcontrol->private_value = 1589 kcontrol->private_value =
1569 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 1590 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
@@ -1584,6 +1605,8 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1584 3, 0, HDA_INPUT); 1605 3, 0, HDA_INPUT);
1585 err = func(kcontrol, ucontrol); 1606 err = func(kcontrol, ucontrol);
1586 } 1607 }
1608 if (err >= 0 && is_put)
1609 alc_inv_dmic_sync(codec, false);
1587 error: 1610 error:
1588 mutex_unlock(&codec->control_mutex); 1611 mutex_unlock(&codec->control_mutex);
1589 return err; 1612 return err;
@@ -1676,6 +1699,116 @@ DEFINE_CAPMIX_NOSRC(2);
1676DEFINE_CAPMIX_NOSRC(3); 1699DEFINE_CAPMIX_NOSRC(3);
1677 1700
1678/* 1701/*
1702 * Inverted digital-mic handling
1703 *
1704 * First off, it's a bit tricky. The "Inverted Internal Mic Capture Switch"
1705 * gives the additional mute only to the right channel of the digital mic
1706 * capture stream. This is a workaround for avoiding the almost silence
1707 * by summing the stereo stream from some (known to be ForteMedia)
1708 * digital mic unit.
1709 *
1710 * The logic is to call alc_inv_dmic_sync() after each action (possibly)
1711 * modifying ADC amp. When the mute flag is set, it mutes the R-channel
1712 * without caching so that the cache can still keep the original value.
1713 * The cached value is then restored when the flag is set off or any other
1714 * than d-mic is used as the current input source.
1715 */
1716static void alc_inv_dmic_sync(struct hda_codec *codec, bool force)
1717{
1718 struct alc_spec *spec = codec->spec;
1719 int i;
1720
1721 if (!spec->inv_dmic_fixup)
1722 return;
1723 if (!spec->inv_dmic_muted && !force)
1724 return;
1725 for (i = 0; i < spec->num_adc_nids; i++) {
1726 int src = spec->dyn_adc_switch ? 0 : i;
1727 bool dmic_fixup = false;
1728 hda_nid_t nid;
1729 int parm, dir, v;
1730
1731 if (spec->inv_dmic_muted &&
1732 spec->imux_pins[spec->cur_mux[src]] == spec->inv_dmic_pin)
1733 dmic_fixup = true;
1734 if (!dmic_fixup && !force)
1735 continue;
1736 if (spec->vol_in_capsrc) {
1737 nid = spec->capsrc_nids[i];
1738 parm = AC_AMP_SET_RIGHT | AC_AMP_SET_OUTPUT;
1739 dir = HDA_OUTPUT;
1740 } else {
1741 nid = spec->adc_nids[i];
1742 parm = AC_AMP_SET_RIGHT | AC_AMP_SET_INPUT;
1743 dir = HDA_INPUT;
1744 }
1745 /* we care only right channel */
1746 v = snd_hda_codec_amp_read(codec, nid, 1, dir, 0);
1747 if (v & 0x80) /* if already muted, we don't need to touch */
1748 continue;
1749 if (dmic_fixup) /* add mute for d-mic */
1750 v |= 0x80;
1751 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1752 parm | v);
1753 }
1754}
1755
1756static int alc_inv_dmic_sw_get(struct snd_kcontrol *kcontrol,
1757 struct snd_ctl_elem_value *ucontrol)
1758{
1759 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1760 struct alc_spec *spec = codec->spec;
1761
1762 ucontrol->value.integer.value[0] = !spec->inv_dmic_muted;
1763 return 0;
1764}
1765
1766static int alc_inv_dmic_sw_put(struct snd_kcontrol *kcontrol,
1767 struct snd_ctl_elem_value *ucontrol)
1768{
1769 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1770 struct alc_spec *spec = codec->spec;
1771 unsigned int val = !ucontrol->value.integer.value[0];
1772
1773 if (val == spec->inv_dmic_muted)
1774 return 0;
1775 spec->inv_dmic_muted = val;
1776 alc_inv_dmic_sync(codec, true);
1777 return 0;
1778}
1779
1780static const struct snd_kcontrol_new alc_inv_dmic_sw = {
1781 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1782 .info = snd_ctl_boolean_mono_info,
1783 .get = alc_inv_dmic_sw_get,
1784 .put = alc_inv_dmic_sw_put,
1785};
1786
1787static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid)
1788{
1789 struct alc_spec *spec = codec->spec;
1790 struct snd_kcontrol_new *knew = alc_kcontrol_new(spec);
1791 if (!knew)
1792 return -ENOMEM;
1793 *knew = alc_inv_dmic_sw;
1794 knew->name = kstrdup("Inverted Internal Mic Capture Switch", GFP_KERNEL);
1795 if (!knew->name)
1796 return -ENOMEM;
1797 spec->inv_dmic_fixup = 1;
1798 spec->inv_dmic_muted = 0;
1799 spec->inv_dmic_pin = nid;
1800 return 0;
1801}
1802
1803/* typically the digital mic is put at node 0x12 */
1804static void alc_fixup_inv_dmic_0x12(struct hda_codec *codec,
1805 const struct alc_fixup *fix, int action)
1806{
1807 if (action == ALC_FIXUP_ACT_PROBE)
1808 alc_add_inv_dmic_mixer(codec, 0x12);
1809}
1810
1811/*
1679 * virtual master controls 1812 * virtual master controls
1680 */ 1813 */
1681 1814
@@ -1865,13 +1998,31 @@ static int __alc_build_controls(struct hda_codec *codec)
1865 return 0; 1998 return 0;
1866} 1999}
1867 2000
1868static int alc_build_controls(struct hda_codec *codec) 2001static int alc_build_jacks(struct hda_codec *codec)
1869{ 2002{
1870 struct alc_spec *spec = codec->spec; 2003 struct alc_spec *spec = codec->spec;
2004
2005 if (spec->shared_mic_hp) {
2006 int err;
2007 int nid = spec->autocfg.inputs[1].pin;
2008 err = snd_hda_jack_add_kctl(codec, nid, "Headphone Mic", 0);
2009 if (err < 0)
2010 return err;
2011 err = snd_hda_jack_detect_enable(codec, nid, 0);
2012 if (err < 0)
2013 return err;
2014 }
2015
2016 return snd_hda_jack_add_kctls(codec, &spec->autocfg);
2017}
2018
2019static int alc_build_controls(struct hda_codec *codec)
2020{
1871 int err = __alc_build_controls(codec); 2021 int err = __alc_build_controls(codec);
1872 if (err < 0) 2022 if (err < 0)
1873 return err; 2023 return err;
1874 err = snd_hda_jack_add_kctls(codec, &spec->autocfg); 2024
2025 err = alc_build_jacks(codec);
1875 if (err < 0) 2026 if (err < 0)
1876 return err; 2027 return err;
1877 alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD); 2028 alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD);
@@ -1908,14 +2059,6 @@ static int alc_init(struct hda_codec *codec)
1908 return 0; 2059 return 0;
1909} 2060}
1910 2061
1911static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
1912{
1913 struct alc_spec *spec = codec->spec;
1914
1915 if (spec->unsol_event)
1916 spec->unsol_event(codec, res);
1917}
1918
1919#ifdef CONFIG_SND_HDA_POWER_SAVE 2062#ifdef CONFIG_SND_HDA_POWER_SAVE
1920static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) 2063static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1921{ 2064{
@@ -2300,7 +2443,7 @@ static void alc_power_eapd(struct hda_codec *codec)
2300 alc_auto_setup_eapd(codec, false); 2443 alc_auto_setup_eapd(codec, false);
2301} 2444}
2302 2445
2303static int alc_suspend(struct hda_codec *codec, pm_message_t state) 2446static int alc_suspend(struct hda_codec *codec)
2304{ 2447{
2305 struct alc_spec *spec = codec->spec; 2448 struct alc_spec *spec = codec->spec;
2306 alc_shutup(codec); 2449 alc_shutup(codec);
@@ -2317,6 +2460,7 @@ static int alc_resume(struct hda_codec *codec)
2317 codec->patch_ops.init(codec); 2460 codec->patch_ops.init(codec);
2318 snd_hda_codec_resume_amp(codec); 2461 snd_hda_codec_resume_amp(codec);
2319 snd_hda_codec_resume_cache(codec); 2462 snd_hda_codec_resume_cache(codec);
2463 alc_inv_dmic_sync(codec, true);
2320 hda_call_check_power_status(codec, 0x01); 2464 hda_call_check_power_status(codec, 0x01);
2321 return 0; 2465 return 0;
2322} 2466}
@@ -4116,14 +4260,12 @@ static void set_capture_mixer(struct hda_codec *codec)
4116 */ 4260 */
4117static void alc_auto_init_std(struct hda_codec *codec) 4261static void alc_auto_init_std(struct hda_codec *codec)
4118{ 4262{
4119 struct alc_spec *spec = codec->spec;
4120 alc_auto_init_multi_out(codec); 4263 alc_auto_init_multi_out(codec);
4121 alc_auto_init_extra_out(codec); 4264 alc_auto_init_extra_out(codec);
4122 alc_auto_init_analog_input(codec); 4265 alc_auto_init_analog_input(codec);
4123 alc_auto_init_input_src(codec); 4266 alc_auto_init_input_src(codec);
4124 alc_auto_init_digital(codec); 4267 alc_auto_init_digital(codec);
4125 if (spec->unsol_event) 4268 alc_inithook(codec);
4126 alc_inithook(codec);
4127} 4269}
4128 4270
4129/* 4271/*
@@ -4182,7 +4324,8 @@ static int alc_parse_auto_config(struct hda_codec *codec,
4182 return 0; /* can't find valid BIOS pin config */ 4324 return 0; /* can't find valid BIOS pin config */
4183 } 4325 }
4184 4326
4185 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && 4327 if (!spec->no_primary_hp &&
4328 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
4186 cfg->line_outs <= cfg->hp_outs) { 4329 cfg->line_outs <= cfg->hp_outs) {
4187 /* use HP as primary out */ 4330 /* use HP as primary out */
4188 cfg->speaker_outs = cfg->line_outs; 4331 cfg->speaker_outs = cfg->line_outs;
@@ -4724,7 +4867,6 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
4724 spec->automute_speaker = 1; 4867 spec->automute_speaker = 1;
4725 spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ 4868 spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
4726 snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT); 4869 snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT);
4727 spec->unsol_event = alc_sku_unsol_event;
4728 snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs); 4870 snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs);
4729 } 4871 }
4730} 4872}
@@ -4909,6 +5051,8 @@ enum {
4909 ALC889_FIXUP_DAC_ROUTE, 5051 ALC889_FIXUP_DAC_ROUTE,
4910 ALC889_FIXUP_MBP_VREF, 5052 ALC889_FIXUP_MBP_VREF,
4911 ALC889_FIXUP_IMAC91_VREF, 5053 ALC889_FIXUP_IMAC91_VREF,
5054 ALC882_FIXUP_INV_DMIC,
5055 ALC882_FIXUP_NO_PRIMARY_HP,
4912}; 5056};
4913 5057
4914static void alc889_fixup_coef(struct hda_codec *codec, 5058static void alc889_fixup_coef(struct hda_codec *codec,
@@ -5030,6 +5174,17 @@ static void alc889_fixup_imac91_vref(struct hda_codec *codec,
5030 spec->keep_vref_in_automute = 1; 5174 spec->keep_vref_in_automute = 1;
5031} 5175}
5032 5176
5177/* Don't take HP output as primary
5178 * strangely, the speaker output doesn't work on VAIO Z through DAC 0x05
5179 */
5180static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
5181 const struct alc_fixup *fix, int action)
5182{
5183 struct alc_spec *spec = codec->spec;
5184 if (action == ALC_FIXUP_ACT_PRE_PROBE)
5185 spec->no_primary_hp = 1;
5186}
5187
5033static const struct alc_fixup alc882_fixups[] = { 5188static const struct alc_fixup alc882_fixups[] = {
5034 [ALC882_FIXUP_ABIT_AW9D_MAX] = { 5189 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
5035 .type = ALC_FIXUP_PINS, 5190 .type = ALC_FIXUP_PINS,
@@ -5212,6 +5367,14 @@ static const struct alc_fixup alc882_fixups[] = {
5212 .chained = true, 5367 .chained = true,
5213 .chain_id = ALC882_FIXUP_GPIO1, 5368 .chain_id = ALC882_FIXUP_GPIO1,
5214 }, 5369 },
5370 [ALC882_FIXUP_INV_DMIC] = {
5371 .type = ALC_FIXUP_FUNC,
5372 .v.func = alc_fixup_inv_dmic_0x12,
5373 },
5374 [ALC882_FIXUP_NO_PRIMARY_HP] = {
5375 .type = ALC_FIXUP_FUNC,
5376 .v.func = alc882_fixup_no_primary_hp,
5377 },
5215}; 5378};
5216 5379
5217static const struct snd_pci_quirk alc882_fixup_tbl[] = { 5380static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -5246,6 +5409,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
5246 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC), 5409 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
5247 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), 5410 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
5248 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), 5411 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
5412 SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
5249 5413
5250 /* All Apple entries are in codec SSIDs */ 5414 /* All Apple entries are in codec SSIDs */
5251 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), 5415 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
@@ -5286,6 +5450,8 @@ static const struct alc_model_fixup alc882_fixup_models[] = {
5286 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, 5450 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
5287 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, 5451 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
5288 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, 5452 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
5453 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
5454 {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
5289 {} 5455 {}
5290}; 5456};
5291 5457
@@ -5373,6 +5539,7 @@ enum {
5373 ALC262_FIXUP_LENOVO_3000, 5539 ALC262_FIXUP_LENOVO_3000,
5374 ALC262_FIXUP_BENQ, 5540 ALC262_FIXUP_BENQ,
5375 ALC262_FIXUP_BENQ_T31, 5541 ALC262_FIXUP_BENQ_T31,
5542 ALC262_FIXUP_INV_DMIC,
5376}; 5543};
5377 5544
5378static const struct alc_fixup alc262_fixups[] = { 5545static const struct alc_fixup alc262_fixups[] = {
@@ -5424,6 +5591,10 @@ static const struct alc_fixup alc262_fixups[] = {
5424 {} 5591 {}
5425 } 5592 }
5426 }, 5593 },
5594 [ALC262_FIXUP_INV_DMIC] = {
5595 .type = ALC_FIXUP_FUNC,
5596 .v.func = alc_fixup_inv_dmic_0x12,
5597 },
5427}; 5598};
5428 5599
5429static const struct snd_pci_quirk alc262_fixup_tbl[] = { 5600static const struct snd_pci_quirk alc262_fixup_tbl[] = {
@@ -5438,6 +5609,10 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
5438 {} 5609 {}
5439}; 5610};
5440 5611
5612static const struct alc_model_fixup alc262_fixup_models[] = {
5613 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
5614 {}
5615};
5441 5616
5442/* 5617/*
5443 */ 5618 */
@@ -5466,7 +5641,8 @@ static int patch_alc262(struct hda_codec *codec)
5466#endif 5641#endif
5467 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 5642 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
5468 5643
5469 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); 5644 alc_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
5645 alc262_fixups);
5470 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 5646 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
5471 5647
5472 alc_auto_parse_customize_define(codec); 5648 alc_auto_parse_customize_define(codec);
@@ -5522,6 +5698,22 @@ static const struct hda_verb alc268_beep_init_verbs[] = {
5522 { } 5698 { }
5523}; 5699};
5524 5700
5701enum {
5702 ALC268_FIXUP_INV_DMIC,
5703};
5704
5705static const struct alc_fixup alc268_fixups[] = {
5706 [ALC268_FIXUP_INV_DMIC] = {
5707 .type = ALC_FIXUP_FUNC,
5708 .v.func = alc_fixup_inv_dmic_0x12,
5709 },
5710};
5711
5712static const struct alc_model_fixup alc268_fixup_models[] = {
5713 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
5714 {}
5715};
5716
5525/* 5717/*
5526 * BIOS auto configuration 5718 * BIOS auto configuration
5527 */ 5719 */
@@ -5553,6 +5745,9 @@ static int patch_alc268(struct hda_codec *codec)
5553 5745
5554 spec = codec->spec; 5746 spec = codec->spec;
5555 5747
5748 alc_pick_fixup(codec, alc268_fixup_models, NULL, alc268_fixups);
5749 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
5750
5556 /* automatic parse from the BIOS config */ 5751 /* automatic parse from the BIOS config */
5557 err = alc268_parse_auto_config(codec); 5752 err = alc268_parse_auto_config(codec);
5558 if (err < 0) 5753 if (err < 0)
@@ -5582,6 +5777,8 @@ static int patch_alc268(struct hda_codec *codec)
5582 codec->patch_ops = alc_patch_ops; 5777 codec->patch_ops = alc_patch_ops;
5583 spec->shutup = alc_eapd_shutup; 5778 spec->shutup = alc_eapd_shutup;
5584 5779
5780 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5781
5585 return 0; 5782 return 0;
5586 5783
5587 error: 5784 error:
@@ -5704,6 +5901,15 @@ static int alc269_resume(struct hda_codec *codec)
5704} 5901}
5705#endif /* CONFIG_PM */ 5902#endif /* CONFIG_PM */
5706 5903
5904static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
5905 const struct alc_fixup *fix, int action)
5906{
5907 struct alc_spec *spec = codec->spec;
5908
5909 if (action == ALC_FIXUP_ACT_PRE_PROBE)
5910 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5911}
5912
5707static void alc269_fixup_hweq(struct hda_codec *codec, 5913static void alc269_fixup_hweq(struct hda_codec *codec,
5708 const struct alc_fixup *fix, int action) 5914 const struct alc_fixup *fix, int action)
5709{ 5915{
@@ -5810,6 +6016,7 @@ static void alc269_fixup_mic2_mute(struct hda_codec *codec,
5810 } 6016 }
5811} 6017}
5812 6018
6019
5813enum { 6020enum {
5814 ALC269_FIXUP_SONY_VAIO, 6021 ALC269_FIXUP_SONY_VAIO,
5815 ALC275_FIXUP_SONY_VAIO_GPIO2, 6022 ALC275_FIXUP_SONY_VAIO_GPIO2,
@@ -5828,6 +6035,9 @@ enum {
5828 ALC269VB_FIXUP_AMIC, 6035 ALC269VB_FIXUP_AMIC,
5829 ALC269VB_FIXUP_DMIC, 6036 ALC269VB_FIXUP_DMIC,
5830 ALC269_FIXUP_MIC2_MUTE_LED, 6037 ALC269_FIXUP_MIC2_MUTE_LED,
6038 ALC269_FIXUP_INV_DMIC,
6039 ALC269_FIXUP_LENOVO_DOCK,
6040 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
5831}; 6041};
5832 6042
5833static const struct alc_fixup alc269_fixups[] = { 6043static const struct alc_fixup alc269_fixups[] = {
@@ -5889,6 +6099,8 @@ static const struct alc_fixup alc269_fixups[] = {
5889 [ALC269_FIXUP_PCM_44K] = { 6099 [ALC269_FIXUP_PCM_44K] = {
5890 .type = ALC_FIXUP_FUNC, 6100 .type = ALC_FIXUP_FUNC,
5891 .v.func = alc269_fixup_pcm_44k, 6101 .v.func = alc269_fixup_pcm_44k,
6102 .chained = true,
6103 .chain_id = ALC269_FIXUP_QUANTA_MUTE
5892 }, 6104 },
5893 [ALC269_FIXUP_STEREO_DMIC] = { 6105 [ALC269_FIXUP_STEREO_DMIC] = {
5894 .type = ALC_FIXUP_FUNC, 6106 .type = ALC_FIXUP_FUNC,
@@ -5952,12 +6164,33 @@ static const struct alc_fixup alc269_fixups[] = {
5952 .type = ALC_FIXUP_FUNC, 6164 .type = ALC_FIXUP_FUNC,
5953 .v.func = alc269_fixup_mic2_mute, 6165 .v.func = alc269_fixup_mic2_mute,
5954 }, 6166 },
6167 [ALC269_FIXUP_INV_DMIC] = {
6168 .type = ALC_FIXUP_FUNC,
6169 .v.func = alc_fixup_inv_dmic_0x12,
6170 },
6171 [ALC269_FIXUP_LENOVO_DOCK] = {
6172 .type = ALC_FIXUP_PINS,
6173 .v.pins = (const struct alc_pincfg[]) {
6174 { 0x19, 0x23a11040 }, /* dock mic */
6175 { 0x1b, 0x2121103f }, /* dock headphone */
6176 { }
6177 },
6178 .chained = true,
6179 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
6180 },
6181 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
6182 .type = ALC_FIXUP_FUNC,
6183 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
6184 },
5955}; 6185};
5956 6186
5957static const struct snd_pci_quirk alc269_fixup_tbl[] = { 6187static const struct snd_pci_quirk alc269_fixup_tbl[] = {
6188 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
6189 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
5958 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), 6190 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED),
5959 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), 6191 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC),
5960 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 6192 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
6193 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
5961 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), 6194 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
5962 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), 6195 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
5963 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), 6196 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
@@ -5975,8 +6208,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5975 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), 6208 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
5976 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), 6209 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
5977 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), 6210 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
5978 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_QUANTA_MUTE), 6211 SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
5979 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), 6212 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
6213 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
6214 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
6215 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
5980 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 6216 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
5981 6217
5982#if 0 6218#if 0
@@ -6033,6 +6269,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
6033static const struct alc_model_fixup alc269_fixup_models[] = { 6269static const struct alc_model_fixup alc269_fixup_models[] = {
6034 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, 6270 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
6035 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, 6271 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
6272 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
6273 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
6274 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
6275 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
6036 {} 6276 {}
6037}; 6277};
6038 6278
@@ -6329,12 +6569,6 @@ static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
6329 {} 6569 {}
6330}; 6570};
6331 6571
6332static const struct hda_verb alc660vd_eapd_verbs[] = {
6333 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
6334 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
6335 { }
6336};
6337
6338/* 6572/*
6339 */ 6573 */
6340static int patch_alc861vd(struct hda_codec *codec) 6574static int patch_alc861vd(struct hda_codec *codec)
@@ -6356,11 +6590,6 @@ static int patch_alc861vd(struct hda_codec *codec)
6356 if (err < 0) 6590 if (err < 0)
6357 goto error; 6591 goto error;
6358 6592
6359 if (codec->vendor_id == 0x10ec0660) {
6360 /* always turn on EAPD */
6361 snd_hda_gen_add_verbs(&spec->gen, alc660vd_eapd_verbs);
6362 }
6363
6364 if (!spec->no_analog) { 6593 if (!spec->no_analog) {
6365 err = snd_hda_attach_beep_device(codec, 0x23); 6594 err = snd_hda_attach_beep_device(codec, 0x23);
6366 if (err < 0) 6595 if (err < 0)
@@ -6443,6 +6672,7 @@ enum {
6443 ALC662_FIXUP_ASUS_MODE8, 6672 ALC662_FIXUP_ASUS_MODE8,
6444 ALC662_FIXUP_NO_JACK_DETECT, 6673 ALC662_FIXUP_NO_JACK_DETECT,
6445 ALC662_FIXUP_ZOTAC_Z68, 6674 ALC662_FIXUP_ZOTAC_Z68,
6675 ALC662_FIXUP_INV_DMIC,
6446}; 6676};
6447 6677
6448static const struct alc_fixup alc662_fixups[] = { 6678static const struct alc_fixup alc662_fixups[] = {
@@ -6599,12 +6829,17 @@ static const struct alc_fixup alc662_fixups[] = {
6599 { } 6829 { }
6600 } 6830 }
6601 }, 6831 },
6832 [ALC662_FIXUP_INV_DMIC] = {
6833 .type = ALC_FIXUP_FUNC,
6834 .v.func = alc_fixup_inv_dmic_0x12,
6835 },
6602}; 6836};
6603 6837
6604static const struct snd_pci_quirk alc662_fixup_tbl[] = { 6838static const struct snd_pci_quirk alc662_fixup_tbl[] = {
6605 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), 6839 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
6606 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), 6840 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
6607 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), 6841 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
6842 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
6608 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 6843 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
6609 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), 6844 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
6610 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), 6845 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
@@ -6685,6 +6920,7 @@ static const struct alc_model_fixup alc662_fixup_models[] = {
6685 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, 6920 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
6686 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, 6921 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
6687 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, 6922 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
6923 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
6688 {} 6924 {}
6689}; 6925};
6690 6926
@@ -6831,6 +7067,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
6831 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, 7067 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
6832 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, 7068 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
6833 { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, 7069 { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
7070 { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
6834 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 7071 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
6835 .patch = patch_alc861 }, 7072 .patch = patch_alc861 },
6836 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 7073 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 07675282015a..3d4722f0a1ca 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -101,6 +101,8 @@ enum {
101 STAC_92HD83XXX_HP_cNB11_INTQUAD, 101 STAC_92HD83XXX_HP_cNB11_INTQUAD,
102 STAC_HP_DV7_4000, 102 STAC_HP_DV7_4000,
103 STAC_HP_ZEPHYR, 103 STAC_HP_ZEPHYR,
104 STAC_92HD83XXX_HP_LED,
105 STAC_92HD83XXX_HP_INV_LED,
104 STAC_92HD83XXX_MODELS 106 STAC_92HD83XXX_MODELS
105}; 107};
106 108
@@ -1073,7 +1075,7 @@ static struct snd_kcontrol_new stac_smux_mixer = {
1073 1075
1074static const char * const slave_pfxs[] = { 1076static const char * const slave_pfxs[] = {
1075 "Front", "Surround", "Center", "LFE", "Side", 1077 "Front", "Surround", "Center", "LFE", "Side",
1076 "Headphone", "Speaker", "IEC958", 1078 "Headphone", "Speaker", "IEC958", "PCM",
1077 NULL 1079 NULL
1078}; 1080};
1079 1081
@@ -1675,6 +1677,8 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1675 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", 1677 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
1676 [STAC_HP_DV7_4000] = "hp-dv7-4000", 1678 [STAC_HP_DV7_4000] = "hp-dv7-4000",
1677 [STAC_HP_ZEPHYR] = "hp-zephyr", 1679 [STAC_HP_ZEPHYR] = "hp-zephyr",
1680 [STAC_92HD83XXX_HP_LED] = "hp-led",
1681 [STAC_92HD83XXX_HP_INV_LED] = "hp-inv-led",
1678}; 1682};
1679 1683
1680static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { 1684static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
@@ -1729,6 +1733,8 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1729 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 1733 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1730 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561, 1734 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
1731 "HP", STAC_HP_ZEPHYR), 1735 "HP", STAC_HP_ZEPHYR),
1736 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3660,
1737 "HP Mini", STAC_92HD83XXX_HP_LED),
1732 {} /* terminator */ 1738 {} /* terminator */
1733}; 1739};
1734 1740
@@ -4266,7 +4272,8 @@ static int stac92xx_init(struct hda_codec *codec)
4266 unsigned int gpio; 4272 unsigned int gpio;
4267 int i; 4273 int i;
4268 4274
4269 snd_hda_sequence_write(codec, spec->init); 4275 if (spec->init)
4276 snd_hda_sequence_write(codec, spec->init);
4270 4277
4271 /* power down adcs initially */ 4278 /* power down adcs initially */
4272 if (spec->powerdown_adcs) 4279 if (spec->powerdown_adcs)
@@ -4414,7 +4421,12 @@ static int stac92xx_init(struct hda_codec *codec)
4414 snd_hda_jack_report_sync(codec); 4421 snd_hda_jack_report_sync(codec);
4415 4422
4416 /* sync mute LED */ 4423 /* sync mute LED */
4417 snd_hda_sync_vmaster_hook(&spec->vmaster_mute); 4424 if (spec->gpio_led) {
4425 if (spec->vmaster_mute.hook)
4426 snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
4427 else /* the very first init call doesn't have vmaster yet */
4428 stac92xx_update_led_status(codec, false);
4429 }
4418 4430
4419 /* sync the power-map */ 4431 /* sync the power-map */
4420 if (spec->num_pwrs) 4432 if (spec->num_pwrs)
@@ -4531,6 +4543,9 @@ static void stac92xx_line_out_detect(struct hda_codec *codec,
4531 struct auto_pin_cfg *cfg = &spec->autocfg; 4543 struct auto_pin_cfg *cfg = &spec->autocfg;
4532 int i; 4544 int i;
4533 4545
4546 if (cfg->speaker_outs == 0)
4547 return;
4548
4534 for (i = 0; i < cfg->line_outs; i++) { 4549 for (i = 0; i < cfg->line_outs; i++) {
4535 if (presence) 4550 if (presence)
4536 break; 4551 break;
@@ -4997,7 +5012,7 @@ static int stac92xx_resume(struct hda_codec *codec)
4997 return 0; 5012 return 0;
4998} 5013}
4999 5014
5000static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) 5015static int stac92xx_suspend(struct hda_codec *codec)
5001{ 5016{
5002 stac92xx_shutup(codec); 5017 stac92xx_shutup(codec);
5003 return 0; 5018 return 0;
@@ -5507,6 +5522,7 @@ static void stac92hd8x_fill_auto_spec(struct hda_codec *codec)
5507static int patch_stac92hd83xxx(struct hda_codec *codec) 5522static int patch_stac92hd83xxx(struct hda_codec *codec)
5508{ 5523{
5509 struct sigmatel_spec *spec; 5524 struct sigmatel_spec *spec;
5525 int default_polarity = -1; /* no default cfg */
5510 int err; 5526 int err;
5511 5527
5512 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5528 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -5518,6 +5534,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5518 snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e); 5534 snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
5519 } 5535 }
5520 5536
5537 codec->epss = 0; /* longer delay needed for D3 */
5521 codec->no_trigger_sense = 1; 5538 codec->no_trigger_sense = 1;
5522 codec->spec = spec; 5539 codec->spec = spec;
5523 5540
@@ -5555,9 +5572,15 @@ again:
5555 case STAC_HP_ZEPHYR: 5572 case STAC_HP_ZEPHYR:
5556 spec->init = stac92hd83xxx_hp_zephyr_init; 5573 spec->init = stac92hd83xxx_hp_zephyr_init;
5557 break; 5574 break;
5575 case STAC_92HD83XXX_HP_LED:
5576 default_polarity = 0;
5577 break;
5578 case STAC_92HD83XXX_HP_INV_LED:
5579 default_polarity = 1;
5580 break;
5558 } 5581 }
5559 5582
5560 if (find_mute_led_cfg(codec, -1/*no default cfg*/)) 5583 if (find_mute_led_cfg(codec, default_polarity))
5561 snd_printd("mute LED gpio %d polarity %d\n", 5584 snd_printd("mute LED gpio %d polarity %d\n",
5562 spec->gpio_led, 5585 spec->gpio_led,
5563 spec->gpio_led_polarity); 5586 spec->gpio_led_polarity);
@@ -5730,7 +5753,6 @@ again:
5730 /* fallthru */ 5753 /* fallthru */
5731 case 0x111d76b4: /* 6 Port without Analog Mixer */ 5754 case 0x111d76b4: /* 6 Port without Analog Mixer */
5732 case 0x111d76b5: 5755 case 0x111d76b5:
5733 spec->init = stac92hd71bxx_core_init;
5734 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; 5756 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
5735 spec->num_dmics = stac92xx_connected_ports(codec, 5757 spec->num_dmics = stac92xx_connected_ports(codec,
5736 stac92hd71bxx_dmic_nids, 5758 stac92hd71bxx_dmic_nids,
@@ -5755,7 +5777,6 @@ again:
5755 spec->stream_delay = 40; /* 40 milliseconds */ 5777 spec->stream_delay = 40; /* 40 milliseconds */
5756 5778
5757 /* disable VSW */ 5779 /* disable VSW */
5758 spec->init = stac92hd71bxx_core_init;
5759 unmute_init++; 5780 unmute_init++;
5760 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); 5781 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
5761 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); 5782 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
@@ -5770,7 +5791,6 @@ again:
5770 5791
5771 /* fallthru */ 5792 /* fallthru */
5772 default: 5793 default:
5773 spec->init = stac92hd71bxx_core_init;
5774 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; 5794 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
5775 spec->num_dmics = stac92xx_connected_ports(codec, 5795 spec->num_dmics = stac92xx_connected_ports(codec,
5776 stac92hd71bxx_dmic_nids, 5796 stac92hd71bxx_dmic_nids,
@@ -5778,6 +5798,9 @@ again:
5778 break; 5798 break;
5779 } 5799 }
5780 5800
5801 if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB)
5802 spec->init = stac92hd71bxx_core_init;
5803
5781 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) 5804 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
5782 snd_hda_sequence_write_cache(codec, unmute_init); 5805 snd_hda_sequence_write_cache(codec, unmute_init);
5783 5806
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 82b368068e08..430771776915 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -1748,10 +1748,18 @@ static void via_unsol_event(struct hda_codec *codec,
1748} 1748}
1749 1749
1750#ifdef CONFIG_PM 1750#ifdef CONFIG_PM
1751static int via_suspend(struct hda_codec *codec, pm_message_t state) 1751static int via_suspend(struct hda_codec *codec)
1752{ 1752{
1753 struct via_spec *spec = codec->spec; 1753 struct via_spec *spec = codec->spec;
1754 vt1708_stop_hp_work(spec); 1754 vt1708_stop_hp_work(spec);
1755
1756 if (spec->codec_type == VT1802) {
1757 /* Fix pop noise on headphones */
1758 int i;
1759 for (i = 0; i < spec->autocfg.hp_outs; i++)
1760 snd_hda_set_pin_ctl(codec, spec->autocfg.hp_pins[i], 0);
1761 }
1762
1755 return 0; 1763 return 0;
1756} 1764}
1757#endif 1765#endif
@@ -3226,7 +3234,7 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
3226{ 3234{
3227 struct via_spec *spec = codec->spec; 3235 struct via_spec *spec = codec->spec;
3228 int imux_is_smixer; 3236 int imux_is_smixer;
3229 unsigned int parm; 3237 unsigned int parm, parm2;
3230 /* MUX6 (1eh) = stereo mixer */ 3238 /* MUX6 (1eh) = stereo mixer */
3231 imux_is_smixer = 3239 imux_is_smixer =
3232 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; 3240 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
@@ -3249,7 +3257,7 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
3249 parm = AC_PWRST_D3; 3257 parm = AC_PWRST_D3;
3250 set_pin_power_state(codec, 0x27, &parm); 3258 set_pin_power_state(codec, 0x27, &parm);
3251 update_power_state(codec, 0x1a, parm); 3259 update_power_state(codec, 0x1a, parm);
3252 update_power_state(codec, 0xb, parm); 3260 parm2 = parm; /* for pin 0x0b */
3253 3261
3254 /* PW2 (26h), AOW2 (ah) */ 3262 /* PW2 (26h), AOW2 (ah) */
3255 parm = AC_PWRST_D3; 3263 parm = AC_PWRST_D3;
@@ -3264,6 +3272,9 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
3264 if (!spec->hp_independent_mode) /* check for redirected HP */ 3272 if (!spec->hp_independent_mode) /* check for redirected HP */
3265 set_pin_power_state(codec, 0x28, &parm); 3273 set_pin_power_state(codec, 0x28, &parm);
3266 update_power_state(codec, 0x8, parm); 3274 update_power_state(codec, 0x8, parm);
3275 if (!spec->hp_independent_mode && parm2 != AC_PWRST_D3)
3276 parm = parm2;
3277 update_power_state(codec, 0xb, parm);
3267 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ 3278 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
3268 update_power_state(codec, 0x21, imux_is_smixer ? AC_PWRST_D0 : parm); 3279 update_power_state(codec, 0x21, imux_is_smixer ? AC_PWRST_D0 : parm);
3269 3280
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index a01a00d1cf4d..bed9f34f4efe 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -2793,9 +2793,10 @@ static void __devexit snd_vt1724_remove(struct pci_dev *pci)
2793} 2793}
2794 2794
2795#ifdef CONFIG_PM 2795#ifdef CONFIG_PM
2796static int snd_vt1724_suspend(struct pci_dev *pci, pm_message_t state) 2796static int snd_vt1724_suspend(struct device *dev)
2797{ 2797{
2798 struct snd_card *card = pci_get_drvdata(pci); 2798 struct pci_dev *pci = to_pci_dev(dev);
2799 struct snd_card *card = dev_get_drvdata(dev);
2799 struct snd_ice1712 *ice = card->private_data; 2800 struct snd_ice1712 *ice = card->private_data;
2800 2801
2801 if (!ice->pm_suspend_enabled) 2802 if (!ice->pm_suspend_enabled)
@@ -2820,13 +2821,14 @@ static int snd_vt1724_suspend(struct pci_dev *pci, pm_message_t state)
2820 2821
2821 pci_disable_device(pci); 2822 pci_disable_device(pci);
2822 pci_save_state(pci); 2823 pci_save_state(pci);
2823 pci_set_power_state(pci, pci_choose_state(pci, state)); 2824 pci_set_power_state(pci, PCI_D3hot);
2824 return 0; 2825 return 0;
2825} 2826}
2826 2827
2827static int snd_vt1724_resume(struct pci_dev *pci) 2828static int snd_vt1724_resume(struct device *dev)
2828{ 2829{
2829 struct snd_card *card = pci_get_drvdata(pci); 2830 struct pci_dev *pci = to_pci_dev(dev);
2831 struct snd_card *card = dev_get_drvdata(dev);
2830 struct snd_ice1712 *ice = card->private_data; 2832 struct snd_ice1712 *ice = card->private_data;
2831 2833
2832 if (!ice->pm_suspend_enabled) 2834 if (!ice->pm_suspend_enabled)
@@ -2871,17 +2873,21 @@ static int snd_vt1724_resume(struct pci_dev *pci)
2871 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2873 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2872 return 0; 2874 return 0;
2873} 2875}
2874#endif 2876
2877static SIMPLE_DEV_PM_OPS(snd_vt1724_pm, snd_vt1724_suspend, snd_vt1724_resume);
2878#define SND_VT1724_PM_OPS &snd_vt1724_pm
2879#else
2880#define SND_VT1724_PM_OPS NULL
2881#endif /* CONFIG_PM */
2875 2882
2876static struct pci_driver vt1724_driver = { 2883static struct pci_driver vt1724_driver = {
2877 .name = KBUILD_MODNAME, 2884 .name = KBUILD_MODNAME,
2878 .id_table = snd_vt1724_ids, 2885 .id_table = snd_vt1724_ids,
2879 .probe = snd_vt1724_probe, 2886 .probe = snd_vt1724_probe,
2880 .remove = __devexit_p(snd_vt1724_remove), 2887 .remove = __devexit_p(snd_vt1724_remove),
2881#ifdef CONFIG_PM 2888 .driver = {
2882 .suspend = snd_vt1724_suspend, 2889 .pm = SND_VT1724_PM_OPS,
2883 .resume = snd_vt1724_resume, 2890 },
2884#endif
2885}; 2891};
2886 2892
2887module_pci_driver(vt1724_driver); 2893module_pci_driver(vt1724_driver);
diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c
index 764cc93dbca4..075d5aa1fee0 100644
--- a/sound/pci/ice1712/prodigy_hifi.c
+++ b/sound/pci/ice1712/prodigy_hifi.c
@@ -297,6 +297,7 @@ static int ak4396_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
297} 297}
298 298
299static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); 299static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
300static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
300 301
301static struct snd_kcontrol_new prodigy_hd2_controls[] __devinitdata = { 302static struct snd_kcontrol_new prodigy_hd2_controls[] __devinitdata = {
302 { 303 {
@@ -307,7 +308,7 @@ static struct snd_kcontrol_new prodigy_hd2_controls[] __devinitdata = {
307 .info = ak4396_dac_vol_info, 308 .info = ak4396_dac_vol_info,
308 .get = ak4396_dac_vol_get, 309 .get = ak4396_dac_vol_get,
309 .put = ak4396_dac_vol_put, 310 .put = ak4396_dac_vol_put,
310 .tlv = { .p = db_scale_wm_dac }, 311 .tlv = { .p = ak4396_db_scale },
311 }, 312 },
312}; 313};
313 314
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index f4e2dd4da8cf..cd553f592e2d 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -2624,9 +2624,10 @@ static int snd_intel8x0_free(struct intel8x0 *chip)
2624/* 2624/*
2625 * power management 2625 * power management
2626 */ 2626 */
2627static int intel8x0_suspend(struct pci_dev *pci, pm_message_t state) 2627static int intel8x0_suspend(struct device *dev)
2628{ 2628{
2629 struct snd_card *card = pci_get_drvdata(pci); 2629 struct pci_dev *pci = to_pci_dev(dev);
2630 struct snd_card *card = dev_get_drvdata(dev);
2630 struct intel8x0 *chip = card->private_data; 2631 struct intel8x0 *chip = card->private_data;
2631 int i; 2632 int i;
2632 2633
@@ -2658,13 +2659,14 @@ static int intel8x0_suspend(struct pci_dev *pci, pm_message_t state)
2658 /* The call below may disable built-in speaker on some laptops 2659 /* The call below may disable built-in speaker on some laptops
2659 * after S2RAM. So, don't touch it. 2660 * after S2RAM. So, don't touch it.
2660 */ 2661 */
2661 /* pci_set_power_state(pci, pci_choose_state(pci, state)); */ 2662 /* pci_set_power_state(pci, PCI_D3hot); */
2662 return 0; 2663 return 0;
2663} 2664}
2664 2665
2665static int intel8x0_resume(struct pci_dev *pci) 2666static int intel8x0_resume(struct device *dev)
2666{ 2667{
2667 struct snd_card *card = pci_get_drvdata(pci); 2668 struct pci_dev *pci = to_pci_dev(dev);
2669 struct snd_card *card = dev_get_drvdata(dev);
2668 struct intel8x0 *chip = card->private_data; 2670 struct intel8x0 *chip = card->private_data;
2669 int i; 2671 int i;
2670 2672
@@ -2734,6 +2736,11 @@ static int intel8x0_resume(struct pci_dev *pci)
2734 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2736 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2735 return 0; 2737 return 0;
2736} 2738}
2739
2740static SIMPLE_DEV_PM_OPS(intel8x0_pm, intel8x0_suspend, intel8x0_resume);
2741#define INTEL8X0_PM_OPS &intel8x0_pm
2742#else
2743#define INTEL8X0_PM_OPS NULL
2737#endif /* CONFIG_PM */ 2744#endif /* CONFIG_PM */
2738 2745
2739#define INTEL8X0_TESTBUF_SIZE 32768 /* enough large for one shot */ 2746#define INTEL8X0_TESTBUF_SIZE 32768 /* enough large for one shot */
@@ -3343,10 +3350,9 @@ static struct pci_driver intel8x0_driver = {
3343 .id_table = snd_intel8x0_ids, 3350 .id_table = snd_intel8x0_ids,
3344 .probe = snd_intel8x0_probe, 3351 .probe = snd_intel8x0_probe,
3345 .remove = __devexit_p(snd_intel8x0_remove), 3352 .remove = __devexit_p(snd_intel8x0_remove),
3346#ifdef CONFIG_PM 3353 .driver = {
3347 .suspend = intel8x0_suspend, 3354 .pm = INTEL8X0_PM_OPS,
3348 .resume = intel8x0_resume, 3355 },
3349#endif
3350}; 3356};
3351 3357
3352module_pci_driver(intel8x0_driver); 3358module_pci_driver(intel8x0_driver);
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index fc27a6a69e77..da44bb3f8e7a 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -1012,9 +1012,10 @@ static int snd_intel8x0m_free(struct intel8x0m *chip)
1012/* 1012/*
1013 * power management 1013 * power management
1014 */ 1014 */
1015static int intel8x0m_suspend(struct pci_dev *pci, pm_message_t state) 1015static int intel8x0m_suspend(struct device *dev)
1016{ 1016{
1017 struct snd_card *card = pci_get_drvdata(pci); 1017 struct pci_dev *pci = to_pci_dev(dev);
1018 struct snd_card *card = dev_get_drvdata(dev);
1018 struct intel8x0m *chip = card->private_data; 1019 struct intel8x0m *chip = card->private_data;
1019 int i; 1020 int i;
1020 1021
@@ -1028,13 +1029,14 @@ static int intel8x0m_suspend(struct pci_dev *pci, pm_message_t state)
1028 } 1029 }
1029 pci_disable_device(pci); 1030 pci_disable_device(pci);
1030 pci_save_state(pci); 1031 pci_save_state(pci);
1031 pci_set_power_state(pci, pci_choose_state(pci, state)); 1032 pci_set_power_state(pci, PCI_D3hot);
1032 return 0; 1033 return 0;
1033} 1034}
1034 1035
1035static int intel8x0m_resume(struct pci_dev *pci) 1036static int intel8x0m_resume(struct device *dev)
1036{ 1037{
1037 struct snd_card *card = pci_get_drvdata(pci); 1038 struct pci_dev *pci = to_pci_dev(dev);
1039 struct snd_card *card = dev_get_drvdata(dev);
1038 struct intel8x0m *chip = card->private_data; 1040 struct intel8x0m *chip = card->private_data;
1039 1041
1040 pci_set_power_state(pci, PCI_D0); 1042 pci_set_power_state(pci, PCI_D0);
@@ -1060,6 +1062,11 @@ static int intel8x0m_resume(struct pci_dev *pci)
1060 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1062 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1061 return 0; 1063 return 0;
1062} 1064}
1065
1066static SIMPLE_DEV_PM_OPS(intel8x0m_pm, intel8x0m_suspend, intel8x0m_resume);
1067#define INTEL8X0M_PM_OPS &intel8x0m_pm
1068#else
1069#define INTEL8X0M_PM_OPS NULL
1063#endif /* CONFIG_PM */ 1070#endif /* CONFIG_PM */
1064 1071
1065#ifdef CONFIG_PROC_FS 1072#ifdef CONFIG_PROC_FS
@@ -1329,10 +1336,9 @@ static struct pci_driver intel8x0m_driver = {
1329 .id_table = snd_intel8x0m_ids, 1336 .id_table = snd_intel8x0m_ids,
1330 .probe = snd_intel8x0m_probe, 1337 .probe = snd_intel8x0m_probe,
1331 .remove = __devexit_p(snd_intel8x0m_remove), 1338 .remove = __devexit_p(snd_intel8x0m_remove),
1332#ifdef CONFIG_PM 1339 .driver = {
1333 .suspend = intel8x0m_suspend, 1340 .pm = INTEL8X0M_PM_OPS,
1334 .resume = intel8x0m_resume, 1341 },
1335#endif
1336}; 1342};
1337 1343
1338module_pci_driver(intel8x0m_driver); 1344module_pci_driver(intel8x0m_driver);
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index d1ab43706735..5579b08bb35b 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -851,6 +851,8 @@ static int __devinit lx_pcm_create(struct lx6464es *chip)
851 /* hardcoded device name & channel count */ 851 /* hardcoded device name & channel count */
852 err = snd_pcm_new(chip->card, (char *)card_name, 0, 852 err = snd_pcm_new(chip->card, (char *)card_name, 0,
853 1, 1, &pcm); 853 1, 1, &pcm);
854 if (err < 0)
855 return err;
854 856
855 pcm->private_data = chip; 857 pcm->private_data = chip;
856 858
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index deef21399586..c85d1ffcc955 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -361,74 +361,6 @@ MODULE_PARM_DESC(amp_gpio, "GPIO pin number for external amp. (default = -1)");
361#define DSP2HOST_REQ_I2SRATE 0x02 361#define DSP2HOST_REQ_I2SRATE 0x02
362#define DSP2HOST_REQ_TIMER 0x04 362#define DSP2HOST_REQ_TIMER 0x04
363 363
364/* AC97 registers */
365/* XXX fix this crap up */
366/*#define AC97_RESET 0x00*/
367
368#define AC97_VOL_MUTE_B 0x8000
369#define AC97_VOL_M 0x1F
370#define AC97_LEFT_VOL_S 8
371
372#define AC97_MASTER_VOL 0x02
373#define AC97_LINE_LEVEL_VOL 0x04
374#define AC97_MASTER_MONO_VOL 0x06
375#define AC97_PC_BEEP_VOL 0x0A
376#define AC97_PC_BEEP_VOL_M 0x0F
377#define AC97_SROUND_MASTER_VOL 0x38
378#define AC97_PC_BEEP_VOL_S 1
379
380/*#define AC97_PHONE_VOL 0x0C
381#define AC97_MIC_VOL 0x0E*/
382#define AC97_MIC_20DB_ENABLE 0x40
383
384/*#define AC97_LINEIN_VOL 0x10
385#define AC97_CD_VOL 0x12
386#define AC97_VIDEO_VOL 0x14
387#define AC97_AUX_VOL 0x16*/
388#define AC97_PCM_OUT_VOL 0x18
389/*#define AC97_RECORD_SELECT 0x1A*/
390#define AC97_RECORD_MIC 0x00
391#define AC97_RECORD_CD 0x01
392#define AC97_RECORD_VIDEO 0x02
393#define AC97_RECORD_AUX 0x03
394#define AC97_RECORD_MONO_MUX 0x02
395#define AC97_RECORD_DIGITAL 0x03
396#define AC97_RECORD_LINE 0x04
397#define AC97_RECORD_STEREO 0x05
398#define AC97_RECORD_MONO 0x06
399#define AC97_RECORD_PHONE 0x07
400
401/*#define AC97_RECORD_GAIN 0x1C*/
402#define AC97_RECORD_VOL_M 0x0F
403
404/*#define AC97_GENERAL_PURPOSE 0x20*/
405#define AC97_POWER_DOWN_CTRL 0x26
406#define AC97_ADC_READY 0x0001
407#define AC97_DAC_READY 0x0002
408#define AC97_ANALOG_READY 0x0004
409#define AC97_VREF_ON 0x0008
410#define AC97_PR0 0x0100
411#define AC97_PR1 0x0200
412#define AC97_PR2 0x0400
413#define AC97_PR3 0x0800
414#define AC97_PR4 0x1000
415
416#define AC97_RESERVED1 0x28
417
418#define AC97_VENDOR_TEST 0x5A
419
420#define AC97_CLOCK_DELAY 0x5C
421#define AC97_LINEOUT_MUX_SEL 0x0001
422#define AC97_MONO_MUX_SEL 0x0002
423#define AC97_CLOCK_DELAY_SEL 0x1F
424#define AC97_DAC_CDS_SHIFT 6
425#define AC97_ADC_CDS_SHIFT 11
426
427#define AC97_MULTI_CHANNEL_SEL 0x74
428
429/*#define AC97_VENDOR_ID1 0x7C
430#define AC97_VENDOR_ID2 0x7E*/
431
432/* 364/*
433 * ASSP control regs 365 * ASSP control regs
434 */ 366 */
@@ -2459,9 +2391,10 @@ static int snd_m3_free(struct snd_m3 *chip)
2459 * APM support 2391 * APM support
2460 */ 2392 */
2461#ifdef CONFIG_PM 2393#ifdef CONFIG_PM
2462static int m3_suspend(struct pci_dev *pci, pm_message_t state) 2394static int m3_suspend(struct device *dev)
2463{ 2395{
2464 struct snd_card *card = pci_get_drvdata(pci); 2396 struct pci_dev *pci = to_pci_dev(dev);
2397 struct snd_card *card = dev_get_drvdata(dev);
2465 struct snd_m3 *chip = card->private_data; 2398 struct snd_m3 *chip = card->private_data;
2466 int i, dsp_index; 2399 int i, dsp_index;
2467 2400
@@ -2489,13 +2422,14 @@ static int m3_suspend(struct pci_dev *pci, pm_message_t state)
2489 2422
2490 pci_disable_device(pci); 2423 pci_disable_device(pci);
2491 pci_save_state(pci); 2424 pci_save_state(pci);
2492 pci_set_power_state(pci, pci_choose_state(pci, state)); 2425 pci_set_power_state(pci, PCI_D3hot);
2493 return 0; 2426 return 0;
2494} 2427}
2495 2428
2496static int m3_resume(struct pci_dev *pci) 2429static int m3_resume(struct device *dev)
2497{ 2430{
2498 struct snd_card *card = pci_get_drvdata(pci); 2431 struct pci_dev *pci = to_pci_dev(dev);
2432 struct snd_card *card = dev_get_drvdata(dev);
2499 struct snd_m3 *chip = card->private_data; 2433 struct snd_m3 *chip = card->private_data;
2500 int i, dsp_index; 2434 int i, dsp_index;
2501 2435
@@ -2546,6 +2480,11 @@ static int m3_resume(struct pci_dev *pci)
2546 chip->in_suspend = 0; 2480 chip->in_suspend = 0;
2547 return 0; 2481 return 0;
2548} 2482}
2483
2484static SIMPLE_DEV_PM_OPS(m3_pm, m3_suspend, m3_resume);
2485#define M3_PM_OPS &m3_pm
2486#else
2487#define M3_PM_OPS NULL
2549#endif /* CONFIG_PM */ 2488#endif /* CONFIG_PM */
2550 2489
2551#ifdef CONFIG_SND_MAESTRO3_INPUT 2490#ifdef CONFIG_SND_MAESTRO3_INPUT
@@ -2842,10 +2781,9 @@ static struct pci_driver m3_driver = {
2842 .id_table = snd_m3_ids, 2781 .id_table = snd_m3_ids,
2843 .probe = snd_m3_probe, 2782 .probe = snd_m3_probe,
2844 .remove = __devexit_p(snd_m3_remove), 2783 .remove = __devexit_p(snd_m3_remove),
2845#ifdef CONFIG_PM 2784 .driver = {
2846 .suspend = m3_suspend, 2785 .pm = M3_PM_OPS,
2847 .resume = m3_resume, 2786 },
2848#endif
2849}; 2787};
2850 2788
2851module_pci_driver(m3_driver); 2789module_pci_driver(m3_driver);
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 8159b05ee94d..465cff25b146 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -1382,9 +1382,10 @@ snd_nm256_peek_for_sig(struct nm256 *chip)
1382 * APM event handler, so the card is properly reinitialized after a power 1382 * APM event handler, so the card is properly reinitialized after a power
1383 * event. 1383 * event.
1384 */ 1384 */
1385static int nm256_suspend(struct pci_dev *pci, pm_message_t state) 1385static int nm256_suspend(struct device *dev)
1386{ 1386{
1387 struct snd_card *card = pci_get_drvdata(pci); 1387 struct pci_dev *pci = to_pci_dev(dev);
1388 struct snd_card *card = dev_get_drvdata(dev);
1388 struct nm256 *chip = card->private_data; 1389 struct nm256 *chip = card->private_data;
1389 1390
1390 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 1391 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -1393,13 +1394,14 @@ static int nm256_suspend(struct pci_dev *pci, pm_message_t state)
1393 chip->coeffs_current = 0; 1394 chip->coeffs_current = 0;
1394 pci_disable_device(pci); 1395 pci_disable_device(pci);
1395 pci_save_state(pci); 1396 pci_save_state(pci);
1396 pci_set_power_state(pci, pci_choose_state(pci, state)); 1397 pci_set_power_state(pci, PCI_D3hot);
1397 return 0; 1398 return 0;
1398} 1399}
1399 1400
1400static int nm256_resume(struct pci_dev *pci) 1401static int nm256_resume(struct device *dev)
1401{ 1402{
1402 struct snd_card *card = pci_get_drvdata(pci); 1403 struct pci_dev *pci = to_pci_dev(dev);
1404 struct snd_card *card = dev_get_drvdata(dev);
1403 struct nm256 *chip = card->private_data; 1405 struct nm256 *chip = card->private_data;
1404 int i; 1406 int i;
1405 1407
@@ -1434,6 +1436,11 @@ static int nm256_resume(struct pci_dev *pci)
1434 chip->in_resume = 0; 1436 chip->in_resume = 0;
1435 return 0; 1437 return 0;
1436} 1438}
1439
1440static SIMPLE_DEV_PM_OPS(nm256_pm, nm256_suspend, nm256_resume);
1441#define NM256_PM_OPS &nm256_pm
1442#else
1443#define NM256_PM_OPS NULL
1437#endif /* CONFIG_PM */ 1444#endif /* CONFIG_PM */
1438 1445
1439static int snd_nm256_free(struct nm256 *chip) 1446static int snd_nm256_free(struct nm256 *chip)
@@ -1747,10 +1754,9 @@ static struct pci_driver nm256_driver = {
1747 .id_table = snd_nm256_ids, 1754 .id_table = snd_nm256_ids,
1748 .probe = snd_nm256_probe, 1755 .probe = snd_nm256_probe,
1749 .remove = __devexit_p(snd_nm256_remove), 1756 .remove = __devexit_p(snd_nm256_remove),
1750#ifdef CONFIG_PM 1757 .driver = {
1751 .suspend = nm256_suspend, 1758 .pm = NM256_PM_OPS,
1752 .resume = nm256_resume, 1759 },
1753#endif
1754}; 1760};
1755 1761
1756module_pci_driver(nm256_driver); 1762module_pci_driver(nm256_driver);
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 610275bfbaeb..37520a2b4dcf 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -873,8 +873,9 @@ static struct pci_driver oxygen_driver = {
873 .probe = generic_oxygen_probe, 873 .probe = generic_oxygen_probe,
874 .remove = __devexit_p(oxygen_pci_remove), 874 .remove = __devexit_p(oxygen_pci_remove),
875#ifdef CONFIG_PM 875#ifdef CONFIG_PM
876 .suspend = oxygen_pci_suspend, 876 .driver = {
877 .resume = oxygen_pci_resume, 877 .pm = &oxygen_pci_pm,
878 },
878#endif 879#endif
879}; 880};
880 881
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index f53897a708b4..7112a89fb8bd 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -162,8 +162,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
162 ); 162 );
163void oxygen_pci_remove(struct pci_dev *pci); 163void oxygen_pci_remove(struct pci_dev *pci);
164#ifdef CONFIG_PM 164#ifdef CONFIG_PM
165int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state); 165extern const struct dev_pm_ops oxygen_pci_pm;
166int oxygen_pci_resume(struct pci_dev *pci);
167#endif 166#endif
168void oxygen_pci_shutdown(struct pci_dev *pci); 167void oxygen_pci_shutdown(struct pci_dev *pci);
169 168
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 92e2d67f16a1..e9fa2d07951d 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -573,8 +573,8 @@ static void oxygen_card_free(struct snd_card *card)
573 oxygen_shutdown(chip); 573 oxygen_shutdown(chip);
574 if (chip->irq >= 0) 574 if (chip->irq >= 0)
575 free_irq(chip->irq, chip); 575 free_irq(chip->irq, chip);
576 flush_work_sync(&chip->spdif_input_bits_work); 576 flush_work(&chip->spdif_input_bits_work);
577 flush_work_sync(&chip->gpio_work); 577 flush_work(&chip->gpio_work);
578 chip->model.cleanup(chip); 578 chip->model.cleanup(chip);
579 kfree(chip->model_data); 579 kfree(chip->model_data);
580 mutex_destroy(&chip->mutex); 580 mutex_destroy(&chip->mutex);
@@ -727,9 +727,10 @@ void oxygen_pci_remove(struct pci_dev *pci)
727EXPORT_SYMBOL(oxygen_pci_remove); 727EXPORT_SYMBOL(oxygen_pci_remove);
728 728
729#ifdef CONFIG_PM 729#ifdef CONFIG_PM
730int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state) 730static int oxygen_pci_suspend(struct device *dev)
731{ 731{
732 struct snd_card *card = pci_get_drvdata(pci); 732 struct pci_dev *pci = to_pci_dev(dev);
733 struct snd_card *card = dev_get_drvdata(dev);
733 struct oxygen *chip = card->private_data; 734 struct oxygen *chip = card->private_data;
734 unsigned int i, saved_interrupt_mask; 735 unsigned int i, saved_interrupt_mask;
735 736
@@ -750,16 +751,15 @@ int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state)
750 spin_unlock_irq(&chip->reg_lock); 751 spin_unlock_irq(&chip->reg_lock);
751 752
752 synchronize_irq(chip->irq); 753 synchronize_irq(chip->irq);
753 flush_work_sync(&chip->spdif_input_bits_work); 754 flush_work(&chip->spdif_input_bits_work);
754 flush_work_sync(&chip->gpio_work); 755 flush_work(&chip->gpio_work);
755 chip->interrupt_mask = saved_interrupt_mask; 756 chip->interrupt_mask = saved_interrupt_mask;
756 757
757 pci_disable_device(pci); 758 pci_disable_device(pci);
758 pci_save_state(pci); 759 pci_save_state(pci);
759 pci_set_power_state(pci, pci_choose_state(pci, state)); 760 pci_set_power_state(pci, PCI_D3hot);
760 return 0; 761 return 0;
761} 762}
762EXPORT_SYMBOL(oxygen_pci_suspend);
763 763
764static const u32 registers_to_restore[OXYGEN_IO_SIZE / 32] = { 764static const u32 registers_to_restore[OXYGEN_IO_SIZE / 32] = {
765 0xffffffff, 0x00ff077f, 0x00011d08, 0x007f00ff, 765 0xffffffff, 0x00ff077f, 0x00011d08, 0x007f00ff,
@@ -787,9 +787,10 @@ static void oxygen_restore_ac97(struct oxygen *chip, unsigned int codec)
787 chip->saved_ac97_registers[codec][i]); 787 chip->saved_ac97_registers[codec][i]);
788} 788}
789 789
790int oxygen_pci_resume(struct pci_dev *pci) 790static int oxygen_pci_resume(struct device *dev)
791{ 791{
792 struct snd_card *card = pci_get_drvdata(pci); 792 struct pci_dev *pci = to_pci_dev(dev);
793 struct snd_card *card = dev_get_drvdata(dev);
793 struct oxygen *chip = card->private_data; 794 struct oxygen *chip = card->private_data;
794 unsigned int i; 795 unsigned int i;
795 796
@@ -820,7 +821,9 @@ int oxygen_pci_resume(struct pci_dev *pci)
820 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 821 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
821 return 0; 822 return 0;
822} 823}
823EXPORT_SYMBOL(oxygen_pci_resume); 824
825SIMPLE_DEV_PM_OPS(oxygen_pci_pm, oxygen_pci_suspend, oxygen_pci_resume);
826EXPORT_SYMBOL(oxygen_pci_pm);
824#endif /* CONFIG_PM */ 827#endif /* CONFIG_PM */
825 828
826void oxygen_pci_shutdown(struct pci_dev *pci) 829void oxygen_pci_shutdown(struct pci_dev *pci)
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 19962c6d38c3..d3b606b69f3b 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -94,8 +94,9 @@ static struct pci_driver xonar_driver = {
94 .probe = xonar_probe, 94 .probe = xonar_probe,
95 .remove = __devexit_p(oxygen_pci_remove), 95 .remove = __devexit_p(oxygen_pci_remove),
96#ifdef CONFIG_PM 96#ifdef CONFIG_PM
97 .suspend = oxygen_pci_suspend, 97 .driver = {
98 .resume = oxygen_pci_resume, 98 .pm = &oxygen_pci_pm,
99 },
99#endif 100#endif
100 .shutdown = oxygen_pci_shutdown, 101 .shutdown = oxygen_pci_shutdown,
101}; 102};
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 0435f45e9513..e3ac1f768ff6 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -1368,6 +1368,67 @@ static void pcxhr_proc_gpo_write(struct snd_info_entry *entry,
1368 } 1368 }
1369} 1369}
1370 1370
1371/* Access to the results of the CMD_GET_TIME_CODE RMH */
1372#define TIME_CODE_VALID_MASK 0x00800000
1373#define TIME_CODE_NEW_MASK 0x00400000
1374#define TIME_CODE_BACK_MASK 0x00200000
1375#define TIME_CODE_WAIT_MASK 0x00100000
1376
1377/* Values for the CMD_MANAGE_SIGNAL RMH */
1378#define MANAGE_SIGNAL_TIME_CODE 0x01
1379#define MANAGE_SIGNAL_MIDI 0x02
1380
1381/* linear time code read proc*/
1382static void pcxhr_proc_ltc(struct snd_info_entry *entry,
1383 struct snd_info_buffer *buffer)
1384{
1385 struct snd_pcxhr *chip = entry->private_data;
1386 struct pcxhr_mgr *mgr = chip->mgr;
1387 struct pcxhr_rmh rmh;
1388 unsigned int ltcHrs, ltcMin, ltcSec, ltcFrm;
1389 int err;
1390 /* commands available when embedded DSP is running */
1391 if (!(mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX))) {
1392 snd_iprintf(buffer, "no firmware loaded\n");
1393 return;
1394 }
1395 if (!mgr->capture_ltc) {
1396 pcxhr_init_rmh(&rmh, CMD_MANAGE_SIGNAL);
1397 rmh.cmd[0] |= MANAGE_SIGNAL_TIME_CODE;
1398 err = pcxhr_send_msg(mgr, &rmh);
1399 if (err) {
1400 snd_iprintf(buffer, "ltc not activated (%d)\n", err);
1401 return;
1402 }
1403 if (mgr->is_hr_stereo)
1404 hr222_manage_timecode(mgr, 1);
1405 else
1406 pcxhr_write_io_num_reg_cont(mgr, REG_CONT_VALSMPTE,
1407 REG_CONT_VALSMPTE, NULL);
1408 mgr->capture_ltc = 1;
1409 }
1410 pcxhr_init_rmh(&rmh, CMD_GET_TIME_CODE);
1411 err = pcxhr_send_msg(mgr, &rmh);
1412 if (err) {
1413 snd_iprintf(buffer, "ltc read error (err=%d)\n", err);
1414 return ;
1415 }
1416 ltcHrs = 10*((rmh.stat[0] >> 8) & 0x3) + (rmh.stat[0] & 0xf);
1417 ltcMin = 10*((rmh.stat[1] >> 16) & 0x7) + ((rmh.stat[1] >> 8) & 0xf);
1418 ltcSec = 10*(rmh.stat[1] & 0x7) + ((rmh.stat[2] >> 16) & 0xf);
1419 ltcFrm = 10*((rmh.stat[2] >> 8) & 0x3) + (rmh.stat[2] & 0xf);
1420
1421 snd_iprintf(buffer, "timecode: %02u:%02u:%02u-%02u\n",
1422 ltcHrs, ltcMin, ltcSec, ltcFrm);
1423 snd_iprintf(buffer, "raw: 0x%04x%06x%06x\n", rmh.stat[0] & 0x00ffff,
1424 rmh.stat[1] & 0xffffff, rmh.stat[2] & 0xffffff);
1425 /*snd_iprintf(buffer, "dsp ref time: 0x%06x%06x\n",
1426 rmh.stat[3] & 0xffffff, rmh.stat[4] & 0xffffff);*/
1427 if (!(rmh.stat[0] & TIME_CODE_VALID_MASK)) {
1428 snd_iprintf(buffer, "warning: linear timecode not valid\n");
1429 }
1430}
1431
1371static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip) 1432static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip)
1372{ 1433{
1373 struct snd_info_entry *entry; 1434 struct snd_info_entry *entry;
@@ -1383,6 +1444,8 @@ static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip)
1383 entry->c.text.write = pcxhr_proc_gpo_write; 1444 entry->c.text.write = pcxhr_proc_gpo_write;
1384 entry->mode |= S_IWUSR; 1445 entry->mode |= S_IWUSR;
1385 } 1446 }
1447 if (!snd_card_proc_new(chip->card, "ltc", &entry))
1448 snd_info_set_text_ops(entry, chip, pcxhr_proc_ltc);
1386} 1449}
1387/* end of proc interface */ 1450/* end of proc interface */
1388 1451
diff --git a/sound/pci/pcxhr/pcxhr.h b/sound/pci/pcxhr/pcxhr.h
index bda776c49884..a4c602c45173 100644
--- a/sound/pci/pcxhr/pcxhr.h
+++ b/sound/pci/pcxhr/pcxhr.h
@@ -103,6 +103,7 @@ struct pcxhr_mgr {
103 unsigned int board_has_mic:1; /* if 1 the board has microphone input */ 103 unsigned int board_has_mic:1; /* if 1 the board has microphone input */
104 unsigned int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */ 104 unsigned int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */
105 unsigned int mono_capture:1; /* if 1 the board does mono capture */ 105 unsigned int mono_capture:1; /* if 1 the board does mono capture */
106 unsigned int capture_ltc:1; /* if 1 the board captures LTC input */
106 107
107 struct snd_dma_buffer hostport; 108 struct snd_dma_buffer hostport;
108 109
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c
index 304411c1fe4b..b33db1e006e7 100644
--- a/sound/pci/pcxhr/pcxhr_core.c
+++ b/sound/pci/pcxhr/pcxhr_core.c
@@ -504,6 +504,8 @@ static struct pcxhr_cmd_info pcxhr_dsp_cmds[] = {
504[CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED }, 504[CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED },
505[CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED }, 505[CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED },
506[CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED }, 506[CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED },
507[CMD_GET_TIME_CODE] = { 0x060000, 5, RMH_SSIZE_FIXED },
508[CMD_MANAGE_SIGNAL] = { 0x0f0000, 0, RMH_SSIZE_FIXED },
507}; 509};
508 510
509#ifdef CONFIG_SND_DEBUG_VERBOSE 511#ifdef CONFIG_SND_DEBUG_VERBOSE
@@ -533,6 +535,8 @@ static char* cmd_names[] = {
533[CMD_FORMAT_STREAM_IN] = "CMD_FORMAT_STREAM_IN", 535[CMD_FORMAT_STREAM_IN] = "CMD_FORMAT_STREAM_IN",
534[CMD_STREAM_SAMPLE_COUNT] = "CMD_STREAM_SAMPLE_COUNT", 536[CMD_STREAM_SAMPLE_COUNT] = "CMD_STREAM_SAMPLE_COUNT",
535[CMD_AUDIO_LEVEL_ADJUST] = "CMD_AUDIO_LEVEL_ADJUST", 537[CMD_AUDIO_LEVEL_ADJUST] = "CMD_AUDIO_LEVEL_ADJUST",
538[CMD_GET_TIME_CODE] = "CMD_GET_TIME_CODE",
539[CMD_MANAGE_SIGNAL] = "CMD_MANAGE_SIGNAL",
536}; 540};
537#endif 541#endif
538 542
@@ -1133,13 +1137,12 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr,
1133 hw_sample_count = ((u_int64_t)rmh.stat[0]) << 24; 1137 hw_sample_count = ((u_int64_t)rmh.stat[0]) << 24;
1134 hw_sample_count += (u_int64_t)rmh.stat[1]; 1138 hw_sample_count += (u_int64_t)rmh.stat[1];
1135 1139
1136 snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n", 1140 snd_printdd("stream %c%d : abs samples real(%llu) timer(%llu)\n",
1137 stream->pipe->is_capture ? 'C' : 'P', 1141 stream->pipe->is_capture ? 'C' : 'P',
1138 stream->substream->number, 1142 stream->substream->number,
1139 (long unsigned int)hw_sample_count, 1143 hw_sample_count,
1140 (long unsigned int)(stream->timer_abs_periods + 1144 stream->timer_abs_periods + stream->timer_period_frag +
1141 stream->timer_period_frag + 1145 mgr->granularity);
1142 mgr->granularity));
1143 return hw_sample_count; 1146 return hw_sample_count;
1144} 1147}
1145 1148
@@ -1243,10 +1246,18 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1243 1246
1244 if ((dsp_time_diff < 0) && 1247 if ((dsp_time_diff < 0) &&
1245 (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) { 1248 (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) {
1246 snd_printdd("ERROR DSP TIME old(%d) new(%d) -> " 1249 /* handle dsp counter wraparound without resync */
1247 "resynchronize all streams\n", 1250 int tmp_diff = dsp_time_diff + PCXHR_DSP_TIME_MASK + 1;
1251 snd_printdd("WARNING DSP timestamp old(%d) new(%d)",
1248 mgr->dsp_time_last, dsp_time_new); 1252 mgr->dsp_time_last, dsp_time_new);
1249 mgr->dsp_time_err++; 1253 if (tmp_diff > 0 && tmp_diff <= (2*mgr->granularity)) {
1254 snd_printdd("-> timestamp wraparound OK: "
1255 "diff=%d\n", tmp_diff);
1256 dsp_time_diff = tmp_diff;
1257 } else {
1258 snd_printdd("-> resynchronize all streams\n");
1259 mgr->dsp_time_err++;
1260 }
1250 } 1261 }
1251#ifdef CONFIG_SND_DEBUG_VERBOSE 1262#ifdef CONFIG_SND_DEBUG_VERBOSE
1252 if (dsp_time_diff == 0) 1263 if (dsp_time_diff == 0)
diff --git a/sound/pci/pcxhr/pcxhr_core.h b/sound/pci/pcxhr/pcxhr_core.h
index be0173796cdb..a81ab6b811e7 100644
--- a/sound/pci/pcxhr/pcxhr_core.h
+++ b/sound/pci/pcxhr/pcxhr_core.h
@@ -79,6 +79,8 @@ enum {
79 CMD_FORMAT_STREAM_IN, /* cmd_len >= 4 stat_len = 0 */ 79 CMD_FORMAT_STREAM_IN, /* cmd_len >= 4 stat_len = 0 */
80 CMD_STREAM_SAMPLE_COUNT, /* cmd_len = 2 stat_len = (2 * nb_stream) */ 80 CMD_STREAM_SAMPLE_COUNT, /* cmd_len = 2 stat_len = (2 * nb_stream) */
81 CMD_AUDIO_LEVEL_ADJUST, /* cmd_len = 3 stat_len = 0 */ 81 CMD_AUDIO_LEVEL_ADJUST, /* cmd_len = 3 stat_len = 0 */
82 CMD_GET_TIME_CODE, /* cmd_len = 1 stat_len = 5 */
83 CMD_MANAGE_SIGNAL, /* cmd_len = 1 stat_len = 0 */
82 CMD_LAST_INDEX 84 CMD_LAST_INDEX
83}; 85};
84 86
@@ -116,7 +118,7 @@ int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh);
116#define IO_NUM_REG_OUT_ANA_LEVEL 20 118#define IO_NUM_REG_OUT_ANA_LEVEL 20
117#define IO_NUM_REG_IN_ANA_LEVEL 21 119#define IO_NUM_REG_IN_ANA_LEVEL 21
118 120
119 121#define REG_CONT_VALSMPTE 0x000800
120#define REG_CONT_UNMUTE_INPUTS 0x020000 122#define REG_CONT_UNMUTE_INPUTS 0x020000
121 123
122/* parameters used with register IO_NUM_REG_STATUS */ 124/* parameters used with register IO_NUM_REG_STATUS */
diff --git a/sound/pci/pcxhr/pcxhr_mix22.c b/sound/pci/pcxhr/pcxhr_mix22.c
index 1cb82c0a9cb3..84fe57626eba 100644
--- a/sound/pci/pcxhr/pcxhr_mix22.c
+++ b/sound/pci/pcxhr/pcxhr_mix22.c
@@ -53,6 +53,7 @@
53#define PCXHR_DSP_RESET_DSP 0x01 53#define PCXHR_DSP_RESET_DSP 0x01
54#define PCXHR_DSP_RESET_MUTE 0x02 54#define PCXHR_DSP_RESET_MUTE 0x02
55#define PCXHR_DSP_RESET_CODEC 0x08 55#define PCXHR_DSP_RESET_CODEC 0x08
56#define PCXHR_DSP_RESET_SMPTE 0x10
56#define PCXHR_DSP_RESET_GPO_OFFSET 5 57#define PCXHR_DSP_RESET_GPO_OFFSET 5
57#define PCXHR_DSP_RESET_GPO_MASK 0x60 58#define PCXHR_DSP_RESET_GPO_MASK 0x60
58 59
@@ -527,6 +528,16 @@ int hr222_write_gpo(struct pcxhr_mgr *mgr, int value)
527 return 0; 528 return 0;
528} 529}
529 530
531int hr222_manage_timecode(struct pcxhr_mgr *mgr, int enable)
532{
533 if (enable)
534 mgr->dsp_reset |= PCXHR_DSP_RESET_SMPTE;
535 else
536 mgr->dsp_reset &= ~PCXHR_DSP_RESET_SMPTE;
537
538 PCXHR_OUTPB(mgr, PCXHR_DSP_RESET, mgr->dsp_reset);
539 return 0;
540}
530 541
531int hr222_update_analog_audio_level(struct snd_pcxhr *chip, 542int hr222_update_analog_audio_level(struct snd_pcxhr *chip,
532 int is_capture, int channel) 543 int is_capture, int channel)
diff --git a/sound/pci/pcxhr/pcxhr_mix22.h b/sound/pci/pcxhr/pcxhr_mix22.h
index 5a37a0007e8f..5971b9933f41 100644
--- a/sound/pci/pcxhr/pcxhr_mix22.h
+++ b/sound/pci/pcxhr/pcxhr_mix22.h
@@ -34,6 +34,7 @@ int hr222_get_external_clock(struct pcxhr_mgr *mgr,
34 34
35int hr222_read_gpio(struct pcxhr_mgr *mgr, int is_gpi, int *value); 35int hr222_read_gpio(struct pcxhr_mgr *mgr, int is_gpi, int *value);
36int hr222_write_gpo(struct pcxhr_mgr *mgr, int value); 36int hr222_write_gpo(struct pcxhr_mgr *mgr, int value);
37int hr222_manage_timecode(struct pcxhr_mgr *mgr, int enable);
37 38
38#define HR222_LINE_PLAYBACK_LEVEL_MIN 0 /* -25.5 dB */ 39#define HR222_LINE_PLAYBACK_LEVEL_MIN 0 /* -25.5 dB */
39#define HR222_LINE_PLAYBACK_ZERO_LEVEL 51 /* 0.0 dB */ 40#define HR222_LINE_PLAYBACK_ZERO_LEVEL 51 /* 0.0 dB */
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index cbeb3f77350c..760ee467cd9a 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -1151,9 +1151,10 @@ static void riptide_handleirq(unsigned long dev_id)
1151} 1151}
1152 1152
1153#ifdef CONFIG_PM 1153#ifdef CONFIG_PM
1154static int riptide_suspend(struct pci_dev *pci, pm_message_t state) 1154static int riptide_suspend(struct device *dev)
1155{ 1155{
1156 struct snd_card *card = pci_get_drvdata(pci); 1156 struct pci_dev *pci = to_pci_dev(dev);
1157 struct snd_card *card = dev_get_drvdata(dev);
1157 struct snd_riptide *chip = card->private_data; 1158 struct snd_riptide *chip = card->private_data;
1158 1159
1159 chip->in_suspend = 1; 1160 chip->in_suspend = 1;
@@ -1162,13 +1163,14 @@ static int riptide_suspend(struct pci_dev *pci, pm_message_t state)
1162 snd_ac97_suspend(chip->ac97); 1163 snd_ac97_suspend(chip->ac97);
1163 pci_disable_device(pci); 1164 pci_disable_device(pci);
1164 pci_save_state(pci); 1165 pci_save_state(pci);
1165 pci_set_power_state(pci, pci_choose_state(pci, state)); 1166 pci_set_power_state(pci, PCI_D3hot);
1166 return 0; 1167 return 0;
1167} 1168}
1168 1169
1169static int riptide_resume(struct pci_dev *pci) 1170static int riptide_resume(struct device *dev)
1170{ 1171{
1171 struct snd_card *card = pci_get_drvdata(pci); 1172 struct pci_dev *pci = to_pci_dev(dev);
1173 struct snd_card *card = dev_get_drvdata(dev);
1172 struct snd_riptide *chip = card->private_data; 1174 struct snd_riptide *chip = card->private_data;
1173 1175
1174 pci_set_power_state(pci, PCI_D0); 1176 pci_set_power_state(pci, PCI_D0);
@@ -1186,7 +1188,12 @@ static int riptide_resume(struct pci_dev *pci)
1186 chip->in_suspend = 0; 1188 chip->in_suspend = 0;
1187 return 0; 1189 return 0;
1188} 1190}
1189#endif 1191
1192static SIMPLE_DEV_PM_OPS(riptide_pm, riptide_suspend, riptide_resume);
1193#define RIPTIDE_PM_OPS &riptide_pm
1194#else
1195#define RIPTIDE_PM_OPS NULL
1196#endif /* CONFIG_PM */
1190 1197
1191static int try_to_load_firmware(struct cmdif *cif, struct snd_riptide *chip) 1198static int try_to_load_firmware(struct cmdif *cif, struct snd_riptide *chip)
1192{ 1199{
@@ -2180,10 +2187,9 @@ static struct pci_driver driver = {
2180 .id_table = snd_riptide_ids, 2187 .id_table = snd_riptide_ids,
2181 .probe = snd_card_riptide_probe, 2188 .probe = snd_card_riptide_probe,
2182 .remove = __devexit_p(snd_card_riptide_remove), 2189 .remove = __devexit_p(snd_card_riptide_remove),
2183#ifdef CONFIG_PM 2190 .driver = {
2184 .suspend = riptide_suspend, 2191 .pm = RIPTIDE_PM_OPS,
2185 .resume = riptide_resume, 2192 },
2186#endif
2187}; 2193};
2188 2194
2189#ifdef SUPPORT_JOYSTICK 2195#ifdef SUPPORT_JOYSTICK
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index b8ac8710f47f..b12308b5ba2a 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -6585,7 +6585,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
6585 snd_printk(KERN_ERR "HDSPM: " 6585 snd_printk(KERN_ERR "HDSPM: "
6586 "unable to kmalloc Mixer memory of %d Bytes\n", 6586 "unable to kmalloc Mixer memory of %d Bytes\n",
6587 (int)sizeof(struct hdspm_mixer)); 6587 (int)sizeof(struct hdspm_mixer));
6588 return err; 6588 return -ENOMEM;
6589 } 6589 }
6590 6590
6591 hdspm->port_names_in = NULL; 6591 hdspm->port_names_in = NULL;
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 1552642765d6..805ab6e9a78f 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -1209,9 +1209,10 @@ static int sis_chip_init(struct sis7019 *sis)
1209} 1209}
1210 1210
1211#ifdef CONFIG_PM 1211#ifdef CONFIG_PM
1212static int sis_suspend(struct pci_dev *pci, pm_message_t state) 1212static int sis_suspend(struct device *dev)
1213{ 1213{
1214 struct snd_card *card = pci_get_drvdata(pci); 1214 struct pci_dev *pci = to_pci_dev(dev);
1215 struct snd_card *card = dev_get_drvdata(dev);
1215 struct sis7019 *sis = card->private_data; 1216 struct sis7019 *sis = card->private_data;
1216 void __iomem *ioaddr = sis->ioaddr; 1217 void __iomem *ioaddr = sis->ioaddr;
1217 int i; 1218 int i;
@@ -1241,13 +1242,14 @@ static int sis_suspend(struct pci_dev *pci, pm_message_t state)
1241 1242
1242 pci_disable_device(pci); 1243 pci_disable_device(pci);
1243 pci_save_state(pci); 1244 pci_save_state(pci);
1244 pci_set_power_state(pci, pci_choose_state(pci, state)); 1245 pci_set_power_state(pci, PCI_D3hot);
1245 return 0; 1246 return 0;
1246} 1247}
1247 1248
1248static int sis_resume(struct pci_dev *pci) 1249static int sis_resume(struct device *dev)
1249{ 1250{
1250 struct snd_card *card = pci_get_drvdata(pci); 1251 struct pci_dev *pci = to_pci_dev(dev);
1252 struct snd_card *card = dev_get_drvdata(dev);
1251 struct sis7019 *sis = card->private_data; 1253 struct sis7019 *sis = card->private_data;
1252 void __iomem *ioaddr = sis->ioaddr; 1254 void __iomem *ioaddr = sis->ioaddr;
1253 int i; 1255 int i;
@@ -1298,6 +1300,11 @@ error:
1298 snd_card_disconnect(card); 1300 snd_card_disconnect(card);
1299 return -EIO; 1301 return -EIO;
1300} 1302}
1303
1304static SIMPLE_DEV_PM_OPS(sis_pm, sis_suspend, sis_resume);
1305#define SIS_PM_OPS &sis_pm
1306#else
1307#define SIS_PM_OPS NULL
1301#endif /* CONFIG_PM */ 1308#endif /* CONFIG_PM */
1302 1309
1303static int sis_alloc_suspend(struct sis7019 *sis) 1310static int sis_alloc_suspend(struct sis7019 *sis)
@@ -1370,8 +1377,9 @@ static int __devinit sis_chip_create(struct snd_card *card,
1370 if (rc) 1377 if (rc)
1371 goto error_out_cleanup; 1378 goto error_out_cleanup;
1372 1379
1373 if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED, KBUILD_MODNAME, 1380 rc = request_irq(pci->irq, sis_interrupt, IRQF_SHARED, KBUILD_MODNAME,
1374 sis)) { 1381 sis);
1382 if (rc) {
1375 dev_err(&pci->dev, "unable to allocate irq %d\n", sis->irq); 1383 dev_err(&pci->dev, "unable to allocate irq %d\n", sis->irq);
1376 goto error_out_cleanup; 1384 goto error_out_cleanup;
1377 } 1385 }
@@ -1481,11 +1489,9 @@ static struct pci_driver sis7019_driver = {
1481 .id_table = snd_sis7019_ids, 1489 .id_table = snd_sis7019_ids,
1482 .probe = snd_sis7019_probe, 1490 .probe = snd_sis7019_probe,
1483 .remove = __devexit_p(snd_sis7019_remove), 1491 .remove = __devexit_p(snd_sis7019_remove),
1484 1492 .driver = {
1485#ifdef CONFIG_PM 1493 .pm = SIS_PM_OPS,
1486 .suspend = sis_suspend, 1494 },
1487 .resume = sis_resume,
1488#endif
1489}; 1495};
1490 1496
1491module_pci_driver(sis7019_driver); 1497module_pci_driver(sis7019_driver);
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index 611983ec7321..d36e6ca147e1 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -26,7 +26,7 @@
26#include <linux/time.h> 26#include <linux/time.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <sound/core.h> 28#include <sound/core.h>
29#include <sound/trident.h> 29#include "trident.h"
30#include <sound/initval.h> 30#include <sound/initval.h>
31 31
32MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, <audio@tridentmicro.com>"); 32MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, <audio@tridentmicro.com>");
@@ -178,8 +178,9 @@ static struct pci_driver trident_driver = {
178 .probe = snd_trident_probe, 178 .probe = snd_trident_probe,
179 .remove = __devexit_p(snd_trident_remove), 179 .remove = __devexit_p(snd_trident_remove),
180#ifdef CONFIG_PM 180#ifdef CONFIG_PM
181 .suspend = snd_trident_suspend, 181 .driver = {
182 .resume = snd_trident_resume, 182 .pm = &snd_trident_pm,
183 },
183#endif 184#endif
184}; 185};
185 186
diff --git a/sound/pci/trident/trident.h b/sound/pci/trident/trident.h
new file mode 100644
index 000000000000..5f110eb56e47
--- /dev/null
+++ b/sound/pci/trident/trident.h
@@ -0,0 +1,444 @@
1#ifndef __SOUND_TRIDENT_H
2#define __SOUND_TRIDENT_H
3
4/*
5 * audio@tridentmicro.com
6 * Fri Feb 19 15:55:28 MST 1999
7 * Definitions for Trident 4DWave DX/NX chips
8 *
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 as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26#include <sound/pcm.h>
27#include <sound/mpu401.h>
28#include <sound/ac97_codec.h>
29#include <sound/util_mem.h>
30
31#define TRIDENT_DEVICE_ID_DX ((PCI_VENDOR_ID_TRIDENT<<16)|PCI_DEVICE_ID_TRIDENT_4DWAVE_DX)
32#define TRIDENT_DEVICE_ID_NX ((PCI_VENDOR_ID_TRIDENT<<16)|PCI_DEVICE_ID_TRIDENT_4DWAVE_NX)
33#define TRIDENT_DEVICE_ID_SI7018 ((PCI_VENDOR_ID_SI<<16)|PCI_DEVICE_ID_SI_7018)
34
35#define SNDRV_TRIDENT_VOICE_TYPE_PCM 0
36#define SNDRV_TRIDENT_VOICE_TYPE_SYNTH 1
37#define SNDRV_TRIDENT_VOICE_TYPE_MIDI 2
38
39#define SNDRV_TRIDENT_VFLG_RUNNING (1<<0)
40
41/* TLB code constants */
42#define SNDRV_TRIDENT_PAGE_SIZE 4096
43#define SNDRV_TRIDENT_PAGE_SHIFT 12
44#define SNDRV_TRIDENT_PAGE_MASK ((1<<SNDRV_TRIDENT_PAGE_SHIFT)-1)
45#define SNDRV_TRIDENT_MAX_PAGES 4096
46
47/*
48 * Direct registers
49 */
50
51#define TRID_REG(trident, x) ((trident)->port + (x))
52
53#define ID_4DWAVE_DX 0x2000
54#define ID_4DWAVE_NX 0x2001
55
56/* Bank definitions */
57
58#define T4D_BANK_A 0
59#define T4D_BANK_B 1
60#define T4D_NUM_BANKS 2
61
62/* Register definitions */
63
64/* Global registers */
65
66enum global_control_bits {
67 CHANNEL_IDX = 0x0000003f,
68 OVERRUN_IE = 0x00000400, /* interrupt enable: capture overrun */
69 UNDERRUN_IE = 0x00000800, /* interrupt enable: playback underrun */
70 ENDLP_IE = 0x00001000, /* interrupt enable: end of buffer */
71 MIDLP_IE = 0x00002000, /* interrupt enable: middle buffer */
72 ETOG_IE = 0x00004000, /* interrupt enable: envelope toggling */
73 EDROP_IE = 0x00008000, /* interrupt enable: envelope drop */
74 BANK_B_EN = 0x00010000, /* SiS: enable bank B (64 channels) */
75 PCMIN_B_MIX = 0x00020000, /* SiS: PCM IN B mixing enable */
76 I2S_OUT_ASSIGN = 0x00040000, /* SiS: I2S Out contains surround PCM */
77 SPDIF_OUT_ASSIGN= 0x00080000, /* SiS: 0=S/PDIF L/R | 1=PCM Out FIFO */
78 MAIN_OUT_ASSIGN = 0x00100000, /* SiS: 0=PCM Out FIFO | 1=MMC Out buffer */
79};
80
81enum miscint_bits {
82 PB_UNDERRUN_IRQ = 0x00000001, REC_OVERRUN_IRQ = 0x00000002,
83 SB_IRQ = 0x00000004, MPU401_IRQ = 0x00000008,
84 OPL3_IRQ = 0x00000010, ADDRESS_IRQ = 0x00000020,
85 ENVELOPE_IRQ = 0x00000040, PB_UNDERRUN = 0x00000100,
86 REC_OVERRUN = 0x00000200, MIXER_UNDERFLOW = 0x00000400,
87 MIXER_OVERFLOW = 0x00000800, NX_SB_IRQ_DISABLE = 0x00001000,
88 ST_TARGET_REACHED = 0x00008000,
89 PB_24K_MODE = 0x00010000, ST_IRQ_EN = 0x00800000,
90 ACGPIO_IRQ = 0x01000000
91};
92
93/* T2 legacy dma control registers. */
94#define LEGACY_DMAR0 0x00 // ADR0
95#define LEGACY_DMAR4 0x04 // CNT0
96#define LEGACY_DMAR6 0x06 // CNT0 - High bits
97#define LEGACY_DMAR11 0x0b // MOD
98#define LEGACY_DMAR15 0x0f // MMR
99
100#define T4D_START_A 0x80
101#define T4D_STOP_A 0x84
102#define T4D_DLY_A 0x88
103#define T4D_SIGN_CSO_A 0x8c
104#define T4D_CSPF_A 0x90
105#define T4D_CSPF_B 0xbc
106#define T4D_CEBC_A 0x94
107#define T4D_AINT_A 0x98
108#define T4D_AINTEN_A 0x9c
109#define T4D_LFO_GC_CIR 0xa0
110#define T4D_MUSICVOL_WAVEVOL 0xa8
111#define T4D_SBDELTA_DELTA_R 0xac
112#define T4D_MISCINT 0xb0
113#define T4D_START_B 0xb4
114#define T4D_STOP_B 0xb8
115#define T4D_SBBL_SBCL 0xc0
116#define T4D_SBCTRL_SBE2R_SBDD 0xc4
117#define T4D_STIMER 0xc8
118#define T4D_AINT_B 0xd8
119#define T4D_AINTEN_B 0xdc
120#define T4D_RCI 0x70
121
122/* MPU-401 UART */
123#define T4D_MPU401_BASE 0x20
124#define T4D_MPUR0 0x20
125#define T4D_MPUR1 0x21
126#define T4D_MPUR2 0x22
127#define T4D_MPUR3 0x23
128
129/* S/PDIF Registers */
130#define NX_SPCTRL_SPCSO 0x24
131#define NX_SPLBA 0x28
132#define NX_SPESO 0x2c
133#define NX_SPCSTATUS 0x64
134
135/* Joystick */
136#define GAMEPORT_GCR 0x30
137#define GAMEPORT_MODE_ADC 0x80
138#define GAMEPORT_LEGACY 0x31
139#define GAMEPORT_AXES 0x34
140
141/* NX Specific Registers */
142#define NX_TLBC 0x6c
143
144/* Channel Registers */
145
146#define CH_START 0xe0
147
148#define CH_DX_CSO_ALPHA_FMS 0xe0
149#define CH_DX_ESO_DELTA 0xe8
150#define CH_DX_FMC_RVOL_CVOL 0xec
151
152#define CH_NX_DELTA_CSO 0xe0
153#define CH_NX_DELTA_ESO 0xe8
154#define CH_NX_ALPHA_FMS_FMC_RVOL_CVOL 0xec
155
156#define CH_LBA 0xe4
157#define CH_GVSEL_PAN_VOL_CTRL_EC 0xf0
158#define CH_EBUF1 0xf4
159#define CH_EBUF2 0xf8
160
161/* AC-97 Registers */
162
163#define DX_ACR0_AC97_W 0x40
164#define DX_ACR1_AC97_R 0x44
165#define DX_ACR2_AC97_COM_STAT 0x48
166
167#define NX_ACR0_AC97_COM_STAT 0x40
168#define NX_ACR1_AC97_W 0x44
169#define NX_ACR2_AC97_R_PRIMARY 0x48
170#define NX_ACR3_AC97_R_SECONDARY 0x4c
171
172#define SI_AC97_WRITE 0x40
173#define SI_AC97_READ 0x44
174#define SI_SERIAL_INTF_CTRL 0x48
175#define SI_AC97_GPIO 0x4c
176#define SI_ASR0 0x50
177#define SI_SPDIF_CS 0x70
178#define SI_GPIO 0x7c
179
180enum trident_nx_ac97_bits {
181 /* ACR1-3 */
182 NX_AC97_BUSY_WRITE = 0x0800,
183 NX_AC97_BUSY_READ = 0x0800,
184 NX_AC97_BUSY_DATA = 0x0400,
185 NX_AC97_WRITE_SECONDARY = 0x0100,
186 /* ACR0 */
187 NX_AC97_SECONDARY_READY = 0x0040,
188 NX_AC97_SECONDARY_RECORD = 0x0020,
189 NX_AC97_SURROUND_OUTPUT = 0x0010,
190 NX_AC97_PRIMARY_READY = 0x0008,
191 NX_AC97_PRIMARY_RECORD = 0x0004,
192 NX_AC97_PCM_OUTPUT = 0x0002,
193 NX_AC97_WARM_RESET = 0x0001
194};
195
196enum trident_dx_ac97_bits {
197 DX_AC97_BUSY_WRITE = 0x8000,
198 DX_AC97_BUSY_READ = 0x8000,
199 DX_AC97_READY = 0x0010,
200 DX_AC97_RECORD = 0x0008,
201 DX_AC97_PLAYBACK = 0x0002
202};
203
204enum sis7018_ac97_bits {
205 SI_AC97_BUSY_WRITE = 0x00008000,
206 SI_AC97_AUDIO_BUSY = 0x00004000,
207 SI_AC97_MODEM_BUSY = 0x00002000,
208 SI_AC97_BUSY_READ = 0x00008000,
209 SI_AC97_SECONDARY = 0x00000080,
210};
211
212enum serial_intf_ctrl_bits {
213 WARM_RESET = 0x00000001,
214 COLD_RESET = 0x00000002,
215 I2S_CLOCK = 0x00000004,
216 PCM_SEC_AC97 = 0x00000008,
217 AC97_DBL_RATE = 0x00000010,
218 SPDIF_EN = 0x00000020,
219 I2S_OUTPUT_EN = 0x00000040,
220 I2S_INPUT_EN = 0x00000080,
221 PCMIN = 0x00000100,
222 LINE1IN = 0x00000200,
223 MICIN = 0x00000400,
224 LINE2IN = 0x00000800,
225 HEAD_SET_IN = 0x00001000,
226 GPIOIN = 0x00002000,
227 /* 7018 spec says id = 01 but the demo board routed to 10
228 SECONDARY_ID= 0x00004000, */
229 SECONDARY_ID = 0x00004000,
230 PCMOUT = 0x00010000,
231 SURROUT = 0x00020000,
232 CENTEROUT = 0x00040000,
233 LFEOUT = 0x00080000,
234 LINE1OUT = 0x00100000,
235 LINE2OUT = 0x00200000,
236 GPIOOUT = 0x00400000,
237 SI_AC97_PRIMARY_READY = 0x01000000,
238 SI_AC97_SECONDARY_READY = 0x02000000,
239 SI_AC97_POWERDOWN = 0x04000000,
240};
241
242/* PCM defaults */
243
244#define T4D_DEFAULT_PCM_VOL 10 /* 0 - 255 */
245#define T4D_DEFAULT_PCM_PAN 0 /* 0 - 127 */
246#define T4D_DEFAULT_PCM_RVOL 127 /* 0 - 127 */
247#define T4D_DEFAULT_PCM_CVOL 127 /* 0 - 127 */
248
249struct snd_trident;
250struct snd_trident_voice;
251struct snd_trident_pcm_mixer;
252
253struct snd_trident_port {
254 struct snd_midi_channel_set * chset;
255 struct snd_trident * trident;
256 int mode; /* operation mode */
257 int client; /* sequencer client number */
258 int port; /* sequencer port number */
259 unsigned int midi_has_voices: 1;
260};
261
262struct snd_trident_memblk_arg {
263 short first_page, last_page;
264};
265
266struct snd_trident_tlb {
267 unsigned int * entries; /* 16k-aligned TLB table */
268 dma_addr_t entries_dmaaddr; /* 16k-aligned PCI address to TLB table */
269 unsigned long * shadow_entries; /* shadow entries with virtual addresses */
270 struct snd_dma_buffer buffer;
271 struct snd_util_memhdr * memhdr; /* page allocation list */
272 struct snd_dma_buffer silent_page;
273};
274
275struct snd_trident_voice {
276 unsigned int number;
277 unsigned int use: 1,
278 pcm: 1,
279 synth:1,
280 midi: 1;
281 unsigned int flags;
282 unsigned char client;
283 unsigned char port;
284 unsigned char index;
285
286 struct snd_trident_sample_ops *sample_ops;
287
288 /* channel parameters */
289 unsigned int CSO; /* 24 bits (16 on DX) */
290 unsigned int ESO; /* 24 bits (16 on DX) */
291 unsigned int LBA; /* 30 bits */
292 unsigned short EC; /* 12 bits */
293 unsigned short Alpha; /* 12 bits */
294 unsigned short Delta; /* 16 bits */
295 unsigned short Attribute; /* 16 bits - SiS 7018 */
296 unsigned short Vol; /* 12 bits (6.6) */
297 unsigned char Pan; /* 7 bits (1.4.2) */
298 unsigned char GVSel; /* 1 bit */
299 unsigned char RVol; /* 7 bits (5.2) */
300 unsigned char CVol; /* 7 bits (5.2) */
301 unsigned char FMC; /* 2 bits */
302 unsigned char CTRL; /* 4 bits */
303 unsigned char FMS; /* 4 bits */
304 unsigned char LFO; /* 8 bits */
305
306 unsigned int negCSO; /* nonzero - use negative CSO */
307
308 struct snd_util_memblk *memblk; /* memory block if TLB enabled */
309
310 /* PCM data */
311
312 struct snd_trident *trident;
313 struct snd_pcm_substream *substream;
314 struct snd_trident_voice *extra; /* extra PCM voice (acts as interrupt generator) */
315 unsigned int running: 1,
316 capture: 1,
317 spdif: 1,
318 foldback: 1,
319 isync: 1,
320 isync2: 1,
321 isync3: 1;
322 int foldback_chan; /* foldback subdevice number */
323 unsigned int stimer; /* global sample timer (to detect spurious interrupts) */
324 unsigned int spurious_threshold; /* spurious threshold */
325 unsigned int isync_mark;
326 unsigned int isync_max;
327 unsigned int isync_ESO;
328
329 /* --- */
330
331 void *private_data;
332 void (*private_free)(struct snd_trident_voice *voice);
333};
334
335struct snd_4dwave {
336 int seq_client;
337
338 struct snd_trident_port seq_ports[4];
339 struct snd_trident_voice voices[64];
340
341 int ChanSynthCount; /* number of allocated synth channels */
342 int max_size; /* maximum synth memory size in bytes */
343 int current_size; /* current allocated synth mem in bytes */
344};
345
346struct snd_trident_pcm_mixer {
347 struct snd_trident_voice *voice; /* active voice */
348 unsigned short vol; /* front volume */
349 unsigned char pan; /* pan control */
350 unsigned char rvol; /* rear volume */
351 unsigned char cvol; /* center volume */
352 unsigned char pad;
353};
354
355struct snd_trident {
356 int irq;
357
358 unsigned int device; /* device ID */
359
360 unsigned char bDMAStart;
361
362 unsigned long port;
363 unsigned long midi_port;
364
365 unsigned int spurious_irq_count;
366 unsigned int spurious_irq_max_delta;
367
368 struct snd_trident_tlb tlb; /* TLB entries for NX cards */
369
370 unsigned char spdif_ctrl;
371 unsigned char spdif_pcm_ctrl;
372 unsigned int spdif_bits;
373 unsigned int spdif_pcm_bits;
374 struct snd_kcontrol *spdif_pcm_ctl; /* S/PDIF settings */
375 unsigned int ac97_ctrl;
376
377 unsigned int ChanMap[2]; /* allocation map for hardware channels */
378
379 int ChanPCM; /* max number of PCM channels */
380 int ChanPCMcnt; /* actual number of PCM channels */
381
382 unsigned int ac97_detect: 1; /* 1 = AC97 in detection phase */
383 unsigned int in_suspend: 1; /* 1 during suspend/resume */
384
385 struct snd_4dwave synth; /* synth specific variables */
386
387 spinlock_t event_lock;
388 spinlock_t voice_alloc;
389
390 struct snd_dma_device dma_dev;
391
392 struct pci_dev *pci;
393 struct snd_card *card;
394 struct snd_pcm *pcm; /* ADC/DAC PCM */
395 struct snd_pcm *foldback; /* Foldback PCM */
396 struct snd_pcm *spdif; /* SPDIF PCM */
397 struct snd_rawmidi *rmidi;
398
399 struct snd_ac97_bus *ac97_bus;
400 struct snd_ac97 *ac97;
401 struct snd_ac97 *ac97_sec;
402
403 unsigned int musicvol_wavevol;
404 struct snd_trident_pcm_mixer pcm_mixer[32];
405 struct snd_kcontrol *ctl_vol; /* front volume */
406 struct snd_kcontrol *ctl_pan; /* pan */
407 struct snd_kcontrol *ctl_rvol; /* rear volume */
408 struct snd_kcontrol *ctl_cvol; /* center volume */
409
410 spinlock_t reg_lock;
411
412 struct gameport *gameport;
413};
414
415int snd_trident_create(struct snd_card *card,
416 struct pci_dev *pci,
417 int pcm_streams,
418 int pcm_spdif_device,
419 int max_wavetable_size,
420 struct snd_trident ** rtrident);
421int snd_trident_create_gameport(struct snd_trident *trident);
422
423int snd_trident_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm);
424int snd_trident_foldback_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm);
425int snd_trident_spdif_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm);
426int snd_trident_attach_synthesizer(struct snd_trident * trident);
427struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident, int type,
428 int client, int port);
429void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voice *voice);
430void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice);
431void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice);
432void snd_trident_write_voice_regs(struct snd_trident * trident, struct snd_trident_voice *voice);
433extern const struct dev_pm_ops snd_trident_pm;
434
435/* TLB memory allocation */
436struct snd_util_memblk *snd_trident_alloc_pages(struct snd_trident *trident,
437 struct snd_pcm_substream *substream);
438int snd_trident_free_pages(struct snd_trident *trident, struct snd_util_memblk *blk);
439struct snd_util_memblk *snd_trident_synth_alloc(struct snd_trident *trident, unsigned int size);
440int snd_trident_synth_free(struct snd_trident *trident, struct snd_util_memblk *blk);
441int snd_trident_synth_copy_from_user(struct snd_trident *trident, struct snd_util_memblk *blk,
442 int offset, const char __user *data, int size);
443
444#endif /* __SOUND_TRIDENT_H */
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 61d3c0e8d4ce..94011dcae731 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -41,7 +41,7 @@
41#include <sound/info.h> 41#include <sound/info.h>
42#include <sound/control.h> 42#include <sound/control.h>
43#include <sound/tlv.h> 43#include <sound/tlv.h>
44#include <sound/trident.h> 44#include "trident.h"
45#include <sound/asoundef.h> 45#include <sound/asoundef.h>
46 46
47#include <asm/io.h> 47#include <asm/io.h>
@@ -3920,9 +3920,10 @@ static void snd_trident_clear_voices(struct snd_trident * trident, unsigned shor
3920} 3920}
3921 3921
3922#ifdef CONFIG_PM 3922#ifdef CONFIG_PM
3923int snd_trident_suspend(struct pci_dev *pci, pm_message_t state) 3923static int snd_trident_suspend(struct device *dev)
3924{ 3924{
3925 struct snd_card *card = pci_get_drvdata(pci); 3925 struct pci_dev *pci = to_pci_dev(dev);
3926 struct snd_card *card = dev_get_drvdata(dev);
3926 struct snd_trident *trident = card->private_data; 3927 struct snd_trident *trident = card->private_data;
3927 3928
3928 trident->in_suspend = 1; 3929 trident->in_suspend = 1;
@@ -3936,13 +3937,14 @@ int snd_trident_suspend(struct pci_dev *pci, pm_message_t state)
3936 3937
3937 pci_disable_device(pci); 3938 pci_disable_device(pci);
3938 pci_save_state(pci); 3939 pci_save_state(pci);
3939 pci_set_power_state(pci, pci_choose_state(pci, state)); 3940 pci_set_power_state(pci, PCI_D3hot);
3940 return 0; 3941 return 0;
3941} 3942}
3942 3943
3943int snd_trident_resume(struct pci_dev *pci) 3944static int snd_trident_resume(struct device *dev)
3944{ 3945{
3945 struct snd_card *card = pci_get_drvdata(pci); 3946 struct pci_dev *pci = to_pci_dev(dev);
3947 struct snd_card *card = dev_get_drvdata(dev);
3946 struct snd_trident *trident = card->private_data; 3948 struct snd_trident *trident = card->private_data;
3947 3949
3948 pci_set_power_state(pci, PCI_D0); 3950 pci_set_power_state(pci, PCI_D0);
@@ -3979,4 +3981,6 @@ int snd_trident_resume(struct pci_dev *pci)
3979 trident->in_suspend = 0; 3981 trident->in_suspend = 0;
3980 return 0; 3982 return 0;
3981} 3983}
3984
3985SIMPLE_DEV_PM_OPS(snd_trident_pm, snd_trident_suspend, snd_trident_resume);
3982#endif /* CONFIG_PM */ 3986#endif /* CONFIG_PM */
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
index f9779e23fe57..3102a579660b 100644
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -29,7 +29,7 @@
29#include <linux/mutex.h> 29#include <linux/mutex.h>
30 30
31#include <sound/core.h> 31#include <sound/core.h>
32#include <sound/trident.h> 32#include "trident.h"
33 33
34/* page arguments of these two macros are Trident page (4096 bytes), not like 34/* page arguments of these two macros are Trident page (4096 bytes), not like
35 * aligned pages in others 35 * aligned pages in others
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index b5afab48943e..0eb7245dd362 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -2242,9 +2242,10 @@ static int snd_via82xx_chip_init(struct via82xx *chip)
2242/* 2242/*
2243 * power management 2243 * power management
2244 */ 2244 */
2245static int snd_via82xx_suspend(struct pci_dev *pci, pm_message_t state) 2245static int snd_via82xx_suspend(struct device *dev)
2246{ 2246{
2247 struct snd_card *card = pci_get_drvdata(pci); 2247 struct pci_dev *pci = to_pci_dev(dev);
2248 struct snd_card *card = dev_get_drvdata(dev);
2248 struct via82xx *chip = card->private_data; 2249 struct via82xx *chip = card->private_data;
2249 int i; 2250 int i;
2250 2251
@@ -2265,13 +2266,14 @@ static int snd_via82xx_suspend(struct pci_dev *pci, pm_message_t state)
2265 2266
2266 pci_disable_device(pci); 2267 pci_disable_device(pci);
2267 pci_save_state(pci); 2268 pci_save_state(pci);
2268 pci_set_power_state(pci, pci_choose_state(pci, state)); 2269 pci_set_power_state(pci, PCI_D3hot);
2269 return 0; 2270 return 0;
2270} 2271}
2271 2272
2272static int snd_via82xx_resume(struct pci_dev *pci) 2273static int snd_via82xx_resume(struct device *dev)
2273{ 2274{
2274 struct snd_card *card = pci_get_drvdata(pci); 2275 struct pci_dev *pci = to_pci_dev(dev);
2276 struct snd_card *card = dev_get_drvdata(dev);
2275 struct via82xx *chip = card->private_data; 2277 struct via82xx *chip = card->private_data;
2276 int i; 2278 int i;
2277 2279
@@ -2306,6 +2308,11 @@ static int snd_via82xx_resume(struct pci_dev *pci)
2306 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2308 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2307 return 0; 2309 return 0;
2308} 2310}
2311
2312static SIMPLE_DEV_PM_OPS(snd_via82xx_pm, snd_via82xx_suspend, snd_via82xx_resume);
2313#define SND_VIA82XX_PM_OPS &snd_via82xx_pm
2314#else
2315#define SND_VIA82XX_PM_OPS NULL
2309#endif /* CONFIG_PM */ 2316#endif /* CONFIG_PM */
2310 2317
2311static int snd_via82xx_free(struct via82xx *chip) 2318static int snd_via82xx_free(struct via82xx *chip)
@@ -2624,10 +2631,9 @@ static struct pci_driver via82xx_driver = {
2624 .id_table = snd_via82xx_ids, 2631 .id_table = snd_via82xx_ids,
2625 .probe = snd_via82xx_probe, 2632 .probe = snd_via82xx_probe,
2626 .remove = __devexit_p(snd_via82xx_remove), 2633 .remove = __devexit_p(snd_via82xx_remove),
2627#ifdef CONFIG_PM 2634 .driver = {
2628 .suspend = snd_via82xx_suspend, 2635 .pm = SND_VIA82XX_PM_OPS,
2629 .resume = snd_via82xx_resume, 2636 },
2630#endif
2631}; 2637};
2632 2638
2633module_pci_driver(via82xx_driver); 2639module_pci_driver(via82xx_driver);
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 59fd47ed0a31..e886bc16999d 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -1023,9 +1023,10 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip)
1023/* 1023/*
1024 * power management 1024 * power management
1025 */ 1025 */
1026static int snd_via82xx_suspend(struct pci_dev *pci, pm_message_t state) 1026static int snd_via82xx_suspend(struct device *dev)
1027{ 1027{
1028 struct snd_card *card = pci_get_drvdata(pci); 1028 struct pci_dev *pci = to_pci_dev(dev);
1029 struct snd_card *card = dev_get_drvdata(dev);
1029 struct via82xx_modem *chip = card->private_data; 1030 struct via82xx_modem *chip = card->private_data;
1030 int i; 1031 int i;
1031 1032
@@ -1039,13 +1040,14 @@ static int snd_via82xx_suspend(struct pci_dev *pci, pm_message_t state)
1039 1040
1040 pci_disable_device(pci); 1041 pci_disable_device(pci);
1041 pci_save_state(pci); 1042 pci_save_state(pci);
1042 pci_set_power_state(pci, pci_choose_state(pci, state)); 1043 pci_set_power_state(pci, PCI_D3hot);
1043 return 0; 1044 return 0;
1044} 1045}
1045 1046
1046static int snd_via82xx_resume(struct pci_dev *pci) 1047static int snd_via82xx_resume(struct device *dev)
1047{ 1048{
1048 struct snd_card *card = pci_get_drvdata(pci); 1049 struct pci_dev *pci = to_pci_dev(dev);
1050 struct snd_card *card = dev_get_drvdata(dev);
1049 struct via82xx_modem *chip = card->private_data; 1051 struct via82xx_modem *chip = card->private_data;
1050 int i; 1052 int i;
1051 1053
@@ -1069,6 +1071,11 @@ static int snd_via82xx_resume(struct pci_dev *pci)
1069 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1071 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1070 return 0; 1072 return 0;
1071} 1073}
1074
1075static SIMPLE_DEV_PM_OPS(snd_via82xx_pm, snd_via82xx_suspend, snd_via82xx_resume);
1076#define SND_VIA82XX_PM_OPS &snd_via82xx_pm
1077#else
1078#define SND_VIA82XX_PM_OPS NULL
1072#endif /* CONFIG_PM */ 1079#endif /* CONFIG_PM */
1073 1080
1074static int snd_via82xx_free(struct via82xx_modem *chip) 1081static int snd_via82xx_free(struct via82xx_modem *chip)
@@ -1228,10 +1235,9 @@ static struct pci_driver via82xx_modem_driver = {
1228 .id_table = snd_via82xx_modem_ids, 1235 .id_table = snd_via82xx_modem_ids,
1229 .probe = snd_via82xx_probe, 1236 .probe = snd_via82xx_probe,
1230 .remove = __devexit_p(snd_via82xx_remove), 1237 .remove = __devexit_p(snd_via82xx_remove),
1231#ifdef CONFIG_PM 1238 .driver = {
1232 .suspend = snd_via82xx_suspend, 1239 .pm = SND_VIA82XX_PM_OPS,
1233 .resume = snd_via82xx_resume, 1240 },
1234#endif
1235}; 1241};
1236 1242
1237module_pci_driver(via82xx_modem_driver); 1243module_pci_driver(via82xx_modem_driver);
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index 1ea1f656a5dc..b89e7a86e9d8 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -258,22 +258,24 @@ static void __devexit snd_vx222_remove(struct pci_dev *pci)
258} 258}
259 259
260#ifdef CONFIG_PM 260#ifdef CONFIG_PM
261static int snd_vx222_suspend(struct pci_dev *pci, pm_message_t state) 261static int snd_vx222_suspend(struct device *dev)
262{ 262{
263 struct snd_card *card = pci_get_drvdata(pci); 263 struct pci_dev *pci = to_pci_dev(dev);
264 struct snd_card *card = dev_get_drvdata(dev);
264 struct snd_vx222 *vx = card->private_data; 265 struct snd_vx222 *vx = card->private_data;
265 int err; 266 int err;
266 267
267 err = snd_vx_suspend(&vx->core, state); 268 err = snd_vx_suspend(&vx->core);
268 pci_disable_device(pci); 269 pci_disable_device(pci);
269 pci_save_state(pci); 270 pci_save_state(pci);
270 pci_set_power_state(pci, pci_choose_state(pci, state)); 271 pci_set_power_state(pci, PCI_D3hot);
271 return err; 272 return err;
272} 273}
273 274
274static int snd_vx222_resume(struct pci_dev *pci) 275static int snd_vx222_resume(struct device *dev)
275{ 276{
276 struct snd_card *card = pci_get_drvdata(pci); 277 struct pci_dev *pci = to_pci_dev(dev);
278 struct snd_card *card = dev_get_drvdata(dev);
277 struct snd_vx222 *vx = card->private_data; 279 struct snd_vx222 *vx = card->private_data;
278 280
279 pci_set_power_state(pci, PCI_D0); 281 pci_set_power_state(pci, PCI_D0);
@@ -287,6 +289,11 @@ static int snd_vx222_resume(struct pci_dev *pci)
287 pci_set_master(pci); 289 pci_set_master(pci);
288 return snd_vx_resume(&vx->core); 290 return snd_vx_resume(&vx->core);
289} 291}
292
293static SIMPLE_DEV_PM_OPS(snd_vx222_pm, snd_vx222_suspend, snd_vx222_resume);
294#define SND_VX222_PM_OPS &snd_vx222_pm
295#else
296#define SND_VX222_PM_OPS NULL
290#endif 297#endif
291 298
292static struct pci_driver vx222_driver = { 299static struct pci_driver vx222_driver = {
@@ -294,10 +301,9 @@ static struct pci_driver vx222_driver = {
294 .id_table = snd_vx222_ids, 301 .id_table = snd_vx222_ids,
295 .probe = snd_vx222_probe, 302 .probe = snd_vx222_probe,
296 .remove = __devexit_p(snd_vx222_remove), 303 .remove = __devexit_p(snd_vx222_remove),
297#ifdef CONFIG_PM 304 .driver = {
298 .suspend = snd_vx222_suspend, 305 .pm = SND_VX222_PM_OPS,
299 .resume = snd_vx222_resume, 306 },
300#endif
301}; 307};
302 308
303module_pci_driver(vx222_driver); 309module_pci_driver(vx222_driver);
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 9a1d01d653a7..4810356b97ba 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -24,7 +24,7 @@
24#include <linux/time.h> 24#include <linux/time.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <sound/core.h> 26#include <sound/core.h>
27#include <sound/ymfpci.h> 27#include "ymfpci.h"
28#include <sound/mpu401.h> 28#include <sound/mpu401.h>
29#include <sound/opl3.h> 29#include <sound/opl3.h>
30#include <sound/initval.h> 30#include <sound/initval.h>
@@ -356,8 +356,9 @@ static struct pci_driver ymfpci_driver = {
356 .probe = snd_card_ymfpci_probe, 356 .probe = snd_card_ymfpci_probe,
357 .remove = __devexit_p(snd_card_ymfpci_remove), 357 .remove = __devexit_p(snd_card_ymfpci_remove),
358#ifdef CONFIG_PM 358#ifdef CONFIG_PM
359 .suspend = snd_ymfpci_suspend, 359 .driver = {
360 .resume = snd_ymfpci_resume, 360 .pm = &snd_ymfpci_pm,
361 },
361#endif 362#endif
362}; 363};
363 364
diff --git a/sound/pci/ymfpci/ymfpci.h b/sound/pci/ymfpci/ymfpci.h
new file mode 100644
index 000000000000..bddc4052286b
--- /dev/null
+++ b/sound/pci/ymfpci/ymfpci.h
@@ -0,0 +1,389 @@
1#ifndef __SOUND_YMFPCI_H
2#define __SOUND_YMFPCI_H
3
4/*
5 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
6 * Definitions for Yahama YMF724/740/744/754 chips
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <sound/pcm.h>
26#include <sound/rawmidi.h>
27#include <sound/ac97_codec.h>
28#include <sound/timer.h>
29#include <linux/gameport.h>
30
31/*
32 * Direct registers
33 */
34
35#define YMFREG(chip, reg) (chip->port + YDSXGR_##reg)
36
37#define YDSXGR_INTFLAG 0x0004
38#define YDSXGR_ACTIVITY 0x0006
39#define YDSXGR_GLOBALCTRL 0x0008
40#define YDSXGR_ZVCTRL 0x000A
41#define YDSXGR_TIMERCTRL 0x0010
42#define YDSXGR_TIMERCOUNT 0x0012
43#define YDSXGR_SPDIFOUTCTRL 0x0018
44#define YDSXGR_SPDIFOUTSTATUS 0x001C
45#define YDSXGR_EEPROMCTRL 0x0020
46#define YDSXGR_SPDIFINCTRL 0x0034
47#define YDSXGR_SPDIFINSTATUS 0x0038
48#define YDSXGR_DSPPROGRAMDL 0x0048
49#define YDSXGR_DLCNTRL 0x004C
50#define YDSXGR_GPIOININTFLAG 0x0050
51#define YDSXGR_GPIOININTENABLE 0x0052
52#define YDSXGR_GPIOINSTATUS 0x0054
53#define YDSXGR_GPIOOUTCTRL 0x0056
54#define YDSXGR_GPIOFUNCENABLE 0x0058
55#define YDSXGR_GPIOTYPECONFIG 0x005A
56#define YDSXGR_AC97CMDDATA 0x0060
57#define YDSXGR_AC97CMDADR 0x0062
58#define YDSXGR_PRISTATUSDATA 0x0064
59#define YDSXGR_PRISTATUSADR 0x0066
60#define YDSXGR_SECSTATUSDATA 0x0068
61#define YDSXGR_SECSTATUSADR 0x006A
62#define YDSXGR_SECCONFIG 0x0070
63#define YDSXGR_LEGACYOUTVOL 0x0080
64#define YDSXGR_LEGACYOUTVOLL 0x0080
65#define YDSXGR_LEGACYOUTVOLR 0x0082
66#define YDSXGR_NATIVEDACOUTVOL 0x0084
67#define YDSXGR_NATIVEDACOUTVOLL 0x0084
68#define YDSXGR_NATIVEDACOUTVOLR 0x0086
69#define YDSXGR_ZVOUTVOL 0x0088
70#define YDSXGR_ZVOUTVOLL 0x0088
71#define YDSXGR_ZVOUTVOLR 0x008A
72#define YDSXGR_SECADCOUTVOL 0x008C
73#define YDSXGR_SECADCOUTVOLL 0x008C
74#define YDSXGR_SECADCOUTVOLR 0x008E
75#define YDSXGR_PRIADCOUTVOL 0x0090
76#define YDSXGR_PRIADCOUTVOLL 0x0090
77#define YDSXGR_PRIADCOUTVOLR 0x0092
78#define YDSXGR_LEGACYLOOPVOL 0x0094
79#define YDSXGR_LEGACYLOOPVOLL 0x0094
80#define YDSXGR_LEGACYLOOPVOLR 0x0096
81#define YDSXGR_NATIVEDACLOOPVOL 0x0098
82#define YDSXGR_NATIVEDACLOOPVOLL 0x0098
83#define YDSXGR_NATIVEDACLOOPVOLR 0x009A
84#define YDSXGR_ZVLOOPVOL 0x009C
85#define YDSXGR_ZVLOOPVOLL 0x009E
86#define YDSXGR_ZVLOOPVOLR 0x009E
87#define YDSXGR_SECADCLOOPVOL 0x00A0
88#define YDSXGR_SECADCLOOPVOLL 0x00A0
89#define YDSXGR_SECADCLOOPVOLR 0x00A2
90#define YDSXGR_PRIADCLOOPVOL 0x00A4
91#define YDSXGR_PRIADCLOOPVOLL 0x00A4
92#define YDSXGR_PRIADCLOOPVOLR 0x00A6
93#define YDSXGR_NATIVEADCINVOL 0x00A8
94#define YDSXGR_NATIVEADCINVOLL 0x00A8
95#define YDSXGR_NATIVEADCINVOLR 0x00AA
96#define YDSXGR_NATIVEDACINVOL 0x00AC
97#define YDSXGR_NATIVEDACINVOLL 0x00AC
98#define YDSXGR_NATIVEDACINVOLR 0x00AE
99#define YDSXGR_BUF441OUTVOL 0x00B0
100#define YDSXGR_BUF441OUTVOLL 0x00B0
101#define YDSXGR_BUF441OUTVOLR 0x00B2
102#define YDSXGR_BUF441LOOPVOL 0x00B4
103#define YDSXGR_BUF441LOOPVOLL 0x00B4
104#define YDSXGR_BUF441LOOPVOLR 0x00B6
105#define YDSXGR_SPDIFOUTVOL 0x00B8
106#define YDSXGR_SPDIFOUTVOLL 0x00B8
107#define YDSXGR_SPDIFOUTVOLR 0x00BA
108#define YDSXGR_SPDIFLOOPVOL 0x00BC
109#define YDSXGR_SPDIFLOOPVOLL 0x00BC
110#define YDSXGR_SPDIFLOOPVOLR 0x00BE
111#define YDSXGR_ADCSLOTSR 0x00C0
112#define YDSXGR_RECSLOTSR 0x00C4
113#define YDSXGR_ADCFORMAT 0x00C8
114#define YDSXGR_RECFORMAT 0x00CC
115#define YDSXGR_P44SLOTSR 0x00D0
116#define YDSXGR_STATUS 0x0100
117#define YDSXGR_CTRLSELECT 0x0104
118#define YDSXGR_MODE 0x0108
119#define YDSXGR_SAMPLECOUNT 0x010C
120#define YDSXGR_NUMOFSAMPLES 0x0110
121#define YDSXGR_CONFIG 0x0114
122#define YDSXGR_PLAYCTRLSIZE 0x0140
123#define YDSXGR_RECCTRLSIZE 0x0144
124#define YDSXGR_EFFCTRLSIZE 0x0148
125#define YDSXGR_WORKSIZE 0x014C
126#define YDSXGR_MAPOFREC 0x0150
127#define YDSXGR_MAPOFEFFECT 0x0154
128#define YDSXGR_PLAYCTRLBASE 0x0158
129#define YDSXGR_RECCTRLBASE 0x015C
130#define YDSXGR_EFFCTRLBASE 0x0160
131#define YDSXGR_WORKBASE 0x0164
132#define YDSXGR_DSPINSTRAM 0x1000
133#define YDSXGR_CTRLINSTRAM 0x4000
134
135#define YDSXG_AC97READCMD 0x8000
136#define YDSXG_AC97WRITECMD 0x0000
137
138#define PCIR_DSXG_LEGACY 0x40
139#define PCIR_DSXG_ELEGACY 0x42
140#define PCIR_DSXG_CTRL 0x48
141#define PCIR_DSXG_PWRCTRL1 0x4a
142#define PCIR_DSXG_PWRCTRL2 0x4e
143#define PCIR_DSXG_FMBASE 0x60
144#define PCIR_DSXG_SBBASE 0x62
145#define PCIR_DSXG_MPU401BASE 0x64
146#define PCIR_DSXG_JOYBASE 0x66
147
148#define YDSXG_DSPLENGTH 0x0080
149#define YDSXG_CTRLLENGTH 0x3000
150
151#define YDSXG_DEFAULT_WORK_SIZE 0x0400
152
153#define YDSXG_PLAYBACK_VOICES 64
154#define YDSXG_CAPTURE_VOICES 2
155#define YDSXG_EFFECT_VOICES 5
156
157#define YMFPCI_LEGACY_SBEN (1 << 0) /* soundblaster enable */
158#define YMFPCI_LEGACY_FMEN (1 << 1) /* OPL3 enable */
159#define YMFPCI_LEGACY_JPEN (1 << 2) /* joystick enable */
160#define YMFPCI_LEGACY_MEN (1 << 3) /* MPU401 enable */
161#define YMFPCI_LEGACY_MIEN (1 << 4) /* MPU RX irq enable */
162#define YMFPCI_LEGACY_IOBITS (1 << 5) /* i/o bits range, 0 = 16bit, 1 =10bit */
163#define YMFPCI_LEGACY_SDMA (3 << 6) /* SB DMA select */
164#define YMFPCI_LEGACY_SBIRQ (7 << 8) /* SB IRQ select */
165#define YMFPCI_LEGACY_MPUIRQ (7 << 11) /* MPU IRQ select */
166#define YMFPCI_LEGACY_SIEN (1 << 14) /* serialized IRQ */
167#define YMFPCI_LEGACY_LAD (1 << 15) /* legacy audio disable */
168
169#define YMFPCI_LEGACY2_FMIO (3 << 0) /* OPL3 i/o address (724/740) */
170#define YMFPCI_LEGACY2_SBIO (3 << 2) /* SB i/o address (724/740) */
171#define YMFPCI_LEGACY2_MPUIO (3 << 4) /* MPU401 i/o address (724/740) */
172#define YMFPCI_LEGACY2_JSIO (3 << 6) /* joystick i/o address (724/740) */
173#define YMFPCI_LEGACY2_MAIM (1 << 8) /* MPU401 ack intr mask */
174#define YMFPCI_LEGACY2_SMOD (3 << 11) /* SB DMA mode */
175#define YMFPCI_LEGACY2_SBVER (3 << 13) /* SB version select */
176#define YMFPCI_LEGACY2_IMOD (1 << 15) /* legacy IRQ mode */
177/* SIEN:IMOD 0:0 = legacy irq, 0:1 = INTA, 1:0 = serialized IRQ */
178
179#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
180#define SUPPORT_JOYSTICK
181#endif
182
183/*
184 *
185 */
186
187struct snd_ymfpci_playback_bank {
188 u32 format;
189 u32 loop_default;
190 u32 base; /* 32-bit address */
191 u32 loop_start; /* 32-bit offset */
192 u32 loop_end; /* 32-bit offset */
193 u32 loop_frac; /* 8-bit fraction - loop_start */
194 u32 delta_end; /* pitch delta end */
195 u32 lpfK_end;
196 u32 eg_gain_end;
197 u32 left_gain_end;
198 u32 right_gain_end;
199 u32 eff1_gain_end;
200 u32 eff2_gain_end;
201 u32 eff3_gain_end;
202 u32 lpfQ;
203 u32 status;
204 u32 num_of_frames;
205 u32 loop_count;
206 u32 start;
207 u32 start_frac;
208 u32 delta;
209 u32 lpfK;
210 u32 eg_gain;
211 u32 left_gain;
212 u32 right_gain;
213 u32 eff1_gain;
214 u32 eff2_gain;
215 u32 eff3_gain;
216 u32 lpfD1;
217 u32 lpfD2;
218 };
219
220struct snd_ymfpci_capture_bank {
221 u32 base; /* 32-bit address */
222 u32 loop_end; /* 32-bit offset */
223 u32 start; /* 32-bit offset */
224 u32 num_of_loops; /* counter */
225};
226
227struct snd_ymfpci_effect_bank {
228 u32 base; /* 32-bit address */
229 u32 loop_end; /* 32-bit offset */
230 u32 start; /* 32-bit offset */
231 u32 temp;
232};
233
234struct snd_ymfpci_pcm;
235struct snd_ymfpci;
236
237enum snd_ymfpci_voice_type {
238 YMFPCI_PCM,
239 YMFPCI_SYNTH,
240 YMFPCI_MIDI
241};
242
243struct snd_ymfpci_voice {
244 struct snd_ymfpci *chip;
245 int number;
246 unsigned int use: 1,
247 pcm: 1,
248 synth: 1,
249 midi: 1;
250 struct snd_ymfpci_playback_bank *bank;
251 dma_addr_t bank_addr;
252 void (*interrupt)(struct snd_ymfpci *chip, struct snd_ymfpci_voice *voice);
253 struct snd_ymfpci_pcm *ypcm;
254};
255
256enum snd_ymfpci_pcm_type {
257 PLAYBACK_VOICE,
258 CAPTURE_REC,
259 CAPTURE_AC97,
260 EFFECT_DRY_LEFT,
261 EFFECT_DRY_RIGHT,
262 EFFECT_EFF1,
263 EFFECT_EFF2,
264 EFFECT_EFF3
265};
266
267struct snd_ymfpci_pcm {
268 struct snd_ymfpci *chip;
269 enum snd_ymfpci_pcm_type type;
270 struct snd_pcm_substream *substream;
271 struct snd_ymfpci_voice *voices[2]; /* playback only */
272 unsigned int running: 1,
273 use_441_slot: 1,
274 output_front: 1,
275 output_rear: 1,
276 swap_rear: 1;
277 unsigned int update_pcm_vol;
278 u32 period_size; /* cached from runtime->period_size */
279 u32 buffer_size; /* cached from runtime->buffer_size */
280 u32 period_pos;
281 u32 last_pos;
282 u32 capture_bank_number;
283 u32 shift;
284};
285
286struct snd_ymfpci {
287 int irq;
288
289 unsigned int device_id; /* PCI device ID */
290 unsigned char rev; /* PCI revision */
291 unsigned long reg_area_phys;
292 void __iomem *reg_area_virt;
293 struct resource *res_reg_area;
294 struct resource *fm_res;
295 struct resource *mpu_res;
296
297 unsigned short old_legacy_ctrl;
298#ifdef SUPPORT_JOYSTICK
299 struct gameport *gameport;
300#endif
301
302 struct snd_dma_buffer work_ptr;
303
304 unsigned int bank_size_playback;
305 unsigned int bank_size_capture;
306 unsigned int bank_size_effect;
307 unsigned int work_size;
308
309 void *bank_base_playback;
310 void *bank_base_capture;
311 void *bank_base_effect;
312 void *work_base;
313 dma_addr_t bank_base_playback_addr;
314 dma_addr_t bank_base_capture_addr;
315 dma_addr_t bank_base_effect_addr;
316 dma_addr_t work_base_addr;
317 struct snd_dma_buffer ac3_tmp_base;
318
319 u32 *ctrl_playback;
320 struct snd_ymfpci_playback_bank *bank_playback[YDSXG_PLAYBACK_VOICES][2];
321 struct snd_ymfpci_capture_bank *bank_capture[YDSXG_CAPTURE_VOICES][2];
322 struct snd_ymfpci_effect_bank *bank_effect[YDSXG_EFFECT_VOICES][2];
323
324 int start_count;
325
326 u32 active_bank;
327 struct snd_ymfpci_voice voices[64];
328 int src441_used;
329
330 struct snd_ac97_bus *ac97_bus;
331 struct snd_ac97 *ac97;
332 struct snd_rawmidi *rawmidi;
333 struct snd_timer *timer;
334 unsigned int timer_ticks;
335
336 struct pci_dev *pci;
337 struct snd_card *card;
338 struct snd_pcm *pcm;
339 struct snd_pcm *pcm2;
340 struct snd_pcm *pcm_spdif;
341 struct snd_pcm *pcm_4ch;
342 struct snd_pcm_substream *capture_substream[YDSXG_CAPTURE_VOICES];
343 struct snd_pcm_substream *effect_substream[YDSXG_EFFECT_VOICES];
344 struct snd_kcontrol *ctl_vol_recsrc;
345 struct snd_kcontrol *ctl_vol_adcrec;
346 struct snd_kcontrol *ctl_vol_spdifrec;
347 unsigned short spdif_bits, spdif_pcm_bits;
348 struct snd_kcontrol *spdif_pcm_ctl;
349 int mode_dup4ch;
350 int rear_opened;
351 int spdif_opened;
352 struct snd_ymfpci_pcm_mixer {
353 u16 left;
354 u16 right;
355 struct snd_kcontrol *ctl;
356 } pcm_mixer[32];
357
358 spinlock_t reg_lock;
359 spinlock_t voice_lock;
360 wait_queue_head_t interrupt_sleep;
361 atomic_t interrupt_sleep_count;
362 struct snd_info_entry *proc_entry;
363 const struct firmware *dsp_microcode;
364 const struct firmware *controller_microcode;
365
366#ifdef CONFIG_PM
367 u32 *saved_regs;
368 u32 saved_ydsxgr_mode;
369 u16 saved_dsxg_legacy;
370 u16 saved_dsxg_elegacy;
371#endif
372};
373
374int snd_ymfpci_create(struct snd_card *card,
375 struct pci_dev *pci,
376 unsigned short old_legacy_ctrl,
377 struct snd_ymfpci ** rcodec);
378void snd_ymfpci_free_gameport(struct snd_ymfpci *chip);
379
380extern const struct dev_pm_ops snd_ymfpci_pm;
381
382int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
383int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
384int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
385int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
386int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch);
387int snd_ymfpci_timer(struct snd_ymfpci *chip, int device);
388
389#endif /* __SOUND_YMFPCI_H */
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index a8159b81e9c4..62b23635b754 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -33,7 +33,7 @@
33#include <sound/control.h> 33#include <sound/control.h>
34#include <sound/info.h> 34#include <sound/info.h>
35#include <sound/tlv.h> 35#include <sound/tlv.h>
36#include <sound/ymfpci.h> 36#include "ymfpci.h"
37#include <sound/asoundef.h> 37#include <sound/asoundef.h>
38#include <sound/mpu401.h> 38#include <sound/mpu401.h>
39 39
@@ -2302,9 +2302,10 @@ static int saved_regs_index[] = {
2302}; 2302};
2303#define YDSXGR_NUM_SAVED_REGS ARRAY_SIZE(saved_regs_index) 2303#define YDSXGR_NUM_SAVED_REGS ARRAY_SIZE(saved_regs_index)
2304 2304
2305int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state) 2305static int snd_ymfpci_suspend(struct device *dev)
2306{ 2306{
2307 struct snd_card *card = pci_get_drvdata(pci); 2307 struct pci_dev *pci = to_pci_dev(dev);
2308 struct snd_card *card = dev_get_drvdata(dev);
2308 struct snd_ymfpci *chip = card->private_data; 2309 struct snd_ymfpci *chip = card->private_data;
2309 unsigned int i; 2310 unsigned int i;
2310 2311
@@ -2326,13 +2327,14 @@ int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state)
2326 snd_ymfpci_disable_dsp(chip); 2327 snd_ymfpci_disable_dsp(chip);
2327 pci_disable_device(pci); 2328 pci_disable_device(pci);
2328 pci_save_state(pci); 2329 pci_save_state(pci);
2329 pci_set_power_state(pci, pci_choose_state(pci, state)); 2330 pci_set_power_state(pci, PCI_D3hot);
2330 return 0; 2331 return 0;
2331} 2332}
2332 2333
2333int snd_ymfpci_resume(struct pci_dev *pci) 2334static int snd_ymfpci_resume(struct device *dev)
2334{ 2335{
2335 struct snd_card *card = pci_get_drvdata(pci); 2336 struct pci_dev *pci = to_pci_dev(dev);
2337 struct snd_card *card = dev_get_drvdata(dev);
2336 struct snd_ymfpci *chip = card->private_data; 2338 struct snd_ymfpci *chip = card->private_data;
2337 unsigned int i; 2339 unsigned int i;
2338 2340
@@ -2370,6 +2372,8 @@ int snd_ymfpci_resume(struct pci_dev *pci)
2370 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2372 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2371 return 0; 2373 return 0;
2372} 2374}
2375
2376SIMPLE_DEV_PM_OPS(snd_ymfpci_pm, snd_ymfpci_suspend, snd_ymfpci_resume);
2373#endif /* CONFIG_PM */ 2377#endif /* CONFIG_PM */
2374 2378
2375int __devinit snd_ymfpci_create(struct snd_card *card, 2379int __devinit snd_ymfpci_create(struct snd_card *card,
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index 830839a874b6..f9b5229b2723 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -251,7 +251,7 @@ static int pdacf_suspend(struct pcmcia_device *link)
251 snd_printdd(KERN_DEBUG "SUSPEND\n"); 251 snd_printdd(KERN_DEBUG "SUSPEND\n");
252 if (chip) { 252 if (chip) {
253 snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n"); 253 snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n");
254 snd_pdacf_suspend(chip, PMSG_SUSPEND); 254 snd_pdacf_suspend(chip);
255 } 255 }
256 256
257 return 0; 257 return 0;
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.h b/sound/pcmcia/pdaudiocf/pdaudiocf.h
index 6ce9ad700290..ea41e57d7179 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.h
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.h
@@ -131,7 +131,7 @@ struct snd_pdacf *snd_pdacf_create(struct snd_card *card);
131int snd_pdacf_ak4117_create(struct snd_pdacf *pdacf); 131int snd_pdacf_ak4117_create(struct snd_pdacf *pdacf);
132void snd_pdacf_powerdown(struct snd_pdacf *chip); 132void snd_pdacf_powerdown(struct snd_pdacf *chip);
133#ifdef CONFIG_PM 133#ifdef CONFIG_PM
134int snd_pdacf_suspend(struct snd_pdacf *chip, pm_message_t state); 134int snd_pdacf_suspend(struct snd_pdacf *chip);
135int snd_pdacf_resume(struct snd_pdacf *chip); 135int snd_pdacf_resume(struct snd_pdacf *chip);
136#endif 136#endif
137int snd_pdacf_pcm_new(struct snd_pdacf *chip); 137int snd_pdacf_pcm_new(struct snd_pdacf *chip);
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
index 9dce0bde5c05..ea0adfb984ad 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
@@ -262,7 +262,7 @@ void snd_pdacf_powerdown(struct snd_pdacf *chip)
262 262
263#ifdef CONFIG_PM 263#ifdef CONFIG_PM
264 264
265int snd_pdacf_suspend(struct snd_pdacf *chip, pm_message_t state) 265int snd_pdacf_suspend(struct snd_pdacf *chip)
266{ 266{
267 u16 val; 267 u16 val;
268 268
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 512f0b472375..8f9350475c7b 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -260,7 +260,7 @@ static int vxp_suspend(struct pcmcia_device *link)
260 snd_printdd(KERN_DEBUG "SUSPEND\n"); 260 snd_printdd(KERN_DEBUG "SUSPEND\n");
261 if (chip) { 261 if (chip) {
262 snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n"); 262 snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n");
263 snd_vx_suspend(chip, PMSG_SUSPEND); 263 snd_vx_suspend(chip);
264 } 264 }
265 265
266 return 0; 266 return 0;
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c
index 5a4e263b5b0f..210cafe04890 100644
--- a/sound/ppc/powermac.c
+++ b/sound/ppc/powermac.c
@@ -143,20 +143,25 @@ static int __devexit snd_pmac_remove(struct platform_device *devptr)
143 return 0; 143 return 0;
144} 144}
145 145
146#ifdef CONFIG_PM 146#ifdef CONFIG_PM_SLEEP
147static int snd_pmac_driver_suspend(struct platform_device *devptr, pm_message_t state) 147static int snd_pmac_driver_suspend(struct device *dev)
148{ 148{
149 struct snd_card *card = platform_get_drvdata(devptr); 149 struct snd_card *card = dev_get_drvdata(dev);
150 snd_pmac_suspend(card->private_data); 150 snd_pmac_suspend(card->private_data);
151 return 0; 151 return 0;
152} 152}
153 153
154static int snd_pmac_driver_resume(struct platform_device *devptr) 154static int snd_pmac_driver_resume(struct device *dev)
155{ 155{
156 struct snd_card *card = platform_get_drvdata(devptr); 156 struct snd_card *card = dev_get_drvdata(dev);
157 snd_pmac_resume(card->private_data); 157 snd_pmac_resume(card->private_data);
158 return 0; 158 return 0;
159} 159}
160
161static SIMPLE_DEV_PM_OPS(snd_pmac_pm, snd_pmac_driver_suspend, snd_pmac_driver_resume);
162#define SND_PMAC_PM_OPS &snd_pmac_pm
163#else
164#define SND_PMAC_PM_OPS NULL
160#endif 165#endif
161 166
162#define SND_PMAC_DRIVER "snd_powermac" 167#define SND_PMAC_DRIVER "snd_powermac"
@@ -164,12 +169,10 @@ static int snd_pmac_driver_resume(struct platform_device *devptr)
164static struct platform_driver snd_pmac_driver = { 169static struct platform_driver snd_pmac_driver = {
165 .probe = snd_pmac_probe, 170 .probe = snd_pmac_probe,
166 .remove = __devexit_p(snd_pmac_remove), 171 .remove = __devexit_p(snd_pmac_remove),
167#ifdef CONFIG_PM
168 .suspend = snd_pmac_driver_suspend,
169 .resume = snd_pmac_driver_resume,
170#endif
171 .driver = { 172 .driver = {
172 .name = SND_PMAC_DRIVER 173 .name = SND_PMAC_DRIVER,
174 .owner = THIS_MODULE,
175 .pm = SND_PMAC_PM_OPS,
173 }, 176 },
174}; 177};
175 178
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
index 1aa52eff526a..9b18b5243a56 100644
--- a/sound/ppc/snd_ps3.c
+++ b/sound/ppc/snd_ps3.c
@@ -1040,6 +1040,7 @@ static int __devinit snd_ps3_driver_probe(struct ps3_system_bus_device *dev)
1040 GFP_KERNEL); 1040 GFP_KERNEL);
1041 if (!the_card.null_buffer_start_vaddr) { 1041 if (!the_card.null_buffer_start_vaddr) {
1042 pr_info("%s: nullbuffer alloc failed\n", __func__); 1042 pr_info("%s: nullbuffer alloc failed\n", __func__);
1043 ret = -ENOMEM;
1043 goto clean_preallocate; 1044 goto clean_preallocate;
1044 } 1045 }
1045 pr_debug("%s: null vaddr=%p dma=%#llx\n", __func__, 1046 pr_debug("%s: null vaddr=%p dma=%#llx\n", __func__,
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index 391a38ca58bc..d48b523207eb 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -654,7 +654,9 @@ static struct platform_driver snd_aica_driver = {
654 .probe = snd_aica_probe, 654 .probe = snd_aica_probe,
655 .remove = __devexit_p(snd_aica_remove), 655 .remove = __devexit_p(snd_aica_remove),
656 .driver = { 656 .driver = {
657 .name = SND_AICA_DRIVER}, 657 .name = SND_AICA_DRIVER,
658 .owner = THIS_MODULE,
659 },
658}; 660};
659 661
660static int __init aica_init(void) 662static int __init aica_init(void)
diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c
index f8b01c77b298..0a3394751ed2 100644
--- a/sound/sh/sh_dac_audio.c
+++ b/sound/sh/sh_dac_audio.c
@@ -438,6 +438,7 @@ static struct platform_driver sh_dac_driver = {
438 .remove = snd_sh_dac_remove, 438 .remove = snd_sh_dac_remove,
439 .driver = { 439 .driver = {
440 .name = "dac_audio", 440 .name = "dac_audio",
441 .owner = THIS_MODULE,
441 }, 442 },
442}; 443};
443 444
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 40b2ad1bb1cd..c5de0a84566f 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -33,6 +33,7 @@ source "sound/soc/atmel/Kconfig"
33source "sound/soc/au1x/Kconfig" 33source "sound/soc/au1x/Kconfig"
34source "sound/soc/blackfin/Kconfig" 34source "sound/soc/blackfin/Kconfig"
35source "sound/soc/davinci/Kconfig" 35source "sound/soc/davinci/Kconfig"
36source "sound/soc/dwc/Kconfig"
36source "sound/soc/ep93xx/Kconfig" 37source "sound/soc/ep93xx/Kconfig"
37source "sound/soc/fsl/Kconfig" 38source "sound/soc/fsl/Kconfig"
38source "sound/soc/jz4740/Kconfig" 39source "sound/soc/jz4740/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 70990f4017f4..00a555a743b6 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_SND_SOC) += atmel/
11obj-$(CONFIG_SND_SOC) += au1x/ 11obj-$(CONFIG_SND_SOC) += au1x/
12obj-$(CONFIG_SND_SOC) += blackfin/ 12obj-$(CONFIG_SND_SOC) += blackfin/
13obj-$(CONFIG_SND_SOC) += davinci/ 13obj-$(CONFIG_SND_SOC) += davinci/
14obj-$(CONFIG_SND_SOC) += dwc/
14obj-$(CONFIG_SND_SOC) += ep93xx/ 15obj-$(CONFIG_SND_SOC) += ep93xx/
15obj-$(CONFIG_SND_SOC) += fsl/ 16obj-$(CONFIG_SND_SOC) += fsl/
16obj-$(CONFIG_SND_SOC) += jz4740/ 17obj-$(CONFIG_SND_SOC) += jz4740/
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index 9f6bc55fc399..16b88f5c26e2 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -1,7 +1,8 @@
1config SND_BF5XX_I2S 1config SND_BF5XX_I2S
2 tristate "SoC I2S Audio for the ADI BF5xx chip" 2 tristate "SoC I2S Audio for the ADI Blackfin chip"
3 depends on BLACKFIN 3 depends on BLACKFIN
4 select SND_BF5XX_SOC_SPORT 4 select SND_BF5XX_SOC_SPORT if !BF60x
5 select SND_BF6XX_SOC_SPORT if BF60x
5 help 6 help
6 Say Y or M if you want to add support for codecs attached to 7 Say Y or M if you want to add support for codecs attached to
7 the Blackfin SPORT (synchronous serial ports) interface in I2S 8 the Blackfin SPORT (synchronous serial ports) interface in I2S
@@ -9,12 +10,14 @@ config SND_BF5XX_I2S
9 You will also need to select the audio interfaces to support below. 10 You will also need to select the audio interfaces to support below.
10 11
11config SND_BF5XX_SOC_SSM2602 12config SND_BF5XX_SOC_SSM2602
12 tristate "SoC SSM2602 Audio support for BF52x ezkit" 13 tristate "SoC SSM2602 Audio Codec Add-On Card support"
13 depends on SND_BF5XX_I2S && (SPI_MASTER || I2C) 14 depends on SND_BF5XX_I2S && (SPI_MASTER || I2C)
14 select SND_BF5XX_SOC_I2S 15 select SND_BF5XX_SOC_I2S if !BF60x
16 select SND_BF6XX_SOC_I2S if BF60x
15 select SND_SOC_SSM2602 17 select SND_SOC_SSM2602
16 help 18 help
17 Say Y if you want to add support for SoC audio on BF527-EZKIT. 19 Say Y if you want to add support for the Analog Devices
20 SSM2602 Audio Codec Add-On Card.
18 21
19config SND_SOC_BFIN_EVAL_ADAU1701 22config SND_SOC_BFIN_EVAL_ADAU1701
20 tristate "Support for the EVAL-ADAU1701MINIZ board on Blackfin eval boards" 23 tristate "Support for the EVAL-ADAU1701MINIZ board on Blackfin eval boards"
@@ -162,9 +165,15 @@ config SND_BF5XX_SOC_AD1980
162config SND_BF5XX_SOC_SPORT 165config SND_BF5XX_SOC_SPORT
163 tristate 166 tristate
164 167
168config SND_BF6XX_SOC_SPORT
169 tristate
170
165config SND_BF5XX_SOC_I2S 171config SND_BF5XX_SOC_I2S
166 tristate 172 tristate
167 173
174config SND_BF6XX_SOC_I2S
175 tristate
176
168config SND_BF5XX_SOC_TDM 177config SND_BF5XX_SOC_TDM
169 tristate 178 tristate
170 179
@@ -173,7 +182,7 @@ config SND_BF5XX_SOC_AC97
173 182
174config SND_BF5XX_SPORT_NUM 183config SND_BF5XX_SPORT_NUM
175 int "Set a SPORT for Sound chip" 184 int "Set a SPORT for Sound chip"
176 depends on (SND_BF5XX_I2S || SND_BF5XX_AC97 || SND_BF5XX_TDM) 185 depends on (SND_BF5XX_SOC_SPORT || SND_BF6XX_SOC_SPORT)
177 range 0 3 if BF54x 186 range 0 3 if BF54x
178 range 0 1 if !BF54x 187 range 0 1 if !BF54x
179 default 0 188 default 0
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile
index 1bf86ccaa8de..6fea1f4cbee2 100644
--- a/sound/soc/blackfin/Makefile
+++ b/sound/soc/blackfin/Makefile
@@ -3,16 +3,20 @@ snd-bf5xx-ac97-objs := bf5xx-ac97-pcm.o
3snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o 3snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o
4snd-bf5xx-tdm-objs := bf5xx-tdm-pcm.o 4snd-bf5xx-tdm-objs := bf5xx-tdm-pcm.o
5snd-soc-bf5xx-sport-objs := bf5xx-sport.o 5snd-soc-bf5xx-sport-objs := bf5xx-sport.o
6snd-soc-bf6xx-sport-objs := bf6xx-sport.o
6snd-soc-bf5xx-ac97-objs := bf5xx-ac97.o 7snd-soc-bf5xx-ac97-objs := bf5xx-ac97.o
7snd-soc-bf5xx-i2s-objs := bf5xx-i2s.o 8snd-soc-bf5xx-i2s-objs := bf5xx-i2s.o
9snd-soc-bf6xx-i2s-objs := bf6xx-i2s.o
8snd-soc-bf5xx-tdm-objs := bf5xx-tdm.o 10snd-soc-bf5xx-tdm-objs := bf5xx-tdm.o
9 11
10obj-$(CONFIG_SND_BF5XX_AC97) += snd-bf5xx-ac97.o 12obj-$(CONFIG_SND_BF5XX_AC97) += snd-bf5xx-ac97.o
11obj-$(CONFIG_SND_BF5XX_I2S) += snd-bf5xx-i2s.o 13obj-$(CONFIG_SND_BF5XX_I2S) += snd-bf5xx-i2s.o
12obj-$(CONFIG_SND_BF5XX_TDM) += snd-bf5xx-tdm.o 14obj-$(CONFIG_SND_BF5XX_TDM) += snd-bf5xx-tdm.o
13obj-$(CONFIG_SND_BF5XX_SOC_SPORT) += snd-soc-bf5xx-sport.o 15obj-$(CONFIG_SND_BF5XX_SOC_SPORT) += snd-soc-bf5xx-sport.o
16obj-$(CONFIG_SND_BF6XX_SOC_SPORT) += snd-soc-bf6xx-sport.o
14obj-$(CONFIG_SND_BF5XX_SOC_AC97) += snd-soc-bf5xx-ac97.o 17obj-$(CONFIG_SND_BF5XX_SOC_AC97) += snd-soc-bf5xx-ac97.o
15obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o 18obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o
19obj-$(CONFIG_SND_BF6XX_SOC_I2S) += snd-soc-bf6xx-i2s.o
16obj-$(CONFIG_SND_BF5XX_SOC_TDM) += snd-soc-bf5xx-tdm.o 20obj-$(CONFIG_SND_BF5XX_SOC_TDM) += snd-soc-bf5xx-tdm.o
17 21
18# Blackfin Machine Support 22# Blackfin Machine Support
diff --git a/sound/soc/blackfin/bf6xx-i2s.c b/sound/soc/blackfin/bf6xx-i2s.c
new file mode 100644
index 000000000000..c3c2466d3a42
--- /dev/null
+++ b/sound/soc/blackfin/bf6xx-i2s.c
@@ -0,0 +1,234 @@
1/*
2 * bf6xx-i2s.c - Analog Devices BF6XX i2s interface driver
3 *
4 * Copyright (c) 2012 Analog Devices Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/device.h>
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/platform_device.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dai.h>
28
29#include "bf6xx-sport.h"
30
31struct sport_params param;
32
33static int bfin_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
34 unsigned int fmt)
35{
36 struct sport_device *sport = snd_soc_dai_get_drvdata(cpu_dai);
37 struct device *dev = &sport->pdev->dev;
38 int ret = 0;
39
40 param.spctl &= ~(SPORT_CTL_OPMODE | SPORT_CTL_CKRE | SPORT_CTL_FSR
41 | SPORT_CTL_LFS | SPORT_CTL_LAFS);
42 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
43 case SND_SOC_DAIFMT_I2S:
44 param.spctl |= SPORT_CTL_OPMODE | SPORT_CTL_CKRE
45 | SPORT_CTL_LFS;
46 break;
47 case SND_SOC_DAIFMT_DSP_A:
48 param.spctl |= SPORT_CTL_FSR;
49 break;
50 case SND_SOC_DAIFMT_LEFT_J:
51 param.spctl |= SPORT_CTL_OPMODE | SPORT_CTL_LFS
52 | SPORT_CTL_LAFS;
53 break;
54 default:
55 dev_err(dev, "%s: Unknown DAI format type\n", __func__);
56 ret = -EINVAL;
57 break;
58 }
59
60 param.spctl &= ~(SPORT_CTL_ICLK | SPORT_CTL_IFS);
61 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
62 case SND_SOC_DAIFMT_CBM_CFM:
63 break;
64 case SND_SOC_DAIFMT_CBS_CFS:
65 case SND_SOC_DAIFMT_CBM_CFS:
66 case SND_SOC_DAIFMT_CBS_CFM:
67 ret = -EINVAL;
68 break;
69 default:
70 dev_err(dev, "%s: Unknown DAI master type\n", __func__);
71 ret = -EINVAL;
72 break;
73 }
74
75 return ret;
76}
77
78static int bfin_i2s_hw_params(struct snd_pcm_substream *substream,
79 struct snd_pcm_hw_params *params,
80 struct snd_soc_dai *dai)
81{
82 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
83 struct device *dev = &sport->pdev->dev;
84 int ret = 0;
85
86 param.spctl &= ~SPORT_CTL_SLEN;
87 switch (params_format(params)) {
88 case SNDRV_PCM_FORMAT_S8:
89 param.spctl |= 0x70;
90 sport->wdsize = 1;
91 case SNDRV_PCM_FORMAT_S16_LE:
92 param.spctl |= 0xf0;
93 sport->wdsize = 2;
94 break;
95 case SNDRV_PCM_FORMAT_S24_LE:
96 param.spctl |= 0x170;
97 sport->wdsize = 3;
98 break;
99 case SNDRV_PCM_FORMAT_S32_LE:
100 param.spctl |= 0x1f0;
101 sport->wdsize = 4;
102 break;
103 }
104
105 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
106 ret = sport_set_tx_params(sport, &param);
107 if (ret) {
108 dev_err(dev, "SPORT tx is busy!\n");
109 return ret;
110 }
111 } else {
112 ret = sport_set_rx_params(sport, &param);
113 if (ret) {
114 dev_err(dev, "SPORT rx is busy!\n");
115 return ret;
116 }
117 }
118 return 0;
119}
120
121#ifdef CONFIG_PM
122static int bfin_i2s_suspend(struct snd_soc_dai *dai)
123{
124 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
125
126 if (dai->capture_active)
127 sport_rx_stop(sport);
128 if (dai->playback_active)
129 sport_tx_stop(sport);
130 return 0;
131}
132
133static int bfin_i2s_resume(struct snd_soc_dai *dai)
134{
135 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
136 struct device *dev = &sport->pdev->dev;
137 int ret;
138
139 ret = sport_set_tx_params(sport, &param);
140 if (ret) {
141 dev_err(dev, "SPORT tx is busy!\n");
142 return ret;
143 }
144 ret = sport_set_rx_params(sport, &param);
145 if (ret) {
146 dev_err(dev, "SPORT rx is busy!\n");
147 return ret;
148 }
149
150 return 0;
151}
152
153#else
154#define bfin_i2s_suspend NULL
155#define bfin_i2s_resume NULL
156#endif
157
158#define BFIN_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
159 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
160 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
161 SNDRV_PCM_RATE_96000)
162
163#define BFIN_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
164 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
165
166static struct snd_soc_dai_ops bfin_i2s_dai_ops = {
167 .hw_params = bfin_i2s_hw_params,
168 .set_fmt = bfin_i2s_set_dai_fmt,
169};
170
171static struct snd_soc_dai_driver bfin_i2s_dai = {
172 .suspend = bfin_i2s_suspend,
173 .resume = bfin_i2s_resume,
174 .playback = {
175 .channels_min = 1,
176 .channels_max = 2,
177 .rates = BFIN_I2S_RATES,
178 .formats = BFIN_I2S_FORMATS,
179 },
180 .capture = {
181 .channels_min = 1,
182 .channels_max = 2,
183 .rates = BFIN_I2S_RATES,
184 .formats = BFIN_I2S_FORMATS,
185 },
186 .ops = &bfin_i2s_dai_ops,
187};
188
189static int __devinit bfin_i2s_probe(struct platform_device *pdev)
190{
191 struct sport_device *sport;
192 struct device *dev = &pdev->dev;
193 int ret;
194
195 sport = sport_create(pdev);
196 if (!sport)
197 return -ENODEV;
198
199 /* register with the ASoC layers */
200 ret = snd_soc_register_dai(dev, &bfin_i2s_dai);
201 if (ret) {
202 dev_err(dev, "Failed to register DAI: %d\n", ret);
203 sport_delete(sport);
204 return ret;
205 }
206 platform_set_drvdata(pdev, sport);
207
208 return 0;
209}
210
211static int __devexit bfin_i2s_remove(struct platform_device *pdev)
212{
213 struct sport_device *sport = platform_get_drvdata(pdev);
214
215 snd_soc_unregister_dai(&pdev->dev);
216 sport_delete(sport);
217
218 return 0;
219}
220
221static struct platform_driver bfin_i2s_driver = {
222 .probe = bfin_i2s_probe,
223 .remove = __devexit_p(bfin_i2s_remove),
224 .driver = {
225 .name = "bfin-i2s",
226 .owner = THIS_MODULE,
227 },
228};
229
230module_platform_driver(bfin_i2s_driver);
231
232MODULE_DESCRIPTION("Analog Devices BF6XX i2s interface driver");
233MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
234MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/blackfin/bf6xx-sport.c b/sound/soc/blackfin/bf6xx-sport.c
new file mode 100644
index 000000000000..dfb744381c42
--- /dev/null
+++ b/sound/soc/blackfin/bf6xx-sport.c
@@ -0,0 +1,429 @@
1/*
2 * bf6xx_sport.c Analog Devices BF6XX SPORT driver
3 *
4 * Copyright (c) 2012 Analog Devices Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/device.h>
21#include <linux/dma-mapping.h>
22#include <linux/interrupt.h>
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/slab.h>
26
27#include <asm/blackfin.h>
28#include <asm/dma.h>
29#include <asm/portmux.h>
30
31#include "bf6xx-sport.h"
32
33int sport_set_tx_params(struct sport_device *sport,
34 struct sport_params *params)
35{
36 if (sport->tx_regs->spctl & SPORT_CTL_SPENPRI)
37 return -EBUSY;
38 sport->tx_regs->spctl = params->spctl | SPORT_CTL_SPTRAN;
39 sport->tx_regs->div = params->div;
40 SSYNC();
41 return 0;
42}
43EXPORT_SYMBOL(sport_set_tx_params);
44
45int sport_set_rx_params(struct sport_device *sport,
46 struct sport_params *params)
47{
48 if (sport->rx_regs->spctl & SPORT_CTL_SPENPRI)
49 return -EBUSY;
50 sport->rx_regs->spctl = params->spctl & ~SPORT_CTL_SPTRAN;
51 sport->rx_regs->div = params->div;
52 SSYNC();
53 return 0;
54}
55EXPORT_SYMBOL(sport_set_rx_params);
56
57static int compute_wdsize(size_t wdsize)
58{
59 switch (wdsize) {
60 case 1:
61 return WDSIZE_8 | PSIZE_8;
62 case 2:
63 return WDSIZE_16 | PSIZE_16;
64 default:
65 return WDSIZE_32 | PSIZE_32;
66 }
67}
68
69void sport_tx_start(struct sport_device *sport)
70{
71 set_dma_next_desc_addr(sport->tx_dma_chan, sport->tx_desc);
72 set_dma_config(sport->tx_dma_chan, DMAFLOW_LIST | DI_EN
73 | compute_wdsize(sport->wdsize) | NDSIZE_6);
74 enable_dma(sport->tx_dma_chan);
75 sport->tx_regs->spctl |= SPORT_CTL_SPENPRI;
76 SSYNC();
77}
78EXPORT_SYMBOL(sport_tx_start);
79
80void sport_rx_start(struct sport_device *sport)
81{
82 set_dma_next_desc_addr(sport->rx_dma_chan, sport->rx_desc);
83 set_dma_config(sport->rx_dma_chan, DMAFLOW_LIST | DI_EN | WNR
84 | compute_wdsize(sport->wdsize) | NDSIZE_6);
85 enable_dma(sport->rx_dma_chan);
86 sport->rx_regs->spctl |= SPORT_CTL_SPENPRI;
87 SSYNC();
88}
89EXPORT_SYMBOL(sport_rx_start);
90
91void sport_tx_stop(struct sport_device *sport)
92{
93 sport->tx_regs->spctl &= ~SPORT_CTL_SPENPRI;
94 SSYNC();
95 disable_dma(sport->tx_dma_chan);
96}
97EXPORT_SYMBOL(sport_tx_stop);
98
99void sport_rx_stop(struct sport_device *sport)
100{
101 sport->rx_regs->spctl &= ~SPORT_CTL_SPENPRI;
102 SSYNC();
103 disable_dma(sport->rx_dma_chan);
104}
105EXPORT_SYMBOL(sport_rx_stop);
106
107void sport_set_tx_callback(struct sport_device *sport,
108 void (*tx_callback)(void *), void *tx_data)
109{
110 sport->tx_callback = tx_callback;
111 sport->tx_data = tx_data;
112}
113EXPORT_SYMBOL(sport_set_tx_callback);
114
115void sport_set_rx_callback(struct sport_device *sport,
116 void (*rx_callback)(void *), void *rx_data)
117{
118 sport->rx_callback = rx_callback;
119 sport->rx_data = rx_data;
120}
121EXPORT_SYMBOL(sport_set_rx_callback);
122
123static void setup_desc(struct dmasg *desc, void *buf, int fragcount,
124 size_t fragsize, unsigned int cfg,
125 unsigned int count, size_t wdsize)
126{
127
128 int i;
129
130 for (i = 0; i < fragcount; ++i) {
131 desc[i].next_desc_addr = &(desc[i + 1]);
132 desc[i].start_addr = (unsigned long)buf + i*fragsize;
133 desc[i].cfg = cfg;
134 desc[i].x_count = count;
135 desc[i].x_modify = wdsize;
136 desc[i].y_count = 0;
137 desc[i].y_modify = 0;
138 }
139
140 /* make circular */
141 desc[fragcount-1].next_desc_addr = desc;
142}
143
144int sport_config_tx_dma(struct sport_device *sport, void *buf,
145 int fragcount, size_t fragsize)
146{
147 unsigned int count;
148 unsigned int cfg;
149 dma_addr_t addr;
150
151 count = fragsize/sport->wdsize;
152
153 if (sport->tx_desc)
154 dma_free_coherent(NULL, sport->tx_desc_size,
155 sport->tx_desc, 0);
156
157 sport->tx_desc = dma_alloc_coherent(NULL,
158 fragcount * sizeof(struct dmasg), &addr, 0);
159 sport->tx_desc_size = fragcount * sizeof(struct dmasg);
160 if (!sport->tx_desc)
161 return -ENOMEM;
162
163 sport->tx_buf = buf;
164 sport->tx_fragsize = fragsize;
165 sport->tx_frags = fragcount;
166 cfg = DMAFLOW_LIST | DI_EN | compute_wdsize(sport->wdsize) | NDSIZE_6;
167
168 setup_desc(sport->tx_desc, buf, fragcount, fragsize,
169 cfg|DMAEN, count, sport->wdsize);
170
171 return 0;
172}
173EXPORT_SYMBOL(sport_config_tx_dma);
174
175int sport_config_rx_dma(struct sport_device *sport, void *buf,
176 int fragcount, size_t fragsize)
177{
178 unsigned int count;
179 unsigned int cfg;
180 dma_addr_t addr;
181
182 count = fragsize/sport->wdsize;
183
184 if (sport->rx_desc)
185 dma_free_coherent(NULL, sport->rx_desc_size,
186 sport->rx_desc, 0);
187
188 sport->rx_desc = dma_alloc_coherent(NULL,
189 fragcount * sizeof(struct dmasg), &addr, 0);
190 sport->rx_desc_size = fragcount * sizeof(struct dmasg);
191 if (!sport->rx_desc)
192 return -ENOMEM;
193
194 sport->rx_buf = buf;
195 sport->rx_fragsize = fragsize;
196 sport->rx_frags = fragcount;
197 cfg = DMAFLOW_LIST | DI_EN | compute_wdsize(sport->wdsize)
198 | WNR | NDSIZE_6;
199
200 setup_desc(sport->rx_desc, buf, fragcount, fragsize,
201 cfg|DMAEN, count, sport->wdsize);
202
203 return 0;
204}
205EXPORT_SYMBOL(sport_config_rx_dma);
206
207unsigned long sport_curr_offset_tx(struct sport_device *sport)
208{
209 unsigned long curr = get_dma_curr_addr(sport->tx_dma_chan);
210
211 return (unsigned char *)curr - sport->tx_buf;
212}
213EXPORT_SYMBOL(sport_curr_offset_tx);
214
215unsigned long sport_curr_offset_rx(struct sport_device *sport)
216{
217 unsigned long curr = get_dma_curr_addr(sport->rx_dma_chan);
218
219 return (unsigned char *)curr - sport->rx_buf;
220}
221EXPORT_SYMBOL(sport_curr_offset_rx);
222
223static irqreturn_t sport_tx_irq(int irq, void *dev_id)
224{
225 struct sport_device *sport = dev_id;
226 static unsigned long status;
227
228 status = get_dma_curr_irqstat(sport->tx_dma_chan);
229 if (status & (DMA_DONE|DMA_ERR)) {
230 clear_dma_irqstat(sport->tx_dma_chan);
231 SSYNC();
232 }
233 if (sport->tx_callback)
234 sport->tx_callback(sport->tx_data);
235 return IRQ_HANDLED;
236}
237
238static irqreturn_t sport_rx_irq(int irq, void *dev_id)
239{
240 struct sport_device *sport = dev_id;
241 unsigned long status;
242
243 status = get_dma_curr_irqstat(sport->rx_dma_chan);
244 if (status & (DMA_DONE|DMA_ERR)) {
245 clear_dma_irqstat(sport->rx_dma_chan);
246 SSYNC();
247 }
248 if (sport->rx_callback)
249 sport->rx_callback(sport->rx_data);
250 return IRQ_HANDLED;
251}
252
253static irqreturn_t sport_err_irq(int irq, void *dev_id)
254{
255 struct sport_device *sport = dev_id;
256 struct device *dev = &sport->pdev->dev;
257
258 if (sport->tx_regs->spctl & SPORT_CTL_DERRPRI)
259 dev_err(dev, "sport error: TUVF\n");
260 if (sport->rx_regs->spctl & SPORT_CTL_DERRPRI)
261 dev_err(dev, "sport error: ROVF\n");
262
263 return IRQ_HANDLED;
264}
265
266static int sport_get_resource(struct sport_device *sport)
267{
268 struct platform_device *pdev = sport->pdev;
269 struct device *dev = &pdev->dev;
270 struct bfin_snd_platform_data *pdata = dev->platform_data;
271 struct resource *res;
272
273 if (!pdata) {
274 dev_err(dev, "No platform data\n");
275 return -ENODEV;
276 }
277 sport->pin_req = pdata->pin_req;
278
279 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
280 if (!res) {
281 dev_err(dev, "No tx MEM resource\n");
282 return -ENODEV;
283 }
284 sport->tx_regs = (struct sport_register *)res->start;
285
286 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
287 if (!res) {
288 dev_err(dev, "No rx MEM resource\n");
289 return -ENODEV;
290 }
291 sport->rx_regs = (struct sport_register *)res->start;
292
293 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
294 if (!res) {
295 dev_err(dev, "No tx DMA resource\n");
296 return -ENODEV;
297 }
298 sport->tx_dma_chan = res->start;
299
300 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
301 if (!res) {
302 dev_err(dev, "No rx DMA resource\n");
303 return -ENODEV;
304 }
305 sport->rx_dma_chan = res->start;
306
307 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
308 if (!res) {
309 dev_err(dev, "No tx error irq resource\n");
310 return -ENODEV;
311 }
312 sport->tx_err_irq = res->start;
313
314 res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
315 if (!res) {
316 dev_err(dev, "No rx error irq resource\n");
317 return -ENODEV;
318 }
319 sport->rx_err_irq = res->start;
320
321 return 0;
322}
323
324static int sport_request_resource(struct sport_device *sport)
325{
326 struct device *dev = &sport->pdev->dev;
327 int ret;
328
329 ret = peripheral_request_list(sport->pin_req, "soc-audio");
330 if (ret) {
331 dev_err(dev, "Unable to request sport pin\n");
332 return ret;
333 }
334
335 ret = request_dma(sport->tx_dma_chan, "SPORT TX Data");
336 if (ret) {
337 dev_err(dev, "Unable to allocate DMA channel for sport tx\n");
338 goto err_tx_dma;
339 }
340 set_dma_callback(sport->tx_dma_chan, sport_tx_irq, sport);
341
342 ret = request_dma(sport->rx_dma_chan, "SPORT RX Data");
343 if (ret) {
344 dev_err(dev, "Unable to allocate DMA channel for sport rx\n");
345 goto err_rx_dma;
346 }
347 set_dma_callback(sport->rx_dma_chan, sport_rx_irq, sport);
348
349 ret = request_irq(sport->tx_err_irq, sport_err_irq,
350 0, "SPORT TX ERROR", sport);
351 if (ret) {
352 dev_err(dev, "Unable to allocate tx error IRQ for sport\n");
353 goto err_tx_irq;
354 }
355
356 ret = request_irq(sport->rx_err_irq, sport_err_irq,
357 0, "SPORT RX ERROR", sport);
358 if (ret) {
359 dev_err(dev, "Unable to allocate rx error IRQ for sport\n");
360 goto err_rx_irq;
361 }
362
363 return 0;
364err_rx_irq:
365 free_irq(sport->tx_err_irq, sport);
366err_tx_irq:
367 free_dma(sport->rx_dma_chan);
368err_rx_dma:
369 free_dma(sport->tx_dma_chan);
370err_tx_dma:
371 peripheral_free_list(sport->pin_req);
372 return ret;
373}
374
375static void sport_free_resource(struct sport_device *sport)
376{
377 free_irq(sport->rx_err_irq, sport);
378 free_irq(sport->tx_err_irq, sport);
379 free_dma(sport->rx_dma_chan);
380 free_dma(sport->tx_dma_chan);
381 peripheral_free_list(sport->pin_req);
382}
383
384struct sport_device *sport_create(struct platform_device *pdev)
385{
386 struct device *dev = &pdev->dev;
387 struct sport_device *sport;
388 int ret;
389
390 sport = kzalloc(sizeof(*sport), GFP_KERNEL);
391 if (!sport) {
392 dev_err(dev, "Unable to allocate memory for sport device\n");
393 return NULL;
394 }
395 sport->pdev = pdev;
396
397 ret = sport_get_resource(sport);
398 if (ret) {
399 kfree(sport);
400 return NULL;
401 }
402
403 ret = sport_request_resource(sport);
404 if (ret) {
405 kfree(sport);
406 return NULL;
407 }
408
409 dev_dbg(dev, "SPORT create success\n");
410 return sport;
411}
412EXPORT_SYMBOL(sport_create);
413
414void sport_delete(struct sport_device *sport)
415{
416 if (sport->tx_desc)
417 dma_free_coherent(NULL, sport->tx_desc_size,
418 sport->tx_desc, 0);
419 if (sport->rx_desc)
420 dma_free_coherent(NULL, sport->rx_desc_size,
421 sport->rx_desc, 0);
422 sport_free_resource(sport);
423 kfree(sport);
424}
425EXPORT_SYMBOL(sport_delete);
426
427MODULE_DESCRIPTION("Analog Devices BF6XX SPORT driver");
428MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
429MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/blackfin/bf6xx-sport.h b/sound/soc/blackfin/bf6xx-sport.h
new file mode 100644
index 000000000000..307d193cfcef
--- /dev/null
+++ b/sound/soc/blackfin/bf6xx-sport.h
@@ -0,0 +1,82 @@
1/*
2 * bf6xx_sport - Analog Devices BF6XX SPORT driver
3 *
4 * Copyright (c) 2012 Analog Devices Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#ifndef _BF6XX_SPORT_H_
21#define _BF6XX_SPORT_H_
22
23#include <linux/platform_device.h>
24#include <asm/bfin_sport3.h>
25
26struct sport_device {
27 struct platform_device *pdev;
28 const unsigned short *pin_req;
29 struct sport_register *tx_regs;
30 struct sport_register *rx_regs;
31 int tx_dma_chan;
32 int rx_dma_chan;
33 int tx_err_irq;
34 int rx_err_irq;
35
36 void (*tx_callback)(void *data);
37 void *tx_data;
38 void (*rx_callback)(void *data);
39 void *rx_data;
40
41 struct dmasg *tx_desc;
42 struct dmasg *rx_desc;
43 unsigned int tx_desc_size;
44 unsigned int rx_desc_size;
45 unsigned char *tx_buf;
46 unsigned char *rx_buf;
47 unsigned int tx_fragsize;
48 unsigned int rx_fragsize;
49 unsigned int tx_frags;
50 unsigned int rx_frags;
51 unsigned int wdsize;
52};
53
54struct sport_params {
55 u32 spctl;
56 u32 div;
57};
58
59struct sport_device *sport_create(struct platform_device *pdev);
60void sport_delete(struct sport_device *sport);
61int sport_set_tx_params(struct sport_device *sport,
62 struct sport_params *params);
63int sport_set_rx_params(struct sport_device *sport,
64 struct sport_params *params);
65void sport_tx_start(struct sport_device *sport);
66void sport_rx_start(struct sport_device *sport);
67void sport_tx_stop(struct sport_device *sport);
68void sport_rx_stop(struct sport_device *sport);
69void sport_set_tx_callback(struct sport_device *sport,
70 void (*tx_callback)(void *), void *tx_data);
71void sport_set_rx_callback(struct sport_device *sport,
72 void (*rx_callback)(void *), void *rx_data);
73int sport_config_tx_dma(struct sport_device *sport, void *buf,
74 int fragcount, size_t fragsize);
75int sport_config_rx_dma(struct sport_device *sport, void *buf,
76 int fragcount, size_t fragsize);
77unsigned long sport_curr_offset_tx(struct sport_device *sport);
78unsigned long sport_curr_offset_rx(struct sport_device *sport);
79
80
81
82#endif
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 1e1613a438dd..9f8e8594aeb9 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -12,6 +12,7 @@ config SND_SOC_ALL_CODECS
12 tristate "Build all ASoC CODEC drivers" 12 tristate "Build all ASoC CODEC drivers"
13 select SND_SOC_88PM860X if MFD_88PM860X 13 select SND_SOC_88PM860X if MFD_88PM860X
14 select SND_SOC_L3 14 select SND_SOC_L3
15 select SND_SOC_AB8500_CODEC if ABX500_CORE
15 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS 16 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
16 select SND_SOC_AD1836 if SPI_MASTER 17 select SND_SOC_AD1836 if SPI_MASTER
17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI 18 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI
@@ -35,7 +36,9 @@ config SND_SOC_ALL_CODECS
35 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI 36 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
36 select SND_SOC_CX20442 37 select SND_SOC_CX20442
37 select SND_SOC_DA7210 if I2C 38 select SND_SOC_DA7210 if I2C
39 select SND_SOC_DA732X if I2C
38 select SND_SOC_DFBMCS320 40 select SND_SOC_DFBMCS320
41 select SND_SOC_ISABELLE if I2C
39 select SND_SOC_JZ4740_CODEC 42 select SND_SOC_JZ4740_CODEC
40 select SND_SOC_LM4857 if I2C 43 select SND_SOC_LM4857 if I2C
41 select SND_SOC_LM49453 if I2C 44 select SND_SOC_LM49453 if I2C
@@ -54,6 +57,7 @@ config SND_SOC_ALL_CODECS
54 select SND_SOC_SPDIF 57 select SND_SOC_SPDIF
55 select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI 58 select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI
56 select SND_SOC_STA32X if I2C 59 select SND_SOC_STA32X if I2C
60 select SND_SOC_STA529 if I2C
57 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 61 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
58 select SND_SOC_TLV320AIC23 if I2C 62 select SND_SOC_TLV320AIC23 if I2C
59 select SND_SOC_TLV320AIC26 if SPI_MASTER 63 select SND_SOC_TLV320AIC26 if SPI_MASTER
@@ -70,6 +74,8 @@ config SND_SOC_ALL_CODECS
70 select SND_SOC_WM2000 if I2C 74 select SND_SOC_WM2000 if I2C
71 select SND_SOC_WM2200 if I2C 75 select SND_SOC_WM2200 if I2C
72 select SND_SOC_WM5100 if I2C 76 select SND_SOC_WM5100 if I2C
77 select SND_SOC_WM5102 if MFD_WM5102
78 select SND_SOC_WM5110 if MFD_WM5110
73 select SND_SOC_WM8350 if MFD_WM8350 79 select SND_SOC_WM8350 if MFD_WM8350
74 select SND_SOC_WM8400 if MFD_WM8400 80 select SND_SOC_WM8400 if MFD_WM8400
75 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI 81 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
@@ -126,11 +132,21 @@ config SND_SOC_ALL_CODECS
126config SND_SOC_88PM860X 132config SND_SOC_88PM860X
127 tristate 133 tristate
128 134
135config SND_SOC_ARIZONA
136 tristate
137 default y if SND_SOC_WM5102=y
138 default y if SND_SOC_WM5110=y
139 default m if SND_SOC_WM5102=m
140 default m if SND_SOC_WM5110=m
141
129config SND_SOC_WM_HUBS 142config SND_SOC_WM_HUBS
130 tristate 143 tristate
131 default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y 144 default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y
132 default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m 145 default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m
133 146
147config SND_SOC_AB8500_CODEC
148 tristate
149
134config SND_SOC_AC97_CODEC 150config SND_SOC_AC97_CODEC
135 tristate 151 tristate
136 select SND_AC97_CODEC 152 select SND_AC97_CODEC
@@ -219,12 +235,18 @@ config SND_SOC_L3
219config SND_SOC_DA7210 235config SND_SOC_DA7210
220 tristate 236 tristate
221 237
238config SND_SOC_DA732X
239 tristate
240
222config SND_SOC_DFBMCS320 241config SND_SOC_DFBMCS320
223 tristate 242 tristate
224 243
225config SND_SOC_DMIC 244config SND_SOC_DMIC
226 tristate 245 tristate
227 246
247config SND_SOC_ISABELLE
248 tristate
249
228config SND_SOC_LM49453 250config SND_SOC_LM49453
229 tristate 251 tristate
230 252
@@ -266,6 +288,9 @@ config SND_SOC_SSM2602
266config SND_SOC_STA32X 288config SND_SOC_STA32X
267 tristate 289 tristate
268 290
291config SND_SOC_STA529
292 tristate
293
269config SND_SOC_STAC9766 294config SND_SOC_STAC9766
270 tristate 295 tristate
271 296
@@ -313,6 +338,12 @@ config SND_SOC_WM2200
313config SND_SOC_WM5100 338config SND_SOC_WM5100
314 tristate 339 tristate
315 340
341config SND_SOC_WM5102
342 tristate
343
344config SND_SOC_WM5110
345 tristate
346
316config SND_SOC_WM8350 347config SND_SOC_WM8350
317 tristate 348 tristate
318 349
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index fc27fec39487..34148bb59c68 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,4 +1,5 @@
1snd-soc-88pm860x-objs := 88pm860x-codec.o 1snd-soc-88pm860x-objs := 88pm860x-codec.o
2snd-soc-ab8500-codec-objs := ab8500-codec.o
2snd-soc-ac97-objs := ac97.o 3snd-soc-ac97-objs := ac97.o
3snd-soc-ad1836-objs := ad1836.o 4snd-soc-ad1836-objs := ad1836.o
4snd-soc-ad193x-objs := ad193x.o 5snd-soc-ad193x-objs := ad193x.o
@@ -13,6 +14,7 @@ snd-soc-ak4535-objs := ak4535.o
13snd-soc-ak4641-objs := ak4641.o 14snd-soc-ak4641-objs := ak4641.o
14snd-soc-ak4642-objs := ak4642.o 15snd-soc-ak4642-objs := ak4642.o
15snd-soc-ak4671-objs := ak4671.o 16snd-soc-ak4671-objs := ak4671.o
17snd-soc-arizona-objs := arizona.o
16snd-soc-cq93vc-objs := cq93vc.o 18snd-soc-cq93vc-objs := cq93vc.o
17snd-soc-cs42l51-objs := cs42l51.o 19snd-soc-cs42l51-objs := cs42l51.o
18snd-soc-cs42l52-objs := cs42l52.o 20snd-soc-cs42l52-objs := cs42l52.o
@@ -21,8 +23,10 @@ snd-soc-cs4270-objs := cs4270.o
21snd-soc-cs4271-objs := cs4271.o 23snd-soc-cs4271-objs := cs4271.o
22snd-soc-cx20442-objs := cx20442.o 24snd-soc-cx20442-objs := cx20442.o
23snd-soc-da7210-objs := da7210.o 25snd-soc-da7210-objs := da7210.o
26snd-soc-da732x-objs := da732x.o
24snd-soc-dfbmcs320-objs := dfbmcs320.o 27snd-soc-dfbmcs320-objs := dfbmcs320.o
25snd-soc-dmic-objs := dmic.o 28snd-soc-dmic-objs := dmic.o
29snd-soc-isabelle-objs := isabelle.o
26snd-soc-jz4740-codec-objs := jz4740.o 30snd-soc-jz4740-codec-objs := jz4740.o
27snd-soc-l3-objs := l3.o 31snd-soc-l3-objs := l3.o
28snd-soc-lm4857-objs := lm4857.o 32snd-soc-lm4857-objs := lm4857.o
@@ -41,9 +45,11 @@ snd-soc-alc5623-objs := alc5623.o
41snd-soc-alc5632-objs := alc5632.o 45snd-soc-alc5632-objs := alc5632.o
42snd-soc-sigmadsp-objs := sigmadsp.o 46snd-soc-sigmadsp-objs := sigmadsp.o
43snd-soc-sn95031-objs := sn95031.o 47snd-soc-sn95031-objs := sn95031.o
44snd-soc-spdif-objs := spdif_transciever.o 48snd-soc-spdif-tx-objs := spdif_transciever.o
49snd-soc-spdif-rx-objs := spdif_receiver.o
45snd-soc-ssm2602-objs := ssm2602.o 50snd-soc-ssm2602-objs := ssm2602.o
46snd-soc-sta32x-objs := sta32x.o 51snd-soc-sta32x-objs := sta32x.o
52snd-soc-sta529-objs := sta529.o
47snd-soc-stac9766-objs := stac9766.o 53snd-soc-stac9766-objs := stac9766.o
48snd-soc-tlv320aic23-objs := tlv320aic23.o 54snd-soc-tlv320aic23-objs := tlv320aic23.o
49snd-soc-tlv320aic26-objs := tlv320aic26.o 55snd-soc-tlv320aic26-objs := tlv320aic26.o
@@ -59,6 +65,8 @@ snd-soc-wm1250-ev1-objs := wm1250-ev1.o
59snd-soc-wm2000-objs := wm2000.o 65snd-soc-wm2000-objs := wm2000.o
60snd-soc-wm2200-objs := wm2200.o 66snd-soc-wm2200-objs := wm2200.o
61snd-soc-wm5100-objs := wm5100.o wm5100-tables.o 67snd-soc-wm5100-objs := wm5100.o wm5100-tables.o
68snd-soc-wm5102-objs := wm5102.o
69snd-soc-wm5110-objs := wm5110.o
62snd-soc-wm8350-objs := wm8350.o 70snd-soc-wm8350-objs := wm8350.o
63snd-soc-wm8400-objs := wm8400.o 71snd-soc-wm8400-objs := wm8400.o
64snd-soc-wm8510-objs := wm8510.o 72snd-soc-wm8510-objs := wm8510.o
@@ -108,6 +116,7 @@ snd-soc-max9877-objs := max9877.o
108snd-soc-tpa6130a2-objs := tpa6130a2.o 116snd-soc-tpa6130a2-objs := tpa6130a2.o
109 117
110obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o 118obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o
119obj-$(CONFIG_SND_SOC_AB8500_CODEC) += snd-soc-ab8500-codec.o
111obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 120obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
112obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o 121obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
113obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o 122obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o
@@ -124,6 +133,7 @@ obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
124obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 133obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
125obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o 134obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
126obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o 135obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o
136obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o
127obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o 137obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
128obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o 138obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
129obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o 139obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o
@@ -132,8 +142,10 @@ obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
132obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o 142obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
133obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 143obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
134obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 144obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
145obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o
135obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o 146obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o
136obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o 147obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
148obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o
137obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 149obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
138obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 150obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
139obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o 151obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
@@ -150,9 +162,10 @@ obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
150obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o 162obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
151obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o 163obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
152obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o 164obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
153obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 165obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o
154obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 166obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
155obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o 167obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o
168obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o
156obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o 169obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
157obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 170obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
158obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 171obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
@@ -168,6 +181,8 @@ obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
168obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o 181obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
169obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o 182obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o
170obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o 183obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o
184obj-$(CONFIG_SND_SOC_WM5102) += snd-soc-wm5102.o
185obj-$(CONFIG_SND_SOC_WM5110) += snd-soc-wm5110.o
171obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o 186obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
172obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o 187obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
173obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 188obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
new file mode 100644
index 000000000000..07abd09e0b1d
--- /dev/null
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -0,0 +1,2607 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
5 * Kristoffer Karlsson <kristoffer.karlsson@stericsson.com>,
6 * Roger Nilsson <roger.xr.nilsson@stericsson.com>,
7 * for ST-Ericsson.
8 *
9 * Based on the early work done by:
10 * Mikko J. Lehto <mikko.lehto@symbio.com>,
11 * Mikko Sarmanne <mikko.sarmanne@symbio.com>,
12 * Jarmo K. Kuronen <jarmo.kuronen@symbio.com>,
13 * for ST-Ericsson.
14 *
15 * License terms:
16 *
17 * This program is free software; you can redistribute it and/or modify it
18 * under the terms of the GNU General Public License version 2 as published
19 * by the Free Software Foundation.
20 */
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/device.h>
25#include <linux/slab.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/pm.h>
30#include <linux/platform_device.h>
31#include <linux/mutex.h>
32#include <linux/mfd/abx500/ab8500.h>
33#include <linux/mfd/abx500.h>
34#include <linux/mfd/abx500/ab8500-sysctrl.h>
35#include <linux/mfd/abx500/ab8500-codec.h>
36#include <linux/regulator/consumer.h>
37#include <linux/of.h>
38
39#include <sound/core.h>
40#include <sound/pcm.h>
41#include <sound/pcm_params.h>
42#include <sound/initval.h>
43#include <sound/soc.h>
44#include <sound/soc-dapm.h>
45#include <sound/tlv.h>
46
47#include "ab8500-codec.h"
48
49/* Macrocell value definitions */
50#define CLK_32K_OUT2_DISABLE 0x01
51#define INACTIVE_RESET_AUDIO 0x02
52#define ENABLE_AUDIO_CLK_TO_AUDIO_BLK 0x10
53#define ENABLE_VINTCORE12_SUPPLY 0x04
54#define GPIO27_DIR_OUTPUT 0x04
55#define GPIO29_DIR_OUTPUT 0x10
56#define GPIO31_DIR_OUTPUT 0x40
57
58/* Macrocell register definitions */
59#define AB8500_CTRL3_REG 0x0200
60#define AB8500_GPIO_DIR4_REG 0x1013
61
62/* Nr of FIR/IIR-coeff banks in ANC-block */
63#define AB8500_NR_OF_ANC_COEFF_BANKS 2
64
65/* Minimum duration to keep ANC IIR Init bit high or
66low before proceeding with the configuration sequence */
67#define AB8500_ANC_SM_DELAY 2000
68
69#define AB8500_FILTER_CONTROL(xname, xcount, xmin, xmax) \
70{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
71 .info = filter_control_info, \
72 .get = filter_control_get, .put = filter_control_put, \
73 .private_value = (unsigned long)&(struct filter_control) \
74 {.count = xcount, .min = xmin, .max = xmax} }
75
76struct filter_control {
77 long min, max;
78 unsigned int count;
79 long value[128];
80};
81
82/* Sidetone states */
83static const char * const enum_sid_state[] = {
84 "Unconfigured",
85 "Apply FIR",
86 "FIR is configured",
87};
88enum sid_state {
89 SID_UNCONFIGURED = 0,
90 SID_APPLY_FIR = 1,
91 SID_FIR_CONFIGURED = 2,
92};
93
94static const char * const enum_anc_state[] = {
95 "Unconfigured",
96 "Apply FIR and IIR",
97 "FIR and IIR are configured",
98 "Apply FIR",
99 "FIR is configured",
100 "Apply IIR",
101 "IIR is configured"
102};
103enum anc_state {
104 ANC_UNCONFIGURED = 0,
105 ANC_APPLY_FIR_IIR = 1,
106 ANC_FIR_IIR_CONFIGURED = 2,
107 ANC_APPLY_FIR = 3,
108 ANC_FIR_CONFIGURED = 4,
109 ANC_APPLY_IIR = 5,
110 ANC_IIR_CONFIGURED = 6
111};
112
113/* Analog microphones */
114enum amic_idx {
115 AMIC_IDX_1A,
116 AMIC_IDX_1B,
117 AMIC_IDX_2
118};
119
120struct ab8500_codec_drvdata_dbg {
121 struct regulator *vaud;
122 struct regulator *vamic1;
123 struct regulator *vamic2;
124 struct regulator *vdmic;
125};
126
127/* Private data for AB8500 device-driver */
128struct ab8500_codec_drvdata {
129 /* Sidetone */
130 long *sid_fir_values;
131 enum sid_state sid_status;
132
133 /* ANC */
134 struct mutex anc_lock;
135 long *anc_fir_values;
136 long *anc_iir_values;
137 enum anc_state anc_status;
138};
139
140static inline const char *amic_micbias_str(enum amic_micbias micbias)
141{
142 switch (micbias) {
143 case AMIC_MICBIAS_VAMIC1:
144 return "VAMIC1";
145 case AMIC_MICBIAS_VAMIC2:
146 return "VAMIC2";
147 default:
148 return "Unknown";
149 }
150}
151
152static inline const char *amic_type_str(enum amic_type type)
153{
154 switch (type) {
155 case AMIC_TYPE_DIFFERENTIAL:
156 return "DIFFERENTIAL";
157 case AMIC_TYPE_SINGLE_ENDED:
158 return "SINGLE ENDED";
159 default:
160 return "Unknown";
161 }
162}
163
164/*
165 * Read'n'write functions
166 */
167
168/* Read a register from the audio-bank of AB8500 */
169static unsigned int ab8500_codec_read_reg(struct snd_soc_codec *codec,
170 unsigned int reg)
171{
172 int status;
173 unsigned int value = 0;
174
175 u8 value8;
176 status = abx500_get_register_interruptible(codec->dev, AB8500_AUDIO,
177 reg, &value8);
178 if (status < 0) {
179 dev_err(codec->dev,
180 "%s: ERROR: Register (0x%02x:0x%02x) read failed (%d).\n",
181 __func__, (u8)AB8500_AUDIO, (u8)reg, status);
182 } else {
183 dev_dbg(codec->dev,
184 "%s: Read 0x%02x from register 0x%02x:0x%02x\n",
185 __func__, value8, (u8)AB8500_AUDIO, (u8)reg);
186 value = (unsigned int)value8;
187 }
188
189 return value;
190}
191
192/* Write to a register in the audio-bank of AB8500 */
193static int ab8500_codec_write_reg(struct snd_soc_codec *codec,
194 unsigned int reg, unsigned int value)
195{
196 int status;
197
198 status = abx500_set_register_interruptible(codec->dev, AB8500_AUDIO,
199 reg, value);
200 if (status < 0)
201 dev_err(codec->dev,
202 "%s: ERROR: Register (%02x:%02x) write failed (%d).\n",
203 __func__, (u8)AB8500_AUDIO, (u8)reg, status);
204 else
205 dev_dbg(codec->dev,
206 "%s: Wrote 0x%02x into register %02x:%02x\n",
207 __func__, (u8)value, (u8)AB8500_AUDIO, (u8)reg);
208
209 return status;
210}
211
212/*
213 * Controls - DAPM
214 */
215
216/* Earpiece */
217
218/* Earpiece source selector */
219static const char * const enum_ear_lineout_source[] = {"Headset Left",
220 "Speaker Left"};
221static SOC_ENUM_SINGLE_DECL(dapm_enum_ear_lineout_source, AB8500_DMICFILTCONF,
222 AB8500_DMICFILTCONF_DA3TOEAR, enum_ear_lineout_source);
223static const struct snd_kcontrol_new dapm_ear_lineout_source =
224 SOC_DAPM_ENUM("Earpiece or LineOut Mono Source",
225 dapm_enum_ear_lineout_source);
226
227/* LineOut */
228
229/* LineOut source selector */
230static const char * const enum_lineout_source[] = {"Mono Path", "Stereo Path"};
231static SOC_ENUM_DOUBLE_DECL(dapm_enum_lineout_source, AB8500_ANACONF5,
232 AB8500_ANACONF5_HSLDACTOLOL,
233 AB8500_ANACONF5_HSRDACTOLOR, enum_lineout_source);
234static const struct snd_kcontrol_new dapm_lineout_source[] = {
235 SOC_DAPM_ENUM("LineOut Source", dapm_enum_lineout_source),
236};
237
238/* Handsfree */
239
240/* Speaker Left - ANC selector */
241static const char * const enum_HFx_sel[] = {"Audio Path", "ANC"};
242static SOC_ENUM_SINGLE_DECL(dapm_enum_HFl_sel, AB8500_DIGMULTCONF2,
243 AB8500_DIGMULTCONF2_HFLSEL, enum_HFx_sel);
244static const struct snd_kcontrol_new dapm_HFl_select[] = {
245 SOC_DAPM_ENUM("Speaker Left Source", dapm_enum_HFl_sel),
246};
247
248/* Speaker Right - ANC selector */
249static SOC_ENUM_SINGLE_DECL(dapm_enum_HFr_sel, AB8500_DIGMULTCONF2,
250 AB8500_DIGMULTCONF2_HFRSEL, enum_HFx_sel);
251static const struct snd_kcontrol_new dapm_HFr_select[] = {
252 SOC_DAPM_ENUM("Speaker Right Source", dapm_enum_HFr_sel),
253};
254
255/* Mic 1 */
256
257/* Mic 1 - Mic 1a or 1b selector */
258static const char * const enum_mic1ab_sel[] = {"Mic 1b", "Mic 1a"};
259static SOC_ENUM_SINGLE_DECL(dapm_enum_mic1ab_sel, AB8500_ANACONF3,
260 AB8500_ANACONF3_MIC1SEL, enum_mic1ab_sel);
261static const struct snd_kcontrol_new dapm_mic1ab_mux[] = {
262 SOC_DAPM_ENUM("Mic 1a or 1b Select", dapm_enum_mic1ab_sel),
263};
264
265/* Mic 1 - AD3 - Mic 1 or DMic 3 selector */
266static const char * const enum_ad3_sel[] = {"Mic 1", "DMic 3"};
267static SOC_ENUM_SINGLE_DECL(dapm_enum_ad3_sel, AB8500_DIGMULTCONF1,
268 AB8500_DIGMULTCONF1_AD3SEL, enum_ad3_sel);
269static const struct snd_kcontrol_new dapm_ad3_select[] = {
270 SOC_DAPM_ENUM("AD3 Source Select", dapm_enum_ad3_sel),
271};
272
273/* Mic 1 - AD6 - Mic 1 or DMic 6 selector */
274static const char * const enum_ad6_sel[] = {"Mic 1", "DMic 6"};
275static SOC_ENUM_SINGLE_DECL(dapm_enum_ad6_sel, AB8500_DIGMULTCONF1,
276 AB8500_DIGMULTCONF1_AD6SEL, enum_ad6_sel);
277static const struct snd_kcontrol_new dapm_ad6_select[] = {
278 SOC_DAPM_ENUM("AD6 Source Select", dapm_enum_ad6_sel),
279};
280
281/* Mic 2 */
282
283/* Mic 2 - AD5 - Mic 2 or DMic 5 selector */
284static const char * const enum_ad5_sel[] = {"Mic 2", "DMic 5"};
285static SOC_ENUM_SINGLE_DECL(dapm_enum_ad5_sel, AB8500_DIGMULTCONF1,
286 AB8500_DIGMULTCONF1_AD5SEL, enum_ad5_sel);
287static const struct snd_kcontrol_new dapm_ad5_select[] = {
288 SOC_DAPM_ENUM("AD5 Source Select", dapm_enum_ad5_sel),
289};
290
291/* LineIn */
292
293/* LineIn left - AD1 - LineIn Left or DMic 1 selector */
294static const char * const enum_ad1_sel[] = {"LineIn Left", "DMic 1"};
295static SOC_ENUM_SINGLE_DECL(dapm_enum_ad1_sel, AB8500_DIGMULTCONF1,
296 AB8500_DIGMULTCONF1_AD1SEL, enum_ad1_sel);
297static const struct snd_kcontrol_new dapm_ad1_select[] = {
298 SOC_DAPM_ENUM("AD1 Source Select", dapm_enum_ad1_sel),
299};
300
301/* LineIn right - Mic 2 or LineIn Right selector */
302static const char * const enum_mic2lr_sel[] = {"Mic 2", "LineIn Right"};
303static SOC_ENUM_SINGLE_DECL(dapm_enum_mic2lr_sel, AB8500_ANACONF3,
304 AB8500_ANACONF3_LINRSEL, enum_mic2lr_sel);
305static const struct snd_kcontrol_new dapm_mic2lr_select[] = {
306 SOC_DAPM_ENUM("Mic 2 or LINR Select", dapm_enum_mic2lr_sel),
307};
308
309/* LineIn right - AD2 - LineIn Right or DMic2 selector */
310static const char * const enum_ad2_sel[] = {"LineIn Right", "DMic 2"};
311static SOC_ENUM_SINGLE_DECL(dapm_enum_ad2_sel, AB8500_DIGMULTCONF1,
312 AB8500_DIGMULTCONF1_AD2SEL, enum_ad2_sel);
313static const struct snd_kcontrol_new dapm_ad2_select[] = {
314 SOC_DAPM_ENUM("AD2 Source Select", dapm_enum_ad2_sel),
315};
316
317
318/* ANC */
319
320static const char * const enum_anc_in_sel[] = {"Mic 1 / DMic 6",
321 "Mic 2 / DMic 5"};
322static SOC_ENUM_SINGLE_DECL(dapm_enum_anc_in_sel, AB8500_DMICFILTCONF,
323 AB8500_DMICFILTCONF_ANCINSEL, enum_anc_in_sel);
324static const struct snd_kcontrol_new dapm_anc_in_select[] = {
325 SOC_DAPM_ENUM("ANC Source", dapm_enum_anc_in_sel),
326};
327
328/* ANC - Enable/Disable */
329static const struct snd_kcontrol_new dapm_anc_enable[] = {
330 SOC_DAPM_SINGLE("Switch", AB8500_ANCCONF1,
331 AB8500_ANCCONF1_ENANC, 0, 0),
332};
333
334/* ANC to Earpiece - Mute */
335static const struct snd_kcontrol_new dapm_anc_ear_mute[] = {
336 SOC_DAPM_SINGLE("Switch", AB8500_DIGMULTCONF1,
337 AB8500_DIGMULTCONF1_ANCSEL, 1, 0),
338};
339
340
341
342/* Sidetone left */
343
344/* Sidetone left - Input selector */
345static const char * const enum_stfir1_in_sel[] = {
346 "LineIn Left", "LineIn Right", "Mic 1", "Headset Left"
347};
348static SOC_ENUM_SINGLE_DECL(dapm_enum_stfir1_in_sel, AB8500_DIGMULTCONF2,
349 AB8500_DIGMULTCONF2_FIRSID1SEL, enum_stfir1_in_sel);
350static const struct snd_kcontrol_new dapm_stfir1_in_select[] = {
351 SOC_DAPM_ENUM("Sidetone Left Source", dapm_enum_stfir1_in_sel),
352};
353
354/* Sidetone right path */
355
356/* Sidetone right - Input selector */
357static const char * const enum_stfir2_in_sel[] = {
358 "LineIn Right", "Mic 1", "DMic 4", "Headset Right"
359};
360static SOC_ENUM_SINGLE_DECL(dapm_enum_stfir2_in_sel, AB8500_DIGMULTCONF2,
361 AB8500_DIGMULTCONF2_FIRSID2SEL, enum_stfir2_in_sel);
362static const struct snd_kcontrol_new dapm_stfir2_in_select[] = {
363 SOC_DAPM_ENUM("Sidetone Right Source", dapm_enum_stfir2_in_sel),
364};
365
366/* Vibra */
367
368static const char * const enum_pwm2vibx[] = {"Audio Path", "PWM Generator"};
369
370static SOC_ENUM_SINGLE_DECL(dapm_enum_pwm2vib1, AB8500_PWMGENCONF1,
371 AB8500_PWMGENCONF1_PWMTOVIB1, enum_pwm2vibx);
372
373static const struct snd_kcontrol_new dapm_pwm2vib1[] = {
374 SOC_DAPM_ENUM("Vibra 1 Controller", dapm_enum_pwm2vib1),
375};
376
377static SOC_ENUM_SINGLE_DECL(dapm_enum_pwm2vib2, AB8500_PWMGENCONF1,
378 AB8500_PWMGENCONF1_PWMTOVIB2, enum_pwm2vibx);
379
380static const struct snd_kcontrol_new dapm_pwm2vib2[] = {
381 SOC_DAPM_ENUM("Vibra 2 Controller", dapm_enum_pwm2vib2),
382};
383
384/*
385 * DAPM-widgets
386 */
387
388static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {
389
390 /* Clocks */
391 SND_SOC_DAPM_CLOCK_SUPPLY("audioclk"),
392
393 /* Regulators */
394 SND_SOC_DAPM_REGULATOR_SUPPLY("V-AUD", 0),
395 SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC1", 0),
396 SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC2", 0),
397 SND_SOC_DAPM_REGULATOR_SUPPLY("V-DMIC", 0),
398
399 /* Power */
400 SND_SOC_DAPM_SUPPLY("Audio Power",
401 AB8500_POWERUP, AB8500_POWERUP_POWERUP, 0,
402 NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
403 SND_SOC_DAPM_SUPPLY("Audio Analog Power",
404 AB8500_POWERUP, AB8500_POWERUP_ENANA, 0,
405 NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
406
407 /* Main supply node */
408 SND_SOC_DAPM_SUPPLY("Main Supply", SND_SOC_NOPM, 0, 0,
409 NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
410
411 /* DA/AD */
412
413 SND_SOC_DAPM_INPUT("ADC Input"),
414 SND_SOC_DAPM_ADC("ADC", "ab8500_0c", SND_SOC_NOPM, 0, 0),
415
416 SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
417 SND_SOC_DAPM_OUTPUT("DAC Output"),
418
419 SND_SOC_DAPM_AIF_IN("DA_IN1", NULL, 0, SND_SOC_NOPM, 0, 0),
420 SND_SOC_DAPM_AIF_IN("DA_IN2", NULL, 0, SND_SOC_NOPM, 0, 0),
421 SND_SOC_DAPM_AIF_IN("DA_IN3", NULL, 0, SND_SOC_NOPM, 0, 0),
422 SND_SOC_DAPM_AIF_IN("DA_IN4", NULL, 0, SND_SOC_NOPM, 0, 0),
423 SND_SOC_DAPM_AIF_IN("DA_IN5", NULL, 0, SND_SOC_NOPM, 0, 0),
424 SND_SOC_DAPM_AIF_IN("DA_IN6", NULL, 0, SND_SOC_NOPM, 0, 0),
425 SND_SOC_DAPM_AIF_OUT("AD_OUT1", NULL, 0, SND_SOC_NOPM, 0, 0),
426 SND_SOC_DAPM_AIF_OUT("AD_OUT2", NULL, 0, SND_SOC_NOPM, 0, 0),
427 SND_SOC_DAPM_AIF_OUT("AD_OUT3", NULL, 0, SND_SOC_NOPM, 0, 0),
428 SND_SOC_DAPM_AIF_OUT("AD_OUT4", NULL, 0, SND_SOC_NOPM, 0, 0),
429 SND_SOC_DAPM_AIF_OUT("AD_OUT57", NULL, 0, SND_SOC_NOPM, 0, 0),
430 SND_SOC_DAPM_AIF_OUT("AD_OUT68", NULL, 0, SND_SOC_NOPM, 0, 0),
431
432 /* Headset path */
433
434 SND_SOC_DAPM_SUPPLY("Charge Pump", AB8500_ANACONF5,
435 AB8500_ANACONF5_ENCPHS, 0, NULL, 0),
436
437 SND_SOC_DAPM_DAC("DA1 Enable", "ab8500_0p",
438 AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA1, 0),
439 SND_SOC_DAPM_DAC("DA2 Enable", "ab8500_0p",
440 AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA2, 0),
441
442 SND_SOC_DAPM_PGA("HSL Digital Volume", SND_SOC_NOPM, 0, 0,
443 NULL, 0),
444 SND_SOC_DAPM_PGA("HSR Digital Volume", SND_SOC_NOPM, 0, 0,
445 NULL, 0),
446
447 SND_SOC_DAPM_DAC("HSL DAC", "ab8500_0p",
448 AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACHSL, 0),
449 SND_SOC_DAPM_DAC("HSR DAC", "ab8500_0p",
450 AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACHSR, 0),
451 SND_SOC_DAPM_MIXER("HSL DAC Mute", AB8500_MUTECONF,
452 AB8500_MUTECONF_MUTDACHSL, 1,
453 NULL, 0),
454 SND_SOC_DAPM_MIXER("HSR DAC Mute", AB8500_MUTECONF,
455 AB8500_MUTECONF_MUTDACHSR, 1,
456 NULL, 0),
457 SND_SOC_DAPM_DAC("HSL DAC Driver", "ab8500_0p",
458 AB8500_ANACONF3, AB8500_ANACONF3_ENDRVHSL, 0),
459 SND_SOC_DAPM_DAC("HSR DAC Driver", "ab8500_0p",
460 AB8500_ANACONF3, AB8500_ANACONF3_ENDRVHSR, 0),
461
462 SND_SOC_DAPM_MIXER("HSL Mute",
463 AB8500_MUTECONF, AB8500_MUTECONF_MUTHSL, 1,
464 NULL, 0),
465 SND_SOC_DAPM_MIXER("HSR Mute",
466 AB8500_MUTECONF, AB8500_MUTECONF_MUTHSR, 1,
467 NULL, 0),
468 SND_SOC_DAPM_MIXER("HSL Enable",
469 AB8500_ANACONF4, AB8500_ANACONF4_ENHSL, 0,
470 NULL, 0),
471 SND_SOC_DAPM_MIXER("HSR Enable",
472 AB8500_ANACONF4, AB8500_ANACONF4_ENHSR, 0,
473 NULL, 0),
474 SND_SOC_DAPM_PGA("HSL Volume",
475 SND_SOC_NOPM, 0, 0,
476 NULL, 0),
477 SND_SOC_DAPM_PGA("HSR Volume",
478 SND_SOC_NOPM, 0, 0,
479 NULL, 0),
480
481 SND_SOC_DAPM_OUTPUT("Headset Left"),
482 SND_SOC_DAPM_OUTPUT("Headset Right"),
483
484 /* LineOut path */
485
486 SND_SOC_DAPM_MUX("LineOut Source",
487 SND_SOC_NOPM, 0, 0, dapm_lineout_source),
488
489 SND_SOC_DAPM_MIXER("LOL Disable HFL",
490 AB8500_ANACONF4, AB8500_ANACONF4_ENHFL, 1,
491 NULL, 0),
492 SND_SOC_DAPM_MIXER("LOR Disable HFR",
493 AB8500_ANACONF4, AB8500_ANACONF4_ENHFR, 1,
494 NULL, 0),
495
496 SND_SOC_DAPM_MIXER("LOL Enable",
497 AB8500_ANACONF5, AB8500_ANACONF5_ENLOL, 0,
498 NULL, 0),
499 SND_SOC_DAPM_MIXER("LOR Enable",
500 AB8500_ANACONF5, AB8500_ANACONF5_ENLOR, 0,
501 NULL, 0),
502
503 SND_SOC_DAPM_OUTPUT("LineOut Left"),
504 SND_SOC_DAPM_OUTPUT("LineOut Right"),
505
506 /* Earpiece path */
507
508 SND_SOC_DAPM_MUX("Earpiece or LineOut Mono Source",
509 SND_SOC_NOPM, 0, 0, &dapm_ear_lineout_source),
510 SND_SOC_DAPM_MIXER("EAR DAC",
511 AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACEAR, 0,
512 NULL, 0),
513 SND_SOC_DAPM_MIXER("EAR Mute",
514 AB8500_MUTECONF, AB8500_MUTECONF_MUTEAR, 1,
515 NULL, 0),
516 SND_SOC_DAPM_MIXER("EAR Enable",
517 AB8500_ANACONF4, AB8500_ANACONF4_ENEAR, 0,
518 NULL, 0),
519
520 SND_SOC_DAPM_OUTPUT("Earpiece"),
521
522 /* Handsfree path */
523
524 SND_SOC_DAPM_MIXER("DA3 Channel Volume",
525 AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA3, 0,
526 NULL, 0),
527 SND_SOC_DAPM_MIXER("DA4 Channel Volume",
528 AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA4, 0,
529 NULL, 0),
530 SND_SOC_DAPM_MUX("Speaker Left Source",
531 SND_SOC_NOPM, 0, 0, dapm_HFl_select),
532 SND_SOC_DAPM_MUX("Speaker Right Source",
533 SND_SOC_NOPM, 0, 0, dapm_HFr_select),
534 SND_SOC_DAPM_MIXER("HFL DAC", AB8500_DAPATHCONF,
535 AB8500_DAPATHCONF_ENDACHFL, 0,
536 NULL, 0),
537 SND_SOC_DAPM_MIXER("HFR DAC",
538 AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACHFR, 0,
539 NULL, 0),
540 SND_SOC_DAPM_MIXER("DA4 or ANC path to HfR",
541 AB8500_DIGMULTCONF2, AB8500_DIGMULTCONF2_DATOHFREN, 0,
542 NULL, 0),
543 SND_SOC_DAPM_MIXER("DA3 or ANC path to HfL",
544 AB8500_DIGMULTCONF2, AB8500_DIGMULTCONF2_DATOHFLEN, 0,
545 NULL, 0),
546 SND_SOC_DAPM_MIXER("HFL Enable",
547 AB8500_ANACONF4, AB8500_ANACONF4_ENHFL, 0,
548 NULL, 0),
549 SND_SOC_DAPM_MIXER("HFR Enable",
550 AB8500_ANACONF4, AB8500_ANACONF4_ENHFR, 0,
551 NULL, 0),
552
553 SND_SOC_DAPM_OUTPUT("Speaker Left"),
554 SND_SOC_DAPM_OUTPUT("Speaker Right"),
555
556 /* Vibrator path */
557
558 SND_SOC_DAPM_INPUT("PWMGEN1"),
559 SND_SOC_DAPM_INPUT("PWMGEN2"),
560
561 SND_SOC_DAPM_MIXER("DA5 Channel Volume",
562 AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA5, 0,
563 NULL, 0),
564 SND_SOC_DAPM_MIXER("DA6 Channel Volume",
565 AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA6, 0,
566 NULL, 0),
567 SND_SOC_DAPM_MIXER("VIB1 DAC",
568 AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACVIB1, 0,
569 NULL, 0),
570 SND_SOC_DAPM_MIXER("VIB2 DAC",
571 AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACVIB2, 0,
572 NULL, 0),
573 SND_SOC_DAPM_MUX("Vibra 1 Controller",
574 SND_SOC_NOPM, 0, 0, dapm_pwm2vib1),
575 SND_SOC_DAPM_MUX("Vibra 2 Controller",
576 SND_SOC_NOPM, 0, 0, dapm_pwm2vib2),
577 SND_SOC_DAPM_MIXER("VIB1 Enable",
578 AB8500_ANACONF4, AB8500_ANACONF4_ENVIB1, 0,
579 NULL, 0),
580 SND_SOC_DAPM_MIXER("VIB2 Enable",
581 AB8500_ANACONF4, AB8500_ANACONF4_ENVIB2, 0,
582 NULL, 0),
583
584 SND_SOC_DAPM_OUTPUT("Vibra 1"),
585 SND_SOC_DAPM_OUTPUT("Vibra 2"),
586
587 /* Mic 1 */
588
589 SND_SOC_DAPM_INPUT("Mic 1"),
590
591 SND_SOC_DAPM_MUX("Mic 1a or 1b Select",
592 SND_SOC_NOPM, 0, 0, dapm_mic1ab_mux),
593 SND_SOC_DAPM_MIXER("MIC1 Mute",
594 AB8500_ANACONF2, AB8500_ANACONF2_MUTMIC1, 1,
595 NULL, 0),
596 SND_SOC_DAPM_MIXER("MIC1A V-AMICx Enable",
597 AB8500_ANACONF2, AB8500_ANACONF2_ENMIC1, 0,
598 NULL, 0),
599 SND_SOC_DAPM_MIXER("MIC1B V-AMICx Enable",
600 AB8500_ANACONF2, AB8500_ANACONF2_ENMIC1, 0,
601 NULL, 0),
602 SND_SOC_DAPM_MIXER("MIC1 ADC",
603 AB8500_ANACONF3, AB8500_ANACONF3_ENADCMIC, 0,
604 NULL, 0),
605 SND_SOC_DAPM_MUX("AD3 Source Select",
606 SND_SOC_NOPM, 0, 0, dapm_ad3_select),
607 SND_SOC_DAPM_MIXER("AD3 Channel Volume",
608 SND_SOC_NOPM, 0, 0,
609 NULL, 0),
610 SND_SOC_DAPM_MIXER("AD3 Enable",
611 AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD34, 0,
612 NULL, 0),
613
614 /* Mic 2 */
615
616 SND_SOC_DAPM_INPUT("Mic 2"),
617
618 SND_SOC_DAPM_MIXER("MIC2 Mute",
619 AB8500_ANACONF2, AB8500_ANACONF2_MUTMIC2, 1,
620 NULL, 0),
621 SND_SOC_DAPM_MIXER("MIC2 V-AMICx Enable", AB8500_ANACONF2,
622 AB8500_ANACONF2_ENMIC2, 0,
623 NULL, 0),
624
625 /* LineIn */
626
627 SND_SOC_DAPM_INPUT("LineIn Left"),
628 SND_SOC_DAPM_INPUT("LineIn Right"),
629
630 SND_SOC_DAPM_MIXER("LINL Mute",
631 AB8500_ANACONF2, AB8500_ANACONF2_MUTLINL, 1,
632 NULL, 0),
633 SND_SOC_DAPM_MIXER("LINR Mute",
634 AB8500_ANACONF2, AB8500_ANACONF2_MUTLINR, 1,
635 NULL, 0),
636 SND_SOC_DAPM_MIXER("LINL Enable", AB8500_ANACONF2,
637 AB8500_ANACONF2_ENLINL, 0,
638 NULL, 0),
639 SND_SOC_DAPM_MIXER("LINR Enable", AB8500_ANACONF2,
640 AB8500_ANACONF2_ENLINR, 0,
641 NULL, 0),
642
643 /* LineIn Bypass path */
644 SND_SOC_DAPM_MIXER("LINL to HSL Volume",
645 SND_SOC_NOPM, 0, 0,
646 NULL, 0),
647 SND_SOC_DAPM_MIXER("LINR to HSR Volume",
648 SND_SOC_NOPM, 0, 0,
649 NULL, 0),
650
651 /* LineIn, Mic 2 */
652 SND_SOC_DAPM_MUX("Mic 2 or LINR Select",
653 SND_SOC_NOPM, 0, 0, dapm_mic2lr_select),
654 SND_SOC_DAPM_MIXER("LINL ADC", AB8500_ANACONF3,
655 AB8500_ANACONF3_ENADCLINL, 0,
656 NULL, 0),
657 SND_SOC_DAPM_MIXER("LINR ADC", AB8500_ANACONF3,
658 AB8500_ANACONF3_ENADCLINR, 0,
659 NULL, 0),
660 SND_SOC_DAPM_MUX("AD1 Source Select",
661 SND_SOC_NOPM, 0, 0, dapm_ad1_select),
662 SND_SOC_DAPM_MUX("AD2 Source Select",
663 SND_SOC_NOPM, 0, 0, dapm_ad2_select),
664 SND_SOC_DAPM_MIXER("AD1 Channel Volume",
665 SND_SOC_NOPM, 0, 0,
666 NULL, 0),
667 SND_SOC_DAPM_MIXER("AD2 Channel Volume",
668 SND_SOC_NOPM, 0, 0,
669 NULL, 0),
670
671 SND_SOC_DAPM_MIXER("AD12 Enable",
672 AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD12, 0,
673 NULL, 0),
674
675 /* HD Capture path */
676
677 SND_SOC_DAPM_MUX("AD5 Source Select",
678 SND_SOC_NOPM, 0, 0, dapm_ad5_select),
679 SND_SOC_DAPM_MUX("AD6 Source Select",
680 SND_SOC_NOPM, 0, 0, dapm_ad6_select),
681 SND_SOC_DAPM_MIXER("AD5 Channel Volume",
682 SND_SOC_NOPM, 0, 0,
683 NULL, 0),
684 SND_SOC_DAPM_MIXER("AD6 Channel Volume",
685 SND_SOC_NOPM, 0, 0,
686 NULL, 0),
687 SND_SOC_DAPM_MIXER("AD57 Enable",
688 AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD5768, 0,
689 NULL, 0),
690 SND_SOC_DAPM_MIXER("AD68 Enable",
691 AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD5768, 0,
692 NULL, 0),
693
694 /* Digital Microphone path */
695
696 SND_SOC_DAPM_INPUT("DMic 1"),
697 SND_SOC_DAPM_INPUT("DMic 2"),
698 SND_SOC_DAPM_INPUT("DMic 3"),
699 SND_SOC_DAPM_INPUT("DMic 4"),
700 SND_SOC_DAPM_INPUT("DMic 5"),
701 SND_SOC_DAPM_INPUT("DMic 6"),
702
703 SND_SOC_DAPM_MIXER("DMIC1",
704 AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC1, 0,
705 NULL, 0),
706 SND_SOC_DAPM_MIXER("DMIC2",
707 AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC2, 0,
708 NULL, 0),
709 SND_SOC_DAPM_MIXER("DMIC3",
710 AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC3, 0,
711 NULL, 0),
712 SND_SOC_DAPM_MIXER("DMIC4",
713 AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC4, 0,
714 NULL, 0),
715 SND_SOC_DAPM_MIXER("DMIC5",
716 AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC5, 0,
717 NULL, 0),
718 SND_SOC_DAPM_MIXER("DMIC6",
719 AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC6, 0,
720 NULL, 0),
721 SND_SOC_DAPM_MIXER("AD4 Channel Volume",
722 SND_SOC_NOPM, 0, 0,
723 NULL, 0),
724 SND_SOC_DAPM_MIXER("AD4 Enable",
725 AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD34,
726 0, NULL, 0),
727
728 /* Acoustical Noise Cancellation path */
729
730 SND_SOC_DAPM_INPUT("ANC Configure Input"),
731 SND_SOC_DAPM_OUTPUT("ANC Configure Output"),
732
733 SND_SOC_DAPM_MUX("ANC Source",
734 SND_SOC_NOPM, 0, 0,
735 dapm_anc_in_select),
736 SND_SOC_DAPM_SWITCH("ANC",
737 SND_SOC_NOPM, 0, 0,
738 dapm_anc_enable),
739 SND_SOC_DAPM_SWITCH("ANC to Earpiece",
740 SND_SOC_NOPM, 0, 0,
741 dapm_anc_ear_mute),
742
743 /* Sidetone Filter path */
744
745 SND_SOC_DAPM_MUX("Sidetone Left Source",
746 SND_SOC_NOPM, 0, 0,
747 dapm_stfir1_in_select),
748 SND_SOC_DAPM_MUX("Sidetone Right Source",
749 SND_SOC_NOPM, 0, 0,
750 dapm_stfir2_in_select),
751 SND_SOC_DAPM_MIXER("STFIR1 Control",
752 SND_SOC_NOPM, 0, 0,
753 NULL, 0),
754 SND_SOC_DAPM_MIXER("STFIR2 Control",
755 SND_SOC_NOPM, 0, 0,
756 NULL, 0),
757 SND_SOC_DAPM_MIXER("STFIR1 Volume",
758 SND_SOC_NOPM, 0, 0,
759 NULL, 0),
760 SND_SOC_DAPM_MIXER("STFIR2 Volume",
761 SND_SOC_NOPM, 0, 0,
762 NULL, 0),
763};
764
765/*
766 * DAPM-routes
767 */
768static const struct snd_soc_dapm_route ab8500_dapm_routes[] = {
769 /* Power AB8500 audio-block when AD/DA is active */
770 {"Main Supply", NULL, "V-AUD"},
771 {"Main Supply", NULL, "audioclk"},
772 {"Main Supply", NULL, "Audio Power"},
773 {"Main Supply", NULL, "Audio Analog Power"},
774
775 {"DAC", NULL, "ab8500_0p"},
776 {"DAC", NULL, "Main Supply"},
777 {"ADC", NULL, "ab8500_0c"},
778 {"ADC", NULL, "Main Supply"},
779
780 /* ANC Configure */
781 {"ANC Configure Input", NULL, "Main Supply"},
782 {"ANC Configure Output", NULL, "ANC Configure Input"},
783
784 /* AD/DA */
785 {"ADC", NULL, "ADC Input"},
786 {"DAC Output", NULL, "DAC"},
787
788 /* Powerup charge pump if DA1/2 is in use */
789
790 {"DA_IN1", NULL, "ab8500_0p"},
791 {"DA_IN1", NULL, "Charge Pump"},
792 {"DA_IN2", NULL, "ab8500_0p"},
793 {"DA_IN2", NULL, "Charge Pump"},
794
795 /* Headset path */
796
797 {"DA1 Enable", NULL, "DA_IN1"},
798 {"DA2 Enable", NULL, "DA_IN2"},
799
800 {"HSL Digital Volume", NULL, "DA1 Enable"},
801 {"HSR Digital Volume", NULL, "DA2 Enable"},
802
803 {"HSL DAC", NULL, "HSL Digital Volume"},
804 {"HSR DAC", NULL, "HSR Digital Volume"},
805
806 {"HSL DAC Mute", NULL, "HSL DAC"},
807 {"HSR DAC Mute", NULL, "HSR DAC"},
808
809 {"HSL DAC Driver", NULL, "HSL DAC Mute"},
810 {"HSR DAC Driver", NULL, "HSR DAC Mute"},
811
812 {"HSL Mute", NULL, "HSL DAC Driver"},
813 {"HSR Mute", NULL, "HSR DAC Driver"},
814
815 {"HSL Enable", NULL, "HSL Mute"},
816 {"HSR Enable", NULL, "HSR Mute"},
817
818 {"HSL Volume", NULL, "HSL Enable"},
819 {"HSR Volume", NULL, "HSR Enable"},
820
821 {"Headset Left", NULL, "HSL Volume"},
822 {"Headset Right", NULL, "HSR Volume"},
823
824 /* HF or LineOut path */
825
826 {"DA_IN3", NULL, "ab8500_0p"},
827 {"DA3 Channel Volume", NULL, "DA_IN3"},
828 {"DA_IN4", NULL, "ab8500_0p"},
829 {"DA4 Channel Volume", NULL, "DA_IN4"},
830
831 {"Speaker Left Source", "Audio Path", "DA3 Channel Volume"},
832 {"Speaker Right Source", "Audio Path", "DA4 Channel Volume"},
833
834 {"DA3 or ANC path to HfL", NULL, "Speaker Left Source"},
835 {"DA4 or ANC path to HfR", NULL, "Speaker Right Source"},
836
837 /* HF path */
838
839 {"HFL DAC", NULL, "DA3 or ANC path to HfL"},
840 {"HFR DAC", NULL, "DA4 or ANC path to HfR"},
841
842 {"HFL Enable", NULL, "HFL DAC"},
843 {"HFR Enable", NULL, "HFR DAC"},
844
845 {"Speaker Left", NULL, "HFL Enable"},
846 {"Speaker Right", NULL, "HFR Enable"},
847
848 /* Earpiece path */
849
850 {"Earpiece or LineOut Mono Source", "Headset Left",
851 "HSL Digital Volume"},
852 {"Earpiece or LineOut Mono Source", "Speaker Left",
853 "DA3 or ANC path to HfL"},
854
855 {"EAR DAC", NULL, "Earpiece or LineOut Mono Source"},
856
857 {"EAR Mute", NULL, "EAR DAC"},
858
859 {"EAR Enable", NULL, "EAR Mute"},
860
861 {"Earpiece", NULL, "EAR Enable"},
862
863 /* LineOut path stereo */
864
865 {"LineOut Source", "Stereo Path", "HSL DAC Driver"},
866 {"LineOut Source", "Stereo Path", "HSR DAC Driver"},
867
868 /* LineOut path mono */
869
870 {"LineOut Source", "Mono Path", "EAR DAC"},
871
872 /* LineOut path */
873
874 {"LOL Disable HFL", NULL, "LineOut Source"},
875 {"LOR Disable HFR", NULL, "LineOut Source"},
876
877 {"LOL Enable", NULL, "LOL Disable HFL"},
878 {"LOR Enable", NULL, "LOR Disable HFR"},
879
880 {"LineOut Left", NULL, "LOL Enable"},
881 {"LineOut Right", NULL, "LOR Enable"},
882
883 /* Vibrator path */
884
885 {"DA_IN5", NULL, "ab8500_0p"},
886 {"DA5 Channel Volume", NULL, "DA_IN5"},
887 {"DA_IN6", NULL, "ab8500_0p"},
888 {"DA6 Channel Volume", NULL, "DA_IN6"},
889
890 {"VIB1 DAC", NULL, "DA5 Channel Volume"},
891 {"VIB2 DAC", NULL, "DA6 Channel Volume"},
892
893 {"Vibra 1 Controller", "Audio Path", "VIB1 DAC"},
894 {"Vibra 2 Controller", "Audio Path", "VIB2 DAC"},
895 {"Vibra 1 Controller", "PWM Generator", "PWMGEN1"},
896 {"Vibra 2 Controller", "PWM Generator", "PWMGEN2"},
897
898 {"VIB1 Enable", NULL, "Vibra 1 Controller"},
899 {"VIB2 Enable", NULL, "Vibra 2 Controller"},
900
901 {"Vibra 1", NULL, "VIB1 Enable"},
902 {"Vibra 2", NULL, "VIB2 Enable"},
903
904
905 /* Mic 2 */
906
907 {"MIC2 V-AMICx Enable", NULL, "Mic 2"},
908
909 /* LineIn */
910 {"LINL Mute", NULL, "LineIn Left"},
911 {"LINR Mute", NULL, "LineIn Right"},
912
913 {"LINL Enable", NULL, "LINL Mute"},
914 {"LINR Enable", NULL, "LINR Mute"},
915
916 /* LineIn, Mic 2 */
917 {"Mic 2 or LINR Select", "LineIn Right", "LINR Enable"},
918 {"Mic 2 or LINR Select", "Mic 2", "MIC2 V-AMICx Enable"},
919
920 {"LINL ADC", NULL, "LINL Enable"},
921 {"LINR ADC", NULL, "Mic 2 or LINR Select"},
922
923 {"AD1 Source Select", "LineIn Left", "LINL ADC"},
924 {"AD2 Source Select", "LineIn Right", "LINR ADC"},
925
926 {"AD1 Channel Volume", NULL, "AD1 Source Select"},
927 {"AD2 Channel Volume", NULL, "AD2 Source Select"},
928
929 {"AD12 Enable", NULL, "AD1 Channel Volume"},
930 {"AD12 Enable", NULL, "AD2 Channel Volume"},
931
932 {"AD_OUT1", NULL, "ab8500_0c"},
933 {"AD_OUT1", NULL, "AD12 Enable"},
934 {"AD_OUT2", NULL, "ab8500_0c"},
935 {"AD_OUT2", NULL, "AD12 Enable"},
936
937 /* Mic 1 */
938
939 {"MIC1 Mute", NULL, "Mic 1"},
940
941 {"MIC1A V-AMICx Enable", NULL, "MIC1 Mute"},
942 {"MIC1B V-AMICx Enable", NULL, "MIC1 Mute"},
943
944 {"Mic 1a or 1b Select", "Mic 1a", "MIC1A V-AMICx Enable"},
945 {"Mic 1a or 1b Select", "Mic 1b", "MIC1B V-AMICx Enable"},
946
947 {"MIC1 ADC", NULL, "Mic 1a or 1b Select"},
948
949 {"AD3 Source Select", "Mic 1", "MIC1 ADC"},
950
951 {"AD3 Channel Volume", NULL, "AD3 Source Select"},
952
953 {"AD3 Enable", NULL, "AD3 Channel Volume"},
954
955 {"AD_OUT3", NULL, "ab8500_0c"},
956 {"AD_OUT3", NULL, "AD3 Enable"},
957
958 /* HD Capture path */
959
960 {"AD5 Source Select", "Mic 2", "LINR ADC"},
961 {"AD6 Source Select", "Mic 1", "MIC1 ADC"},
962
963 {"AD5 Channel Volume", NULL, "AD5 Source Select"},
964 {"AD6 Channel Volume", NULL, "AD6 Source Select"},
965
966 {"AD57 Enable", NULL, "AD5 Channel Volume"},
967 {"AD68 Enable", NULL, "AD6 Channel Volume"},
968
969 {"AD_OUT57", NULL, "ab8500_0c"},
970 {"AD_OUT57", NULL, "AD57 Enable"},
971 {"AD_OUT68", NULL, "ab8500_0c"},
972 {"AD_OUT68", NULL, "AD68 Enable"},
973
974 /* Digital Microphone path */
975
976 {"DMic 1", NULL, "V-DMIC"},
977 {"DMic 2", NULL, "V-DMIC"},
978 {"DMic 3", NULL, "V-DMIC"},
979 {"DMic 4", NULL, "V-DMIC"},
980 {"DMic 5", NULL, "V-DMIC"},
981 {"DMic 6", NULL, "V-DMIC"},
982
983 {"AD1 Source Select", NULL, "DMic 1"},
984 {"AD2 Source Select", NULL, "DMic 2"},
985 {"AD3 Source Select", NULL, "DMic 3"},
986 {"AD5 Source Select", NULL, "DMic 5"},
987 {"AD6 Source Select", NULL, "DMic 6"},
988
989 {"AD4 Channel Volume", NULL, "DMic 4"},
990 {"AD4 Enable", NULL, "AD4 Channel Volume"},
991
992 {"AD_OUT4", NULL, "ab8500_0c"},
993 {"AD_OUT4", NULL, "AD4 Enable"},
994
995 /* LineIn Bypass path */
996
997 {"LINL to HSL Volume", NULL, "LINL Enable"},
998 {"LINR to HSR Volume", NULL, "LINR Enable"},
999
1000 {"HSL DAC Driver", NULL, "LINL to HSL Volume"},
1001 {"HSR DAC Driver", NULL, "LINR to HSR Volume"},
1002
1003 /* ANC path (Acoustic Noise Cancellation) */
1004
1005 {"ANC Source", "Mic 2 / DMic 5", "AD5 Channel Volume"},
1006 {"ANC Source", "Mic 1 / DMic 6", "AD6 Channel Volume"},
1007
1008 {"ANC", "Switch", "ANC Source"},
1009
1010 {"Speaker Left Source", "ANC", "ANC"},
1011 {"Speaker Right Source", "ANC", "ANC"},
1012 {"ANC to Earpiece", "Switch", "ANC"},
1013
1014 {"HSL Digital Volume", NULL, "ANC to Earpiece"},
1015
1016 /* Sidetone Filter path */
1017
1018 {"Sidetone Left Source", "LineIn Left", "AD12 Enable"},
1019 {"Sidetone Left Source", "LineIn Right", "AD12 Enable"},
1020 {"Sidetone Left Source", "Mic 1", "AD3 Enable"},
1021 {"Sidetone Left Source", "Headset Left", "DA_IN1"},
1022 {"Sidetone Right Source", "LineIn Right", "AD12 Enable"},
1023 {"Sidetone Right Source", "Mic 1", "AD3 Enable"},
1024 {"Sidetone Right Source", "DMic 4", "AD4 Enable"},
1025 {"Sidetone Right Source", "Headset Right", "DA_IN2"},
1026
1027 {"STFIR1 Control", NULL, "Sidetone Left Source"},
1028 {"STFIR2 Control", NULL, "Sidetone Right Source"},
1029
1030 {"STFIR1 Volume", NULL, "STFIR1 Control"},
1031 {"STFIR2 Volume", NULL, "STFIR2 Control"},
1032
1033 {"DA1 Enable", NULL, "STFIR1 Volume"},
1034 {"DA2 Enable", NULL, "STFIR2 Volume"},
1035};
1036
1037static const struct snd_soc_dapm_route ab8500_dapm_routes_mic1a_vamicx[] = {
1038 {"MIC1A V-AMICx Enable", NULL, "V-AMIC1"},
1039 {"MIC1A V-AMICx Enable", NULL, "V-AMIC2"},
1040};
1041
1042static const struct snd_soc_dapm_route ab8500_dapm_routes_mic1b_vamicx[] = {
1043 {"MIC1B V-AMICx Enable", NULL, "V-AMIC1"},
1044 {"MIC1B V-AMICx Enable", NULL, "V-AMIC2"},
1045};
1046
1047static const struct snd_soc_dapm_route ab8500_dapm_routes_mic2_vamicx[] = {
1048 {"MIC2 V-AMICx Enable", NULL, "V-AMIC1"},
1049 {"MIC2 V-AMICx Enable", NULL, "V-AMIC2"},
1050};
1051
1052/* ANC FIR-coefficients configuration sequence */
1053static void anc_fir(struct snd_soc_codec *codec,
1054 unsigned int bnk, unsigned int par, unsigned int val)
1055{
1056 if (par == 0 && bnk == 0)
1057 snd_soc_update_bits(codec, AB8500_ANCCONF1,
1058 BIT(AB8500_ANCCONF1_ANCFIRUPDATE),
1059 BIT(AB8500_ANCCONF1_ANCFIRUPDATE));
1060
1061 snd_soc_write(codec, AB8500_ANCCONF5, val >> 8 & 0xff);
1062 snd_soc_write(codec, AB8500_ANCCONF6, val & 0xff);
1063
1064 if (par == AB8500_ANC_FIR_COEFFS - 1 && bnk == 1)
1065 snd_soc_update_bits(codec, AB8500_ANCCONF1,
1066 BIT(AB8500_ANCCONF1_ANCFIRUPDATE), 0);
1067}
1068
1069/* ANC IIR-coefficients configuration sequence */
1070static void anc_iir(struct snd_soc_codec *codec, unsigned int bnk,
1071 unsigned int par, unsigned int val)
1072{
1073 if (par == 0) {
1074 if (bnk == 0) {
1075 snd_soc_update_bits(codec, AB8500_ANCCONF1,
1076 BIT(AB8500_ANCCONF1_ANCIIRINIT),
1077 BIT(AB8500_ANCCONF1_ANCIIRINIT));
1078 usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY);
1079 snd_soc_update_bits(codec, AB8500_ANCCONF1,
1080 BIT(AB8500_ANCCONF1_ANCIIRINIT), 0);
1081 usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY);
1082 } else {
1083 snd_soc_update_bits(codec, AB8500_ANCCONF1,
1084 BIT(AB8500_ANCCONF1_ANCIIRUPDATE),
1085 BIT(AB8500_ANCCONF1_ANCIIRUPDATE));
1086 }
1087 } else if (par > 3) {
1088 snd_soc_write(codec, AB8500_ANCCONF7, 0);
1089 snd_soc_write(codec, AB8500_ANCCONF8, val >> 16 & 0xff);
1090 }
1091
1092 snd_soc_write(codec, AB8500_ANCCONF7, val >> 8 & 0xff);
1093 snd_soc_write(codec, AB8500_ANCCONF8, val & 0xff);
1094
1095 if (par == AB8500_ANC_IIR_COEFFS - 1 && bnk == 1)
1096 snd_soc_update_bits(codec, AB8500_ANCCONF1,
1097 BIT(AB8500_ANCCONF1_ANCIIRUPDATE), 0);
1098}
1099
1100/* ANC IIR-/FIR-coefficients configuration sequence */
1101static void anc_configure(struct snd_soc_codec *codec,
1102 bool apply_fir, bool apply_iir)
1103{
1104 struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
1105 unsigned int bnk, par, val;
1106
1107 dev_dbg(codec->dev, "%s: Enter.\n", __func__);
1108
1109 if (apply_fir)
1110 snd_soc_update_bits(codec, AB8500_ANCCONF1,
1111 BIT(AB8500_ANCCONF1_ENANC), 0);
1112
1113 snd_soc_update_bits(codec, AB8500_ANCCONF1,
1114 BIT(AB8500_ANCCONF1_ENANC), BIT(AB8500_ANCCONF1_ENANC));
1115
1116 if (apply_fir)
1117 for (bnk = 0; bnk < AB8500_NR_OF_ANC_COEFF_BANKS; bnk++)
1118 for (par = 0; par < AB8500_ANC_FIR_COEFFS; par++) {
1119 val = snd_soc_read(codec,
1120 drvdata->anc_fir_values[par]);
1121 anc_fir(codec, bnk, par, val);
1122 }
1123
1124 if (apply_iir)
1125 for (bnk = 0; bnk < AB8500_NR_OF_ANC_COEFF_BANKS; bnk++)
1126 for (par = 0; par < AB8500_ANC_IIR_COEFFS; par++) {
1127 val = snd_soc_read(codec,
1128 drvdata->anc_iir_values[par]);
1129 anc_iir(codec, bnk, par, val);
1130 }
1131
1132 dev_dbg(codec->dev, "%s: Exit.\n", __func__);
1133}
1134
1135/*
1136 * Control-events
1137 */
1138
1139static int sid_status_control_get(struct snd_kcontrol *kcontrol,
1140 struct snd_ctl_elem_value *ucontrol)
1141{
1142 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1143 struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
1144
1145 mutex_lock(&codec->mutex);
1146 ucontrol->value.integer.value[0] = drvdata->sid_status;
1147 mutex_unlock(&codec->mutex);
1148
1149 return 0;
1150}
1151
1152/* Write sidetone FIR-coefficients configuration sequence */
1153static int sid_status_control_put(struct snd_kcontrol *kcontrol,
1154 struct snd_ctl_elem_value *ucontrol)
1155{
1156 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1157 struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
1158 unsigned int param, sidconf, val;
1159 int status = 1;
1160
1161 dev_dbg(codec->dev, "%s: Enter\n", __func__);
1162
1163 if (ucontrol->value.integer.value[0] != SID_APPLY_FIR) {
1164 dev_err(codec->dev,
1165 "%s: ERROR: This control supports '%s' only!\n",
1166 __func__, enum_sid_state[SID_APPLY_FIR]);
1167 return -EIO;
1168 }
1169
1170 mutex_lock(&codec->mutex);
1171
1172 sidconf = snd_soc_read(codec, AB8500_SIDFIRCONF);
1173 if (((sidconf & BIT(AB8500_SIDFIRCONF_FIRSIDBUSY)) != 0)) {
1174 if ((sidconf & BIT(AB8500_SIDFIRCONF_ENFIRSIDS)) == 0) {
1175 dev_err(codec->dev, "%s: Sidetone busy while off!\n",
1176 __func__);
1177 status = -EPERM;
1178 } else {
1179 status = -EBUSY;
1180 }
1181 goto out;
1182 }
1183
1184 snd_soc_write(codec, AB8500_SIDFIRADR, 0);
1185
1186 for (param = 0; param < AB8500_SID_FIR_COEFFS; param++) {
1187 val = snd_soc_read(codec, drvdata->sid_fir_values[param]);
1188 snd_soc_write(codec, AB8500_SIDFIRCOEF1, val >> 8 & 0xff);
1189 snd_soc_write(codec, AB8500_SIDFIRCOEF2, val & 0xff);
1190 }
1191
1192 snd_soc_update_bits(codec, AB8500_SIDFIRADR,
1193 BIT(AB8500_SIDFIRADR_FIRSIDSET),
1194 BIT(AB8500_SIDFIRADR_FIRSIDSET));
1195 snd_soc_update_bits(codec, AB8500_SIDFIRADR,
1196 BIT(AB8500_SIDFIRADR_FIRSIDSET), 0);
1197
1198 drvdata->sid_status = SID_FIR_CONFIGURED;
1199
1200out:
1201 mutex_unlock(&codec->mutex);
1202
1203 dev_dbg(codec->dev, "%s: Exit\n", __func__);
1204
1205 return status;
1206}
1207
1208static int anc_status_control_get(struct snd_kcontrol *kcontrol,
1209 struct snd_ctl_elem_value *ucontrol)
1210{
1211 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1212 struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
1213
1214 mutex_lock(&codec->mutex);
1215 ucontrol->value.integer.value[0] = drvdata->anc_status;
1216 mutex_unlock(&codec->mutex);
1217
1218 return 0;
1219}
1220
1221static int anc_status_control_put(struct snd_kcontrol *kcontrol,
1222 struct snd_ctl_elem_value *ucontrol)
1223{
1224 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1225 struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
1226 struct device *dev = codec->dev;
1227 bool apply_fir, apply_iir;
1228 int req, status;
1229
1230 dev_dbg(dev, "%s: Enter.\n", __func__);
1231
1232 mutex_lock(&drvdata->anc_lock);
1233
1234 req = ucontrol->value.integer.value[0];
1235 if (req != ANC_APPLY_FIR_IIR && req != ANC_APPLY_FIR &&
1236 req != ANC_APPLY_IIR) {
1237 dev_err(dev, "%s: ERROR: Unsupported status to set '%s'!\n",
1238 __func__, enum_anc_state[req]);
1239 status = -EINVAL;
1240 goto cleanup;
1241 }
1242 apply_fir = req == ANC_APPLY_FIR || req == ANC_APPLY_FIR_IIR;
1243 apply_iir = req == ANC_APPLY_IIR || req == ANC_APPLY_FIR_IIR;
1244
1245 status = snd_soc_dapm_force_enable_pin(&codec->dapm,
1246 "ANC Configure Input");
1247 if (status < 0) {
1248 dev_err(dev,
1249 "%s: ERROR: Failed to enable power (status = %d)!\n",
1250 __func__, status);
1251 goto cleanup;
1252 }
1253 snd_soc_dapm_sync(&codec->dapm);
1254
1255 mutex_lock(&codec->mutex);
1256 anc_configure(codec, apply_fir, apply_iir);
1257 mutex_unlock(&codec->mutex);
1258
1259 if (apply_fir) {
1260 if (drvdata->anc_status == ANC_IIR_CONFIGURED)
1261 drvdata->anc_status = ANC_FIR_IIR_CONFIGURED;
1262 else if (drvdata->anc_status != ANC_FIR_IIR_CONFIGURED)
1263 drvdata->anc_status = ANC_FIR_CONFIGURED;
1264 }
1265 if (apply_iir) {
1266 if (drvdata->anc_status == ANC_FIR_CONFIGURED)
1267 drvdata->anc_status = ANC_FIR_IIR_CONFIGURED;
1268 else if (drvdata->anc_status != ANC_FIR_IIR_CONFIGURED)
1269 drvdata->anc_status = ANC_IIR_CONFIGURED;
1270 }
1271
1272 status = snd_soc_dapm_disable_pin(&codec->dapm, "ANC Configure Input");
1273 snd_soc_dapm_sync(&codec->dapm);
1274
1275cleanup:
1276 mutex_unlock(&drvdata->anc_lock);
1277
1278 if (status < 0)
1279 dev_err(dev, "%s: Unable to configure ANC! (status = %d)\n",
1280 __func__, status);
1281
1282 dev_dbg(dev, "%s: Exit.\n", __func__);
1283
1284 return (status < 0) ? status : 1;
1285}
1286
1287static int filter_control_info(struct snd_kcontrol *kcontrol,
1288 struct snd_ctl_elem_info *uinfo)
1289{
1290 struct filter_control *fc =
1291 (struct filter_control *)kcontrol->private_value;
1292
1293 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1294 uinfo->count = fc->count;
1295 uinfo->value.integer.min = fc->min;
1296 uinfo->value.integer.max = fc->max;
1297
1298 return 0;
1299}
1300
1301static int filter_control_get(struct snd_kcontrol *kcontrol,
1302 struct snd_ctl_elem_value *ucontrol)
1303{
1304 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1305 struct filter_control *fc =
1306 (struct filter_control *)kcontrol->private_value;
1307 unsigned int i;
1308
1309 mutex_lock(&codec->mutex);
1310 for (i = 0; i < fc->count; i++)
1311 ucontrol->value.integer.value[i] = fc->value[i];
1312 mutex_unlock(&codec->mutex);
1313
1314 return 0;
1315}
1316
1317static int filter_control_put(struct snd_kcontrol *kcontrol,
1318 struct snd_ctl_elem_value *ucontrol)
1319{
1320 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1321 struct filter_control *fc =
1322 (struct filter_control *)kcontrol->private_value;
1323 unsigned int i;
1324
1325 mutex_lock(&codec->mutex);
1326 for (i = 0; i < fc->count; i++)
1327 fc->value[i] = ucontrol->value.integer.value[i];
1328 mutex_unlock(&codec->mutex);
1329
1330 return 0;
1331}
1332
1333/*
1334 * Controls - Non-DAPM ASoC
1335 */
1336
1337static DECLARE_TLV_DB_SCALE(adx_dig_gain_tlv, -3200, 100, 1);
1338/* -32dB = Mute */
1339
1340static DECLARE_TLV_DB_SCALE(dax_dig_gain_tlv, -6300, 100, 1);
1341/* -63dB = Mute */
1342
1343static DECLARE_TLV_DB_SCALE(hs_ear_dig_gain_tlv, -100, 100, 1);
1344/* -1dB = Mute */
1345
1346static const unsigned int hs_gain_tlv[] = {
1347 TLV_DB_RANGE_HEAD(2),
1348 0, 3, TLV_DB_SCALE_ITEM(-3200, 400, 0),
1349 4, 15, TLV_DB_SCALE_ITEM(-1800, 200, 0),
1350};
1351
1352static DECLARE_TLV_DB_SCALE(mic_gain_tlv, 0, 100, 0);
1353
1354static DECLARE_TLV_DB_SCALE(lin_gain_tlv, -1000, 200, 0);
1355
1356static DECLARE_TLV_DB_SCALE(lin2hs_gain_tlv, -3800, 200, 1);
1357/* -38dB = Mute */
1358
1359static const char * const enum_hsfadspeed[] = {"2ms", "0.5ms", "10.6ms",
1360 "5ms"};
1361static SOC_ENUM_SINGLE_DECL(soc_enum_hsfadspeed,
1362 AB8500_DIGMICCONF, AB8500_DIGMICCONF_HSFADSPEED, enum_hsfadspeed);
1363
1364static const char * const enum_envdetthre[] = {
1365 "250mV", "300mV", "350mV", "400mV",
1366 "450mV", "500mV", "550mV", "600mV",
1367 "650mV", "700mV", "750mV", "800mV",
1368 "850mV", "900mV", "950mV", "1.00V" };
1369static SOC_ENUM_SINGLE_DECL(soc_enum_envdeththre,
1370 AB8500_ENVCPCONF, AB8500_ENVCPCONF_ENVDETHTHRE, enum_envdetthre);
1371static SOC_ENUM_SINGLE_DECL(soc_enum_envdetlthre,
1372 AB8500_ENVCPCONF, AB8500_ENVCPCONF_ENVDETLTHRE, enum_envdetthre);
1373static const char * const enum_envdettime[] = {
1374 "26.6us", "53.2us", "106us", "213us",
1375 "426us", "851us", "1.70ms", "3.40ms",
1376 "6.81ms", "13.6ms", "27.2ms", "54.5ms",
1377 "109ms", "218ms", "436ms", "872ms" };
1378static SOC_ENUM_SINGLE_DECL(soc_enum_envdettime,
1379 AB8500_SIGENVCONF, AB8500_SIGENVCONF_ENVDETTIME, enum_envdettime);
1380
1381static const char * const enum_sinc31[] = {"Sinc 3", "Sinc 1"};
1382static SOC_ENUM_SINGLE_DECL(soc_enum_hsesinc, AB8500_HSLEARDIGGAIN,
1383 AB8500_HSLEARDIGGAIN_HSSINC1, enum_sinc31);
1384
1385static const char * const enum_fadespeed[] = {"1ms", "4ms", "8ms", "16ms"};
1386static SOC_ENUM_SINGLE_DECL(soc_enum_fadespeed, AB8500_HSRDIGGAIN,
1387 AB8500_HSRDIGGAIN_FADESPEED, enum_fadespeed);
1388
1389/* Earpiece */
1390
1391static const char * const enum_lowpow[] = {"Normal", "Low Power"};
1392static SOC_ENUM_SINGLE_DECL(soc_enum_eardaclowpow, AB8500_ANACONF1,
1393 AB8500_ANACONF1_EARDACLOWPOW, enum_lowpow);
1394static SOC_ENUM_SINGLE_DECL(soc_enum_eardrvlowpow, AB8500_ANACONF1,
1395 AB8500_ANACONF1_EARDRVLOWPOW, enum_lowpow);
1396
1397static const char * const enum_av_mode[] = {"Audio", "Voice"};
1398static SOC_ENUM_DOUBLE_DECL(soc_enum_ad12voice, AB8500_ADFILTCONF,
1399 AB8500_ADFILTCONF_AD1VOICE, AB8500_ADFILTCONF_AD2VOICE, enum_av_mode);
1400static SOC_ENUM_DOUBLE_DECL(soc_enum_ad34voice, AB8500_ADFILTCONF,
1401 AB8500_ADFILTCONF_AD3VOICE, AB8500_ADFILTCONF_AD4VOICE, enum_av_mode);
1402
1403/* DA */
1404
1405static SOC_ENUM_SINGLE_DECL(soc_enum_da12voice,
1406 AB8500_DASLOTCONF1, AB8500_DASLOTCONF1_DA12VOICE,
1407 enum_av_mode);
1408static SOC_ENUM_SINGLE_DECL(soc_enum_da34voice,
1409 AB8500_DASLOTCONF3, AB8500_DASLOTCONF3_DA34VOICE,
1410 enum_av_mode);
1411static SOC_ENUM_SINGLE_DECL(soc_enum_da56voice,
1412 AB8500_DASLOTCONF5, AB8500_DASLOTCONF5_DA56VOICE,
1413 enum_av_mode);
1414
1415static const char * const enum_da2hslr[] = {"Sidetone", "Audio Path"};
1416static SOC_ENUM_DOUBLE_DECL(soc_enum_da2hslr, AB8500_DIGMULTCONF1,
1417 AB8500_DIGMULTCONF1_DATOHSLEN,
1418 AB8500_DIGMULTCONF1_DATOHSREN, enum_da2hslr);
1419
1420static const char * const enum_sinc53[] = {"Sinc 5", "Sinc 3"};
1421static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic12sinc, AB8500_DMICFILTCONF,
1422 AB8500_DMICFILTCONF_DMIC1SINC3,
1423 AB8500_DMICFILTCONF_DMIC2SINC3, enum_sinc53);
1424static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic34sinc, AB8500_DMICFILTCONF,
1425 AB8500_DMICFILTCONF_DMIC3SINC3,
1426 AB8500_DMICFILTCONF_DMIC4SINC3, enum_sinc53);
1427static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic56sinc, AB8500_DMICFILTCONF,
1428 AB8500_DMICFILTCONF_DMIC5SINC3,
1429 AB8500_DMICFILTCONF_DMIC6SINC3, enum_sinc53);
1430
1431/* Digital interface - DA from slot mapping */
1432static const char * const enum_da_from_slot_map[] = {"SLOT0",
1433 "SLOT1",
1434 "SLOT2",
1435 "SLOT3",
1436 "SLOT4",
1437 "SLOT5",
1438 "SLOT6",
1439 "SLOT7",
1440 "SLOT8",
1441 "SLOT9",
1442 "SLOT10",
1443 "SLOT11",
1444 "SLOT12",
1445 "SLOT13",
1446 "SLOT14",
1447 "SLOT15",
1448 "SLOT16",
1449 "SLOT17",
1450 "SLOT18",
1451 "SLOT19",
1452 "SLOT20",
1453 "SLOT21",
1454 "SLOT22",
1455 "SLOT23",
1456 "SLOT24",
1457 "SLOT25",
1458 "SLOT26",
1459 "SLOT27",
1460 "SLOT28",
1461 "SLOT29",
1462 "SLOT30",
1463 "SLOT31"};
1464static SOC_ENUM_SINGLE_DECL(soc_enum_da1slotmap,
1465 AB8500_DASLOTCONF1, AB8500_DASLOTCONFX_SLTODAX_SHIFT,
1466 enum_da_from_slot_map);
1467static SOC_ENUM_SINGLE_DECL(soc_enum_da2slotmap,
1468 AB8500_DASLOTCONF2, AB8500_DASLOTCONFX_SLTODAX_SHIFT,
1469 enum_da_from_slot_map);
1470static SOC_ENUM_SINGLE_DECL(soc_enum_da3slotmap,
1471 AB8500_DASLOTCONF3, AB8500_DASLOTCONFX_SLTODAX_SHIFT,
1472 enum_da_from_slot_map);
1473static SOC_ENUM_SINGLE_DECL(soc_enum_da4slotmap,
1474 AB8500_DASLOTCONF4, AB8500_DASLOTCONFX_SLTODAX_SHIFT,
1475 enum_da_from_slot_map);
1476static SOC_ENUM_SINGLE_DECL(soc_enum_da5slotmap,
1477 AB8500_DASLOTCONF5, AB8500_DASLOTCONFX_SLTODAX_SHIFT,
1478 enum_da_from_slot_map);
1479static SOC_ENUM_SINGLE_DECL(soc_enum_da6slotmap,
1480 AB8500_DASLOTCONF6, AB8500_DASLOTCONFX_SLTODAX_SHIFT,
1481 enum_da_from_slot_map);
1482static SOC_ENUM_SINGLE_DECL(soc_enum_da7slotmap,
1483 AB8500_DASLOTCONF7, AB8500_DASLOTCONFX_SLTODAX_SHIFT,
1484 enum_da_from_slot_map);
1485static SOC_ENUM_SINGLE_DECL(soc_enum_da8slotmap,
1486 AB8500_DASLOTCONF8, AB8500_DASLOTCONFX_SLTODAX_SHIFT,
1487 enum_da_from_slot_map);
1488
1489/* Digital interface - AD to slot mapping */
1490static const char * const enum_ad_to_slot_map[] = {"AD_OUT1",
1491 "AD_OUT2",
1492 "AD_OUT3",
1493 "AD_OUT4",
1494 "AD_OUT5",
1495 "AD_OUT6",
1496 "AD_OUT7",
1497 "AD_OUT8",
1498 "zeroes",
1499 "tristate"};
1500static SOC_ENUM_SINGLE_DECL(soc_enum_adslot0map,
1501 AB8500_ADSLOTSEL1, AB8500_ADSLOTSELX_EVEN_SHIFT,
1502 enum_ad_to_slot_map);
1503static SOC_ENUM_SINGLE_DECL(soc_enum_adslot1map,
1504 AB8500_ADSLOTSEL1, AB8500_ADSLOTSELX_ODD_SHIFT,
1505 enum_ad_to_slot_map);
1506static SOC_ENUM_SINGLE_DECL(soc_enum_adslot2map,
1507 AB8500_ADSLOTSEL2, AB8500_ADSLOTSELX_EVEN_SHIFT,
1508 enum_ad_to_slot_map);
1509static SOC_ENUM_SINGLE_DECL(soc_enum_adslot3map,
1510 AB8500_ADSLOTSEL2, AB8500_ADSLOTSELX_ODD_SHIFT,
1511 enum_ad_to_slot_map);
1512static SOC_ENUM_SINGLE_DECL(soc_enum_adslot4map,
1513 AB8500_ADSLOTSEL3, AB8500_ADSLOTSELX_EVEN_SHIFT,
1514 enum_ad_to_slot_map);
1515static SOC_ENUM_SINGLE_DECL(soc_enum_adslot5map,
1516 AB8500_ADSLOTSEL3, AB8500_ADSLOTSELX_ODD_SHIFT,
1517 enum_ad_to_slot_map);
1518static SOC_ENUM_SINGLE_DECL(soc_enum_adslot6map,
1519 AB8500_ADSLOTSEL4, AB8500_ADSLOTSELX_EVEN_SHIFT,
1520 enum_ad_to_slot_map);
1521static SOC_ENUM_SINGLE_DECL(soc_enum_adslot7map,
1522 AB8500_ADSLOTSEL4, AB8500_ADSLOTSELX_ODD_SHIFT,
1523 enum_ad_to_slot_map);
1524static SOC_ENUM_SINGLE_DECL(soc_enum_adslot8map,
1525 AB8500_ADSLOTSEL5, AB8500_ADSLOTSELX_EVEN_SHIFT,
1526 enum_ad_to_slot_map);
1527static SOC_ENUM_SINGLE_DECL(soc_enum_adslot9map,
1528 AB8500_ADSLOTSEL5, AB8500_ADSLOTSELX_ODD_SHIFT,
1529 enum_ad_to_slot_map);
1530static SOC_ENUM_SINGLE_DECL(soc_enum_adslot10map,
1531 AB8500_ADSLOTSEL6, AB8500_ADSLOTSELX_EVEN_SHIFT,
1532 enum_ad_to_slot_map);
1533static SOC_ENUM_SINGLE_DECL(soc_enum_adslot11map,
1534 AB8500_ADSLOTSEL6, AB8500_ADSLOTSELX_ODD_SHIFT,
1535 enum_ad_to_slot_map);
1536static SOC_ENUM_SINGLE_DECL(soc_enum_adslot12map,
1537 AB8500_ADSLOTSEL7, AB8500_ADSLOTSELX_EVEN_SHIFT,
1538 enum_ad_to_slot_map);
1539static SOC_ENUM_SINGLE_DECL(soc_enum_adslot13map,
1540 AB8500_ADSLOTSEL7, AB8500_ADSLOTSELX_ODD_SHIFT,
1541 enum_ad_to_slot_map);
1542static SOC_ENUM_SINGLE_DECL(soc_enum_adslot14map,
1543 AB8500_ADSLOTSEL8, AB8500_ADSLOTSELX_EVEN_SHIFT,
1544 enum_ad_to_slot_map);
1545static SOC_ENUM_SINGLE_DECL(soc_enum_adslot15map,
1546 AB8500_ADSLOTSEL8, AB8500_ADSLOTSELX_ODD_SHIFT,
1547 enum_ad_to_slot_map);
1548static SOC_ENUM_SINGLE_DECL(soc_enum_adslot16map,
1549 AB8500_ADSLOTSEL9, AB8500_ADSLOTSELX_EVEN_SHIFT,
1550 enum_ad_to_slot_map);
1551static SOC_ENUM_SINGLE_DECL(soc_enum_adslot17map,
1552 AB8500_ADSLOTSEL9, AB8500_ADSLOTSELX_ODD_SHIFT,
1553 enum_ad_to_slot_map);
1554static SOC_ENUM_SINGLE_DECL(soc_enum_adslot18map,
1555 AB8500_ADSLOTSEL10, AB8500_ADSLOTSELX_EVEN_SHIFT,
1556 enum_ad_to_slot_map);
1557static SOC_ENUM_SINGLE_DECL(soc_enum_adslot19map,
1558 AB8500_ADSLOTSEL10, AB8500_ADSLOTSELX_ODD_SHIFT,
1559 enum_ad_to_slot_map);
1560static SOC_ENUM_SINGLE_DECL(soc_enum_adslot20map,
1561 AB8500_ADSLOTSEL11, AB8500_ADSLOTSELX_EVEN_SHIFT,
1562 enum_ad_to_slot_map);
1563static SOC_ENUM_SINGLE_DECL(soc_enum_adslot21map,
1564 AB8500_ADSLOTSEL11, AB8500_ADSLOTSELX_ODD_SHIFT,
1565 enum_ad_to_slot_map);
1566static SOC_ENUM_SINGLE_DECL(soc_enum_adslot22map,
1567 AB8500_ADSLOTSEL12, AB8500_ADSLOTSELX_EVEN_SHIFT,
1568 enum_ad_to_slot_map);
1569static SOC_ENUM_SINGLE_DECL(soc_enum_adslot23map,
1570 AB8500_ADSLOTSEL12, AB8500_ADSLOTSELX_ODD_SHIFT,
1571 enum_ad_to_slot_map);
1572static SOC_ENUM_SINGLE_DECL(soc_enum_adslot24map,
1573 AB8500_ADSLOTSEL13, AB8500_ADSLOTSELX_EVEN_SHIFT,
1574 enum_ad_to_slot_map);
1575static SOC_ENUM_SINGLE_DECL(soc_enum_adslot25map,
1576 AB8500_ADSLOTSEL13, AB8500_ADSLOTSELX_ODD_SHIFT,
1577 enum_ad_to_slot_map);
1578static SOC_ENUM_SINGLE_DECL(soc_enum_adslot26map,
1579 AB8500_ADSLOTSEL14, AB8500_ADSLOTSELX_EVEN_SHIFT,
1580 enum_ad_to_slot_map);
1581static SOC_ENUM_SINGLE_DECL(soc_enum_adslot27map,
1582 AB8500_ADSLOTSEL14, AB8500_ADSLOTSELX_ODD_SHIFT,
1583 enum_ad_to_slot_map);
1584static SOC_ENUM_SINGLE_DECL(soc_enum_adslot28map,
1585 AB8500_ADSLOTSEL15, AB8500_ADSLOTSELX_EVEN_SHIFT,
1586 enum_ad_to_slot_map);
1587static SOC_ENUM_SINGLE_DECL(soc_enum_adslot29map,
1588 AB8500_ADSLOTSEL15, AB8500_ADSLOTSELX_ODD_SHIFT,
1589 enum_ad_to_slot_map);
1590static SOC_ENUM_SINGLE_DECL(soc_enum_adslot30map,
1591 AB8500_ADSLOTSEL16, AB8500_ADSLOTSELX_EVEN_SHIFT,
1592 enum_ad_to_slot_map);
1593static SOC_ENUM_SINGLE_DECL(soc_enum_adslot31map,
1594 AB8500_ADSLOTSEL16, AB8500_ADSLOTSELX_ODD_SHIFT,
1595 enum_ad_to_slot_map);
1596
1597/* Digital interface - Burst mode */
1598static const char * const enum_mask[] = {"Unmasked", "Masked"};
1599static SOC_ENUM_SINGLE_DECL(soc_enum_bfifomask,
1600 AB8500_FIFOCONF1, AB8500_FIFOCONF1_BFIFOMASK,
1601 enum_mask);
1602static const char * const enum_bitclk0[] = {"19_2_MHz", "38_4_MHz"};
1603static SOC_ENUM_SINGLE_DECL(soc_enum_bfifo19m2,
1604 AB8500_FIFOCONF1, AB8500_FIFOCONF1_BFIFO19M2,
1605 enum_bitclk0);
1606static const char * const enum_slavemaster[] = {"Slave", "Master"};
1607static SOC_ENUM_SINGLE_DECL(soc_enum_bfifomast,
1608 AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFOMAST_SHIFT,
1609 enum_slavemaster);
1610
1611/* Sidetone */
1612static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_sidstate, enum_sid_state);
1613
1614/* ANC */
1615static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_ancstate, enum_anc_state);
1616
1617static struct snd_kcontrol_new ab8500_ctrls[] = {
1618 /* Charge pump */
1619 SOC_ENUM("Charge Pump High Threshold For Low Voltage",
1620 soc_enum_envdeththre),
1621 SOC_ENUM("Charge Pump Low Threshold For Low Voltage",
1622 soc_enum_envdetlthre),
1623 SOC_SINGLE("Charge Pump Envelope Detection Switch",
1624 AB8500_SIGENVCONF, AB8500_SIGENVCONF_ENVDETCPEN,
1625 1, 0),
1626 SOC_ENUM("Charge Pump Envelope Detection Decay Time",
1627 soc_enum_envdettime),
1628
1629 /* Headset */
1630 SOC_ENUM("Headset Mode", soc_enum_da12voice),
1631 SOC_SINGLE("Headset High Pass Switch",
1632 AB8500_ANACONF1, AB8500_ANACONF1_HSHPEN,
1633 1, 0),
1634 SOC_SINGLE("Headset Low Power Switch",
1635 AB8500_ANACONF1, AB8500_ANACONF1_HSLOWPOW,
1636 1, 0),
1637 SOC_SINGLE("Headset DAC Low Power Switch",
1638 AB8500_ANACONF1, AB8500_ANACONF1_DACLOWPOW1,
1639 1, 0),
1640 SOC_SINGLE("Headset DAC Drv Low Power Switch",
1641 AB8500_ANACONF1, AB8500_ANACONF1_DACLOWPOW0,
1642 1, 0),
1643 SOC_ENUM("Headset Fade Speed", soc_enum_hsfadspeed),
1644 SOC_ENUM("Headset Source", soc_enum_da2hslr),
1645 SOC_ENUM("Headset Filter", soc_enum_hsesinc),
1646 SOC_DOUBLE_R_TLV("Headset Master Volume",
1647 AB8500_DADIGGAIN1, AB8500_DADIGGAIN2,
1648 0, AB8500_DADIGGAINX_DAXGAIN_MAX, 1, dax_dig_gain_tlv),
1649 SOC_DOUBLE_R_TLV("Headset Digital Volume",
1650 AB8500_HSLEARDIGGAIN, AB8500_HSRDIGGAIN,
1651 0, AB8500_HSLEARDIGGAIN_HSLDGAIN_MAX, 1, hs_ear_dig_gain_tlv),
1652 SOC_DOUBLE_TLV("Headset Volume",
1653 AB8500_ANAGAIN3,
1654 AB8500_ANAGAIN3_HSLGAIN, AB8500_ANAGAIN3_HSRGAIN,
1655 AB8500_ANAGAIN3_HSXGAIN_MAX, 1, hs_gain_tlv),
1656
1657 /* Earpiece */
1658 SOC_ENUM("Earpiece DAC Mode",
1659 soc_enum_eardaclowpow),
1660 SOC_ENUM("Earpiece DAC Drv Mode",
1661 soc_enum_eardrvlowpow),
1662
1663 /* HandsFree */
1664 SOC_ENUM("HF Mode", soc_enum_da34voice),
1665 SOC_SINGLE("HF and Headset Swap Switch",
1666 AB8500_DASLOTCONF1, AB8500_DASLOTCONF1_SWAPDA12_34,
1667 1, 0),
1668 SOC_DOUBLE("HF Low EMI Mode Switch",
1669 AB8500_CLASSDCONF1,
1670 AB8500_CLASSDCONF1_HFLSWAPEN, AB8500_CLASSDCONF1_HFRSWAPEN,
1671 1, 0),
1672 SOC_DOUBLE("HF FIR Bypass Switch",
1673 AB8500_CLASSDCONF2,
1674 AB8500_CLASSDCONF2_FIRBYP0, AB8500_CLASSDCONF2_FIRBYP1,
1675 1, 0),
1676 SOC_DOUBLE("HF High Volume Switch",
1677 AB8500_CLASSDCONF2,
1678 AB8500_CLASSDCONF2_HIGHVOLEN0, AB8500_CLASSDCONF2_HIGHVOLEN1,
1679 1, 0),
1680 SOC_SINGLE("HF L and R Bridge Switch",
1681 AB8500_CLASSDCONF1, AB8500_CLASSDCONF1_PARLHF,
1682 1, 0),
1683 SOC_DOUBLE_R_TLV("HF Master Volume",
1684 AB8500_DADIGGAIN3, AB8500_DADIGGAIN4,
1685 0, AB8500_DADIGGAINX_DAXGAIN_MAX, 1, dax_dig_gain_tlv),
1686
1687 /* Vibra */
1688 SOC_DOUBLE("Vibra High Volume Switch",
1689 AB8500_CLASSDCONF2,
1690 AB8500_CLASSDCONF2_HIGHVOLEN2, AB8500_CLASSDCONF2_HIGHVOLEN3,
1691 1, 0),
1692 SOC_DOUBLE("Vibra Low EMI Mode Switch",
1693 AB8500_CLASSDCONF1,
1694 AB8500_CLASSDCONF1_VIB1SWAPEN, AB8500_CLASSDCONF1_VIB2SWAPEN,
1695 1, 0),
1696 SOC_DOUBLE("Vibra FIR Bypass Switch",
1697 AB8500_CLASSDCONF2,
1698 AB8500_CLASSDCONF2_FIRBYP2, AB8500_CLASSDCONF2_FIRBYP3,
1699 1, 0),
1700 SOC_ENUM("Vibra Mode", soc_enum_da56voice),
1701 SOC_DOUBLE_R("Vibra PWM Duty Cycle N",
1702 AB8500_PWMGENCONF3, AB8500_PWMGENCONF5,
1703 AB8500_PWMGENCONFX_PWMVIBXDUTCYC,
1704 AB8500_PWMGENCONFX_PWMVIBXDUTCYC_MAX, 0),
1705 SOC_DOUBLE_R("Vibra PWM Duty Cycle P",
1706 AB8500_PWMGENCONF2, AB8500_PWMGENCONF4,
1707 AB8500_PWMGENCONFX_PWMVIBXDUTCYC,
1708 AB8500_PWMGENCONFX_PWMVIBXDUTCYC_MAX, 0),
1709 SOC_SINGLE("Vibra 1 and 2 Bridge Switch",
1710 AB8500_CLASSDCONF1, AB8500_CLASSDCONF1_PARLVIB,
1711 1, 0),
1712 SOC_DOUBLE_R_TLV("Vibra Master Volume",
1713 AB8500_DADIGGAIN5, AB8500_DADIGGAIN6,
1714 0, AB8500_DADIGGAINX_DAXGAIN_MAX, 1, dax_dig_gain_tlv),
1715
1716 /* HandsFree, Vibra */
1717 SOC_SINGLE("ClassD High Pass Volume",
1718 AB8500_CLASSDCONF3, AB8500_CLASSDCONF3_DITHHPGAIN,
1719 AB8500_CLASSDCONF3_DITHHPGAIN_MAX, 0),
1720 SOC_SINGLE("ClassD White Volume",
1721 AB8500_CLASSDCONF3, AB8500_CLASSDCONF3_DITHWGAIN,
1722 AB8500_CLASSDCONF3_DITHWGAIN_MAX, 0),
1723
1724 /* Mic 1, Mic 2, LineIn */
1725 SOC_DOUBLE_R_TLV("Mic Master Volume",
1726 AB8500_ADDIGGAIN3, AB8500_ADDIGGAIN4,
1727 0, AB8500_ADDIGGAINX_ADXGAIN_MAX, 1, adx_dig_gain_tlv),
1728
1729 /* Mic 1 */
1730 SOC_SINGLE_TLV("Mic 1",
1731 AB8500_ANAGAIN1,
1732 AB8500_ANAGAINX_MICXGAIN,
1733 AB8500_ANAGAINX_MICXGAIN_MAX, 0, mic_gain_tlv),
1734 SOC_SINGLE("Mic 1 Low Power Switch",
1735 AB8500_ANAGAIN1, AB8500_ANAGAINX_LOWPOWMICX,
1736 1, 0),
1737
1738 /* Mic 2 */
1739 SOC_DOUBLE("Mic High Pass Switch",
1740 AB8500_ADFILTCONF,
1741 AB8500_ADFILTCONF_AD3NH, AB8500_ADFILTCONF_AD4NH,
1742 1, 1),
1743 SOC_ENUM("Mic Mode", soc_enum_ad34voice),
1744 SOC_ENUM("Mic Filter", soc_enum_dmic34sinc),
1745 SOC_SINGLE_TLV("Mic 2",
1746 AB8500_ANAGAIN2,
1747 AB8500_ANAGAINX_MICXGAIN,
1748 AB8500_ANAGAINX_MICXGAIN_MAX, 0, mic_gain_tlv),
1749 SOC_SINGLE("Mic 2 Low Power Switch",
1750 AB8500_ANAGAIN2, AB8500_ANAGAINX_LOWPOWMICX,
1751 1, 0),
1752
1753 /* LineIn */
1754 SOC_DOUBLE("LineIn High Pass Switch",
1755 AB8500_ADFILTCONF,
1756 AB8500_ADFILTCONF_AD1NH, AB8500_ADFILTCONF_AD2NH,
1757 1, 1),
1758 SOC_ENUM("LineIn Filter", soc_enum_dmic12sinc),
1759 SOC_ENUM("LineIn Mode", soc_enum_ad12voice),
1760 SOC_DOUBLE_R_TLV("LineIn Master Volume",
1761 AB8500_ADDIGGAIN1, AB8500_ADDIGGAIN2,
1762 0, AB8500_ADDIGGAINX_ADXGAIN_MAX, 1, adx_dig_gain_tlv),
1763 SOC_DOUBLE_TLV("LineIn",
1764 AB8500_ANAGAIN4,
1765 AB8500_ANAGAIN4_LINLGAIN, AB8500_ANAGAIN4_LINRGAIN,
1766 AB8500_ANAGAIN4_LINXGAIN_MAX, 0, lin_gain_tlv),
1767 SOC_DOUBLE_R_TLV("LineIn to Headset Volume",
1768 AB8500_DIGLINHSLGAIN, AB8500_DIGLINHSRGAIN,
1769 AB8500_DIGLINHSXGAIN_LINTOHSXGAIN,
1770 AB8500_DIGLINHSXGAIN_LINTOHSXGAIN_MAX,
1771 1, lin2hs_gain_tlv),
1772
1773 /* DMic */
1774 SOC_ENUM("DMic Filter", soc_enum_dmic56sinc),
1775 SOC_DOUBLE_R_TLV("DMic Master Volume",
1776 AB8500_ADDIGGAIN5, AB8500_ADDIGGAIN6,
1777 0, AB8500_ADDIGGAINX_ADXGAIN_MAX, 1, adx_dig_gain_tlv),
1778
1779 /* Digital gains */
1780 SOC_ENUM("Digital Gain Fade Speed", soc_enum_fadespeed),
1781
1782 /* Analog loopback */
1783 SOC_DOUBLE_R_TLV("Analog Loopback Volume",
1784 AB8500_ADDIGLOOPGAIN1, AB8500_ADDIGLOOPGAIN2,
1785 0, AB8500_ADDIGLOOPGAINX_ADXLBGAIN_MAX, 1, dax_dig_gain_tlv),
1786
1787 /* Digital interface - DA from slot mapping */
1788 SOC_ENUM("Digital Interface DA 1 From Slot Map", soc_enum_da1slotmap),
1789 SOC_ENUM("Digital Interface DA 2 From Slot Map", soc_enum_da2slotmap),
1790 SOC_ENUM("Digital Interface DA 3 From Slot Map", soc_enum_da3slotmap),
1791 SOC_ENUM("Digital Interface DA 4 From Slot Map", soc_enum_da4slotmap),
1792 SOC_ENUM("Digital Interface DA 5 From Slot Map", soc_enum_da5slotmap),
1793 SOC_ENUM("Digital Interface DA 6 From Slot Map", soc_enum_da6slotmap),
1794 SOC_ENUM("Digital Interface DA 7 From Slot Map", soc_enum_da7slotmap),
1795 SOC_ENUM("Digital Interface DA 8 From Slot Map", soc_enum_da8slotmap),
1796
1797 /* Digital interface - AD to slot mapping */
1798 SOC_ENUM("Digital Interface AD To Slot 0 Map", soc_enum_adslot0map),
1799 SOC_ENUM("Digital Interface AD To Slot 1 Map", soc_enum_adslot1map),
1800 SOC_ENUM("Digital Interface AD To Slot 2 Map", soc_enum_adslot2map),
1801 SOC_ENUM("Digital Interface AD To Slot 3 Map", soc_enum_adslot3map),
1802 SOC_ENUM("Digital Interface AD To Slot 4 Map", soc_enum_adslot4map),
1803 SOC_ENUM("Digital Interface AD To Slot 5 Map", soc_enum_adslot5map),
1804 SOC_ENUM("Digital Interface AD To Slot 6 Map", soc_enum_adslot6map),
1805 SOC_ENUM("Digital Interface AD To Slot 7 Map", soc_enum_adslot7map),
1806 SOC_ENUM("Digital Interface AD To Slot 8 Map", soc_enum_adslot8map),
1807 SOC_ENUM("Digital Interface AD To Slot 9 Map", soc_enum_adslot9map),
1808 SOC_ENUM("Digital Interface AD To Slot 10 Map", soc_enum_adslot10map),
1809 SOC_ENUM("Digital Interface AD To Slot 11 Map", soc_enum_adslot11map),
1810 SOC_ENUM("Digital Interface AD To Slot 12 Map", soc_enum_adslot12map),
1811 SOC_ENUM("Digital Interface AD To Slot 13 Map", soc_enum_adslot13map),
1812 SOC_ENUM("Digital Interface AD To Slot 14 Map", soc_enum_adslot14map),
1813 SOC_ENUM("Digital Interface AD To Slot 15 Map", soc_enum_adslot15map),
1814 SOC_ENUM("Digital Interface AD To Slot 16 Map", soc_enum_adslot16map),
1815 SOC_ENUM("Digital Interface AD To Slot 17 Map", soc_enum_adslot17map),
1816 SOC_ENUM("Digital Interface AD To Slot 18 Map", soc_enum_adslot18map),
1817 SOC_ENUM("Digital Interface AD To Slot 19 Map", soc_enum_adslot19map),
1818 SOC_ENUM("Digital Interface AD To Slot 20 Map", soc_enum_adslot20map),
1819 SOC_ENUM("Digital Interface AD To Slot 21 Map", soc_enum_adslot21map),
1820 SOC_ENUM("Digital Interface AD To Slot 22 Map", soc_enum_adslot22map),
1821 SOC_ENUM("Digital Interface AD To Slot 23 Map", soc_enum_adslot23map),
1822 SOC_ENUM("Digital Interface AD To Slot 24 Map", soc_enum_adslot24map),
1823 SOC_ENUM("Digital Interface AD To Slot 25 Map", soc_enum_adslot25map),
1824 SOC_ENUM("Digital Interface AD To Slot 26 Map", soc_enum_adslot26map),
1825 SOC_ENUM("Digital Interface AD To Slot 27 Map", soc_enum_adslot27map),
1826 SOC_ENUM("Digital Interface AD To Slot 28 Map", soc_enum_adslot28map),
1827 SOC_ENUM("Digital Interface AD To Slot 29 Map", soc_enum_adslot29map),
1828 SOC_ENUM("Digital Interface AD To Slot 30 Map", soc_enum_adslot30map),
1829 SOC_ENUM("Digital Interface AD To Slot 31 Map", soc_enum_adslot31map),
1830
1831 /* Digital interface - Loopback */
1832 SOC_SINGLE("Digital Interface AD 1 Loopback Switch",
1833 AB8500_DASLOTCONF1, AB8500_DASLOTCONF1_DAI7TOADO1,
1834 1, 0),
1835 SOC_SINGLE("Digital Interface AD 2 Loopback Switch",
1836 AB8500_DASLOTCONF2, AB8500_DASLOTCONF2_DAI8TOADO2,
1837 1, 0),
1838 SOC_SINGLE("Digital Interface AD 3 Loopback Switch",
1839 AB8500_DASLOTCONF3, AB8500_DASLOTCONF3_DAI7TOADO3,
1840 1, 0),
1841 SOC_SINGLE("Digital Interface AD 4 Loopback Switch",
1842 AB8500_DASLOTCONF4, AB8500_DASLOTCONF4_DAI8TOADO4,
1843 1, 0),
1844 SOC_SINGLE("Digital Interface AD 5 Loopback Switch",
1845 AB8500_DASLOTCONF5, AB8500_DASLOTCONF5_DAI7TOADO5,
1846 1, 0),
1847 SOC_SINGLE("Digital Interface AD 6 Loopback Switch",
1848 AB8500_DASLOTCONF6, AB8500_DASLOTCONF6_DAI8TOADO6,
1849 1, 0),
1850 SOC_SINGLE("Digital Interface AD 7 Loopback Switch",
1851 AB8500_DASLOTCONF7, AB8500_DASLOTCONF7_DAI8TOADO7,
1852 1, 0),
1853 SOC_SINGLE("Digital Interface AD 8 Loopback Switch",
1854 AB8500_DASLOTCONF8, AB8500_DASLOTCONF8_DAI7TOADO8,
1855 1, 0),
1856
1857 /* Digital interface - Burst FIFO */
1858 SOC_SINGLE("Digital Interface 0 FIFO Enable Switch",
1859 AB8500_DIGIFCONF3, AB8500_DIGIFCONF3_IF0BFIFOEN,
1860 1, 0),
1861 SOC_ENUM("Burst FIFO Mask", soc_enum_bfifomask),
1862 SOC_ENUM("Burst FIFO Bit-clock Frequency", soc_enum_bfifo19m2),
1863 SOC_SINGLE("Burst FIFO Threshold",
1864 AB8500_FIFOCONF1, AB8500_FIFOCONF1_BFIFOINT_SHIFT,
1865 AB8500_FIFOCONF1_BFIFOINT_MAX, 0),
1866 SOC_SINGLE("Burst FIFO Length",
1867 AB8500_FIFOCONF2, AB8500_FIFOCONF2_BFIFOTX_SHIFT,
1868 AB8500_FIFOCONF2_BFIFOTX_MAX, 0),
1869 SOC_SINGLE("Burst FIFO EOS Extra Slots",
1870 AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFOEXSL_SHIFT,
1871 AB8500_FIFOCONF3_BFIFOEXSL_MAX, 0),
1872 SOC_SINGLE("Burst FIFO FS Extra Bit-clocks",
1873 AB8500_FIFOCONF3, AB8500_FIFOCONF3_PREBITCLK0_SHIFT,
1874 AB8500_FIFOCONF3_PREBITCLK0_MAX, 0),
1875 SOC_ENUM("Burst FIFO Interface Mode", soc_enum_bfifomast),
1876
1877 SOC_SINGLE("Burst FIFO Interface Switch",
1878 AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFORUN_SHIFT,
1879 1, 0),
1880 SOC_SINGLE("Burst FIFO Switch Frame Number",
1881 AB8500_FIFOCONF4, AB8500_FIFOCONF4_BFIFOFRAMSW_SHIFT,
1882 AB8500_FIFOCONF4_BFIFOFRAMSW_MAX, 0),
1883 SOC_SINGLE("Burst FIFO Wake Up Delay",
1884 AB8500_FIFOCONF5, AB8500_FIFOCONF5_BFIFOWAKEUP_SHIFT,
1885 AB8500_FIFOCONF5_BFIFOWAKEUP_MAX, 0),
1886 SOC_SINGLE("Burst FIFO Samples In FIFO",
1887 AB8500_FIFOCONF6, AB8500_FIFOCONF6_BFIFOSAMPLE_SHIFT,
1888 AB8500_FIFOCONF6_BFIFOSAMPLE_MAX, 0),
1889
1890 /* ANC */
1891 SOC_ENUM_EXT("ANC Status", soc_enum_ancstate,
1892 anc_status_control_get, anc_status_control_put),
1893 SOC_SINGLE_XR_SX("ANC Warp Delay Shift",
1894 AB8500_ANCCONF2, 1, AB8500_ANCCONF2_SHIFT,
1895 AB8500_ANCCONF2_MIN, AB8500_ANCCONF2_MAX, 0),
1896 SOC_SINGLE_XR_SX("ANC FIR Output Shift",
1897 AB8500_ANCCONF3, 1, AB8500_ANCCONF3_SHIFT,
1898 AB8500_ANCCONF3_MIN, AB8500_ANCCONF3_MAX, 0),
1899 SOC_SINGLE_XR_SX("ANC IIR Output Shift",
1900 AB8500_ANCCONF4, 1, AB8500_ANCCONF4_SHIFT,
1901 AB8500_ANCCONF4_MIN, AB8500_ANCCONF4_MAX, 0),
1902 SOC_SINGLE_XR_SX("ANC Warp Delay",
1903 AB8500_ANCCONF9, 2, AB8500_ANC_WARP_DELAY_SHIFT,
1904 AB8500_ANC_WARP_DELAY_MIN, AB8500_ANC_WARP_DELAY_MAX, 0),
1905
1906 /* Sidetone */
1907 SOC_ENUM_EXT("Sidetone Status", soc_enum_sidstate,
1908 sid_status_control_get, sid_status_control_put),
1909 SOC_SINGLE_STROBE("Sidetone Reset",
1910 AB8500_SIDFIRADR, AB8500_SIDFIRADR_FIRSIDSET, 0),
1911};
1912
1913static struct snd_kcontrol_new ab8500_filter_controls[] = {
1914 AB8500_FILTER_CONTROL("ANC FIR Coefficients", AB8500_ANC_FIR_COEFFS,
1915 AB8500_ANC_FIR_COEFF_MIN, AB8500_ANC_FIR_COEFF_MAX),
1916 AB8500_FILTER_CONTROL("ANC IIR Coefficients", AB8500_ANC_IIR_COEFFS,
1917 AB8500_ANC_IIR_COEFF_MIN, AB8500_ANC_IIR_COEFF_MAX),
1918 AB8500_FILTER_CONTROL("Sidetone FIR Coefficients",
1919 AB8500_SID_FIR_COEFFS, AB8500_SID_FIR_COEFF_MIN,
1920 AB8500_SID_FIR_COEFF_MAX)
1921};
1922enum ab8500_filter {
1923 AB8500_FILTER_ANC_FIR = 0,
1924 AB8500_FILTER_ANC_IIR = 1,
1925 AB8500_FILTER_SID_FIR = 2,
1926};
1927
1928/*
1929 * Extended interface for codec-driver
1930 */
1931
1932static int ab8500_audio_init_audioblock(struct snd_soc_codec *codec)
1933{
1934 int status;
1935
1936 dev_dbg(codec->dev, "%s: Enter.\n", __func__);
1937
1938 /* Reset audio-registers and disable 32kHz-clock output 2 */
1939 status = ab8500_sysctrl_write(AB8500_STW4500CTRL3,
1940 AB8500_STW4500CTRL3_CLK32KOUT2DIS |
1941 AB8500_STW4500CTRL3_RESETAUDN,
1942 AB8500_STW4500CTRL3_RESETAUDN);
1943 if (status < 0)
1944 return status;
1945
1946 return 0;
1947}
1948
1949static int ab8500_audio_setup_mics(struct snd_soc_codec *codec,
1950 struct amic_settings *amics)
1951{
1952 u8 value8;
1953 unsigned int value;
1954 int status;
1955 const struct snd_soc_dapm_route *route;
1956
1957 dev_dbg(codec->dev, "%s: Enter.\n", __func__);
1958
1959 /* Set DMic-clocks to outputs */
1960 status = abx500_get_register_interruptible(codec->dev, (u8)AB8500_MISC,
1961 (u8)AB8500_GPIO_DIR4_REG,
1962 &value8);
1963 if (status < 0)
1964 return status;
1965 value = value8 | GPIO27_DIR_OUTPUT | GPIO29_DIR_OUTPUT |
1966 GPIO31_DIR_OUTPUT;
1967 status = abx500_set_register_interruptible(codec->dev,
1968 (u8)AB8500_MISC,
1969 (u8)AB8500_GPIO_DIR4_REG,
1970 value);
1971 if (status < 0)
1972 return status;
1973
1974 /* Attach regulators to AMic DAPM-paths */
1975 dev_dbg(codec->dev, "%s: Mic 1a regulator: %s\n", __func__,
1976 amic_micbias_str(amics->mic1a_micbias));
1977 route = &ab8500_dapm_routes_mic1a_vamicx[amics->mic1a_micbias];
1978 status = snd_soc_dapm_add_routes(&codec->dapm, route, 1);
1979 dev_dbg(codec->dev, "%s: Mic 1b regulator: %s\n", __func__,
1980 amic_micbias_str(amics->mic1b_micbias));
1981 route = &ab8500_dapm_routes_mic1b_vamicx[amics->mic1b_micbias];
1982 status |= snd_soc_dapm_add_routes(&codec->dapm, route, 1);
1983 dev_dbg(codec->dev, "%s: Mic 2 regulator: %s\n", __func__,
1984 amic_micbias_str(amics->mic2_micbias));
1985 route = &ab8500_dapm_routes_mic2_vamicx[amics->mic2_micbias];
1986 status |= snd_soc_dapm_add_routes(&codec->dapm, route, 1);
1987 if (status < 0) {
1988 dev_err(codec->dev,
1989 "%s: Failed to add AMic-regulator DAPM-routes (%d).\n",
1990 __func__, status);
1991 return status;
1992 }
1993
1994 /* Set AMic-configuration */
1995 dev_dbg(codec->dev, "%s: Mic 1 mic-type: %s\n", __func__,
1996 amic_type_str(amics->mic1_type));
1997 snd_soc_update_bits(codec, AB8500_ANAGAIN1, AB8500_ANAGAINX_ENSEMICX,
1998 amics->mic1_type == AMIC_TYPE_DIFFERENTIAL ?
1999 0 : AB8500_ANAGAINX_ENSEMICX);
2000 dev_dbg(codec->dev, "%s: Mic 2 mic-type: %s\n", __func__,
2001 amic_type_str(amics->mic2_type));
2002 snd_soc_update_bits(codec, AB8500_ANAGAIN2, AB8500_ANAGAINX_ENSEMICX,
2003 amics->mic2_type == AMIC_TYPE_DIFFERENTIAL ?
2004 0 : AB8500_ANAGAINX_ENSEMICX);
2005
2006 return 0;
2007}
2008EXPORT_SYMBOL_GPL(ab8500_audio_setup_mics);
2009
2010static int ab8500_audio_set_ear_cmv(struct snd_soc_codec *codec,
2011 enum ear_cm_voltage ear_cmv)
2012{
2013 char *cmv_str;
2014
2015 switch (ear_cmv) {
2016 case EAR_CMV_0_95V:
2017 cmv_str = "0.95V";
2018 break;
2019 case EAR_CMV_1_10V:
2020 cmv_str = "1.10V";
2021 break;
2022 case EAR_CMV_1_27V:
2023 cmv_str = "1.27V";
2024 break;
2025 case EAR_CMV_1_58V:
2026 cmv_str = "1.58V";
2027 break;
2028 default:
2029 dev_err(codec->dev,
2030 "%s: Unknown earpiece CM-voltage (%d)!\n",
2031 __func__, (int)ear_cmv);
2032 return -EINVAL;
2033 }
2034 dev_dbg(codec->dev, "%s: Earpiece CM-voltage: %s\n", __func__,
2035 cmv_str);
2036 snd_soc_update_bits(codec, AB8500_ANACONF1, AB8500_ANACONF1_EARSELCM,
2037 ear_cmv);
2038
2039 return 0;
2040}
2041EXPORT_SYMBOL_GPL(ab8500_audio_set_ear_cmv);
2042
2043static int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai,
2044 unsigned int delay)
2045{
2046 unsigned int mask, val;
2047 struct snd_soc_codec *codec = dai->codec;
2048
2049 mask = BIT(AB8500_DIGIFCONF2_IF0DEL);
2050 val = 0;
2051
2052 switch (delay) {
2053 case 0:
2054 break;
2055 case 1:
2056 val |= BIT(AB8500_DIGIFCONF2_IF0DEL);
2057 break;
2058 default:
2059 dev_err(dai->codec->dev,
2060 "%s: ERROR: Unsupported bit-delay (0x%x)!\n",
2061 __func__, delay);
2062 return -EINVAL;
2063 }
2064
2065 dev_dbg(dai->codec->dev, "%s: IF0 Bit-delay: %d bits.\n",
2066 __func__, delay);
2067 snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val);
2068
2069 return 0;
2070}
2071
2072/* Gates clocking according format mask */
2073static int ab8500_codec_set_dai_clock_gate(struct snd_soc_codec *codec,
2074 unsigned int fmt)
2075{
2076 unsigned int mask;
2077 unsigned int val;
2078
2079 mask = BIT(AB8500_DIGIFCONF1_ENMASTGEN) |
2080 BIT(AB8500_DIGIFCONF1_ENFSBITCLK0);
2081
2082 val = BIT(AB8500_DIGIFCONF1_ENMASTGEN);
2083
2084 switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
2085 case SND_SOC_DAIFMT_CONT: /* continuous clock */
2086 dev_dbg(codec->dev, "%s: IF0 Clock is continuous.\n",
2087 __func__);
2088 val |= BIT(AB8500_DIGIFCONF1_ENFSBITCLK0);
2089 break;
2090 case SND_SOC_DAIFMT_GATED: /* clock is gated */
2091 dev_dbg(codec->dev, "%s: IF0 Clock is gated.\n",
2092 __func__);
2093 break;
2094 default:
2095 dev_err(codec->dev,
2096 "%s: ERROR: Unsupported clock mask (0x%x)!\n",
2097 __func__, fmt & SND_SOC_DAIFMT_CLOCK_MASK);
2098 return -EINVAL;
2099 }
2100
2101 snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val);
2102
2103 return 0;
2104}
2105
2106static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2107{
2108 unsigned int mask;
2109 unsigned int val;
2110 struct snd_soc_codec *codec = dai->codec;
2111 int status;
2112
2113 dev_dbg(codec->dev, "%s: Enter (fmt = 0x%x)\n", __func__, fmt);
2114
2115 mask = BIT(AB8500_DIGIFCONF3_IF1DATOIF0AD) |
2116 BIT(AB8500_DIGIFCONF3_IF1CLKTOIF0CLK) |
2117 BIT(AB8500_DIGIFCONF3_IF0BFIFOEN) |
2118 BIT(AB8500_DIGIFCONF3_IF0MASTER);
2119 val = 0;
2120
2121 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2122 case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & FRM master */
2123 dev_dbg(dai->codec->dev,
2124 "%s: IF0 Master-mode: AB8500 master.\n", __func__);
2125 val |= BIT(AB8500_DIGIFCONF3_IF0MASTER);
2126 break;
2127 case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & FRM slave */
2128 dev_dbg(dai->codec->dev,
2129 "%s: IF0 Master-mode: AB8500 slave.\n", __func__);
2130 break;
2131 case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & FRM master */
2132 case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */
2133 dev_err(dai->codec->dev,
2134 "%s: ERROR: The device is either a master or a slave.\n",
2135 __func__);
2136 default:
2137 dev_err(dai->codec->dev,
2138 "%s: ERROR: Unsupporter master mask 0x%x\n",
2139 __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
2140 return -EINVAL;
2141 break;
2142 }
2143
2144 snd_soc_update_bits(codec, AB8500_DIGIFCONF3, mask, val);
2145
2146 /* Set clock gating */
2147 status = ab8500_codec_set_dai_clock_gate(codec, fmt);
2148 if (status) {
2149 dev_err(dai->codec->dev,
2150 "%s: ERRROR: Failed to set clock gate (%d).\n",
2151 __func__, status);
2152 return status;
2153 }
2154
2155 /* Setting data transfer format */
2156
2157 mask = BIT(AB8500_DIGIFCONF2_IF0FORMAT0) |
2158 BIT(AB8500_DIGIFCONF2_IF0FORMAT1) |
2159 BIT(AB8500_DIGIFCONF2_FSYNC0P) |
2160 BIT(AB8500_DIGIFCONF2_BITCLK0P);
2161 val = 0;
2162
2163 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2164 case SND_SOC_DAIFMT_I2S: /* I2S mode */
2165 dev_dbg(dai->codec->dev, "%s: IF0 Protocol: I2S\n", __func__);
2166 val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT1);
2167 ab8500_audio_set_bit_delay(dai, 0);
2168 break;
2169
2170 case SND_SOC_DAIFMT_DSP_A: /* L data MSB after FRM LRC */
2171 dev_dbg(dai->codec->dev,
2172 "%s: IF0 Protocol: DSP A (TDM)\n", __func__);
2173 val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0);
2174 ab8500_audio_set_bit_delay(dai, 1);
2175 break;
2176
2177 case SND_SOC_DAIFMT_DSP_B: /* L data MSB during FRM LRC */
2178 dev_dbg(dai->codec->dev,
2179 "%s: IF0 Protocol: DSP B (TDM)\n", __func__);
2180 val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0);
2181 ab8500_audio_set_bit_delay(dai, 0);
2182 break;
2183
2184 default:
2185 dev_err(dai->codec->dev,
2186 "%s: ERROR: Unsupported format (0x%x)!\n",
2187 __func__, fmt & SND_SOC_DAIFMT_FORMAT_MASK);
2188 return -EINVAL;
2189 }
2190
2191 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
2192 case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
2193 dev_dbg(dai->codec->dev,
2194 "%s: IF0: Normal bit clock, normal frame\n",
2195 __func__);
2196 break;
2197 case SND_SOC_DAIFMT_NB_IF: /* normal BCLK + inv FRM */
2198 dev_dbg(dai->codec->dev,
2199 "%s: IF0: Normal bit clock, inverted frame\n",
2200 __func__);
2201 val |= BIT(AB8500_DIGIFCONF2_FSYNC0P);
2202 break;
2203 case SND_SOC_DAIFMT_IB_NF: /* invert BCLK + nor FRM */
2204 dev_dbg(dai->codec->dev,
2205 "%s: IF0: Inverted bit clock, normal frame\n",
2206 __func__);
2207 val |= BIT(AB8500_DIGIFCONF2_BITCLK0P);
2208 break;
2209 case SND_SOC_DAIFMT_IB_IF: /* invert BCLK + FRM */
2210 dev_dbg(dai->codec->dev,
2211 "%s: IF0: Inverted bit clock, inverted frame\n",
2212 __func__);
2213 val |= BIT(AB8500_DIGIFCONF2_FSYNC0P);
2214 val |= BIT(AB8500_DIGIFCONF2_BITCLK0P);
2215 break;
2216 default:
2217 dev_err(dai->codec->dev,
2218 "%s: ERROR: Unsupported INV mask 0x%x\n",
2219 __func__, fmt & SND_SOC_DAIFMT_INV_MASK);
2220 return -EINVAL;
2221 }
2222
2223 snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val);
2224
2225 return 0;
2226}
2227
2228static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
2229 unsigned int tx_mask, unsigned int rx_mask,
2230 int slots, int slot_width)
2231{
2232 struct snd_soc_codec *codec = dai->codec;
2233 unsigned int val, mask, slots_active;
2234
2235 mask = BIT(AB8500_DIGIFCONF2_IF0WL0) |
2236 BIT(AB8500_DIGIFCONF2_IF0WL1);
2237 val = 0;
2238
2239 switch (slot_width) {
2240 case 16:
2241 break;
2242 case 20:
2243 val |= BIT(AB8500_DIGIFCONF2_IF0WL0);
2244 break;
2245 case 24:
2246 val |= BIT(AB8500_DIGIFCONF2_IF0WL1);
2247 break;
2248 case 32:
2249 val |= BIT(AB8500_DIGIFCONF2_IF0WL1) |
2250 BIT(AB8500_DIGIFCONF2_IF0WL0);
2251 break;
2252 default:
2253 dev_err(dai->codec->dev, "%s: Unsupported slot-width 0x%x\n",
2254 __func__, slot_width);
2255 return -EINVAL;
2256 }
2257
2258 dev_dbg(dai->codec->dev, "%s: IF0 slot-width: %d bits.\n",
2259 __func__, slot_width);
2260 snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val);
2261
2262 /* Setup TDM clocking according to slot count */
2263 dev_dbg(dai->codec->dev, "%s: Slots, total: %d\n", __func__, slots);
2264 mask = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0) |
2265 BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1);
2266 switch (slots) {
2267 case 2:
2268 val = AB8500_MASK_NONE;
2269 break;
2270 case 4:
2271 val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0);
2272 break;
2273 case 8:
2274 val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1);
2275 break;
2276 case 16:
2277 val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0) |
2278 BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1);
2279 break;
2280 default:
2281 dev_err(dai->codec->dev,
2282 "%s: ERROR: Unsupported number of slots (%d)!\n",
2283 __func__, slots);
2284 return -EINVAL;
2285 }
2286 snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val);
2287
2288 /* Setup TDM DA according to active tx slots */
2289 mask = AB8500_DASLOTCONFX_SLTODAX_MASK;
2290 slots_active = hweight32(tx_mask);
2291 dev_dbg(dai->codec->dev, "%s: Slots, active, TX: %d\n", __func__,
2292 slots_active);
2293 switch (slots_active) {
2294 case 0:
2295 break;
2296 case 1:
2297 /* Slot 9 -> DA_IN1 & DA_IN3 */
2298 snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, 11);
2299 snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, 11);
2300 snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, 11);
2301 snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, 11);
2302 break;
2303 case 2:
2304 /* Slot 9 -> DA_IN1 & DA_IN3, Slot 11 -> DA_IN2 & DA_IN4 */
2305 snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, 9);
2306 snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, 9);
2307 snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, 11);
2308 snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, 11);
2309
2310 break;
2311 case 8:
2312 dev_dbg(dai->codec->dev,
2313 "%s: In 8-channel mode DA-from-slot mapping is set manually.",
2314 __func__);
2315 break;
2316 default:
2317 dev_err(dai->codec->dev,
2318 "%s: Unsupported number of active TX-slots (%d)!\n",
2319 __func__, slots_active);
2320 return -EINVAL;
2321 }
2322
2323 /* Setup TDM AD according to active RX-slots */
2324 slots_active = hweight32(rx_mask);
2325 dev_dbg(dai->codec->dev, "%s: Slots, active, RX: %d\n", __func__,
2326 slots_active);
2327 switch (slots_active) {
2328 case 0:
2329 break;
2330 case 1:
2331 /* AD_OUT3 -> slot 0 & 1 */
2332 snd_soc_update_bits(codec, AB8500_ADSLOTSEL1, AB8500_MASK_ALL,
2333 AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN |
2334 AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD);
2335 break;
2336 case 2:
2337 /* AD_OUT3 -> slot 0, AD_OUT2 -> slot 1 */
2338 snd_soc_update_bits(codec,
2339 AB8500_ADSLOTSEL1,
2340 AB8500_MASK_ALL,
2341 AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN |
2342 AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD);
2343 break;
2344 case 8:
2345 dev_dbg(dai->codec->dev,
2346 "%s: In 8-channel mode AD-to-slot mapping is set manually.",
2347 __func__);
2348 break;
2349 default:
2350 dev_err(dai->codec->dev,
2351 "%s: Unsupported number of active RX-slots (%d)!\n",
2352 __func__, slots_active);
2353 return -EINVAL;
2354 }
2355
2356 return 0;
2357}
2358
2359struct snd_soc_dai_driver ab8500_codec_dai[] = {
2360 {
2361 .name = "ab8500-codec-dai.0",
2362 .id = 0,
2363 .playback = {
2364 .stream_name = "ab8500_0p",
2365 .channels_min = 1,
2366 .channels_max = 8,
2367 .rates = AB8500_SUPPORTED_RATE,
2368 .formats = AB8500_SUPPORTED_FMT,
2369 },
2370 .ops = (struct snd_soc_dai_ops[]) {
2371 {
2372 .set_tdm_slot = ab8500_codec_set_dai_tdm_slot,
2373 .set_fmt = ab8500_codec_set_dai_fmt,
2374 }
2375 },
2376 .symmetric_rates = 1
2377 },
2378 {
2379 .name = "ab8500-codec-dai.1",
2380 .id = 1,
2381 .capture = {
2382 .stream_name = "ab8500_0c",
2383 .channels_min = 1,
2384 .channels_max = 8,
2385 .rates = AB8500_SUPPORTED_RATE,
2386 .formats = AB8500_SUPPORTED_FMT,
2387 },
2388 .ops = (struct snd_soc_dai_ops[]) {
2389 {
2390 .set_tdm_slot = ab8500_codec_set_dai_tdm_slot,
2391 .set_fmt = ab8500_codec_set_dai_fmt,
2392 }
2393 },
2394 .symmetric_rates = 1
2395 }
2396};
2397
2398static void ab8500_codec_of_probe(struct device *dev, struct device_node *np,
2399 struct ab8500_codec_platform_data *codec)
2400{
2401 u32 value;
2402
2403 if (of_get_property(np, "stericsson,amic1-type-single-ended", NULL))
2404 codec->amics.mic1_type = AMIC_TYPE_SINGLE_ENDED;
2405 else
2406 codec->amics.mic1_type = AMIC_TYPE_DIFFERENTIAL;
2407
2408 if (of_get_property(np, "stericsson,amic2-type-single-ended", NULL))
2409 codec->amics.mic2_type = AMIC_TYPE_SINGLE_ENDED;
2410 else
2411 codec->amics.mic2_type = AMIC_TYPE_DIFFERENTIAL;
2412
2413 /* Has a non-standard Vamic been requested? */
2414 if (of_get_property(np, "stericsson,amic1a-bias-vamic2", NULL))
2415 codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC2;
2416 else
2417 codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC1;
2418
2419 if (of_get_property(np, "stericsson,amic1b-bias-vamic2", NULL))
2420 codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC2;
2421 else
2422 codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC1;
2423
2424 if (of_get_property(np, "stericsson,amic2-bias-vamic1", NULL))
2425 codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC1;
2426 else
2427 codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC2;
2428
2429 if (!of_property_read_u32(np, "stericsson,earpeice-cmv", &value)) {
2430 switch (value) {
2431 case 950 :
2432 codec->ear_cmv = EAR_CMV_0_95V;
2433 break;
2434 case 1100 :
2435 codec->ear_cmv = EAR_CMV_1_10V;
2436 break;
2437 case 1270 :
2438 codec->ear_cmv = EAR_CMV_1_27V;
2439 break;
2440 case 1580 :
2441 codec->ear_cmv = EAR_CMV_1_58V;
2442 break;
2443 default :
2444 codec->ear_cmv = EAR_CMV_UNKNOWN;
2445 dev_err(dev, "Unsuitable earpiece voltage found in DT\n");
2446 }
2447 } else {
2448 dev_warn(dev, "No earpiece voltage found in DT - using default\n");
2449 codec->ear_cmv = EAR_CMV_0_95V;
2450 }
2451}
2452
2453static int ab8500_codec_probe(struct snd_soc_codec *codec)
2454{
2455 struct device *dev = codec->dev;
2456 struct device_node *np = dev->of_node;
2457 struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev);
2458 struct ab8500_platform_data *pdata;
2459 struct filter_control *fc;
2460 int status;
2461
2462 dev_dbg(dev, "%s: Enter.\n", __func__);
2463
2464 /* Setup AB8500 according to board-settings */
2465 pdata = (struct ab8500_platform_data *)dev_get_platdata(dev->parent);
2466
2467 /* Inform SoC Core that we have our own I/O arrangements. */
2468 codec->control_data = (void *)true;
2469
2470 if (np) {
2471 if (!pdata)
2472 pdata = devm_kzalloc(dev,
2473 sizeof(struct ab8500_platform_data),
2474 GFP_KERNEL);
2475
2476 if (pdata && !pdata->codec)
2477 pdata->codec
2478 = devm_kzalloc(dev,
2479 sizeof(struct ab8500_codec_platform_data),
2480 GFP_KERNEL);
2481
2482 if (!(pdata && pdata->codec))
2483 return -ENOMEM;
2484
2485 ab8500_codec_of_probe(dev, np, pdata->codec);
2486
2487 } else {
2488 if (!(pdata && pdata->codec)) {
2489 dev_err(dev, "No codec platform data or DT found\n");
2490 return -EINVAL;
2491 }
2492 }
2493
2494 status = ab8500_audio_setup_mics(codec, &pdata->codec->amics);
2495 if (status < 0) {
2496 pr_err("%s: Failed to setup mics (%d)!\n", __func__, status);
2497 return status;
2498 }
2499 status = ab8500_audio_set_ear_cmv(codec, pdata->codec->ear_cmv);
2500 if (status < 0) {
2501 pr_err("%s: Failed to set earpiece CM-voltage (%d)!\n",
2502 __func__, status);
2503 return status;
2504 }
2505
2506 status = ab8500_audio_init_audioblock(codec);
2507 if (status < 0) {
2508 dev_err(dev, "%s: failed to init audio-block (%d)!\n",
2509 __func__, status);
2510 return status;
2511 }
2512
2513 /* Override HW-defaults */
2514 ab8500_codec_write_reg(codec,
2515 AB8500_ANACONF5,
2516 BIT(AB8500_ANACONF5_HSAUTOEN));
2517 ab8500_codec_write_reg(codec,
2518 AB8500_SHORTCIRCONF,
2519 BIT(AB8500_SHORTCIRCONF_HSZCDDIS));
2520
2521 /* Add filter controls */
2522 status = snd_soc_add_codec_controls(codec, ab8500_filter_controls,
2523 ARRAY_SIZE(ab8500_filter_controls));
2524 if (status < 0) {
2525 dev_err(dev,
2526 "%s: failed to add ab8500 filter controls (%d).\n",
2527 __func__, status);
2528 return status;
2529 }
2530 fc = (struct filter_control *)
2531 &ab8500_filter_controls[AB8500_FILTER_ANC_FIR].private_value;
2532 drvdata->anc_fir_values = (long *)fc->value;
2533 fc = (struct filter_control *)
2534 &ab8500_filter_controls[AB8500_FILTER_ANC_IIR].private_value;
2535 drvdata->anc_iir_values = (long *)fc->value;
2536 fc = (struct filter_control *)
2537 &ab8500_filter_controls[AB8500_FILTER_SID_FIR].private_value;
2538 drvdata->sid_fir_values = (long *)fc->value;
2539
2540 (void)snd_soc_dapm_disable_pin(&codec->dapm, "ANC Configure Input");
2541
2542 mutex_init(&drvdata->anc_lock);
2543
2544 return status;
2545}
2546
2547static struct snd_soc_codec_driver ab8500_codec_driver = {
2548 .probe = ab8500_codec_probe,
2549 .read = ab8500_codec_read_reg,
2550 .write = ab8500_codec_write_reg,
2551 .reg_word_size = sizeof(u8),
2552 .controls = ab8500_ctrls,
2553 .num_controls = ARRAY_SIZE(ab8500_ctrls),
2554 .dapm_widgets = ab8500_dapm_widgets,
2555 .num_dapm_widgets = ARRAY_SIZE(ab8500_dapm_widgets),
2556 .dapm_routes = ab8500_dapm_routes,
2557 .num_dapm_routes = ARRAY_SIZE(ab8500_dapm_routes),
2558};
2559
2560static int __devinit ab8500_codec_driver_probe(struct platform_device *pdev)
2561{
2562 int status;
2563 struct ab8500_codec_drvdata *drvdata;
2564
2565 dev_dbg(&pdev->dev, "%s: Enter.\n", __func__);
2566
2567 /* Create driver private-data struct */
2568 drvdata = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_codec_drvdata),
2569 GFP_KERNEL);
2570 drvdata->sid_status = SID_UNCONFIGURED;
2571 drvdata->anc_status = ANC_UNCONFIGURED;
2572 dev_set_drvdata(&pdev->dev, drvdata);
2573
2574 dev_dbg(&pdev->dev, "%s: Register codec.\n", __func__);
2575 status = snd_soc_register_codec(&pdev->dev, &ab8500_codec_driver,
2576 ab8500_codec_dai,
2577 ARRAY_SIZE(ab8500_codec_dai));
2578 if (status < 0)
2579 dev_err(&pdev->dev,
2580 "%s: Error: Failed to register codec (%d).\n",
2581 __func__, status);
2582
2583 return status;
2584}
2585
2586static int __devexit ab8500_codec_driver_remove(struct platform_device *pdev)
2587{
2588 dev_info(&pdev->dev, "%s Enter.\n", __func__);
2589
2590 snd_soc_unregister_codec(&pdev->dev);
2591
2592 return 0;
2593}
2594
2595static struct platform_driver ab8500_codec_platform_driver = {
2596 .driver = {
2597 .name = "ab8500-codec",
2598 .owner = THIS_MODULE,
2599 },
2600 .probe = ab8500_codec_driver_probe,
2601 .remove = __devexit_p(ab8500_codec_driver_remove),
2602 .suspend = NULL,
2603 .resume = NULL,
2604};
2605module_platform_driver(ab8500_codec_platform_driver);
2606
2607MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/ab8500-codec.h b/sound/soc/codecs/ab8500-codec.h
new file mode 100644
index 000000000000..114f69a0c629
--- /dev/null
+++ b/sound/soc/codecs/ab8500-codec.h
@@ -0,0 +1,590 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
5 * Kristoffer Karlsson <kristoffer.karlsson@stericsson.com>,
6 * Roger Nilsson <roger.xr.nilsson@stericsson.com>,
7 * for ST-Ericsson.
8 *
9 * Based on the early work done by:
10 * Mikko J. Lehto <mikko.lehto@symbio.com>,
11 * Mikko Sarmanne <mikko.sarmanne@symbio.com>,
12 * for ST-Ericsson.
13 *
14 * License terms:
15 *
16 * This program is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License version 2 as published
18 * by the Free Software Foundation.
19 */
20
21#ifndef AB8500_CODEC_REGISTERS_H
22#define AB8500_CODEC_REGISTERS_H
23
24#define AB8500_SUPPORTED_RATE (SNDRV_PCM_RATE_48000)
25#define AB8500_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE)
26
27/* AB8500 audio bank (0x0d) register definitions */
28
29#define AB8500_POWERUP 0x00
30#define AB8500_AUDSWRESET 0x01
31#define AB8500_ADPATHENA 0x02
32#define AB8500_DAPATHENA 0x03
33#define AB8500_ANACONF1 0x04
34#define AB8500_ANACONF2 0x05
35#define AB8500_DIGMICCONF 0x06
36#define AB8500_ANACONF3 0x07
37#define AB8500_ANACONF4 0x08
38#define AB8500_DAPATHCONF 0x09
39#define AB8500_MUTECONF 0x0A
40#define AB8500_SHORTCIRCONF 0x0B
41#define AB8500_ANACONF5 0x0C
42#define AB8500_ENVCPCONF 0x0D
43#define AB8500_SIGENVCONF 0x0E
44#define AB8500_PWMGENCONF1 0x0F
45#define AB8500_PWMGENCONF2 0x10
46#define AB8500_PWMGENCONF3 0x11
47#define AB8500_PWMGENCONF4 0x12
48#define AB8500_PWMGENCONF5 0x13
49#define AB8500_ANAGAIN1 0x14
50#define AB8500_ANAGAIN2 0x15
51#define AB8500_ANAGAIN3 0x16
52#define AB8500_ANAGAIN4 0x17
53#define AB8500_DIGLINHSLGAIN 0x18
54#define AB8500_DIGLINHSRGAIN 0x19
55#define AB8500_ADFILTCONF 0x1A
56#define AB8500_DIGIFCONF1 0x1B
57#define AB8500_DIGIFCONF2 0x1C
58#define AB8500_DIGIFCONF3 0x1D
59#define AB8500_DIGIFCONF4 0x1E
60#define AB8500_ADSLOTSEL1 0x1F
61#define AB8500_ADSLOTSEL2 0x20
62#define AB8500_ADSLOTSEL3 0x21
63#define AB8500_ADSLOTSEL4 0x22
64#define AB8500_ADSLOTSEL5 0x23
65#define AB8500_ADSLOTSEL6 0x24
66#define AB8500_ADSLOTSEL7 0x25
67#define AB8500_ADSLOTSEL8 0x26
68#define AB8500_ADSLOTSEL9 0x27
69#define AB8500_ADSLOTSEL10 0x28
70#define AB8500_ADSLOTSEL11 0x29
71#define AB8500_ADSLOTSEL12 0x2A
72#define AB8500_ADSLOTSEL13 0x2B
73#define AB8500_ADSLOTSEL14 0x2C
74#define AB8500_ADSLOTSEL15 0x2D
75#define AB8500_ADSLOTSEL16 0x2E
76#define AB8500_ADSLOTHIZCTRL1 0x2F
77#define AB8500_ADSLOTHIZCTRL2 0x30
78#define AB8500_ADSLOTHIZCTRL3 0x31
79#define AB8500_ADSLOTHIZCTRL4 0x32
80#define AB8500_DASLOTCONF1 0x33
81#define AB8500_DASLOTCONF2 0x34
82#define AB8500_DASLOTCONF3 0x35
83#define AB8500_DASLOTCONF4 0x36
84#define AB8500_DASLOTCONF5 0x37
85#define AB8500_DASLOTCONF6 0x38
86#define AB8500_DASLOTCONF7 0x39
87#define AB8500_DASLOTCONF8 0x3A
88#define AB8500_CLASSDCONF1 0x3B
89#define AB8500_CLASSDCONF2 0x3C
90#define AB8500_CLASSDCONF3 0x3D
91#define AB8500_DMICFILTCONF 0x3E
92#define AB8500_DIGMULTCONF1 0x3F
93#define AB8500_DIGMULTCONF2 0x40
94#define AB8500_ADDIGGAIN1 0x41
95#define AB8500_ADDIGGAIN2 0x42
96#define AB8500_ADDIGGAIN3 0x43
97#define AB8500_ADDIGGAIN4 0x44
98#define AB8500_ADDIGGAIN5 0x45
99#define AB8500_ADDIGGAIN6 0x46
100#define AB8500_DADIGGAIN1 0x47
101#define AB8500_DADIGGAIN2 0x48
102#define AB8500_DADIGGAIN3 0x49
103#define AB8500_DADIGGAIN4 0x4A
104#define AB8500_DADIGGAIN5 0x4B
105#define AB8500_DADIGGAIN6 0x4C
106#define AB8500_ADDIGLOOPGAIN1 0x4D
107#define AB8500_ADDIGLOOPGAIN2 0x4E
108#define AB8500_HSLEARDIGGAIN 0x4F
109#define AB8500_HSRDIGGAIN 0x50
110#define AB8500_SIDFIRGAIN1 0x51
111#define AB8500_SIDFIRGAIN2 0x52
112#define AB8500_ANCCONF1 0x53
113#define AB8500_ANCCONF2 0x54
114#define AB8500_ANCCONF3 0x55
115#define AB8500_ANCCONF4 0x56
116#define AB8500_ANCCONF5 0x57
117#define AB8500_ANCCONF6 0x58
118#define AB8500_ANCCONF7 0x59
119#define AB8500_ANCCONF8 0x5A
120#define AB8500_ANCCONF9 0x5B
121#define AB8500_ANCCONF10 0x5C
122#define AB8500_ANCCONF11 0x5D
123#define AB8500_ANCCONF12 0x5E
124#define AB8500_ANCCONF13 0x5F
125#define AB8500_ANCCONF14 0x60
126#define AB8500_SIDFIRADR 0x61
127#define AB8500_SIDFIRCOEF1 0x62
128#define AB8500_SIDFIRCOEF2 0x63
129#define AB8500_SIDFIRCONF 0x64
130#define AB8500_AUDINTMASK1 0x65
131#define AB8500_AUDINTSOURCE1 0x66
132#define AB8500_AUDINTMASK2 0x67
133#define AB8500_AUDINTSOURCE2 0x68
134#define AB8500_FIFOCONF1 0x69
135#define AB8500_FIFOCONF2 0x6A
136#define AB8500_FIFOCONF3 0x6B
137#define AB8500_FIFOCONF4 0x6C
138#define AB8500_FIFOCONF5 0x6D
139#define AB8500_FIFOCONF6 0x6E
140#define AB8500_AUDREV 0x6F
141
142#define AB8500_FIRST_REG AB8500_POWERUP
143#define AB8500_LAST_REG AB8500_AUDREV
144#define AB8500_CACHEREGNUM (AB8500_LAST_REG + 1)
145
146#define AB8500_MASK_ALL 0xFF
147#define AB8500_MASK_NONE 0x00
148
149/* AB8500_POWERUP */
150#define AB8500_POWERUP_POWERUP 7
151#define AB8500_POWERUP_ENANA 3
152
153/* AB8500_AUDSWRESET */
154#define AB8500_AUDSWRESET_SWRESET 7
155
156/* AB8500_ADPATHENA */
157#define AB8500_ADPATHENA_ENAD12 7
158#define AB8500_ADPATHENA_ENAD34 5
159#define AB8500_ADPATHENA_ENAD5768 3
160
161/* AB8500_DAPATHENA */
162#define AB8500_DAPATHENA_ENDA1 7
163#define AB8500_DAPATHENA_ENDA2 6
164#define AB8500_DAPATHENA_ENDA3 5
165#define AB8500_DAPATHENA_ENDA4 4
166#define AB8500_DAPATHENA_ENDA5 3
167#define AB8500_DAPATHENA_ENDA6 2
168
169/* AB8500_ANACONF1 */
170#define AB8500_ANACONF1_HSLOWPOW 7
171#define AB8500_ANACONF1_DACLOWPOW1 6
172#define AB8500_ANACONF1_DACLOWPOW0 5
173#define AB8500_ANACONF1_EARDACLOWPOW 4
174#define AB8500_ANACONF1_EARSELCM 2
175#define AB8500_ANACONF1_HSHPEN 1
176#define AB8500_ANACONF1_EARDRVLOWPOW 0
177
178/* AB8500_ANACONF2 */
179#define AB8500_ANACONF2_ENMIC1 7
180#define AB8500_ANACONF2_ENMIC2 6
181#define AB8500_ANACONF2_ENLINL 5
182#define AB8500_ANACONF2_ENLINR 4
183#define AB8500_ANACONF2_MUTMIC1 3
184#define AB8500_ANACONF2_MUTMIC2 2
185#define AB8500_ANACONF2_MUTLINL 1
186#define AB8500_ANACONF2_MUTLINR 0
187
188/* AB8500_DIGMICCONF */
189#define AB8500_DIGMICCONF_ENDMIC1 7
190#define AB8500_DIGMICCONF_ENDMIC2 6
191#define AB8500_DIGMICCONF_ENDMIC3 5
192#define AB8500_DIGMICCONF_ENDMIC4 4
193#define AB8500_DIGMICCONF_ENDMIC5 3
194#define AB8500_DIGMICCONF_ENDMIC6 2
195#define AB8500_DIGMICCONF_HSFADSPEED 0
196
197/* AB8500_ANACONF3 */
198#define AB8500_ANACONF3_MIC1SEL 7
199#define AB8500_ANACONF3_LINRSEL 6
200#define AB8500_ANACONF3_ENDRVHSL 5
201#define AB8500_ANACONF3_ENDRVHSR 4
202#define AB8500_ANACONF3_ENADCMIC 2
203#define AB8500_ANACONF3_ENADCLINL 1
204#define AB8500_ANACONF3_ENADCLINR 0
205
206/* AB8500_ANACONF4 */
207#define AB8500_ANACONF4_DISPDVSS 7
208#define AB8500_ANACONF4_ENEAR 6
209#define AB8500_ANACONF4_ENHSL 5
210#define AB8500_ANACONF4_ENHSR 4
211#define AB8500_ANACONF4_ENHFL 3
212#define AB8500_ANACONF4_ENHFR 2
213#define AB8500_ANACONF4_ENVIB1 1
214#define AB8500_ANACONF4_ENVIB2 0
215
216/* AB8500_DAPATHCONF */
217#define AB8500_DAPATHCONF_ENDACEAR 6
218#define AB8500_DAPATHCONF_ENDACHSL 5
219#define AB8500_DAPATHCONF_ENDACHSR 4
220#define AB8500_DAPATHCONF_ENDACHFL 3
221#define AB8500_DAPATHCONF_ENDACHFR 2
222#define AB8500_DAPATHCONF_ENDACVIB1 1
223#define AB8500_DAPATHCONF_ENDACVIB2 0
224
225/* AB8500_MUTECONF */
226#define AB8500_MUTECONF_MUTEAR 6
227#define AB8500_MUTECONF_MUTHSL 5
228#define AB8500_MUTECONF_MUTHSR 4
229#define AB8500_MUTECONF_MUTDACEAR 2
230#define AB8500_MUTECONF_MUTDACHSL 1
231#define AB8500_MUTECONF_MUTDACHSR 0
232
233/* AB8500_SHORTCIRCONF */
234#define AB8500_SHORTCIRCONF_ENSHORTPWD 7
235#define AB8500_SHORTCIRCONF_EARSHORTDIS 6
236#define AB8500_SHORTCIRCONF_HSSHORTDIS 5
237#define AB8500_SHORTCIRCONF_HSPULLDEN 4
238#define AB8500_SHORTCIRCONF_HSOSCEN 2
239#define AB8500_SHORTCIRCONF_HSFADDIS 1
240#define AB8500_SHORTCIRCONF_HSZCDDIS 0
241/* Zero cross should be disabled */
242
243/* AB8500_ANACONF5 */
244#define AB8500_ANACONF5_ENCPHS 7
245#define AB8500_ANACONF5_HSLDACTOLOL 5
246#define AB8500_ANACONF5_HSRDACTOLOR 4
247#define AB8500_ANACONF5_ENLOL 3
248#define AB8500_ANACONF5_ENLOR 2
249#define AB8500_ANACONF5_HSAUTOEN 0
250
251/* AB8500_ENVCPCONF */
252#define AB8500_ENVCPCONF_ENVDETHTHRE 4
253#define AB8500_ENVCPCONF_ENVDETLTHRE 0
254#define AB8500_ENVCPCONF_ENVDETHTHRE_MAX 0x0F
255#define AB8500_ENVCPCONF_ENVDETLTHRE_MAX 0x0F
256
257/* AB8500_SIGENVCONF */
258#define AB8500_SIGENVCONF_CPLVEN 5
259#define AB8500_SIGENVCONF_ENVDETCPEN 4
260#define AB8500_SIGENVCONF_ENVDETTIME 0
261#define AB8500_SIGENVCONF_ENVDETTIME_MAX 0x0F
262
263/* AB8500_PWMGENCONF1 */
264#define AB8500_PWMGENCONF1_PWMTOVIB1 7
265#define AB8500_PWMGENCONF1_PWMTOVIB2 6
266#define AB8500_PWMGENCONF1_PWM1CTRL 5
267#define AB8500_PWMGENCONF1_PWM2CTRL 4
268#define AB8500_PWMGENCONF1_PWM1NCTRL 3
269#define AB8500_PWMGENCONF1_PWM1PCTRL 2
270#define AB8500_PWMGENCONF1_PWM2NCTRL 1
271#define AB8500_PWMGENCONF1_PWM2PCTRL 0
272
273/* AB8500_PWMGENCONF2 */
274/* AB8500_PWMGENCONF3 */
275/* AB8500_PWMGENCONF4 */
276/* AB8500_PWMGENCONF5 */
277#define AB8500_PWMGENCONFX_PWMVIBXPOL 7
278#define AB8500_PWMGENCONFX_PWMVIBXDUTCYC 0
279#define AB8500_PWMGENCONFX_PWMVIBXDUTCYC_MAX 0x64
280
281/* AB8500_ANAGAIN1 */
282/* AB8500_ANAGAIN2 */
283#define AB8500_ANAGAINX_ENSEMICX 7
284#define AB8500_ANAGAINX_LOWPOWMICX 6
285#define AB8500_ANAGAINX_MICXGAIN 0
286#define AB8500_ANAGAINX_MICXGAIN_MAX 0x1F
287
288/* AB8500_ANAGAIN3 */
289#define AB8500_ANAGAIN3_HSLGAIN 4
290#define AB8500_ANAGAIN3_HSRGAIN 0
291#define AB8500_ANAGAIN3_HSXGAIN_MAX 0x0F
292
293/* AB8500_ANAGAIN4 */
294#define AB8500_ANAGAIN4_LINLGAIN 4
295#define AB8500_ANAGAIN4_LINRGAIN 0
296#define AB8500_ANAGAIN4_LINXGAIN_MAX 0x0F
297
298/* AB8500_DIGLINHSLGAIN */
299/* AB8500_DIGLINHSRGAIN */
300#define AB8500_DIGLINHSXGAIN_LINTOHSXGAIN 0
301#define AB8500_DIGLINHSXGAIN_LINTOHSXGAIN_MAX 0x13
302
303/* AB8500_ADFILTCONF */
304#define AB8500_ADFILTCONF_AD1NH 7
305#define AB8500_ADFILTCONF_AD2NH 6
306#define AB8500_ADFILTCONF_AD3NH 5
307#define AB8500_ADFILTCONF_AD4NH 4
308#define AB8500_ADFILTCONF_AD1VOICE 3
309#define AB8500_ADFILTCONF_AD2VOICE 2
310#define AB8500_ADFILTCONF_AD3VOICE 1
311#define AB8500_ADFILTCONF_AD4VOICE 0
312
313/* AB8500_DIGIFCONF1 */
314#define AB8500_DIGIFCONF1_ENMASTGEN 7
315#define AB8500_DIGIFCONF1_IF1BITCLKOS1 6
316#define AB8500_DIGIFCONF1_IF1BITCLKOS0 5
317#define AB8500_DIGIFCONF1_ENFSBITCLK1 4
318#define AB8500_DIGIFCONF1_IF0BITCLKOS1 2
319#define AB8500_DIGIFCONF1_IF0BITCLKOS0 1
320#define AB8500_DIGIFCONF1_ENFSBITCLK0 0
321
322/* AB8500_DIGIFCONF2 */
323#define AB8500_DIGIFCONF2_FSYNC0P 6
324#define AB8500_DIGIFCONF2_BITCLK0P 5
325#define AB8500_DIGIFCONF2_IF0DEL 4
326#define AB8500_DIGIFCONF2_IF0FORMAT1 3
327#define AB8500_DIGIFCONF2_IF0FORMAT0 2
328#define AB8500_DIGIFCONF2_IF0WL1 1
329#define AB8500_DIGIFCONF2_IF0WL0 0
330
331/* AB8500_DIGIFCONF3 */
332#define AB8500_DIGIFCONF3_IF0DATOIF1AD 7
333#define AB8500_DIGIFCONF3_IF0CLKTOIF1CLK 6
334#define AB8500_DIGIFCONF3_IF1MASTER 5
335#define AB8500_DIGIFCONF3_IF1DATOIF0AD 3
336#define AB8500_DIGIFCONF3_IF1CLKTOIF0CLK 2
337#define AB8500_DIGIFCONF3_IF0MASTER 1
338#define AB8500_DIGIFCONF3_IF0BFIFOEN 0
339
340/* AB8500_DIGIFCONF4 */
341#define AB8500_DIGIFCONF4_FSYNC1P 6
342#define AB8500_DIGIFCONF4_BITCLK1P 5
343#define AB8500_DIGIFCONF4_IF1DEL 4
344#define AB8500_DIGIFCONF4_IF1FORMAT1 3
345#define AB8500_DIGIFCONF4_IF1FORMAT0 2
346#define AB8500_DIGIFCONF4_IF1WL1 1
347#define AB8500_DIGIFCONF4_IF1WL0 0
348
349/* AB8500_ADSLOTSELX */
350#define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_ODD 0x00
351#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD 0x01
352#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD 0x02
353#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_ODD 0x03
354#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_ODD 0x04
355#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_ODD 0x05
356#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_ODD 0x06
357#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_ODD 0x07
358#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_ODD 0x08
359#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_ODD 0x0F
360#define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_EVEN 0x00
361#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_EVEN 0x10
362#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN 0x20
363#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_EVEN 0x30
364#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_EVEN 0x40
365#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_EVEN 0x50
366#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_EVEN 0x60
367#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_EVEN 0x70
368#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_EVEN 0x80
369#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_EVEN 0xF0
370#define AB8500_ADSLOTSELX_EVEN_SHIFT 0
371#define AB8500_ADSLOTSELX_ODD_SHIFT 4
372
373/* AB8500_ADSLOTHIZCTRL1 */
374/* AB8500_ADSLOTHIZCTRL2 */
375/* AB8500_ADSLOTHIZCTRL3 */
376/* AB8500_ADSLOTHIZCTRL4 */
377/* AB8500_DASLOTCONF1 */
378#define AB8500_DASLOTCONF1_DA12VOICE 7
379#define AB8500_DASLOTCONF1_SWAPDA12_34 6
380#define AB8500_DASLOTCONF1_DAI7TOADO1 5
381
382/* AB8500_DASLOTCONF2 */
383#define AB8500_DASLOTCONF2_DAI8TOADO2 5
384
385/* AB8500_DASLOTCONF3 */
386#define AB8500_DASLOTCONF3_DA34VOICE 7
387#define AB8500_DASLOTCONF3_DAI7TOADO3 5
388
389/* AB8500_DASLOTCONF4 */
390#define AB8500_DASLOTCONF4_DAI8TOADO4 5
391
392/* AB8500_DASLOTCONF5 */
393#define AB8500_DASLOTCONF5_DA56VOICE 7
394#define AB8500_DASLOTCONF5_DAI7TOADO5 5
395
396/* AB8500_DASLOTCONF6 */
397#define AB8500_DASLOTCONF6_DAI8TOADO6 5
398
399/* AB8500_DASLOTCONF7 */
400#define AB8500_DASLOTCONF7_DAI8TOADO7 5
401
402/* AB8500_DASLOTCONF8 */
403#define AB8500_DASLOTCONF8_DAI7TOADO8 5
404
405#define AB8500_DASLOTCONFX_SLTODAX_SHIFT 0
406#define AB8500_DASLOTCONFX_SLTODAX_MASK 0x1F
407
408/* AB8500_CLASSDCONF1 */
409#define AB8500_CLASSDCONF1_PARLHF 7
410#define AB8500_CLASSDCONF1_PARLVIB 6
411#define AB8500_CLASSDCONF1_VIB1SWAPEN 3
412#define AB8500_CLASSDCONF1_VIB2SWAPEN 2
413#define AB8500_CLASSDCONF1_HFLSWAPEN 1
414#define AB8500_CLASSDCONF1_HFRSWAPEN 0
415
416/* AB8500_CLASSDCONF2 */
417#define AB8500_CLASSDCONF2_FIRBYP3 7
418#define AB8500_CLASSDCONF2_FIRBYP2 6
419#define AB8500_CLASSDCONF2_FIRBYP1 5
420#define AB8500_CLASSDCONF2_FIRBYP0 4
421#define AB8500_CLASSDCONF2_HIGHVOLEN3 3
422#define AB8500_CLASSDCONF2_HIGHVOLEN2 2
423#define AB8500_CLASSDCONF2_HIGHVOLEN1 1
424#define AB8500_CLASSDCONF2_HIGHVOLEN0 0
425
426/* AB8500_CLASSDCONF3 */
427#define AB8500_CLASSDCONF3_DITHHPGAIN 4
428#define AB8500_CLASSDCONF3_DITHHPGAIN_MAX 0x0A
429#define AB8500_CLASSDCONF3_DITHWGAIN 0
430#define AB8500_CLASSDCONF3_DITHWGAIN_MAX 0x0A
431
432/* AB8500_DMICFILTCONF */
433#define AB8500_DMICFILTCONF_ANCINSEL 7
434#define AB8500_DMICFILTCONF_DA3TOEAR 6
435#define AB8500_DMICFILTCONF_DMIC1SINC3 5
436#define AB8500_DMICFILTCONF_DMIC2SINC3 4
437#define AB8500_DMICFILTCONF_DMIC3SINC3 3
438#define AB8500_DMICFILTCONF_DMIC4SINC3 2
439#define AB8500_DMICFILTCONF_DMIC5SINC3 1
440#define AB8500_DMICFILTCONF_DMIC6SINC3 0
441
442/* AB8500_DIGMULTCONF1 */
443#define AB8500_DIGMULTCONF1_DATOHSLEN 7
444#define AB8500_DIGMULTCONF1_DATOHSREN 6
445#define AB8500_DIGMULTCONF1_AD1SEL 5
446#define AB8500_DIGMULTCONF1_AD2SEL 4
447#define AB8500_DIGMULTCONF1_AD3SEL 3
448#define AB8500_DIGMULTCONF1_AD5SEL 2
449#define AB8500_DIGMULTCONF1_AD6SEL 1
450#define AB8500_DIGMULTCONF1_ANCSEL 0
451
452/* AB8500_DIGMULTCONF2 */
453#define AB8500_DIGMULTCONF2_DATOHFREN 7
454#define AB8500_DIGMULTCONF2_DATOHFLEN 6
455#define AB8500_DIGMULTCONF2_HFRSEL 5
456#define AB8500_DIGMULTCONF2_HFLSEL 4
457#define AB8500_DIGMULTCONF2_FIRSID1SEL 2
458#define AB8500_DIGMULTCONF2_FIRSID2SEL 0
459
460/* AB8500_ADDIGGAIN1 */
461/* AB8500_ADDIGGAIN2 */
462/* AB8500_ADDIGGAIN3 */
463/* AB8500_ADDIGGAIN4 */
464/* AB8500_ADDIGGAIN5 */
465/* AB8500_ADDIGGAIN6 */
466#define AB8500_ADDIGGAINX_FADEDISADX 6
467#define AB8500_ADDIGGAINX_ADXGAIN_MAX 0x3F
468
469/* AB8500_DADIGGAIN1 */
470/* AB8500_DADIGGAIN2 */
471/* AB8500_DADIGGAIN3 */
472/* AB8500_DADIGGAIN4 */
473/* AB8500_DADIGGAIN5 */
474/* AB8500_DADIGGAIN6 */
475#define AB8500_DADIGGAINX_FADEDISDAX 6
476#define AB8500_DADIGGAINX_DAXGAIN_MAX 0x3F
477
478/* AB8500_ADDIGLOOPGAIN1 */
479/* AB8500_ADDIGLOOPGAIN2 */
480#define AB8500_ADDIGLOOPGAINX_FADEDISADXL 6
481#define AB8500_ADDIGLOOPGAINX_ADXLBGAIN_MAX 0x3F
482
483/* AB8500_HSLEARDIGGAIN */
484#define AB8500_HSLEARDIGGAIN_HSSINC1 7
485#define AB8500_HSLEARDIGGAIN_FADEDISHSL 4
486#define AB8500_HSLEARDIGGAIN_HSLDGAIN_MAX 0x09
487
488/* AB8500_HSRDIGGAIN */
489#define AB8500_HSRDIGGAIN_FADESPEED 6
490#define AB8500_HSRDIGGAIN_FADEDISHSR 4
491#define AB8500_HSRDIGGAIN_HSRDGAIN_MAX 0x09
492
493/* AB8500_SIDFIRGAIN1 */
494/* AB8500_SIDFIRGAIN2 */
495#define AB8500_SIDFIRGAINX_FIRSIDXGAIN_MAX 0x1F
496
497/* AB8500_ANCCONF1 */
498#define AB8500_ANCCONF1_ANCIIRUPDATE 3
499#define AB8500_ANCCONF1_ENANC 2
500#define AB8500_ANCCONF1_ANCIIRINIT 1
501#define AB8500_ANCCONF1_ANCFIRUPDATE 0
502
503/* AB8500_ANCCONF2 */
504#define AB8500_ANCCONF2_SHIFT 5
505#define AB8500_ANCCONF2_MIN -0x10
506#define AB8500_ANCCONF2_MAX 0xF
507
508/* AB8500_ANCCONF3 */
509#define AB8500_ANCCONF3_SHIFT 5
510#define AB8500_ANCCONF3_MIN -0x10
511#define AB8500_ANCCONF3_MAX 0xF
512
513/* AB8500_ANCCONF4 */
514#define AB8500_ANCCONF4_SHIFT 5
515#define AB8500_ANCCONF4_MIN -0x10
516#define AB8500_ANCCONF4_MAX 0xF
517
518/* AB8500_ANC_FIR_COEFFS */
519#define AB8500_ANC_FIR_COEFF_MIN -0x8000
520#define AB8500_ANC_FIR_COEFF_MAX 0x7FFF
521#define AB8500_ANC_FIR_COEFFS 15
522
523/* AB8500_ANC_IIR_COEFFS */
524#define AB8500_ANC_IIR_COEFF_MIN -0x800000
525#define AB8500_ANC_IIR_COEFF_MAX 0x7FFFFF
526#define AB8500_ANC_IIR_COEFFS 24
527/* AB8500_ANC_WARP_DELAY */
528#define AB8500_ANC_WARP_DELAY_SHIFT 16
529#define AB8500_ANC_WARP_DELAY_MIN 0x0000
530#define AB8500_ANC_WARP_DELAY_MAX 0xFFFF
531
532/* AB8500_ANCCONF11 */
533/* AB8500_ANCCONF12 */
534/* AB8500_ANCCONF13 */
535/* AB8500_ANCCONF14 */
536
537/* AB8500_SIDFIRADR */
538#define AB8500_SIDFIRADR_FIRSIDSET 7
539#define AB8500_SIDFIRADR_ADDRESS_SHIFT 0
540#define AB8500_SIDFIRADR_ADDRESS_MAX 0x7F
541
542/* AB8500_SIDFIRCOEF1 */
543/* AB8500_SIDFIRCOEF2 */
544#define AB8500_SID_FIR_COEFF_MIN 0
545#define AB8500_SID_FIR_COEFF_MAX 0xFFFF
546#define AB8500_SID_FIR_COEFFS 128
547
548/* AB8500_SIDFIRCONF */
549#define AB8500_SIDFIRCONF_ENFIRSIDS 2
550#define AB8500_SIDFIRCONF_FIRSIDSTOIF1 1
551#define AB8500_SIDFIRCONF_FIRSIDBUSY 0
552
553/* AB8500_AUDINTMASK1 */
554/* AB8500_AUDINTSOURCE1 */
555/* AB8500_AUDINTMASK2 */
556/* AB8500_AUDINTSOURCE2 */
557
558/* AB8500_FIFOCONF1 */
559#define AB8500_FIFOCONF1_BFIFOMASK 0x80
560#define AB8500_FIFOCONF1_BFIFO19M2 0x40
561#define AB8500_FIFOCONF1_BFIFOINT_SHIFT 0
562#define AB8500_FIFOCONF1_BFIFOINT_MAX 0x3F
563
564/* AB8500_FIFOCONF2 */
565#define AB8500_FIFOCONF2_BFIFOTX_SHIFT 0
566#define AB8500_FIFOCONF2_BFIFOTX_MAX 0xFF
567
568/* AB8500_FIFOCONF3 */
569#define AB8500_FIFOCONF3_BFIFOEXSL_SHIFT 5
570#define AB8500_FIFOCONF3_BFIFOEXSL_MAX 0x5
571#define AB8500_FIFOCONF3_PREBITCLK0_SHIFT 2
572#define AB8500_FIFOCONF3_PREBITCLK0_MAX 0x7
573#define AB8500_FIFOCONF3_BFIFOMAST_SHIFT 1
574#define AB8500_FIFOCONF3_BFIFORUN_SHIFT 0
575
576/* AB8500_FIFOCONF4 */
577#define AB8500_FIFOCONF4_BFIFOFRAMSW_SHIFT 0
578#define AB8500_FIFOCONF4_BFIFOFRAMSW_MAX 0xFF
579
580/* AB8500_FIFOCONF5 */
581#define AB8500_FIFOCONF5_BFIFOWAKEUP_SHIFT 0
582#define AB8500_FIFOCONF5_BFIFOWAKEUP_MAX 0xFF
583
584/* AB8500_FIFOCONF6 */
585#define AB8500_FIFOCONF6_BFIFOSAMPLE_SHIFT 0
586#define AB8500_FIFOCONF6_BFIFOSAMPLE_MAX 0xFF
587
588/* AB8500_AUDREV */
589
590#endif
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 2023c749f232..ea06b834a7de 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -91,11 +91,6 @@ static int ac97_soc_probe(struct snd_soc_codec *codec)
91 return 0; 91 return 0;
92} 92}
93 93
94static int ac97_soc_remove(struct snd_soc_codec *codec)
95{
96 return 0;
97}
98
99#ifdef CONFIG_PM 94#ifdef CONFIG_PM
100static int ac97_soc_suspend(struct snd_soc_codec *codec) 95static int ac97_soc_suspend(struct snd_soc_codec *codec)
101{ 96{
@@ -119,7 +114,6 @@ static struct snd_soc_codec_driver soc_codec_dev_ac97 = {
119 .write = ac97_write, 114 .write = ac97_write,
120 .read = ac97_read, 115 .read = ac97_read,
121 .probe = ac97_soc_probe, 116 .probe = ac97_soc_probe,
122 .remove = ac97_soc_remove,
123 .suspend = ac97_soc_suspend, 117 .suspend = ac97_soc_suspend,
124 .resume = ac97_soc_resume, 118 .resume = ac97_soc_resume,
125}; 119};
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 8c39dddd7d00..11b1b714b8b5 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -186,6 +186,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec)
186 186
187 printk(KERN_INFO "AD1980 SoC Audio Codec\n"); 187 printk(KERN_INFO "AD1980 SoC Audio Codec\n");
188 188
189 codec->control_data = codec; /* we don't use regmap! */
189 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 190 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
190 if (ret < 0) { 191 if (ret < 0) {
191 printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); 192 printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
new file mode 100644
index 000000000000..1cf7a32d1b21
--- /dev/null
+++ b/sound/soc/codecs/arizona.c
@@ -0,0 +1,937 @@
1/*
2 * arizona.c - Wolfson Arizona class device shared support
3 *
4 * Copyright 2012 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/gcd.h>
14#include <linux/module.h>
15#include <linux/pm_runtime.h>
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18#include <sound/tlv.h>
19
20#include <linux/mfd/arizona/core.h>
21#include <linux/mfd/arizona/registers.h>
22
23#include "arizona.h"
24
25#define ARIZONA_AIF_BCLK_CTRL 0x00
26#define ARIZONA_AIF_TX_PIN_CTRL 0x01
27#define ARIZONA_AIF_RX_PIN_CTRL 0x02
28#define ARIZONA_AIF_RATE_CTRL 0x03
29#define ARIZONA_AIF_FORMAT 0x04
30#define ARIZONA_AIF_TX_BCLK_RATE 0x05
31#define ARIZONA_AIF_RX_BCLK_RATE 0x06
32#define ARIZONA_AIF_FRAME_CTRL_1 0x07
33#define ARIZONA_AIF_FRAME_CTRL_2 0x08
34#define ARIZONA_AIF_FRAME_CTRL_3 0x09
35#define ARIZONA_AIF_FRAME_CTRL_4 0x0A
36#define ARIZONA_AIF_FRAME_CTRL_5 0x0B
37#define ARIZONA_AIF_FRAME_CTRL_6 0x0C
38#define ARIZONA_AIF_FRAME_CTRL_7 0x0D
39#define ARIZONA_AIF_FRAME_CTRL_8 0x0E
40#define ARIZONA_AIF_FRAME_CTRL_9 0x0F
41#define ARIZONA_AIF_FRAME_CTRL_10 0x10
42#define ARIZONA_AIF_FRAME_CTRL_11 0x11
43#define ARIZONA_AIF_FRAME_CTRL_12 0x12
44#define ARIZONA_AIF_FRAME_CTRL_13 0x13
45#define ARIZONA_AIF_FRAME_CTRL_14 0x14
46#define ARIZONA_AIF_FRAME_CTRL_15 0x15
47#define ARIZONA_AIF_FRAME_CTRL_16 0x16
48#define ARIZONA_AIF_FRAME_CTRL_17 0x17
49#define ARIZONA_AIF_FRAME_CTRL_18 0x18
50#define ARIZONA_AIF_TX_ENABLES 0x19
51#define ARIZONA_AIF_RX_ENABLES 0x1A
52#define ARIZONA_AIF_FORCE_WRITE 0x1B
53
54#define arizona_fll_err(_fll, fmt, ...) \
55 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
56#define arizona_fll_warn(_fll, fmt, ...) \
57 dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
58#define arizona_fll_dbg(_fll, fmt, ...) \
59 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
60
61#define arizona_aif_err(_dai, fmt, ...) \
62 dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
63#define arizona_aif_warn(_dai, fmt, ...) \
64 dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
65#define arizona_aif_dbg(_dai, fmt, ...) \
66 dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
67
68const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
69 "None",
70 "Tone Generator 1",
71 "Tone Generator 2",
72 "Haptics",
73 "AEC",
74 "Mic Mute Mixer",
75 "Noise Generator",
76 "IN1L",
77 "IN1R",
78 "IN2L",
79 "IN2R",
80 "IN3L",
81 "IN3R",
82 "IN4L",
83 "IN4R",
84 "AIF1RX1",
85 "AIF1RX2",
86 "AIF1RX3",
87 "AIF1RX4",
88 "AIF1RX5",
89 "AIF1RX6",
90 "AIF1RX7",
91 "AIF1RX8",
92 "AIF2RX1",
93 "AIF2RX2",
94 "AIF3RX1",
95 "AIF3RX2",
96 "SLIMRX1",
97 "SLIMRX2",
98 "SLIMRX3",
99 "SLIMRX4",
100 "SLIMRX5",
101 "SLIMRX6",
102 "SLIMRX7",
103 "SLIMRX8",
104 "EQ1",
105 "EQ2",
106 "EQ3",
107 "EQ4",
108 "DRC1L",
109 "DRC1R",
110 "DRC2L",
111 "DRC2R",
112 "LHPF1",
113 "LHPF2",
114 "LHPF3",
115 "LHPF4",
116 "DSP1.1",
117 "DSP1.2",
118 "DSP1.3",
119 "DSP1.4",
120 "DSP1.5",
121 "DSP1.6",
122 "ASRC1L",
123 "ASRC1R",
124 "ASRC2L",
125 "ASRC2R",
126};
127EXPORT_SYMBOL_GPL(arizona_mixer_texts);
128
129int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
130 0x00, /* None */
131 0x04, /* Tone */
132 0x05,
133 0x06, /* Haptics */
134 0x08, /* AEC */
135 0x0c, /* Noise mixer */
136 0x0d, /* Comfort noise */
137 0x10, /* IN1L */
138 0x11,
139 0x12,
140 0x13,
141 0x14,
142 0x15,
143 0x16,
144 0x17,
145 0x20, /* AIF1RX1 */
146 0x21,
147 0x22,
148 0x23,
149 0x24,
150 0x25,
151 0x26,
152 0x27,
153 0x28, /* AIF2RX1 */
154 0x29,
155 0x30, /* AIF3RX1 */
156 0x31,
157 0x38, /* SLIMRX1 */
158 0x39,
159 0x3a,
160 0x3b,
161 0x3c,
162 0x3d,
163 0x3e,
164 0x3f,
165 0x50, /* EQ1 */
166 0x51,
167 0x52,
168 0x53,
169 0x58, /* DRC1L */
170 0x59,
171 0x5a,
172 0x5b,
173 0x60, /* LHPF1 */
174 0x61,
175 0x62,
176 0x63,
177 0x68, /* DSP1.1 */
178 0x69,
179 0x6a,
180 0x6b,
181 0x6c,
182 0x6d,
183 0x90, /* ASRC1L */
184 0x91,
185 0x92,
186 0x93,
187};
188EXPORT_SYMBOL_GPL(arizona_mixer_values);
189
190const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
191EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
192
193static const char *arizona_lhpf_mode_text[] = {
194 "Low-pass", "High-pass"
195};
196
197const struct soc_enum arizona_lhpf1_mode =
198 SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2,
199 arizona_lhpf_mode_text);
200EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
201
202const struct soc_enum arizona_lhpf2_mode =
203 SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2,
204 arizona_lhpf_mode_text);
205EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
206
207const struct soc_enum arizona_lhpf3_mode =
208 SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2,
209 arizona_lhpf_mode_text);
210EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
211
212const struct soc_enum arizona_lhpf4_mode =
213 SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2,
214 arizona_lhpf_mode_text);
215EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
216
217int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
218 int event)
219{
220 return 0;
221}
222EXPORT_SYMBOL_GPL(arizona_in_ev);
223
224int arizona_out_ev(struct snd_soc_dapm_widget *w,
225 struct snd_kcontrol *kcontrol,
226 int event)
227{
228 return 0;
229}
230EXPORT_SYMBOL_GPL(arizona_out_ev);
231
232int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
233 int source, unsigned int freq, int dir)
234{
235 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
236 struct arizona *arizona = priv->arizona;
237 char *name;
238 unsigned int reg;
239 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
240 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
241 unsigned int *clk;
242
243 switch (clk_id) {
244 case ARIZONA_CLK_SYSCLK:
245 name = "SYSCLK";
246 reg = ARIZONA_SYSTEM_CLOCK_1;
247 clk = &priv->sysclk;
248 mask |= ARIZONA_SYSCLK_FRAC;
249 break;
250 case ARIZONA_CLK_ASYNCCLK:
251 name = "ASYNCCLK";
252 reg = ARIZONA_ASYNC_CLOCK_1;
253 clk = &priv->asyncclk;
254 break;
255 default:
256 return -EINVAL;
257 }
258
259 switch (freq) {
260 case 5644800:
261 case 6144000:
262 break;
263 case 11289600:
264 case 12288000:
265 val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT;
266 break;
267 case 22579200:
268 case 24576000:
269 val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT;
270 break;
271 case 45158400:
272 case 49152000:
273 val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT;
274 break;
275 default:
276 return -EINVAL;
277 }
278
279 *clk = freq;
280
281 if (freq % 6144000)
282 val |= ARIZONA_SYSCLK_FRAC;
283
284 dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
285
286 return regmap_update_bits(arizona->regmap, reg, mask, val);
287}
288EXPORT_SYMBOL_GPL(arizona_set_sysclk);
289
290static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
291{
292 struct snd_soc_codec *codec = dai->codec;
293 int lrclk, bclk, mode, base;
294
295 base = dai->driver->base;
296
297 lrclk = 0;
298 bclk = 0;
299
300 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
301 case SND_SOC_DAIFMT_DSP_A:
302 mode = 0;
303 break;
304 case SND_SOC_DAIFMT_DSP_B:
305 mode = 1;
306 break;
307 case SND_SOC_DAIFMT_I2S:
308 mode = 2;
309 break;
310 case SND_SOC_DAIFMT_LEFT_J:
311 mode = 3;
312 break;
313 default:
314 arizona_aif_err(dai, "Unsupported DAI format %d\n",
315 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
316 return -EINVAL;
317 }
318
319 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
320 case SND_SOC_DAIFMT_CBS_CFS:
321 break;
322 case SND_SOC_DAIFMT_CBS_CFM:
323 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
324 break;
325 case SND_SOC_DAIFMT_CBM_CFS:
326 bclk |= ARIZONA_AIF1_BCLK_MSTR;
327 break;
328 case SND_SOC_DAIFMT_CBM_CFM:
329 bclk |= ARIZONA_AIF1_BCLK_MSTR;
330 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
331 break;
332 default:
333 arizona_aif_err(dai, "Unsupported master mode %d\n",
334 fmt & SND_SOC_DAIFMT_MASTER_MASK);
335 return -EINVAL;
336 }
337
338 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
339 case SND_SOC_DAIFMT_NB_NF:
340 break;
341 case SND_SOC_DAIFMT_IB_IF:
342 bclk |= ARIZONA_AIF1_BCLK_INV;
343 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
344 break;
345 case SND_SOC_DAIFMT_IB_NF:
346 bclk |= ARIZONA_AIF1_BCLK_INV;
347 break;
348 case SND_SOC_DAIFMT_NB_IF:
349 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
350 break;
351 default:
352 return -EINVAL;
353 }
354
355 snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
356 ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR,
357 bclk);
358 snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL,
359 ARIZONA_AIF1TX_LRCLK_INV |
360 ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
361 snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL,
362 ARIZONA_AIF1RX_LRCLK_INV |
363 ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
364 snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT,
365 ARIZONA_AIF1_FMT_MASK, mode);
366
367 return 0;
368}
369
370static const int arizona_48k_bclk_rates[] = {
371 -1,
372 48000,
373 64000,
374 96000,
375 128000,
376 192000,
377 256000,
378 384000,
379 512000,
380 768000,
381 1024000,
382 1536000,
383 2048000,
384 3072000,
385 4096000,
386 6144000,
387 8192000,
388 12288000,
389 24576000,
390};
391
392static const unsigned int arizona_48k_rates[] = {
393 12000,
394 24000,
395 48000,
396 96000,
397 192000,
398 384000,
399 768000,
400 4000,
401 8000,
402 16000,
403 32000,
404 64000,
405 128000,
406 256000,
407 512000,
408};
409
410static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
411 .count = ARRAY_SIZE(arizona_48k_rates),
412 .list = arizona_48k_rates,
413};
414
415static const int arizona_44k1_bclk_rates[] = {
416 -1,
417 44100,
418 58800,
419 88200,
420 117600,
421 177640,
422 235200,
423 352800,
424 470400,
425 705600,
426 940800,
427 1411200,
428 1881600,
429 2822400,
430 3763200,
431 5644800,
432 7526400,
433 11289600,
434 22579200,
435};
436
437static const unsigned int arizona_44k1_rates[] = {
438 11025,
439 22050,
440 44100,
441 88200,
442 176400,
443 352800,
444 705600,
445};
446
447static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
448 .count = ARRAY_SIZE(arizona_44k1_rates),
449 .list = arizona_44k1_rates,
450};
451
452static int arizona_sr_vals[] = {
453 0,
454 12000,
455 24000,
456 48000,
457 96000,
458 192000,
459 384000,
460 768000,
461 0,
462 11025,
463 22050,
464 44100,
465 88200,
466 176400,
467 352800,
468 705600,
469 4000,
470 8000,
471 16000,
472 32000,
473 64000,
474 128000,
475 256000,
476 512000,
477};
478
479static int arizona_startup(struct snd_pcm_substream *substream,
480 struct snd_soc_dai *dai)
481{
482 struct snd_soc_codec *codec = dai->codec;
483 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
484 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
485 const struct snd_pcm_hw_constraint_list *constraint;
486 unsigned int base_rate;
487
488 switch (dai_priv->clk) {
489 case ARIZONA_CLK_SYSCLK:
490 base_rate = priv->sysclk;
491 break;
492 case ARIZONA_CLK_ASYNCCLK:
493 base_rate = priv->asyncclk;
494 break;
495 default:
496 return 0;
497 }
498
499 if (base_rate % 8000)
500 constraint = &arizona_44k1_constraint;
501 else
502 constraint = &arizona_48k_constraint;
503
504 return snd_pcm_hw_constraint_list(substream->runtime, 0,
505 SNDRV_PCM_HW_PARAM_RATE,
506 constraint);
507}
508
509static int arizona_hw_params(struct snd_pcm_substream *substream,
510 struct snd_pcm_hw_params *params,
511 struct snd_soc_dai *dai)
512{
513 struct snd_soc_codec *codec = dai->codec;
514 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
515 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
516 int base = dai->driver->base;
517 const int *rates;
518 int i;
519 int bclk, lrclk, wl, frame, sr_val;
520
521 if (params_rate(params) % 8000)
522 rates = &arizona_44k1_bclk_rates[0];
523 else
524 rates = &arizona_48k_bclk_rates[0];
525
526 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
527 if (rates[i] >= snd_soc_params_to_bclk(params) &&
528 rates[i] % params_rate(params) == 0) {
529 bclk = i;
530 break;
531 }
532 }
533 if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
534 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
535 params_rate(params));
536 return -EINVAL;
537 }
538
539 for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
540 if (arizona_sr_vals[i] == params_rate(params))
541 break;
542 if (i == ARRAY_SIZE(arizona_sr_vals)) {
543 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
544 params_rate(params));
545 return -EINVAL;
546 }
547 sr_val = i;
548
549 lrclk = snd_soc_params_to_bclk(params) / params_rate(params);
550
551 arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
552 rates[bclk], rates[bclk] / lrclk);
553
554 wl = snd_pcm_format_width(params_format(params));
555 frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
556
557 /*
558 * We will need to be more flexible than this in future,
559 * currently we use a single sample rate for SYSCLK.
560 */
561 switch (dai_priv->clk) {
562 case ARIZONA_CLK_SYSCLK:
563 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
564 ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
565 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
566 ARIZONA_AIF1_RATE_MASK, 0);
567 break;
568 case ARIZONA_CLK_ASYNCCLK:
569 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
570 ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
571 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
572 ARIZONA_AIF1_RATE_MASK, 8);
573 break;
574 default:
575 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
576 return -EINVAL;
577 }
578
579 snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
580 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
581 snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE,
582 ARIZONA_AIF1TX_BCPF_MASK, lrclk);
583 snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE,
584 ARIZONA_AIF1RX_BCPF_MASK, lrclk);
585 snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1,
586 ARIZONA_AIF1TX_WL_MASK |
587 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
588 snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2,
589 ARIZONA_AIF1RX_WL_MASK |
590 ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
591
592 return 0;
593}
594
595static const char *arizona_dai_clk_str(int clk_id)
596{
597 switch (clk_id) {
598 case ARIZONA_CLK_SYSCLK:
599 return "SYSCLK";
600 case ARIZONA_CLK_ASYNCCLK:
601 return "ASYNCCLK";
602 default:
603 return "Unknown clock";
604 }
605}
606
607static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
608 int clk_id, unsigned int freq, int dir)
609{
610 struct snd_soc_codec *codec = dai->codec;
611 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
612 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
613 struct snd_soc_dapm_route routes[2];
614
615 switch (clk_id) {
616 case ARIZONA_CLK_SYSCLK:
617 case ARIZONA_CLK_ASYNCCLK:
618 break;
619 default:
620 return -EINVAL;
621 }
622
623 if (clk_id == dai_priv->clk)
624 return 0;
625
626 if (dai->active) {
627 dev_err(codec->dev, "Can't change clock on active DAI %d\n",
628 dai->id);
629 return -EBUSY;
630 }
631
632 memset(&routes, 0, sizeof(routes));
633 routes[0].sink = dai->driver->capture.stream_name;
634 routes[1].sink = dai->driver->playback.stream_name;
635
636 routes[0].source = arizona_dai_clk_str(dai_priv->clk);
637 routes[1].source = arizona_dai_clk_str(dai_priv->clk);
638 snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
639
640 routes[0].source = arizona_dai_clk_str(clk_id);
641 routes[1].source = arizona_dai_clk_str(clk_id);
642 snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
643
644 return snd_soc_dapm_sync(&codec->dapm);
645}
646
647const struct snd_soc_dai_ops arizona_dai_ops = {
648 .startup = arizona_startup,
649 .set_fmt = arizona_set_fmt,
650 .hw_params = arizona_hw_params,
651 .set_sysclk = arizona_dai_set_sysclk,
652};
653EXPORT_SYMBOL_GPL(arizona_dai_ops);
654
655int arizona_init_dai(struct arizona_priv *priv, int id)
656{
657 struct arizona_dai_priv *dai_priv = &priv->dai[id];
658
659 dai_priv->clk = ARIZONA_CLK_SYSCLK;
660
661 return 0;
662}
663EXPORT_SYMBOL_GPL(arizona_init_dai);
664
665static irqreturn_t arizona_fll_lock(int irq, void *data)
666{
667 struct arizona_fll *fll = data;
668
669 arizona_fll_dbg(fll, "Locked\n");
670
671 complete(&fll->lock);
672
673 return IRQ_HANDLED;
674}
675
676static irqreturn_t arizona_fll_clock_ok(int irq, void *data)
677{
678 struct arizona_fll *fll = data;
679
680 arizona_fll_dbg(fll, "clock OK\n");
681
682 complete(&fll->ok);
683
684 return IRQ_HANDLED;
685}
686
687static struct {
688 unsigned int min;
689 unsigned int max;
690 u16 fratio;
691 int ratio;
692} fll_fratios[] = {
693 { 0, 64000, 4, 16 },
694 { 64000, 128000, 3, 8 },
695 { 128000, 256000, 2, 4 },
696 { 256000, 1000000, 1, 2 },
697 { 1000000, 13500000, 0, 1 },
698};
699
700struct arizona_fll_cfg {
701 int n;
702 int theta;
703 int lambda;
704 int refdiv;
705 int outdiv;
706 int fratio;
707};
708
709static int arizona_calc_fll(struct arizona_fll *fll,
710 struct arizona_fll_cfg *cfg,
711 unsigned int Fref,
712 unsigned int Fout)
713{
714 unsigned int target, div, gcd_fll;
715 int i, ratio;
716
717 arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout);
718
719 /* Fref must be <=13.5MHz */
720 div = 1;
721 cfg->refdiv = 0;
722 while ((Fref / div) > 13500000) {
723 div *= 2;
724 cfg->refdiv++;
725
726 if (div > 8) {
727 arizona_fll_err(fll,
728 "Can't scale %dMHz in to <=13.5MHz\n",
729 Fref);
730 return -EINVAL;
731 }
732 }
733
734 /* Apply the division for our remaining calculations */
735 Fref /= div;
736
737 /* Fvco should be over the targt; don't check the upper bound */
738 div = 1;
739 while (Fout * div < 90000000 * fll->vco_mult) {
740 div++;
741 if (div > 7) {
742 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
743 Fout);
744 return -EINVAL;
745 }
746 }
747 target = Fout * div / fll->vco_mult;
748 cfg->outdiv = div;
749
750 arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
751
752 /* Find an appropraite FLL_FRATIO and factor it out of the target */
753 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
754 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
755 cfg->fratio = fll_fratios[i].fratio;
756 ratio = fll_fratios[i].ratio;
757 break;
758 }
759 }
760 if (i == ARRAY_SIZE(fll_fratios)) {
761 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
762 Fref);
763 return -EINVAL;
764 }
765
766 cfg->n = target / (ratio * Fref);
767
768 if (target % Fref) {
769 gcd_fll = gcd(target, ratio * Fref);
770 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
771
772 cfg->theta = (target - (cfg->n * ratio * Fref))
773 / gcd_fll;
774 cfg->lambda = (ratio * Fref) / gcd_fll;
775 } else {
776 cfg->theta = 0;
777 cfg->lambda = 0;
778 }
779
780 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
781 cfg->n, cfg->theta, cfg->lambda);
782 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
783 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
784
785 return 0;
786
787}
788
789static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
790 struct arizona_fll_cfg *cfg, int source)
791{
792 regmap_update_bits(arizona->regmap, base + 3,
793 ARIZONA_FLL1_THETA_MASK, cfg->theta);
794 regmap_update_bits(arizona->regmap, base + 4,
795 ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
796 regmap_update_bits(arizona->regmap, base + 5,
797 ARIZONA_FLL1_FRATIO_MASK,
798 cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
799 regmap_update_bits(arizona->regmap, base + 6,
800 ARIZONA_FLL1_CLK_REF_DIV_MASK |
801 ARIZONA_FLL1_CLK_REF_SRC_MASK,
802 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
803 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
804
805 regmap_update_bits(arizona->regmap, base + 2,
806 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
807 ARIZONA_FLL1_CTRL_UPD | cfg->n);
808}
809
810int arizona_set_fll(struct arizona_fll *fll, int source,
811 unsigned int Fref, unsigned int Fout)
812{
813 struct arizona *arizona = fll->arizona;
814 struct arizona_fll_cfg cfg, sync;
815 unsigned int reg, val;
816 int syncsrc;
817 bool ena;
818 int ret;
819
820 ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
821 if (ret != 0) {
822 arizona_fll_err(fll, "Failed to read current state: %d\n",
823 ret);
824 return ret;
825 }
826 ena = reg & ARIZONA_FLL1_ENA;
827
828 if (Fout) {
829 /* Do we have a 32kHz reference? */
830 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
831 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
832 case ARIZONA_CLK_SRC_MCLK1:
833 case ARIZONA_CLK_SRC_MCLK2:
834 syncsrc = val & ARIZONA_CLK_32K_SRC_MASK;
835 break;
836 default:
837 syncsrc = -1;
838 }
839
840 if (source == syncsrc)
841 syncsrc = -1;
842
843 if (syncsrc >= 0) {
844 ret = arizona_calc_fll(fll, &sync, Fref, Fout);
845 if (ret != 0)
846 return ret;
847
848 ret = arizona_calc_fll(fll, &cfg, 32768, Fout);
849 if (ret != 0)
850 return ret;
851 } else {
852 ret = arizona_calc_fll(fll, &cfg, Fref, Fout);
853 if (ret != 0)
854 return ret;
855 }
856 } else {
857 regmap_update_bits(arizona->regmap, fll->base + 1,
858 ARIZONA_FLL1_ENA, 0);
859 regmap_update_bits(arizona->regmap, fll->base + 0x11,
860 ARIZONA_FLL1_SYNC_ENA, 0);
861
862 if (ena)
863 pm_runtime_put_autosuspend(arizona->dev);
864
865 return 0;
866 }
867
868 regmap_update_bits(arizona->regmap, fll->base + 5,
869 ARIZONA_FLL1_OUTDIV_MASK,
870 cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
871
872 if (syncsrc >= 0) {
873 arizona_apply_fll(arizona, fll->base, &cfg, syncsrc);
874 arizona_apply_fll(arizona, fll->base + 0x10, &sync, source);
875 } else {
876 arizona_apply_fll(arizona, fll->base, &cfg, source);
877 }
878
879 if (!ena)
880 pm_runtime_get(arizona->dev);
881
882 /* Clear any pending completions */
883 try_wait_for_completion(&fll->ok);
884
885 regmap_update_bits(arizona->regmap, fll->base + 1,
886 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
887 if (syncsrc >= 0)
888 regmap_update_bits(arizona->regmap, fll->base + 0x11,
889 ARIZONA_FLL1_SYNC_ENA,
890 ARIZONA_FLL1_SYNC_ENA);
891
892 ret = wait_for_completion_timeout(&fll->ok,
893 msecs_to_jiffies(25));
894 if (ret == 0)
895 arizona_fll_warn(fll, "Timed out waiting for lock\n");
896
897 return 0;
898}
899EXPORT_SYMBOL_GPL(arizona_set_fll);
900
901int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
902 int ok_irq, struct arizona_fll *fll)
903{
904 int ret;
905
906 init_completion(&fll->lock);
907 init_completion(&fll->ok);
908
909 fll->id = id;
910 fll->base = base;
911 fll->arizona = arizona;
912
913 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
914 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
915 "FLL%d clock OK", id);
916
917 ret = arizona_request_irq(arizona, lock_irq, fll->lock_name,
918 arizona_fll_lock, fll);
919 if (ret != 0) {
920 dev_err(arizona->dev, "Failed to get FLL%d lock IRQ: %d\n",
921 id, ret);
922 }
923
924 ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
925 arizona_fll_clock_ok, fll);
926 if (ret != 0) {
927 dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n",
928 id, ret);
929 }
930
931 return 0;
932}
933EXPORT_SYMBOL_GPL(arizona_init_fll);
934
935MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
936MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
937MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
new file mode 100644
index 000000000000..59caca8865e8
--- /dev/null
+++ b/sound/soc/codecs/arizona.h
@@ -0,0 +1,159 @@
1/*
2 * arizona.h - Wolfson Arizona class device shared support
3 *
4 * Copyright 2012 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _ASOC_ARIZONA_H
14#define _ASOC_ARIZONA_H
15
16#include <linux/completion.h>
17
18#include <sound/soc.h>
19
20#define ARIZONA_CLK_SYSCLK 1
21#define ARIZONA_CLK_ASYNCCLK 2
22
23#define ARIZONA_CLK_SRC_MCLK1 0x0
24#define ARIZONA_CLK_SRC_MCLK2 0x1
25#define ARIZONA_CLK_SRC_FLL1 0x4
26#define ARIZONA_CLK_SRC_FLL2 0x5
27#define ARIZONA_CLK_SRC_AIF1BCLK 0x8
28#define ARIZONA_CLK_SRC_AIF2BCLK 0x9
29#define ARIZONA_CLK_SRC_AIF3BCLK 0xa
30
31#define ARIZONA_FLL_SRC_MCLK1 0
32#define ARIZONA_FLL_SRC_MCLK2 1
33#define ARIZONA_FLL_SRC_SLIMCLK 2
34#define ARIZONA_FLL_SRC_FLL1 3
35#define ARIZONA_FLL_SRC_FLL2 4
36#define ARIZONA_FLL_SRC_AIF1BCLK 5
37#define ARIZONA_FLL_SRC_AIF2BCLK 6
38#define ARIZONA_FLL_SRC_AIF3BCLK 7
39#define ARIZONA_FLL_SRC_AIF1LRCLK 8
40#define ARIZONA_FLL_SRC_AIF2LRCLK 9
41#define ARIZONA_FLL_SRC_AIF3LRCLK 10
42
43#define ARIZONA_MIXER_VOL_MASK 0x00FE
44#define ARIZONA_MIXER_VOL_SHIFT 1
45#define ARIZONA_MIXER_VOL_WIDTH 7
46
47#define ARIZONA_MAX_DAI 3
48
49struct arizona;
50
51struct arizona_dai_priv {
52 int clk;
53};
54
55struct arizona_priv {
56 struct arizona *arizona;
57 int sysclk;
58 int asyncclk;
59 struct arizona_dai_priv dai[ARIZONA_MAX_DAI];
60};
61
62#define ARIZONA_NUM_MIXER_INPUTS 57
63
64extern const unsigned int arizona_mixer_tlv[];
65extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS];
66extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
67
68#define ARIZONA_MIXER_CONTROLS(name, base) \
69 SOC_SINGLE_RANGE_TLV(name " Input 1 Volume", base + 1, \
70 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
71 arizona_mixer_tlv), \
72 SOC_SINGLE_RANGE_TLV(name " Input 2 Volume", base + 3, \
73 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
74 arizona_mixer_tlv), \
75 SOC_SINGLE_RANGE_TLV(name " Input 3 Volume", base + 5, \
76 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
77 arizona_mixer_tlv), \
78 SOC_SINGLE_RANGE_TLV(name " Input 4 Volume", base + 7, \
79 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
80 arizona_mixer_tlv)
81
82#define ARIZONA_MUX_ENUM_DECL(name, reg) \
83 SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \
84 arizona_mixer_texts, arizona_mixer_values)
85
86#define ARIZONA_MUX_CTL_DECL(name) \
87 const struct snd_kcontrol_new name##_mux = \
88 SOC_DAPM_VALUE_ENUM("Route", name##_enum)
89
90#define ARIZONA_MIXER_ENUMS(name, base_reg) \
91 static ARIZONA_MUX_ENUM_DECL(name##_in1_enum, base_reg); \
92 static ARIZONA_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \
93 static ARIZONA_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \
94 static ARIZONA_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \
95 static ARIZONA_MUX_CTL_DECL(name##_in1); \
96 static ARIZONA_MUX_CTL_DECL(name##_in2); \
97 static ARIZONA_MUX_CTL_DECL(name##_in3); \
98 static ARIZONA_MUX_CTL_DECL(name##_in4)
99
100#define ARIZONA_MUX(name, ctrl) \
101 SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
102
103#define ARIZONA_MIXER_WIDGETS(name, name_str) \
104 ARIZONA_MUX(name_str " Input 1", &name##_in1_mux), \
105 ARIZONA_MUX(name_str " Input 2", &name##_in2_mux), \
106 ARIZONA_MUX(name_str " Input 3", &name##_in3_mux), \
107 ARIZONA_MUX(name_str " Input 4", &name##_in4_mux), \
108 SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
109
110#define ARIZONA_MIXER_ROUTES(widget, name) \
111 { widget, NULL, name " Mixer" }, \
112 { name " Mixer", NULL, name " Input 1" }, \
113 { name " Mixer", NULL, name " Input 2" }, \
114 { name " Mixer", NULL, name " Input 3" }, \
115 { name " Mixer", NULL, name " Input 4" }, \
116 ARIZONA_MIXER_INPUT_ROUTES(name " Input 1"), \
117 ARIZONA_MIXER_INPUT_ROUTES(name " Input 2"), \
118 ARIZONA_MIXER_INPUT_ROUTES(name " Input 3"), \
119 ARIZONA_MIXER_INPUT_ROUTES(name " Input 4")
120
121extern const struct soc_enum arizona_lhpf1_mode;
122extern const struct soc_enum arizona_lhpf2_mode;
123extern const struct soc_enum arizona_lhpf3_mode;
124extern const struct soc_enum arizona_lhpf4_mode;
125
126extern int arizona_in_ev(struct snd_soc_dapm_widget *w,
127 struct snd_kcontrol *kcontrol,
128 int event);
129extern int arizona_out_ev(struct snd_soc_dapm_widget *w,
130 struct snd_kcontrol *kcontrol,
131 int event);
132
133extern int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
134 int source, unsigned int freq, int dir);
135
136extern const struct snd_soc_dai_ops arizona_dai_ops;
137
138#define ARIZONA_FLL_NAME_LEN 20
139
140struct arizona_fll {
141 struct arizona *arizona;
142 int id;
143 unsigned int base;
144 unsigned int vco_mult;
145 struct completion lock;
146 struct completion ok;
147
148 char lock_name[ARIZONA_FLL_NAME_LEN];
149 char clock_ok_name[ARIZONA_FLL_NAME_LEN];
150};
151
152extern int arizona_init_fll(struct arizona *arizona, int id, int base,
153 int lock_irq, int ok_irq, struct arizona_fll *fll);
154extern int arizona_set_fll(struct arizona_fll *fll, int source,
155 unsigned int Fref, unsigned int Fout);
156
157extern int arizona_init_dai(struct arizona_priv *priv, int dai);
158
159#endif
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
index a7109413aef1..628daf6a1d97 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -14,7 +14,6 @@
14 14
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/moduleparam.h> 16#include <linux/moduleparam.h>
17#include <linux/version.h>
18#include <linux/kernel.h> 17#include <linux/kernel.h>
19#include <linux/init.h> 18#include <linux/init.h>
20#include <linux/delay.h> 19#include <linux/delay.h>
@@ -1217,11 +1216,11 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
1217 return -ENOMEM; 1216 return -ENOMEM;
1218 cs42l52->dev = &i2c_client->dev; 1217 cs42l52->dev = &i2c_client->dev;
1219 1218
1220 cs42l52->regmap = regmap_init_i2c(i2c_client, &cs42l52_regmap); 1219 cs42l52->regmap = devm_regmap_init_i2c(i2c_client, &cs42l52_regmap);
1221 if (IS_ERR(cs42l52->regmap)) { 1220 if (IS_ERR(cs42l52->regmap)) {
1222 ret = PTR_ERR(cs42l52->regmap); 1221 ret = PTR_ERR(cs42l52->regmap);
1223 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); 1222 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
1224 goto err; 1223 return ret;
1225 } 1224 }
1226 1225
1227 i2c_set_clientdata(i2c_client, cs42l52); 1226 i2c_set_clientdata(i2c_client, cs42l52);
@@ -1243,7 +1242,7 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
1243 dev_err(&i2c_client->dev, 1242 dev_err(&i2c_client->dev,
1244 "CS42L52 Device ID (%X). Expected %X\n", 1243 "CS42L52 Device ID (%X). Expected %X\n",
1245 devid, CS42L52_CHIP_ID); 1244 devid, CS42L52_CHIP_ID);
1246 goto err_regmap; 1245 return ret;
1247 } 1246 }
1248 1247
1249 regcache_cache_only(cs42l52->regmap, true); 1248 regcache_cache_only(cs42l52->regmap, true);
@@ -1251,23 +1250,13 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
1251 ret = snd_soc_register_codec(&i2c_client->dev, 1250 ret = snd_soc_register_codec(&i2c_client->dev,
1252 &soc_codec_dev_cs42l52, &cs42l52_dai, 1); 1251 &soc_codec_dev_cs42l52, &cs42l52_dai, 1);
1253 if (ret < 0) 1252 if (ret < 0)
1254 goto err_regmap; 1253 return ret;
1255 return 0; 1254 return 0;
1256
1257err_regmap:
1258 regmap_exit(cs42l52->regmap);
1259
1260err:
1261 return ret;
1262} 1255}
1263 1256
1264static int cs42l52_i2c_remove(struct i2c_client *client) 1257static int cs42l52_i2c_remove(struct i2c_client *client)
1265{ 1258{
1266 struct cs42l52_private *cs42l52 = i2c_get_clientdata(client);
1267
1268 snd_soc_unregister_codec(&client->dev); 1259 snd_soc_unregister_codec(&client->dev);
1269 regmap_exit(cs42l52->regmap);
1270
1271 return 0; 1260 return 0;
1272} 1261}
1273 1262
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
index e0d45fdaa750..2c08c4cb465a 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -1362,11 +1362,11 @@ static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client,
1362 1362
1363 i2c_set_clientdata(i2c_client, cs42l73); 1363 i2c_set_clientdata(i2c_client, cs42l73);
1364 1364
1365 cs42l73->regmap = regmap_init_i2c(i2c_client, &cs42l73_regmap); 1365 cs42l73->regmap = devm_regmap_init_i2c(i2c_client, &cs42l73_regmap);
1366 if (IS_ERR(cs42l73->regmap)) { 1366 if (IS_ERR(cs42l73->regmap)) {
1367 ret = PTR_ERR(cs42l73->regmap); 1367 ret = PTR_ERR(cs42l73->regmap);
1368 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); 1368 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
1369 goto err; 1369 return ret;
1370 } 1370 }
1371 /* initialize codec */ 1371 /* initialize codec */
1372 ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, &reg); 1372 ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, &reg);
@@ -1384,13 +1384,13 @@ static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client,
1384 dev_err(&i2c_client->dev, 1384 dev_err(&i2c_client->dev,
1385 "CS42L73 Device ID (%X). Expected %X\n", 1385 "CS42L73 Device ID (%X). Expected %X\n",
1386 devid, CS42L73_DEVID); 1386 devid, CS42L73_DEVID);
1387 goto err_regmap; 1387 return ret;
1388 } 1388 }
1389 1389
1390 ret = regmap_read(cs42l73->regmap, CS42L73_REVID, &reg); 1390 ret = regmap_read(cs42l73->regmap, CS42L73_REVID, &reg);
1391 if (ret < 0) { 1391 if (ret < 0) {
1392 dev_err(&i2c_client->dev, "Get Revision ID failed\n"); 1392 dev_err(&i2c_client->dev, "Get Revision ID failed\n");
1393 goto err_regmap; 1393 return ret;;
1394 } 1394 }
1395 1395
1396 dev_info(&i2c_client->dev, 1396 dev_info(&i2c_client->dev,
@@ -1402,23 +1402,13 @@ static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client,
1402 &soc_codec_dev_cs42l73, cs42l73_dai, 1402 &soc_codec_dev_cs42l73, cs42l73_dai,
1403 ARRAY_SIZE(cs42l73_dai)); 1403 ARRAY_SIZE(cs42l73_dai));
1404 if (ret < 0) 1404 if (ret < 0)
1405 goto err_regmap; 1405 return ret;
1406 return 0; 1406 return 0;
1407
1408err_regmap:
1409 regmap_exit(cs42l73->regmap);
1410
1411err:
1412 return ret;
1413} 1407}
1414 1408
1415static __devexit int cs42l73_i2c_remove(struct i2c_client *client) 1409static __devexit int cs42l73_i2c_remove(struct i2c_client *client)
1416{ 1410{
1417 struct cs42l73_private *cs42l73 = i2c_get_clientdata(client);
1418
1419 snd_soc_unregister_codec(&client->dev); 1411 snd_soc_unregister_codec(&client->dev);
1420 regmap_exit(cs42l73->regmap);
1421
1422 return 0; 1412 return 0;
1423} 1413}
1424 1414
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c
new file mode 100644
index 000000000000..01be2a320e21
--- /dev/null
+++ b/sound/soc/codecs/da732x.c
@@ -0,0 +1,1627 @@
1/*
2 * da732x.c --- Dialog DA732X ALSA SoC Audio Driver
3 *
4 * Copyright (C) 2012 Dialog Semiconductor GmbH
5 *
6 * Author: Michal Hajduk <Michal.Hajduk@diasemi.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/regmap.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h>
22#include <linux/sysfs.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#include <asm/div64.h>
31
32#include "da732x.h"
33#include "da732x_reg.h"
34
35
36struct da732x_priv {
37 struct regmap *regmap;
38 struct snd_soc_codec *codec;
39
40 unsigned int sysclk;
41 bool pll_en;
42};
43
44/*
45 * da732x register cache - default settings
46 */
47static struct reg_default da732x_reg_cache[] = {
48 { DA732X_REG_REF1 , 0x02 },
49 { DA732X_REG_BIAS_EN , 0x80 },
50 { DA732X_REG_BIAS1 , 0x00 },
51 { DA732X_REG_BIAS2 , 0x00 },
52 { DA732X_REG_BIAS3 , 0x00 },
53 { DA732X_REG_BIAS4 , 0x00 },
54 { DA732X_REG_MICBIAS2 , 0x00 },
55 { DA732X_REG_MICBIAS1 , 0x00 },
56 { DA732X_REG_MICDET , 0x00 },
57 { DA732X_REG_MIC1_PRE , 0x01 },
58 { DA732X_REG_MIC1 , 0x40 },
59 { DA732X_REG_MIC2_PRE , 0x01 },
60 { DA732X_REG_MIC2 , 0x40 },
61 { DA732X_REG_AUX1L , 0x75 },
62 { DA732X_REG_AUX1R , 0x75 },
63 { DA732X_REG_MIC3_PRE , 0x01 },
64 { DA732X_REG_MIC3 , 0x40 },
65 { DA732X_REG_INP_PINBIAS , 0x00 },
66 { DA732X_REG_INP_ZC_EN , 0x00 },
67 { DA732X_REG_INP_MUX , 0x50 },
68 { DA732X_REG_HP_DET , 0x00 },
69 { DA732X_REG_HPL_DAC_OFFSET , 0x00 },
70 { DA732X_REG_HPL_DAC_OFF_CNTL , 0x00 },
71 { DA732X_REG_HPL_OUT_OFFSET , 0x00 },
72 { DA732X_REG_HPL , 0x40 },
73 { DA732X_REG_HPL_VOL , 0x0F },
74 { DA732X_REG_HPR_DAC_OFFSET , 0x00 },
75 { DA732X_REG_HPR_DAC_OFF_CNTL , 0x00 },
76 { DA732X_REG_HPR_OUT_OFFSET , 0x00 },
77 { DA732X_REG_HPR , 0x40 },
78 { DA732X_REG_HPR_VOL , 0x0F },
79 { DA732X_REG_LIN2 , 0x4F },
80 { DA732X_REG_LIN3 , 0x4F },
81 { DA732X_REG_LIN4 , 0x4F },
82 { DA732X_REG_OUT_ZC_EN , 0x00 },
83 { DA732X_REG_HP_LIN1_GNDSEL , 0x00 },
84 { DA732X_REG_CP_HP1 , 0x0C },
85 { DA732X_REG_CP_HP2 , 0x03 },
86 { DA732X_REG_CP_CTRL1 , 0x00 },
87 { DA732X_REG_CP_CTRL2 , 0x99 },
88 { DA732X_REG_CP_CTRL3 , 0x25 },
89 { DA732X_REG_CP_LEVEL_MASK , 0x3F },
90 { DA732X_REG_CP_DET , 0x00 },
91 { DA732X_REG_CP_STATUS , 0x00 },
92 { DA732X_REG_CP_THRESH1 , 0x00 },
93 { DA732X_REG_CP_THRESH2 , 0x00 },
94 { DA732X_REG_CP_THRESH3 , 0x00 },
95 { DA732X_REG_CP_THRESH4 , 0x00 },
96 { DA732X_REG_CP_THRESH5 , 0x00 },
97 { DA732X_REG_CP_THRESH6 , 0x00 },
98 { DA732X_REG_CP_THRESH7 , 0x00 },
99 { DA732X_REG_CP_THRESH8 , 0x00 },
100 { DA732X_REG_PLL_DIV_LO , 0x00 },
101 { DA732X_REG_PLL_DIV_MID , 0x00 },
102 { DA732X_REG_PLL_DIV_HI , 0x00 },
103 { DA732X_REG_PLL_CTRL , 0x02 },
104 { DA732X_REG_CLK_CTRL , 0xaa },
105 { DA732X_REG_CLK_DSP , 0x07 },
106 { DA732X_REG_CLK_EN1 , 0x00 },
107 { DA732X_REG_CLK_EN2 , 0x00 },
108 { DA732X_REG_CLK_EN3 , 0x00 },
109 { DA732X_REG_CLK_EN4 , 0x00 },
110 { DA732X_REG_CLK_EN5 , 0x00 },
111 { DA732X_REG_AIF_MCLK , 0x00 },
112 { DA732X_REG_AIFA1 , 0x02 },
113 { DA732X_REG_AIFA2 , 0x00 },
114 { DA732X_REG_AIFA3 , 0x08 },
115 { DA732X_REG_AIFB1 , 0x02 },
116 { DA732X_REG_AIFB2 , 0x00 },
117 { DA732X_REG_AIFB3 , 0x08 },
118 { DA732X_REG_PC_CTRL , 0xC0 },
119 { DA732X_REG_DATA_ROUTE , 0x00 },
120 { DA732X_REG_DSP_CTRL , 0x00 },
121 { DA732X_REG_CIF_CTRL2 , 0x00 },
122 { DA732X_REG_HANDSHAKE , 0x00 },
123 { DA732X_REG_SPARE1_OUT , 0x00 },
124 { DA732X_REG_SPARE2_OUT , 0x00 },
125 { DA732X_REG_SPARE1_IN , 0x00 },
126 { DA732X_REG_ADC1_PD , 0x00 },
127 { DA732X_REG_ADC1_HPF , 0x00 },
128 { DA732X_REG_ADC1_SEL , 0x00 },
129 { DA732X_REG_ADC1_EQ12 , 0x00 },
130 { DA732X_REG_ADC1_EQ34 , 0x00 },
131 { DA732X_REG_ADC1_EQ5 , 0x00 },
132 { DA732X_REG_ADC2_PD , 0x00 },
133 { DA732X_REG_ADC2_HPF , 0x00 },
134 { DA732X_REG_ADC2_SEL , 0x00 },
135 { DA732X_REG_ADC2_EQ12 , 0x00 },
136 { DA732X_REG_ADC2_EQ34 , 0x00 },
137 { DA732X_REG_ADC2_EQ5 , 0x00 },
138 { DA732X_REG_DAC1_HPF , 0x00 },
139 { DA732X_REG_DAC1_L_VOL , 0x00 },
140 { DA732X_REG_DAC1_R_VOL , 0x00 },
141 { DA732X_REG_DAC1_SEL , 0x00 },
142 { DA732X_REG_DAC1_SOFTMUTE , 0x00 },
143 { DA732X_REG_DAC1_EQ12 , 0x00 },
144 { DA732X_REG_DAC1_EQ34 , 0x00 },
145 { DA732X_REG_DAC1_EQ5 , 0x00 },
146 { DA732X_REG_DAC2_HPF , 0x00 },
147 { DA732X_REG_DAC2_L_VOL , 0x00 },
148 { DA732X_REG_DAC2_R_VOL , 0x00 },
149 { DA732X_REG_DAC2_SEL , 0x00 },
150 { DA732X_REG_DAC2_SOFTMUTE , 0x00 },
151 { DA732X_REG_DAC2_EQ12 , 0x00 },
152 { DA732X_REG_DAC2_EQ34 , 0x00 },
153 { DA732X_REG_DAC2_EQ5 , 0x00 },
154 { DA732X_REG_DAC3_HPF , 0x00 },
155 { DA732X_REG_DAC3_VOL , 0x00 },
156 { DA732X_REG_DAC3_SEL , 0x00 },
157 { DA732X_REG_DAC3_SOFTMUTE , 0x00 },
158 { DA732X_REG_DAC3_EQ12 , 0x00 },
159 { DA732X_REG_DAC3_EQ34 , 0x00 },
160 { DA732X_REG_DAC3_EQ5 , 0x00 },
161 { DA732X_REG_BIQ_BYP , 0x00 },
162 { DA732X_REG_DMA_CMD , 0x00 },
163 { DA732X_REG_DMA_ADDR0 , 0x00 },
164 { DA732X_REG_DMA_ADDR1 , 0x00 },
165 { DA732X_REG_DMA_DATA0 , 0x00 },
166 { DA732X_REG_DMA_DATA1 , 0x00 },
167 { DA732X_REG_DMA_DATA2 , 0x00 },
168 { DA732X_REG_DMA_DATA3 , 0x00 },
169 { DA732X_REG_UNLOCK , 0x00 },
170};
171
172static inline int da732x_get_input_div(struct snd_soc_codec *codec, int sysclk)
173{
174 int val;
175 int ret;
176
177 if (sysclk < DA732X_MCLK_10MHZ) {
178 val = DA732X_MCLK_RET_0_10MHZ;
179 ret = DA732X_MCLK_VAL_0_10MHZ;
180 } else if ((sysclk >= DA732X_MCLK_10MHZ) &&
181 (sysclk < DA732X_MCLK_20MHZ)) {
182 val = DA732X_MCLK_RET_10_20MHZ;
183 ret = DA732X_MCLK_VAL_10_20MHZ;
184 } else if ((sysclk >= DA732X_MCLK_20MHZ) &&
185 (sysclk < DA732X_MCLK_40MHZ)) {
186 val = DA732X_MCLK_RET_20_40MHZ;
187 ret = DA732X_MCLK_VAL_20_40MHZ;
188 } else if ((sysclk >= DA732X_MCLK_40MHZ) &&
189 (sysclk <= DA732X_MCLK_54MHZ)) {
190 val = DA732X_MCLK_RET_40_54MHZ;
191 ret = DA732X_MCLK_VAL_40_54MHZ;
192 } else {
193 return -EINVAL;
194 }
195
196 snd_soc_write(codec, DA732X_REG_PLL_CTRL, val);
197
198 return ret;
199}
200
201static void da732x_set_charge_pump(struct snd_soc_codec *codec, int state)
202{
203 switch (state) {
204 case DA732X_ENABLE_CP:
205 snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_EN);
206 snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_EN |
207 DA732X_HP_CP_REG | DA732X_HP_CP_PULSESKIP);
208 snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA732X_CP_EN |
209 DA732X_CP_CTRL_CPVDD1);
210 snd_soc_write(codec, DA732X_REG_CP_CTRL2,
211 DA732X_CP_MANAGE_MAGNITUDE | DA732X_CP_BOOST);
212 snd_soc_write(codec, DA732X_REG_CP_CTRL3, DA732X_CP_1MHZ);
213 break;
214 case DA732X_DISABLE_CP:
215 snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_DIS);
216 snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_DIS);
217 snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA723X_CP_DIS);
218 break;
219 default:
220 pr_err(KERN_ERR "Wrong charge pump state\n");
221 break;
222 }
223}
224
225static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, DA732X_MIC_PRE_VOL_DB_MIN,
226 DA732X_MIC_PRE_VOL_DB_INC, 0);
227
228static const DECLARE_TLV_DB_SCALE(mic_pga_tlv, DA732X_MIC_VOL_DB_MIN,
229 DA732X_MIC_VOL_DB_INC, 0);
230
231static const DECLARE_TLV_DB_SCALE(aux_pga_tlv, DA732X_AUX_VOL_DB_MIN,
232 DA732X_AUX_VOL_DB_INC, 0);
233
234static const DECLARE_TLV_DB_SCALE(hp_pga_tlv, DA732X_HP_VOL_DB_MIN,
235 DA732X_AUX_VOL_DB_INC, 0);
236
237static const DECLARE_TLV_DB_SCALE(lin2_pga_tlv, DA732X_LIN2_VOL_DB_MIN,
238 DA732X_LIN2_VOL_DB_INC, 0);
239
240static const DECLARE_TLV_DB_SCALE(lin3_pga_tlv, DA732X_LIN3_VOL_DB_MIN,
241 DA732X_LIN3_VOL_DB_INC, 0);
242
243static const DECLARE_TLV_DB_SCALE(lin4_pga_tlv, DA732X_LIN4_VOL_DB_MIN,
244 DA732X_LIN4_VOL_DB_INC, 0);
245
246static const DECLARE_TLV_DB_SCALE(adc_pga_tlv, DA732X_ADC_VOL_DB_MIN,
247 DA732X_ADC_VOL_DB_INC, 0);
248
249static const DECLARE_TLV_DB_SCALE(dac_pga_tlv, DA732X_DAC_VOL_DB_MIN,
250 DA732X_DAC_VOL_DB_INC, 0);
251
252static const DECLARE_TLV_DB_SCALE(eq_band_pga_tlv, DA732X_EQ_BAND_VOL_DB_MIN,
253 DA732X_EQ_BAND_VOL_DB_INC, 0);
254
255static const DECLARE_TLV_DB_SCALE(eq_overall_tlv, DA732X_EQ_OVERALL_VOL_DB_MIN,
256 DA732X_EQ_OVERALL_VOL_DB_INC, 0);
257
258/* High Pass Filter */
259static const char *da732x_hpf_mode[] = {
260 "Disable", "Music", "Voice",
261};
262
263static const char *da732x_hpf_music[] = {
264 "1.8Hz", "3.75Hz", "7.5Hz", "15Hz",
265};
266
267static const char *da732x_hpf_voice[] = {
268 "2.5Hz", "25Hz", "50Hz", "100Hz",
269 "150Hz", "200Hz", "300Hz", "400Hz"
270};
271
272static const struct soc_enum da732x_dac1_hpf_mode_enum[] = {
273 SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MODE_SHIFT,
274 DA732X_HPF_MODE_MAX, da732x_hpf_mode)
275};
276
277static const struct soc_enum da732x_dac2_hpf_mode_enum[] = {
278 SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MODE_SHIFT,
279 DA732X_HPF_MODE_MAX, da732x_hpf_mode)
280};
281
282static const struct soc_enum da732x_dac3_hpf_mode_enum[] = {
283 SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MODE_SHIFT,
284 DA732X_HPF_MODE_MAX, da732x_hpf_mode)
285};
286
287static const struct soc_enum da732x_adc1_hpf_mode_enum[] = {
288 SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MODE_SHIFT,
289 DA732X_HPF_MODE_MAX, da732x_hpf_mode)
290};
291
292static const struct soc_enum da732x_adc2_hpf_mode_enum[] = {
293 SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MODE_SHIFT,
294 DA732X_HPF_MODE_MAX, da732x_hpf_mode)
295};
296
297static const struct soc_enum da732x_dac1_hp_filter_enum[] = {
298 SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MUSIC_SHIFT,
299 DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
300};
301
302static const struct soc_enum da732x_dac2_hp_filter_enum[] = {
303 SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MUSIC_SHIFT,
304 DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
305};
306
307static const struct soc_enum da732x_dac3_hp_filter_enum[] = {
308 SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MUSIC_SHIFT,
309 DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
310};
311
312static const struct soc_enum da732x_adc1_hp_filter_enum[] = {
313 SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MUSIC_SHIFT,
314 DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
315};
316
317static const struct soc_enum da732x_adc2_hp_filter_enum[] = {
318 SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MUSIC_SHIFT,
319 DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
320};
321
322static const struct soc_enum da732x_dac1_voice_filter_enum[] = {
323 SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_VOICE_SHIFT,
324 DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
325};
326
327static const struct soc_enum da732x_dac2_voice_filter_enum[] = {
328 SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_VOICE_SHIFT,
329 DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
330};
331
332static const struct soc_enum da732x_dac3_voice_filter_enum[] = {
333 SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_VOICE_SHIFT,
334 DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
335};
336
337static const struct soc_enum da732x_adc1_voice_filter_enum[] = {
338 SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_VOICE_SHIFT,
339 DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
340};
341
342static const struct soc_enum da732x_adc2_voice_filter_enum[] = {
343 SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_VOICE_SHIFT,
344 DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
345};
346
347
348static int da732x_hpf_set(struct snd_kcontrol *kcontrol,
349 struct snd_ctl_elem_value *ucontrol)
350{
351 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
352 struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value;
353 unsigned int reg = enum_ctrl->reg;
354 unsigned int sel = ucontrol->value.integer.value[0];
355 unsigned int bits;
356
357 switch (sel) {
358 case DA732X_HPF_DISABLED:
359 bits = DA732X_HPF_DIS;
360 break;
361 case DA732X_HPF_VOICE:
362 bits = DA732X_HPF_VOICE_EN;
363 break;
364 case DA732X_HPF_MUSIC:
365 bits = DA732X_HPF_MUSIC_EN;
366 break;
367 default:
368 return -EINVAL;
369 }
370
371 snd_soc_update_bits(codec, reg, DA732X_HPF_MASK, bits);
372
373 return 0;
374}
375
376static int da732x_hpf_get(struct snd_kcontrol *kcontrol,
377 struct snd_ctl_elem_value *ucontrol)
378{
379 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
380 struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value;
381 unsigned int reg = enum_ctrl->reg;
382 int val;
383
384 val = snd_soc_read(codec, reg) & DA732X_HPF_MASK;
385
386 switch (val) {
387 case DA732X_HPF_VOICE_EN:
388 ucontrol->value.integer.value[0] = DA732X_HPF_VOICE;
389 break;
390 case DA732X_HPF_MUSIC_EN:
391 ucontrol->value.integer.value[0] = DA732X_HPF_MUSIC;
392 break;
393 default:
394 ucontrol->value.integer.value[0] = DA732X_HPF_DISABLED;
395 break;
396 }
397
398 return 0;
399}
400
401static const struct snd_kcontrol_new da732x_snd_controls[] = {
402 /* Input PGAs */
403 SOC_SINGLE_RANGE_TLV("MIC1 Boost Volume", DA732X_REG_MIC1_PRE,
404 DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN,
405 DA732X_MICBOOST_MAX, 0, mic_boost_tlv),
406 SOC_SINGLE_RANGE_TLV("MIC2 Boost Volume", DA732X_REG_MIC2_PRE,
407 DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN,
408 DA732X_MICBOOST_MAX, 0, mic_boost_tlv),
409 SOC_SINGLE_RANGE_TLV("MIC3 Boost Volume", DA732X_REG_MIC3_PRE,
410 DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN,
411 DA732X_MICBOOST_MAX, 0, mic_boost_tlv),
412
413 /* MICs */
414 SOC_SINGLE("MIC1 Switch", DA732X_REG_MIC1, DA732X_MIC_MUTE_SHIFT,
415 DA732X_SWITCH_MAX, DA732X_INVERT),
416 SOC_SINGLE_RANGE_TLV("MIC1 Volume", DA732X_REG_MIC1,
417 DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN,
418 DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv),
419 SOC_SINGLE("MIC2 Switch", DA732X_REG_MIC2, DA732X_MIC_MUTE_SHIFT,
420 DA732X_SWITCH_MAX, DA732X_INVERT),
421 SOC_SINGLE_RANGE_TLV("MIC2 Volume", DA732X_REG_MIC2,
422 DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN,
423 DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv),
424 SOC_SINGLE("MIC3 Switch", DA732X_REG_MIC3, DA732X_MIC_MUTE_SHIFT,
425 DA732X_SWITCH_MAX, DA732X_INVERT),
426 SOC_SINGLE_RANGE_TLV("MIC3 Volume", DA732X_REG_MIC3,
427 DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN,
428 DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv),
429
430 /* AUXs */
431 SOC_SINGLE("AUX1L Switch", DA732X_REG_AUX1L, DA732X_AUX_MUTE_SHIFT,
432 DA732X_SWITCH_MAX, DA732X_INVERT),
433 SOC_SINGLE_TLV("AUX1L Volume", DA732X_REG_AUX1L,
434 DA732X_AUX_VOL_SHIFT, DA732X_AUX_VOL_VAL_MAX,
435 DA732X_NO_INVERT, aux_pga_tlv),
436 SOC_SINGLE("AUX1R Switch", DA732X_REG_AUX1R, DA732X_AUX_MUTE_SHIFT,
437 DA732X_SWITCH_MAX, DA732X_INVERT),
438 SOC_SINGLE_TLV("AUX1R Volume", DA732X_REG_AUX1R,
439 DA732X_AUX_VOL_SHIFT, DA732X_AUX_VOL_VAL_MAX,
440 DA732X_NO_INVERT, aux_pga_tlv),
441
442 /* ADCs */
443 SOC_DOUBLE_TLV("ADC1 Volume", DA732X_REG_ADC1_SEL,
444 DA732X_ADCL_VOL_SHIFT, DA732X_ADCR_VOL_SHIFT,
445 DA732X_ADC_VOL_VAL_MAX, DA732X_INVERT, adc_pga_tlv),
446
447 SOC_DOUBLE_TLV("ADC2 Volume", DA732X_REG_ADC2_SEL,
448 DA732X_ADCL_VOL_SHIFT, DA732X_ADCR_VOL_SHIFT,
449 DA732X_ADC_VOL_VAL_MAX, DA732X_INVERT, adc_pga_tlv),
450
451 /* DACs */
452 SOC_DOUBLE("Digital Playback DAC12 Switch", DA732X_REG_DAC1_SEL,
453 DA732X_DACL_MUTE_SHIFT, DA732X_DACR_MUTE_SHIFT,
454 DA732X_SWITCH_MAX, DA732X_INVERT),
455 SOC_DOUBLE_R_TLV("Digital Playback DAC12 Volume", DA732X_REG_DAC1_L_VOL,
456 DA732X_REG_DAC1_R_VOL, DA732X_DAC_VOL_SHIFT,
457 DA732X_DAC_VOL_VAL_MAX, DA732X_INVERT, dac_pga_tlv),
458 SOC_SINGLE("Digital Playback DAC3 Switch", DA732X_REG_DAC2_SEL,
459 DA732X_DACL_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT),
460 SOC_SINGLE_TLV("Digital Playback DAC3 Volume", DA732X_REG_DAC2_L_VOL,
461 DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX,
462 DA732X_INVERT, dac_pga_tlv),
463 SOC_SINGLE("Digital Playback DAC4 Switch", DA732X_REG_DAC2_SEL,
464 DA732X_DACR_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT),
465 SOC_SINGLE_TLV("Digital Playback DAC4 Volume", DA732X_REG_DAC2_R_VOL,
466 DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX,
467 DA732X_INVERT, dac_pga_tlv),
468 SOC_SINGLE("Digital Playback DAC5 Switch", DA732X_REG_DAC3_SEL,
469 DA732X_DACL_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT),
470 SOC_SINGLE_TLV("Digital Playback DAC5 Volume", DA732X_REG_DAC3_VOL,
471 DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX,
472 DA732X_INVERT, dac_pga_tlv),
473
474 /* High Pass Filters */
475 SOC_ENUM_EXT("DAC1 High Pass Filter Mode",
476 da732x_dac1_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set),
477 SOC_ENUM("DAC1 High Pass Filter", da732x_dac1_hp_filter_enum),
478 SOC_ENUM("DAC1 Voice Filter", da732x_dac1_voice_filter_enum),
479
480 SOC_ENUM_EXT("DAC2 High Pass Filter Mode",
481 da732x_dac2_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set),
482 SOC_ENUM("DAC2 High Pass Filter", da732x_dac2_hp_filter_enum),
483 SOC_ENUM("DAC2 Voice Filter", da732x_dac2_voice_filter_enum),
484
485 SOC_ENUM_EXT("DAC3 High Pass Filter Mode",
486 da732x_dac3_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set),
487 SOC_ENUM("DAC3 High Pass Filter", da732x_dac3_hp_filter_enum),
488 SOC_ENUM("DAC3 Filter Mode", da732x_dac3_voice_filter_enum),
489
490 SOC_ENUM_EXT("ADC1 High Pass Filter Mode",
491 da732x_adc1_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set),
492 SOC_ENUM("ADC1 High Pass Filter", da732x_adc1_hp_filter_enum),
493 SOC_ENUM("ADC1 Voice Filter", da732x_adc1_voice_filter_enum),
494
495 SOC_ENUM_EXT("ADC2 High Pass Filter Mode",
496 da732x_adc2_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set),
497 SOC_ENUM("ADC2 High Pass Filter", da732x_adc2_hp_filter_enum),
498 SOC_ENUM("ADC2 Voice Filter", da732x_adc2_voice_filter_enum),
499
500 /* Equalizers */
501 SOC_SINGLE("ADC1 EQ Switch", DA732X_REG_ADC1_EQ5,
502 DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT),
503 SOC_SINGLE_TLV("ADC1 EQ Band 1 Volume", DA732X_REG_ADC1_EQ12,
504 DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX,
505 DA732X_INVERT, eq_band_pga_tlv),
506 SOC_SINGLE_TLV("ADC1 EQ Band 2 Volume", DA732X_REG_ADC1_EQ12,
507 DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX,
508 DA732X_INVERT, eq_band_pga_tlv),
509 SOC_SINGLE_TLV("ADC1 EQ Band 3 Volume", DA732X_REG_ADC1_EQ34,
510 DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX,
511 DA732X_INVERT, eq_band_pga_tlv),
512 SOC_SINGLE_TLV("ADC1 EQ Band 4 Volume", DA732X_REG_ADC1_EQ34,
513 DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX,
514 DA732X_INVERT, eq_band_pga_tlv),
515 SOC_SINGLE_TLV("ADC1 EQ Band 5 Volume", DA732X_REG_ADC1_EQ5,
516 DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX,
517 DA732X_INVERT, eq_band_pga_tlv),
518 SOC_SINGLE_TLV("ADC1 EQ Overall Volume", DA732X_REG_ADC1_EQ5,
519 DA732X_EQ_OVERALL_SHIFT, DA732X_EQ_OVERALL_VOL_VAL_MAX,
520 DA732X_INVERT, eq_overall_tlv),
521
522 SOC_SINGLE("ADC2 EQ Switch", DA732X_REG_ADC2_EQ5,
523 DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT),
524 SOC_SINGLE_TLV("ADC2 EQ Band 1 Volume", DA732X_REG_ADC2_EQ12,
525 DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX,
526 DA732X_INVERT, eq_band_pga_tlv),
527 SOC_SINGLE_TLV("ADC2 EQ Band 2 Volume", DA732X_REG_ADC2_EQ12,
528 DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX,
529 DA732X_INVERT, eq_band_pga_tlv),
530 SOC_SINGLE_TLV("ADC2 EQ Band 3 Volume", DA732X_REG_ADC2_EQ34,
531 DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX,
532 DA732X_INVERT, eq_band_pga_tlv),
533 SOC_SINGLE_TLV("ACD2 EQ Band 4 Volume", DA732X_REG_ADC2_EQ34,
534 DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX,
535 DA732X_INVERT, eq_band_pga_tlv),
536 SOC_SINGLE_TLV("ACD2 EQ Band 5 Volume", DA732X_REG_ADC2_EQ5,
537 DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX,
538 DA732X_INVERT, eq_band_pga_tlv),
539 SOC_SINGLE_TLV("ADC2 EQ Overall Volume", DA732X_REG_ADC1_EQ5,
540 DA732X_EQ_OVERALL_SHIFT, DA732X_EQ_OVERALL_VOL_VAL_MAX,
541 DA732X_INVERT, eq_overall_tlv),
542
543 SOC_SINGLE("DAC1 EQ Switch", DA732X_REG_DAC1_EQ5,
544 DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT),
545 SOC_SINGLE_TLV("DAC1 EQ Band 1 Volume", DA732X_REG_DAC1_EQ12,
546 DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX,
547 DA732X_INVERT, eq_band_pga_tlv),
548 SOC_SINGLE_TLV("DAC1 EQ Band 2 Volume", DA732X_REG_DAC1_EQ12,
549 DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX,
550 DA732X_INVERT, eq_band_pga_tlv),
551 SOC_SINGLE_TLV("DAC1 EQ Band 3 Volume", DA732X_REG_DAC1_EQ34,
552 DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX,
553 DA732X_INVERT, eq_band_pga_tlv),
554 SOC_SINGLE_TLV("DAC1 EQ Band 4 Volume", DA732X_REG_DAC1_EQ34,
555 DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX,
556 DA732X_INVERT, eq_band_pga_tlv),
557 SOC_SINGLE_TLV("DAC1 EQ Band 5 Volume", DA732X_REG_DAC1_EQ5,
558 DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX,
559 DA732X_INVERT, eq_band_pga_tlv),
560
561 SOC_SINGLE("DAC2 EQ Switch", DA732X_REG_DAC2_EQ5,
562 DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT),
563 SOC_SINGLE_TLV("DAC2 EQ Band 1 Volume", DA732X_REG_DAC2_EQ12,
564 DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX,
565 DA732X_INVERT, eq_band_pga_tlv),
566 SOC_SINGLE_TLV("DAC2 EQ Band 2 Volume", DA732X_REG_DAC2_EQ12,
567 DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX,
568 DA732X_INVERT, eq_band_pga_tlv),
569 SOC_SINGLE_TLV("DAC2 EQ Band 3 Volume", DA732X_REG_DAC2_EQ34,
570 DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX,
571 DA732X_INVERT, eq_band_pga_tlv),
572 SOC_SINGLE_TLV("DAC2 EQ Band 4 Volume", DA732X_REG_DAC2_EQ34,
573 DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX,
574 DA732X_INVERT, eq_band_pga_tlv),
575 SOC_SINGLE_TLV("DAC2 EQ Band 5 Volume", DA732X_REG_DAC2_EQ5,
576 DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX,
577 DA732X_INVERT, eq_band_pga_tlv),
578
579 SOC_SINGLE("DAC3 EQ Switch", DA732X_REG_DAC3_EQ5,
580 DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT),
581 SOC_SINGLE_TLV("DAC3 EQ Band 1 Volume", DA732X_REG_DAC3_EQ12,
582 DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX,
583 DA732X_INVERT, eq_band_pga_tlv),
584 SOC_SINGLE_TLV("DAC3 EQ Band 2 Volume", DA732X_REG_DAC3_EQ12,
585 DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX,
586 DA732X_INVERT, eq_band_pga_tlv),
587 SOC_SINGLE_TLV("DAC3 EQ Band 3 Volume", DA732X_REG_DAC3_EQ34,
588 DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX,
589 DA732X_INVERT, eq_band_pga_tlv),
590 SOC_SINGLE_TLV("DAC3 EQ Band 4 Volume", DA732X_REG_DAC3_EQ34,
591 DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX,
592 DA732X_INVERT, eq_band_pga_tlv),
593 SOC_SINGLE_TLV("DAC3 EQ Band 5 Volume", DA732X_REG_DAC3_EQ5,
594 DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX,
595 DA732X_INVERT, eq_band_pga_tlv),
596
597 /* Lineout 2 Reciever*/
598 SOC_SINGLE("Lineout 2 Switch", DA732X_REG_LIN2, DA732X_LOUT_MUTE_SHIFT,
599 DA732X_SWITCH_MAX, DA732X_INVERT),
600 SOC_SINGLE_TLV("Lineout 2 Volume", DA732X_REG_LIN2,
601 DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX,
602 DA732X_NO_INVERT, lin2_pga_tlv),
603
604 /* Lineout 3 SPEAKER*/
605 SOC_SINGLE("Lineout 3 Switch", DA732X_REG_LIN3, DA732X_LOUT_MUTE_SHIFT,
606 DA732X_SWITCH_MAX, DA732X_INVERT),
607 SOC_SINGLE_TLV("Lineout 3 Volume", DA732X_REG_LIN3,
608 DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX,
609 DA732X_NO_INVERT, lin3_pga_tlv),
610
611 /* Lineout 4 */
612 SOC_SINGLE("Lineout 4 Switch", DA732X_REG_LIN4, DA732X_LOUT_MUTE_SHIFT,
613 DA732X_SWITCH_MAX, DA732X_INVERT),
614 SOC_SINGLE_TLV("Lineout 4 Volume", DA732X_REG_LIN4,
615 DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX,
616 DA732X_NO_INVERT, lin4_pga_tlv),
617
618 /* Headphones */
619 SOC_DOUBLE_R("Headphone Switch", DA732X_REG_HPR, DA732X_REG_HPL,
620 DA732X_HP_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT),
621 SOC_DOUBLE_R_TLV("Headphone Volume", DA732X_REG_HPL_VOL,
622 DA732X_REG_HPR_VOL, DA732X_HP_VOL_SHIFT,
623 DA732X_HP_VOL_VAL_MAX, DA732X_NO_INVERT, hp_pga_tlv),
624};
625
626static int da732x_adc_event(struct snd_soc_dapm_widget *w,
627 struct snd_kcontrol *kcontrol, int event)
628{
629 struct snd_soc_codec *codec = w->codec;
630
631 switch (event) {
632 case SND_SOC_DAPM_POST_PMU:
633 switch (w->reg) {
634 case DA732X_REG_ADC1_PD:
635 snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
636 DA732X_ADCA_BB_CLK_EN,
637 DA732X_ADCA_BB_CLK_EN);
638 break;
639 case DA732X_REG_ADC2_PD:
640 snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
641 DA732X_ADCC_BB_CLK_EN,
642 DA732X_ADCC_BB_CLK_EN);
643 break;
644 default:
645 return -EINVAL;
646 }
647
648 snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK,
649 DA732X_ADC_SET_ACT);
650 snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK,
651 DA732X_ADC_ON);
652 break;
653 case SND_SOC_DAPM_POST_PMD:
654 snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK,
655 DA732X_ADC_OFF);
656 snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK,
657 DA732X_ADC_SET_RST);
658
659 switch (w->reg) {
660 case DA732X_REG_ADC1_PD:
661 snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
662 DA732X_ADCA_BB_CLK_EN, 0);
663 break;
664 case DA732X_REG_ADC2_PD:
665 snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
666 DA732X_ADCC_BB_CLK_EN, 0);
667 break;
668 default:
669 return -EINVAL;
670 }
671
672 break;
673 default:
674 return -EINVAL;
675 }
676
677 return 0;
678}
679
680static int da732x_out_pga_event(struct snd_soc_dapm_widget *w,
681 struct snd_kcontrol *kcontrol, int event)
682{
683 struct snd_soc_codec *codec = w->codec;
684
685 switch (event) {
686 case SND_SOC_DAPM_POST_PMU:
687 snd_soc_update_bits(codec, w->reg,
688 (1 << w->shift) | DA732X_OUT_HIZ_EN,
689 (1 << w->shift) | DA732X_OUT_HIZ_EN);
690 break;
691 case SND_SOC_DAPM_POST_PMD:
692 snd_soc_update_bits(codec, w->reg,
693 (1 << w->shift) | DA732X_OUT_HIZ_EN,
694 (1 << w->shift) | DA732X_OUT_HIZ_DIS);
695 break;
696 default:
697 return -EINVAL;
698 }
699
700 return 0;
701}
702
703static const char *adcl_text[] = {
704 "AUX1L", "MIC1"
705};
706
707static const char *adcr_text[] = {
708 "AUX1R", "MIC2", "MIC3"
709};
710
711static const char *enable_text[] = {
712 "Disabled",
713 "Enabled"
714};
715
716/* ADC1LMUX */
717static const struct soc_enum adc1l_enum =
718 SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1L_MUX_SEL_SHIFT,
719 DA732X_ADCL_MUX_MAX, adcl_text);
720static const struct snd_kcontrol_new adc1l_mux =
721 SOC_DAPM_ENUM("ADC Route", adc1l_enum);
722
723/* ADC1RMUX */
724static const struct soc_enum adc1r_enum =
725 SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1R_MUX_SEL_SHIFT,
726 DA732X_ADCR_MUX_MAX, adcr_text);
727static const struct snd_kcontrol_new adc1r_mux =
728 SOC_DAPM_ENUM("ADC Route", adc1r_enum);
729
730/* ADC2LMUX */
731static const struct soc_enum adc2l_enum =
732 SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2L_MUX_SEL_SHIFT,
733 DA732X_ADCL_MUX_MAX, adcl_text);
734static const struct snd_kcontrol_new adc2l_mux =
735 SOC_DAPM_ENUM("ADC Route", adc2l_enum);
736
737/* ADC2RMUX */
738static const struct soc_enum adc2r_enum =
739 SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2R_MUX_SEL_SHIFT,
740 DA732X_ADCR_MUX_MAX, adcr_text);
741
742static const struct snd_kcontrol_new adc2r_mux =
743 SOC_DAPM_ENUM("ADC Route", adc2r_enum);
744
745static const struct soc_enum da732x_hp_left_output =
746 SOC_ENUM_SINGLE(DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN_SHIFT,
747 DA732X_DAC_EN_MAX, enable_text);
748
749static const struct snd_kcontrol_new hpl_mux =
750 SOC_DAPM_ENUM("HPL Switch", da732x_hp_left_output);
751
752static const struct soc_enum da732x_hp_right_output =
753 SOC_ENUM_SINGLE(DA732X_REG_HPR, DA732X_HP_OUT_DAC_EN_SHIFT,
754 DA732X_DAC_EN_MAX, enable_text);
755
756static const struct snd_kcontrol_new hpr_mux =
757 SOC_DAPM_ENUM("HPR Switch", da732x_hp_right_output);
758
759static const struct soc_enum da732x_speaker_output =
760 SOC_ENUM_SINGLE(DA732X_REG_LIN3, DA732X_LOUT_DAC_EN_SHIFT,
761 DA732X_DAC_EN_MAX, enable_text);
762
763static const struct snd_kcontrol_new spk_mux =
764 SOC_DAPM_ENUM("SPK Switch", da732x_speaker_output);
765
766static const struct soc_enum da732x_lout4_output =
767 SOC_ENUM_SINGLE(DA732X_REG_LIN4, DA732X_LOUT_DAC_EN_SHIFT,
768 DA732X_DAC_EN_MAX, enable_text);
769
770static const struct snd_kcontrol_new lout4_mux =
771 SOC_DAPM_ENUM("LOUT4 Switch", da732x_lout4_output);
772
773static const struct soc_enum da732x_lout2_output =
774 SOC_ENUM_SINGLE(DA732X_REG_LIN2, DA732X_LOUT_DAC_EN_SHIFT,
775 DA732X_DAC_EN_MAX, enable_text);
776
777static const struct snd_kcontrol_new lout2_mux =
778 SOC_DAPM_ENUM("LOUT2 Switch", da732x_lout2_output);
779
780static const struct snd_soc_dapm_widget da732x_dapm_widgets[] = {
781 /* Supplies */
782 SND_SOC_DAPM_SUPPLY("ADC1 Supply", DA732X_REG_ADC1_PD, 0,
783 DA732X_NO_INVERT, da732x_adc_event,
784 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
785 SND_SOC_DAPM_SUPPLY("ADC2 Supply", DA732X_REG_ADC2_PD, 0,
786 DA732X_NO_INVERT, da732x_adc_event,
787 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
788 SND_SOC_DAPM_SUPPLY("DAC1 CLK", DA732X_REG_CLK_EN4,
789 DA732X_DACA_BB_CLK_SHIFT, DA732X_NO_INVERT,
790 NULL, 0),
791 SND_SOC_DAPM_SUPPLY("DAC2 CLK", DA732X_REG_CLK_EN4,
792 DA732X_DACC_BB_CLK_SHIFT, DA732X_NO_INVERT,
793 NULL, 0),
794 SND_SOC_DAPM_SUPPLY("DAC3 CLK", DA732X_REG_CLK_EN5,
795 DA732X_DACE_BB_CLK_SHIFT, DA732X_NO_INVERT,
796 NULL, 0),
797
798 /* Micbias */
799 SND_SOC_DAPM_SUPPLY("MICBIAS1", DA732X_REG_MICBIAS1,
800 DA732X_MICBIAS_EN_SHIFT,
801 DA732X_NO_INVERT, NULL, 0),
802 SND_SOC_DAPM_SUPPLY("MICBIAS2", DA732X_REG_MICBIAS2,
803 DA732X_MICBIAS_EN_SHIFT,
804 DA732X_NO_INVERT, NULL, 0),
805
806 /* Inputs */
807 SND_SOC_DAPM_INPUT("MIC1"),
808 SND_SOC_DAPM_INPUT("MIC2"),
809 SND_SOC_DAPM_INPUT("MIC3"),
810 SND_SOC_DAPM_INPUT("AUX1L"),
811 SND_SOC_DAPM_INPUT("AUX1R"),
812
813 /* Outputs */
814 SND_SOC_DAPM_OUTPUT("HPL"),
815 SND_SOC_DAPM_OUTPUT("HPR"),
816 SND_SOC_DAPM_OUTPUT("LOUTL"),
817 SND_SOC_DAPM_OUTPUT("LOUTR"),
818 SND_SOC_DAPM_OUTPUT("ClassD"),
819
820 /* ADCs */
821 SND_SOC_DAPM_ADC("ADC1L", NULL, DA732X_REG_ADC1_SEL,
822 DA732X_ADCL_EN_SHIFT, DA732X_NO_INVERT),
823 SND_SOC_DAPM_ADC("ADC1R", NULL, DA732X_REG_ADC1_SEL,
824 DA732X_ADCR_EN_SHIFT, DA732X_NO_INVERT),
825 SND_SOC_DAPM_ADC("ADC2L", NULL, DA732X_REG_ADC2_SEL,
826 DA732X_ADCL_EN_SHIFT, DA732X_NO_INVERT),
827 SND_SOC_DAPM_ADC("ADC2R", NULL, DA732X_REG_ADC2_SEL,
828 DA732X_ADCR_EN_SHIFT, DA732X_NO_INVERT),
829
830 /* DACs */
831 SND_SOC_DAPM_DAC("DAC1L", NULL, DA732X_REG_DAC1_SEL,
832 DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT),
833 SND_SOC_DAPM_DAC("DAC1R", NULL, DA732X_REG_DAC1_SEL,
834 DA732X_DACR_EN_SHIFT, DA732X_NO_INVERT),
835 SND_SOC_DAPM_DAC("DAC2L", NULL, DA732X_REG_DAC2_SEL,
836 DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT),
837 SND_SOC_DAPM_DAC("DAC2R", NULL, DA732X_REG_DAC2_SEL,
838 DA732X_DACR_EN_SHIFT, DA732X_NO_INVERT),
839 SND_SOC_DAPM_DAC("DAC3", NULL, DA732X_REG_DAC3_SEL,
840 DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT),
841
842 /* Input Pgas */
843 SND_SOC_DAPM_PGA("MIC1 PGA", DA732X_REG_MIC1, DA732X_MIC_EN_SHIFT,
844 0, NULL, 0),
845 SND_SOC_DAPM_PGA("MIC2 PGA", DA732X_REG_MIC2, DA732X_MIC_EN_SHIFT,
846 0, NULL, 0),
847 SND_SOC_DAPM_PGA("MIC3 PGA", DA732X_REG_MIC3, DA732X_MIC_EN_SHIFT,
848 0, NULL, 0),
849 SND_SOC_DAPM_PGA("AUX1L PGA", DA732X_REG_AUX1L, DA732X_AUX_EN_SHIFT,
850 0, NULL, 0),
851 SND_SOC_DAPM_PGA("AUX1R PGA", DA732X_REG_AUX1R, DA732X_AUX_EN_SHIFT,
852 0, NULL, 0),
853
854 SND_SOC_DAPM_PGA_E("HP Left", DA732X_REG_HPL, DA732X_HP_OUT_EN_SHIFT,
855 0, NULL, 0, da732x_out_pga_event,
856 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
857 SND_SOC_DAPM_PGA_E("HP Right", DA732X_REG_HPR, DA732X_HP_OUT_EN_SHIFT,
858 0, NULL, 0, da732x_out_pga_event,
859 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
860 SND_SOC_DAPM_PGA_E("LIN2", DA732X_REG_LIN2, DA732X_LIN_OUT_EN_SHIFT,
861 0, NULL, 0, da732x_out_pga_event,
862 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
863 SND_SOC_DAPM_PGA_E("LIN3", DA732X_REG_LIN3, DA732X_LIN_OUT_EN_SHIFT,
864 0, NULL, 0, da732x_out_pga_event,
865 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
866 SND_SOC_DAPM_PGA_E("LIN4", DA732X_REG_LIN4, DA732X_LIN_OUT_EN_SHIFT,
867 0, NULL, 0, da732x_out_pga_event,
868 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
869
870 /* MUXs */
871 SND_SOC_DAPM_MUX("ADC1 Left MUX", SND_SOC_NOPM, 0, 0, &adc1l_mux),
872 SND_SOC_DAPM_MUX("ADC1 Right MUX", SND_SOC_NOPM, 0, 0, &adc1r_mux),
873 SND_SOC_DAPM_MUX("ADC2 Left MUX", SND_SOC_NOPM, 0, 0, &adc2l_mux),
874 SND_SOC_DAPM_MUX("ADC2 Right MUX", SND_SOC_NOPM, 0, 0, &adc2r_mux),
875
876 SND_SOC_DAPM_MUX("HP Left MUX", SND_SOC_NOPM, 0, 0, &hpl_mux),
877 SND_SOC_DAPM_MUX("HP Right MUX", SND_SOC_NOPM, 0, 0, &hpr_mux),
878 SND_SOC_DAPM_MUX("Speaker MUX", SND_SOC_NOPM, 0, 0, &spk_mux),
879 SND_SOC_DAPM_MUX("LOUT2 MUX", SND_SOC_NOPM, 0, 0, &lout2_mux),
880 SND_SOC_DAPM_MUX("LOUT4 MUX", SND_SOC_NOPM, 0, 0, &lout4_mux),
881
882 /* AIF interfaces */
883 SND_SOC_DAPM_AIF_OUT("AIFA Output", "AIFA Capture", 0, DA732X_REG_AIFA3,
884 DA732X_AIF_EN_SHIFT, 0),
885 SND_SOC_DAPM_AIF_IN("AIFA Input", "AIFA Playback", 0, DA732X_REG_AIFA3,
886 DA732X_AIF_EN_SHIFT, 0),
887
888 SND_SOC_DAPM_AIF_OUT("AIFB Output", "AIFB Capture", 0, DA732X_REG_AIFB3,
889 DA732X_AIF_EN_SHIFT, 0),
890 SND_SOC_DAPM_AIF_IN("AIFB Input", "AIFB Playback", 0, DA732X_REG_AIFB3,
891 DA732X_AIF_EN_SHIFT, 0),
892};
893
894static const struct snd_soc_dapm_route da732x_dapm_routes[] = {
895 /* Inputs */
896 {"AUX1L PGA", "NULL", "AUX1L"},
897 {"AUX1R PGA", "NULL", "AUX1R"},
898 {"MIC1 PGA", NULL, "MIC1"},
899 {"MIC2 PGA", "NULL", "MIC2"},
900 {"MIC3 PGA", "NULL", "MIC3"},
901
902 /* Capture Path */
903 {"ADC1 Left MUX", "MIC1", "MIC1 PGA"},
904 {"ADC1 Left MUX", "AUX1L", "AUX1L PGA"},
905
906 {"ADC1 Right MUX", "AUX1R", "AUX1R PGA"},
907 {"ADC1 Right MUX", "MIC2", "MIC2 PGA"},
908 {"ADC1 Right MUX", "MIC3", "MIC3 PGA"},
909
910 {"ADC2 Left MUX", "AUX1L", "AUX1L PGA"},
911 {"ADC2 Left MUX", "MIC1", "MIC1 PGA"},
912
913 {"ADC2 Right MUX", "AUX1R", "AUX1R PGA"},
914 {"ADC2 Right MUX", "MIC2", "MIC2 PGA"},
915 {"ADC2 Right MUX", "MIC3", "MIC3 PGA"},
916
917 {"ADC1L", NULL, "ADC1 Supply"},
918 {"ADC1R", NULL, "ADC1 Supply"},
919 {"ADC2L", NULL, "ADC2 Supply"},
920 {"ADC2R", NULL, "ADC2 Supply"},
921
922 {"ADC1L", NULL, "ADC1 Left MUX"},
923 {"ADC1R", NULL, "ADC1 Right MUX"},
924 {"ADC2L", NULL, "ADC2 Left MUX"},
925 {"ADC2R", NULL, "ADC2 Right MUX"},
926
927 {"AIFA Output", NULL, "ADC1L"},
928 {"AIFA Output", NULL, "ADC1R"},
929 {"AIFB Output", NULL, "ADC2L"},
930 {"AIFB Output", NULL, "ADC2R"},
931
932 {"HP Left MUX", "Enabled", "AIFA Input"},
933 {"HP Right MUX", "Enabled", "AIFA Input"},
934 {"Speaker MUX", "Enabled", "AIFB Input"},
935 {"LOUT2 MUX", "Enabled", "AIFB Input"},
936 {"LOUT4 MUX", "Enabled", "AIFB Input"},
937
938 {"DAC1L", NULL, "DAC1 CLK"},
939 {"DAC1R", NULL, "DAC1 CLK"},
940 {"DAC2L", NULL, "DAC2 CLK"},
941 {"DAC2R", NULL, "DAC2 CLK"},
942 {"DAC3", NULL, "DAC3 CLK"},
943
944 {"DAC1L", NULL, "HP Left MUX"},
945 {"DAC1R", NULL, "HP Right MUX"},
946 {"DAC2L", NULL, "Speaker MUX"},
947 {"DAC2R", NULL, "LOUT4 MUX"},
948 {"DAC3", NULL, "LOUT2 MUX"},
949
950 /* Output Pgas */
951 {"HP Left", NULL, "DAC1L"},
952 {"HP Right", NULL, "DAC1R"},
953 {"LIN3", NULL, "DAC2L"},
954 {"LIN4", NULL, "DAC2R"},
955 {"LIN2", NULL, "DAC3"},
956
957 /* Outputs */
958 {"ClassD", NULL, "LIN3"},
959 {"LOUTL", NULL, "LIN2"},
960 {"LOUTR", NULL, "LIN4"},
961 {"HPL", NULL, "HP Left"},
962 {"HPR", NULL, "HP Right"},
963};
964
965static int da732x_hw_params(struct snd_pcm_substream *substream,
966 struct snd_pcm_hw_params *params,
967 struct snd_soc_dai *dai)
968{
969 struct snd_soc_codec *codec = dai->codec;
970 u32 aif = 0;
971 u32 reg_aif;
972 u32 fs;
973
974 reg_aif = dai->driver->base;
975
976 switch (params_format(params)) {
977 case SNDRV_PCM_FORMAT_S16_LE:
978 aif |= DA732X_AIF_WORD_16;
979 break;
980 case SNDRV_PCM_FORMAT_S20_3LE:
981 aif |= DA732X_AIF_WORD_20;
982 break;
983 case SNDRV_PCM_FORMAT_S24_LE:
984 aif |= DA732X_AIF_WORD_24;
985 break;
986 case SNDRV_PCM_FORMAT_S32_LE:
987 aif |= DA732X_AIF_WORD_32;
988 break;
989 default:
990 return -EINVAL;
991 }
992
993 switch (params_rate(params)) {
994 case 8000:
995 fs = DA732X_SR_8KHZ;
996 break;
997 case 11025:
998 fs = DA732X_SR_11_025KHZ;
999 break;
1000 case 12000:
1001 fs = DA732X_SR_12KHZ;
1002 break;
1003 case 16000:
1004 fs = DA732X_SR_16KHZ;
1005 break;
1006 case 22050:
1007 fs = DA732X_SR_22_05KHZ;
1008 break;
1009 case 24000:
1010 fs = DA732X_SR_24KHZ;
1011 break;
1012 case 32000:
1013 fs = DA732X_SR_32KHZ;
1014 break;
1015 case 44100:
1016 fs = DA732X_SR_44_1KHZ;
1017 break;
1018 case 48000:
1019 fs = DA732X_SR_48KHZ;
1020 break;
1021 case 88100:
1022 fs = DA732X_SR_88_1KHZ;
1023 break;
1024 case 96000:
1025 fs = DA732X_SR_96KHZ;
1026 break;
1027 default:
1028 return -EINVAL;
1029 }
1030
1031 snd_soc_update_bits(codec, reg_aif, DA732X_AIF_WORD_MASK, aif);
1032 snd_soc_update_bits(codec, DA732X_REG_CLK_CTRL, DA732X_SR1_MASK, fs);
1033
1034 return 0;
1035}
1036
1037static int da732x_set_dai_fmt(struct snd_soc_dai *dai, u32 fmt)
1038{
1039 struct snd_soc_codec *codec = dai->codec;
1040 u32 aif_mclk, pc_count;
1041 u32 reg_aif1, aif1;
1042 u32 reg_aif3, aif3;
1043
1044 switch (dai->id) {
1045 case DA732X_DAI_ID1:
1046 reg_aif1 = DA732X_REG_AIFA1;
1047 reg_aif3 = DA732X_REG_AIFA3;
1048 pc_count = DA732X_PC_PULSE_AIFA | DA732X_PC_RESYNC_NOT_AUT |
1049 DA732X_PC_SAME;
1050 break;
1051 case DA732X_DAI_ID2:
1052 reg_aif1 = DA732X_REG_AIFB1;
1053 reg_aif3 = DA732X_REG_AIFB3;
1054 pc_count = DA732X_PC_PULSE_AIFB | DA732X_PC_RESYNC_NOT_AUT |
1055 DA732X_PC_SAME;
1056 break;
1057 default:
1058 return -EINVAL;
1059 }
1060
1061 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1062 case SND_SOC_DAIFMT_CBS_CFS:
1063 aif1 = DA732X_AIF_SLAVE;
1064 aif_mclk = DA732X_AIFM_FRAME_64 | DA732X_AIFM_SRC_SEL_AIFA;
1065 break;
1066 case SND_SOC_DAIFMT_CBM_CFM:
1067 aif1 = DA732X_AIF_CLK_FROM_SRC;
1068 aif_mclk = DA732X_CLK_GENERATION_AIF_A;
1069 break;
1070 default:
1071 return -EINVAL;
1072 }
1073
1074 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1075 case SND_SOC_DAIFMT_I2S:
1076 aif3 = DA732X_AIF_I2S_MODE;
1077 break;
1078 case SND_SOC_DAIFMT_RIGHT_J:
1079 aif3 = DA732X_AIF_RIGHT_J_MODE;
1080 break;
1081 case SND_SOC_DAIFMT_LEFT_J:
1082 aif3 = DA732X_AIF_LEFT_J_MODE;
1083 break;
1084 case SND_SOC_DAIFMT_DSP_B:
1085 aif3 = DA732X_AIF_DSP_MODE;
1086 break;
1087 default:
1088 return -EINVAL;
1089 }
1090
1091 /* Clock inversion */
1092 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1093 case SND_SOC_DAIFMT_DSP_B:
1094 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1095 case SND_SOC_DAIFMT_NB_NF:
1096 break;
1097 case SND_SOC_DAIFMT_IB_NF:
1098 aif3 |= DA732X_AIF_BCLK_INV;
1099 break;
1100 default:
1101 return -EINVAL;
1102 }
1103 break;
1104 case SND_SOC_DAIFMT_I2S:
1105 case SND_SOC_DAIFMT_RIGHT_J:
1106 case SND_SOC_DAIFMT_LEFT_J:
1107 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1108 case SND_SOC_DAIFMT_NB_NF:
1109 break;
1110 case SND_SOC_DAIFMT_IB_IF:
1111 aif3 |= DA732X_AIF_BCLK_INV | DA732X_AIF_WCLK_INV;
1112 break;
1113 case SND_SOC_DAIFMT_IB_NF:
1114 aif3 |= DA732X_AIF_BCLK_INV;
1115 break;
1116 case SND_SOC_DAIFMT_NB_IF:
1117 aif3 |= DA732X_AIF_WCLK_INV;
1118 break;
1119 default:
1120 return -EINVAL;
1121 }
1122 break;
1123 default:
1124 return -EINVAL;
1125 }
1126
1127 snd_soc_write(codec, DA732X_REG_AIF_MCLK, aif_mclk);
1128 snd_soc_update_bits(codec, reg_aif1, DA732X_AIF1_CLK_MASK, aif1);
1129 snd_soc_update_bits(codec, reg_aif3, DA732X_AIF_BCLK_INV |
1130 DA732X_AIF_WCLK_INV | DA732X_AIF_MODE_MASK, aif3);
1131 snd_soc_write(codec, DA732X_REG_PC_CTRL, pc_count);
1132
1133 return 0;
1134}
1135
1136
1137
1138static int da732x_set_dai_pll(struct snd_soc_codec *codec, int pll_id,
1139 int source, unsigned int freq_in,
1140 unsigned int freq_out)
1141{
1142 struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
1143 int fref, indiv;
1144 u8 div_lo, div_mid, div_hi;
1145 u64 frac_div;
1146
1147 /* Disable PLL */
1148 if (freq_out == 0) {
1149 snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL,
1150 DA732X_PLL_EN, 0);
1151 da732x->pll_en = false;
1152 return 0;
1153 }
1154
1155 if (da732x->pll_en)
1156 return -EBUSY;
1157
1158 if (source == DA732X_SRCCLK_MCLK) {
1159 /* Validate Sysclk rate */
1160 switch (da732x->sysclk) {
1161 case 11290000:
1162 case 12288000:
1163 case 22580000:
1164 case 24576000:
1165 case 45160000:
1166 case 49152000:
1167 snd_soc_write(codec, DA732X_REG_PLL_CTRL,
1168 DA732X_PLL_BYPASS);
1169 return 0;
1170 default:
1171 dev_err(codec->dev,
1172 "Cannot use PLL Bypass, invalid SYSCLK rate\n");
1173 return -EINVAL;
1174 }
1175 }
1176
1177 indiv = da732x_get_input_div(codec, da732x->sysclk);
1178 if (indiv < 0)
1179 return indiv;
1180
1181 fref = (da732x->sysclk / indiv);
1182 div_hi = freq_out / fref;
1183 frac_div = (u64)(freq_out % fref) * 8192ULL;
1184 do_div(frac_div, fref);
1185 div_mid = (frac_div >> DA732X_1BYTE_SHIFT) & DA732X_U8_MASK;
1186 div_lo = (frac_div) & DA732X_U8_MASK;
1187
1188 snd_soc_write(codec, DA732X_REG_PLL_DIV_LO, div_lo);
1189 snd_soc_write(codec, DA732X_REG_PLL_DIV_MID, div_mid);
1190 snd_soc_write(codec, DA732X_REG_PLL_DIV_HI, div_hi);
1191
1192 snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, DA732X_PLL_EN,
1193 DA732X_PLL_EN);
1194
1195 da732x->pll_en = true;
1196
1197 return 0;
1198}
1199
1200static int da732x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
1201 unsigned int freq, int dir)
1202{
1203 struct snd_soc_codec *codec = dai->codec;
1204 struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
1205
1206 da732x->sysclk = freq;
1207
1208 return 0;
1209}
1210
1211#define DA732X_RATES SNDRV_PCM_RATE_8000_96000
1212
1213#define DA732X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1214 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1215
1216static struct snd_soc_dai_ops da732x_dai1_ops = {
1217 .hw_params = da732x_hw_params,
1218 .set_fmt = da732x_set_dai_fmt,
1219 .set_sysclk = da732x_set_dai_sysclk,
1220};
1221
1222static struct snd_soc_dai_ops da732x_dai2_ops = {
1223 .hw_params = da732x_hw_params,
1224 .set_fmt = da732x_set_dai_fmt,
1225 .set_sysclk = da732x_set_dai_sysclk,
1226};
1227
1228static struct snd_soc_dai_driver da732x_dai[] = {
1229 {
1230 .name = "DA732X_AIFA",
1231 .id = DA732X_DAI_ID1,
1232 .base = DA732X_REG_AIFA1,
1233 .playback = {
1234 .stream_name = "AIFA Playback",
1235 .channels_min = 1,
1236 .channels_max = 2,
1237 .rates = DA732X_RATES,
1238 .formats = DA732X_FORMATS,
1239 },
1240 .capture = {
1241 .stream_name = "AIFA Capture",
1242 .channels_min = 1,
1243 .channels_max = 2,
1244 .rates = DA732X_RATES,
1245 .formats = DA732X_FORMATS,
1246 },
1247 .ops = &da732x_dai1_ops,
1248 },
1249 {
1250 .name = "DA732X_AIFB",
1251 .id = DA732X_DAI_ID2,
1252 .base = DA732X_REG_AIFB1,
1253 .playback = {
1254 .stream_name = "AIFB Playback",
1255 .channels_min = 1,
1256 .channels_max = 2,
1257 .rates = DA732X_RATES,
1258 .formats = DA732X_FORMATS,
1259 },
1260 .capture = {
1261 .stream_name = "AIFB Capture",
1262 .channels_min = 1,
1263 .channels_max = 2,
1264 .rates = DA732X_RATES,
1265 .formats = DA732X_FORMATS,
1266 },
1267 .ops = &da732x_dai2_ops,
1268 },
1269};
1270
1271static const struct regmap_config da732x_regmap = {
1272 .reg_bits = 8,
1273 .val_bits = 8,
1274
1275 .max_register = DA732X_MAX_REG,
1276 .reg_defaults = da732x_reg_cache,
1277 .num_reg_defaults = ARRAY_SIZE(da732x_reg_cache),
1278 .cache_type = REGCACHE_RBTREE,
1279};
1280
1281
1282static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
1283{
1284 u8 offset[DA732X_HP_DACS];
1285 u8 sign[DA732X_HP_DACS];
1286 u8 step = DA732X_DAC_OFFSET_STEP;
1287
1288 /* Initialize DAC offset calibration circuits and registers */
1289 snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET,
1290 DA732X_HP_DAC_OFFSET_TRIM_VAL);
1291 snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET,
1292 DA732X_HP_DAC_OFFSET_TRIM_VAL);
1293 snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL,
1294 DA732X_HP_DAC_OFF_CALIBRATION |
1295 DA732X_HP_DAC_OFF_SCALE_STEPS);
1296 snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL,
1297 DA732X_HP_DAC_OFF_CALIBRATION |
1298 DA732X_HP_DAC_OFF_SCALE_STEPS);
1299
1300 /* Wait for voltage stabilization */
1301 msleep(DA732X_WAIT_FOR_STABILIZATION);
1302
1303 /* Check DAC offset sign */
1304 sign[DA732X_HPL_DAC] = (codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
1305 DA732X_HP_DAC_OFF_CNTL_COMPO);
1306 sign[DA732X_HPR_DAC] = (codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
1307 DA732X_HP_DAC_OFF_CNTL_COMPO);
1308
1309 /* Binary search DAC offset values (both channels at once) */
1310 offset[DA732X_HPL_DAC] = sign[DA732X_HPL_DAC] << DA732X_HP_DAC_COMPO_SHIFT;
1311 offset[DA732X_HPR_DAC] = sign[DA732X_HPR_DAC] << DA732X_HP_DAC_COMPO_SHIFT;
1312
1313 do {
1314 offset[DA732X_HPL_DAC] |= step;
1315 offset[DA732X_HPR_DAC] |= step;
1316 snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET,
1317 ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK);
1318 snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET,
1319 ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK);
1320
1321 msleep(DA732X_WAIT_FOR_STABILIZATION);
1322
1323 if ((codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
1324 DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPL_DAC])
1325 offset[DA732X_HPL_DAC] &= ~step;
1326 if ((codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
1327 DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPR_DAC])
1328 offset[DA732X_HPR_DAC] &= ~step;
1329
1330 step >>= 1;
1331 } while (step);
1332
1333 /* Write final DAC offsets to registers */
1334 snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET,
1335 ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK);
1336 snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET,
1337 ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK);
1338
1339 /* End DAC calibration mode */
1340 snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL,
1341 DA732X_HP_DAC_OFF_SCALE_STEPS);
1342 snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL,
1343 DA732X_HP_DAC_OFF_SCALE_STEPS);
1344}
1345
1346static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
1347{
1348 u8 offset[DA732X_HP_AMPS];
1349 u8 sign[DA732X_HP_AMPS];
1350 u8 step = DA732X_OUTPUT_OFFSET_STEP;
1351
1352 offset[DA732X_HPL_AMP] = DA732X_HP_OUT_TRIM_VAL;
1353 offset[DA732X_HPR_AMP] = DA732X_HP_OUT_TRIM_VAL;
1354
1355 /* Initialize output offset calibration circuits and registers */
1356 snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL);
1357 snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL);
1358 snd_soc_write(codec, DA732X_REG_HPL,
1359 DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN);
1360 snd_soc_write(codec, DA732X_REG_HPR,
1361 DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN);
1362
1363 /* Wait for voltage stabilization */
1364 msleep(DA732X_WAIT_FOR_STABILIZATION);
1365
1366 /* Check output offset sign */
1367 sign[DA732X_HPL_AMP] = codec->hw_read(codec, DA732X_REG_HPL) &
1368 DA732X_HP_OUT_COMPO;
1369 sign[DA732X_HPR_AMP] = codec->hw_read(codec, DA732X_REG_HPR) &
1370 DA732X_HP_OUT_COMPO;
1371
1372 snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_COMP |
1373 (sign[DA732X_HPL_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) |
1374 DA732X_HP_OUT_EN);
1375 snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_COMP |
1376 (sign[DA732X_HPR_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) |
1377 DA732X_HP_OUT_EN);
1378
1379 /* Binary search output offset values (both channels at once) */
1380 do {
1381 offset[DA732X_HPL_AMP] |= step;
1382 offset[DA732X_HPR_AMP] |= step;
1383 snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET,
1384 offset[DA732X_HPL_AMP]);
1385 snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET,
1386 offset[DA732X_HPR_AMP]);
1387
1388 msleep(DA732X_WAIT_FOR_STABILIZATION);
1389
1390 if ((codec->hw_read(codec, DA732X_REG_HPL) &
1391 DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPL_AMP])
1392 offset[DA732X_HPL_AMP] &= ~step;
1393 if ((codec->hw_read(codec, DA732X_REG_HPR) &
1394 DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPR_AMP])
1395 offset[DA732X_HPR_AMP] &= ~step;
1396
1397 step >>= 1;
1398 } while (step);
1399
1400 /* Write final DAC offsets to registers */
1401 snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, offset[DA732X_HPL_AMP]);
1402 snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, offset[DA732X_HPR_AMP]);
1403}
1404
1405static void da732x_hp_dc_offset_cancellation(struct snd_soc_codec *codec)
1406{
1407 /* Make sure that we have Soft Mute enabled */
1408 snd_soc_write(codec, DA732X_REG_DAC1_SOFTMUTE, DA732X_SOFTMUTE_EN |
1409 DA732X_GAIN_RAMPED | DA732X_16_SAMPLES);
1410 snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACL_EN |
1411 DA732X_DACR_EN | DA732X_DACL_SDM | DA732X_DACR_SDM |
1412 DA732X_DACL_MUTE | DA732X_DACR_MUTE);
1413 snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN |
1414 DA732X_HP_OUT_MUTE | DA732X_HP_OUT_EN);
1415 snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_EN |
1416 DA732X_HP_OUT_MUTE | DA732X_HP_OUT_DAC_EN);
1417
1418 da732x_dac_offset_adjust(codec);
1419 da732x_output_offset_adjust(codec);
1420
1421 snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACS_DIS);
1422 snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_DIS);
1423 snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_DIS);
1424}
1425
1426static int da732x_set_bias_level(struct snd_soc_codec *codec,
1427 enum snd_soc_bias_level level)
1428{
1429 struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
1430
1431 switch (level) {
1432 case SND_SOC_BIAS_ON:
1433 snd_soc_update_bits(codec, DA732X_REG_BIAS_EN,
1434 DA732X_BIAS_BOOST_MASK,
1435 DA732X_BIAS_BOOST_100PC);
1436 break;
1437 case SND_SOC_BIAS_PREPARE:
1438 break;
1439 case SND_SOC_BIAS_STANDBY:
1440 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1441 /* Init Codec */
1442 snd_soc_write(codec, DA732X_REG_REF1,
1443 DA732X_VMID_FASTCHG);
1444 snd_soc_write(codec, DA732X_REG_BIAS_EN,
1445 DA732X_BIAS_EN);
1446
1447 mdelay(DA732X_STARTUP_DELAY);
1448
1449 /* Disable Fast Charge and enable DAC ref voltage */
1450 snd_soc_write(codec, DA732X_REG_REF1,
1451 DA732X_REFBUFX2_EN);
1452
1453 /* Enable bypass DSP routing */
1454 snd_soc_write(codec, DA732X_REG_DATA_ROUTE,
1455 DA732X_BYPASS_DSP);
1456
1457 /* Enable Digital subsystem */
1458 snd_soc_write(codec, DA732X_REG_DSP_CTRL,
1459 DA732X_DIGITAL_EN);
1460
1461 snd_soc_write(codec, DA732X_REG_SPARE1_OUT,
1462 DA732X_HP_DRIVER_EN |
1463 DA732X_HP_GATE_LOW |
1464 DA732X_HP_LOOP_GAIN_CTRL);
1465 snd_soc_write(codec, DA732X_REG_HP_LIN1_GNDSEL,
1466 DA732X_HP_OUT_GNDSEL);
1467
1468 da732x_set_charge_pump(codec, DA732X_ENABLE_CP);
1469
1470 snd_soc_write(codec, DA732X_REG_CLK_EN1,
1471 DA732X_SYS3_CLK_EN | DA732X_PC_CLK_EN);
1472
1473 /* Enable Zero Crossing */
1474 snd_soc_write(codec, DA732X_REG_INP_ZC_EN,
1475 DA732X_MIC1_PRE_ZC_EN |
1476 DA732X_MIC1_ZC_EN |
1477 DA732X_MIC2_PRE_ZC_EN |
1478 DA732X_MIC2_ZC_EN |
1479 DA732X_AUXL_ZC_EN |
1480 DA732X_AUXR_ZC_EN |
1481 DA732X_MIC3_PRE_ZC_EN |
1482 DA732X_MIC3_ZC_EN);
1483 snd_soc_write(codec, DA732X_REG_OUT_ZC_EN,
1484 DA732X_HPL_ZC_EN | DA732X_HPR_ZC_EN |
1485 DA732X_LIN2_ZC_EN | DA732X_LIN3_ZC_EN |
1486 DA732X_LIN4_ZC_EN);
1487
1488 da732x_hp_dc_offset_cancellation(codec);
1489
1490 regcache_cache_only(codec->control_data, false);
1491 regcache_sync(codec->control_data);
1492 } else {
1493 snd_soc_update_bits(codec, DA732X_REG_BIAS_EN,
1494 DA732X_BIAS_BOOST_MASK,
1495 DA732X_BIAS_BOOST_50PC);
1496 snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL,
1497 DA732X_PLL_EN, 0);
1498 da732x->pll_en = false;
1499 }
1500 break;
1501 case SND_SOC_BIAS_OFF:
1502 regcache_cache_only(codec->control_data, true);
1503 da732x_set_charge_pump(codec, DA732X_DISABLE_CP);
1504 snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN,
1505 DA732X_BIAS_DIS);
1506 da732x->pll_en = false;
1507 break;
1508 }
1509
1510 codec->dapm.bias_level = level;
1511
1512 return 0;
1513}
1514
1515static int da732x_probe(struct snd_soc_codec *codec)
1516{
1517 struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
1518 struct snd_soc_dapm_context *dapm = &codec->dapm;
1519 int ret = 0;
1520
1521 da732x->codec = codec;
1522
1523 dapm->idle_bias_off = false;
1524
1525 codec->control_data = da732x->regmap;
1526
1527 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
1528 if (ret != 0) {
1529 dev_err(codec->dev, "Failed to register codec.\n");
1530 goto err;
1531 }
1532
1533 da732x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1534err:
1535 return ret;
1536}
1537
1538static int da732x_remove(struct snd_soc_codec *codec)
1539{
1540
1541 da732x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1542
1543 return 0;
1544}
1545
1546static struct snd_soc_codec_driver soc_codec_dev_da732x = {
1547 .probe = da732x_probe,
1548 .remove = da732x_remove,
1549 .set_bias_level = da732x_set_bias_level,
1550 .controls = da732x_snd_controls,
1551 .num_controls = ARRAY_SIZE(da732x_snd_controls),
1552 .dapm_widgets = da732x_dapm_widgets,
1553 .num_dapm_widgets = ARRAY_SIZE(da732x_dapm_widgets),
1554 .dapm_routes = da732x_dapm_routes,
1555 .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes),
1556 .set_pll = da732x_set_dai_pll,
1557 .reg_cache_size = ARRAY_SIZE(da732x_reg_cache),
1558};
1559
1560static __devinit int da732x_i2c_probe(struct i2c_client *i2c,
1561 const struct i2c_device_id *id)
1562{
1563 struct da732x_priv *da732x;
1564 unsigned int reg;
1565 int ret;
1566
1567 da732x = devm_kzalloc(&i2c->dev, sizeof(struct da732x_priv),
1568 GFP_KERNEL);
1569 if (!da732x)
1570 return -ENOMEM;
1571
1572 i2c_set_clientdata(i2c, da732x);
1573
1574 da732x->regmap = devm_regmap_init_i2c(i2c, &da732x_regmap);
1575 if (IS_ERR(da732x->regmap)) {
1576 ret = PTR_ERR(da732x->regmap);
1577 dev_err(&i2c->dev, "Failed to initialize regmap\n");
1578 goto err;
1579 }
1580
1581 ret = regmap_read(da732x->regmap, DA732X_REG_ID, &reg);
1582 if (ret < 0) {
1583 dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
1584 goto err;
1585 }
1586
1587 dev_info(&i2c->dev, "Revision: %d.%d\n",
1588 (reg & DA732X_ID_MAJOR_MASK), (reg & DA732X_ID_MINOR_MASK));
1589
1590 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da732x,
1591 da732x_dai, ARRAY_SIZE(da732x_dai));
1592 if (ret != 0)
1593 dev_err(&i2c->dev, "Failed to register codec.\n");
1594
1595err:
1596 return ret;
1597}
1598
1599static __devexit int da732x_i2c_remove(struct i2c_client *client)
1600{
1601 snd_soc_unregister_codec(&client->dev);
1602
1603 return 0;
1604}
1605
1606static const struct i2c_device_id da732x_i2c_id[] = {
1607 { "da7320", 0},
1608 { }
1609};
1610MODULE_DEVICE_TABLE(i2c, da732x_i2c_id);
1611
1612static struct i2c_driver da732x_i2c_driver = {
1613 .driver = {
1614 .name = "da7320",
1615 .owner = THIS_MODULE,
1616 },
1617 .probe = da732x_i2c_probe,
1618 .remove = __devexit_p(da732x_i2c_remove),
1619 .id_table = da732x_i2c_id,
1620};
1621
1622module_i2c_driver(da732x_i2c_driver);
1623
1624
1625MODULE_DESCRIPTION("ASoC DA732X driver");
1626MODULE_AUTHOR("Michal Hajduk <michal.hajduk@diasemi.com>");
1627MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/da732x.h b/sound/soc/codecs/da732x.h
new file mode 100644
index 000000000000..c8ce5475de22
--- /dev/null
+++ b/sound/soc/codecs/da732x.h
@@ -0,0 +1,133 @@
1/*
2 * da732x.h -- Dialog DA732X ALSA SoC Audio Driver Header File
3 *
4 * Copyright (C) 2012 Dialog Semiconductor GmbH
5 *
6 * Author: Michal Hajduk <Michal.Hajduk@diasemi.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 __DA732X_H_
14#define __DA732X_H
15
16#include <sound/soc.h>
17
18/* General */
19#define DA732X_U8_MASK 0xFF
20#define DA732X_4BYTES 4
21#define DA732X_3BYTES 3
22#define DA732X_2BYTES 2
23#define DA732X_1BYTE 1
24#define DA732X_1BYTE_SHIFT 8
25#define DA732X_2BYTES_SHIFT 16
26#define DA732X_3BYTES_SHIFT 24
27#define DA732X_4BYTES_SHIFT 32
28
29#define DA732X_DACS_DIS 0x0
30#define DA732X_HP_DIS 0x0
31#define DA732X_CLEAR_REG 0x0
32
33/* Calibration */
34#define DA732X_DAC_OFFSET_STEP 0x20
35#define DA732X_OUTPUT_OFFSET_STEP 0x80
36#define DA732X_HP_OUT_TRIM_VAL 0x0
37#define DA732X_WAIT_FOR_STABILIZATION 1
38#define DA732X_HPL_DAC 0
39#define DA732X_HPR_DAC 1
40#define DA732X_HP_DACS 2
41#define DA732X_HPL_AMP 0
42#define DA732X_HPR_AMP 1
43#define DA732X_HP_AMPS 2
44
45/* Clock settings */
46#define DA732X_STARTUP_DELAY 100
47#define DA732X_PLL_OUT_196608 196608000
48#define DA732X_PLL_OUT_180634 180633600
49#define DA732X_PLL_OUT_SRM 188620800
50#define DA732X_MCLK_10MHZ 10000000
51#define DA732X_MCLK_20MHZ 20000000
52#define DA732X_MCLK_40MHZ 40000000
53#define DA732X_MCLK_54MHZ 54000000
54#define DA732X_MCLK_RET_0_10MHZ 0
55#define DA732X_MCLK_VAL_0_10MHZ 1
56#define DA732X_MCLK_RET_10_20MHZ 1
57#define DA732X_MCLK_VAL_10_20MHZ 2
58#define DA732X_MCLK_RET_20_40MHZ 2
59#define DA732X_MCLK_VAL_20_40MHZ 4
60#define DA732X_MCLK_RET_40_54MHZ 3
61#define DA732X_MCLK_VAL_40_54MHZ 8
62#define DA732X_DAI_ID1 0
63#define DA732X_DAI_ID2 1
64#define DA732X_SRCCLK_PLL 0
65#define DA732X_SRCCLK_MCLK 1
66
67#define DA732X_LIN_LP_VOL 0x4F
68#define DA732X_LP_VOL 0x40
69
70/* Kcontrols */
71#define DA732X_DAC_EN_MAX 2
72#define DA732X_ADCL_MUX_MAX 2
73#define DA732X_ADCR_MUX_MAX 3
74#define DA732X_HPF_MODE_MAX 3
75#define DA732X_HPF_MODE_SHIFT 4
76#define DA732X_HPF_MUSIC_SHIFT 0
77#define DA732X_HPF_MUSIC_MAX 4
78#define DA732X_HPF_VOICE_SHIFT 4
79#define DA732X_HPF_VOICE_MAX 8
80#define DA732X_EQ_EN_MAX 1
81#define DA732X_HPF_VOICE 1
82#define DA732X_HPF_MUSIC 2
83#define DA732X_HPF_DISABLED 0
84#define DA732X_NO_INVERT 0
85#define DA732X_INVERT 1
86#define DA732X_SWITCH_MAX 1
87#define DA732X_ENABLE_CP 1
88#define DA732X_DISABLE_CP 0
89#define DA732X_DISABLE_ALL_CLKS 0
90#define DA732X_RESET_ADCS 0
91
92/* dB values */
93#define DA732X_MIC_VOL_DB_MIN 0
94#define DA732X_MIC_VOL_DB_INC 50
95#define DA732X_MIC_PRE_VOL_DB_MIN 0
96#define DA732X_MIC_PRE_VOL_DB_INC 600
97#define DA732X_AUX_VOL_DB_MIN -6000
98#define DA732X_AUX_VOL_DB_INC 150
99#define DA732X_HP_VOL_DB_MIN -2250
100#define DA732X_HP_VOL_DB_INC 150
101#define DA732X_LIN2_VOL_DB_MIN -1650
102#define DA732X_LIN2_VOL_DB_INC 150
103#define DA732X_LIN3_VOL_DB_MIN -1650
104#define DA732X_LIN3_VOL_DB_INC 150
105#define DA732X_LIN4_VOL_DB_MIN -2250
106#define DA732X_LIN4_VOL_DB_INC 150
107#define DA732X_EQ_BAND_VOL_DB_MIN -1050
108#define DA732X_EQ_BAND_VOL_DB_INC 150
109#define DA732X_DAC_VOL_DB_MIN -7725
110#define DA732X_DAC_VOL_DB_INC 75
111#define DA732X_ADC_VOL_DB_MIN 0
112#define DA732X_ADC_VOL_DB_INC -1
113#define DA732X_EQ_OVERALL_VOL_DB_MIN -1800
114#define DA732X_EQ_OVERALL_VOL_DB_INC 600
115
116#define DA732X_SOC_ENUM_DOUBLE_R(xreg, xrreg, xmax, xtext) \
117 {.reg = xreg, .reg2 = xrreg, .max = xmax, .texts = xtext}
118
119enum da732x_sysctl {
120 DA732X_SR_8KHZ = 0x1,
121 DA732X_SR_11_025KHZ = 0x2,
122 DA732X_SR_12KHZ = 0x3,
123 DA732X_SR_16KHZ = 0x5,
124 DA732X_SR_22_05KHZ = 0x6,
125 DA732X_SR_24KHZ = 0x7,
126 DA732X_SR_32KHZ = 0x9,
127 DA732X_SR_44_1KHZ = 0xA,
128 DA732X_SR_48KHZ = 0xB,
129 DA732X_SR_88_1KHZ = 0xE,
130 DA732X_SR_96KHZ = 0xF,
131};
132
133#endif /* __DA732X_H_ */
diff --git a/sound/soc/codecs/da732x_reg.h b/sound/soc/codecs/da732x_reg.h
new file mode 100644
index 000000000000..bdd03ca4b2de
--- /dev/null
+++ b/sound/soc/codecs/da732x_reg.h
@@ -0,0 +1,654 @@
1/*
2 * da732x_reg.h --- Dialog DA732X ALSA SoC Audio Registers Header File
3 *
4 * Copyright (C) 2012 Dialog Semiconductor GmbH
5 *
6 * Author: Michal Hajduk <Michal.Hajduk@diasemi.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 __DA732X_REG_H_
14#define __DA732X_REG_H_
15
16/* DA732X registers */
17#define DA732X_REG_STATUS_EXT 0x00
18#define DA732X_REG_STATUS 0x01
19#define DA732X_REG_REF1 0x02
20#define DA732X_REG_BIAS_EN 0x03
21#define DA732X_REG_BIAS1 0x04
22#define DA732X_REG_BIAS2 0x05
23#define DA732X_REG_BIAS3 0x06
24#define DA732X_REG_BIAS4 0x07
25#define DA732X_REG_MICBIAS2 0x0F
26#define DA732X_REG_MICBIAS1 0x10
27#define DA732X_REG_MICDET 0x11
28#define DA732X_REG_MIC1_PRE 0x12
29#define DA732X_REG_MIC1 0x13
30#define DA732X_REG_MIC2_PRE 0x14
31#define DA732X_REG_MIC2 0x15
32#define DA732X_REG_AUX1L 0x16
33#define DA732X_REG_AUX1R 0x17
34#define DA732X_REG_MIC3_PRE 0x18
35#define DA732X_REG_MIC3 0x19
36#define DA732X_REG_INP_PINBIAS 0x1A
37#define DA732X_REG_INP_ZC_EN 0x1B
38#define DA732X_REG_INP_MUX 0x1D
39#define DA732X_REG_HP_DET 0x20
40#define DA732X_REG_HPL_DAC_OFFSET 0x21
41#define DA732X_REG_HPL_DAC_OFF_CNTL 0x22
42#define DA732X_REG_HPL_OUT_OFFSET 0x23
43#define DA732X_REG_HPL 0x24
44#define DA732X_REG_HPL_VOL 0x25
45#define DA732X_REG_HPR_DAC_OFFSET 0x26
46#define DA732X_REG_HPR_DAC_OFF_CNTL 0x27
47#define DA732X_REG_HPR_OUT_OFFSET 0x28
48#define DA732X_REG_HPR 0x29
49#define DA732X_REG_HPR_VOL 0x2A
50#define DA732X_REG_LIN2 0x2B
51#define DA732X_REG_LIN3 0x2C
52#define DA732X_REG_LIN4 0x2D
53#define DA732X_REG_OUT_ZC_EN 0x2E
54#define DA732X_REG_HP_LIN1_GNDSEL 0x37
55#define DA732X_REG_CP_HP1 0x3A
56#define DA732X_REG_CP_HP2 0x3B
57#define DA732X_REG_CP_CTRL1 0x40
58#define DA732X_REG_CP_CTRL2 0x41
59#define DA732X_REG_CP_CTRL3 0x42
60#define DA732X_REG_CP_LEVEL_MASK 0x43
61#define DA732X_REG_CP_DET 0x44
62#define DA732X_REG_CP_STATUS 0x45
63#define DA732X_REG_CP_THRESH1 0x46
64#define DA732X_REG_CP_THRESH2 0x47
65#define DA732X_REG_CP_THRESH3 0x48
66#define DA732X_REG_CP_THRESH4 0x49
67#define DA732X_REG_CP_THRESH5 0x4A
68#define DA732X_REG_CP_THRESH6 0x4B
69#define DA732X_REG_CP_THRESH7 0x4C
70#define DA732X_REG_CP_THRESH8 0x4D
71#define DA732X_REG_PLL_DIV_LO 0x50
72#define DA732X_REG_PLL_DIV_MID 0x51
73#define DA732X_REG_PLL_DIV_HI 0x52
74#define DA732X_REG_PLL_CTRL 0x53
75#define DA732X_REG_CLK_CTRL 0x54
76#define DA732X_REG_CLK_DSP 0x5A
77#define DA732X_REG_CLK_EN1 0x5B
78#define DA732X_REG_CLK_EN2 0x5C
79#define DA732X_REG_CLK_EN3 0x5D
80#define DA732X_REG_CLK_EN4 0x5E
81#define DA732X_REG_CLK_EN5 0x5F
82#define DA732X_REG_AIF_MCLK 0x60
83#define DA732X_REG_AIFA1 0x61
84#define DA732X_REG_AIFA2 0x62
85#define DA732X_REG_AIFA3 0x63
86#define DA732X_REG_AIFB1 0x64
87#define DA732X_REG_AIFB2 0x65
88#define DA732X_REG_AIFB3 0x66
89#define DA732X_REG_PC_CTRL 0x6A
90#define DA732X_REG_DATA_ROUTE 0x70
91#define DA732X_REG_DSP_CTRL 0x71
92#define DA732X_REG_CIF_CTRL2 0x74
93#define DA732X_REG_HANDSHAKE 0x75
94#define DA732X_REG_MBOX0 0x76
95#define DA732X_REG_MBOX1 0x77
96#define DA732X_REG_MBOX2 0x78
97#define DA732X_REG_MBOX_STATUS 0x79
98#define DA732X_REG_SPARE1_OUT 0x7D
99#define DA732X_REG_SPARE2_OUT 0x7E
100#define DA732X_REG_SPARE1_IN 0x7F
101#define DA732X_REG_ID 0x81
102#define DA732X_REG_ADC1_PD 0x90
103#define DA732X_REG_ADC1_HPF 0x93
104#define DA732X_REG_ADC1_SEL 0x94
105#define DA732X_REG_ADC1_EQ12 0x95
106#define DA732X_REG_ADC1_EQ34 0x96
107#define DA732X_REG_ADC1_EQ5 0x97
108#define DA732X_REG_ADC2_PD 0x98
109#define DA732X_REG_ADC2_HPF 0x9B
110#define DA732X_REG_ADC2_SEL 0x9C
111#define DA732X_REG_ADC2_EQ12 0x9D
112#define DA732X_REG_ADC2_EQ34 0x9E
113#define DA732X_REG_ADC2_EQ5 0x9F
114#define DA732X_REG_DAC1_HPF 0xA0
115#define DA732X_REG_DAC1_L_VOL 0xA1
116#define DA732X_REG_DAC1_R_VOL 0xA2
117#define DA732X_REG_DAC1_SEL 0xA3
118#define DA732X_REG_DAC1_SOFTMUTE 0xA4
119#define DA732X_REG_DAC1_EQ12 0xA5
120#define DA732X_REG_DAC1_EQ34 0xA6
121#define DA732X_REG_DAC1_EQ5 0xA7
122#define DA732X_REG_DAC2_HPF 0xB0
123#define DA732X_REG_DAC2_L_VOL 0xB1
124#define DA732X_REG_DAC2_R_VOL 0xB2
125#define DA732X_REG_DAC2_SEL 0xB3
126#define DA732X_REG_DAC2_SOFTMUTE 0xB4
127#define DA732X_REG_DAC2_EQ12 0xB5
128#define DA732X_REG_DAC2_EQ34 0xB6
129#define DA732X_REG_DAC2_EQ5 0xB7
130#define DA732X_REG_DAC3_HPF 0xC0
131#define DA732X_REG_DAC3_VOL 0xC1
132#define DA732X_REG_DAC3_SEL 0xC3
133#define DA732X_REG_DAC3_SOFTMUTE 0xC4
134#define DA732X_REG_DAC3_EQ12 0xC5
135#define DA732X_REG_DAC3_EQ34 0xC6
136#define DA732X_REG_DAC3_EQ5 0xC7
137#define DA732X_REG_BIQ_BYP 0xD2
138#define DA732X_REG_DMA_CMD 0xD3
139#define DA732X_REG_DMA_ADDR0 0xD4
140#define DA732X_REG_DMA_ADDR1 0xD5
141#define DA732X_REG_DMA_DATA0 0xD6
142#define DA732X_REG_DMA_DATA1 0xD7
143#define DA732X_REG_DMA_DATA2 0xD8
144#define DA732X_REG_DMA_DATA3 0xD9
145#define DA732X_REG_DMA_STATUS 0xDA
146#define DA732X_REG_BROWNOUT 0xDF
147#define DA732X_REG_UNLOCK 0xE0
148
149#define DA732X_MAX_REG DA732X_REG_UNLOCK
150/*
151 * Bits
152 */
153
154/* DA732X_REG_STATUS_EXT (addr=0x00) */
155#define DA732X_STATUS_EXT_DSP (1 << 4)
156#define DA732X_STATUS_EXT_CLEAR (0 << 0)
157
158/* DA732X_REG_STATUS (addr=0x01) */
159#define DA732X_STATUS_PLL_LOCK (1 << 0)
160#define DA732X_STATUS_PLL_MCLK_DET (1 << 1)
161#define DA732X_STATUS_HPDET_OUT (1 << 2)
162#define DA732X_STATUS_INP_MIXDET_1 (1 << 3)
163#define DA732X_STATUS_INP_MIXDET_2 (1 << 4)
164#define DA732X_STATUS_BO_STATUS (1 << 5)
165
166/* DA732X_REG_REF1 (addr=0x02) */
167#define DA732X_VMID_FASTCHG (1 << 1)
168#define DA732X_VMID_FASTDISCHG (1 << 2)
169#define DA732X_REFBUFX2_EN (1 << 6)
170#define DA732X_REFBUFX2_DIS (0 << 6)
171
172/* DA732X_REG_BIAS_EN (addr=0x03) */
173#define DA732X_BIAS_BOOST_MASK (3 << 0)
174#define DA732X_BIAS_BOOST_100PC (0 << 0)
175#define DA732X_BIAS_BOOST_133PC (1 << 0)
176#define DA732X_BIAS_BOOST_88PC (2 << 0)
177#define DA732X_BIAS_BOOST_50PC (3 << 0)
178#define DA732X_BIAS_EN (1 << 7)
179#define DA732X_BIAS_DIS (0 << 7)
180
181/* DA732X_REG_BIAS1 (addr=0x04) */
182#define DA732X_BIAS1_HP_DAC_BIAS_MASK (3 << 0)
183#define DA732X_BIAS1_HP_DAC_BIAS_100PC (0 << 0)
184#define DA732X_BIAS1_HP_DAC_BIAS_150PC (1 << 0)
185#define DA732X_BIAS1_HP_DAC_BIAS_50PC (2 << 0)
186#define DA732X_BIAS1_HP_DAC_BIAS_75PC (3 << 0)
187#define DA732X_BIAS1_HP_OUT_BIAS_MASK (7 << 4)
188#define DA732X_BIAS1_HP_OUT_BIAS_100PC (0 << 4)
189#define DA732X_BIAS1_HP_OUT_BIAS_125PC (1 << 4)
190#define DA732X_BIAS1_HP_OUT_BIAS_150PC (2 << 4)
191#define DA732X_BIAS1_HP_OUT_BIAS_175PC (3 << 4)
192#define DA732X_BIAS1_HP_OUT_BIAS_200PC (4 << 4)
193#define DA732X_BIAS1_HP_OUT_BIAS_250PC (5 << 4)
194#define DA732X_BIAS1_HP_OUT_BIAS_300PC (6 << 4)
195#define DA732X_BIAS1_HP_OUT_BIAS_350PC (7 << 4)
196
197/* DA732X_REG_BIAS2 (addr=0x05) */
198#define DA732X_BIAS2_LINE2_DAC_BIAS_MASK (3 << 0)
199#define DA732X_BIAS2_LINE2_DAC_BIAS_100PC (0 << 0)
200#define DA732X_BIAS2_LINE2_DAC_BIAS_150PC (1 << 0)
201#define DA732X_BIAS2_LINE2_DAC_BIAS_50PC (2 << 0)
202#define DA732X_BIAS2_LINE2_DAC_BIAS_75PC (3 << 0)
203#define DA732X_BIAS2_LINE2_OUT_BIAS_MASK (7 << 4)
204#define DA732X_BIAS2_LINE2_OUT_BIAS_100PC (0 << 4)
205#define DA732X_BIAS2_LINE2_OUT_BIAS_125PC (1 << 4)
206#define DA732X_BIAS2_LINE2_OUT_BIAS_150PC (2 << 4)
207#define DA732X_BIAS2_LINE2_OUT_BIAS_175PC (3 << 4)
208#define DA732X_BIAS2_LINE2_OUT_BIAS_200PC (4 << 4)
209#define DA732X_BIAS2_LINE2_OUT_BIAS_250PC (5 << 4)
210#define DA732X_BIAS2_LINE2_OUT_BIAS_300PC (6 << 4)
211#define DA732X_BIAS2_LINE2_OUT_BIAS_350PC (7 << 4)
212
213/* DA732X_REG_BIAS3 (addr=0x06) */
214#define DA732X_BIAS3_LINE3_DAC_BIAS_MASK (3 << 0)
215#define DA732X_BIAS3_LINE3_DAC_BIAS_100PC (0 << 0)
216#define DA732X_BIAS3_LINE3_DAC_BIAS_150PC (1 << 0)
217#define DA732X_BIAS3_LINE3_DAC_BIAS_50PC (2 << 0)
218#define DA732X_BIAS3_LINE3_DAC_BIAS_75PC (3 << 0)
219#define DA732X_BIAS3_LINE3_OUT_BIAS_MASK (7 << 4)
220#define DA732X_BIAS3_LINE3_OUT_BIAS_100PC (0 << 4)
221#define DA732X_BIAS3_LINE3_OUT_BIAS_125PC (1 << 4)
222#define DA732X_BIAS3_LINE3_OUT_BIAS_150PC (2 << 4)
223#define DA732X_BIAS3_LINE3_OUT_BIAS_175PC (3 << 4)
224#define DA732X_BIAS3_LINE3_OUT_BIAS_200PC (4 << 4)
225#define DA732X_BIAS3_LINE3_OUT_BIAS_250PC (5 << 4)
226#define DA732X_BIAS3_LINE3_OUT_BIAS_300PC (6 << 4)
227#define DA732X_BIAS3_LINE3_OUT_BIAS_350PC (7 << 4)
228
229/* DA732X_REG_BIAS4 (addr=0x07) */
230#define DA732X_BIAS4_LINE4_DAC_BIAS_MASK (3 << 0)
231#define DA732X_BIAS4_LINE4_DAC_BIAS_100PC (0 << 0)
232#define DA732X_BIAS4_LINE4_DAC_BIAS_150PC (1 << 0)
233#define DA732X_BIAS4_LINE4_DAC_BIAS_50PC (2 << 0)
234#define DA732X_BIAS4_LINE4_DAC_BIAS_75PC (3 << 0)
235#define DA732X_BIAS4_LINE4_OUT_BIAS_MASK (7 << 4)
236#define DA732X_BIAS4_LINE4_OUT_BIAS_100PC (0 << 4)
237#define DA732X_BIAS4_LINE4_OUT_BIAS_125PC (1 << 4)
238#define DA732X_BIAS4_LINE4_OUT_BIAS_150PC (2 << 4)
239#define DA732X_BIAS4_LINE4_OUT_BIAS_175PC (3 << 4)
240#define DA732X_BIAS4_LINE4_OUT_BIAS_200PC (4 << 4)
241#define DA732X_BIAS4_LINE4_OUT_BIAS_250PC (5 << 4)
242#define DA732X_BIAS4_LINE4_OUT_BIAS_300PC (6 << 4)
243#define DA732X_BIAS4_LINE4_OUT_BIAS_350PC (7 << 4)
244
245/* DA732X_REG_SIF_VDD_SEL (addr=0x08) */
246#define DA732X_SIF_VDD_SEL_AIFA_VDD2 (1 << 0)
247#define DA732X_SIF_VDD_SEL_AIFB_VDD2 (1 << 1)
248#define DA732X_SIF_VDD_SEL_CIFA_VDD2 (1 << 4)
249
250/* DA732X_REG_MICBIAS2/1 (addr=0x0F/0x10) */
251#define DA732X_MICBIAS_VOLTAGE_MASK (0x0F << 0)
252#define DA732X_MICBIAS_VOLTAGE_2V (0x00 << 0)
253#define DA732X_MICBIAS_VOLTAGE_2V05 (0x01 << 0)
254#define DA732X_MICBIAS_VOLTAGE_2V1 (0x02 << 0)
255#define DA732X_MICBIAS_VOLTAGE_2V15 (0x03 << 0)
256#define DA732X_MICBIAS_VOLTAGE_2V2 (0x04 << 0)
257#define DA732X_MICBIAS_VOLTAGE_2V25 (0x05 << 0)
258#define DA732X_MICBIAS_VOLTAGE_2V3 (0x06 << 0)
259#define DA732X_MICBIAS_VOLTAGE_2V35 (0x07 << 0)
260#define DA732X_MICBIAS_VOLTAGE_2V4 (0x08 << 0)
261#define DA732X_MICBIAS_VOLTAGE_2V45 (0x09 << 0)
262#define DA732X_MICBIAS_VOLTAGE_2V5 (0x0A << 0)
263#define DA732X_MICBIAS_EN (1 << 7)
264#define DA732X_MICBIAS_EN_SHIFT 7
265#define DA732X_MICBIAS_VOLTAGE_SHIFT 0
266#define DA732X_MICBIAS_VOLTAGE_MAX 0x0B
267
268/* DA732X_REG_MICDET (addr=0x11) */
269#define DA732X_MICDET_INP_MICRES (1 << 0)
270#define DA732X_MICDET_INP_MICHOOK (1 << 1)
271#define DA732X_MICDET_INP_DEBOUNCE_PRD_8MS (0 << 0)
272#define DA732X_MICDET_INP_DEBOUNCE_PRD_16MS (1 << 0)
273#define DA732X_MICDET_INP_DEBOUNCE_PRD_32MS (2 << 0)
274#define DA732X_MICDET_INP_DEBOUNCE_PRD_64MS (3 << 0)
275#define DA732X_MICDET_INP_MICDET_EN (1 << 7)
276
277/* DA732X_REG_MIC1/2/3_PRE (addr=0x11/0x14/0x18) */
278#define DA732X_MICBOOST_MASK 0x7
279#define DA732X_MICBOOST_SHIFT 0
280#define DA732X_MICBOOST_MIN 0x1
281#define DA732X_MICBOOST_MAX DA732X_MICBOOST_MASK
282
283/* DA732X_REG_MIC1/2/3 (addr=0x13/0x15/0x19) */
284#define DA732X_MIC_VOL_SHIFT 0
285#define DA732X_MIC_VOL_VAL_MASK 0x1F
286#define DA732X_MIC_MUTE_SHIFT 6
287#define DA732X_MIC_EN_SHIFT 7
288#define DA732X_MIC_VOL_VAL_MIN 0x7
289#define DA732X_MIC_VOL_VAL_MAX DA732X_MIC_VOL_VAL_MASK
290
291/* DA732X_REG_AUX1L/R (addr=0x16/0x17) */
292#define DA732X_AUX_VOL_SHIFT 0
293#define DA732X_AUX_VOL_MASK 0x7
294#define DA732X_AUX_MUTE_SHIFT 6
295#define DA732X_AUX_EN_SHIFT 7
296#define DA732X_AUX_VOL_VAL_MAX DA732X_AUX_VOL_MASK
297
298/* DA732X_REG_INP_PINBIAS (addr=0x1A) */
299#define DA732X_INP_MICL_PINBIAS_EN (1 << 0)
300#define DA732X_INP_MICR_PINBIAS_EN (1 << 1)
301#define DA732X_INP_AUX1L_PINBIAS_EN (1 << 2)
302#define DA732X_INP_AUX1R_PINBIAS_EN (1 << 3)
303#define DA732X_INP_AUX2_PINBIAS_EN (1 << 4)
304
305/* DA732X_REG_INP_ZC_EN (addr=0x1B) */
306#define DA732X_MIC1_PRE_ZC_EN (1 << 0)
307#define DA732X_MIC1_ZC_EN (1 << 1)
308#define DA732X_MIC2_PRE_ZC_EN (1 << 2)
309#define DA732X_MIC2_ZC_EN (1 << 3)
310#define DA732X_AUXL_ZC_EN (1 << 4)
311#define DA732X_AUXR_ZC_EN (1 << 5)
312#define DA732X_MIC3_PRE_ZC_EN (1 << 6)
313#define DA732X_MIC3_ZC_EN (1 << 7)
314
315/* DA732X_REG_INP_MUX (addr=0x1D) */
316#define DA732X_INP_ADC1L_MUX_SEL_AUX1L (0 << 0)
317#define DA732X_INP_ADC1L_MUX_SEL_MIC1 (1 << 0)
318#define DA732X_INP_ADC1R_MUX_SEL_MASK (3 << 2)
319#define DA732X_INP_ADC1R_MUX_SEL_AUX1R (0 << 2)
320#define DA732X_INP_ADC1R_MUX_SEL_MIC2 (1 << 2)
321#define DA732X_INP_ADC1R_MUX_SEL_MIC3 (2 << 2)
322#define DA732X_INP_ADC2L_MUX_SEL_AUX1L (0 << 4)
323#define DA732X_INP_ADC2L_MUX_SEL_MICL (1 << 4)
324#define DA732X_INP_ADC2R_MUX_SEL_MASK (3 << 6)
325#define DA732X_INP_ADC2R_MUX_SEL_AUX1R (0 << 6)
326#define DA732X_INP_ADC2R_MUX_SEL_MICR (1 << 6)
327#define DA732X_INP_ADC2R_MUX_SEL_AUX2 (2 << 6)
328#define DA732X_ADC1L_MUX_SEL_SHIFT 0
329#define DA732X_ADC1R_MUX_SEL_SHIFT 2
330#define DA732X_ADC2L_MUX_SEL_SHIFT 4
331#define DA732X_ADC2R_MUX_SEL_SHIFT 6
332
333/* DA732X_REG_HP_DET (addr=0x20) */
334#define DA732X_HP_DET_AZ (1 << 0)
335#define DA732X_HP_DET_SEL1 (1 << 1)
336#define DA732X_HP_DET_IS_MASK (3 << 2)
337#define DA732X_HP_DET_IS_0_5UA (0 << 2)
338#define DA732X_HP_DET_IS_1UA (1 << 2)
339#define DA732X_HP_DET_IS_2UA (2 << 2)
340#define DA732X_HP_DET_IS_4UA (3 << 2)
341#define DA732X_HP_DET_RS_MASK (3 << 4)
342#define DA732X_HP_DET_RS_INFINITE (0 << 4)
343#define DA732X_HP_DET_RS_100KOHM (1 << 4)
344#define DA732X_HP_DET_RS_10KOHM (2 << 4)
345#define DA732X_HP_DET_RS_1KOHM (3 << 4)
346#define DA732X_HP_DET_EN (1 << 7)
347
348/* DA732X_REG_HPL_DAC_OFFSET (addr=0x21/0x26) */
349#define DA732X_HP_DAC_OFFSET_TRIM_MASK (0x3F << 0)
350#define DA732X_HP_DAC_OFFSET_DAC_SIGN (1 << 6)
351
352/* DA732X_REG_HPL_DAC_OFF_CNTL (addr=0x22/0x27) */
353#define DA732X_HP_DAC_OFF_CNTL_CONT_MASK (7 << 0)
354#define DA732X_HP_DAC_OFF_CNTL_COMPO (1 << 3)
355#define DA732X_HP_DAC_OFF_CALIBRATION (1 << 0)
356#define DA732X_HP_DAC_OFF_SCALE_STEPS (1 << 1)
357#define DA732X_HP_DAC_OFF_MASK 0x7F
358#define DA732X_HP_DAC_COMPO_SHIFT 3
359
360/* DA732X_REG_HPL_OUT_OFFSET (addr=0x23/0x28) */
361#define DA732X_HP_OUT_OFFSET_MASK (0xFF << 0)
362#define DA732X_HP_DAC_OFFSET_TRIM_VAL 0x7F
363
364/* DA732X_REG_HPL/R (addr=0x24/0x29) */
365#define DA732X_HP_OUT_SIGN (1 << 0)
366#define DA732X_HP_OUT_COMP (1 << 1)
367#define DA732X_HP_OUT_RESERVED (1 << 2)
368#define DA732X_HP_OUT_COMPO (1 << 3)
369#define DA732X_HP_OUT_DAC_EN (1 << 4)
370#define DA732X_HP_OUT_HIZ_EN (1 << 5)
371#define DA732X_HP_OUT_HIZ_DIS (0 << 5)
372#define DA732X_HP_OUT_MUTE (1 << 6)
373#define DA732X_HP_OUT_EN (1 << 7)
374#define DA732X_HP_OUT_COMPO_SHIFT 3
375#define DA732X_HP_OUT_DAC_EN_SHIFT 4
376#define DA732X_HP_HIZ_SHIFT 5
377#define DA732X_HP_MUTE_SHIFT 6
378#define DA732X_HP_OUT_EN_SHIFT 7
379
380#define DA732X_OUT_HIZ_EN (1 << 5)
381#define DA732X_OUT_HIZ_DIS (0 << 5)
382
383/* DA732X_REG_HPL/R_VOL (addr=0x25/0x2A) */
384#define DA732X_HP_VOL_VAL_MASK 0xF
385#define DA732X_HP_VOL_SHIFT 0
386#define DA732X_HP_VOL_VAL_MAX DA732X_HP_VOL_VAL_MASK
387
388/* DA732X_REG_LIN2/3/4 (addr=0x2B/0x2C/0x2D) */
389#define DA732X_LOUT_VOL_SHIFT 0
390#define DA732X_LOUT_VOL_MASK 0x0F
391#define DA732X_LOUT_DAC_OFF (0 << 4)
392#define DA732X_LOUT_DAC_EN (1 << 4)
393#define DA732X_LOUT_HIZ_N_DIS (0 << 5)
394#define DA732X_LOUT_HIZ_N_EN (1 << 5)
395#define DA732X_LOUT_UNMUTED (0 << 6)
396#define DA732X_LOUT_MUTED (1 << 6)
397#define DA732X_LOUT_EN (0 << 7)
398#define DA732X_LOUT_DIS (1 << 7)
399#define DA732X_LOUT_DAC_EN_SHIFT 4
400#define DA732X_LOUT_MUTE_SHIFT 6
401#define DA732X_LIN_OUT_EN_SHIFT 7
402#define DA732X_LOUT_VOL_VAL_MAX DA732X_LOUT_VOL_MASK
403
404/* DA732X_REG_OUT_ZC_EN (addr=0x2E) */
405#define DA732X_HPL_ZC_EN_SHIFT 0
406#define DA732X_HPR_ZC_EN_SHIFT 1
407#define DA732X_HPL_ZC_EN (1 << 0)
408#define DA732X_HPL_ZC_DIS (0 << 0)
409#define DA732X_HPR_ZC_EN (1 << 1)
410#define DA732X_HPR_ZC_DIS (0 << 1)
411#define DA732X_LIN2_ZC_EN (1 << 2)
412#define DA732X_LIN2_ZC_DIS (0 << 2)
413#define DA732X_LIN3_ZC_EN (1 << 3)
414#define DA732X_LIN3_ZC_DIS (0 << 3)
415#define DA732X_LIN4_ZC_EN (1 << 4)
416#define DA732X_LIN4_ZC_DIS (0 << 4)
417
418/* DA732X_REG_HP_LIN1_GNDSEL (addr=0x37) */
419#define DA732X_HP_OUT_GNDSEL (1 << 0)
420
421/* DA732X_REG_CP_HP2 (addr=0x3a) */
422#define DA732X_HP_CP_PULSESKIP (1 << 0)
423#define DA732X_HP_CP_REG (1 << 1)
424#define DA732X_HP_CP_EN (1 << 3)
425#define DA732X_HP_CP_DIS (0 << 3)
426
427/* DA732X_REG_CP_CTRL1 (addr=0x40) */
428#define DA732X_CP_MODE_MASK (7 << 1)
429#define DA732X_CP_CTRL_STANDBY (0 << 1)
430#define DA732X_CP_CTRL_CPVDD6 (2 << 1)
431#define DA732X_CP_CTRL_CPVDD5 (3 << 1)
432#define DA732X_CP_CTRL_CPVDD4 (4 << 1)
433#define DA732X_CP_CTRL_CPVDD3 (5 << 1)
434#define DA732X_CP_CTRL_CPVDD2 (6 << 1)
435#define DA732X_CP_CTRL_CPVDD1 (7 << 1)
436#define DA723X_CP_DIS (0 << 7)
437#define DA732X_CP_EN (1 << 7)
438
439/* DA732X_REG_CP_CTRL2 (addr=0x41) */
440#define DA732X_CP_BOOST (1 << 0)
441#define DA732X_CP_MANAGE_MAGNITUDE (2 << 2)
442
443/* DA732X_REG_CP_CTRL3 (addr=0x42) */
444#define DA732X_CP_1MHZ (0 << 0)
445#define DA732X_CP_500KHZ (1 << 0)
446#define DA732X_CP_250KHZ (2 << 0)
447#define DA732X_CP_125KHZ (3 << 0)
448#define DA732X_CP_63KHZ (4 << 0)
449#define DA732X_CP_0KHZ (5 << 0)
450
451/* DA732X_REG_PLL_CTRL (addr=0x53) */
452#define DA732X_PLL_INDIV_MASK (3 << 0)
453#define DA732X_PLL_SRM_EN (1 << 2)
454#define DA732X_PLL_EN (1 << 7)
455#define DA732X_PLL_BYPASS (0 << 0)
456
457/* DA732X_REG_CLK_CTRL (addr=0x54) */
458#define DA732X_SR1_MASK (0xF)
459#define DA732X_SR2_MASK (0xF0)
460
461/* DA732X_REG_CLK_DSP (addr=0x5A) */
462#define DA732X_DSP_FREQ_MASK (7 << 0)
463#define DA732X_DSP_FREQ_12MHZ (0 << 0)
464#define DA732X_DSP_FREQ_24MHZ (1 << 0)
465#define DA732X_DSP_FREQ_36MHZ (2 << 0)
466#define DA732X_DSP_FREQ_48MHZ (3 << 0)
467#define DA732X_DSP_FREQ_60MHZ (4 << 0)
468#define DA732X_DSP_FREQ_72MHZ (5 << 0)
469#define DA732X_DSP_FREQ_84MHZ (6 << 0)
470#define DA732X_DSP_FREQ_96MHZ (7 << 0)
471
472/* DA732X_REG_CLK_EN1 (addr=0x5B) */
473#define DA732X_DSP_CLK_EN (1 << 0)
474#define DA732X_SYS3_CLK_EN (1 << 1)
475#define DA732X_DSP12_CLK_EN (1 << 2)
476#define DA732X_PC_CLK_EN (1 << 3)
477#define DA732X_MCLK_SQR_EN (1 << 7)
478
479/* DA732X_REG_CLK_EN2 (addr=0x5C) */
480#define DA732X_UART_CLK_EN (1 << 1)
481#define DA732X_CP_CLK_EN (1 << 2)
482#define DA732X_CP_CLK_DIS (0 << 2)
483
484/* DA732X_REG_CLK_EN3 (addr=0x5D) */
485#define DA732X_ADCA_BB_CLK_EN (1 << 0)
486#define DA732X_ADCC_BB_CLK_EN (1 << 4)
487
488/* DA732X_REG_CLK_EN4 (addr=0x5E) */
489#define DA732X_DACA_BB_CLK_EN (1 << 0)
490#define DA732X_DACC_BB_CLK_EN (1 << 4)
491#define DA732X_DACA_BB_CLK_SHIFT 0
492#define DA732X_DACC_BB_CLK_SHIFT 4
493
494/* DA732X_REG_CLK_EN5 (addr=0x5F) */
495#define DA732X_DACE_BB_CLK_EN (1 << 0)
496#define DA732X_DACE_BB_CLK_SHIFT 0
497
498/* DA732X_REG_AIF_MCLK (addr=0x60) */
499#define DA732X_AIFM_FRAME_64 (1 << 2)
500#define DA732X_AIFM_SRC_SEL_AIFA (1 << 6)
501#define DA732X_CLK_GENERATION_AIF_A (1 << 4)
502#define DA732X_NO_CLK_GENERATION 0x0
503
504/* DA732X_REG_AIFA1 (addr=0x61) */
505#define DA732X_AIF_WORD_MASK (0x3 << 0)
506#define DA732X_AIF_WORD_16 (0 << 0)
507#define DA732X_AIF_WORD_20 (1 << 0)
508#define DA732X_AIF_WORD_24 (2 << 0)
509#define DA732X_AIF_WORD_32 (3 << 0)
510#define DA732X_AIF_TDM_MONO_SHIFT (1 << 6)
511#define DA732X_AIF1_CLK_MASK (1 << 7)
512#define DA732X_AIF_SLAVE (0 << 7)
513#define DA732X_AIF_CLK_FROM_SRC (1 << 7)
514
515/* DA732X_REG_AIFA3 (addr=0x63) */
516#define DA732X_AIF_MODE_SHIFT 0
517#define DA732X_AIF_MODE_MASK 0x3
518#define DA732X_AIF_I2S_MODE (0 << 0)
519#define DA732X_AIF_LEFT_J_MODE (1 << 0)
520#define DA732X_AIF_RIGHT_J_MODE (2 << 0)
521#define DA732X_AIF_DSP_MODE (3 << 0)
522#define DA732X_AIF_WCLK_INV (1 << 4)
523#define DA732X_AIF_BCLK_INV (1 << 5)
524#define DA732X_AIF_EN (1 << 7)
525#define DA732X_AIF_EN_SHIFT 7
526
527/* DA732X_REG_PC_CTRL (addr=0x6a) */
528#define DA732X_PC_PULSE_AIFA (0 << 0)
529#define DA732X_PC_PULSE_AIFB (1 << 0)
530#define DA732X_PC_RESYNC_AUT (1 << 6)
531#define DA732X_PC_RESYNC_NOT_AUT (0 << 6)
532#define DA732X_PC_SAME (1 << 7)
533
534/* DA732X_REG_DATA_ROUTE (addr=0x70) */
535#define DA732X_ADC1_TO_AIFA (0 << 0)
536#define DA732X_DSP_TO_AIFA (1 << 0)
537#define DA732X_ADC2_TO_AIFB (0 << 1)
538#define DA732X_DSP_TO_AIFB (1 << 1)
539#define DA732X_AIFA_TO_DAC1L (0 << 2)
540#define DA732X_DSP_TO_DAC1L (1 << 2)
541#define DA732X_AIFA_TO_DAC1R (0 << 3)
542#define DA732X_DSP_TO_DAC1R (1 << 3)
543#define DA732X_AIFB_TO_DAC2L (0 << 4)
544#define DA732X_DSP_TO_DAC2L (1 << 4)
545#define DA732X_AIFB_TO_DAC2R (0 << 5)
546#define DA732X_DSP_TO_DAC2R (1 << 5)
547#define DA732X_AIFB_TO_DAC3 (0 << 6)
548#define DA732X_DSP_TO_DAC3 (1 << 6)
549#define DA732X_BYPASS_DSP (0 << 0)
550#define DA732X_ALL_TO_DSP (0x7F << 0)
551
552/* DA732X_REG_DSP_CTRL (addr=0x71) */
553#define DA732X_DIGITAL_EN (1 << 0)
554#define DA732X_DIGITAL_RESET (0 << 0)
555#define DA732X_DSP_CORE_EN (1 << 1)
556#define DA732X_DSP_CORE_RESET (0 << 1)
557
558/* DA732X_REG_SPARE1_OUT (addr=0x7D)*/
559#define DA732X_HP_DRIVER_EN (1 << 0)
560#define DA732X_HP_GATE_LOW (1 << 2)
561#define DA732X_HP_LOOP_GAIN_CTRL (1 << 3)
562
563/* DA732X_REG_ID (addr=0x81)*/
564#define DA732X_ID_MINOR_MASK (0xF << 0)
565#define DA732X_ID_MAJOR_MASK (0xF << 4)
566
567/* DA732X_REG_ADC1/2_PD (addr=0x90/0x98) */
568#define DA732X_ADC_RST_MASK (0x3 << 0)
569#define DA732X_ADC_PD_MASK (0x3 << 2)
570#define DA732X_ADC_SET_ACT (0x3 << 0)
571#define DA732X_ADC_SET_RST (0x0 << 0)
572#define DA732X_ADC_ON (0x3 << 2)
573#define DA732X_ADC_OFF (0x0 << 2)
574
575/* DA732X_REG_ADC1/2_SEL (addr=0x94/0x9C) */
576#define DA732X_ADC_VOL_VAL_MASK 0x7
577#define DA732X_ADCL_VOL_SHIFT 0
578#define DA732X_ADCR_VOL_SHIFT 4
579#define DA732X_ADCL_EN_SHIFT 2
580#define DA732X_ADCR_EN_SHIFT 3
581#define DA732X_ADCL_EN (1 << 2)
582#define DA732X_ADCR_EN (1 << 3)
583#define DA732X_ADC_VOL_VAL_MAX DA732X_ADC_VOL_VAL_MASK
584
585/*
586 * DA732X_REG_ADC1/2_HPF (addr=0x93/0x9b)
587 * DA732x_REG_DAC1/2/3_HPG (addr=0xA5/0xB5/0xC5)
588 */
589#define DA732X_HPF_MUSIC_EN (1 << 3)
590#define DA732X_HPF_VOICE_EN ((1 << 3) | (1 << 7))
591#define DA732X_HPF_MASK ((1 << 3) | (1 << 7))
592#define DA732X_HPF_DIS ((0 << 3) | (0 << 7))
593
594/* DA732X_REG_DAC1/2/3_VOL */
595#define DA732X_DAC_VOL_VAL_MASK 0x7F
596#define DA732X_DAC_VOL_SHIFT 0
597#define DA732X_DAC_VOL_VAL_MAX DA732X_DAC_VOL_VAL_MASK
598
599/* DA732X_REG_DAC1/2/3_SEL (addr=0xA3/0xB3/0xC3) */
600#define DA732X_DACL_EN_SHIFT 3
601#define DA732X_DACR_EN_SHIFT 7
602#define DA732X_DACL_MUTE_SHIFT 2
603#define DA732X_DACR_MUTE_SHIFT 6
604#define DA732X_DACL_EN (1 << 3)
605#define DA732X_DACR_EN (1 << 7)
606#define DA732X_DACL_SDM (1 << 0)
607#define DA732X_DACR_SDM (1 << 4)
608#define DA732X_DACL_MUTE (1 << 2)
609#define DA732X_DACR_MUTE (1 << 6)
610
611/* DA732X_REG_DAC_SOFTMUTE (addr=0xA4/0xB4/0xC4) */
612#define DA732X_SOFTMUTE_EN (1 << 7)
613#define DA732X_GAIN_RAMPED (1 << 6)
614#define DA732X_16_SAMPLES (4 << 0)
615#define DA732X_SOFTMUTE_MASK (1 << 7)
616#define DA732X_SOFTMUTE_SHIFT 7
617
618/*
619 * DA732x_REG_ADC1/2_EQ12 (addr=0x95/0x9D)
620 * DA732x_REG_ADC1/2_EQ34 (addr=0x96/0x9E)
621 * DA732x_REG_ADC1/2_EQ5 (addr=0x97/0x9F)
622 * DA732x_REG_DAC1/2/3_EQ12 (addr=0xA5/0xB5/0xC5)
623 * DA732x_REG_DAC1/2/3_EQ34 (addr=0xA6/0xB6/0xC6)
624 * DA732x_REG_DAC1/2/3_EQ5 (addr=0xA7/0xB7/0xB7)
625 */
626#define DA732X_EQ_VOL_VAL_MASK 0xF
627#define DA732X_EQ_BAND1_SHIFT 0
628#define DA732X_EQ_BAND2_SHIFT 4
629#define DA732X_EQ_BAND3_SHIFT 0
630#define DA732X_EQ_BAND4_SHIFT 4
631#define DA732X_EQ_BAND5_SHIFT 0
632#define DA732X_EQ_OVERALL_SHIFT 4
633#define DA732X_EQ_OVERALL_VOL_VAL_MASK 0x3
634#define DA732X_EQ_DIS (0 << 7)
635#define DA732X_EQ_EN (1 << 7)
636#define DA732X_EQ_EN_SHIFT 7
637#define DA732X_EQ_VOL_VAL_MAX DA732X_EQ_VOL_VAL_MASK
638#define DA732X_EQ_OVERALL_VOL_VAL_MAX DA732X_EQ_OVERALL_VOL_VAL_MASK
639
640/* DA732X_REG_DMA_CMD (addr=0xD3) */
641#define DA732X_SEL_DSP_DMA_MASK (3 << 0)
642#define DA732X_SEL_DSP_DMA_DIS (0 << 0)
643#define DA732X_SEL_DSP_DMA_PMEM (1 << 0)
644#define DA732X_SEL_DSP_DMA_XMEM (2 << 0)
645#define DA732X_SEL_DSP_DMA_YMEM (3 << 0)
646#define DA732X_DSP_RW_MASK (1 << 4)
647#define DA732X_DSP_DMA_WRITE (0 << 4)
648#define DA732X_DSP_DMA_READ (1 << 4)
649
650/* DA732X_REG_DMA_STATUS (addr=0xDA) */
651#define DA732X_DSP_DMA_FREE (0 << 0)
652#define DA732X_DSP_DMA_BUSY (1 << 0)
653
654#endif /* __DA732X_REG_H_ */
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c
new file mode 100644
index 000000000000..5d8f39e32978
--- /dev/null
+++ b/sound/soc/codecs/isabelle.c
@@ -0,0 +1,1176 @@
1/*
2 * isabelle.c - Low power high fidelity audio codec driver
3 *
4 * Copyright (c) 2012 Texas Instruments, Inc
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 *
11 * Initially based on sound/soc/codecs/twl6040.c
12 *
13 */
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/version.h>
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/pm.h>
21#include <linux/regmap.h>
22#include <linux/i2c.h>
23#include <linux/slab.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/tlv.h>
30#include <sound/jack.h>
31#include <sound/initval.h>
32#include <asm/div64.h>
33#include "isabelle.h"
34
35
36/* Register default values for ISABELLE driver. */
37static struct reg_default isabelle_reg_defs[] = {
38 { 0, 0x00 },
39 { 1, 0x00 },
40 { 2, 0x00 },
41 { 3, 0x00 },
42 { 4, 0x00 },
43 { 5, 0x00 },
44 { 6, 0x00 },
45 { 7, 0x00 },
46 { 8, 0x00 },
47 { 9, 0x00 },
48 { 10, 0x00 },
49 { 11, 0x00 },
50 { 12, 0x00 },
51 { 13, 0x00 },
52 { 14, 0x00 },
53 { 15, 0x00 },
54 { 16, 0x00 },
55 { 17, 0x00 },
56 { 18, 0x00 },
57 { 19, 0x00 },
58 { 20, 0x00 },
59 { 21, 0x02 },
60 { 22, 0x02 },
61 { 23, 0x02 },
62 { 24, 0x02 },
63 { 25, 0x0F },
64 { 26, 0x8F },
65 { 27, 0x0F },
66 { 28, 0x8F },
67 { 29, 0x00 },
68 { 30, 0x00 },
69 { 31, 0x00 },
70 { 32, 0x00 },
71 { 33, 0x00 },
72 { 34, 0x00 },
73 { 35, 0x00 },
74 { 36, 0x00 },
75 { 37, 0x00 },
76 { 38, 0x00 },
77 { 39, 0x00 },
78 { 40, 0x00 },
79 { 41, 0x00 },
80 { 42, 0x00 },
81 { 43, 0x00 },
82 { 44, 0x00 },
83 { 45, 0x00 },
84 { 46, 0x00 },
85 { 47, 0x00 },
86 { 48, 0x00 },
87 { 49, 0x00 },
88 { 50, 0x00 },
89 { 51, 0x00 },
90 { 52, 0x00 },
91 { 53, 0x00 },
92 { 54, 0x00 },
93 { 55, 0x00 },
94 { 56, 0x00 },
95 { 57, 0x00 },
96 { 58, 0x00 },
97 { 59, 0x00 },
98 { 60, 0x00 },
99 { 61, 0x00 },
100 { 62, 0x00 },
101 { 63, 0x00 },
102 { 64, 0x00 },
103 { 65, 0x00 },
104 { 66, 0x00 },
105 { 67, 0x00 },
106 { 68, 0x00 },
107 { 69, 0x90 },
108 { 70, 0x90 },
109 { 71, 0x90 },
110 { 72, 0x00 },
111 { 73, 0x00 },
112 { 74, 0x00 },
113 { 75, 0x00 },
114 { 76, 0x00 },
115 { 77, 0x00 },
116 { 78, 0x00 },
117 { 79, 0x00 },
118 { 80, 0x00 },
119 { 81, 0x00 },
120 { 82, 0x00 },
121 { 83, 0x00 },
122 { 84, 0x00 },
123 { 85, 0x07 },
124 { 86, 0x00 },
125 { 87, 0x00 },
126 { 88, 0x00 },
127 { 89, 0x07 },
128 { 90, 0x80 },
129 { 91, 0x07 },
130 { 92, 0x07 },
131 { 93, 0x00 },
132 { 94, 0x00 },
133 { 95, 0x00 },
134 { 96, 0x00 },
135 { 97, 0x00 },
136 { 98, 0x00 },
137 { 99, 0x00 },
138};
139
140static const char *isabelle_rx1_texts[] = {"VRX1", "ARX1"};
141static const char *isabelle_rx2_texts[] = {"VRX2", "ARX2"};
142
143static const struct soc_enum isabelle_rx1_enum[] = {
144 SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 3, 1, isabelle_rx1_texts),
145 SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 5, 1, isabelle_rx1_texts),
146};
147
148static const struct soc_enum isabelle_rx2_enum[] = {
149 SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 2, 1, isabelle_rx2_texts),
150 SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 4, 1, isabelle_rx2_texts),
151};
152
153/* Headset DAC playback switches */
154static const struct snd_kcontrol_new rx1_mux_controls =
155 SOC_DAPM_ENUM("Route", isabelle_rx1_enum);
156
157static const struct snd_kcontrol_new rx2_mux_controls =
158 SOC_DAPM_ENUM("Route", isabelle_rx2_enum);
159
160/* TX input selection */
161static const char *isabelle_atx_texts[] = {"AMIC1", "DMIC"};
162static const char *isabelle_vtx_texts[] = {"AMIC2", "DMIC"};
163
164static const struct soc_enum isabelle_atx_enum[] = {
165 SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 7, 1, isabelle_atx_texts),
166 SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_atx_texts),
167};
168
169static const struct soc_enum isabelle_vtx_enum[] = {
170 SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 6, 1, isabelle_vtx_texts),
171 SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_vtx_texts),
172};
173
174static const struct snd_kcontrol_new atx_mux_controls =
175 SOC_DAPM_ENUM("Route", isabelle_atx_enum);
176
177static const struct snd_kcontrol_new vtx_mux_controls =
178 SOC_DAPM_ENUM("Route", isabelle_vtx_enum);
179
180/* Left analog microphone selection */
181static const char *isabelle_amic1_texts[] = {
182 "Main Mic", "Headset Mic", "Aux/FM Left"};
183
184/* Left analog microphone selection */
185static const char *isabelle_amic2_texts[] = {"Sub Mic", "Aux/FM Right"};
186
187static const struct soc_enum isabelle_amic1_enum[] = {
188 SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 5,
189 ARRAY_SIZE(isabelle_amic1_texts),
190 isabelle_amic1_texts),
191};
192
193static const struct soc_enum isabelle_amic2_enum[] = {
194 SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 4,
195 ARRAY_SIZE(isabelle_amic2_texts),
196 isabelle_amic2_texts),
197};
198
199static const struct snd_kcontrol_new amic1_control =
200 SOC_DAPM_ENUM("Route", isabelle_amic1_enum);
201
202static const struct snd_kcontrol_new amic2_control =
203 SOC_DAPM_ENUM("Route", isabelle_amic2_enum);
204
205static const char *isabelle_st_audio_texts[] = {"ATX1", "ATX2"};
206
207static const char *isabelle_st_voice_texts[] = {"VTX1", "VTX2"};
208
209static const struct soc_enum isabelle_st_audio_enum[] = {
210 SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA1_CFG_REG, 7, 1,
211 isabelle_st_audio_texts),
212 SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA2_CFG_REG, 7, 1,
213 isabelle_st_audio_texts),
214};
215
216static const struct soc_enum isabelle_st_voice_enum[] = {
217 SOC_ENUM_SINGLE(ISABELLE_VTX_STPGA1_CFG_REG, 7, 1,
218 isabelle_st_voice_texts),
219 SOC_ENUM_SINGLE(ISABELLE_VTX2_STPGA2_CFG_REG, 7, 1,
220 isabelle_st_voice_texts),
221};
222
223static const struct snd_kcontrol_new st_audio_control =
224 SOC_DAPM_ENUM("Route", isabelle_st_audio_enum);
225
226static const struct snd_kcontrol_new st_voice_control =
227 SOC_DAPM_ENUM("Route", isabelle_st_voice_enum);
228
229/* Mixer controls */
230static const struct snd_kcontrol_new isabelle_hs_left_mixer_controls[] = {
231SOC_DAPM_SINGLE("DAC1L Playback Switch", ISABELLE_HSDRV_CFG1_REG, 7, 1, 0),
232SOC_DAPM_SINGLE("APGA1 Playback Switch", ISABELLE_HSDRV_CFG1_REG, 6, 1, 0),
233};
234
235static const struct snd_kcontrol_new isabelle_hs_right_mixer_controls[] = {
236SOC_DAPM_SINGLE("DAC1R Playback Switch", ISABELLE_HSDRV_CFG1_REG, 5, 1, 0),
237SOC_DAPM_SINGLE("APGA2 Playback Switch", ISABELLE_HSDRV_CFG1_REG, 4, 1, 0),
238};
239
240static const struct snd_kcontrol_new isabelle_hf_left_mixer_controls[] = {
241SOC_DAPM_SINGLE("DAC2L Playback Switch", ISABELLE_HFLPGA_CFG_REG, 7, 1, 0),
242SOC_DAPM_SINGLE("APGA1 Playback Switch", ISABELLE_HFLPGA_CFG_REG, 6, 1, 0),
243};
244
245static const struct snd_kcontrol_new isabelle_hf_right_mixer_controls[] = {
246SOC_DAPM_SINGLE("DAC2R Playback Switch", ISABELLE_HFRPGA_CFG_REG, 7, 1, 0),
247SOC_DAPM_SINGLE("APGA2 Playback Switch", ISABELLE_HFRPGA_CFG_REG, 6, 1, 0),
248};
249
250static const struct snd_kcontrol_new isabelle_ep_mixer_controls[] = {
251SOC_DAPM_SINGLE("DAC2L Playback Switch", ISABELLE_EARDRV_CFG1_REG, 7, 1, 0),
252SOC_DAPM_SINGLE("APGA1 Playback Switch", ISABELLE_EARDRV_CFG1_REG, 6, 1, 0),
253};
254
255static const struct snd_kcontrol_new isabelle_aux_left_mixer_controls[] = {
256SOC_DAPM_SINGLE("DAC3L Playback Switch", ISABELLE_LINEAMP_CFG_REG, 7, 1, 0),
257SOC_DAPM_SINGLE("APGA1 Playback Switch", ISABELLE_LINEAMP_CFG_REG, 6, 1, 0),
258};
259
260static const struct snd_kcontrol_new isabelle_aux_right_mixer_controls[] = {
261SOC_DAPM_SINGLE("DAC3R Playback Switch", ISABELLE_LINEAMP_CFG_REG, 5, 1, 0),
262SOC_DAPM_SINGLE("APGA2 Playback Switch", ISABELLE_LINEAMP_CFG_REG, 4, 1, 0),
263};
264
265static const struct snd_kcontrol_new isabelle_dpga1_left_mixer_controls[] = {
266SOC_DAPM_SINGLE("RX1 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 7, 1, 0),
267SOC_DAPM_SINGLE("RX3 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 6, 1, 0),
268SOC_DAPM_SINGLE("RX5 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 5, 1, 0),
269};
270
271static const struct snd_kcontrol_new isabelle_dpga1_right_mixer_controls[] = {
272SOC_DAPM_SINGLE("RX2 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 3, 1, 0),
273SOC_DAPM_SINGLE("RX4 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 2, 1, 0),
274SOC_DAPM_SINGLE("RX6 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 1, 1, 0),
275};
276
277static const struct snd_kcontrol_new isabelle_dpga2_left_mixer_controls[] = {
278SOC_DAPM_SINGLE("RX1 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 7, 1, 0),
279SOC_DAPM_SINGLE("RX2 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 6, 1, 0),
280SOC_DAPM_SINGLE("RX3 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 5, 1, 0),
281SOC_DAPM_SINGLE("RX4 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 4, 1, 0),
282SOC_DAPM_SINGLE("RX5 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 3, 1, 0),
283SOC_DAPM_SINGLE("RX6 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 2, 1, 0),
284};
285
286static const struct snd_kcontrol_new isabelle_dpga2_right_mixer_controls[] = {
287SOC_DAPM_SINGLE("USNC Playback Switch", ISABELLE_DPGA2R_IN_SEL_REG, 7, 1, 0),
288SOC_DAPM_SINGLE("RX2 Playback Switch", ISABELLE_DPGA2R_IN_SEL_REG, 3, 1, 0),
289SOC_DAPM_SINGLE("RX4 Playback Switch", ISABELLE_DPGA2R_IN_SEL_REG, 2, 1, 0),
290SOC_DAPM_SINGLE("RX6 Playback Switch", ISABELLE_DPGA2R_IN_SEL_REG, 1, 1, 0),
291};
292
293static const struct snd_kcontrol_new isabelle_dpga3_left_mixer_controls[] = {
294SOC_DAPM_SINGLE("RX1 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 7, 1, 0),
295SOC_DAPM_SINGLE("RX3 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 6, 1, 0),
296SOC_DAPM_SINGLE("RX5 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 5, 1, 0),
297};
298
299static const struct snd_kcontrol_new isabelle_dpga3_right_mixer_controls[] = {
300SOC_DAPM_SINGLE("RX2 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 3, 1, 0),
301SOC_DAPM_SINGLE("RX4 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 2, 1, 0),
302SOC_DAPM_SINGLE("RX6 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 1, 1, 0),
303};
304
305static const struct snd_kcontrol_new isabelle_rx1_mixer_controls[] = {
306SOC_DAPM_SINGLE("ST1 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 7, 1, 0),
307SOC_DAPM_SINGLE("DL1 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 6, 1, 0),
308};
309
310static const struct snd_kcontrol_new isabelle_rx2_mixer_controls[] = {
311SOC_DAPM_SINGLE("ST2 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 5, 1, 0),
312SOC_DAPM_SINGLE("DL2 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 4, 1, 0),
313};
314
315static const struct snd_kcontrol_new isabelle_rx3_mixer_controls[] = {
316SOC_DAPM_SINGLE("ST1 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 3, 1, 0),
317SOC_DAPM_SINGLE("DL3 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 2, 1, 0),
318};
319
320static const struct snd_kcontrol_new isabelle_rx4_mixer_controls[] = {
321SOC_DAPM_SINGLE("ST2 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 1, 1, 0),
322SOC_DAPM_SINGLE("DL4 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 0, 1, 0),
323};
324
325static const struct snd_kcontrol_new isabelle_rx5_mixer_controls[] = {
326SOC_DAPM_SINGLE("ST1 Playback Switch", ISABELLE_RX_INPUT_CFG2_REG, 7, 1, 0),
327SOC_DAPM_SINGLE("DL5 Playback Switch", ISABELLE_RX_INPUT_CFG2_REG, 6, 1, 0),
328};
329
330static const struct snd_kcontrol_new isabelle_rx6_mixer_controls[] = {
331SOC_DAPM_SINGLE("ST2 Playback Switch", ISABELLE_RX_INPUT_CFG2_REG, 5, 1, 0),
332SOC_DAPM_SINGLE("DL6 Playback Switch", ISABELLE_RX_INPUT_CFG2_REG, 4, 1, 0),
333};
334
335static const struct snd_kcontrol_new ep_path_enable_control =
336 SOC_DAPM_SINGLE("Switch", ISABELLE_EARDRV_CFG2_REG, 0, 1, 0);
337
338/* TLV Declarations */
339static const DECLARE_TLV_DB_SCALE(mic_amp_tlv, 0, 100, 0);
340static const DECLARE_TLV_DB_SCALE(afm_amp_tlv, -3300, 300, 0);
341static const DECLARE_TLV_DB_SCALE(dac_tlv, -1200, 200, 0);
342static const DECLARE_TLV_DB_SCALE(hf_tlv, -5000, 200, 0);
343
344/* from -63 to 0 dB in 1 dB steps */
345static const DECLARE_TLV_DB_SCALE(dpga_tlv, -6300, 100, 1);
346
347/* from -63 to 9 dB in 1 dB steps */
348static const DECLARE_TLV_DB_SCALE(rx_tlv, -6300, 100, 1);
349
350static const DECLARE_TLV_DB_SCALE(st_tlv, -2700, 300, 1);
351static const DECLARE_TLV_DB_SCALE(tx_tlv, -600, 100, 0);
352
353static const struct snd_kcontrol_new isabelle_snd_controls[] = {
354 SOC_DOUBLE_TLV("Headset Playback Volume", ISABELLE_HSDRV_GAIN_REG,
355 4, 0, 0xF, 0, dac_tlv),
356 SOC_DOUBLE_R_TLV("Handsfree Playback Volume",
357 ISABELLE_HFLPGA_CFG_REG, ISABELLE_HFRPGA_CFG_REG,
358 0, 0x1F, 0, hf_tlv),
359 SOC_DOUBLE_TLV("Aux Playback Volume", ISABELLE_LINEAMP_GAIN_REG,
360 4, 0, 0xF, 0, dac_tlv),
361 SOC_SINGLE_TLV("Earpiece Playback Volume", ISABELLE_EARDRV_CFG1_REG,
362 0, 0xF, 0, dac_tlv),
363
364 SOC_DOUBLE_TLV("Aux FM Volume", ISABELLE_APGA_GAIN_REG, 4, 0, 0xF, 0,
365 afm_amp_tlv),
366 SOC_SINGLE_TLV("Mic1 Capture Volume", ISABELLE_MIC1_GAIN_REG, 3, 0x1F,
367 0, mic_amp_tlv),
368 SOC_SINGLE_TLV("Mic2 Capture Volume", ISABELLE_MIC2_GAIN_REG, 3, 0x1F,
369 0, mic_amp_tlv),
370
371 SOC_DOUBLE_R_TLV("DPGA1 Volume", ISABELLE_DPGA1L_GAIN_REG,
372 ISABELLE_DPGA1R_GAIN_REG, 0, 0x3F, 0, dpga_tlv),
373 SOC_DOUBLE_R_TLV("DPGA2 Volume", ISABELLE_DPGA2L_GAIN_REG,
374 ISABELLE_DPGA2R_GAIN_REG, 0, 0x3F, 0, dpga_tlv),
375 SOC_DOUBLE_R_TLV("DPGA3 Volume", ISABELLE_DPGA3L_GAIN_REG,
376 ISABELLE_DPGA3R_GAIN_REG, 0, 0x3F, 0, dpga_tlv),
377
378 SOC_SINGLE_TLV("Sidetone Audio TX1 Volume",
379 ISABELLE_ATX_STPGA1_CFG_REG, 0, 0xF, 0, st_tlv),
380 SOC_SINGLE_TLV("Sidetone Audio TX2 Volume",
381 ISABELLE_ATX_STPGA2_CFG_REG, 0, 0xF, 0, st_tlv),
382 SOC_SINGLE_TLV("Sidetone Voice TX1 Volume",
383 ISABELLE_VTX_STPGA1_CFG_REG, 0, 0xF, 0, st_tlv),
384 SOC_SINGLE_TLV("Sidetone Voice TX2 Volume",
385 ISABELLE_VTX2_STPGA2_CFG_REG, 0, 0xF, 0, st_tlv),
386
387 SOC_SINGLE_TLV("Audio TX1 Volume", ISABELLE_ATX1_DPGA_REG, 4, 0xF, 0,
388 tx_tlv),
389 SOC_SINGLE_TLV("Audio TX2 Volume", ISABELLE_ATX2_DPGA_REG, 4, 0xF, 0,
390 tx_tlv),
391 SOC_SINGLE_TLV("Voice TX1 Volume", ISABELLE_VTX1_DPGA_REG, 4, 0xF, 0,
392 tx_tlv),
393 SOC_SINGLE_TLV("Voice TX2 Volume", ISABELLE_VTX2_DPGA_REG, 4, 0xF, 0,
394 tx_tlv),
395
396 SOC_SINGLE_TLV("RX1 DPGA Volume", ISABELLE_RX1_DPGA_REG, 0, 0x3F, 0,
397 rx_tlv),
398 SOC_SINGLE_TLV("RX2 DPGA Volume", ISABELLE_RX2_DPGA_REG, 0, 0x3F, 0,
399 rx_tlv),
400 SOC_SINGLE_TLV("RX3 DPGA Volume", ISABELLE_RX3_DPGA_REG, 0, 0x3F, 0,
401 rx_tlv),
402 SOC_SINGLE_TLV("RX4 DPGA Volume", ISABELLE_RX4_DPGA_REG, 0, 0x3F, 0,
403 rx_tlv),
404 SOC_SINGLE_TLV("RX5 DPGA Volume", ISABELLE_RX5_DPGA_REG, 0, 0x3F, 0,
405 rx_tlv),
406 SOC_SINGLE_TLV("RX6 DPGA Volume", ISABELLE_RX6_DPGA_REG, 0, 0x3F, 0,
407 rx_tlv),
408
409 SOC_SINGLE("Headset Noise Gate", ISABELLE_HS_NG_CFG1_REG, 7, 1, 0),
410 SOC_SINGLE("Handsfree Noise Gate", ISABELLE_HF_NG_CFG1_REG, 7, 1, 0),
411
412 SOC_SINGLE("ATX1 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
413 7, 1, 0),
414 SOC_SINGLE("ATX2 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
415 6, 1, 0),
416 SOC_SINGLE("ARX1 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
417 5, 1, 0),
418 SOC_SINGLE("ARX2 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
419 4, 1, 0),
420 SOC_SINGLE("ARX3 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
421 3, 1, 0),
422 SOC_SINGLE("ARX4 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
423 2, 1, 0),
424 SOC_SINGLE("ARX5 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
425 1, 1, 0),
426 SOC_SINGLE("ARX6 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
427 0, 1, 0),
428 SOC_SINGLE("VRX1 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
429 3, 1, 0),
430 SOC_SINGLE("VRX2 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
431 2, 1, 0),
432
433 SOC_SINGLE("ATX1 Filter Enable Switch", ISABELLE_ALU_TX_EN_REG,
434 7, 1, 0),
435 SOC_SINGLE("ATX2 Filter Enable Switch", ISABELLE_ALU_TX_EN_REG,
436 6, 1, 0),
437 SOC_SINGLE("VTX1 Filter Enable Switch", ISABELLE_ALU_TX_EN_REG,
438 5, 1, 0),
439 SOC_SINGLE("VTX2 Filter Enable Switch", ISABELLE_ALU_TX_EN_REG,
440 4, 1, 0),
441 SOC_SINGLE("RX1 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG,
442 5, 1, 0),
443 SOC_SINGLE("RX2 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG,
444 4, 1, 0),
445 SOC_SINGLE("RX3 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG,
446 3, 1, 0),
447 SOC_SINGLE("RX4 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG,
448 2, 1, 0),
449 SOC_SINGLE("RX5 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG,
450 1, 1, 0),
451 SOC_SINGLE("RX6 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG,
452 0, 1, 0),
453
454 SOC_SINGLE("ULATX12 Capture Switch", ISABELLE_ULATX12_INTF_CFG_REG,
455 7, 1, 0),
456
457 SOC_SINGLE("DL12 Playback Switch", ISABELLE_DL12_INTF_CFG_REG,
458 7, 1, 0),
459 SOC_SINGLE("DL34 Playback Switch", ISABELLE_DL34_INTF_CFG_REG,
460 7, 1, 0),
461 SOC_SINGLE("DL56 Playback Switch", ISABELLE_DL56_INTF_CFG_REG,
462 7, 1, 0),
463
464 /* DMIC Switch */
465 SOC_SINGLE("DMIC Switch", ISABELLE_DMIC_CFG_REG, 0, 1, 0),
466};
467
468static const struct snd_soc_dapm_widget isabelle_dapm_widgets[] = {
469 /* Inputs */
470 SND_SOC_DAPM_INPUT("MAINMIC"),
471 SND_SOC_DAPM_INPUT("HSMIC"),
472 SND_SOC_DAPM_INPUT("SUBMIC"),
473 SND_SOC_DAPM_INPUT("LINEIN1"),
474 SND_SOC_DAPM_INPUT("LINEIN2"),
475 SND_SOC_DAPM_INPUT("DMICDAT"),
476
477 /* Outputs */
478 SND_SOC_DAPM_OUTPUT("HSOL"),
479 SND_SOC_DAPM_OUTPUT("HSOR"),
480 SND_SOC_DAPM_OUTPUT("HFL"),
481 SND_SOC_DAPM_OUTPUT("HFR"),
482 SND_SOC_DAPM_OUTPUT("EP"),
483 SND_SOC_DAPM_OUTPUT("LINEOUT1"),
484 SND_SOC_DAPM_OUTPUT("LINEOUT2"),
485
486 SND_SOC_DAPM_PGA("DL1", SND_SOC_NOPM, 0, 0, NULL, 0),
487 SND_SOC_DAPM_PGA("DL2", SND_SOC_NOPM, 0, 0, NULL, 0),
488 SND_SOC_DAPM_PGA("DL3", SND_SOC_NOPM, 0, 0, NULL, 0),
489 SND_SOC_DAPM_PGA("DL4", SND_SOC_NOPM, 0, 0, NULL, 0),
490 SND_SOC_DAPM_PGA("DL5", SND_SOC_NOPM, 0, 0, NULL, 0),
491 SND_SOC_DAPM_PGA("DL6", SND_SOC_NOPM, 0, 0, NULL, 0),
492
493 /* Analog input muxes for the capture amplifiers */
494 SND_SOC_DAPM_MUX("Analog Left Capture Route",
495 SND_SOC_NOPM, 0, 0, &amic1_control),
496 SND_SOC_DAPM_MUX("Analog Right Capture Route",
497 SND_SOC_NOPM, 0, 0, &amic2_control),
498
499 SND_SOC_DAPM_MUX("Sidetone Audio Playback", SND_SOC_NOPM, 0, 0,
500 &st_audio_control),
501 SND_SOC_DAPM_MUX("Sidetone Voice Playback", SND_SOC_NOPM, 0, 0,
502 &st_voice_control),
503
504 /* AIF */
505 SND_SOC_DAPM_AIF_IN("INTF1_SDI", NULL, 0, ISABELLE_INTF_EN_REG, 7, 0),
506 SND_SOC_DAPM_AIF_IN("INTF2_SDI", NULL, 0, ISABELLE_INTF_EN_REG, 6, 0),
507
508 SND_SOC_DAPM_AIF_OUT("INTF1_SDO", NULL, 0, ISABELLE_INTF_EN_REG, 5, 0),
509 SND_SOC_DAPM_AIF_OUT("INTF2_SDO", NULL, 0, ISABELLE_INTF_EN_REG, 4, 0),
510
511 SND_SOC_DAPM_OUT_DRV("ULATX1", SND_SOC_NOPM, 0, 0, NULL, 0),
512 SND_SOC_DAPM_OUT_DRV("ULATX2", SND_SOC_NOPM, 0, 0, NULL, 0),
513 SND_SOC_DAPM_OUT_DRV("ULVTX1", SND_SOC_NOPM, 0, 0, NULL, 0),
514 SND_SOC_DAPM_OUT_DRV("ULVTX2", SND_SOC_NOPM, 0, 0, NULL, 0),
515
516 /* Analog Capture PGAs */
517 SND_SOC_DAPM_PGA("MicAmp1", ISABELLE_AMIC_CFG_REG, 5, 0, NULL, 0),
518 SND_SOC_DAPM_PGA("MicAmp2", ISABELLE_AMIC_CFG_REG, 4, 0, NULL, 0),
519
520 /* Auxiliary FM PGAs */
521 SND_SOC_DAPM_PGA("APGA1", ISABELLE_APGA_CFG_REG, 7, 0, NULL, 0),
522 SND_SOC_DAPM_PGA("APGA2", ISABELLE_APGA_CFG_REG, 6, 0, NULL, 0),
523
524 /* ADCs */
525 SND_SOC_DAPM_ADC("ADC1", "Left Front Capture",
526 ISABELLE_AMIC_CFG_REG, 7, 0),
527 SND_SOC_DAPM_ADC("ADC2", "Right Front Capture",
528 ISABELLE_AMIC_CFG_REG, 6, 0),
529
530 /* Microphone Bias */
531 SND_SOC_DAPM_SUPPLY("Headset Mic Bias", ISABELLE_ABIAS_CFG_REG,
532 3, 0, NULL, 0),
533 SND_SOC_DAPM_SUPPLY("Main Mic Bias", ISABELLE_ABIAS_CFG_REG,
534 2, 0, NULL, 0),
535 SND_SOC_DAPM_SUPPLY("Digital Mic1 Bias",
536 ISABELLE_DBIAS_CFG_REG, 3, 0, NULL, 0),
537 SND_SOC_DAPM_SUPPLY("Digital Mic2 Bias",
538 ISABELLE_DBIAS_CFG_REG, 2, 0, NULL, 0),
539
540 /* Mixers */
541 SND_SOC_DAPM_MIXER("Headset Left Mixer", SND_SOC_NOPM, 0, 0,
542 isabelle_hs_left_mixer_controls,
543 ARRAY_SIZE(isabelle_hs_left_mixer_controls)),
544 SND_SOC_DAPM_MIXER("Headset Right Mixer", SND_SOC_NOPM, 0, 0,
545 isabelle_hs_right_mixer_controls,
546 ARRAY_SIZE(isabelle_hs_right_mixer_controls)),
547 SND_SOC_DAPM_MIXER("Handsfree Left Mixer", SND_SOC_NOPM, 0, 0,
548 isabelle_hf_left_mixer_controls,
549 ARRAY_SIZE(isabelle_hf_left_mixer_controls)),
550 SND_SOC_DAPM_MIXER("Handsfree Right Mixer", SND_SOC_NOPM, 0, 0,
551 isabelle_hf_right_mixer_controls,
552 ARRAY_SIZE(isabelle_hf_right_mixer_controls)),
553 SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0,
554 isabelle_aux_left_mixer_controls,
555 ARRAY_SIZE(isabelle_aux_left_mixer_controls)),
556 SND_SOC_DAPM_MIXER("LINEOUT2 Mixer", SND_SOC_NOPM, 0, 0,
557 isabelle_aux_right_mixer_controls,
558 ARRAY_SIZE(isabelle_aux_right_mixer_controls)),
559 SND_SOC_DAPM_MIXER("Earphone Mixer", SND_SOC_NOPM, 0, 0,
560 isabelle_ep_mixer_controls,
561 ARRAY_SIZE(isabelle_ep_mixer_controls)),
562
563 SND_SOC_DAPM_MIXER("DPGA1L Mixer", SND_SOC_NOPM, 0, 0,
564 isabelle_dpga1_left_mixer_controls,
565 ARRAY_SIZE(isabelle_dpga1_left_mixer_controls)),
566 SND_SOC_DAPM_MIXER("DPGA1R Mixer", SND_SOC_NOPM, 0, 0,
567 isabelle_dpga1_right_mixer_controls,
568 ARRAY_SIZE(isabelle_dpga1_right_mixer_controls)),
569 SND_SOC_DAPM_MIXER("DPGA2L Mixer", SND_SOC_NOPM, 0, 0,
570 isabelle_dpga2_left_mixer_controls,
571 ARRAY_SIZE(isabelle_dpga2_left_mixer_controls)),
572 SND_SOC_DAPM_MIXER("DPGA2R Mixer", SND_SOC_NOPM, 0, 0,
573 isabelle_dpga2_right_mixer_controls,
574 ARRAY_SIZE(isabelle_dpga2_right_mixer_controls)),
575 SND_SOC_DAPM_MIXER("DPGA3L Mixer", SND_SOC_NOPM, 0, 0,
576 isabelle_dpga3_left_mixer_controls,
577 ARRAY_SIZE(isabelle_dpga3_left_mixer_controls)),
578 SND_SOC_DAPM_MIXER("DPGA3R Mixer", SND_SOC_NOPM, 0, 0,
579 isabelle_dpga3_right_mixer_controls,
580 ARRAY_SIZE(isabelle_dpga3_right_mixer_controls)),
581
582 SND_SOC_DAPM_MIXER("RX1 Mixer", SND_SOC_NOPM, 0, 0,
583 isabelle_rx1_mixer_controls,
584 ARRAY_SIZE(isabelle_rx1_mixer_controls)),
585 SND_SOC_DAPM_MIXER("RX2 Mixer", SND_SOC_NOPM, 0, 0,
586 isabelle_rx2_mixer_controls,
587 ARRAY_SIZE(isabelle_rx2_mixer_controls)),
588 SND_SOC_DAPM_MIXER("RX3 Mixer", SND_SOC_NOPM, 0, 0,
589 isabelle_rx3_mixer_controls,
590 ARRAY_SIZE(isabelle_rx3_mixer_controls)),
591 SND_SOC_DAPM_MIXER("RX4 Mixer", SND_SOC_NOPM, 0, 0,
592 isabelle_rx4_mixer_controls,
593 ARRAY_SIZE(isabelle_rx4_mixer_controls)),
594 SND_SOC_DAPM_MIXER("RX5 Mixer", SND_SOC_NOPM, 0, 0,
595 isabelle_rx5_mixer_controls,
596 ARRAY_SIZE(isabelle_rx5_mixer_controls)),
597 SND_SOC_DAPM_MIXER("RX6 Mixer", SND_SOC_NOPM, 0, 0,
598 isabelle_rx6_mixer_controls,
599 ARRAY_SIZE(isabelle_rx6_mixer_controls)),
600
601 /* DACs */
602 SND_SOC_DAPM_DAC("DAC1L", "Headset Playback", ISABELLE_DAC_CFG_REG,
603 5, 0),
604 SND_SOC_DAPM_DAC("DAC1R", "Headset Playback", ISABELLE_DAC_CFG_REG,
605 4, 0),
606 SND_SOC_DAPM_DAC("DAC2L", "Handsfree Playback", ISABELLE_DAC_CFG_REG,
607 3, 0),
608 SND_SOC_DAPM_DAC("DAC2R", "Handsfree Playback", ISABELLE_DAC_CFG_REG,
609 2, 0),
610 SND_SOC_DAPM_DAC("DAC3L", "Lineout Playback", ISABELLE_DAC_CFG_REG,
611 1, 0),
612 SND_SOC_DAPM_DAC("DAC3R", "Lineout Playback", ISABELLE_DAC_CFG_REG,
613 0, 0),
614
615 /* Analog Playback PGAs */
616 SND_SOC_DAPM_PGA("Sidetone Audio PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
617 SND_SOC_DAPM_PGA("Sidetone Voice PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
618 SND_SOC_DAPM_PGA("HF Left PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
619 SND_SOC_DAPM_PGA("HF Right PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
620 SND_SOC_DAPM_PGA("DPGA1L", SND_SOC_NOPM, 0, 0, NULL, 0),
621 SND_SOC_DAPM_PGA("DPGA1R", SND_SOC_NOPM, 0, 0, NULL, 0),
622 SND_SOC_DAPM_PGA("DPGA2L", SND_SOC_NOPM, 0, 0, NULL, 0),
623 SND_SOC_DAPM_PGA("DPGA2R", SND_SOC_NOPM, 0, 0, NULL, 0),
624 SND_SOC_DAPM_PGA("DPGA3L", SND_SOC_NOPM, 0, 0, NULL, 0),
625 SND_SOC_DAPM_PGA("DPGA3R", SND_SOC_NOPM, 0, 0, NULL, 0),
626
627 /* Analog Playback Mux */
628 SND_SOC_DAPM_MUX("RX1 Playback", ISABELLE_ALU_RX_EN_REG, 5, 0,
629 &rx1_mux_controls),
630 SND_SOC_DAPM_MUX("RX2 Playback", ISABELLE_ALU_RX_EN_REG, 4, 0,
631 &rx2_mux_controls),
632
633 /* TX Select */
634 SND_SOC_DAPM_MUX("ATX Select", ISABELLE_TX_INPUT_CFG_REG,
635 7, 0, &atx_mux_controls),
636 SND_SOC_DAPM_MUX("VTX Select", ISABELLE_TX_INPUT_CFG_REG,
637 6, 0, &vtx_mux_controls),
638
639 SND_SOC_DAPM_SWITCH("Earphone Playback", SND_SOC_NOPM, 0, 0,
640 &ep_path_enable_control),
641
642 /* Output Drivers */
643 SND_SOC_DAPM_OUT_DRV("HS Left Driver", ISABELLE_HSDRV_CFG2_REG,
644 1, 0, NULL, 0),
645 SND_SOC_DAPM_OUT_DRV("HS Right Driver", ISABELLE_HSDRV_CFG2_REG,
646 0, 0, NULL, 0),
647 SND_SOC_DAPM_OUT_DRV("LINEOUT1 Left Driver", ISABELLE_LINEAMP_CFG_REG,
648 1, 0, NULL, 0),
649 SND_SOC_DAPM_OUT_DRV("LINEOUT2 Right Driver", ISABELLE_LINEAMP_CFG_REG,
650 0, 0, NULL, 0),
651 SND_SOC_DAPM_OUT_DRV("Earphone Driver", ISABELLE_EARDRV_CFG2_REG,
652 1, 0, NULL, 0),
653
654 SND_SOC_DAPM_OUT_DRV("HF Left Driver", ISABELLE_HFDRV_CFG_REG,
655 1, 0, NULL, 0),
656 SND_SOC_DAPM_OUT_DRV("HF Right Driver", ISABELLE_HFDRV_CFG_REG,
657 0, 0, NULL, 0),
658};
659
660static const struct snd_soc_dapm_route isabelle_intercon[] = {
661 /* Interface mapping */
662 { "DL1", "DL12 Playback Switch", "INTF1_SDI" },
663 { "DL2", "DL12 Playback Switch", "INTF1_SDI" },
664 { "DL3", "DL34 Playback Switch", "INTF1_SDI" },
665 { "DL4", "DL34 Playback Switch", "INTF1_SDI" },
666 { "DL5", "DL56 Playback Switch", "INTF1_SDI" },
667 { "DL6", "DL56 Playback Switch", "INTF1_SDI" },
668
669 { "DL1", "DL12 Playback Switch", "INTF2_SDI" },
670 { "DL2", "DL12 Playback Switch", "INTF2_SDI" },
671 { "DL3", "DL34 Playback Switch", "INTF2_SDI" },
672 { "DL4", "DL34 Playback Switch", "INTF2_SDI" },
673 { "DL5", "DL56 Playback Switch", "INTF2_SDI" },
674 { "DL6", "DL56 Playback Switch", "INTF2_SDI" },
675
676 /* Input side mapping */
677 { "Sidetone Audio PGA", NULL, "Sidetone Audio Playback" },
678 { "Sidetone Voice PGA", NULL, "Sidetone Voice Playback" },
679
680 { "RX1 Mixer", "ST1 Playback Switch", "Sidetone Audio PGA" },
681
682 { "RX1 Mixer", "ST1 Playback Switch", "Sidetone Voice PGA" },
683 { "RX1 Mixer", "DL1 Playback Switch", "DL1" },
684
685 { "RX2 Mixer", "ST2 Playback Switch", "Sidetone Audio PGA" },
686
687 { "RX2 Mixer", "ST2 Playback Switch", "Sidetone Voice PGA" },
688 { "RX2 Mixer", "DL2 Playback Switch", "DL2" },
689
690 { "RX3 Mixer", "ST1 Playback Switch", "Sidetone Voice PGA" },
691 { "RX3 Mixer", "DL3 Playback Switch", "DL3" },
692
693 { "RX4 Mixer", "ST2 Playback Switch", "Sidetone Voice PGA" },
694 { "RX4 Mixer", "DL4 Playback Switch", "DL4" },
695
696 { "RX5 Mixer", "ST1 Playback Switch", "Sidetone Voice PGA" },
697 { "RX5 Mixer", "DL5 Playback Switch", "DL5" },
698
699 { "RX6 Mixer", "ST2 Playback Switch", "Sidetone Voice PGA" },
700 { "RX6 Mixer", "DL6 Playback Switch", "DL6" },
701
702 /* Capture path */
703 { "Analog Left Capture Route", "Headset Mic", "HSMIC" },
704 { "Analog Left Capture Route", "Main Mic", "MAINMIC" },
705 { "Analog Left Capture Route", "Aux/FM Left", "LINEIN1" },
706
707 { "Analog Right Capture Route", "Sub Mic", "SUBMIC" },
708 { "Analog Right Capture Route", "Aux/FM Right", "LINEIN2" },
709
710 { "MicAmp1", NULL, "Analog Left Capture Route" },
711 { "MicAmp2", NULL, "Analog Right Capture Route" },
712
713 { "ADC1", NULL, "MicAmp1" },
714 { "ADC2", NULL, "MicAmp2" },
715
716 { "ATX Select", "AMIC1", "ADC1" },
717 { "ATX Select", "DMIC", "DMICDAT" },
718 { "ATX Select", "AMIC2", "ADC2" },
719
720 { "VTX Select", "AMIC1", "ADC1" },
721 { "VTX Select", "DMIC", "DMICDAT" },
722 { "VTX Select", "AMIC2", "ADC2" },
723
724 { "ULATX1", "ATX1 Filter Enable Switch", "ATX Select" },
725 { "ULATX1", "ATX1 Filter Bypass Switch", "ATX Select" },
726 { "ULATX2", "ATX2 Filter Enable Switch", "ATX Select" },
727 { "ULATX2", "ATX2 Filter Bypass Switch", "ATX Select" },
728
729 { "ULVTX1", "VTX1 Filter Enable Switch", "VTX Select" },
730 { "ULVTX1", "VTX1 Filter Bypass Switch", "VTX Select" },
731 { "ULVTX2", "VTX2 Filter Enable Switch", "VTX Select" },
732 { "ULVTX2", "VTX2 Filter Bypass Switch", "VTX Select" },
733
734 { "INTF1_SDO", "ULATX12 Capture Switch", "ULATX1" },
735 { "INTF1_SDO", "ULATX12 Capture Switch", "ULATX2" },
736 { "INTF2_SDO", "ULATX12 Capture Switch", "ULATX1" },
737 { "INTF2_SDO", "ULATX12 Capture Switch", "ULATX2" },
738
739 { "INTF1_SDO", NULL, "ULVTX1" },
740 { "INTF1_SDO", NULL, "ULVTX2" },
741 { "INTF2_SDO", NULL, "ULVTX1" },
742 { "INTF2_SDO", NULL, "ULVTX2" },
743
744 /* AFM Path */
745 { "APGA1", NULL, "LINEIN1" },
746 { "APGA2", NULL, "LINEIN2" },
747
748 { "RX1 Playback", "VRX1 Filter Bypass Switch", "RX1 Mixer" },
749 { "RX1 Playback", "ARX1 Filter Bypass Switch", "RX1 Mixer" },
750 { "RX1 Playback", "RX1 Filter Enable Switch", "RX1 Mixer" },
751
752 { "RX2 Playback", "VRX2 Filter Bypass Switch", "RX2 Mixer" },
753 { "RX2 Playback", "ARX2 Filter Bypass Switch", "RX2 Mixer" },
754 { "RX2 Playback", "RX2 Filter Enable Switch", "RX2 Mixer" },
755
756 { "RX3 Playback", "ARX3 Filter Bypass Switch", "RX3 Mixer" },
757 { "RX3 Playback", "RX3 Filter Enable Switch", "RX3 Mixer" },
758
759 { "RX4 Playback", "ARX4 Filter Bypass Switch", "RX4 Mixer" },
760 { "RX4 Playback", "RX4 Filter Enable Switch", "RX4 Mixer" },
761
762 { "RX5 Playback", "ARX5 Filter Bypass Switch", "RX5 Mixer" },
763 { "RX5 Playback", "RX5 Filter Enable Switch", "RX5 Mixer" },
764
765 { "RX6 Playback", "ARX6 Filter Bypass Switch", "RX6 Mixer" },
766 { "RX6 Playback", "RX6 Filter Enable Switch", "RX6 Mixer" },
767
768 { "DPGA1L Mixer", "RX1 Playback Switch", "RX1 Playback" },
769 { "DPGA1L Mixer", "RX3 Playback Switch", "RX3 Playback" },
770 { "DPGA1L Mixer", "RX5 Playback Switch", "RX5 Playback" },
771
772 { "DPGA1R Mixer", "RX2 Playback Switch", "RX2 Playback" },
773 { "DPGA1R Mixer", "RX4 Playback Switch", "RX4 Playback" },
774 { "DPGA1R Mixer", "RX6 Playback Switch", "RX6 Playback" },
775
776 { "DPGA1L", NULL, "DPGA1L Mixer" },
777 { "DPGA1R", NULL, "DPGA1R Mixer" },
778
779 { "DAC1L", NULL, "DPGA1L" },
780 { "DAC1R", NULL, "DPGA1R" },
781
782 { "DPGA2L Mixer", "RX1 Playback Switch", "RX1 Playback" },
783 { "DPGA2L Mixer", "RX2 Playback Switch", "RX2 Playback" },
784 { "DPGA2L Mixer", "RX3 Playback Switch", "RX3 Playback" },
785 { "DPGA2L Mixer", "RX4 Playback Switch", "RX4 Playback" },
786 { "DPGA2L Mixer", "RX5 Playback Switch", "RX5 Playback" },
787 { "DPGA2L Mixer", "RX6 Playback Switch", "RX6 Playback" },
788
789 { "DPGA2R Mixer", "RX2 Playback Switch", "RX2 Playback" },
790 { "DPGA2R Mixer", "RX4 Playback Switch", "RX4 Playback" },
791 { "DPGA2R Mixer", "RX6 Playback Switch", "RX6 Playback" },
792
793 { "DPGA2L", NULL, "DPGA2L Mixer" },
794 { "DPGA2R", NULL, "DPGA2R Mixer" },
795
796 { "DAC2L", NULL, "DPGA2L" },
797 { "DAC2R", NULL, "DPGA2R" },
798
799 { "DPGA3L Mixer", "RX1 Playback Switch", "RX1 Playback" },
800 { "DPGA3L Mixer", "RX3 Playback Switch", "RX3 Playback" },
801 { "DPGA3L Mixer", "RX5 Playback Switch", "RX5 Playback" },
802
803 { "DPGA3R Mixer", "RX2 Playback Switch", "RX2 Playback" },
804 { "DPGA3R Mixer", "RX4 Playback Switch", "RX4 Playback" },
805 { "DPGA3R Mixer", "RX6 Playback Switch", "RX6 Playback" },
806
807 { "DPGA3L", NULL, "DPGA3L Mixer" },
808 { "DPGA3R", NULL, "DPGA3R Mixer" },
809
810 { "DAC3L", NULL, "DPGA3L" },
811 { "DAC3R", NULL, "DPGA3R" },
812
813 { "Headset Left Mixer", "DAC1L Playback Switch", "DAC1L" },
814 { "Headset Left Mixer", "APGA1 Playback Switch", "APGA1" },
815
816 { "Headset Right Mixer", "DAC1R Playback Switch", "DAC1R" },
817 { "Headset Right Mixer", "APGA2 Playback Switch", "APGA2" },
818
819 { "HS Left Driver", NULL, "Headset Left Mixer" },
820 { "HS Right Driver", NULL, "Headset Right Mixer" },
821
822 { "HSOL", NULL, "HS Left Driver" },
823 { "HSOR", NULL, "HS Right Driver" },
824
825 /* Earphone playback path */
826 { "Earphone Mixer", "DAC2L Playback Switch", "DAC2L" },
827 { "Earphone Mixer", "APGA1 Playback Switch", "APGA1" },
828
829 { "Earphone Playback", "Switch", "Earphone Mixer" },
830 { "Earphone Driver", NULL, "Earphone Playback" },
831 { "EP", NULL, "Earphone Driver" },
832
833 { "Handsfree Left Mixer", "DAC2L Playback Switch", "DAC2L" },
834 { "Handsfree Left Mixer", "APGA1 Playback Switch", "APGA1" },
835
836 { "Handsfree Right Mixer", "DAC2R Playback Switch", "DAC2R" },
837 { "Handsfree Right Mixer", "APGA2 Playback Switch", "APGA2" },
838
839 { "HF Left PGA", NULL, "Handsfree Left Mixer" },
840 { "HF Right PGA", NULL, "Handsfree Right Mixer" },
841
842 { "HF Left Driver", NULL, "HF Left PGA" },
843 { "HF Right Driver", NULL, "HF Right PGA" },
844
845 { "HFL", NULL, "HF Left Driver" },
846 { "HFR", NULL, "HF Right Driver" },
847
848 { "LINEOUT1 Mixer", "DAC3L Playback Switch", "DAC3L" },
849 { "LINEOUT1 Mixer", "APGA1 Playback Switch", "APGA1" },
850
851 { "LINEOUT2 Mixer", "DAC3R Playback Switch", "DAC3R" },
852 { "LINEOUT2 Mixer", "APGA2 Playback Switch", "APGA2" },
853
854 { "LINEOUT1 Driver", NULL, "LINEOUT1 Mixer" },
855 { "LINEOUT2 Driver", NULL, "LINEOUT2 Mixer" },
856
857 { "LINEOUT1", NULL, "LINEOUT1 Driver" },
858 { "LINEOUT2", NULL, "LINEOUT2 Driver" },
859};
860
861static int isabelle_hs_mute(struct snd_soc_dai *dai, int mute)
862{
863 snd_soc_update_bits(dai->codec, ISABELLE_DAC1_SOFTRAMP_REG,
864 BIT(4), (mute ? BIT(4) : 0));
865
866 return 0;
867}
868
869static int isabelle_hf_mute(struct snd_soc_dai *dai, int mute)
870{
871 snd_soc_update_bits(dai->codec, ISABELLE_DAC2_SOFTRAMP_REG,
872 BIT(4), (mute ? BIT(4) : 0));
873
874 return 0;
875}
876
877static int isabelle_line_mute(struct snd_soc_dai *dai, int mute)
878{
879 snd_soc_update_bits(dai->codec, ISABELLE_DAC3_SOFTRAMP_REG,
880 BIT(4), (mute ? BIT(4) : 0));
881
882 return 0;
883}
884
885static int isabelle_set_bias_level(struct snd_soc_codec *codec,
886 enum snd_soc_bias_level level)
887{
888 switch (level) {
889 case SND_SOC_BIAS_ON:
890 break;
891 case SND_SOC_BIAS_PREPARE:
892 break;
893
894 case SND_SOC_BIAS_STANDBY:
895 snd_soc_update_bits(codec, ISABELLE_PWR_EN_REG,
896 ISABELLE_CHIP_EN, BIT(0));
897 break;
898
899 case SND_SOC_BIAS_OFF:
900 snd_soc_update_bits(codec, ISABELLE_PWR_EN_REG,
901 ISABELLE_CHIP_EN, 0);
902 break;
903 }
904
905 codec->dapm.bias_level = level;
906
907 return 0;
908}
909
910static int isabelle_hw_params(struct snd_pcm_substream *substream,
911 struct snd_pcm_hw_params *params,
912 struct snd_soc_dai *dai)
913{
914 struct snd_soc_pcm_runtime *rtd = substream->private_data;
915 struct snd_soc_codec *codec = rtd->codec;
916 u16 aif = 0;
917 unsigned int fs_val = 0;
918
919 switch (params_rate(params)) {
920 case 8000:
921 fs_val = ISABELLE_FS_RATE_8;
922 break;
923 case 11025:
924 fs_val = ISABELLE_FS_RATE_11;
925 break;
926 case 12000:
927 fs_val = ISABELLE_FS_RATE_12;
928 break;
929 case 16000:
930 fs_val = ISABELLE_FS_RATE_16;
931 break;
932 case 22050:
933 fs_val = ISABELLE_FS_RATE_22;
934 break;
935 case 24000:
936 fs_val = ISABELLE_FS_RATE_24;
937 break;
938 case 32000:
939 fs_val = ISABELLE_FS_RATE_32;
940 break;
941 case 44100:
942 fs_val = ISABELLE_FS_RATE_44;
943 break;
944 case 48000:
945 fs_val = ISABELLE_FS_RATE_48;
946 break;
947 default:
948 return -EINVAL;
949 }
950
951 snd_soc_update_bits(codec, ISABELLE_FS_RATE_CFG_REG,
952 ISABELLE_FS_RATE_MASK, fs_val);
953
954 /* bit size */
955 switch (params_format(params)) {
956 case SNDRV_PCM_FORMAT_S20_3LE:
957 aif |= ISABELLE_AIF_LENGTH_20;
958 break;
959 case SNDRV_PCM_FORMAT_S32_LE:
960 aif |= ISABELLE_AIF_LENGTH_32;
961 break;
962 default:
963 return -EINVAL;
964 }
965
966 snd_soc_update_bits(codec, ISABELLE_INTF_CFG_REG,
967 ISABELLE_AIF_LENGTH_MASK, aif);
968
969 return 0;
970}
971
972static int isabelle_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
973{
974 struct snd_soc_codec *codec = codec_dai->codec;
975 unsigned int aif_val = 0;
976
977 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
978 case SND_SOC_DAIFMT_CBS_CFS:
979 aif_val &= ~ISABELLE_AIF_MS;
980 break;
981 case SND_SOC_DAIFMT_CBM_CFM:
982 aif_val |= ISABELLE_AIF_MS;
983 break;
984 default:
985 return -EINVAL;
986 }
987
988 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
989 case SND_SOC_DAIFMT_I2S:
990 aif_val |= ISABELLE_I2S_MODE;
991 break;
992 case SND_SOC_DAIFMT_LEFT_J:
993 aif_val |= ISABELLE_LEFT_J_MODE;
994 break;
995 case SND_SOC_DAIFMT_PDM:
996 aif_val |= ISABELLE_PDM_MODE;
997 break;
998 default:
999 return -EINVAL;
1000 }
1001
1002 snd_soc_update_bits(codec, ISABELLE_INTF_CFG_REG,
1003 (ISABELLE_AIF_MS | ISABELLE_AIF_FMT_MASK), aif_val);
1004
1005 return 0;
1006}
1007
1008/* Rates supported by Isabelle driver */
1009#define ISABELLE_RATES SNDRV_PCM_RATE_8000_48000
1010
1011/* Formates supported by Isabelle driver. */
1012#define ISABELLE_FORMATS (SNDRV_PCM_FMTBIT_S20_3LE |\
1013 SNDRV_PCM_FMTBIT_S32_LE)
1014
1015static struct snd_soc_dai_ops isabelle_hs_dai_ops = {
1016 .hw_params = isabelle_hw_params,
1017 .set_fmt = isabelle_set_dai_fmt,
1018 .digital_mute = isabelle_hs_mute,
1019};
1020
1021static struct snd_soc_dai_ops isabelle_hf_dai_ops = {
1022 .hw_params = isabelle_hw_params,
1023 .set_fmt = isabelle_set_dai_fmt,
1024 .digital_mute = isabelle_hf_mute,
1025};
1026
1027static struct snd_soc_dai_ops isabelle_line_dai_ops = {
1028 .hw_params = isabelle_hw_params,
1029 .set_fmt = isabelle_set_dai_fmt,
1030 .digital_mute = isabelle_line_mute,
1031};
1032
1033static struct snd_soc_dai_ops isabelle_ul_dai_ops = {
1034 .hw_params = isabelle_hw_params,
1035 .set_fmt = isabelle_set_dai_fmt,
1036};
1037
1038/* ISABELLE dai structure */
1039static struct snd_soc_dai_driver isabelle_dai[] = {
1040 {
1041 .name = "isabelle-dl1",
1042 .playback = {
1043 .stream_name = "Headset Playback",
1044 .channels_min = 1,
1045 .channels_max = 2,
1046 .rates = ISABELLE_RATES,
1047 .formats = ISABELLE_FORMATS,
1048 },
1049 .ops = &isabelle_hs_dai_ops,
1050 },
1051 {
1052 .name = "isabelle-dl2",
1053 .playback = {
1054 .stream_name = "Handsfree Playback",
1055 .channels_min = 1,
1056 .channels_max = 2,
1057 .rates = ISABELLE_RATES,
1058 .formats = ISABELLE_FORMATS,
1059 },
1060 .ops = &isabelle_hf_dai_ops,
1061 },
1062 {
1063 .name = "isabelle-lineout",
1064 .playback = {
1065 .stream_name = "Lineout Playback",
1066 .channels_min = 1,
1067 .channels_max = 2,
1068 .rates = ISABELLE_RATES,
1069 .formats = ISABELLE_FORMATS,
1070 },
1071 .ops = &isabelle_line_dai_ops,
1072 },
1073 {
1074 .name = "isabelle-ul",
1075 .capture = {
1076 .stream_name = "Capture",
1077 .channels_min = 1,
1078 .channels_max = 2,
1079 .rates = ISABELLE_RATES,
1080 .formats = ISABELLE_FORMATS,
1081 },
1082 .ops = &isabelle_ul_dai_ops,
1083 },
1084};
1085
1086static int isabelle_probe(struct snd_soc_codec *codec)
1087{
1088 int ret = 0;
1089
1090 codec->control_data = dev_get_regmap(codec->dev, NULL);
1091
1092 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
1093 if (ret < 0) {
1094 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1095 return ret;
1096 }
1097
1098 return 0;
1099}
1100
1101static struct snd_soc_codec_driver soc_codec_dev_isabelle = {
1102 .probe = isabelle_probe,
1103 .set_bias_level = isabelle_set_bias_level,
1104 .controls = isabelle_snd_controls,
1105 .num_controls = ARRAY_SIZE(isabelle_snd_controls),
1106 .dapm_widgets = isabelle_dapm_widgets,
1107 .num_dapm_widgets = ARRAY_SIZE(isabelle_dapm_widgets),
1108 .dapm_routes = isabelle_intercon,
1109 .num_dapm_routes = ARRAY_SIZE(isabelle_intercon),
1110 .idle_bias_off = true,
1111};
1112
1113static const struct regmap_config isabelle_regmap_config = {
1114 .reg_bits = 8,
1115 .val_bits = 8,
1116
1117 .max_register = ISABELLE_MAX_REGISTER,
1118 .reg_defaults = isabelle_reg_defs,
1119 .num_reg_defaults = ARRAY_SIZE(isabelle_reg_defs),
1120 .cache_type = REGCACHE_RBTREE,
1121};
1122
1123static int __devinit isabelle_i2c_probe(struct i2c_client *i2c,
1124 const struct i2c_device_id *id)
1125{
1126 struct regmap *isabelle_regmap;
1127 int ret = 0;
1128
1129 isabelle_regmap = devm_regmap_init_i2c(i2c, &isabelle_regmap_config);
1130 if (IS_ERR(isabelle_regmap)) {
1131 ret = PTR_ERR(isabelle_regmap);
1132 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
1133 ret);
1134 return ret;
1135 }
1136 i2c_set_clientdata(i2c, isabelle_regmap);
1137
1138 ret = snd_soc_register_codec(&i2c->dev,
1139 &soc_codec_dev_isabelle, isabelle_dai,
1140 ARRAY_SIZE(isabelle_dai));
1141 if (ret < 0) {
1142 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1143 return ret;
1144 }
1145
1146 return ret;
1147}
1148
1149static int __devexit isabelle_i2c_remove(struct i2c_client *client)
1150{
1151 snd_soc_unregister_codec(&client->dev);
1152 return 0;
1153}
1154
1155static const struct i2c_device_id isabelle_i2c_id[] = {
1156 { "isabelle", 0 },
1157 { }
1158};
1159MODULE_DEVICE_TABLE(i2c, isabelle_i2c_id);
1160
1161static struct i2c_driver isabelle_i2c_driver = {
1162 .driver = {
1163 .name = "isabelle",
1164 .owner = THIS_MODULE,
1165 },
1166 .probe = isabelle_i2c_probe,
1167 .remove = __devexit_p(isabelle_i2c_remove),
1168 .id_table = isabelle_i2c_id,
1169};
1170
1171module_i2c_driver(isabelle_i2c_driver);
1172
1173MODULE_DESCRIPTION("ASoC ISABELLE driver");
1174MODULE_AUTHOR("Vishwas A Deshpande <vishwas.a.deshpande@ti.com>");
1175MODULE_AUTHOR("M R Swami Reddy <MR.Swami.Reddy@ti.com>");
1176MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/isabelle.h b/sound/soc/codecs/isabelle.h
new file mode 100644
index 000000000000..96d839a8c956
--- /dev/null
+++ b/sound/soc/codecs/isabelle.h
@@ -0,0 +1,143 @@
1/*
2 * isabelle.h - Low power high fidelity audio codec driver header file
3 *
4 * Copyright (c) 2012 Texas Instruments, Inc
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 */
11
12#ifndef _ISABELLE_H
13#define _ISABELLE_H
14
15#include <linux/bitops.h>
16
17/* ISABELLE REGISTERS */
18
19#define ISABELLE_PWR_CFG_REG 0x01
20#define ISABELLE_PWR_EN_REG 0x02
21#define ISABELLE_PS_EN1_REG 0x03
22#define ISABELLE_INT1_STATUS_REG 0x04
23#define ISABELLE_INT1_MASK_REG 0x05
24#define ISABELLE_INT2_STATUS_REG 0x06
25#define ISABELLE_INT2_MASK_REG 0x07
26#define ISABELLE_HKCTL1_REG 0x08
27#define ISABELLE_HKCTL2_REG 0x09
28#define ISABELLE_HKCTL3_REG 0x0A
29#define ISABELLE_ACCDET_STATUS_REG 0x0B
30#define ISABELLE_BUTTON_ID_REG 0x0C
31#define ISABELLE_PLL_CFG_REG 0x10
32#define ISABELLE_PLL_EN_REG 0x11
33#define ISABELLE_FS_RATE_CFG_REG 0x12
34#define ISABELLE_INTF_CFG_REG 0x13
35#define ISABELLE_INTF_EN_REG 0x14
36#define ISABELLE_ULATX12_INTF_CFG_REG 0x15
37#define ISABELLE_DL12_INTF_CFG_REG 0x16
38#define ISABELLE_DL34_INTF_CFG_REG 0x17
39#define ISABELLE_DL56_INTF_CFG_REG 0x18
40#define ISABELLE_ATX_STPGA1_CFG_REG 0x19
41#define ISABELLE_ATX_STPGA2_CFG_REG 0x1A
42#define ISABELLE_VTX_STPGA1_CFG_REG 0x1B
43#define ISABELLE_VTX2_STPGA2_CFG_REG 0x1C
44#define ISABELLE_ATX1_DPGA_REG 0x1D
45#define ISABELLE_ATX2_DPGA_REG 0x1E
46#define ISABELLE_VTX1_DPGA_REG 0x1F
47#define ISABELLE_VTX2_DPGA_REG 0x20
48#define ISABELLE_TX_INPUT_CFG_REG 0x21
49#define ISABELLE_RX_INPUT_CFG_REG 0x22
50#define ISABELLE_RX_INPUT_CFG2_REG 0x23
51#define ISABELLE_VOICE_HPF_CFG_REG 0x24
52#define ISABELLE_AUDIO_HPF_CFG_REG 0x25
53#define ISABELLE_RX1_DPGA_REG 0x26
54#define ISABELLE_RX2_DPGA_REG 0x27
55#define ISABELLE_RX3_DPGA_REG 0x28
56#define ISABELLE_RX4_DPGA_REG 0x29
57#define ISABELLE_RX5_DPGA_REG 0x2A
58#define ISABELLE_RX6_DPGA_REG 0x2B
59#define ISABELLE_ALU_TX_EN_REG 0x2C
60#define ISABELLE_ALU_RX_EN_REG 0x2D
61#define ISABELLE_IIR_RESYNC_REG 0x2E
62#define ISABELLE_ABIAS_CFG_REG 0x30
63#define ISABELLE_DBIAS_CFG_REG 0x31
64#define ISABELLE_MIC1_GAIN_REG 0x32
65#define ISABELLE_MIC2_GAIN_REG 0x33
66#define ISABELLE_AMIC_CFG_REG 0x34
67#define ISABELLE_DMIC_CFG_REG 0x35
68#define ISABELLE_APGA_GAIN_REG 0x36
69#define ISABELLE_APGA_CFG_REG 0x37
70#define ISABELLE_TX_GAIN_DLY_REG 0x38
71#define ISABELLE_RX_GAIN_DLY_REG 0x39
72#define ISABELLE_RX_PWR_CTRL_REG 0x3A
73#define ISABELLE_DPGA1LR_IN_SEL_REG 0x3B
74#define ISABELLE_DPGA1L_GAIN_REG 0x3C
75#define ISABELLE_DPGA1R_GAIN_REG 0x3D
76#define ISABELLE_DPGA2L_IN_SEL_REG 0x3E
77#define ISABELLE_DPGA2R_IN_SEL_REG 0x3F
78#define ISABELLE_DPGA2L_GAIN_REG 0x40
79#define ISABELLE_DPGA2R_GAIN_REG 0x41
80#define ISABELLE_DPGA3LR_IN_SEL_REG 0x42
81#define ISABELLE_DPGA3L_GAIN_REG 0x43
82#define ISABELLE_DPGA3R_GAIN_REG 0x44
83#define ISABELLE_DAC1_SOFTRAMP_REG 0x45
84#define ISABELLE_DAC2_SOFTRAMP_REG 0x46
85#define ISABELLE_DAC3_SOFTRAMP_REG 0x47
86#define ISABELLE_DAC_CFG_REG 0x48
87#define ISABELLE_EARDRV_CFG1_REG 0x49
88#define ISABELLE_EARDRV_CFG2_REG 0x4A
89#define ISABELLE_HSDRV_GAIN_REG 0x4B
90#define ISABELLE_HSDRV_CFG1_REG 0x4C
91#define ISABELLE_HSDRV_CFG2_REG 0x4D
92#define ISABELLE_HS_NG_CFG1_REG 0x4E
93#define ISABELLE_HS_NG_CFG2_REG 0x4F
94#define ISABELLE_LINEAMP_GAIN_REG 0x50
95#define ISABELLE_LINEAMP_CFG_REG 0x51
96#define ISABELLE_HFL_VOL_CTRL_REG 0x52
97#define ISABELLE_HFL_SFTVOL_CTRL_REG 0x53
98#define ISABELLE_HFL_LIM_CTRL_1_REG 0x54
99#define ISABELLE_HFL_LIM_CTRL_2_REG 0x55
100#define ISABELLE_HFR_VOL_CTRL_REG 0x56
101#define ISABELLE_HFR_SFTVOL_CTRL_REG 0x57
102#define ISABELLE_HFR_LIM_CTRL_1_REG 0x58
103#define ISABELLE_HFR_LIM_CTRL_2_REG 0x59
104#define ISABELLE_HF_MODE_REG 0x5A
105#define ISABELLE_HFLPGA_CFG_REG 0x5B
106#define ISABELLE_HFRPGA_CFG_REG 0x5C
107#define ISABELLE_HFDRV_CFG_REG 0x5D
108#define ISABELLE_PDMOUT_CFG1_REG 0x5E
109#define ISABELLE_PDMOUT_CFG2_REG 0x5F
110#define ISABELLE_PDMOUT_L_WM_REG 0x60
111#define ISABELLE_PDMOUT_R_WM_REG 0x61
112#define ISABELLE_HF_NG_CFG1_REG 0x62
113#define ISABELLE_HF_NG_CFG2_REG 0x63
114
115/* ISABELLE_PWR_EN_REG (0x02h) */
116#define ISABELLE_CHIP_EN BIT(0)
117
118/* ISABELLE DAI FORMATS */
119#define ISABELLE_AIF_FMT_MASK 0x70
120#define ISABELLE_I2S_MODE 0x0
121#define ISABELLE_LEFT_J_MODE 0x1
122#define ISABELLE_PDM_MODE 0x2
123
124#define ISABELLE_AIF_LENGTH_MASK 0x30
125#define ISABELLE_AIF_LENGTH_20 0x00
126#define ISABELLE_AIF_LENGTH_32 0x10
127
128#define ISABELLE_AIF_MS 0x80
129
130#define ISABELLE_FS_RATE_MASK 0xF
131#define ISABELLE_FS_RATE_8 0x0
132#define ISABELLE_FS_RATE_11 0x1
133#define ISABELLE_FS_RATE_12 0x2
134#define ISABELLE_FS_RATE_16 0x4
135#define ISABELLE_FS_RATE_22 0x5
136#define ISABELLE_FS_RATE_24 0x6
137#define ISABELLE_FS_RATE_32 0x8
138#define ISABELLE_FS_RATE_44 0x9
139#define ISABELLE_FS_RATE_48 0xA
140
141#define ISABELLE_MAX_REGISTER 0xFF
142
143#endif
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c
index 802b9f176b16..99b0a9dcff34 100644
--- a/sound/soc/codecs/lm49453.c
+++ b/sound/soc/codecs/lm49453.c
@@ -12,7 +12,6 @@
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/moduleparam.h> 14#include <linux/moduleparam.h>
15#include <linux/version.h>
16#include <linux/kernel.h> 15#include <linux/kernel.h>
17#include <linux/init.h> 16#include <linux/init.h>
18#include <linux/delay.h> 17#include <linux/delay.h>
@@ -1358,7 +1357,7 @@ static struct snd_soc_dai_ops lm49453_lineout_dai_ops = {
1358}; 1357};
1359 1358
1360/* LM49453 dai structure. */ 1359/* LM49453 dai structure. */
1361static const struct snd_soc_dai_driver lm49453_dai[] = { 1360static struct snd_soc_dai_driver lm49453_dai[] = {
1362 { 1361 {
1363 .name = "LM49453 Headset", 1362 .name = "LM49453 Headset",
1364 .playback = { 1363 .playback = {
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 35179e2c23c9..7cd508e16a5c 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -2216,7 +2216,7 @@ static irqreturn_t max98095_report_jack(int irq, void *data)
2216 return IRQ_HANDLED; 2216 return IRQ_HANDLED;
2217} 2217}
2218 2218
2219int max98095_jack_detect_enable(struct snd_soc_codec *codec) 2219static int max98095_jack_detect_enable(struct snd_soc_codec *codec)
2220{ 2220{
2221 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); 2221 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2222 int ret = 0; 2222 int ret = 0;
@@ -2245,7 +2245,7 @@ int max98095_jack_detect_enable(struct snd_soc_codec *codec)
2245 return ret; 2245 return ret;
2246} 2246}
2247 2247
2248int max98095_jack_detect_disable(struct snd_soc_codec *codec) 2248static int max98095_jack_detect_disable(struct snd_soc_codec *codec)
2249{ 2249{
2250 int ret = 0; 2250 int ret = 0;
2251 2251
@@ -2286,6 +2286,7 @@ int max98095_jack_detect(struct snd_soc_codec *codec,
2286 max98095_report_jack(client->irq, codec); 2286 max98095_report_jack(client->irq, codec);
2287 return 0; 2287 return 0;
2288} 2288}
2289EXPORT_SYMBOL_GPL(max98095_jack_detect);
2289 2290
2290#ifdef CONFIG_PM 2291#ifdef CONFIG_PM
2291static int max98095_suspend(struct snd_soc_codec *codec) 2292static int max98095_suspend(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index 6276e352125f..115a40301810 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -581,6 +581,8 @@ static int mc13783_probe(struct snd_soc_codec *codec)
581{ 581{
582 struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); 582 struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
583 583
584 codec->control_data = priv->mc13xxx;
585
584 mc13xxx_lock(priv->mc13xxx); 586 mc13xxx_lock(priv->mc13xxx);
585 587
586 /* these are the reset values */ 588 /* these are the reset values */
@@ -657,7 +659,7 @@ static struct snd_soc_dai_driver mc13783_dai_async[] = {
657 .id = MC13783_ID_STEREO_DAC, 659 .id = MC13783_ID_STEREO_DAC,
658 .playback = { 660 .playback = {
659 .stream_name = "Playback", 661 .stream_name = "Playback",
660 .channels_min = 1, 662 .channels_min = 2,
661 .channels_max = 2, 663 .channels_max = 2,
662 .rates = SNDRV_PCM_RATE_8000_96000, 664 .rates = SNDRV_PCM_RATE_8000_96000,
663 .formats = MC13783_FORMATS, 665 .formats = MC13783_FORMATS,
@@ -668,7 +670,7 @@ static struct snd_soc_dai_driver mc13783_dai_async[] = {
668 .id = MC13783_ID_STEREO_CODEC, 670 .id = MC13783_ID_STEREO_CODEC,
669 .capture = { 671 .capture = {
670 .stream_name = "Capture", 672 .stream_name = "Capture",
671 .channels_min = 1, 673 .channels_min = 2,
672 .channels_max = 2, 674 .channels_max = 2,
673 .rates = MC13783_RATES_RECORD, 675 .rates = MC13783_RATES_RECORD,
674 .formats = MC13783_FORMATS, 676 .formats = MC13783_FORMATS,
@@ -690,14 +692,14 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = {
690 .id = MC13783_ID_SYNC, 692 .id = MC13783_ID_SYNC,
691 .playback = { 693 .playback = {
692 .stream_name = "Playback", 694 .stream_name = "Playback",
693 .channels_min = 1, 695 .channels_min = 2,
694 .channels_max = 2, 696 .channels_max = 2,
695 .rates = SNDRV_PCM_RATE_8000_96000, 697 .rates = SNDRV_PCM_RATE_8000_96000,
696 .formats = MC13783_FORMATS, 698 .formats = MC13783_FORMATS,
697 }, 699 },
698 .capture = { 700 .capture = {
699 .stream_name = "Capture", 701 .stream_name = "Capture",
700 .channels_min = 1, 702 .channels_min = 2,
701 .channels_max = 2, 703 .channels_max = 2,
702 .rates = MC13783_RATES_RECORD, 704 .rates = MC13783_RATES_RECORD,
703 .formats = MC13783_FORMATS, 705 .formats = MC13783_FORMATS,
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c
index 22cb5bf59273..96aa5fa05160 100644
--- a/sound/soc/codecs/ml26124.c
+++ b/sound/soc/codecs/ml26124.c
@@ -638,7 +638,7 @@ static __devinit int ml26124_i2c_probe(struct i2c_client *i2c,
638 638
639 i2c_set_clientdata(i2c, priv); 639 i2c_set_clientdata(i2c, priv);
640 640
641 priv->regmap = regmap_init_i2c(i2c, &ml26124_i2c_regmap); 641 priv->regmap = devm_regmap_init_i2c(i2c, &ml26124_i2c_regmap);
642 if (IS_ERR(priv->regmap)) { 642 if (IS_ERR(priv->regmap)) {
643 ret = PTR_ERR(priv->regmap); 643 ret = PTR_ERR(priv->regmap);
644 dev_err(&i2c->dev, "regmap_init_i2c() failed: %d\n", ret); 644 dev_err(&i2c->dev, "regmap_init_i2c() failed: %d\n", ret);
@@ -651,10 +651,7 @@ static __devinit int ml26124_i2c_probe(struct i2c_client *i2c,
651 651
652static __devexit int ml26124_i2c_remove(struct i2c_client *client) 652static __devexit int ml26124_i2c_remove(struct i2c_client *client)
653{ 653{
654 struct ml26124_priv *priv = i2c_get_clientdata(client);
655
656 snd_soc_unregister_codec(&client->dev); 654 snd_soc_unregister_codec(&client->dev);
657 regmap_exit(priv->regmap);
658 return 0; 655 return 0;
659} 656}
660 657
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 8af6a5245b18..df2f99d1d428 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -239,6 +239,7 @@ static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = {
239 {"Headphone Mux", "DAC", "DAC"}, /* dac --> hp_mux */ 239 {"Headphone Mux", "DAC", "DAC"}, /* dac --> hp_mux */
240 {"LO", NULL, "DAC"}, /* dac --> line_out */ 240 {"LO", NULL, "DAC"}, /* dac --> line_out */
241 241
242 {"LINE_IN", NULL, "VAG_POWER"},
242 {"Headphone Mux", "LINE_IN", "LINE_IN"},/* line_in --> hp_mux */ 243 {"Headphone Mux", "LINE_IN", "LINE_IN"},/* line_in --> hp_mux */
243 {"HP", NULL, "Headphone Mux"}, /* hp_mux --> hp */ 244 {"HP", NULL, "Headphone Mux"}, /* hp_mux --> hp */
244 245
@@ -1357,8 +1358,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
1357 if (ret) 1358 if (ret)
1358 goto err; 1359 goto err;
1359 1360
1360 snd_soc_dapm_new_widgets(&codec->dapm);
1361
1362 return 0; 1361 return 0;
1363 1362
1364err: 1363err:
diff --git a/sound/soc/codecs/spdif_receiver.c b/sound/soc/codecs/spdif_receiver.c
new file mode 100644
index 000000000000..dd8d856053fc
--- /dev/null
+++ b/sound/soc/codecs/spdif_receiver.c
@@ -0,0 +1,67 @@
1/*
2 * ALSA SoC SPDIF DIR (Digital Interface Reciever) driver
3 *
4 * Based on ALSA SoC SPDIF DIT driver
5 *
6 * This driver is used by controllers which can operate in DIR (SPDI/F) where
7 * no codec is needed. This file provides stub codec that can be used
8 * in these configurations. SPEAr SPDIF IN Audio controller uses this driver.
9 *
10 * Author: Vipin Kumar, <vipin.kumar@st.com>
11 * Copyright: (C) 2012 ST Microelectronics
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/slab.h>
21#include <sound/soc.h>
22#include <sound/pcm.h>
23#include <sound/initval.h>
24
25#define STUB_RATES SNDRV_PCM_RATE_8000_192000
26#define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
27 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
28
29static struct snd_soc_codec_driver soc_codec_spdif_dir;
30
31static struct snd_soc_dai_driver dir_stub_dai = {
32 .name = "dir-hifi",
33 .capture = {
34 .stream_name = "Capture",
35 .channels_min = 1,
36 .channels_max = 384,
37 .rates = STUB_RATES,
38 .formats = STUB_FORMATS,
39 },
40};
41
42static int spdif_dir_probe(struct platform_device *pdev)
43{
44 return snd_soc_register_codec(&pdev->dev, &soc_codec_spdif_dir,
45 &dir_stub_dai, 1);
46}
47
48static int spdif_dir_remove(struct platform_device *pdev)
49{
50 snd_soc_unregister_codec(&pdev->dev);
51 return 0;
52}
53
54static struct platform_driver spdif_dir_driver = {
55 .probe = spdif_dir_probe,
56 .remove = spdif_dir_remove,
57 .driver = {
58 .name = "spdif-dir",
59 .owner = THIS_MODULE,
60 },
61};
62
63module_platform_driver(spdif_dir_driver);
64
65MODULE_DESCRIPTION("ASoC SPDIF DIR driver");
66MODULE_AUTHOR("Vipin Kumar <vipin.kumar@st.com>");
67MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c
new file mode 100644
index 000000000000..0c225cd569d2
--- /dev/null
+++ b/sound/soc/codecs/sta529.c
@@ -0,0 +1,442 @@
1/*
2 * ASoC codec driver for spear platform
3 *
4 * sound/soc/codecs/sta529.c -- spear ALSA Soc codec driver
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Rajeev Kumar <rajeev-dlh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include <linux/clk.h>
15#include <linux/init.h>
16#include <linux/i2c.h>
17#include <linux/io.h>
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/pm.h>
21#include <linux/regmap.h>
22#include <linux/slab.h>
23
24#include <sound/core.h>
25#include <sound/initval.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/tlv.h>
31
32/* STA529 Register offsets */
33#define STA529_FFXCFG0 0x00
34#define STA529_FFXCFG1 0x01
35#define STA529_MVOL 0x02
36#define STA529_LVOL 0x03
37#define STA529_RVOL 0x04
38#define STA529_TTF0 0x05
39#define STA529_TTF1 0x06
40#define STA529_TTP0 0x07
41#define STA529_TTP1 0x08
42#define STA529_S2PCFG0 0x0A
43#define STA529_S2PCFG1 0x0B
44#define STA529_P2SCFG0 0x0C
45#define STA529_P2SCFG1 0x0D
46#define STA529_PLLCFG0 0x14
47#define STA529_PLLCFG1 0x15
48#define STA529_PLLCFG2 0x16
49#define STA529_PLLCFG3 0x17
50#define STA529_PLLPFE 0x18
51#define STA529_PLLST 0x19
52#define STA529_ADCCFG 0x1E /*mic_select*/
53#define STA529_CKOCFG 0x1F
54#define STA529_MISC 0x20
55#define STA529_PADST0 0x21
56#define STA529_PADST1 0x22
57#define STA529_FFXST 0x23
58#define STA529_PWMIN1 0x2D
59#define STA529_PWMIN2 0x2E
60#define STA529_POWST 0x32
61
62#define STA529_MAX_REGISTER 0x32
63
64#define STA529_RATES (SNDRV_PCM_RATE_8000 | \
65 SNDRV_PCM_RATE_11025 | \
66 SNDRV_PCM_RATE_16000 | \
67 SNDRV_PCM_RATE_22050 | \
68 SNDRV_PCM_RATE_32000 | \
69 SNDRV_PCM_RATE_44100 | \
70 SNDRV_PCM_RATE_48000)
71
72#define STA529_FORMAT (SNDRV_PCM_FMTBIT_S16_LE | \
73 SNDRV_PCM_FMTBIT_S24_LE | \
74 SNDRV_PCM_FMTBIT_S32_LE)
75#define S2PC_VALUE 0x98
76#define CLOCK_OUT 0x60
77#define LEFT_J_DATA_FORMAT 0x10
78#define I2S_DATA_FORMAT 0x12
79#define RIGHT_J_DATA_FORMAT 0x14
80#define CODEC_MUTE_VAL 0x80
81
82#define POWER_CNTLMSAK 0x40
83#define POWER_STDBY 0x40
84#define FFX_MASK 0x80
85#define FFX_OFF 0x80
86#define POWER_UP 0x00
87#define FFX_CLK_ENB 0x01
88#define FFX_CLK_DIS 0x00
89#define FFX_CLK_MSK 0x01
90#define PLAY_FREQ_RANGE_MSK 0x70
91#define CAP_FREQ_RANGE_MSK 0x0C
92#define PDATA_LEN_MSK 0xC0
93#define BCLK_TO_FS_MSK 0x30
94#define AUDIO_MUTE_MSK 0x80
95
96static const struct reg_default sta529_reg_defaults[] = {
97 { 0, 0x35 }, /* R0 - FFX Configuration reg 0 */
98 { 1, 0xc8 }, /* R1 - FFX Configuration reg 1 */
99 { 2, 0x50 }, /* R2 - Master Volume */
100 { 3, 0x00 }, /* R3 - Left Volume */
101 { 4, 0x00 }, /* R4 - Right Volume */
102 { 10, 0xb2 }, /* R10 - S2P Config Reg 0 */
103 { 11, 0x41 }, /* R11 - S2P Config Reg 1 */
104 { 12, 0x92 }, /* R12 - P2S Config Reg 0 */
105 { 13, 0x41 }, /* R13 - P2S Config Reg 1 */
106 { 30, 0xd2 }, /* R30 - ADC Config Reg */
107 { 31, 0x40 }, /* R31 - clock Out Reg */
108 { 32, 0x21 }, /* R32 - Misc Register */
109};
110
111struct sta529 {
112 struct regmap *regmap;
113};
114
115static bool sta529_readable(struct device *dev, unsigned int reg)
116{
117 switch (reg) {
118
119 case STA529_FFXCFG0:
120 case STA529_FFXCFG1:
121 case STA529_MVOL:
122 case STA529_LVOL:
123 case STA529_RVOL:
124 case STA529_S2PCFG0:
125 case STA529_S2PCFG1:
126 case STA529_P2SCFG0:
127 case STA529_P2SCFG1:
128 case STA529_ADCCFG:
129 case STA529_CKOCFG:
130 case STA529_MISC:
131 return true;
132 default:
133 return false;
134 }
135}
136
137
138static const char *pwm_mode_text[] = { "Binary", "Headphone", "Ternary",
139 "Phase-shift"};
140
141static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -9150, 50, 0);
142static const DECLARE_TLV_DB_SCALE(master_vol_tlv, -12750, 50, 0);
143static const SOC_ENUM_SINGLE_DECL(pwm_src, STA529_FFXCFG1, 4, pwm_mode_text);
144
145static const struct snd_kcontrol_new sta529_snd_controls[] = {
146 SOC_DOUBLE_R_TLV("Digital Playback Volume", STA529_LVOL, STA529_RVOL, 0,
147 127, 0, out_gain_tlv),
148 SOC_SINGLE_TLV("Master Playback Volume", STA529_MVOL, 0, 127, 1,
149 master_vol_tlv),
150 SOC_ENUM("PWM Select", pwm_src),
151};
152
153static int sta529_set_bias_level(struct snd_soc_codec *codec, enum
154 snd_soc_bias_level level)
155{
156 struct sta529 *sta529 = snd_soc_codec_get_drvdata(codec);
157
158 switch (level) {
159 case SND_SOC_BIAS_ON:
160 case SND_SOC_BIAS_PREPARE:
161 snd_soc_update_bits(codec, STA529_FFXCFG0, POWER_CNTLMSAK,
162 POWER_UP);
163 snd_soc_update_bits(codec, STA529_MISC, FFX_CLK_MSK,
164 FFX_CLK_ENB);
165 break;
166 case SND_SOC_BIAS_STANDBY:
167 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
168 regcache_sync(sta529->regmap);
169 snd_soc_update_bits(codec, STA529_FFXCFG0,
170 POWER_CNTLMSAK, POWER_STDBY);
171 /* Making FFX output to zero */
172 snd_soc_update_bits(codec, STA529_FFXCFG0, FFX_MASK,
173 FFX_OFF);
174 snd_soc_update_bits(codec, STA529_MISC, FFX_CLK_MSK,
175 FFX_CLK_DIS);
176 break;
177 case SND_SOC_BIAS_OFF:
178 break;
179 }
180
181 /*
182 * store the label for powers down audio subsystem for suspend.This is
183 * used by soc core layer
184 */
185 codec->dapm.bias_level = level;
186
187 return 0;
188
189}
190
191static int sta529_hw_params(struct snd_pcm_substream *substream,
192 struct snd_pcm_hw_params *params,
193 struct snd_soc_dai *dai)
194{
195 struct snd_soc_pcm_runtime *rtd = substream->private_data;
196 struct snd_soc_codec *codec = rtd->codec;
197 int pdata, play_freq_val, record_freq_val;
198 int bclk_to_fs_ratio;
199
200 switch (params_format(params)) {
201 case SNDRV_PCM_FORMAT_S16_LE:
202 pdata = 1;
203 bclk_to_fs_ratio = 0;
204 break;
205 case SNDRV_PCM_FORMAT_S24_LE:
206 pdata = 2;
207 bclk_to_fs_ratio = 1;
208 break;
209 case SNDRV_PCM_FORMAT_S32_LE:
210 pdata = 3;
211 bclk_to_fs_ratio = 2;
212 break;
213 default:
214 dev_err(codec->dev, "Unsupported format\n");
215 return -EINVAL;
216 }
217
218 switch (params_rate(params)) {
219 case 8000:
220 case 11025:
221 play_freq_val = 0;
222 record_freq_val = 2;
223 break;
224 case 16000:
225 case 22050:
226 play_freq_val = 1;
227 record_freq_val = 0;
228 break;
229
230 case 32000:
231 case 44100:
232 case 48000:
233 play_freq_val = 2;
234 record_freq_val = 0;
235 break;
236 default:
237 dev_err(codec->dev, "Unsupported rate\n");
238 return -EINVAL;
239 }
240
241 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
242 snd_soc_update_bits(codec, STA529_S2PCFG1, PDATA_LEN_MSK,
243 pdata << 6);
244 snd_soc_update_bits(codec, STA529_S2PCFG1, BCLK_TO_FS_MSK,
245 bclk_to_fs_ratio << 4);
246 snd_soc_update_bits(codec, STA529_MISC, PLAY_FREQ_RANGE_MSK,
247 play_freq_val << 4);
248 } else {
249 snd_soc_update_bits(codec, STA529_P2SCFG1, PDATA_LEN_MSK,
250 pdata << 6);
251 snd_soc_update_bits(codec, STA529_P2SCFG1, BCLK_TO_FS_MSK,
252 bclk_to_fs_ratio << 4);
253 snd_soc_update_bits(codec, STA529_MISC, CAP_FREQ_RANGE_MSK,
254 record_freq_val << 2);
255 }
256
257 return 0;
258}
259
260static int sta529_mute(struct snd_soc_dai *dai, int mute)
261{
262 u8 val = 0;
263
264 if (mute)
265 val |= CODEC_MUTE_VAL;
266
267 snd_soc_update_bits(dai->codec, STA529_FFXCFG0, AUDIO_MUTE_MSK, val);
268
269 return 0;
270}
271
272static int sta529_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
273{
274 struct snd_soc_codec *codec = codec_dai->codec;
275 u8 mode = 0;
276
277 /* interface format */
278 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
279 case SND_SOC_DAIFMT_LEFT_J:
280 mode = LEFT_J_DATA_FORMAT;
281 break;
282 case SND_SOC_DAIFMT_I2S:
283 mode = I2S_DATA_FORMAT;
284 break;
285 case SND_SOC_DAIFMT_RIGHT_J:
286 mode = RIGHT_J_DATA_FORMAT;
287 break;
288 default:
289 return -EINVAL;
290 }
291
292 snd_soc_update_bits(codec, STA529_S2PCFG0, 0x0D, mode);
293
294 return 0;
295}
296
297static const struct snd_soc_dai_ops sta529_dai_ops = {
298 .hw_params = sta529_hw_params,
299 .set_fmt = sta529_set_dai_fmt,
300 .digital_mute = sta529_mute,
301};
302
303static struct snd_soc_dai_driver sta529_dai = {
304 .name = "sta529-audio",
305 .playback = {
306 .stream_name = "Playback",
307 .channels_min = 2,
308 .channels_max = 2,
309 .rates = STA529_RATES,
310 .formats = STA529_FORMAT,
311 },
312 .capture = {
313 .stream_name = "Capture",
314 .channels_min = 2,
315 .channels_max = 2,
316 .rates = STA529_RATES,
317 .formats = STA529_FORMAT,
318 },
319 .ops = &sta529_dai_ops,
320};
321
322static int sta529_probe(struct snd_soc_codec *codec)
323{
324 struct sta529 *sta529 = snd_soc_codec_get_drvdata(codec);
325 int ret;
326
327 codec->control_data = sta529->regmap;
328 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
329
330 if (ret < 0) {
331 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
332 return ret;
333 }
334 sta529_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
335
336 return 0;
337}
338
339/* power down chip */
340static int sta529_remove(struct snd_soc_codec *codec)
341{
342 sta529_set_bias_level(codec, SND_SOC_BIAS_OFF);
343
344 return 0;
345}
346
347static int sta529_suspend(struct snd_soc_codec *codec)
348{
349 sta529_set_bias_level(codec, SND_SOC_BIAS_OFF);
350
351 return 0;
352}
353
354static int sta529_resume(struct snd_soc_codec *codec)
355{
356 sta529_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
357
358 return 0;
359}
360
361struct snd_soc_codec_driver sta529_codec_driver = {
362 .probe = sta529_probe,
363 .remove = sta529_remove,
364 .set_bias_level = sta529_set_bias_level,
365 .suspend = sta529_suspend,
366 .resume = sta529_resume,
367 .controls = sta529_snd_controls,
368 .num_controls = ARRAY_SIZE(sta529_snd_controls),
369};
370
371static const struct regmap_config sta529_regmap = {
372 .reg_bits = 8,
373 .val_bits = 8,
374
375 .max_register = STA529_MAX_REGISTER,
376 .readable_reg = sta529_readable,
377
378 .cache_type = REGCACHE_RBTREE,
379 .reg_defaults = sta529_reg_defaults,
380 .num_reg_defaults = ARRAY_SIZE(sta529_reg_defaults),
381};
382
383static __devinit int sta529_i2c_probe(struct i2c_client *i2c,
384 const struct i2c_device_id *id)
385{
386 struct sta529 *sta529;
387 int ret;
388
389 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
390 return -EINVAL;
391
392 sta529 = devm_kzalloc(&i2c->dev, sizeof(struct sta529), GFP_KERNEL);
393 if (sta529 == NULL) {
394 dev_err(&i2c->dev, "Can not allocate memory\n");
395 return -ENOMEM;
396 }
397
398 sta529->regmap = devm_regmap_init_i2c(i2c, &sta529_regmap);
399 if (IS_ERR(sta529->regmap)) {
400 ret = PTR_ERR(sta529->regmap);
401 dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
402 return ret;
403 }
404
405 i2c_set_clientdata(i2c, sta529);
406
407 ret = snd_soc_register_codec(&i2c->dev,
408 &sta529_codec_driver, &sta529_dai, 1);
409 if (ret != 0)
410 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
411
412 return ret;
413}
414
415static int __devexit sta529_i2c_remove(struct i2c_client *client)
416{
417 snd_soc_unregister_codec(&client->dev);
418
419 return 0;
420}
421
422static const struct i2c_device_id sta529_i2c_id[] = {
423 { "sta529", 0 },
424 { }
425};
426MODULE_DEVICE_TABLE(i2c, sta529_i2c_id);
427
428static struct i2c_driver sta529_i2c_driver = {
429 .driver = {
430 .name = "sta529",
431 .owner = THIS_MODULE,
432 },
433 .probe = sta529_i2c_probe,
434 .remove = __devexit_p(sta529_i2c_remove),
435 .id_table = sta529_i2c_id,
436};
437
438module_i2c_driver(sta529_i2c_driver);
439
440MODULE_DESCRIPTION("ASoC STA529 codec driver");
441MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>");
442MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 982e437799a8..33c0f3d39c87 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -340,6 +340,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec)
340 340
341 printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION); 341 printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION);
342 342
343 codec->control_data = codec; /* we don't use regmap! */
343 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 344 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
344 if (ret < 0) 345 if (ret < 0)
345 goto codec_err; 346 goto codec_err;
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index e9b62b5ea637..dc78f5a4bcbf 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -118,7 +118,9 @@ static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = {
118 0x00, 0x00, 0x00, 0x00, /* 88 */ 118 0x00, 0x00, 0x00, 0x00, /* 88 */
119 0x00, 0x00, 0x00, 0x00, /* 92 */ 119 0x00, 0x00, 0x00, 0x00, /* 92 */
120 0x00, 0x00, 0x00, 0x00, /* 96 */ 120 0x00, 0x00, 0x00, 0x00, /* 96 */
121 0x00, 0x00, 0x02, /* 100 */ 121 0x00, 0x00, 0x02, 0x00, /* 100 */
122 0x00, 0x00, 0x00, 0x00, /* 104 */
123 0x00, 0x00, /* 108 */
122}; 124};
123 125
124#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \ 126#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \
@@ -229,6 +231,25 @@ static const struct soc_enum aic3x_enum[] = {
229 SOC_ENUM_DOUBLE(AIC3X_CODEC_DFILT_CTRL, 6, 4, 4, aic3x_adc_hpf), 231 SOC_ENUM_DOUBLE(AIC3X_CODEC_DFILT_CTRL, 6, 4, 4, aic3x_adc_hpf),
230}; 232};
231 233
234static const char *aic3x_agc_level[] =
235 { "-5.5dB", "-8dB", "-10dB", "-12dB", "-14dB", "-17dB", "-20dB", "-24dB" };
236static const struct soc_enum aic3x_agc_level_enum[] = {
237 SOC_ENUM_SINGLE(LAGC_CTRL_A, 4, 8, aic3x_agc_level),
238 SOC_ENUM_SINGLE(RAGC_CTRL_A, 4, 8, aic3x_agc_level),
239};
240
241static const char *aic3x_agc_attack[] = { "8ms", "11ms", "16ms", "20ms" };
242static const struct soc_enum aic3x_agc_attack_enum[] = {
243 SOC_ENUM_SINGLE(LAGC_CTRL_A, 2, 4, aic3x_agc_attack),
244 SOC_ENUM_SINGLE(RAGC_CTRL_A, 2, 4, aic3x_agc_attack),
245};
246
247static const char *aic3x_agc_decay[] = { "100ms", "200ms", "400ms", "500ms" };
248static const struct soc_enum aic3x_agc_decay_enum[] = {
249 SOC_ENUM_SINGLE(LAGC_CTRL_A, 0, 4, aic3x_agc_decay),
250 SOC_ENUM_SINGLE(RAGC_CTRL_A, 0, 4, aic3x_agc_decay),
251};
252
232/* 253/*
233 * DAC digital volumes. From -63.5 to 0 dB in 0.5 dB steps 254 * DAC digital volumes. From -63.5 to 0 dB in 0.5 dB steps
234 */ 255 */
@@ -353,6 +374,15 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
353 * adjust PGA to max value when ADC is on and will never go back. 374 * adjust PGA to max value when ADC is on and will never go back.
354 */ 375 */
355 SOC_DOUBLE_R("AGC Switch", LAGC_CTRL_A, RAGC_CTRL_A, 7, 0x01, 0), 376 SOC_DOUBLE_R("AGC Switch", LAGC_CTRL_A, RAGC_CTRL_A, 7, 0x01, 0),
377 SOC_ENUM("Left AGC Target level", aic3x_agc_level_enum[0]),
378 SOC_ENUM("Right AGC Target level", aic3x_agc_level_enum[1]),
379 SOC_ENUM("Left AGC Attack time", aic3x_agc_attack_enum[0]),
380 SOC_ENUM("Right AGC Attack time", aic3x_agc_attack_enum[1]),
381 SOC_ENUM("Left AGC Decay time", aic3x_agc_decay_enum[0]),
382 SOC_ENUM("Right AGC Decay time", aic3x_agc_decay_enum[1]),
383
384 /* De-emphasis */
385 SOC_DOUBLE("De-emphasis Switch", AIC3X_CODEC_DFILT_CTRL, 2, 0, 0x01, 0),
356 386
357 /* Input */ 387 /* Input */
358 SOC_DOUBLE_R_TLV("PGA Capture Volume", LADC_VOL, RADC_VOL, 388 SOC_DOUBLE_R_TLV("PGA Capture Volume", LADC_VOL, RADC_VOL,
@@ -368,7 +398,7 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
368static DECLARE_TLV_DB_SCALE(classd_amp_tlv, 0, 600, 0); 398static DECLARE_TLV_DB_SCALE(classd_amp_tlv, 0, 600, 0);
369 399
370static const struct snd_kcontrol_new aic3x_classd_amp_gain_ctrl = 400static const struct snd_kcontrol_new aic3x_classd_amp_gain_ctrl =
371 SOC_DOUBLE_TLV("Class-D Amplifier Gain", CLASSD_CTRL, 6, 4, 3, 0, classd_amp_tlv); 401 SOC_DOUBLE_TLV("Class-D Playback Volume", CLASSD_CTRL, 6, 4, 3, 0, classd_amp_tlv);
372 402
373/* Left DAC Mux */ 403/* Left DAC Mux */
374static const struct snd_kcontrol_new aic3x_left_dac_mux_controls = 404static const struct snd_kcontrol_new aic3x_left_dac_mux_controls =
@@ -970,6 +1000,12 @@ static int aic3x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
970 struct snd_soc_codec *codec = codec_dai->codec; 1000 struct snd_soc_codec *codec = codec_dai->codec;
971 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 1001 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
972 1002
1003 /* set clock on MCLK or GPIO2 or BCLK */
1004 snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, PLLCLK_IN_MASK,
1005 clk_id << PLLCLK_IN_SHIFT);
1006 snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, CLKDIV_IN_MASK,
1007 clk_id << CLKDIV_IN_SHIFT);
1008
973 aic3x->sysclk = freq; 1009 aic3x->sysclk = freq;
974 return 0; 1010 return 0;
975} 1011}
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index 08c7f6685ff0..6db3c41b0163 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -13,7 +13,7 @@
13#define _AIC3X_H 13#define _AIC3X_H
14 14
15/* AIC3X register space */ 15/* AIC3X register space */
16#define AIC3X_CACHEREGNUM 103 16#define AIC3X_CACHEREGNUM 110
17 17
18/* Page select register */ 18/* Page select register */
19#define AIC3X_PAGE_SELECT 0 19#define AIC3X_PAGE_SELECT 0
@@ -74,6 +74,8 @@
74#define HPLCOM_CFG 37 74#define HPLCOM_CFG 37
75/* Right High Power Output control registers */ 75/* Right High Power Output control registers */
76#define HPRCOM_CFG 38 76#define HPRCOM_CFG 38
77/* High Power Output Stage Control Register */
78#define HPOUT_SC 40
77/* DAC Output Switching control registers */ 79/* DAC Output Switching control registers */
78#define DAC_LINE_MUX 41 80#define DAC_LINE_MUX 41
79/* High Power Output Driver Pop Reduction registers */ 81/* High Power Output Driver Pop Reduction registers */
@@ -148,6 +150,17 @@
148#define AIC3X_GPIOB_REG 101 150#define AIC3X_GPIOB_REG 101
149/* Clock generation control register */ 151/* Clock generation control register */
150#define AIC3X_CLKGEN_CTRL_REG 102 152#define AIC3X_CLKGEN_CTRL_REG 102
153/* New AGC registers */
154#define LAGCN_ATTACK 103
155#define LAGCN_DECAY 104
156#define RAGCN_ATTACK 105
157#define RAGCN_DECAY 106
158/* New Programmable ADC Digital Path and I2C Bus Condition Register */
159#define NEW_ADC_DIGITALPATH 107
160/* Passive Analog Signal Bypass Selection During Powerdown Register */
161#define PASSIVE_BYPASS 108
162/* DAC Quiescent Current Adjustment Register */
163#define DAC_ICC_ADJ 109
151 164
152/* Page select register bits */ 165/* Page select register bits */
153#define PAGE0_SELECT 0 166#define PAGE0_SELECT 0
@@ -163,6 +176,10 @@
163#define DUAL_RATE_MODE ((1 << 5) | (1 << 6)) 176#define DUAL_RATE_MODE ((1 << 5) | (1 << 6))
164#define LDAC2LCH (0x1 << 3) 177#define LDAC2LCH (0x1 << 3)
165#define RDAC2RCH (0x1 << 1) 178#define RDAC2RCH (0x1 << 1)
179#define LDAC2RCH (0x2 << 3)
180#define RDAC2LCH (0x2 << 1)
181#define LDAC2MONOMIX (0x3 << 3)
182#define RDAC2MONOMIX (0x3 << 1)
166 183
167/* PLL registers bitfields */ 184/* PLL registers bitfields */
168#define PLLP_SHIFT 0 185#define PLLP_SHIFT 0
@@ -179,6 +196,14 @@
179#define PLL_CLKIN_SHIFT 4 196#define PLL_CLKIN_SHIFT 4
180#define MCLK_SOURCE 0x0 197#define MCLK_SOURCE 0x0
181#define PLL_CLKDIV_SHIFT 0 198#define PLL_CLKDIV_SHIFT 0
199#define PLLCLK_IN_MASK 0x30
200#define PLLCLK_IN_SHIFT 4
201#define CLKDIV_IN_MASK 0xc0
202#define CLKDIV_IN_SHIFT 6
203/* clock in source */
204#define CLKIN_MCLK 0
205#define CLKIN_GPIO2 1
206#define CLKIN_BCLK 2
182 207
183/* Software reset register bits */ 208/* Software reset register bits */
184#define SOFT_RESET 0x80 209#define SOFT_RESET 0x80
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index a36e9fcdf184..c084c549942e 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -553,7 +553,7 @@ static const struct snd_kcontrol_new vibrar_mux_controls =
553 553
554/* Headset power mode */ 554/* Headset power mode */
555static const char *twl6040_power_mode_texts[] = { 555static const char *twl6040_power_mode_texts[] = {
556 "Low-Power", "High-Perfomance", 556 "Low-Power", "High-Performance",
557}; 557};
558 558
559static const struct soc_enum twl6040_power_mode_enum = 559static const struct soc_enum twl6040_power_mode_enum =
@@ -653,7 +653,7 @@ int twl6040_get_hs_step_size(struct snd_soc_codec *codec)
653{ 653{
654 struct twl6040 *twl6040 = codec->control_data; 654 struct twl6040 *twl6040 = codec->control_data;
655 655
656 if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_2) 656 if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_3)
657 /* For ES under ES_1.3 HS step is 2 mV */ 657 /* For ES under ES_1.3 HS step is 2 mV */
658 return 2; 658 return 2;
659 else 659 else
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c
index e0b51e9f8b12..951d7b49476a 100644
--- a/sound/soc/codecs/wm1250-ev1.c
+++ b/sound/soc/codecs/wm1250-ev1.c
@@ -121,20 +121,23 @@ static const struct snd_soc_dai_ops wm1250_ev1_ops = {
121 .hw_params = wm1250_ev1_hw_params, 121 .hw_params = wm1250_ev1_hw_params,
122}; 122};
123 123
124#define WM1250_EV1_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
125 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_64000)
126
124static struct snd_soc_dai_driver wm1250_ev1_dai = { 127static struct snd_soc_dai_driver wm1250_ev1_dai = {
125 .name = "wm1250-ev1", 128 .name = "wm1250-ev1",
126 .playback = { 129 .playback = {
127 .stream_name = "Playback", 130 .stream_name = "Playback",
128 .channels_min = 1, 131 .channels_min = 1,
129 .channels_max = 2, 132 .channels_max = 2,
130 .rates = SNDRV_PCM_RATE_8000, 133 .rates = WM1250_EV1_RATES,
131 .formats = SNDRV_PCM_FMTBIT_S16_LE, 134 .formats = SNDRV_PCM_FMTBIT_S16_LE,
132 }, 135 },
133 .capture = { 136 .capture = {
134 .stream_name = "Capture", 137 .stream_name = "Capture",
135 .channels_min = 1, 138 .channels_min = 1,
136 .channels_max = 2, 139 .channels_max = 2,
137 .rates = SNDRV_PCM_RATE_8000, 140 .rates = WM1250_EV1_RATES,
138 .formats = SNDRV_PCM_FMTBIT_S16_LE, 141 .formats = SNDRV_PCM_FMTBIT_S16_LE,
139 }, 142 },
140 .ops = &wm1250_ev1_ops, 143 .ops = &wm1250_ev1_ops,
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 0418fa11e6bd..a3acb7a85f6a 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm2000.c -- WM2000 ALSA Soc Audio driver 2 * wm2000.c -- WM2000 ALSA Soc Audio driver
3 * 3 *
4 * Copyright 2008-2010 Wolfson Microelectronics PLC. 4 * Copyright 2008-2011 Wolfson Microelectronics PLC.
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
@@ -674,9 +674,39 @@ static int wm2000_resume(struct snd_soc_codec *codec)
674#define wm2000_resume NULL 674#define wm2000_resume NULL
675#endif 675#endif
676 676
677static bool wm2000_readable_reg(struct device *dev, unsigned int reg)
678{
679 switch (reg) {
680 case WM2000_REG_SYS_START:
681 case WM2000_REG_SPEECH_CLARITY:
682 case WM2000_REG_SYS_WATCHDOG:
683 case WM2000_REG_ANA_VMID_PD_TIME:
684 case WM2000_REG_ANA_VMID_PU_TIME:
685 case WM2000_REG_CAT_FLTR_INDX:
686 case WM2000_REG_CAT_GAIN_0:
687 case WM2000_REG_SYS_STATUS:
688 case WM2000_REG_SYS_MODE_CNTRL:
689 case WM2000_REG_SYS_START0:
690 case WM2000_REG_SYS_START1:
691 case WM2000_REG_ID1:
692 case WM2000_REG_ID2:
693 case WM2000_REG_REVISON:
694 case WM2000_REG_SYS_CTL1:
695 case WM2000_REG_SYS_CTL2:
696 case WM2000_REG_ANC_STAT:
697 case WM2000_REG_IF_CTL:
698 return true;
699 default:
700 return false;
701 }
702}
703
677static const struct regmap_config wm2000_regmap = { 704static const struct regmap_config wm2000_regmap = {
678 .reg_bits = 8, 705 .reg_bits = 16,
679 .val_bits = 8, 706 .val_bits = 8,
707
708 .max_register = WM2000_REG_IF_CTL,
709 .readable_reg = wm2000_readable_reg,
680}; 710};
681 711
682static int wm2000_probe(struct snd_soc_codec *codec) 712static int wm2000_probe(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wm5100-tables.c b/sound/soc/codecs/wm5100-tables.c
index e167207a19cc..e239f4bf2460 100644
--- a/sound/soc/codecs/wm5100-tables.c
+++ b/sound/soc/codecs/wm5100-tables.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm5100-tables.c -- WM5100 ALSA SoC Audio driver data 2 * wm5100-tables.c -- WM5100 ALSA SoC Audio driver data
3 * 3 *
4 * Copyright 2011 Wolfson Microelectronics plc 4 * Copyright 2011-2 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index cb6d5372103a..f4817292ef45 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm5100.c -- WM5100 ALSA SoC Audio driver 2 * wm5100.c -- WM5100 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2011 Wolfson Microelectronics plc 4 * Copyright 2011-2 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
@@ -2378,13 +2378,6 @@ static int wm5100_remove(struct snd_soc_codec *codec)
2378 return 0; 2378 return 0;
2379} 2379}
2380 2380
2381static int wm5100_soc_volatile(struct snd_soc_codec *codec,
2382 unsigned int reg)
2383{
2384 return true;
2385}
2386
2387
2388static struct snd_soc_codec_driver soc_codec_dev_wm5100 = { 2381static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
2389 .probe = wm5100_probe, 2382 .probe = wm5100_probe,
2390 .remove = wm5100_remove, 2383 .remove = wm5100_remove,
@@ -2392,8 +2385,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
2392 .set_sysclk = wm5100_set_sysclk, 2385 .set_sysclk = wm5100_set_sysclk,
2393 .set_pll = wm5100_set_fll, 2386 .set_pll = wm5100_set_fll,
2394 .idle_bias_off = 1, 2387 .idle_bias_off = 1,
2395 .reg_cache_size = WM5100_MAX_REGISTER,
2396 .volatile_register = wm5100_soc_volatile,
2397 2388
2398 .seq_notifier = wm5100_seq_notifier, 2389 .seq_notifier = wm5100_seq_notifier,
2399 .controls = wm5100_snd_controls, 2390 .controls = wm5100_snd_controls,
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
new file mode 100644
index 000000000000..e33d327396ad
--- /dev/null
+++ b/sound/soc/codecs/wm5102.c
@@ -0,0 +1,896 @@
1/*
2 * wm5102.c -- WM5102 ALSA SoC Audio driver
3 *
4 * Copyright 2012 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/pm_runtime.h>
19#include <linux/regmap.h>
20#include <linux/slab.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/jack.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28
29#include <linux/mfd/arizona/core.h>
30#include <linux/mfd/arizona/registers.h>
31
32#include "arizona.h"
33#include "wm5102.h"
34
35struct wm5102_priv {
36 struct arizona_priv core;
37 struct arizona_fll fll[2];
38};
39
40static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
41static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
42static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
43static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0);
44
45static const struct snd_kcontrol_new wm5102_snd_controls[] = {
46SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL,
47 ARIZONA_IN1_OSR_SHIFT, 1, 0),
48SOC_SINGLE("IN2 High Performance Switch", ARIZONA_IN2L_CONTROL,
49 ARIZONA_IN2_OSR_SHIFT, 1, 0),
50SOC_SINGLE("IN3 High Performance Switch", ARIZONA_IN3L_CONTROL,
51 ARIZONA_IN3_OSR_SHIFT, 1, 0),
52
53SOC_DOUBLE_R_RANGE_TLV("IN1 Volume", ARIZONA_IN1L_CONTROL,
54 ARIZONA_IN1R_CONTROL,
55 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
56SOC_DOUBLE_R_RANGE_TLV("IN2 Volume", ARIZONA_IN2L_CONTROL,
57 ARIZONA_IN2R_CONTROL,
58 ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
59SOC_DOUBLE_R_RANGE_TLV("IN3 Volume", ARIZONA_IN3L_CONTROL,
60 ARIZONA_IN3R_CONTROL,
61 ARIZONA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
62
63SOC_DOUBLE_R("IN1 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_1L,
64 ARIZONA_ADC_DIGITAL_VOLUME_1R, ARIZONA_IN1L_MUTE_SHIFT, 1, 1),
65SOC_DOUBLE_R("IN2 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_2L,
66 ARIZONA_ADC_DIGITAL_VOLUME_2R, ARIZONA_IN2L_MUTE_SHIFT, 1, 1),
67SOC_DOUBLE_R("IN3 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_3L,
68 ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_MUTE_SHIFT, 1, 1),
69
70SOC_DOUBLE_R_TLV("IN1 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L,
71 ARIZONA_ADC_DIGITAL_VOLUME_1R, ARIZONA_IN1L_DIG_VOL_SHIFT,
72 0xbf, 0, digital_tlv),
73SOC_DOUBLE_R_TLV("IN2 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2L,
74 ARIZONA_ADC_DIGITAL_VOLUME_2R, ARIZONA_IN2L_DIG_VOL_SHIFT,
75 0xbf, 0, digital_tlv),
76SOC_DOUBLE_R_TLV("IN3 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_3L,
77 ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_DIG_VOL_SHIFT,
78 0xbf, 0, digital_tlv),
79
80ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE),
81ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
82ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
83ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
84
85SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
86 24, 0, eq_tlv),
87SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
88 24, 0, eq_tlv),
89SOC_SINGLE_TLV("EQ1 B3 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B3_GAIN_SHIFT,
90 24, 0, eq_tlv),
91SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT,
92 24, 0, eq_tlv),
93SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT,
94 24, 0, eq_tlv),
95
96SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT,
97 24, 0, eq_tlv),
98SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT,
99 24, 0, eq_tlv),
100SOC_SINGLE_TLV("EQ2 B3 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B3_GAIN_SHIFT,
101 24, 0, eq_tlv),
102SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT,
103 24, 0, eq_tlv),
104SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT,
105 24, 0, eq_tlv),
106
107SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT,
108 24, 0, eq_tlv),
109SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT,
110 24, 0, eq_tlv),
111SOC_SINGLE_TLV("EQ3 B3 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B3_GAIN_SHIFT,
112 24, 0, eq_tlv),
113SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT,
114 24, 0, eq_tlv),
115SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT,
116 24, 0, eq_tlv),
117
118SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT,
119 24, 0, eq_tlv),
120SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT,
121 24, 0, eq_tlv),
122SOC_SINGLE_TLV("EQ4 B3 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B3_GAIN_SHIFT,
123 24, 0, eq_tlv),
124SOC_SINGLE_TLV("EQ4 B4 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B4_GAIN_SHIFT,
125 24, 0, eq_tlv),
126SOC_SINGLE_TLV("EQ4 B5 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B5_GAIN_SHIFT,
127 24, 0, eq_tlv),
128
129ARIZONA_MIXER_CONTROLS("DRC1L", ARIZONA_DRC1LMIX_INPUT_1_SOURCE),
130ARIZONA_MIXER_CONTROLS("DRC1R", ARIZONA_DRC1RMIX_INPUT_1_SOURCE),
131
132SND_SOC_BYTES_MASK("DRC1", ARIZONA_DRC1_CTRL1, 5,
133 ARIZONA_DRC1R_ENA | ARIZONA_DRC1L_ENA),
134
135ARIZONA_MIXER_CONTROLS("LHPF1", ARIZONA_HPLP1MIX_INPUT_1_SOURCE),
136ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE),
137ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE),
138ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE),
139
140SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode),
141SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
142SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
143SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
144
145ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE),
146ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE),
147
148SOC_SINGLE_TLV("Noise Generator Volume", ARIZONA_COMFORT_NOISE_GENERATOR,
149 ARIZONA_NOISE_GEN_GAIN_SHIFT, 0x16, 0, noise_tlv),
150
151ARIZONA_MIXER_CONTROLS("HPOUT1L", ARIZONA_OUT1LMIX_INPUT_1_SOURCE),
152ARIZONA_MIXER_CONTROLS("HPOUT1R", ARIZONA_OUT1RMIX_INPUT_1_SOURCE),
153ARIZONA_MIXER_CONTROLS("HPOUT2L", ARIZONA_OUT2LMIX_INPUT_1_SOURCE),
154ARIZONA_MIXER_CONTROLS("HPOUT2R", ARIZONA_OUT2RMIX_INPUT_1_SOURCE),
155ARIZONA_MIXER_CONTROLS("EPOUT", ARIZONA_OUT3LMIX_INPUT_1_SOURCE),
156ARIZONA_MIXER_CONTROLS("SPKOUTL", ARIZONA_OUT4LMIX_INPUT_1_SOURCE),
157ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE),
158ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE),
159ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE),
160
161SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L,
162 ARIZONA_OUT1_OSR_SHIFT, 1, 0),
163SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
164 ARIZONA_OUT2_OSR_SHIFT, 1, 0),
165SOC_SINGLE("EPOUT High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
166 ARIZONA_OUT3_OSR_SHIFT, 1, 0),
167SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
168 ARIZONA_OUT4_OSR_SHIFT, 1, 0),
169SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
170 ARIZONA_OUT5_OSR_SHIFT, 1, 0),
171
172SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
173 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
174SOC_DOUBLE_R("OUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
175 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1),
176SOC_SINGLE("EPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
177 ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
178SOC_DOUBLE_R("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
179 ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
180SOC_DOUBLE_R("SPKDAT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L,
181 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_MUTE_SHIFT, 1, 1),
182
183SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
184 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_VOL_SHIFT,
185 0xbf, 0, digital_tlv),
186SOC_DOUBLE_R_TLV("OUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
187 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT,
188 0xbf, 0, digital_tlv),
189SOC_SINGLE_TLV("EPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
190 ARIZONA_OUT3L_VOL_SHIFT, 0xbf, 0, digital_tlv),
191SOC_DOUBLE_R_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
192 ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_VOL_SHIFT,
193 0xbf, 0, digital_tlv),
194SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L,
195 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT,
196 0xbf, 0, digital_tlv),
197
198SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L,
199 ARIZONA_OUTPUT_PATH_CONFIG_1R,
200 ARIZONA_OUT1L_PGA_VOL_SHIFT,
201 0x34, 0x40, 0, ana_tlv),
202SOC_DOUBLE_R_RANGE_TLV("OUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L,
203 ARIZONA_OUTPUT_PATH_CONFIG_2R,
204 ARIZONA_OUT2L_PGA_VOL_SHIFT,
205 0x34, 0x40, 0, ana_tlv),
206SOC_SINGLE_RANGE_TLV("EPOUT Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
207 ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
208
209SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
210 ARIZONA_SPK1R_MUTE_SHIFT, 1, 1),
211
212ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE),
213ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE),
214ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE),
215ARIZONA_MIXER_CONTROLS("AIF1TX4", ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE),
216ARIZONA_MIXER_CONTROLS("AIF1TX5", ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE),
217ARIZONA_MIXER_CONTROLS("AIF1TX6", ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE),
218ARIZONA_MIXER_CONTROLS("AIF1TX7", ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE),
219ARIZONA_MIXER_CONTROLS("AIF1TX8", ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE),
220
221ARIZONA_MIXER_CONTROLS("AIF2TX1", ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE),
222ARIZONA_MIXER_CONTROLS("AIF2TX2", ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE),
223
224ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
225ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
226};
227
228ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
229ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE);
230ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE);
231ARIZONA_MIXER_ENUMS(EQ4, ARIZONA_EQ4MIX_INPUT_1_SOURCE);
232
233ARIZONA_MIXER_ENUMS(DRC1L, ARIZONA_DRC1LMIX_INPUT_1_SOURCE);
234ARIZONA_MIXER_ENUMS(DRC1R, ARIZONA_DRC1RMIX_INPUT_1_SOURCE);
235
236ARIZONA_MIXER_ENUMS(LHPF1, ARIZONA_HPLP1MIX_INPUT_1_SOURCE);
237ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE);
238ARIZONA_MIXER_ENUMS(LHPF3, ARIZONA_HPLP3MIX_INPUT_1_SOURCE);
239ARIZONA_MIXER_ENUMS(LHPF4, ARIZONA_HPLP4MIX_INPUT_1_SOURCE);
240
241ARIZONA_MIXER_ENUMS(Mic, ARIZONA_MICMIX_INPUT_1_SOURCE);
242ARIZONA_MIXER_ENUMS(Noise, ARIZONA_NOISEMIX_INPUT_1_SOURCE);
243
244ARIZONA_MIXER_ENUMS(PWM1, ARIZONA_PWM1MIX_INPUT_1_SOURCE);
245ARIZONA_MIXER_ENUMS(PWM2, ARIZONA_PWM2MIX_INPUT_1_SOURCE);
246
247ARIZONA_MIXER_ENUMS(OUT1L, ARIZONA_OUT1LMIX_INPUT_1_SOURCE);
248ARIZONA_MIXER_ENUMS(OUT1R, ARIZONA_OUT1RMIX_INPUT_1_SOURCE);
249ARIZONA_MIXER_ENUMS(OUT2L, ARIZONA_OUT2LMIX_INPUT_1_SOURCE);
250ARIZONA_MIXER_ENUMS(OUT2R, ARIZONA_OUT2RMIX_INPUT_1_SOURCE);
251ARIZONA_MIXER_ENUMS(OUT3, ARIZONA_OUT3LMIX_INPUT_1_SOURCE);
252ARIZONA_MIXER_ENUMS(SPKOUTL, ARIZONA_OUT4LMIX_INPUT_1_SOURCE);
253ARIZONA_MIXER_ENUMS(SPKOUTR, ARIZONA_OUT4RMIX_INPUT_1_SOURCE);
254ARIZONA_MIXER_ENUMS(SPKDAT1L, ARIZONA_OUT5LMIX_INPUT_1_SOURCE);
255ARIZONA_MIXER_ENUMS(SPKDAT1R, ARIZONA_OUT5RMIX_INPUT_1_SOURCE);
256
257ARIZONA_MIXER_ENUMS(AIF1TX1, ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE);
258ARIZONA_MIXER_ENUMS(AIF1TX2, ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE);
259ARIZONA_MIXER_ENUMS(AIF1TX3, ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE);
260ARIZONA_MIXER_ENUMS(AIF1TX4, ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE);
261ARIZONA_MIXER_ENUMS(AIF1TX5, ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE);
262ARIZONA_MIXER_ENUMS(AIF1TX6, ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE);
263ARIZONA_MIXER_ENUMS(AIF1TX7, ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE);
264ARIZONA_MIXER_ENUMS(AIF1TX8, ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE);
265
266ARIZONA_MIXER_ENUMS(AIF2TX1, ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE);
267ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
268
269ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
270ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
271
272ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
273ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
274ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
275ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
276
277static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = {
278SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
279 0, NULL, 0),
280SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
281 ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
282
283SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
284SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
285SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
286SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0),
287SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0),
288SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0),
289
290SND_SOC_DAPM_SIGGEN("TONE"),
291SND_SOC_DAPM_SIGGEN("NOISE"),
292
293SND_SOC_DAPM_INPUT("IN1L"),
294SND_SOC_DAPM_INPUT("IN1R"),
295SND_SOC_DAPM_INPUT("IN2L"),
296SND_SOC_DAPM_INPUT("IN2R"),
297SND_SOC_DAPM_INPUT("IN3L"),
298SND_SOC_DAPM_INPUT("IN3R"),
299
300SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
301 0, NULL, 0, arizona_in_ev,
302 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
303SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
304 0, NULL, 0, arizona_in_ev,
305 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
306SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
307 0, NULL, 0, arizona_in_ev,
308 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
309SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
310 0, NULL, 0, arizona_in_ev,
311 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
312SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT,
313 0, NULL, 0, arizona_in_ev,
314 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
315SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
316 0, NULL, 0, arizona_in_ev,
317 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
318
319SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
320 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
321SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2,
322 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
323SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3,
324 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
325
326SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR,
327 ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0),
328
329SND_SOC_DAPM_PGA("Tone Generator 1", ARIZONA_TONE_GENERATOR_1,
330 ARIZONA_TONE1_ENA_SHIFT, 0, NULL, 0),
331SND_SOC_DAPM_PGA("Tone Generator 2", ARIZONA_TONE_GENERATOR_1,
332 ARIZONA_TONE2_ENA_SHIFT, 0, NULL, 0),
333
334SND_SOC_DAPM_PGA("Mic Mute Mixer", ARIZONA_MIC_NOISE_MIX_CONTROL_1,
335 ARIZONA_MICMUTE_MIX_ENA_SHIFT, 0, NULL, 0),
336
337SND_SOC_DAPM_PGA("EQ1", ARIZONA_EQ1_1, ARIZONA_EQ1_ENA_SHIFT, 0, NULL, 0),
338SND_SOC_DAPM_PGA("EQ2", ARIZONA_EQ2_1, ARIZONA_EQ2_ENA_SHIFT, 0, NULL, 0),
339SND_SOC_DAPM_PGA("EQ3", ARIZONA_EQ3_1, ARIZONA_EQ3_ENA_SHIFT, 0, NULL, 0),
340SND_SOC_DAPM_PGA("EQ4", ARIZONA_EQ4_1, ARIZONA_EQ4_ENA_SHIFT, 0, NULL, 0),
341
342SND_SOC_DAPM_PGA("DRC1L", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1L_ENA_SHIFT, 0,
343 NULL, 0),
344SND_SOC_DAPM_PGA("DRC1R", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1R_ENA_SHIFT, 0,
345 NULL, 0),
346
347SND_SOC_DAPM_PGA("LHPF1", ARIZONA_HPLPF1_1, ARIZONA_LHPF1_ENA_SHIFT, 0,
348 NULL, 0),
349SND_SOC_DAPM_PGA("LHPF2", ARIZONA_HPLPF2_1, ARIZONA_LHPF2_ENA_SHIFT, 0,
350 NULL, 0),
351SND_SOC_DAPM_PGA("LHPF3", ARIZONA_HPLPF3_1, ARIZONA_LHPF3_ENA_SHIFT, 0,
352 NULL, 0),
353SND_SOC_DAPM_PGA("LHPF4", ARIZONA_HPLPF4_1, ARIZONA_LHPF4_ENA_SHIFT, 0,
354 NULL, 0),
355
356SND_SOC_DAPM_PGA("PWM1 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM1_ENA_SHIFT,
357 0, NULL, 0),
358SND_SOC_DAPM_PGA("PWM2 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM2_ENA_SHIFT,
359 0, NULL, 0),
360
361SND_SOC_DAPM_PGA("ASRC1L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC1L_ENA_SHIFT, 0,
362 NULL, 0),
363SND_SOC_DAPM_PGA("ASRC1R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC1R_ENA_SHIFT, 0,
364 NULL, 0),
365SND_SOC_DAPM_PGA("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0,
366 NULL, 0),
367SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
368 NULL, 0),
369
370SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
371 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
372SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
373 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX2_ENA_SHIFT, 0),
374SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0,
375 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX3_ENA_SHIFT, 0),
376SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0,
377 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX4_ENA_SHIFT, 0),
378SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0,
379 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX5_ENA_SHIFT, 0),
380SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0,
381 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX6_ENA_SHIFT, 0),
382SND_SOC_DAPM_AIF_OUT("AIF1TX7", NULL, 0,
383 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX7_ENA_SHIFT, 0),
384SND_SOC_DAPM_AIF_OUT("AIF1TX8", NULL, 0,
385 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX8_ENA_SHIFT, 0),
386
387SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0,
388 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX1_ENA_SHIFT, 0),
389SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0,
390 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX2_ENA_SHIFT, 0),
391SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0,
392 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX3_ENA_SHIFT, 0),
393SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0,
394 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX4_ENA_SHIFT, 0),
395SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0,
396 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX5_ENA_SHIFT, 0),
397SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0,
398 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX6_ENA_SHIFT, 0),
399SND_SOC_DAPM_AIF_IN("AIF1RX7", NULL, 0,
400 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX7_ENA_SHIFT, 0),
401SND_SOC_DAPM_AIF_IN("AIF1RX8", NULL, 0,
402 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX8_ENA_SHIFT, 0),
403
404SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
405 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX1_ENA_SHIFT, 0),
406SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
407 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX2_ENA_SHIFT, 0),
408
409SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
410 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX1_ENA_SHIFT, 0),
411SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
412 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX2_ENA_SHIFT, 0),
413
414SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
415 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX1_ENA_SHIFT, 0),
416SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
417 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX2_ENA_SHIFT, 0),
418
419SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
420 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX1_ENA_SHIFT, 0),
421SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
422 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
423
424SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1,
425 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
426 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
427SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1,
428 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
429 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
430SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1,
431 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
432 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
433SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1,
434 ARIZONA_OUT2R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
435 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
436SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
437 ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
438 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
439SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1,
440 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
441 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
442SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1,
443 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
444 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
445SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
446 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
447 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
448SND_SOC_DAPM_PGA_E("OUT5R", ARIZONA_OUTPUT_ENABLES_1,
449 ARIZONA_OUT5R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
450 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
451
452ARIZONA_MIXER_WIDGETS(EQ1, "EQ1"),
453ARIZONA_MIXER_WIDGETS(EQ2, "EQ2"),
454ARIZONA_MIXER_WIDGETS(EQ3, "EQ3"),
455ARIZONA_MIXER_WIDGETS(EQ4, "EQ4"),
456
457ARIZONA_MIXER_WIDGETS(DRC1L, "DRC1L"),
458ARIZONA_MIXER_WIDGETS(DRC1R, "DRC1R"),
459
460ARIZONA_MIXER_WIDGETS(LHPF1, "LHPF1"),
461ARIZONA_MIXER_WIDGETS(LHPF2, "LHPF2"),
462ARIZONA_MIXER_WIDGETS(LHPF3, "LHPF3"),
463ARIZONA_MIXER_WIDGETS(LHPF4, "LHPF4"),
464
465ARIZONA_MIXER_WIDGETS(Mic, "Mic"),
466ARIZONA_MIXER_WIDGETS(Noise, "Noise"),
467
468ARIZONA_MIXER_WIDGETS(PWM1, "PWM1"),
469ARIZONA_MIXER_WIDGETS(PWM2, "PWM2"),
470
471ARIZONA_MIXER_WIDGETS(OUT1L, "HPOUT1L"),
472ARIZONA_MIXER_WIDGETS(OUT1R, "HPOUT1R"),
473ARIZONA_MIXER_WIDGETS(OUT2L, "HPOUT2L"),
474ARIZONA_MIXER_WIDGETS(OUT2R, "HPOUT2R"),
475ARIZONA_MIXER_WIDGETS(OUT3, "EPOUT"),
476ARIZONA_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"),
477ARIZONA_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"),
478ARIZONA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
479ARIZONA_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"),
480
481ARIZONA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
482ARIZONA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
483ARIZONA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
484ARIZONA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
485ARIZONA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
486ARIZONA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
487ARIZONA_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"),
488ARIZONA_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
489
490ARIZONA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
491ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
492
493ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
494ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
495
496ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"),
497ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"),
498ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"),
499ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"),
500
501SND_SOC_DAPM_OUTPUT("HPOUT1L"),
502SND_SOC_DAPM_OUTPUT("HPOUT1R"),
503SND_SOC_DAPM_OUTPUT("HPOUT2L"),
504SND_SOC_DAPM_OUTPUT("HPOUT2R"),
505SND_SOC_DAPM_OUTPUT("EPOUTN"),
506SND_SOC_DAPM_OUTPUT("EPOUTP"),
507SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
508SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
509SND_SOC_DAPM_OUTPUT("SPKOUTRN"),
510SND_SOC_DAPM_OUTPUT("SPKOUTRP"),
511SND_SOC_DAPM_OUTPUT("SPKDAT1L"),
512SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
513};
514
515#define ARIZONA_MIXER_INPUT_ROUTES(name) \
516 { name, "Noise Generator", "Noise Generator" }, \
517 { name, "Tone Generator 1", "Tone Generator 1" }, \
518 { name, "Tone Generator 2", "Tone Generator 2" }, \
519 { name, "IN1L", "IN1L PGA" }, \
520 { name, "IN1R", "IN1R PGA" }, \
521 { name, "IN2L", "IN2L PGA" }, \
522 { name, "IN2R", "IN2R PGA" }, \
523 { name, "IN3L", "IN3L PGA" }, \
524 { name, "IN3R", "IN3R PGA" }, \
525 { name, "Mic Mute Mixer", "Mic Mute Mixer" }, \
526 { name, "AIF1RX1", "AIF1RX1" }, \
527 { name, "AIF1RX2", "AIF1RX2" }, \
528 { name, "AIF1RX3", "AIF1RX3" }, \
529 { name, "AIF1RX4", "AIF1RX4" }, \
530 { name, "AIF1RX5", "AIF1RX5" }, \
531 { name, "AIF1RX6", "AIF1RX6" }, \
532 { name, "AIF1RX7", "AIF1RX7" }, \
533 { name, "AIF1RX8", "AIF1RX8" }, \
534 { name, "AIF2RX1", "AIF2RX1" }, \
535 { name, "AIF2RX2", "AIF2RX2" }, \
536 { name, "AIF3RX1", "AIF3RX1" }, \
537 { name, "AIF3RX2", "AIF3RX2" }, \
538 { name, "EQ1", "EQ1" }, \
539 { name, "EQ2", "EQ2" }, \
540 { name, "EQ3", "EQ3" }, \
541 { name, "EQ4", "EQ4" }, \
542 { name, "DRC1L", "DRC1L" }, \
543 { name, "DRC1R", "DRC1R" }, \
544 { name, "LHPF1", "LHPF1" }, \
545 { name, "LHPF2", "LHPF2" }, \
546 { name, "LHPF3", "LHPF3" }, \
547 { name, "LHPF4", "LHPF4" }, \
548 { name, "ASRC1L", "ASRC1L" }, \
549 { name, "ASRC1R", "ASRC1R" }, \
550 { name, "ASRC2L", "ASRC2L" }, \
551 { name, "ASRC2R", "ASRC2R" }
552
553static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
554 { "AIF2 Capture", NULL, "DBVDD2" },
555 { "AIF2 Playback", NULL, "DBVDD2" },
556
557 { "AIF3 Capture", NULL, "DBVDD3" },
558 { "AIF3 Playback", NULL, "DBVDD3" },
559
560 { "OUT1L", NULL, "CPVDD" },
561 { "OUT1R", NULL, "CPVDD" },
562 { "OUT2L", NULL, "CPVDD" },
563 { "OUT2R", NULL, "CPVDD" },
564 { "OUT3L", NULL, "CPVDD" },
565
566 { "OUT4L", NULL, "SPKVDDL" },
567 { "OUT4R", NULL, "SPKVDDR" },
568
569 { "OUT1L", NULL, "SYSCLK" },
570 { "OUT1R", NULL, "SYSCLK" },
571 { "OUT2L", NULL, "SYSCLK" },
572 { "OUT2R", NULL, "SYSCLK" },
573 { "OUT3L", NULL, "SYSCLK" },
574 { "OUT4L", NULL, "SYSCLK" },
575 { "OUT4R", NULL, "SYSCLK" },
576 { "OUT5L", NULL, "SYSCLK" },
577 { "OUT5R", NULL, "SYSCLK" },
578
579 { "MICBIAS1", NULL, "MICVDD" },
580 { "MICBIAS2", NULL, "MICVDD" },
581 { "MICBIAS3", NULL, "MICVDD" },
582
583 { "Noise Generator", NULL, "NOISE" },
584 { "Tone Generator 1", NULL, "TONE" },
585 { "Tone Generator 2", NULL, "TONE" },
586
587 { "Mic Mute Mixer", NULL, "Noise Mixer" },
588 { "Mic Mute Mixer", NULL, "Mic Mixer" },
589
590 { "AIF1 Capture", NULL, "AIF1TX1" },
591 { "AIF1 Capture", NULL, "AIF1TX2" },
592 { "AIF1 Capture", NULL, "AIF1TX3" },
593 { "AIF1 Capture", NULL, "AIF1TX4" },
594 { "AIF1 Capture", NULL, "AIF1TX5" },
595 { "AIF1 Capture", NULL, "AIF1TX6" },
596 { "AIF1 Capture", NULL, "AIF1TX7" },
597 { "AIF1 Capture", NULL, "AIF1TX8" },
598
599 { "AIF1RX1", NULL, "AIF1 Playback" },
600 { "AIF1RX2", NULL, "AIF1 Playback" },
601 { "AIF1RX3", NULL, "AIF1 Playback" },
602 { "AIF1RX4", NULL, "AIF1 Playback" },
603 { "AIF1RX5", NULL, "AIF1 Playback" },
604 { "AIF1RX6", NULL, "AIF1 Playback" },
605 { "AIF1RX7", NULL, "AIF1 Playback" },
606 { "AIF1RX8", NULL, "AIF1 Playback" },
607
608 { "AIF2 Capture", NULL, "AIF2TX1" },
609 { "AIF2 Capture", NULL, "AIF2TX2" },
610
611 { "AIF2RX1", NULL, "AIF2 Playback" },
612 { "AIF2RX2", NULL, "AIF2 Playback" },
613
614 { "AIF3 Capture", NULL, "AIF3TX1" },
615 { "AIF3 Capture", NULL, "AIF3TX2" },
616
617 { "AIF3RX1", NULL, "AIF3 Playback" },
618 { "AIF3RX2", NULL, "AIF3 Playback" },
619
620 { "AIF1 Playback", NULL, "SYSCLK" },
621 { "AIF2 Playback", NULL, "SYSCLK" },
622 { "AIF3 Playback", NULL, "SYSCLK" },
623
624 { "AIF1 Capture", NULL, "SYSCLK" },
625 { "AIF2 Capture", NULL, "SYSCLK" },
626 { "AIF3 Capture", NULL, "SYSCLK" },
627
628 { "IN1L PGA", NULL, "IN1L" },
629 { "IN1R PGA", NULL, "IN1R" },
630
631 { "IN2L PGA", NULL, "IN2L" },
632 { "IN2R PGA", NULL, "IN2R" },
633
634 { "IN3L PGA", NULL, "IN3L" },
635 { "IN3R PGA", NULL, "IN3R" },
636
637 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
638 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
639 ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
640 ARIZONA_MIXER_ROUTES("OUT2R", "HPOUT2R"),
641 ARIZONA_MIXER_ROUTES("OUT3L", "EPOUT"),
642
643 ARIZONA_MIXER_ROUTES("OUT4L", "SPKOUTL"),
644 ARIZONA_MIXER_ROUTES("OUT4R", "SPKOUTR"),
645 ARIZONA_MIXER_ROUTES("OUT5L", "SPKDAT1L"),
646 ARIZONA_MIXER_ROUTES("OUT5R", "SPKDAT1R"),
647
648 ARIZONA_MIXER_ROUTES("PWM1 Driver", "PWM1"),
649 ARIZONA_MIXER_ROUTES("PWM2 Driver", "PWM2"),
650
651 ARIZONA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
652 ARIZONA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
653 ARIZONA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
654 ARIZONA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
655 ARIZONA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
656 ARIZONA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
657 ARIZONA_MIXER_ROUTES("AIF1TX7", "AIF1TX7"),
658 ARIZONA_MIXER_ROUTES("AIF1TX8", "AIF1TX8"),
659
660 ARIZONA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
661 ARIZONA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
662
663 ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
664 ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
665
666 ARIZONA_MIXER_ROUTES("EQ1", "EQ1"),
667 ARIZONA_MIXER_ROUTES("EQ2", "EQ2"),
668 ARIZONA_MIXER_ROUTES("EQ3", "EQ3"),
669 ARIZONA_MIXER_ROUTES("EQ4", "EQ4"),
670
671 ARIZONA_MIXER_ROUTES("DRC1L", "DRC1L"),
672 ARIZONA_MIXER_ROUTES("DRC1R", "DRC1R"),
673
674 ARIZONA_MIXER_ROUTES("LHPF1", "LHPF1"),
675 ARIZONA_MIXER_ROUTES("LHPF2", "LHPF2"),
676 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
677 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
678
679 ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"),
680 ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"),
681 ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"),
682 ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"),
683
684 { "HPOUT1L", NULL, "OUT1L" },
685 { "HPOUT1R", NULL, "OUT1R" },
686
687 { "HPOUT2L", NULL, "OUT2L" },
688 { "HPOUT2R", NULL, "OUT2R" },
689
690 { "EPOUTN", NULL, "OUT3L" },
691 { "EPOUTP", NULL, "OUT3L" },
692
693 { "SPKOUTLN", NULL, "OUT4L" },
694 { "SPKOUTLP", NULL, "OUT4L" },
695
696 { "SPKOUTRN", NULL, "OUT4R" },
697 { "SPKOUTRP", NULL, "OUT4R" },
698
699 { "SPKDAT1L", NULL, "OUT5L" },
700 { "SPKDAT1R", NULL, "OUT5R" },
701};
702
703static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
704 unsigned int Fref, unsigned int Fout)
705{
706 struct wm5102_priv *wm5102 = snd_soc_codec_get_drvdata(codec);
707
708 switch (fll_id) {
709 case WM5102_FLL1:
710 return arizona_set_fll(&wm5102->fll[0], source, Fref, Fout);
711 case WM5102_FLL2:
712 return arizona_set_fll(&wm5102->fll[1], source, Fref, Fout);
713 default:
714 return -EINVAL;
715 }
716}
717
718#define WM5102_RATES SNDRV_PCM_RATE_8000_192000
719
720#define WM5102_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
721 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
722
723static struct snd_soc_dai_driver wm5102_dai[] = {
724 {
725 .name = "wm5102-aif1",
726 .id = 1,
727 .base = ARIZONA_AIF1_BCLK_CTRL,
728 .playback = {
729 .stream_name = "AIF1 Playback",
730 .channels_min = 1,
731 .channels_max = 8,
732 .rates = WM5102_RATES,
733 .formats = WM5102_FORMATS,
734 },
735 .capture = {
736 .stream_name = "AIF1 Capture",
737 .channels_min = 1,
738 .channels_max = 8,
739 .rates = WM5102_RATES,
740 .formats = WM5102_FORMATS,
741 },
742 .ops = &arizona_dai_ops,
743 .symmetric_rates = 1,
744 },
745 {
746 .name = "wm5102-aif2",
747 .id = 2,
748 .base = ARIZONA_AIF2_BCLK_CTRL,
749 .playback = {
750 .stream_name = "AIF2 Playback",
751 .channels_min = 1,
752 .channels_max = 2,
753 .rates = WM5102_RATES,
754 .formats = WM5102_FORMATS,
755 },
756 .capture = {
757 .stream_name = "AIF2 Capture",
758 .channels_min = 1,
759 .channels_max = 2,
760 .rates = WM5102_RATES,
761 .formats = WM5102_FORMATS,
762 },
763 .ops = &arizona_dai_ops,
764 .symmetric_rates = 1,
765 },
766 {
767 .name = "wm5102-aif3",
768 .id = 3,
769 .base = ARIZONA_AIF3_BCLK_CTRL,
770 .playback = {
771 .stream_name = "AIF3 Playback",
772 .channels_min = 1,
773 .channels_max = 2,
774 .rates = WM5102_RATES,
775 .formats = WM5102_FORMATS,
776 },
777 .capture = {
778 .stream_name = "AIF3 Capture",
779 .channels_min = 1,
780 .channels_max = 2,
781 .rates = WM5102_RATES,
782 .formats = WM5102_FORMATS,
783 },
784 .ops = &arizona_dai_ops,
785 .symmetric_rates = 1,
786 },
787};
788
789static int wm5102_codec_probe(struct snd_soc_codec *codec)
790{
791 struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
792
793 codec->control_data = priv->core.arizona->regmap;
794 return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
795}
796
797#define WM5102_DIG_VU 0x0200
798
799static unsigned int wm5102_digital_vu[] = {
800 ARIZONA_ADC_DIGITAL_VOLUME_1L,
801 ARIZONA_ADC_DIGITAL_VOLUME_1R,
802 ARIZONA_ADC_DIGITAL_VOLUME_2L,
803 ARIZONA_ADC_DIGITAL_VOLUME_2R,
804 ARIZONA_ADC_DIGITAL_VOLUME_3L,
805 ARIZONA_ADC_DIGITAL_VOLUME_3R,
806
807 ARIZONA_DAC_DIGITAL_VOLUME_1L,
808 ARIZONA_DAC_DIGITAL_VOLUME_1R,
809 ARIZONA_DAC_DIGITAL_VOLUME_2L,
810 ARIZONA_DAC_DIGITAL_VOLUME_2R,
811 ARIZONA_DAC_DIGITAL_VOLUME_3L,
812 ARIZONA_DAC_DIGITAL_VOLUME_3R,
813 ARIZONA_DAC_DIGITAL_VOLUME_4L,
814 ARIZONA_DAC_DIGITAL_VOLUME_4R,
815 ARIZONA_DAC_DIGITAL_VOLUME_5L,
816 ARIZONA_DAC_DIGITAL_VOLUME_5R,
817};
818
819static struct snd_soc_codec_driver soc_codec_dev_wm5102 = {
820 .probe = wm5102_codec_probe,
821
822 .idle_bias_off = true,
823
824 .set_sysclk = arizona_set_sysclk,
825 .set_pll = wm5102_set_fll,
826
827 .controls = wm5102_snd_controls,
828 .num_controls = ARRAY_SIZE(wm5102_snd_controls),
829 .dapm_widgets = wm5102_dapm_widgets,
830 .num_dapm_widgets = ARRAY_SIZE(wm5102_dapm_widgets),
831 .dapm_routes = wm5102_dapm_routes,
832 .num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes),
833};
834
835static int __devinit wm5102_probe(struct platform_device *pdev)
836{
837 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
838 struct wm5102_priv *wm5102;
839 int i;
840
841 wm5102 = devm_kzalloc(&pdev->dev, sizeof(struct wm5102_priv),
842 GFP_KERNEL);
843 if (wm5102 == NULL)
844 return -ENOMEM;
845 platform_set_drvdata(pdev, wm5102);
846
847 wm5102->core.arizona = arizona;
848
849 for (i = 0; i < ARRAY_SIZE(wm5102->fll); i++)
850 wm5102->fll[i].vco_mult = 1;
851
852 arizona_init_fll(arizona, 1, ARIZONA_FLL1_CONTROL_1 - 1,
853 ARIZONA_IRQ_FLL1_LOCK, ARIZONA_IRQ_FLL1_CLOCK_OK,
854 &wm5102->fll[0]);
855 arizona_init_fll(arizona, 2, ARIZONA_FLL2_CONTROL_1 - 1,
856 ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK,
857 &wm5102->fll[1]);
858
859 for (i = 0; i < ARRAY_SIZE(wm5102_dai); i++)
860 arizona_init_dai(&wm5102->core, i);
861
862 /* Latch volume update bits */
863 for (i = 0; i < ARRAY_SIZE(wm5102_digital_vu); i++)
864 regmap_update_bits(arizona->regmap, wm5102_digital_vu[i],
865 WM5102_DIG_VU, WM5102_DIG_VU);
866
867 pm_runtime_enable(&pdev->dev);
868 pm_runtime_idle(&pdev->dev);
869
870 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5102,
871 wm5102_dai, ARRAY_SIZE(wm5102_dai));
872}
873
874static int __devexit wm5102_remove(struct platform_device *pdev)
875{
876 snd_soc_unregister_codec(&pdev->dev);
877 pm_runtime_disable(&pdev->dev);
878
879 return 0;
880}
881
882static struct platform_driver wm5102_codec_driver = {
883 .driver = {
884 .name = "wm5102-codec",
885 .owner = THIS_MODULE,
886 },
887 .probe = wm5102_probe,
888 .remove = __devexit_p(wm5102_remove),
889};
890
891module_platform_driver(wm5102_codec_driver);
892
893MODULE_DESCRIPTION("ASoC WM5102 driver");
894MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
895MODULE_LICENSE("GPL");
896MODULE_ALIAS("platform:wm5102-codec");
diff --git a/sound/soc/codecs/wm5102.h b/sound/soc/codecs/wm5102.h
new file mode 100644
index 000000000000..d30477f3070c
--- /dev/null
+++ b/sound/soc/codecs/wm5102.h
@@ -0,0 +1,21 @@
1/*
2 * wm5102.h -- WM5102 ALSA SoC Audio driver
3 *
4 * Copyright 2012 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM5102_H
14#define _WM5102_H
15
16#include "arizona.h"
17
18#define WM5102_FLL1 1
19#define WM5102_FLL2 2
20
21#endif
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
new file mode 100644
index 000000000000..01ebbcc5c6a4
--- /dev/null
+++ b/sound/soc/codecs/wm5110.c
@@ -0,0 +1,962 @@
1/*
2 * wm5110.c -- WM5110 ALSA SoC Audio driver
3 *
4 * Copyright 2012 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/pm_runtime.h>
19#include <linux/regmap.h>
20#include <linux/slab.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/jack.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28
29#include <linux/mfd/arizona/core.h>
30#include <linux/mfd/arizona/registers.h>
31
32#include "arizona.h"
33#include "wm5110.h"
34
35struct wm5110_priv {
36 struct arizona_priv core;
37 struct arizona_fll fll[2];
38};
39
40static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
41static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
42static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
43static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0);
44
45static const struct snd_kcontrol_new wm5110_snd_controls[] = {
46SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL,
47 ARIZONA_IN1_OSR_SHIFT, 1, 0),
48SOC_SINGLE("IN2 High Performance Switch", ARIZONA_IN2L_CONTROL,
49 ARIZONA_IN2_OSR_SHIFT, 1, 0),
50SOC_SINGLE("IN3 High Performance Switch", ARIZONA_IN3L_CONTROL,
51 ARIZONA_IN3_OSR_SHIFT, 1, 0),
52SOC_SINGLE("IN4 High Performance Switch", ARIZONA_IN4L_CONTROL,
53 ARIZONA_IN4_OSR_SHIFT, 1, 0),
54
55SOC_DOUBLE_R_RANGE_TLV("IN1 Volume", ARIZONA_IN1L_CONTROL,
56 ARIZONA_IN1R_CONTROL,
57 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
58SOC_DOUBLE_R_RANGE_TLV("IN2 Volume", ARIZONA_IN2L_CONTROL,
59 ARIZONA_IN2R_CONTROL,
60 ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
61SOC_DOUBLE_R_RANGE_TLV("IN3 Volume", ARIZONA_IN3L_CONTROL,
62 ARIZONA_IN3R_CONTROL,
63 ARIZONA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
64
65SOC_DOUBLE_R("IN1 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_1L,
66 ARIZONA_ADC_DIGITAL_VOLUME_1R, ARIZONA_IN1L_MUTE_SHIFT, 1, 1),
67SOC_DOUBLE_R("IN2 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_2L,
68 ARIZONA_ADC_DIGITAL_VOLUME_2R, ARIZONA_IN2L_MUTE_SHIFT, 1, 1),
69SOC_DOUBLE_R("IN3 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_3L,
70 ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_MUTE_SHIFT, 1, 1),
71SOC_DOUBLE_R("IN4 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_4L,
72 ARIZONA_ADC_DIGITAL_VOLUME_4R, ARIZONA_IN4L_MUTE_SHIFT, 1, 1),
73
74SOC_DOUBLE_R_TLV("IN1 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L,
75 ARIZONA_ADC_DIGITAL_VOLUME_1R, ARIZONA_IN1L_DIG_VOL_SHIFT,
76 0xbf, 0, digital_tlv),
77SOC_DOUBLE_R_TLV("IN2 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2L,
78 ARIZONA_ADC_DIGITAL_VOLUME_2R, ARIZONA_IN2L_DIG_VOL_SHIFT,
79 0xbf, 0, digital_tlv),
80SOC_DOUBLE_R_TLV("IN3 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_3L,
81 ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_DIG_VOL_SHIFT,
82 0xbf, 0, digital_tlv),
83SOC_DOUBLE_R_TLV("IN4 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_4L,
84 ARIZONA_ADC_DIGITAL_VOLUME_4R, ARIZONA_IN4L_DIG_VOL_SHIFT,
85 0xbf, 0, digital_tlv),
86
87ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE),
88ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
89ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
90ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
91
92SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
93 24, 0, eq_tlv),
94SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
95 24, 0, eq_tlv),
96SOC_SINGLE_TLV("EQ1 B3 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B3_GAIN_SHIFT,
97 24, 0, eq_tlv),
98SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT,
99 24, 0, eq_tlv),
100SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT,
101 24, 0, eq_tlv),
102
103SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT,
104 24, 0, eq_tlv),
105SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT,
106 24, 0, eq_tlv),
107SOC_SINGLE_TLV("EQ2 B3 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B3_GAIN_SHIFT,
108 24, 0, eq_tlv),
109SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT,
110 24, 0, eq_tlv),
111SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT,
112 24, 0, eq_tlv),
113
114SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT,
115 24, 0, eq_tlv),
116SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT,
117 24, 0, eq_tlv),
118SOC_SINGLE_TLV("EQ3 B3 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B3_GAIN_SHIFT,
119 24, 0, eq_tlv),
120SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT,
121 24, 0, eq_tlv),
122SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT,
123 24, 0, eq_tlv),
124
125SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT,
126 24, 0, eq_tlv),
127SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT,
128 24, 0, eq_tlv),
129SOC_SINGLE_TLV("EQ4 B3 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B3_GAIN_SHIFT,
130 24, 0, eq_tlv),
131SOC_SINGLE_TLV("EQ4 B4 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B4_GAIN_SHIFT,
132 24, 0, eq_tlv),
133SOC_SINGLE_TLV("EQ4 B5 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B5_GAIN_SHIFT,
134 24, 0, eq_tlv),
135
136ARIZONA_MIXER_CONTROLS("DRC1L", ARIZONA_DRC1LMIX_INPUT_1_SOURCE),
137ARIZONA_MIXER_CONTROLS("DRC1R", ARIZONA_DRC1RMIX_INPUT_1_SOURCE),
138ARIZONA_MIXER_CONTROLS("DRC2L", ARIZONA_DRC2LMIX_INPUT_1_SOURCE),
139ARIZONA_MIXER_CONTROLS("DRC2R", ARIZONA_DRC2RMIX_INPUT_1_SOURCE),
140
141SND_SOC_BYTES_MASK("DRC1", ARIZONA_DRC1_CTRL1, 5,
142 ARIZONA_DRC1R_ENA | ARIZONA_DRC1L_ENA),
143SND_SOC_BYTES_MASK("DRC2", ARIZONA_DRC2_CTRL1, 5,
144 ARIZONA_DRC2R_ENA | ARIZONA_DRC2L_ENA),
145
146ARIZONA_MIXER_CONTROLS("LHPF1", ARIZONA_HPLP1MIX_INPUT_1_SOURCE),
147ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE),
148ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE),
149ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE),
150
151SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode),
152SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
153SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
154SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
155
156ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE),
157ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE),
158
159SOC_SINGLE_TLV("Noise Generator Volume", ARIZONA_COMFORT_NOISE_GENERATOR,
160 ARIZONA_NOISE_GEN_GAIN_SHIFT, 0x16, 0, noise_tlv),
161
162ARIZONA_MIXER_CONTROLS("HPOUT1L", ARIZONA_OUT1LMIX_INPUT_1_SOURCE),
163ARIZONA_MIXER_CONTROLS("HPOUT1R", ARIZONA_OUT1RMIX_INPUT_1_SOURCE),
164ARIZONA_MIXER_CONTROLS("HPOUT2L", ARIZONA_OUT2LMIX_INPUT_1_SOURCE),
165ARIZONA_MIXER_CONTROLS("HPOUT2R", ARIZONA_OUT2RMIX_INPUT_1_SOURCE),
166ARIZONA_MIXER_CONTROLS("EPOUT", ARIZONA_OUT3LMIX_INPUT_1_SOURCE),
167ARIZONA_MIXER_CONTROLS("SPKOUTL", ARIZONA_OUT4LMIX_INPUT_1_SOURCE),
168ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE),
169ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE),
170ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE),
171ARIZONA_MIXER_CONTROLS("SPKDAT2L", ARIZONA_OUT6LMIX_INPUT_1_SOURCE),
172ARIZONA_MIXER_CONTROLS("SPKDAT2R", ARIZONA_OUT6RMIX_INPUT_1_SOURCE),
173
174SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L,
175 ARIZONA_OUT1_OSR_SHIFT, 1, 0),
176SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
177 ARIZONA_OUT2_OSR_SHIFT, 1, 0),
178SOC_SINGLE("EPOUT High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
179 ARIZONA_OUT3_OSR_SHIFT, 1, 0),
180SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
181 ARIZONA_OUT4_OSR_SHIFT, 1, 0),
182SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
183 ARIZONA_OUT5_OSR_SHIFT, 1, 0),
184SOC_SINGLE("SPKDAT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_6L,
185 ARIZONA_OUT6_OSR_SHIFT, 1, 0),
186
187SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
188 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
189SOC_DOUBLE_R("OUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
190 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1),
191SOC_SINGLE("EPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
192 ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
193SOC_DOUBLE_R("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
194 ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
195SOC_DOUBLE_R("SPKDAT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L,
196 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_MUTE_SHIFT, 1, 1),
197SOC_DOUBLE_R("SPKDAT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_6L,
198 ARIZONA_DAC_DIGITAL_VOLUME_6R, ARIZONA_OUT6L_MUTE_SHIFT, 1, 1),
199
200SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
201 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_VOL_SHIFT,
202 0xbf, 0, digital_tlv),
203SOC_DOUBLE_R_TLV("OUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
204 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT,
205 0xbf, 0, digital_tlv),
206SOC_SINGLE_TLV("EPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
207 ARIZONA_OUT3L_VOL_SHIFT, 0xbf, 0, digital_tlv),
208SOC_DOUBLE_R_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
209 ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_VOL_SHIFT,
210 0xbf, 0, digital_tlv),
211SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L,
212 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT,
213 0xbf, 0, digital_tlv),
214SOC_DOUBLE_R_TLV("SPKDAT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_6L,
215 ARIZONA_DAC_DIGITAL_VOLUME_6R, ARIZONA_OUT6L_VOL_SHIFT,
216 0xbf, 0, digital_tlv),
217
218SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L,
219 ARIZONA_OUTPUT_PATH_CONFIG_1R,
220 ARIZONA_OUT1L_PGA_VOL_SHIFT,
221 0x34, 0x40, 0, ana_tlv),
222SOC_DOUBLE_R_RANGE_TLV("OUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L,
223 ARIZONA_OUTPUT_PATH_CONFIG_2R,
224 ARIZONA_OUT2L_PGA_VOL_SHIFT,
225 0x34, 0x40, 0, ana_tlv),
226SOC_SINGLE_RANGE_TLV("EPOUT Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
227 ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
228
229SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
230 ARIZONA_SPK1R_MUTE_SHIFT, 1, 1),
231SOC_DOUBLE("SPKDAT2 Switch", ARIZONA_PDM_SPK2_CTRL_1, ARIZONA_SPK2L_MUTE_SHIFT,
232 ARIZONA_SPK2R_MUTE_SHIFT, 1, 1),
233
234ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE),
235ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE),
236ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE),
237ARIZONA_MIXER_CONTROLS("AIF1TX4", ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE),
238ARIZONA_MIXER_CONTROLS("AIF1TX5", ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE),
239ARIZONA_MIXER_CONTROLS("AIF1TX6", ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE),
240ARIZONA_MIXER_CONTROLS("AIF1TX7", ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE),
241ARIZONA_MIXER_CONTROLS("AIF1TX8", ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE),
242
243ARIZONA_MIXER_CONTROLS("AIF2TX1", ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE),
244ARIZONA_MIXER_CONTROLS("AIF2TX2", ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE),
245
246ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
247ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
248};
249
250ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
251ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE);
252ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE);
253ARIZONA_MIXER_ENUMS(EQ4, ARIZONA_EQ4MIX_INPUT_1_SOURCE);
254
255ARIZONA_MIXER_ENUMS(DRC1L, ARIZONA_DRC1LMIX_INPUT_1_SOURCE);
256ARIZONA_MIXER_ENUMS(DRC1R, ARIZONA_DRC1RMIX_INPUT_1_SOURCE);
257ARIZONA_MIXER_ENUMS(DRC2L, ARIZONA_DRC2LMIX_INPUT_1_SOURCE);
258ARIZONA_MIXER_ENUMS(DRC2R, ARIZONA_DRC2RMIX_INPUT_1_SOURCE);
259
260ARIZONA_MIXER_ENUMS(LHPF1, ARIZONA_HPLP1MIX_INPUT_1_SOURCE);
261ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE);
262ARIZONA_MIXER_ENUMS(LHPF3, ARIZONA_HPLP3MIX_INPUT_1_SOURCE);
263ARIZONA_MIXER_ENUMS(LHPF4, ARIZONA_HPLP4MIX_INPUT_1_SOURCE);
264
265ARIZONA_MIXER_ENUMS(Mic, ARIZONA_MICMIX_INPUT_1_SOURCE);
266ARIZONA_MIXER_ENUMS(Noise, ARIZONA_NOISEMIX_INPUT_1_SOURCE);
267
268ARIZONA_MIXER_ENUMS(PWM1, ARIZONA_PWM1MIX_INPUT_1_SOURCE);
269ARIZONA_MIXER_ENUMS(PWM2, ARIZONA_PWM2MIX_INPUT_1_SOURCE);
270
271ARIZONA_MIXER_ENUMS(OUT1L, ARIZONA_OUT1LMIX_INPUT_1_SOURCE);
272ARIZONA_MIXER_ENUMS(OUT1R, ARIZONA_OUT1RMIX_INPUT_1_SOURCE);
273ARIZONA_MIXER_ENUMS(OUT2L, ARIZONA_OUT2LMIX_INPUT_1_SOURCE);
274ARIZONA_MIXER_ENUMS(OUT2R, ARIZONA_OUT2RMIX_INPUT_1_SOURCE);
275ARIZONA_MIXER_ENUMS(OUT3, ARIZONA_OUT3LMIX_INPUT_1_SOURCE);
276ARIZONA_MIXER_ENUMS(SPKOUTL, ARIZONA_OUT4LMIX_INPUT_1_SOURCE);
277ARIZONA_MIXER_ENUMS(SPKOUTR, ARIZONA_OUT4RMIX_INPUT_1_SOURCE);
278ARIZONA_MIXER_ENUMS(SPKDAT1L, ARIZONA_OUT5LMIX_INPUT_1_SOURCE);
279ARIZONA_MIXER_ENUMS(SPKDAT1R, ARIZONA_OUT5RMIX_INPUT_1_SOURCE);
280ARIZONA_MIXER_ENUMS(SPKDAT2L, ARIZONA_OUT6LMIX_INPUT_1_SOURCE);
281ARIZONA_MIXER_ENUMS(SPKDAT2R, ARIZONA_OUT6RMIX_INPUT_1_SOURCE);
282
283ARIZONA_MIXER_ENUMS(AIF1TX1, ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE);
284ARIZONA_MIXER_ENUMS(AIF1TX2, ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE);
285ARIZONA_MIXER_ENUMS(AIF1TX3, ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE);
286ARIZONA_MIXER_ENUMS(AIF1TX4, ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE);
287ARIZONA_MIXER_ENUMS(AIF1TX5, ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE);
288ARIZONA_MIXER_ENUMS(AIF1TX6, ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE);
289ARIZONA_MIXER_ENUMS(AIF1TX7, ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE);
290ARIZONA_MIXER_ENUMS(AIF1TX8, ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE);
291
292ARIZONA_MIXER_ENUMS(AIF2TX1, ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE);
293ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
294
295ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
296ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
297
298ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
299ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
300ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
301ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
302
303static const struct snd_soc_dapm_widget wm5110_dapm_widgets[] = {
304SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
305 0, NULL, 0),
306SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
307 ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
308
309SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
310SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
311SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
312SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0),
313SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0),
314SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0),
315
316SND_SOC_DAPM_SIGGEN("TONE"),
317SND_SOC_DAPM_SIGGEN("NOISE"),
318
319SND_SOC_DAPM_INPUT("IN1L"),
320SND_SOC_DAPM_INPUT("IN1R"),
321SND_SOC_DAPM_INPUT("IN2L"),
322SND_SOC_DAPM_INPUT("IN2R"),
323SND_SOC_DAPM_INPUT("IN3L"),
324SND_SOC_DAPM_INPUT("IN3R"),
325SND_SOC_DAPM_INPUT("IN4L"),
326SND_SOC_DAPM_INPUT("IN4R"),
327
328SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
329 0, NULL, 0, arizona_in_ev,
330 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
331SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
332 0, NULL, 0, arizona_in_ev,
333 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
334SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
335 0, NULL, 0, arizona_in_ev,
336 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
337SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
338 0, NULL, 0, arizona_in_ev,
339 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
340SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT,
341 0, NULL, 0, arizona_in_ev,
342 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
343SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
344 0, NULL, 0, arizona_in_ev,
345 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
346SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT,
347 0, NULL, 0, arizona_in_ev,
348 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
349SND_SOC_DAPM_PGA_E("IN4R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4R_ENA_SHIFT,
350 0, NULL, 0, arizona_in_ev,
351 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
352
353SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
354 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
355SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2,
356 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
357SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3,
358 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
359
360SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR,
361 ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0),
362
363SND_SOC_DAPM_PGA("Tone Generator 1", ARIZONA_TONE_GENERATOR_1,
364 ARIZONA_TONE1_ENA_SHIFT, 0, NULL, 0),
365SND_SOC_DAPM_PGA("Tone Generator 2", ARIZONA_TONE_GENERATOR_1,
366 ARIZONA_TONE2_ENA_SHIFT, 0, NULL, 0),
367
368SND_SOC_DAPM_PGA("Mic Mute Mixer", ARIZONA_MIC_NOISE_MIX_CONTROL_1,
369 ARIZONA_MICMUTE_MIX_ENA_SHIFT, 0, NULL, 0),
370
371SND_SOC_DAPM_PGA("EQ1", ARIZONA_EQ1_1, ARIZONA_EQ1_ENA_SHIFT, 0, NULL, 0),
372SND_SOC_DAPM_PGA("EQ2", ARIZONA_EQ2_1, ARIZONA_EQ2_ENA_SHIFT, 0, NULL, 0),
373SND_SOC_DAPM_PGA("EQ3", ARIZONA_EQ3_1, ARIZONA_EQ3_ENA_SHIFT, 0, NULL, 0),
374SND_SOC_DAPM_PGA("EQ4", ARIZONA_EQ4_1, ARIZONA_EQ4_ENA_SHIFT, 0, NULL, 0),
375
376SND_SOC_DAPM_PGA("DRC1L", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1L_ENA_SHIFT, 0,
377 NULL, 0),
378SND_SOC_DAPM_PGA("DRC1R", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1R_ENA_SHIFT, 0,
379 NULL, 0),
380SND_SOC_DAPM_PGA("DRC2L", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2L_ENA_SHIFT, 0,
381 NULL, 0),
382SND_SOC_DAPM_PGA("DRC2R", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2R_ENA_SHIFT, 0,
383 NULL, 0),
384
385SND_SOC_DAPM_PGA("LHPF1", ARIZONA_HPLPF1_1, ARIZONA_LHPF1_ENA_SHIFT, 0,
386 NULL, 0),
387SND_SOC_DAPM_PGA("LHPF2", ARIZONA_HPLPF2_1, ARIZONA_LHPF2_ENA_SHIFT, 0,
388 NULL, 0),
389SND_SOC_DAPM_PGA("LHPF3", ARIZONA_HPLPF3_1, ARIZONA_LHPF3_ENA_SHIFT, 0,
390 NULL, 0),
391SND_SOC_DAPM_PGA("LHPF4", ARIZONA_HPLPF4_1, ARIZONA_LHPF4_ENA_SHIFT, 0,
392 NULL, 0),
393
394SND_SOC_DAPM_PGA("PWM1 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM1_ENA_SHIFT,
395 0, NULL, 0),
396SND_SOC_DAPM_PGA("PWM2 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM2_ENA_SHIFT,
397 0, NULL, 0),
398
399SND_SOC_DAPM_PGA("ASRC1L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC1L_ENA_SHIFT, 0,
400 NULL, 0),
401SND_SOC_DAPM_PGA("ASRC1R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC1R_ENA_SHIFT, 0,
402 NULL, 0),
403SND_SOC_DAPM_PGA("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0,
404 NULL, 0),
405SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
406 NULL, 0),
407
408SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
409 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
410SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
411 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX2_ENA_SHIFT, 0),
412SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0,
413 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX3_ENA_SHIFT, 0),
414SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0,
415 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX4_ENA_SHIFT, 0),
416SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0,
417 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX5_ENA_SHIFT, 0),
418SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0,
419 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX6_ENA_SHIFT, 0),
420SND_SOC_DAPM_AIF_OUT("AIF1TX7", NULL, 0,
421 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX7_ENA_SHIFT, 0),
422SND_SOC_DAPM_AIF_OUT("AIF1TX8", NULL, 0,
423 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX8_ENA_SHIFT, 0),
424
425SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0,
426 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX1_ENA_SHIFT, 0),
427SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0,
428 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX2_ENA_SHIFT, 0),
429SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0,
430 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX3_ENA_SHIFT, 0),
431SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0,
432 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX4_ENA_SHIFT, 0),
433SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0,
434 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX5_ENA_SHIFT, 0),
435SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0,
436 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX6_ENA_SHIFT, 0),
437SND_SOC_DAPM_AIF_IN("AIF1RX7", NULL, 0,
438 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX7_ENA_SHIFT, 0),
439SND_SOC_DAPM_AIF_IN("AIF1RX8", NULL, 0,
440 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX8_ENA_SHIFT, 0),
441
442SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
443 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX1_ENA_SHIFT, 0),
444SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
445 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX2_ENA_SHIFT, 0),
446
447SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
448 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX1_ENA_SHIFT, 0),
449SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
450 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX2_ENA_SHIFT, 0),
451
452SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
453 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX1_ENA_SHIFT, 0),
454SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
455 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX2_ENA_SHIFT, 0),
456
457SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
458 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX1_ENA_SHIFT, 0),
459SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
460 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
461
462SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1,
463 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
464 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
465SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1,
466 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
467 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
468SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1,
469 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
470 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
471SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1,
472 ARIZONA_OUT2R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
473 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
474SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
475 ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
476 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
477SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1,
478 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
479 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
480SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1,
481 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
482 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
483SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
484 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
485 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
486SND_SOC_DAPM_PGA_E("OUT5R", ARIZONA_OUTPUT_ENABLES_1,
487 ARIZONA_OUT5R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
488 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
489SND_SOC_DAPM_PGA_E("OUT6L", ARIZONA_OUTPUT_ENABLES_1,
490 ARIZONA_OUT6L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
491 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
492SND_SOC_DAPM_PGA_E("OUT6R", ARIZONA_OUTPUT_ENABLES_1,
493 ARIZONA_OUT6R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
494 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
495
496ARIZONA_MIXER_WIDGETS(EQ1, "EQ1"),
497ARIZONA_MIXER_WIDGETS(EQ2, "EQ2"),
498ARIZONA_MIXER_WIDGETS(EQ3, "EQ3"),
499ARIZONA_MIXER_WIDGETS(EQ4, "EQ4"),
500
501ARIZONA_MIXER_WIDGETS(DRC1L, "DRC1L"),
502ARIZONA_MIXER_WIDGETS(DRC1R, "DRC1R"),
503ARIZONA_MIXER_WIDGETS(DRC2L, "DRC2L"),
504ARIZONA_MIXER_WIDGETS(DRC2R, "DRC2R"),
505
506ARIZONA_MIXER_WIDGETS(LHPF1, "LHPF1"),
507ARIZONA_MIXER_WIDGETS(LHPF2, "LHPF2"),
508ARIZONA_MIXER_WIDGETS(LHPF3, "LHPF3"),
509ARIZONA_MIXER_WIDGETS(LHPF4, "LHPF4"),
510
511ARIZONA_MIXER_WIDGETS(Mic, "Mic"),
512ARIZONA_MIXER_WIDGETS(Noise, "Noise"),
513
514ARIZONA_MIXER_WIDGETS(PWM1, "PWM1"),
515ARIZONA_MIXER_WIDGETS(PWM2, "PWM2"),
516
517ARIZONA_MIXER_WIDGETS(OUT1L, "HPOUT1L"),
518ARIZONA_MIXER_WIDGETS(OUT1R, "HPOUT1R"),
519ARIZONA_MIXER_WIDGETS(OUT2L, "HPOUT2L"),
520ARIZONA_MIXER_WIDGETS(OUT2R, "HPOUT2R"),
521ARIZONA_MIXER_WIDGETS(OUT3, "EPOUT"),
522ARIZONA_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"),
523ARIZONA_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"),
524ARIZONA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
525ARIZONA_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"),
526ARIZONA_MIXER_WIDGETS(SPKDAT2L, "SPKDAT2L"),
527ARIZONA_MIXER_WIDGETS(SPKDAT2R, "SPKDAT2R"),
528
529ARIZONA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
530ARIZONA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
531ARIZONA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
532ARIZONA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
533ARIZONA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
534ARIZONA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
535ARIZONA_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"),
536ARIZONA_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
537
538ARIZONA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
539ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
540
541ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
542ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
543
544ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"),
545ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"),
546ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"),
547ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"),
548
549SND_SOC_DAPM_OUTPUT("HPOUT1L"),
550SND_SOC_DAPM_OUTPUT("HPOUT1R"),
551SND_SOC_DAPM_OUTPUT("HPOUT2L"),
552SND_SOC_DAPM_OUTPUT("HPOUT2R"),
553SND_SOC_DAPM_OUTPUT("EPOUTN"),
554SND_SOC_DAPM_OUTPUT("EPOUTP"),
555SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
556SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
557SND_SOC_DAPM_OUTPUT("SPKOUTRN"),
558SND_SOC_DAPM_OUTPUT("SPKOUTRP"),
559SND_SOC_DAPM_OUTPUT("SPKDAT1L"),
560SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
561SND_SOC_DAPM_OUTPUT("SPKDAT2L"),
562SND_SOC_DAPM_OUTPUT("SPKDAT2R"),
563};
564
565#define ARIZONA_MIXER_INPUT_ROUTES(name) \
566 { name, "Noise Generator", "Noise Generator" }, \
567 { name, "Tone Generator 1", "Tone Generator 1" }, \
568 { name, "Tone Generator 2", "Tone Generator 2" }, \
569 { name, "IN1L", "IN1L PGA" }, \
570 { name, "IN1R", "IN1R PGA" }, \
571 { name, "IN2L", "IN2L PGA" }, \
572 { name, "IN2R", "IN2R PGA" }, \
573 { name, "IN3L", "IN3L PGA" }, \
574 { name, "IN3R", "IN3R PGA" }, \
575 { name, "IN4L", "IN4L PGA" }, \
576 { name, "IN4R", "IN4R PGA" }, \
577 { name, "Mic Mute Mixer", "Mic Mute Mixer" }, \
578 { name, "AIF1RX1", "AIF1RX1" }, \
579 { name, "AIF1RX2", "AIF1RX2" }, \
580 { name, "AIF1RX3", "AIF1RX3" }, \
581 { name, "AIF1RX4", "AIF1RX4" }, \
582 { name, "AIF1RX5", "AIF1RX5" }, \
583 { name, "AIF1RX6", "AIF1RX6" }, \
584 { name, "AIF1RX7", "AIF1RX7" }, \
585 { name, "AIF1RX8", "AIF1RX8" }, \
586 { name, "AIF2RX1", "AIF2RX1" }, \
587 { name, "AIF2RX2", "AIF2RX2" }, \
588 { name, "AIF3RX1", "AIF3RX1" }, \
589 { name, "AIF3RX2", "AIF3RX2" }, \
590 { name, "EQ1", "EQ1" }, \
591 { name, "EQ2", "EQ2" }, \
592 { name, "EQ3", "EQ3" }, \
593 { name, "EQ4", "EQ4" }, \
594 { name, "DRC1L", "DRC1L" }, \
595 { name, "DRC1R", "DRC1R" }, \
596 { name, "DRC2L", "DRC2L" }, \
597 { name, "DRC2R", "DRC2R" }, \
598 { name, "LHPF1", "LHPF1" }, \
599 { name, "LHPF2", "LHPF2" }, \
600 { name, "LHPF3", "LHPF3" }, \
601 { name, "LHPF4", "LHPF4" }, \
602 { name, "ASRC1L", "ASRC1L" }, \
603 { name, "ASRC1R", "ASRC1R" }, \
604 { name, "ASRC2L", "ASRC2L" }, \
605 { name, "ASRC2R", "ASRC2R" }
606
607static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
608 { "AIF2 Capture", NULL, "DBVDD2" },
609 { "AIF2 Playback", NULL, "DBVDD2" },
610
611 { "AIF3 Capture", NULL, "DBVDD3" },
612 { "AIF3 Playback", NULL, "DBVDD3" },
613
614 { "OUT1L", NULL, "CPVDD" },
615 { "OUT1R", NULL, "CPVDD" },
616 { "OUT2L", NULL, "CPVDD" },
617 { "OUT2R", NULL, "CPVDD" },
618 { "OUT3L", NULL, "CPVDD" },
619
620 { "OUT4L", NULL, "SPKVDDL" },
621 { "OUT4R", NULL, "SPKVDDR" },
622
623 { "OUT1L", NULL, "SYSCLK" },
624 { "OUT1R", NULL, "SYSCLK" },
625 { "OUT2L", NULL, "SYSCLK" },
626 { "OUT2R", NULL, "SYSCLK" },
627 { "OUT3L", NULL, "SYSCLK" },
628 { "OUT4L", NULL, "SYSCLK" },
629 { "OUT4R", NULL, "SYSCLK" },
630 { "OUT5L", NULL, "SYSCLK" },
631 { "OUT5R", NULL, "SYSCLK" },
632 { "OUT6L", NULL, "SYSCLK" },
633 { "OUT6R", NULL, "SYSCLK" },
634
635 { "MICBIAS1", NULL, "MICVDD" },
636 { "MICBIAS2", NULL, "MICVDD" },
637 { "MICBIAS3", NULL, "MICVDD" },
638
639 { "Noise Generator", NULL, "NOISE" },
640 { "Tone Generator 1", NULL, "TONE" },
641 { "Tone Generator 2", NULL, "TONE" },
642
643 { "Mic Mute Mixer", NULL, "Noise Mixer" },
644 { "Mic Mute Mixer", NULL, "Mic Mixer" },
645
646 { "AIF1 Capture", NULL, "AIF1TX1" },
647 { "AIF1 Capture", NULL, "AIF1TX2" },
648 { "AIF1 Capture", NULL, "AIF1TX3" },
649 { "AIF1 Capture", NULL, "AIF1TX4" },
650 { "AIF1 Capture", NULL, "AIF1TX5" },
651 { "AIF1 Capture", NULL, "AIF1TX6" },
652 { "AIF1 Capture", NULL, "AIF1TX7" },
653 { "AIF1 Capture", NULL, "AIF1TX8" },
654
655 { "AIF1RX1", NULL, "AIF1 Playback" },
656 { "AIF1RX2", NULL, "AIF1 Playback" },
657 { "AIF1RX3", NULL, "AIF1 Playback" },
658 { "AIF1RX4", NULL, "AIF1 Playback" },
659 { "AIF1RX5", NULL, "AIF1 Playback" },
660 { "AIF1RX6", NULL, "AIF1 Playback" },
661 { "AIF1RX7", NULL, "AIF1 Playback" },
662 { "AIF1RX8", NULL, "AIF1 Playback" },
663
664 { "AIF2 Capture", NULL, "AIF2TX1" },
665 { "AIF2 Capture", NULL, "AIF2TX2" },
666
667 { "AIF2RX1", NULL, "AIF2 Playback" },
668 { "AIF2RX2", NULL, "AIF2 Playback" },
669
670 { "AIF3 Capture", NULL, "AIF3TX1" },
671 { "AIF3 Capture", NULL, "AIF3TX2" },
672
673 { "AIF3RX1", NULL, "AIF3 Playback" },
674 { "AIF3RX2", NULL, "AIF3 Playback" },
675
676 { "AIF1 Playback", NULL, "SYSCLK" },
677 { "AIF2 Playback", NULL, "SYSCLK" },
678 { "AIF3 Playback", NULL, "SYSCLK" },
679
680 { "AIF1 Capture", NULL, "SYSCLK" },
681 { "AIF2 Capture", NULL, "SYSCLK" },
682 { "AIF3 Capture", NULL, "SYSCLK" },
683
684 { "IN1L PGA", NULL, "IN1L" },
685 { "IN1R PGA", NULL, "IN1R" },
686
687 { "IN2L PGA", NULL, "IN2L" },
688 { "IN2R PGA", NULL, "IN2R" },
689
690 { "IN3L PGA", NULL, "IN3L" },
691 { "IN3R PGA", NULL, "IN3R" },
692
693 { "IN4L PGA", NULL, "IN4L" },
694 { "IN4R PGA", NULL, "IN4R" },
695
696 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
697 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
698 ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
699 ARIZONA_MIXER_ROUTES("OUT2R", "HPOUT2R"),
700 ARIZONA_MIXER_ROUTES("OUT3L", "EPOUT"),
701
702 ARIZONA_MIXER_ROUTES("OUT4L", "SPKOUTL"),
703 ARIZONA_MIXER_ROUTES("OUT4R", "SPKOUTR"),
704 ARIZONA_MIXER_ROUTES("OUT5L", "SPKDAT1L"),
705 ARIZONA_MIXER_ROUTES("OUT5R", "SPKDAT1R"),
706 ARIZONA_MIXER_ROUTES("OUT6L", "SPKDAT2L"),
707 ARIZONA_MIXER_ROUTES("OUT6R", "SPKDAT2R"),
708
709 ARIZONA_MIXER_ROUTES("PWM1 Driver", "PWM1"),
710 ARIZONA_MIXER_ROUTES("PWM2 Driver", "PWM2"),
711
712 ARIZONA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
713 ARIZONA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
714 ARIZONA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
715 ARIZONA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
716 ARIZONA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
717 ARIZONA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
718 ARIZONA_MIXER_ROUTES("AIF1TX7", "AIF1TX7"),
719 ARIZONA_MIXER_ROUTES("AIF1TX8", "AIF1TX8"),
720
721 ARIZONA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
722 ARIZONA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
723
724 ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
725 ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
726
727 ARIZONA_MIXER_ROUTES("EQ1", "EQ1"),
728 ARIZONA_MIXER_ROUTES("EQ2", "EQ2"),
729 ARIZONA_MIXER_ROUTES("EQ3", "EQ3"),
730 ARIZONA_MIXER_ROUTES("EQ4", "EQ4"),
731
732 ARIZONA_MIXER_ROUTES("DRC1L", "DRC1L"),
733 ARIZONA_MIXER_ROUTES("DRC1R", "DRC1R"),
734 ARIZONA_MIXER_ROUTES("DRC2L", "DRC2L"),
735 ARIZONA_MIXER_ROUTES("DRC2R", "DRC2R"),
736
737 ARIZONA_MIXER_ROUTES("LHPF1", "LHPF1"),
738 ARIZONA_MIXER_ROUTES("LHPF2", "LHPF2"),
739 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
740 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
741
742 ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"),
743 ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"),
744 ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"),
745 ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"),
746
747 { "HPOUT1L", NULL, "OUT1L" },
748 { "HPOUT1R", NULL, "OUT1R" },
749
750 { "HPOUT2L", NULL, "OUT2L" },
751 { "HPOUT2R", NULL, "OUT2R" },
752
753 { "EPOUTN", NULL, "OUT3L" },
754 { "EPOUTP", NULL, "OUT3L" },
755
756 { "SPKOUTLN", NULL, "OUT4L" },
757 { "SPKOUTLP", NULL, "OUT4L" },
758
759 { "SPKOUTRN", NULL, "OUT4R" },
760 { "SPKOUTRP", NULL, "OUT4R" },
761
762 { "SPKDAT1L", NULL, "OUT5L" },
763 { "SPKDAT1R", NULL, "OUT5R" },
764
765 { "SPKDAT2L", NULL, "OUT6L" },
766 { "SPKDAT2R", NULL, "OUT6R" },
767};
768
769static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
770 unsigned int Fref, unsigned int Fout)
771{
772 struct wm5110_priv *wm5110 = snd_soc_codec_get_drvdata(codec);
773
774 switch (fll_id) {
775 case WM5110_FLL1:
776 return arizona_set_fll(&wm5110->fll[0], source, Fref, Fout);
777 case WM5110_FLL2:
778 return arizona_set_fll(&wm5110->fll[1], source, Fref, Fout);
779 default:
780 return -EINVAL;
781 }
782}
783
784#define WM5110_RATES SNDRV_PCM_RATE_8000_192000
785
786#define WM5110_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
787 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
788
789static struct snd_soc_dai_driver wm5110_dai[] = {
790 {
791 .name = "wm5110-aif1",
792 .id = 1,
793 .base = ARIZONA_AIF1_BCLK_CTRL,
794 .playback = {
795 .stream_name = "AIF1 Playback",
796 .channels_min = 1,
797 .channels_max = 8,
798 .rates = WM5110_RATES,
799 .formats = WM5110_FORMATS,
800 },
801 .capture = {
802 .stream_name = "AIF1 Capture",
803 .channels_min = 1,
804 .channels_max = 8,
805 .rates = WM5110_RATES,
806 .formats = WM5110_FORMATS,
807 },
808 .ops = &arizona_dai_ops,
809 .symmetric_rates = 1,
810 },
811 {
812 .name = "wm5110-aif2",
813 .id = 2,
814 .base = ARIZONA_AIF2_BCLK_CTRL,
815 .playback = {
816 .stream_name = "AIF2 Playback",
817 .channels_min = 1,
818 .channels_max = 2,
819 .rates = WM5110_RATES,
820 .formats = WM5110_FORMATS,
821 },
822 .capture = {
823 .stream_name = "AIF2 Capture",
824 .channels_min = 1,
825 .channels_max = 2,
826 .rates = WM5110_RATES,
827 .formats = WM5110_FORMATS,
828 },
829 .ops = &arizona_dai_ops,
830 .symmetric_rates = 1,
831 },
832 {
833 .name = "wm5110-aif3",
834 .id = 3,
835 .base = ARIZONA_AIF3_BCLK_CTRL,
836 .playback = {
837 .stream_name = "AIF3 Playback",
838 .channels_min = 1,
839 .channels_max = 2,
840 .rates = WM5110_RATES,
841 .formats = WM5110_FORMATS,
842 },
843 .capture = {
844 .stream_name = "AIF3 Capture",
845 .channels_min = 1,
846 .channels_max = 2,
847 .rates = WM5110_RATES,
848 .formats = WM5110_FORMATS,
849 },
850 .ops = &arizona_dai_ops,
851 .symmetric_rates = 1,
852 },
853};
854
855static int wm5110_codec_probe(struct snd_soc_codec *codec)
856{
857 struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
858
859 codec->control_data = priv->core.arizona->regmap;
860 return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
861}
862
863#define WM5110_DIG_VU 0x0200
864
865static unsigned int wm5110_digital_vu[] = {
866 ARIZONA_ADC_DIGITAL_VOLUME_1L,
867 ARIZONA_ADC_DIGITAL_VOLUME_1R,
868 ARIZONA_ADC_DIGITAL_VOLUME_2L,
869 ARIZONA_ADC_DIGITAL_VOLUME_2R,
870 ARIZONA_ADC_DIGITAL_VOLUME_3L,
871 ARIZONA_ADC_DIGITAL_VOLUME_3R,
872
873 ARIZONA_DAC_DIGITAL_VOLUME_1L,
874 ARIZONA_DAC_DIGITAL_VOLUME_1R,
875 ARIZONA_DAC_DIGITAL_VOLUME_2L,
876 ARIZONA_DAC_DIGITAL_VOLUME_2R,
877 ARIZONA_DAC_DIGITAL_VOLUME_3L,
878 ARIZONA_DAC_DIGITAL_VOLUME_3R,
879 ARIZONA_DAC_DIGITAL_VOLUME_4L,
880 ARIZONA_DAC_DIGITAL_VOLUME_4R,
881 ARIZONA_DAC_DIGITAL_VOLUME_5L,
882 ARIZONA_DAC_DIGITAL_VOLUME_5R,
883};
884
885static struct snd_soc_codec_driver soc_codec_dev_wm5110 = {
886 .probe = wm5110_codec_probe,
887
888 .idle_bias_off = true,
889
890 .set_sysclk = arizona_set_sysclk,
891 .set_pll = wm5110_set_fll,
892
893 .controls = wm5110_snd_controls,
894 .num_controls = ARRAY_SIZE(wm5110_snd_controls),
895 .dapm_widgets = wm5110_dapm_widgets,
896 .num_dapm_widgets = ARRAY_SIZE(wm5110_dapm_widgets),
897 .dapm_routes = wm5110_dapm_routes,
898 .num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes),
899};
900
901static int __devinit wm5110_probe(struct platform_device *pdev)
902{
903 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
904 struct wm5110_priv *wm5110;
905 int i;
906
907 wm5110 = devm_kzalloc(&pdev->dev, sizeof(struct wm5110_priv),
908 GFP_KERNEL);
909 if (wm5110 == NULL)
910 return -ENOMEM;
911 platform_set_drvdata(pdev, wm5110);
912
913 wm5110->core.arizona = arizona;
914
915 for (i = 0; i < ARRAY_SIZE(wm5110->fll); i++)
916 wm5110->fll[i].vco_mult = 3;
917
918 arizona_init_fll(arizona, 1, ARIZONA_FLL1_CONTROL_1 - 1,
919 ARIZONA_IRQ_FLL1_LOCK, ARIZONA_IRQ_FLL1_CLOCK_OK,
920 &wm5110->fll[0]);
921 arizona_init_fll(arizona, 2, ARIZONA_FLL2_CONTROL_1 - 1,
922 ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK,
923 &wm5110->fll[1]);
924
925 for (i = 0; i < ARRAY_SIZE(wm5110_dai); i++)
926 arizona_init_dai(&wm5110->core, i);
927
928 /* Latch volume update bits */
929 for (i = 0; i < ARRAY_SIZE(wm5110_digital_vu); i++)
930 regmap_update_bits(arizona->regmap, wm5110_digital_vu[i],
931 WM5110_DIG_VU, WM5110_DIG_VU);
932
933 pm_runtime_enable(&pdev->dev);
934 pm_runtime_idle(&pdev->dev);
935
936 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5110,
937 wm5110_dai, ARRAY_SIZE(wm5110_dai));
938}
939
940static int __devexit wm5110_remove(struct platform_device *pdev)
941{
942 snd_soc_unregister_codec(&pdev->dev);
943 pm_runtime_disable(&pdev->dev);
944
945 return 0;
946}
947
948static struct platform_driver wm5110_codec_driver = {
949 .driver = {
950 .name = "wm5110-codec",
951 .owner = THIS_MODULE,
952 },
953 .probe = wm5110_probe,
954 .remove = __devexit_p(wm5110_remove),
955};
956
957module_platform_driver(wm5110_codec_driver);
958
959MODULE_DESCRIPTION("ASoC WM5110 driver");
960MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
961MODULE_LICENSE("GPL");
962MODULE_ALIAS("platform:wm5110-codec");
diff --git a/sound/soc/codecs/wm5110.h b/sound/soc/codecs/wm5110.h
new file mode 100644
index 000000000000..75e9351ccab0
--- /dev/null
+++ b/sound/soc/codecs/wm5110.h
@@ -0,0 +1,21 @@
1/*
2 * wm5110.h -- WM5110 ALSA SoC Audio driver
3 *
4 * Copyright 2012 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM5110_H
14#define _WM5110_H
15
16#include "arizona.h"
17
18#define WM5110_FLL1 1
19#define WM5110_FLL2 2
20
21#endif
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 555ee146ae0d..a4cae060bf26 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8350.c -- WM8350 ALSA SoC audio driver 2 * wm8350.c -- WM8350 ALSA SoC audio driver
3 * 3 *
4 * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC. 4 * Copyright (C) 2007-12 Wolfson Microelectronics PLC.
5 * 5 *
6 * Author: Liam Girdwood <lrg@slimlogic.co.uk> 6 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
7 * 7 *
@@ -71,20 +71,6 @@ struct wm8350_data {
71 int fll_freq_in; 71 int fll_freq_in;
72}; 72};
73 73
74static unsigned int wm8350_codec_read(struct snd_soc_codec *codec,
75 unsigned int reg)
76{
77 struct wm8350 *wm8350 = codec->control_data;
78 return wm8350_reg_read(wm8350, reg);
79}
80
81static int wm8350_codec_write(struct snd_soc_codec *codec, unsigned int reg,
82 unsigned int value)
83{
84 struct wm8350 *wm8350 = codec->control_data;
85 return wm8350_reg_write(wm8350, reg, value);
86}
87
88/* 74/*
89 * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown. 75 * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown.
90 */ 76 */
@@ -1519,7 +1505,9 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec)
1519 if (ret != 0) 1505 if (ret != 0)
1520 return ret; 1506 return ret;
1521 1507
1522 codec->control_data = wm8350; 1508 codec->control_data = wm8350->regmap;
1509
1510 snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
1523 1511
1524 /* Put the codec into reset if it wasn't already */ 1512 /* Put the codec into reset if it wasn't already */
1525 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1513 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
@@ -1613,7 +1601,7 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec)
1613 1601
1614 /* if there was any work waiting then we run it now and 1602 /* if there was any work waiting then we run it now and
1615 * wait for its completion */ 1603 * wait for its completion */
1616 flush_delayed_work_sync(&codec->dapm.delayed_work); 1604 flush_delayed_work(&codec->dapm.delayed_work);
1617 1605
1618 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); 1606 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
1619 1607
@@ -1629,8 +1617,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8350 = {
1629 .remove = wm8350_codec_remove, 1617 .remove = wm8350_codec_remove,
1630 .suspend = wm8350_suspend, 1618 .suspend = wm8350_suspend,
1631 .resume = wm8350_resume, 1619 .resume = wm8350_resume,
1632 .read = wm8350_codec_read,
1633 .write = wm8350_codec_write,
1634 .set_bias_level = wm8350_set_bias_level, 1620 .set_bias_level = wm8350_set_bias_level,
1635 1621
1636 .controls = wm8350_snd_controls, 1622 .controls = wm8350_snd_controls,
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 5dc31ebcd0e7..5d277a915f81 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8400.c -- WM8400 ALSA Soc Audio driver 2 * wm8400.c -- WM8400 ALSA Soc Audio driver
3 * 3 *
4 * Copyright 2008, 2009 Wolfson Microelectronics PLC. 4 * Copyright 2008-11 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 211285164d70..7c68226376e4 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8580.c -- WM8580 ALSA Soc Audio driver 2 * wm8580.c -- WM8580 ALSA Soc Audio driver
3 * 3 *
4 * Copyright 2008, 2009 Wolfson Microelectronics PLC. 4 * Copyright 2008-11 Wolfson Microelectronics PLC.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 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 7 * under the terms of the GNU General Public License as published by the
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 9d1b9b0271f1..bb1d26919b10 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -2,6 +2,7 @@
2 * wm8731.c -- WM8731 ALSA SoC Audio driver 2 * wm8731.c -- WM8731 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2005 Openedhand Ltd. 4 * Copyright 2005 Openedhand Ltd.
5 * Copyright 2006-12 Wolfson Microelectronics, plc
5 * 6 *
6 * Author: Richard Purdie <richard@openedhand.com> 7 * Author: Richard Purdie <richard@openedhand.com>
7 * 8 *
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 6e849cb04243..35f3d23200e0 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8741.c -- WM8741 ALSA SoC Audio driver 2 * wm8741.c -- WM8741 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2010 Wolfson Microelectronics plc 4 * Copyright 2010-1 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Ian Lartey <ian@opensource.wolfsonmicro.com> 6 * Author: Ian Lartey <ian@opensource.wolfsonmicro.com>
7 * 7 *
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index a26482cd7654..2e4a775ae560 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8753.c -- WM8753 ALSA Soc Audio driver 2 * wm8753.c -- WM8753 ALSA Soc Audio driver
3 * 3 *
4 * Copyright 2003 Wolfson Microelectronics PLC. 4 * Copyright 2003-11 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood <lrg@slimlogic.co.uk> 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
@@ -1509,7 +1509,7 @@ static int wm8753_probe(struct snd_soc_codec *codec)
1509/* power down chip */ 1509/* power down chip */
1510static int wm8753_remove(struct snd_soc_codec *codec) 1510static int wm8753_remove(struct snd_soc_codec *codec)
1511{ 1511{
1512 flush_delayed_work_sync(&codec->dapm.delayed_work); 1512 flush_delayed_work(&codec->dapm.delayed_work);
1513 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); 1513 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1514 1514
1515 return 0; 1515 return 0;
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index a19db5a0a17a..879c356a9045 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8776.c -- WM8776 ALSA SoC Audio driver 2 * wm8776.c -- WM8776 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2009 Wolfson Microelectronics plc 4 * Copyright 2009-12 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 6bd1b767b138..c088020172ab 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8804.c -- WM8804 S/PDIF transceiver driver 2 * wm8804.c -- WM8804 S/PDIF transceiver driver
3 * 3 *
4 * Copyright 2010 Wolfson Microelectronics plc 4 * Copyright 2010-11 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> 6 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
7 * 7 *
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 86b8a2926591..73f1c8d7bafb 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * wm8903.c -- WM8903 ALSA SoC Audio driver 2 * wm8903.c -- WM8903 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2008 Wolfson Microelectronics 4 * Copyright 2008-12 Wolfson Microelectronics
5 * Copyright 2011 NVIDIA, Inc. 5 * Copyright 2011-2012 NVIDIA, Inc.
6 * 6 *
7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
8 * 8 *
@@ -116,6 +116,7 @@ static const struct reg_default wm8903_reg_defaults[] = {
116 116
117struct wm8903_priv { 117struct wm8903_priv {
118 struct wm8903_platform_data *pdata; 118 struct wm8903_platform_data *pdata;
119 struct device *dev;
119 struct snd_soc_codec *codec; 120 struct snd_soc_codec *codec;
120 struct regmap *regmap; 121 struct regmap *regmap;
121 122
@@ -1635,17 +1636,27 @@ EXPORT_SYMBOL_GPL(wm8903_mic_detect);
1635 1636
1636static irqreturn_t wm8903_irq(int irq, void *data) 1637static irqreturn_t wm8903_irq(int irq, void *data)
1637{ 1638{
1638 struct snd_soc_codec *codec = data; 1639 struct wm8903_priv *wm8903 = data;
1639 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 1640 int mic_report, ret;
1640 int mic_report; 1641 unsigned int int_val, mask, int_pol;
1641 int int_pol;
1642 int int_val = 0;
1643 int mask = ~snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1_MASK);
1644 1642
1645 int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask; 1643 ret = regmap_read(wm8903->regmap, WM8903_INTERRUPT_STATUS_1_MASK,
1644 &mask);
1645 if (ret != 0) {
1646 dev_err(wm8903->dev, "Failed to read IRQ mask: %d\n", ret);
1647 return IRQ_NONE;
1648 }
1649
1650 ret = regmap_read(wm8903->regmap, WM8903_INTERRUPT_STATUS_1, &int_val);
1651 if (ret != 0) {
1652 dev_err(wm8903->dev, "Failed to read IRQ status: %d\n", ret);
1653 return IRQ_NONE;
1654 }
1655
1656 int_val &= ~mask;
1646 1657
1647 if (int_val & WM8903_WSEQ_BUSY_EINT) { 1658 if (int_val & WM8903_WSEQ_BUSY_EINT) {
1648 dev_warn(codec->dev, "Write sequencer done\n"); 1659 dev_warn(wm8903->dev, "Write sequencer done\n");
1649 } 1660 }
1650 1661
1651 /* 1662 /*
@@ -1656,22 +1667,28 @@ static irqreturn_t wm8903_irq(int irq, void *data)
1656 * the polarity register. 1667 * the polarity register.
1657 */ 1668 */
1658 mic_report = wm8903->mic_last_report; 1669 mic_report = wm8903->mic_last_report;
1659 int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1); 1670 ret = regmap_read(wm8903->regmap, WM8903_INTERRUPT_POLARITY_1,
1671 &int_pol);
1672 if (ret != 0) {
1673 dev_err(wm8903->dev, "Failed to read interrupt polarity: %d\n",
1674 ret);
1675 return IRQ_HANDLED;
1676 }
1660 1677
1661#ifndef CONFIG_SND_SOC_WM8903_MODULE 1678#ifndef CONFIG_SND_SOC_WM8903_MODULE
1662 if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT)) 1679 if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT))
1663 trace_snd_soc_jack_irq(dev_name(codec->dev)); 1680 trace_snd_soc_jack_irq(dev_name(wm8903->dev));
1664#endif 1681#endif
1665 1682
1666 if (int_val & WM8903_MICSHRT_EINT) { 1683 if (int_val & WM8903_MICSHRT_EINT) {
1667 dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol); 1684 dev_dbg(wm8903->dev, "Microphone short (pol=%x)\n", int_pol);
1668 1685
1669 mic_report ^= wm8903->mic_short; 1686 mic_report ^= wm8903->mic_short;
1670 int_pol ^= WM8903_MICSHRT_INV; 1687 int_pol ^= WM8903_MICSHRT_INV;
1671 } 1688 }
1672 1689
1673 if (int_val & WM8903_MICDET_EINT) { 1690 if (int_val & WM8903_MICDET_EINT) {
1674 dev_dbg(codec->dev, "Microphone detect (pol=%x)\n", int_pol); 1691 dev_dbg(wm8903->dev, "Microphone detect (pol=%x)\n", int_pol);
1675 1692
1676 mic_report ^= wm8903->mic_det; 1693 mic_report ^= wm8903->mic_det;
1677 int_pol ^= WM8903_MICDET_INV; 1694 int_pol ^= WM8903_MICDET_INV;
@@ -1679,8 +1696,8 @@ static irqreturn_t wm8903_irq(int irq, void *data)
1679 msleep(wm8903->mic_delay); 1696 msleep(wm8903->mic_delay);
1680 } 1697 }
1681 1698
1682 snd_soc_update_bits(codec, WM8903_INTERRUPT_POLARITY_1, 1699 regmap_update_bits(wm8903->regmap, WM8903_INTERRUPT_POLARITY_1,
1683 WM8903_MICSHRT_INV | WM8903_MICDET_INV, int_pol); 1700 WM8903_MICSHRT_INV | WM8903_MICDET_INV, int_pol);
1684 1701
1685 snd_soc_jack_report(wm8903->mic_jack, mic_report, 1702 snd_soc_jack_report(wm8903->mic_jack, mic_report,
1686 wm8903->mic_short | wm8903->mic_det); 1703 wm8903->mic_short | wm8903->mic_det);
@@ -1774,7 +1791,6 @@ static int wm8903_gpio_request(struct gpio_chip *chip, unsigned offset)
1774static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset) 1791static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
1775{ 1792{
1776 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); 1793 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1777 struct snd_soc_codec *codec = wm8903->codec;
1778 unsigned int mask, val; 1794 unsigned int mask, val;
1779 int ret; 1795 int ret;
1780 1796
@@ -1782,8 +1798,8 @@ static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
1782 val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) | 1798 val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) |
1783 WM8903_GP1_DIR; 1799 WM8903_GP1_DIR;
1784 1800
1785 ret = snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, 1801 ret = regmap_update_bits(wm8903->regmap,
1786 mask, val); 1802 WM8903_GPIO_CONTROL_1 + offset, mask, val);
1787 if (ret < 0) 1803 if (ret < 0)
1788 return ret; 1804 return ret;
1789 1805
@@ -1793,10 +1809,9 @@ static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
1793static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset) 1809static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset)
1794{ 1810{
1795 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); 1811 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1796 struct snd_soc_codec *codec = wm8903->codec; 1812 unsigned int reg;
1797 int reg;
1798 1813
1799 reg = snd_soc_read(codec, WM8903_GPIO_CONTROL_1 + offset); 1814 regmap_read(wm8903->regmap, WM8903_GPIO_CONTROL_1 + offset, &reg);
1800 1815
1801 return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT; 1816 return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT;
1802} 1817}
@@ -1805,7 +1820,6 @@ static int wm8903_gpio_direction_out(struct gpio_chip *chip,
1805 unsigned offset, int value) 1820 unsigned offset, int value)
1806{ 1821{
1807 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); 1822 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1808 struct snd_soc_codec *codec = wm8903->codec;
1809 unsigned int mask, val; 1823 unsigned int mask, val;
1810 int ret; 1824 int ret;
1811 1825
@@ -1813,8 +1827,8 @@ static int wm8903_gpio_direction_out(struct gpio_chip *chip,
1813 val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) | 1827 val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) |
1814 (value << WM8903_GP2_LVL_SHIFT); 1828 (value << WM8903_GP2_LVL_SHIFT);
1815 1829
1816 ret = snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, 1830 ret = regmap_update_bits(wm8903->regmap,
1817 mask, val); 1831 WM8903_GPIO_CONTROL_1 + offset, mask, val);
1818 if (ret < 0) 1832 if (ret < 0)
1819 return ret; 1833 return ret;
1820 1834
@@ -1824,11 +1838,10 @@ static int wm8903_gpio_direction_out(struct gpio_chip *chip,
1824static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 1838static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
1825{ 1839{
1826 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); 1840 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1827 struct snd_soc_codec *codec = wm8903->codec;
1828 1841
1829 snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, 1842 regmap_update_bits(wm8903->regmap, WM8903_GPIO_CONTROL_1 + offset,
1830 WM8903_GP1_LVL_MASK, 1843 WM8903_GP1_LVL_MASK,
1831 !!value << WM8903_GP1_LVL_SHIFT); 1844 !!value << WM8903_GP1_LVL_SHIFT);
1832} 1845}
1833 1846
1834static struct gpio_chip wm8903_template_chip = { 1847static struct gpio_chip wm8903_template_chip = {
@@ -1842,15 +1855,14 @@ static struct gpio_chip wm8903_template_chip = {
1842 .can_sleep = 1, 1855 .can_sleep = 1,
1843}; 1856};
1844 1857
1845static void wm8903_init_gpio(struct snd_soc_codec *codec) 1858static void wm8903_init_gpio(struct wm8903_priv *wm8903)
1846{ 1859{
1847 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1848 struct wm8903_platform_data *pdata = wm8903->pdata; 1860 struct wm8903_platform_data *pdata = wm8903->pdata;
1849 int ret; 1861 int ret;
1850 1862
1851 wm8903->gpio_chip = wm8903_template_chip; 1863 wm8903->gpio_chip = wm8903_template_chip;
1852 wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO; 1864 wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO;
1853 wm8903->gpio_chip.dev = codec->dev; 1865 wm8903->gpio_chip.dev = wm8903->dev;
1854 1866
1855 if (pdata->gpio_base) 1867 if (pdata->gpio_base)
1856 wm8903->gpio_chip.base = pdata->gpio_base; 1868 wm8903->gpio_chip.base = pdata->gpio_base;
@@ -1859,24 +1871,23 @@ static void wm8903_init_gpio(struct snd_soc_codec *codec)
1859 1871
1860 ret = gpiochip_add(&wm8903->gpio_chip); 1872 ret = gpiochip_add(&wm8903->gpio_chip);
1861 if (ret != 0) 1873 if (ret != 0)
1862 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret); 1874 dev_err(wm8903->dev, "Failed to add GPIOs: %d\n", ret);
1863} 1875}
1864 1876
1865static void wm8903_free_gpio(struct snd_soc_codec *codec) 1877static void wm8903_free_gpio(struct wm8903_priv *wm8903)
1866{ 1878{
1867 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1868 int ret; 1879 int ret;
1869 1880
1870 ret = gpiochip_remove(&wm8903->gpio_chip); 1881 ret = gpiochip_remove(&wm8903->gpio_chip);
1871 if (ret != 0) 1882 if (ret != 0)
1872 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret); 1883 dev_err(wm8903->dev, "Failed to remove GPIOs: %d\n", ret);
1873} 1884}
1874#else 1885#else
1875static void wm8903_init_gpio(struct snd_soc_codec *codec) 1886static void wm8903_init_gpio(struct wm8903_priv *wm8903)
1876{ 1887{
1877} 1888}
1878 1889
1879static void wm8903_free_gpio(struct snd_soc_codec *codec) 1890static void wm8903_free_gpio(struct wm8903_priv *wm8903)
1880{ 1891{
1881} 1892}
1882#endif 1893#endif
@@ -1884,11 +1895,7 @@ static void wm8903_free_gpio(struct snd_soc_codec *codec)
1884static int wm8903_probe(struct snd_soc_codec *codec) 1895static int wm8903_probe(struct snd_soc_codec *codec)
1885{ 1896{
1886 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 1897 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1887 struct wm8903_platform_data *pdata = wm8903->pdata; 1898 int ret;
1888 int ret, i;
1889 int trigger, irq_pol;
1890 u16 val;
1891 bool mic_gpio = false;
1892 1899
1893 wm8903->codec = codec; 1900 wm8903->codec = codec;
1894 codec->control_data = wm8903->regmap; 1901 codec->control_data = wm8903->regmap;
@@ -1899,121 +1906,16 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1899 return ret; 1906 return ret;
1900 } 1907 }
1901 1908
1902 /* Set up GPIOs, detect if any are MIC detect outputs */
1903 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
1904 if ((!pdata->gpio_cfg[i]) ||
1905 (pdata->gpio_cfg[i] > WM8903_GPIO_CONFIG_ZERO))
1906 continue;
1907
1908 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i,
1909 pdata->gpio_cfg[i] & 0x7fff);
1910
1911 val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK)
1912 >> WM8903_GP1_FN_SHIFT;
1913
1914 switch (val) {
1915 case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT:
1916 case WM8903_GPn_FN_MICBIAS_SHORT_DETECT:
1917 mic_gpio = true;
1918 break;
1919 default:
1920 break;
1921 }
1922 }
1923
1924 /* Set up microphone detection */
1925 snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0,
1926 pdata->micdet_cfg);
1927
1928 /* Microphone detection needs the WSEQ clock */
1929 if (pdata->micdet_cfg)
1930 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
1931 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
1932
1933 /* If microphone detection is enabled by pdata but
1934 * detected via IRQ then interrupts can be lost before
1935 * the machine driver has set up microphone detection
1936 * IRQs as the IRQs are clear on read. The detection
1937 * will be enabled when the machine driver configures.
1938 */
1939 WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA));
1940
1941 wm8903->mic_delay = pdata->micdet_delay;
1942
1943 if (wm8903->irq) {
1944 if (pdata->irq_active_low) {
1945 trigger = IRQF_TRIGGER_LOW;
1946 irq_pol = WM8903_IRQ_POL;
1947 } else {
1948 trigger = IRQF_TRIGGER_HIGH;
1949 irq_pol = 0;
1950 }
1951
1952 snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL,
1953 WM8903_IRQ_POL, irq_pol);
1954
1955 ret = request_threaded_irq(wm8903->irq, NULL, wm8903_irq,
1956 trigger | IRQF_ONESHOT,
1957 "wm8903", codec);
1958 if (ret != 0) {
1959 dev_err(codec->dev, "Failed to request IRQ: %d\n",
1960 ret);
1961 return ret;
1962 }
1963
1964 /* Enable write sequencer interrupts */
1965 snd_soc_update_bits(codec, WM8903_INTERRUPT_STATUS_1_MASK,
1966 WM8903_IM_WSEQ_BUSY_EINT, 0);
1967 }
1968
1969 /* power on device */ 1909 /* power on device */
1970 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1910 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1971 1911
1972 /* Latch volume update bits */
1973 val = snd_soc_read(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT);
1974 val |= WM8903_ADCVU;
1975 snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT, val);
1976 snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_RIGHT, val);
1977
1978 val = snd_soc_read(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT);
1979 val |= WM8903_DACVU;
1980 snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT, val);
1981 snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_RIGHT, val);
1982
1983 val = snd_soc_read(codec, WM8903_ANALOGUE_OUT1_LEFT);
1984 val |= WM8903_HPOUTVU;
1985 snd_soc_write(codec, WM8903_ANALOGUE_OUT1_LEFT, val);
1986 snd_soc_write(codec, WM8903_ANALOGUE_OUT1_RIGHT, val);
1987
1988 val = snd_soc_read(codec, WM8903_ANALOGUE_OUT2_LEFT);
1989 val |= WM8903_LINEOUTVU;
1990 snd_soc_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val);
1991 snd_soc_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val);
1992
1993 val = snd_soc_read(codec, WM8903_ANALOGUE_OUT3_LEFT);
1994 val |= WM8903_SPKVU;
1995 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val);
1996 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val);
1997
1998 /* Enable DAC soft mute by default */
1999 snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1,
2000 WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE,
2001 WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE);
2002
2003 wm8903_init_gpio(codec);
2004
2005 return ret; 1912 return ret;
2006} 1913}
2007 1914
2008/* power down chip */ 1915/* power down chip */
2009static int wm8903_remove(struct snd_soc_codec *codec) 1916static int wm8903_remove(struct snd_soc_codec *codec)
2010{ 1917{
2011 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
2012
2013 wm8903_free_gpio(codec);
2014 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 1918 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
2015 if (wm8903->irq)
2016 free_irq(wm8903->irq, codec);
2017 1919
2018 return 0; 1920 return 0;
2019} 1921}
@@ -2123,15 +2025,18 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
2123{ 2025{
2124 struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev); 2026 struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev);
2125 struct wm8903_priv *wm8903; 2027 struct wm8903_priv *wm8903;
2126 unsigned int val; 2028 int trigger;
2127 int ret; 2029 bool mic_gpio = false;
2030 unsigned int val, irq_pol;
2031 int ret, i;
2128 2032
2129 wm8903 = devm_kzalloc(&i2c->dev, sizeof(struct wm8903_priv), 2033 wm8903 = devm_kzalloc(&i2c->dev, sizeof(struct wm8903_priv),
2130 GFP_KERNEL); 2034 GFP_KERNEL);
2131 if (wm8903 == NULL) 2035 if (wm8903 == NULL)
2132 return -ENOMEM; 2036 return -ENOMEM;
2037 wm8903->dev = &i2c->dev;
2133 2038
2134 wm8903->regmap = regmap_init_i2c(i2c, &wm8903_regmap); 2039 wm8903->regmap = devm_regmap_init_i2c(i2c, &wm8903_regmap);
2135 if (IS_ERR(wm8903->regmap)) { 2040 if (IS_ERR(wm8903->regmap)) {
2136 ret = PTR_ERR(wm8903->regmap); 2041 ret = PTR_ERR(wm8903->regmap);
2137 dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 2042 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
@@ -2140,7 +2045,6 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
2140 } 2045 }
2141 2046
2142 i2c_set_clientdata(i2c, wm8903); 2047 i2c_set_clientdata(i2c, wm8903);
2143 wm8903->irq = i2c->irq;
2144 2048
2145 /* If no platform data was supplied, create storage for defaults */ 2049 /* If no platform data was supplied, create storage for defaults */
2146 if (pdata) { 2050 if (pdata) {
@@ -2167,6 +2071,8 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
2167 } 2071 }
2168 } 2072 }
2169 2073
2074 pdata = wm8903->pdata;
2075
2170 ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val); 2076 ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val);
2171 if (ret != 0) { 2077 if (ret != 0) {
2172 dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); 2078 dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
@@ -2189,6 +2095,107 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
2189 /* Reset the device */ 2095 /* Reset the device */
2190 regmap_write(wm8903->regmap, WM8903_SW_RESET_AND_ID, 0x8903); 2096 regmap_write(wm8903->regmap, WM8903_SW_RESET_AND_ID, 0x8903);
2191 2097
2098 wm8903_init_gpio(wm8903);
2099
2100 /* Set up GPIO pin state, detect if any are MIC detect outputs */
2101 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
2102 if ((!pdata->gpio_cfg[i]) ||
2103 (pdata->gpio_cfg[i] > WM8903_GPIO_CONFIG_ZERO))
2104 continue;
2105
2106 regmap_write(wm8903->regmap, WM8903_GPIO_CONTROL_1 + i,
2107 pdata->gpio_cfg[i] & 0x7fff);
2108
2109 val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK)
2110 >> WM8903_GP1_FN_SHIFT;
2111
2112 switch (val) {
2113 case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT:
2114 case WM8903_GPn_FN_MICBIAS_SHORT_DETECT:
2115 mic_gpio = true;
2116 break;
2117 default:
2118 break;
2119 }
2120 }
2121
2122 /* Set up microphone detection */
2123 regmap_write(wm8903->regmap, WM8903_MIC_BIAS_CONTROL_0,
2124 pdata->micdet_cfg);
2125
2126 /* Microphone detection needs the WSEQ clock */
2127 if (pdata->micdet_cfg)
2128 regmap_update_bits(wm8903->regmap, WM8903_WRITE_SEQUENCER_0,
2129 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
2130
2131 /* If microphone detection is enabled by pdata but
2132 * detected via IRQ then interrupts can be lost before
2133 * the machine driver has set up microphone detection
2134 * IRQs as the IRQs are clear on read. The detection
2135 * will be enabled when the machine driver configures.
2136 */
2137 WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA));
2138
2139 wm8903->mic_delay = pdata->micdet_delay;
2140
2141 if (i2c->irq) {
2142 if (pdata->irq_active_low) {
2143 trigger = IRQF_TRIGGER_LOW;
2144 irq_pol = WM8903_IRQ_POL;
2145 } else {
2146 trigger = IRQF_TRIGGER_HIGH;
2147 irq_pol = 0;
2148 }
2149
2150 regmap_update_bits(wm8903->regmap, WM8903_INTERRUPT_CONTROL,
2151 WM8903_IRQ_POL, irq_pol);
2152
2153 ret = request_threaded_irq(i2c->irq, NULL, wm8903_irq,
2154 trigger | IRQF_ONESHOT,
2155 "wm8903", wm8903);
2156 if (ret != 0) {
2157 dev_err(wm8903->dev, "Failed to request IRQ: %d\n",
2158 ret);
2159 return ret;
2160 }
2161
2162 /* Enable write sequencer interrupts */
2163 regmap_update_bits(wm8903->regmap,
2164 WM8903_INTERRUPT_STATUS_1_MASK,
2165 WM8903_IM_WSEQ_BUSY_EINT, 0);
2166 }
2167
2168 /* Latch volume update bits */
2169 regmap_update_bits(wm8903->regmap, WM8903_ADC_DIGITAL_VOLUME_LEFT,
2170 WM8903_ADCVU, WM8903_ADCVU);
2171 regmap_update_bits(wm8903->regmap, WM8903_ADC_DIGITAL_VOLUME_RIGHT,
2172 WM8903_ADCVU, WM8903_ADCVU);
2173
2174 regmap_update_bits(wm8903->regmap, WM8903_DAC_DIGITAL_VOLUME_LEFT,
2175 WM8903_DACVU, WM8903_DACVU);
2176 regmap_update_bits(wm8903->regmap, WM8903_DAC_DIGITAL_VOLUME_RIGHT,
2177 WM8903_DACVU, WM8903_DACVU);
2178
2179 regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT1_LEFT,
2180 WM8903_HPOUTVU, WM8903_HPOUTVU);
2181 regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT1_RIGHT,
2182 WM8903_HPOUTVU, WM8903_HPOUTVU);
2183
2184 regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT2_LEFT,
2185 WM8903_LINEOUTVU, WM8903_LINEOUTVU);
2186 regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT2_RIGHT,
2187 WM8903_LINEOUTVU, WM8903_LINEOUTVU);
2188
2189 regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT3_LEFT,
2190 WM8903_SPKVU, WM8903_SPKVU);
2191 regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT3_RIGHT,
2192 WM8903_SPKVU, WM8903_SPKVU);
2193
2194 /* Enable DAC soft mute by default */
2195 regmap_update_bits(wm8903->regmap, WM8903_DAC_DIGITAL_1,
2196 WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE,
2197 WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE);
2198
2192 ret = snd_soc_register_codec(&i2c->dev, 2199 ret = snd_soc_register_codec(&i2c->dev,
2193 &soc_codec_dev_wm8903, &wm8903_dai, 1); 2200 &soc_codec_dev_wm8903, &wm8903_dai, 1);
2194 if (ret != 0) 2201 if (ret != 0)
@@ -2196,7 +2203,6 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
2196 2203
2197 return 0; 2204 return 0;
2198err: 2205err:
2199 regmap_exit(wm8903->regmap);
2200 return ret; 2206 return ret;
2201} 2207}
2202 2208
@@ -2204,7 +2210,9 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client)
2204{ 2210{
2205 struct wm8903_priv *wm8903 = i2c_get_clientdata(client); 2211 struct wm8903_priv *wm8903 = i2c_get_clientdata(client);
2206 2212
2207 regmap_exit(wm8903->regmap); 2213 if (client->irq)
2214 free_irq(client->irq, wm8903);
2215 wm8903_free_gpio(wm8903);
2208 snd_soc_unregister_codec(&client->dev); 2216 snd_soc_unregister_codec(&client->dev);
2209 2217
2210 return 0; 2218 return 0;
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 812acd83fb48..dc4262eea4b7 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8904.c -- WM8904 ALSA SoC Audio driver 2 * wm8904.c -- WM8904 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2009 Wolfson Microelectronics plc 4 * Copyright 2009-12 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
@@ -100,7 +100,7 @@ static const struct reg_default wm8904_reg_defaults[] = {
100 { 14, 0x0000 }, /* R14 - Power Management 2 */ 100 { 14, 0x0000 }, /* R14 - Power Management 2 */
101 { 15, 0x0000 }, /* R15 - Power Management 3 */ 101 { 15, 0x0000 }, /* R15 - Power Management 3 */
102 { 18, 0x0000 }, /* R18 - Power Management 6 */ 102 { 18, 0x0000 }, /* R18 - Power Management 6 */
103 { 19, 0x945E }, /* R20 - Clock Rates 0 */ 103 { 20, 0x945E }, /* R20 - Clock Rates 0 */
104 { 21, 0x0C05 }, /* R21 - Clock Rates 1 */ 104 { 21, 0x0C05 }, /* R21 - Clock Rates 1 */
105 { 22, 0x0006 }, /* R22 - Clock Rates 2 */ 105 { 22, 0x0006 }, /* R22 - Clock Rates 2 */
106 { 24, 0x0050 }, /* R24 - Audio Interface 0 */ 106 { 24, 0x0050 }, /* R24 - Audio Interface 0 */
@@ -314,11 +314,6 @@ static bool wm8904_readable_register(struct device *dev, unsigned int reg)
314 } 314 }
315} 315}
316 316
317static int wm8904_reset(struct snd_soc_codec *codec)
318{
319 return snd_soc_write(codec, WM8904_SW_RESET_AND_ID, 0);
320}
321
322static int wm8904_configure_clocking(struct snd_soc_codec *codec) 317static int wm8904_configure_clocking(struct snd_soc_codec *codec)
323{ 318{
324 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 319 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
@@ -1945,25 +1940,6 @@ static struct snd_soc_dai_driver wm8904_dai = {
1945 .symmetric_rates = 1, 1940 .symmetric_rates = 1,
1946}; 1941};
1947 1942
1948#ifdef CONFIG_PM
1949static int wm8904_suspend(struct snd_soc_codec *codec)
1950{
1951 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
1952
1953 return 0;
1954}
1955
1956static int wm8904_resume(struct snd_soc_codec *codec)
1957{
1958 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1959
1960 return 0;
1961}
1962#else
1963#define wm8904_suspend NULL
1964#define wm8904_resume NULL
1965#endif
1966
1967static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec) 1943static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec)
1968{ 1944{
1969 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 1945 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
@@ -2078,8 +2054,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
2078static int wm8904_probe(struct snd_soc_codec *codec) 2054static int wm8904_probe(struct snd_soc_codec *codec)
2079{ 2055{
2080 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 2056 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2081 struct wm8904_pdata *pdata = wm8904->pdata; 2057 int ret;
2082 int ret, i;
2083 2058
2084 codec->control_data = wm8904->regmap; 2059 codec->control_data = wm8904->regmap;
2085 2060
@@ -2101,127 +2076,17 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2101 return ret; 2076 return ret;
2102 } 2077 }
2103 2078
2104 for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++)
2105 wm8904->supplies[i].supply = wm8904_supply_names[i];
2106
2107 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8904->supplies),
2108 wm8904->supplies);
2109 if (ret != 0) {
2110 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
2111 return ret;
2112 }
2113
2114 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2115 wm8904->supplies);
2116 if (ret != 0) {
2117 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
2118 goto err_get;
2119 }
2120
2121 ret = snd_soc_read(codec, WM8904_SW_RESET_AND_ID);
2122 if (ret < 0) {
2123 dev_err(codec->dev, "Failed to read ID register\n");
2124 goto err_enable;
2125 }
2126 if (ret != 0x8904) {
2127 dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret);
2128 ret = -EINVAL;
2129 goto err_enable;
2130 }
2131
2132 ret = snd_soc_read(codec, WM8904_REVISION);
2133 if (ret < 0) {
2134 dev_err(codec->dev, "Failed to read device revision: %d\n",
2135 ret);
2136 goto err_enable;
2137 }
2138 dev_info(codec->dev, "revision %c\n", ret + 'A');
2139
2140 ret = wm8904_reset(codec);
2141 if (ret < 0) {
2142 dev_err(codec->dev, "Failed to issue reset\n");
2143 goto err_enable;
2144 }
2145
2146 regcache_cache_only(wm8904->regmap, true);
2147 /* Change some default settings - latch VU and enable ZC */
2148 snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT,
2149 WM8904_ADC_VU, WM8904_ADC_VU);
2150 snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_RIGHT,
2151 WM8904_ADC_VU, WM8904_ADC_VU);
2152 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_LEFT,
2153 WM8904_DAC_VU, WM8904_DAC_VU);
2154 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_RIGHT,
2155 WM8904_DAC_VU, WM8904_DAC_VU);
2156 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_LEFT,
2157 WM8904_HPOUT_VU | WM8904_HPOUTLZC,
2158 WM8904_HPOUT_VU | WM8904_HPOUTLZC);
2159 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_RIGHT,
2160 WM8904_HPOUT_VU | WM8904_HPOUTRZC,
2161 WM8904_HPOUT_VU | WM8904_HPOUTRZC);
2162 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_LEFT,
2163 WM8904_LINEOUT_VU | WM8904_LINEOUTLZC,
2164 WM8904_LINEOUT_VU | WM8904_LINEOUTLZC);
2165 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_RIGHT,
2166 WM8904_LINEOUT_VU | WM8904_LINEOUTRZC,
2167 WM8904_LINEOUT_VU | WM8904_LINEOUTRZC);
2168 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0,
2169 WM8904_SR_MODE, 0);
2170
2171 /* Apply configuration from the platform data. */
2172 if (wm8904->pdata) {
2173 for (i = 0; i < WM8904_GPIO_REGS; i++) {
2174 if (!pdata->gpio_cfg[i])
2175 continue;
2176
2177 regmap_update_bits(wm8904->regmap,
2178 WM8904_GPIO_CONTROL_1 + i,
2179 0xffff,
2180 pdata->gpio_cfg[i]);
2181 }
2182
2183 /* Zero is the default value for these anyway */
2184 for (i = 0; i < WM8904_MIC_REGS; i++)
2185 regmap_update_bits(wm8904->regmap,
2186 WM8904_MIC_BIAS_CONTROL_0 + i,
2187 0xffff,
2188 pdata->mic_cfg[i]);
2189 }
2190
2191 /* Set Class W by default - this will be managed by the Class
2192 * G widget at runtime where bypass paths are available.
2193 */
2194 snd_soc_update_bits(codec, WM8904_CLASS_W_0,
2195 WM8904_CP_DYN_PWR, WM8904_CP_DYN_PWR);
2196
2197 /* Use normal bias source */
2198 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2199 WM8904_POBCTRL, 0);
2200
2201 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2202
2203 /* Bias level configuration will have done an extra enable */
2204 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2205
2206 wm8904_handle_pdata(codec); 2079 wm8904_handle_pdata(codec);
2207 2080
2208 wm8904_add_widgets(codec); 2081 wm8904_add_widgets(codec);
2209 2082
2210 return 0; 2083 return 0;
2211
2212err_enable:
2213 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2214err_get:
2215 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2216 return ret;
2217} 2084}
2218 2085
2219static int wm8904_remove(struct snd_soc_codec *codec) 2086static int wm8904_remove(struct snd_soc_codec *codec)
2220{ 2087{
2221 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 2088 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2222 2089
2223 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
2224 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2225 kfree(wm8904->retune_mobile_texts); 2090 kfree(wm8904->retune_mobile_texts);
2226 kfree(wm8904->drc_texts); 2091 kfree(wm8904->drc_texts);
2227 2092
@@ -2231,8 +2096,6 @@ static int wm8904_remove(struct snd_soc_codec *codec)
2231static struct snd_soc_codec_driver soc_codec_dev_wm8904 = { 2096static struct snd_soc_codec_driver soc_codec_dev_wm8904 = {
2232 .probe = wm8904_probe, 2097 .probe = wm8904_probe,
2233 .remove = wm8904_remove, 2098 .remove = wm8904_remove,
2234 .suspend = wm8904_suspend,
2235 .resume = wm8904_resume,
2236 .set_bias_level = wm8904_set_bias_level, 2099 .set_bias_level = wm8904_set_bias_level,
2237 .idle_bias_off = true, 2100 .idle_bias_off = true,
2238}; 2101};
@@ -2254,14 +2117,15 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2254 const struct i2c_device_id *id) 2117 const struct i2c_device_id *id)
2255{ 2118{
2256 struct wm8904_priv *wm8904; 2119 struct wm8904_priv *wm8904;
2257 int ret; 2120 unsigned int val;
2121 int ret, i;
2258 2122
2259 wm8904 = devm_kzalloc(&i2c->dev, sizeof(struct wm8904_priv), 2123 wm8904 = devm_kzalloc(&i2c->dev, sizeof(struct wm8904_priv),
2260 GFP_KERNEL); 2124 GFP_KERNEL);
2261 if (wm8904 == NULL) 2125 if (wm8904 == NULL)
2262 return -ENOMEM; 2126 return -ENOMEM;
2263 2127
2264 wm8904->regmap = regmap_init_i2c(i2c, &wm8904_regmap); 2128 wm8904->regmap = devm_regmap_init_i2c(i2c, &wm8904_regmap);
2265 if (IS_ERR(wm8904->regmap)) { 2129 if (IS_ERR(wm8904->regmap)) {
2266 ret = PTR_ERR(wm8904->regmap); 2130 ret = PTR_ERR(wm8904->regmap);
2267 dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 2131 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
@@ -2273,23 +2137,121 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2273 i2c_set_clientdata(i2c, wm8904); 2137 i2c_set_clientdata(i2c, wm8904);
2274 wm8904->pdata = i2c->dev.platform_data; 2138 wm8904->pdata = i2c->dev.platform_data;
2275 2139
2140 for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++)
2141 wm8904->supplies[i].supply = wm8904_supply_names[i];
2142
2143 ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8904->supplies),
2144 wm8904->supplies);
2145 if (ret != 0) {
2146 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
2147 return ret;
2148 }
2149
2150 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2151 wm8904->supplies);
2152 if (ret != 0) {
2153 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
2154 return ret;
2155 }
2156
2157 ret = regmap_read(wm8904->regmap, WM8904_SW_RESET_AND_ID, &val);
2158 if (ret < 0) {
2159 dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
2160 goto err_enable;
2161 }
2162 if (val != 0x8904) {
2163 dev_err(&i2c->dev, "Device is not a WM8904, ID is %x\n", val);
2164 ret = -EINVAL;
2165 goto err_enable;
2166 }
2167
2168 ret = regmap_read(wm8904->regmap, WM8904_REVISION, &val);
2169 if (ret < 0) {
2170 dev_err(&i2c->dev, "Failed to read device revision: %d\n",
2171 ret);
2172 goto err_enable;
2173 }
2174 dev_info(&i2c->dev, "revision %c\n", val + 'A');
2175
2176 ret = regmap_write(wm8904->regmap, WM8904_SW_RESET_AND_ID, 0);
2177 if (ret < 0) {
2178 dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
2179 goto err_enable;
2180 }
2181
2182 /* Change some default settings - latch VU and enable ZC */
2183 regmap_update_bits(wm8904->regmap, WM8904_ADC_DIGITAL_VOLUME_LEFT,
2184 WM8904_ADC_VU, WM8904_ADC_VU);
2185 regmap_update_bits(wm8904->regmap, WM8904_ADC_DIGITAL_VOLUME_RIGHT,
2186 WM8904_ADC_VU, WM8904_ADC_VU);
2187 regmap_update_bits(wm8904->regmap, WM8904_DAC_DIGITAL_VOLUME_LEFT,
2188 WM8904_DAC_VU, WM8904_DAC_VU);
2189 regmap_update_bits(wm8904->regmap, WM8904_DAC_DIGITAL_VOLUME_RIGHT,
2190 WM8904_DAC_VU, WM8904_DAC_VU);
2191 regmap_update_bits(wm8904->regmap, WM8904_ANALOGUE_OUT1_LEFT,
2192 WM8904_HPOUT_VU | WM8904_HPOUTLZC,
2193 WM8904_HPOUT_VU | WM8904_HPOUTLZC);
2194 regmap_update_bits(wm8904->regmap, WM8904_ANALOGUE_OUT1_RIGHT,
2195 WM8904_HPOUT_VU | WM8904_HPOUTRZC,
2196 WM8904_HPOUT_VU | WM8904_HPOUTRZC);
2197 regmap_update_bits(wm8904->regmap, WM8904_ANALOGUE_OUT2_LEFT,
2198 WM8904_LINEOUT_VU | WM8904_LINEOUTLZC,
2199 WM8904_LINEOUT_VU | WM8904_LINEOUTLZC);
2200 regmap_update_bits(wm8904->regmap, WM8904_ANALOGUE_OUT2_RIGHT,
2201 WM8904_LINEOUT_VU | WM8904_LINEOUTRZC,
2202 WM8904_LINEOUT_VU | WM8904_LINEOUTRZC);
2203 regmap_update_bits(wm8904->regmap, WM8904_CLOCK_RATES_0,
2204 WM8904_SR_MODE, 0);
2205
2206 /* Apply configuration from the platform data. */
2207 if (wm8904->pdata) {
2208 for (i = 0; i < WM8904_GPIO_REGS; i++) {
2209 if (!wm8904->pdata->gpio_cfg[i])
2210 continue;
2211
2212 regmap_update_bits(wm8904->regmap,
2213 WM8904_GPIO_CONTROL_1 + i,
2214 0xffff,
2215 wm8904->pdata->gpio_cfg[i]);
2216 }
2217
2218 /* Zero is the default value for these anyway */
2219 for (i = 0; i < WM8904_MIC_REGS; i++)
2220 regmap_update_bits(wm8904->regmap,
2221 WM8904_MIC_BIAS_CONTROL_0 + i,
2222 0xffff,
2223 wm8904->pdata->mic_cfg[i]);
2224 }
2225
2226 /* Set Class W by default - this will be managed by the Class
2227 * G widget at runtime where bypass paths are available.
2228 */
2229 regmap_update_bits(wm8904->regmap, WM8904_CLASS_W_0,
2230 WM8904_CP_DYN_PWR, WM8904_CP_DYN_PWR);
2231
2232 /* Use normal bias source */
2233 regmap_update_bits(wm8904->regmap, WM8904_BIAS_CONTROL_0,
2234 WM8904_POBCTRL, 0);
2235
2236 /* Can leave the device powered off until we need it */
2237 regcache_cache_only(wm8904->regmap, true);
2238 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2239
2276 ret = snd_soc_register_codec(&i2c->dev, 2240 ret = snd_soc_register_codec(&i2c->dev,
2277 &soc_codec_dev_wm8904, &wm8904_dai, 1); 2241 &soc_codec_dev_wm8904, &wm8904_dai, 1);
2278 if (ret != 0) 2242 if (ret != 0)
2279 goto err; 2243 return ret;
2280 2244
2281 return 0; 2245 return 0;
2282 2246
2283err: 2247err_enable:
2284 regmap_exit(wm8904->regmap); 2248 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2285 return ret; 2249 return ret;
2286} 2250}
2287 2251
2288static __devexit int wm8904_i2c_remove(struct i2c_client *client) 2252static __devexit int wm8904_i2c_remove(struct i2c_client *client)
2289{ 2253{
2290 struct wm8904_priv *wm8904 = i2c_get_clientdata(client);
2291 snd_soc_unregister_codec(&client->dev); 2254 snd_soc_unregister_codec(&client->dev);
2292 regmap_exit(wm8904->regmap);
2293 return 0; 2255 return 0;
2294} 2256}
2295 2257
@@ -2311,23 +2273,7 @@ static struct i2c_driver wm8904_i2c_driver = {
2311 .id_table = wm8904_i2c_id, 2273 .id_table = wm8904_i2c_id,
2312}; 2274};
2313 2275
2314static int __init wm8904_modinit(void) 2276module_i2c_driver(wm8904_i2c_driver);
2315{
2316 int ret = 0;
2317 ret = i2c_add_driver(&wm8904_i2c_driver);
2318 if (ret != 0) {
2319 printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n",
2320 ret);
2321 }
2322 return ret;
2323}
2324module_init(wm8904_modinit);
2325
2326static void __exit wm8904_exit(void)
2327{
2328 i2c_del_driver(&wm8904_i2c_driver);
2329}
2330module_exit(wm8904_exit);
2331 2277
2332MODULE_DESCRIPTION("ASoC WM8904 driver"); 2278MODULE_DESCRIPTION("ASoC WM8904 driver");
2333MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 2279MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 8bc659d8dd2e..96518ac8e24c 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -1,6 +1,8 @@
1/* 1/*
2 * wm8960.c -- WM8960 ALSA SoC Audio driver 2 * wm8960.c -- WM8960 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2007-11 Wolfson Microelectronics, plc
5 *
4 * Author: Liam Girdwood 6 * Author: Liam Girdwood
5 * 7 *
6 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 05ea7c274093..01edbcc754d2 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -1,6 +1,8 @@
1/* 1/*
2 * wm8961.c -- WM8961 ALSA SoC Audio driver 2 * wm8961.c -- WM8961 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2009-10 Wolfson Microelectronics, plc
5 *
4 * Author: Mark Brown 6 * Author: Mark Brown
5 * 7 *
6 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 0cfce9999c89..ce6720073798 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8962.c -- WM8962 ALSA SoC Audio driver 2 * wm8962.c -- WM8962 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2010 Wolfson Microelectronics plc 4 * Copyright 2010-2 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
@@ -2501,6 +2501,9 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
2501 /* VMID 2*250k */ 2501 /* VMID 2*250k */
2502 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, 2502 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
2503 WM8962_VMID_SEL_MASK, 0x100); 2503 WM8962_VMID_SEL_MASK, 0x100);
2504
2505 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
2506 msleep(100);
2504 break; 2507 break;
2505 2508
2506 case SND_SOC_BIAS_OFF: 2509 case SND_SOC_BIAS_OFF:
@@ -2580,6 +2583,9 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
2580 WM8962_SAMPLE_RATE_INT_MODE | 2583 WM8962_SAMPLE_RATE_INT_MODE |
2581 WM8962_SAMPLE_RATE_MASK, adctl3); 2584 WM8962_SAMPLE_RATE_MASK, adctl3);
2582 2585
2586 dev_dbg(codec->dev, "hw_params set BCLK %dHz LRCLK %dHz\n",
2587 wm8962->bclk, wm8962->lrclk);
2588
2583 if (codec->dapm.bias_level == SND_SOC_BIAS_ON) 2589 if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
2584 wm8962_configure_bclk(codec); 2590 wm8962_configure_bclk(codec);
2585 2591
@@ -3722,22 +3728,10 @@ static int wm8962_runtime_resume(struct device *dev)
3722 } 3728 }
3723 3729
3724 regcache_cache_only(wm8962->regmap, false); 3730 regcache_cache_only(wm8962->regmap, false);
3725 regcache_sync(wm8962->regmap);
3726 3731
3727 regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP, 3732 wm8962_reset(wm8962);
3728 WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA,
3729 WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA);
3730 3733
3731 /* Bias enable at 2*50k for ramp */ 3734 regcache_sync(wm8962->regmap);
3732 regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
3733 WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA,
3734 WM8962_BIAS_ENA | 0x180);
3735
3736 msleep(5);
3737
3738 /* VMID back to 2x250k for standby */
3739 regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
3740 WM8962_VMID_SEL_MASK, 0x100);
3741 3735
3742 return 0; 3736 return 0;
3743} 3737}
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 36acfccab999..9fd80d688979 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8993.c -- WM8993 ALSA SoC audio driver 2 * wm8993.c -- WM8993 ALSA SoC audio driver
3 * 3 *
4 * Copyright 2009, 2010 Wolfson Microelectronics plc 4 * Copyright 2009-12 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 1436b6ce74d1..6c9eeca85b95 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8994.c -- WM8994 ALSA SoC Audio driver 2 * wm8994.c -- WM8994 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2009 Wolfson Microelectronics plc 4 * Copyright 2009-12 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
@@ -2649,7 +2649,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
2649 return -EINVAL; 2649 return -EINVAL;
2650 } 2650 }
2651 2651
2652 bclk_rate = params_rate(params) * 2; 2652 bclk_rate = params_rate(params) * 4;
2653 switch (params_format(params)) { 2653 switch (params_format(params)) {
2654 case SNDRV_PCM_FORMAT_S16_LE: 2654 case SNDRV_PCM_FORMAT_S16_LE:
2655 bclk_rate *= 16; 2655 bclk_rate *= 16;
@@ -2967,23 +2967,8 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2967static int wm8994_codec_suspend(struct snd_soc_codec *codec) 2967static int wm8994_codec_suspend(struct snd_soc_codec *codec)
2968{ 2968{
2969 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2969 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2970 struct wm8994 *control = wm8994->wm8994;
2971 int i, ret; 2970 int i, ret;
2972 2971
2973 switch (control->type) {
2974 case WM8994:
2975 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0);
2976 break;
2977 case WM1811:
2978 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
2979 WM1811_JACKDET_MODE_MASK, 0);
2980 /* Fall through */
2981 case WM8958:
2982 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
2983 WM8958_MICD_ENA, 0);
2984 break;
2985 }
2986
2987 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { 2972 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
2988 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i], 2973 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i],
2989 sizeof(struct wm8994_fll_config)); 2974 sizeof(struct wm8994_fll_config));
@@ -3033,28 +3018,6 @@ static int wm8994_codec_resume(struct snd_soc_codec *codec)
3033 i + 1, ret); 3018 i + 1, ret);
3034 } 3019 }
3035 3020
3036 switch (control->type) {
3037 case WM8994:
3038 if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
3039 snd_soc_update_bits(codec, WM8994_MICBIAS,
3040 WM8994_MICD_ENA, WM8994_MICD_ENA);
3041 break;
3042 case WM1811:
3043 if (wm8994->jackdet && wm8994->jack_cb) {
3044 /* Restart from idle */
3045 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
3046 WM1811_JACKDET_MODE_MASK,
3047 WM1811_JACKDET_MODE_JACK);
3048 break;
3049 }
3050 break;
3051 case WM8958:
3052 if (wm8994->jack_cb)
3053 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
3054 WM8958_MICD_ENA, WM8958_MICD_ENA);
3055 break;
3056 }
3057
3058 return 0; 3021 return 0;
3059} 3022}
3060#else 3023#else
@@ -3290,10 +3253,13 @@ static void wm8994_mic_work(struct work_struct *work)
3290 int ret; 3253 int ret;
3291 int report; 3254 int report;
3292 3255
3256 pm_runtime_get_sync(dev);
3257
3293 ret = regmap_read(regmap, WM8994_INTERRUPT_RAW_STATUS_2, &reg); 3258 ret = regmap_read(regmap, WM8994_INTERRUPT_RAW_STATUS_2, &reg);
3294 if (ret < 0) { 3259 if (ret < 0) {
3295 dev_err(dev, "Failed to read microphone status: %d\n", 3260 dev_err(dev, "Failed to read microphone status: %d\n",
3296 ret); 3261 ret);
3262 pm_runtime_put(dev);
3297 return; 3263 return;
3298 } 3264 }
3299 3265
@@ -3336,6 +3302,8 @@ static void wm8994_mic_work(struct work_struct *work)
3336 3302
3337 snd_soc_jack_report(priv->micdet[1].jack, report, 3303 snd_soc_jack_report(priv->micdet[1].jack, report,
3338 SND_JACK_HEADSET | SND_JACK_BTN_0); 3304 SND_JACK_HEADSET | SND_JACK_BTN_0);
3305
3306 pm_runtime_put(dev);
3339} 3307}
3340 3308
3341static irqreturn_t wm8994_mic_irq(int irq, void *data) 3309static irqreturn_t wm8994_mic_irq(int irq, void *data)
@@ -3458,12 +3426,15 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3458 int reg; 3426 int reg;
3459 bool present; 3427 bool present;
3460 3428
3429 pm_runtime_get_sync(codec->dev);
3430
3461 mutex_lock(&wm8994->accdet_lock); 3431 mutex_lock(&wm8994->accdet_lock);
3462 3432
3463 reg = snd_soc_read(codec, WM1811_JACKDET_CTRL); 3433 reg = snd_soc_read(codec, WM1811_JACKDET_CTRL);
3464 if (reg < 0) { 3434 if (reg < 0) {
3465 dev_err(codec->dev, "Failed to read jack status: %d\n", reg); 3435 dev_err(codec->dev, "Failed to read jack status: %d\n", reg);
3466 mutex_unlock(&wm8994->accdet_lock); 3436 mutex_unlock(&wm8994->accdet_lock);
3437 pm_runtime_put(codec->dev);
3467 return IRQ_NONE; 3438 return IRQ_NONE;
3468 } 3439 }
3469 3440
@@ -3528,6 +3499,7 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3528 SND_JACK_MECHANICAL | SND_JACK_HEADSET | 3499 SND_JACK_MECHANICAL | SND_JACK_HEADSET |
3529 wm8994->btn_mask); 3500 wm8994->btn_mask);
3530 3501
3502 pm_runtime_put(codec->dev);
3531 return IRQ_HANDLED; 3503 return IRQ_HANDLED;
3532} 3504}
3533 3505
@@ -3639,6 +3611,8 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3639 if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) 3611 if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA))
3640 return IRQ_HANDLED; 3612 return IRQ_HANDLED;
3641 3613
3614 pm_runtime_get_sync(codec->dev);
3615
3642 /* We may occasionally read a detection without an impedence 3616 /* We may occasionally read a detection without an impedence
3643 * range being provided - if that happens loop again. 3617 * range being provided - if that happens loop again.
3644 */ 3618 */
@@ -3649,6 +3623,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3649 dev_err(codec->dev, 3623 dev_err(codec->dev,
3650 "Failed to read mic detect status: %d\n", 3624 "Failed to read mic detect status: %d\n",
3651 reg); 3625 reg);
3626 pm_runtime_put(codec->dev);
3652 return IRQ_NONE; 3627 return IRQ_NONE;
3653 } 3628 }
3654 3629
@@ -3676,6 +3651,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3676 dev_warn(codec->dev, "Accessory detection with no callback\n"); 3651 dev_warn(codec->dev, "Accessory detection with no callback\n");
3677 3652
3678out: 3653out:
3654 pm_runtime_put(codec->dev);
3679 return IRQ_HANDLED; 3655 return IRQ_HANDLED;
3680} 3656}
3681 3657
@@ -3729,9 +3705,6 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3729 3705
3730 if (wm8994->pdata && wm8994->pdata->micdet_irq) 3706 if (wm8994->pdata && wm8994->pdata->micdet_irq)
3731 wm8994->micdet_irq = wm8994->pdata->micdet_irq; 3707 wm8994->micdet_irq = wm8994->pdata->micdet_irq;
3732 else if (wm8994->pdata && wm8994->pdata->irq_base)
3733 wm8994->micdet_irq = wm8994->pdata->irq_base +
3734 WM8994_IRQ_MIC1_DET;
3735 3708
3736 pm_runtime_enable(codec->dev); 3709 pm_runtime_enable(codec->dev);
3737 pm_runtime_idle(codec->dev); 3710 pm_runtime_idle(codec->dev);
@@ -3870,6 +3843,10 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3870 dev_warn(codec->dev, 3843 dev_warn(codec->dev,
3871 "Failed to request Mic detect IRQ: %d\n", 3844 "Failed to request Mic detect IRQ: %d\n",
3872 ret); 3845 ret);
3846 } else {
3847 wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_MIC1_DET,
3848 wm8958_mic_irq, "Mic detect",
3849 wm8994);
3873 } 3850 }
3874 } 3851 }
3875 3852
@@ -4061,6 +4038,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
4061 break; 4038 break;
4062 case WM8958: 4039 case WM8958:
4063 if (wm8994->revision < 1) { 4040 if (wm8994->revision < 1) {
4041 snd_soc_dapm_add_routes(dapm, wm8994_intercon,
4042 ARRAY_SIZE(wm8994_intercon));
4064 snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, 4043 snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon,
4065 ARRAY_SIZE(wm8994_revd_intercon)); 4044 ARRAY_SIZE(wm8994_revd_intercon));
4066 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon, 4045 snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon,
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index dc9b42b7fc4d..00f183dfa454 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8996.c - WM8996 audio codec interface 2 * wm8996.c - WM8996 audio codec interface
3 * 3 *
4 * Copyright 2011 Wolfson Microelectronics PLC. 4 * Copyright 2011-2 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
@@ -296,184 +296,6 @@ static struct reg_default wm8996_reg[] = {
296 { WM8996_RIGHT_PDM_SPEAKER, 0x1 }, 296 { WM8996_RIGHT_PDM_SPEAKER, 0x1 },
297 { WM8996_PDM_SPEAKER_MUTE_SEQUENCE, 0x69 }, 297 { WM8996_PDM_SPEAKER_MUTE_SEQUENCE, 0x69 },
298 { WM8996_PDM_SPEAKER_VOLUME, 0x66 }, 298 { WM8996_PDM_SPEAKER_VOLUME, 0x66 },
299 { WM8996_WRITE_SEQUENCER_0, 0x1 },
300 { WM8996_WRITE_SEQUENCER_1, 0x1 },
301 { WM8996_WRITE_SEQUENCER_3, 0x6 },
302 { WM8996_WRITE_SEQUENCER_4, 0x40 },
303 { WM8996_WRITE_SEQUENCER_5, 0x1 },
304 { WM8996_WRITE_SEQUENCER_6, 0xf },
305 { WM8996_WRITE_SEQUENCER_7, 0x6 },
306 { WM8996_WRITE_SEQUENCER_8, 0x1 },
307 { WM8996_WRITE_SEQUENCER_9, 0x3 },
308 { WM8996_WRITE_SEQUENCER_10, 0x104 },
309 { WM8996_WRITE_SEQUENCER_12, 0x60 },
310 { WM8996_WRITE_SEQUENCER_13, 0x11 },
311 { WM8996_WRITE_SEQUENCER_14, 0x401 },
312 { WM8996_WRITE_SEQUENCER_16, 0x50 },
313 { WM8996_WRITE_SEQUENCER_17, 0x3 },
314 { WM8996_WRITE_SEQUENCER_18, 0x100 },
315 { WM8996_WRITE_SEQUENCER_20, 0x51 },
316 { WM8996_WRITE_SEQUENCER_21, 0x3 },
317 { WM8996_WRITE_SEQUENCER_22, 0x104 },
318 { WM8996_WRITE_SEQUENCER_23, 0xa },
319 { WM8996_WRITE_SEQUENCER_24, 0x60 },
320 { WM8996_WRITE_SEQUENCER_25, 0x3b },
321 { WM8996_WRITE_SEQUENCER_26, 0x502 },
322 { WM8996_WRITE_SEQUENCER_27, 0x100 },
323 { WM8996_WRITE_SEQUENCER_28, 0x2fff },
324 { WM8996_WRITE_SEQUENCER_32, 0x2fff },
325 { WM8996_WRITE_SEQUENCER_36, 0x2fff },
326 { WM8996_WRITE_SEQUENCER_40, 0x2fff },
327 { WM8996_WRITE_SEQUENCER_44, 0x2fff },
328 { WM8996_WRITE_SEQUENCER_48, 0x2fff },
329 { WM8996_WRITE_SEQUENCER_52, 0x2fff },
330 { WM8996_WRITE_SEQUENCER_56, 0x2fff },
331 { WM8996_WRITE_SEQUENCER_60, 0x2fff },
332 { WM8996_WRITE_SEQUENCER_64, 0x1 },
333 { WM8996_WRITE_SEQUENCER_65, 0x1 },
334 { WM8996_WRITE_SEQUENCER_67, 0x6 },
335 { WM8996_WRITE_SEQUENCER_68, 0x40 },
336 { WM8996_WRITE_SEQUENCER_69, 0x1 },
337 { WM8996_WRITE_SEQUENCER_70, 0xf },
338 { WM8996_WRITE_SEQUENCER_71, 0x6 },
339 { WM8996_WRITE_SEQUENCER_72, 0x1 },
340 { WM8996_WRITE_SEQUENCER_73, 0x3 },
341 { WM8996_WRITE_SEQUENCER_74, 0x104 },
342 { WM8996_WRITE_SEQUENCER_76, 0x60 },
343 { WM8996_WRITE_SEQUENCER_77, 0x11 },
344 { WM8996_WRITE_SEQUENCER_78, 0x401 },
345 { WM8996_WRITE_SEQUENCER_80, 0x50 },
346 { WM8996_WRITE_SEQUENCER_81, 0x3 },
347 { WM8996_WRITE_SEQUENCER_82, 0x100 },
348 { WM8996_WRITE_SEQUENCER_84, 0x60 },
349 { WM8996_WRITE_SEQUENCER_85, 0x3b },
350 { WM8996_WRITE_SEQUENCER_86, 0x502 },
351 { WM8996_WRITE_SEQUENCER_87, 0x100 },
352 { WM8996_WRITE_SEQUENCER_88, 0x2fff },
353 { WM8996_WRITE_SEQUENCER_92, 0x2fff },
354 { WM8996_WRITE_SEQUENCER_96, 0x2fff },
355 { WM8996_WRITE_SEQUENCER_100, 0x2fff },
356 { WM8996_WRITE_SEQUENCER_104, 0x2fff },
357 { WM8996_WRITE_SEQUENCER_108, 0x2fff },
358 { WM8996_WRITE_SEQUENCER_112, 0x2fff },
359 { WM8996_WRITE_SEQUENCER_116, 0x2fff },
360 { WM8996_WRITE_SEQUENCER_120, 0x2fff },
361 { WM8996_WRITE_SEQUENCER_124, 0x2fff },
362 { WM8996_WRITE_SEQUENCER_128, 0x1 },
363 { WM8996_WRITE_SEQUENCER_129, 0x1 },
364 { WM8996_WRITE_SEQUENCER_131, 0x6 },
365 { WM8996_WRITE_SEQUENCER_132, 0x40 },
366 { WM8996_WRITE_SEQUENCER_133, 0x1 },
367 { WM8996_WRITE_SEQUENCER_134, 0xf },
368 { WM8996_WRITE_SEQUENCER_135, 0x6 },
369 { WM8996_WRITE_SEQUENCER_136, 0x1 },
370 { WM8996_WRITE_SEQUENCER_137, 0x3 },
371 { WM8996_WRITE_SEQUENCER_138, 0x106 },
372 { WM8996_WRITE_SEQUENCER_140, 0x61 },
373 { WM8996_WRITE_SEQUENCER_141, 0x11 },
374 { WM8996_WRITE_SEQUENCER_142, 0x401 },
375 { WM8996_WRITE_SEQUENCER_144, 0x50 },
376 { WM8996_WRITE_SEQUENCER_145, 0x3 },
377 { WM8996_WRITE_SEQUENCER_146, 0x102 },
378 { WM8996_WRITE_SEQUENCER_148, 0x51 },
379 { WM8996_WRITE_SEQUENCER_149, 0x3 },
380 { WM8996_WRITE_SEQUENCER_150, 0x106 },
381 { WM8996_WRITE_SEQUENCER_151, 0xa },
382 { WM8996_WRITE_SEQUENCER_152, 0x61 },
383 { WM8996_WRITE_SEQUENCER_153, 0x3b },
384 { WM8996_WRITE_SEQUENCER_154, 0x502 },
385 { WM8996_WRITE_SEQUENCER_155, 0x100 },
386 { WM8996_WRITE_SEQUENCER_156, 0x2fff },
387 { WM8996_WRITE_SEQUENCER_160, 0x2fff },
388 { WM8996_WRITE_SEQUENCER_164, 0x2fff },
389 { WM8996_WRITE_SEQUENCER_168, 0x2fff },
390 { WM8996_WRITE_SEQUENCER_172, 0x2fff },
391 { WM8996_WRITE_SEQUENCER_176, 0x2fff },
392 { WM8996_WRITE_SEQUENCER_180, 0x2fff },
393 { WM8996_WRITE_SEQUENCER_184, 0x2fff },
394 { WM8996_WRITE_SEQUENCER_188, 0x2fff },
395 { WM8996_WRITE_SEQUENCER_192, 0x1 },
396 { WM8996_WRITE_SEQUENCER_193, 0x1 },
397 { WM8996_WRITE_SEQUENCER_195, 0x6 },
398 { WM8996_WRITE_SEQUENCER_196, 0x40 },
399 { WM8996_WRITE_SEQUENCER_197, 0x1 },
400 { WM8996_WRITE_SEQUENCER_198, 0xf },
401 { WM8996_WRITE_SEQUENCER_199, 0x6 },
402 { WM8996_WRITE_SEQUENCER_200, 0x1 },
403 { WM8996_WRITE_SEQUENCER_201, 0x3 },
404 { WM8996_WRITE_SEQUENCER_202, 0x106 },
405 { WM8996_WRITE_SEQUENCER_204, 0x61 },
406 { WM8996_WRITE_SEQUENCER_205, 0x11 },
407 { WM8996_WRITE_SEQUENCER_206, 0x401 },
408 { WM8996_WRITE_SEQUENCER_208, 0x50 },
409 { WM8996_WRITE_SEQUENCER_209, 0x3 },
410 { WM8996_WRITE_SEQUENCER_210, 0x102 },
411 { WM8996_WRITE_SEQUENCER_212, 0x61 },
412 { WM8996_WRITE_SEQUENCER_213, 0x3b },
413 { WM8996_WRITE_SEQUENCER_214, 0x502 },
414 { WM8996_WRITE_SEQUENCER_215, 0x100 },
415 { WM8996_WRITE_SEQUENCER_216, 0x2fff },
416 { WM8996_WRITE_SEQUENCER_220, 0x2fff },
417 { WM8996_WRITE_SEQUENCER_224, 0x2fff },
418 { WM8996_WRITE_SEQUENCER_228, 0x2fff },
419 { WM8996_WRITE_SEQUENCER_232, 0x2fff },
420 { WM8996_WRITE_SEQUENCER_236, 0x2fff },
421 { WM8996_WRITE_SEQUENCER_240, 0x2fff },
422 { WM8996_WRITE_SEQUENCER_244, 0x2fff },
423 { WM8996_WRITE_SEQUENCER_248, 0x2fff },
424 { WM8996_WRITE_SEQUENCER_252, 0x2fff },
425 { WM8996_WRITE_SEQUENCER_256, 0x60 },
426 { WM8996_WRITE_SEQUENCER_258, 0x601 },
427 { WM8996_WRITE_SEQUENCER_260, 0x50 },
428 { WM8996_WRITE_SEQUENCER_262, 0x100 },
429 { WM8996_WRITE_SEQUENCER_264, 0x1 },
430 { WM8996_WRITE_SEQUENCER_266, 0x104 },
431 { WM8996_WRITE_SEQUENCER_267, 0x100 },
432 { WM8996_WRITE_SEQUENCER_268, 0x2fff },
433 { WM8996_WRITE_SEQUENCER_272, 0x2fff },
434 { WM8996_WRITE_SEQUENCER_276, 0x2fff },
435 { WM8996_WRITE_SEQUENCER_280, 0x2fff },
436 { WM8996_WRITE_SEQUENCER_284, 0x2fff },
437 { WM8996_WRITE_SEQUENCER_288, 0x2fff },
438 { WM8996_WRITE_SEQUENCER_292, 0x2fff },
439 { WM8996_WRITE_SEQUENCER_296, 0x2fff },
440 { WM8996_WRITE_SEQUENCER_300, 0x2fff },
441 { WM8996_WRITE_SEQUENCER_304, 0x2fff },
442 { WM8996_WRITE_SEQUENCER_308, 0x2fff },
443 { WM8996_WRITE_SEQUENCER_312, 0x2fff },
444 { WM8996_WRITE_SEQUENCER_316, 0x2fff },
445 { WM8996_WRITE_SEQUENCER_320, 0x61 },
446 { WM8996_WRITE_SEQUENCER_322, 0x601 },
447 { WM8996_WRITE_SEQUENCER_324, 0x50 },
448 { WM8996_WRITE_SEQUENCER_326, 0x102 },
449 { WM8996_WRITE_SEQUENCER_328, 0x1 },
450 { WM8996_WRITE_SEQUENCER_330, 0x106 },
451 { WM8996_WRITE_SEQUENCER_331, 0x100 },
452 { WM8996_WRITE_SEQUENCER_332, 0x2fff },
453 { WM8996_WRITE_SEQUENCER_336, 0x2fff },
454 { WM8996_WRITE_SEQUENCER_340, 0x2fff },
455 { WM8996_WRITE_SEQUENCER_344, 0x2fff },
456 { WM8996_WRITE_SEQUENCER_348, 0x2fff },
457 { WM8996_WRITE_SEQUENCER_352, 0x2fff },
458 { WM8996_WRITE_SEQUENCER_356, 0x2fff },
459 { WM8996_WRITE_SEQUENCER_360, 0x2fff },
460 { WM8996_WRITE_SEQUENCER_364, 0x2fff },
461 { WM8996_WRITE_SEQUENCER_368, 0x2fff },
462 { WM8996_WRITE_SEQUENCER_372, 0x2fff },
463 { WM8996_WRITE_SEQUENCER_376, 0x2fff },
464 { WM8996_WRITE_SEQUENCER_380, 0x2fff },
465 { WM8996_WRITE_SEQUENCER_384, 0x60 },
466 { WM8996_WRITE_SEQUENCER_386, 0x601 },
467 { WM8996_WRITE_SEQUENCER_388, 0x61 },
468 { WM8996_WRITE_SEQUENCER_390, 0x601 },
469 { WM8996_WRITE_SEQUENCER_392, 0x50 },
470 { WM8996_WRITE_SEQUENCER_394, 0x300 },
471 { WM8996_WRITE_SEQUENCER_396, 0x1 },
472 { WM8996_WRITE_SEQUENCER_398, 0x304 },
473 { WM8996_WRITE_SEQUENCER_400, 0x40 },
474 { WM8996_WRITE_SEQUENCER_402, 0xf },
475 { WM8996_WRITE_SEQUENCER_404, 0x1 },
476 { WM8996_WRITE_SEQUENCER_407, 0x100 },
477}; 299};
478 300
479static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0); 301static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0);
@@ -1706,18 +1528,6 @@ static bool wm8996_volatile_register(struct device *dev, unsigned int reg)
1706 } 1528 }
1707} 1529}
1708 1530
1709static int wm8996_reset(struct wm8996_priv *wm8996)
1710{
1711 if (wm8996->pdata.ldo_ena > 0) {
1712 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
1713 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1);
1714 return 0;
1715 } else {
1716 return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET,
1717 0x8915);
1718 }
1719}
1720
1721static const int bclk_divs[] = { 1531static const int bclk_divs[] = {
1722 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96 1532 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
1723}; 1533};
@@ -1809,8 +1619,10 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
1809 1619
1810 case SND_SOC_BIAS_OFF: 1620 case SND_SOC_BIAS_OFF:
1811 regcache_cache_only(codec->control_data, true); 1621 regcache_cache_only(codec->control_data, true);
1812 if (wm8996->pdata.ldo_ena >= 0) 1622 if (wm8996->pdata.ldo_ena >= 0) {
1813 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 1623 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
1624 regcache_cache_only(codec->control_data, true);
1625 }
1814 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), 1626 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies),
1815 wm8996->supplies); 1627 wm8996->supplies);
1816 break; 1628 break;
@@ -2807,7 +2619,7 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2807 int ret; 2619 int ret;
2808 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 2620 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
2809 struct i2c_client *i2c = to_i2c_client(codec->dev); 2621 struct i2c_client *i2c = to_i2c_client(codec->dev);
2810 int i, irq_flags; 2622 int irq_flags;
2811 2623
2812 wm8996->codec = codec; 2624 wm8996->codec = codec;
2813 2625
@@ -2822,177 +2634,12 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2822 goto err; 2634 goto err;
2823 } 2635 }
2824 2636
2825 wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0;
2826 wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1;
2827 wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2;
2828
2829 /* This should really be moved into the regulator core */
2830 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) {
2831 ret = regulator_register_notifier(wm8996->supplies[i].consumer,
2832 &wm8996->disable_nb[i]);
2833 if (ret != 0) {
2834 dev_err(codec->dev,
2835 "Failed to register regulator notifier: %d\n",
2836 ret);
2837 }
2838 }
2839
2840 /* Apply platform data settings */
2841 snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL,
2842 WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK,
2843 wm8996->pdata.inl_mode << WM8996_INL_MODE_SHIFT |
2844 wm8996->pdata.inr_mode);
2845
2846 for (i = 0; i < ARRAY_SIZE(wm8996->pdata.gpio_default); i++) {
2847 if (!wm8996->pdata.gpio_default[i])
2848 continue;
2849
2850 snd_soc_write(codec, WM8996_GPIO_1 + i,
2851 wm8996->pdata.gpio_default[i] & 0xffff);
2852 }
2853
2854 if (wm8996->pdata.spkmute_seq)
2855 snd_soc_update_bits(codec, WM8996_PDM_SPEAKER_MUTE_SEQUENCE,
2856 WM8996_SPK_MUTE_ENDIAN |
2857 WM8996_SPK_MUTE_SEQ1_MASK,
2858 wm8996->pdata.spkmute_seq);
2859
2860 snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_2,
2861 WM8996_MICD_BIAS_SRC | WM8996_HPOUT1FB_SRC |
2862 WM8996_MICD_SRC, wm8996->pdata.micdet_def);
2863
2864 /* Latch volume update bits */
2865 snd_soc_update_bits(codec, WM8996_LEFT_LINE_INPUT_VOLUME,
2866 WM8996_IN1_VU, WM8996_IN1_VU);
2867 snd_soc_update_bits(codec, WM8996_RIGHT_LINE_INPUT_VOLUME,
2868 WM8996_IN1_VU, WM8996_IN1_VU);
2869
2870 snd_soc_update_bits(codec, WM8996_DAC1_LEFT_VOLUME,
2871 WM8996_DAC1_VU, WM8996_DAC1_VU);
2872 snd_soc_update_bits(codec, WM8996_DAC1_RIGHT_VOLUME,
2873 WM8996_DAC1_VU, WM8996_DAC1_VU);
2874 snd_soc_update_bits(codec, WM8996_DAC2_LEFT_VOLUME,
2875 WM8996_DAC2_VU, WM8996_DAC2_VU);
2876 snd_soc_update_bits(codec, WM8996_DAC2_RIGHT_VOLUME,
2877 WM8996_DAC2_VU, WM8996_DAC2_VU);
2878
2879 snd_soc_update_bits(codec, WM8996_OUTPUT1_LEFT_VOLUME,
2880 WM8996_DAC1_VU, WM8996_DAC1_VU);
2881 snd_soc_update_bits(codec, WM8996_OUTPUT1_RIGHT_VOLUME,
2882 WM8996_DAC1_VU, WM8996_DAC1_VU);
2883 snd_soc_update_bits(codec, WM8996_OUTPUT2_LEFT_VOLUME,
2884 WM8996_DAC2_VU, WM8996_DAC2_VU);
2885 snd_soc_update_bits(codec, WM8996_OUTPUT2_RIGHT_VOLUME,
2886 WM8996_DAC2_VU, WM8996_DAC2_VU);
2887
2888 snd_soc_update_bits(codec, WM8996_DSP1_TX_LEFT_VOLUME,
2889 WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
2890 snd_soc_update_bits(codec, WM8996_DSP1_TX_RIGHT_VOLUME,
2891 WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
2892 snd_soc_update_bits(codec, WM8996_DSP2_TX_LEFT_VOLUME,
2893 WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
2894 snd_soc_update_bits(codec, WM8996_DSP2_TX_RIGHT_VOLUME,
2895 WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
2896
2897 snd_soc_update_bits(codec, WM8996_DSP1_RX_LEFT_VOLUME,
2898 WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
2899 snd_soc_update_bits(codec, WM8996_DSP1_RX_RIGHT_VOLUME,
2900 WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
2901 snd_soc_update_bits(codec, WM8996_DSP2_RX_LEFT_VOLUME,
2902 WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
2903 snd_soc_update_bits(codec, WM8996_DSP2_RX_RIGHT_VOLUME,
2904 WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
2905
2906 /* No support currently for the underclocked TDM modes and
2907 * pick a default TDM layout with each channel pair working with
2908 * slots 0 and 1. */
2909 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_0_CONFIGURATION,
2910 WM8996_AIF1RX_CHAN0_SLOTS_MASK |
2911 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2912 1 << WM8996_AIF1RX_CHAN0_SLOTS_SHIFT | 0);
2913 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_1_CONFIGURATION,
2914 WM8996_AIF1RX_CHAN1_SLOTS_MASK |
2915 WM8996_AIF1RX_CHAN1_START_SLOT_MASK,
2916 1 << WM8996_AIF1RX_CHAN1_SLOTS_SHIFT | 1);
2917 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_2_CONFIGURATION,
2918 WM8996_AIF1RX_CHAN2_SLOTS_MASK |
2919 WM8996_AIF1RX_CHAN2_START_SLOT_MASK,
2920 1 << WM8996_AIF1RX_CHAN2_SLOTS_SHIFT | 0);
2921 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_3_CONFIGURATION,
2922 WM8996_AIF1RX_CHAN3_SLOTS_MASK |
2923 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2924 1 << WM8996_AIF1RX_CHAN3_SLOTS_SHIFT | 1);
2925 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_4_CONFIGURATION,
2926 WM8996_AIF1RX_CHAN4_SLOTS_MASK |
2927 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2928 1 << WM8996_AIF1RX_CHAN4_SLOTS_SHIFT | 0);
2929 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_5_CONFIGURATION,
2930 WM8996_AIF1RX_CHAN5_SLOTS_MASK |
2931 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2932 1 << WM8996_AIF1RX_CHAN5_SLOTS_SHIFT | 1);
2933
2934 snd_soc_update_bits(codec, WM8996_AIF2RX_CHANNEL_0_CONFIGURATION,
2935 WM8996_AIF2RX_CHAN0_SLOTS_MASK |
2936 WM8996_AIF2RX_CHAN0_START_SLOT_MASK,
2937 1 << WM8996_AIF2RX_CHAN0_SLOTS_SHIFT | 0);
2938 snd_soc_update_bits(codec, WM8996_AIF2RX_CHANNEL_1_CONFIGURATION,
2939 WM8996_AIF2RX_CHAN1_SLOTS_MASK |
2940 WM8996_AIF2RX_CHAN1_START_SLOT_MASK,
2941 1 << WM8996_AIF2RX_CHAN1_SLOTS_SHIFT | 1);
2942
2943 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_0_CONFIGURATION,
2944 WM8996_AIF1TX_CHAN0_SLOTS_MASK |
2945 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2946 1 << WM8996_AIF1TX_CHAN0_SLOTS_SHIFT | 0);
2947 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
2948 WM8996_AIF1TX_CHAN1_SLOTS_MASK |
2949 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2950 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2951 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_2_CONFIGURATION,
2952 WM8996_AIF1TX_CHAN2_SLOTS_MASK |
2953 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2954 1 << WM8996_AIF1TX_CHAN2_SLOTS_SHIFT | 0);
2955 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_3_CONFIGURATION,
2956 WM8996_AIF1TX_CHAN3_SLOTS_MASK |
2957 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2958 1 << WM8996_AIF1TX_CHAN3_SLOTS_SHIFT | 1);
2959 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_4_CONFIGURATION,
2960 WM8996_AIF1TX_CHAN4_SLOTS_MASK |
2961 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2962 1 << WM8996_AIF1TX_CHAN4_SLOTS_SHIFT | 0);
2963 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_5_CONFIGURATION,
2964 WM8996_AIF1TX_CHAN5_SLOTS_MASK |
2965 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2966 1 << WM8996_AIF1TX_CHAN5_SLOTS_SHIFT | 1);
2967
2968 snd_soc_update_bits(codec, WM8996_AIF2TX_CHANNEL_0_CONFIGURATION,
2969 WM8996_AIF2TX_CHAN0_SLOTS_MASK |
2970 WM8996_AIF2TX_CHAN0_START_SLOT_MASK,
2971 1 << WM8996_AIF2TX_CHAN0_SLOTS_SHIFT | 0);
2972 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
2973 WM8996_AIF2TX_CHAN1_SLOTS_MASK |
2974 WM8996_AIF2TX_CHAN1_START_SLOT_MASK,
2975 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2976
2977 if (wm8996->pdata.num_retune_mobile_cfgs) 2637 if (wm8996->pdata.num_retune_mobile_cfgs)
2978 wm8996_retune_mobile_pdata(codec); 2638 wm8996_retune_mobile_pdata(codec);
2979 else 2639 else
2980 snd_soc_add_codec_controls(codec, wm8996_eq_controls, 2640 snd_soc_add_codec_controls(codec, wm8996_eq_controls,
2981 ARRAY_SIZE(wm8996_eq_controls)); 2641 ARRAY_SIZE(wm8996_eq_controls));
2982 2642
2983 /* If the TX LRCLK pins are not in LRCLK mode configure the
2984 * AIFs to source their clocks from the RX LRCLKs.
2985 */
2986 if ((snd_soc_read(codec, WM8996_GPIO_1)))
2987 snd_soc_update_bits(codec, WM8996_AIF1_TX_LRCLK_2,
2988 WM8996_AIF1TX_LRCLK_MODE,
2989 WM8996_AIF1TX_LRCLK_MODE);
2990
2991 if ((snd_soc_read(codec, WM8996_GPIO_2)))
2992 snd_soc_update_bits(codec, WM8996_AIF2_TX_LRCLK_2,
2993 WM8996_AIF2TX_LRCLK_MODE,
2994 WM8996_AIF2TX_LRCLK_MODE);
2995
2996 if (i2c->irq) { 2643 if (i2c->irq) {
2997 if (wm8996->pdata.irq_flags) 2644 if (wm8996->pdata.irq_flags)
2998 irq_flags = wm8996->pdata.irq_flags; 2645 irq_flags = wm8996->pdata.irq_flags;
@@ -3036,9 +2683,7 @@ err:
3036 2683
3037static int wm8996_remove(struct snd_soc_codec *codec) 2684static int wm8996_remove(struct snd_soc_codec *codec)
3038{ 2685{
3039 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
3040 struct i2c_client *i2c = to_i2c_client(codec->dev); 2686 struct i2c_client *i2c = to_i2c_client(codec->dev);
3041 int i;
3042 2687
3043 snd_soc_update_bits(codec, WM8996_INTERRUPT_CONTROL, 2688 snd_soc_update_bits(codec, WM8996_INTERRUPT_CONTROL,
3044 WM8996_IM_IRQ, WM8996_IM_IRQ); 2689 WM8996_IM_IRQ, WM8996_IM_IRQ);
@@ -3046,10 +2691,6 @@ static int wm8996_remove(struct snd_soc_codec *codec)
3046 if (i2c->irq) 2691 if (i2c->irq)
3047 free_irq(i2c->irq, codec); 2692 free_irq(i2c->irq, codec);
3048 2693
3049 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
3050 regulator_unregister_notifier(wm8996->supplies[i].consumer,
3051 &wm8996->disable_nb[i]);
3052
3053 return 0; 2694 return 0;
3054} 2695}
3055 2696
@@ -3163,6 +2804,21 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3163 goto err_gpio; 2804 goto err_gpio;
3164 } 2805 }
3165 2806
2807 wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0;
2808 wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1;
2809 wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2;
2810
2811 /* This should really be moved into the regulator core */
2812 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) {
2813 ret = regulator_register_notifier(wm8996->supplies[i].consumer,
2814 &wm8996->disable_nb[i]);
2815 if (ret != 0) {
2816 dev_err(&i2c->dev,
2817 "Failed to register regulator notifier: %d\n",
2818 ret);
2819 }
2820 }
2821
3166 ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies), 2822 ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
3167 wm8996->supplies); 2823 wm8996->supplies);
3168 if (ret != 0) { 2824 if (ret != 0) {
@@ -3175,7 +2831,7 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3175 msleep(5); 2831 msleep(5);
3176 } 2832 }
3177 2833
3178 wm8996->regmap = regmap_init_i2c(i2c, &wm8996_regmap); 2834 wm8996->regmap = devm_regmap_init_i2c(i2c, &wm8996_regmap);
3179 if (IS_ERR(wm8996->regmap)) { 2835 if (IS_ERR(wm8996->regmap)) {
3180 ret = PTR_ERR(wm8996->regmap); 2836 ret = PTR_ERR(wm8996->regmap);
3181 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); 2837 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
@@ -3203,15 +2859,199 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3203 dev_info(&i2c->dev, "revision %c\n", 2859 dev_info(&i2c->dev, "revision %c\n",
3204 (reg & WM8996_CHIP_REV_MASK) + 'A'); 2860 (reg & WM8996_CHIP_REV_MASK) + 'A');
3205 2861
3206 ret = wm8996_reset(wm8996); 2862 if (wm8996->pdata.ldo_ena > 0) {
3207 if (ret < 0) { 2863 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
3208 dev_err(&i2c->dev, "Failed to issue reset\n"); 2864 regcache_cache_only(wm8996->regmap, true);
3209 goto err_regmap; 2865 } else {
2866 ret = regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET,
2867 0x8915);
2868 if (ret != 0) {
2869 dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
2870 goto err_regmap;
2871 }
3210 } 2872 }
3211 2873
3212 regcache_cache_only(wm8996->regmap, true);
3213 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 2874 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
3214 2875
2876 /* Apply platform data settings */
2877 regmap_update_bits(wm8996->regmap, WM8996_LINE_INPUT_CONTROL,
2878 WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK,
2879 wm8996->pdata.inl_mode << WM8996_INL_MODE_SHIFT |
2880 wm8996->pdata.inr_mode);
2881
2882 for (i = 0; i < ARRAY_SIZE(wm8996->pdata.gpio_default); i++) {
2883 if (!wm8996->pdata.gpio_default[i])
2884 continue;
2885
2886 regmap_write(wm8996->regmap, WM8996_GPIO_1 + i,
2887 wm8996->pdata.gpio_default[i] & 0xffff);
2888 }
2889
2890 if (wm8996->pdata.spkmute_seq)
2891 regmap_update_bits(wm8996->regmap,
2892 WM8996_PDM_SPEAKER_MUTE_SEQUENCE,
2893 WM8996_SPK_MUTE_ENDIAN |
2894 WM8996_SPK_MUTE_SEQ1_MASK,
2895 wm8996->pdata.spkmute_seq);
2896
2897 regmap_update_bits(wm8996->regmap, WM8996_ACCESSORY_DETECT_MODE_2,
2898 WM8996_MICD_BIAS_SRC | WM8996_HPOUT1FB_SRC |
2899 WM8996_MICD_SRC, wm8996->pdata.micdet_def);
2900
2901 /* Latch volume update bits */
2902 regmap_update_bits(wm8996->regmap, WM8996_LEFT_LINE_INPUT_VOLUME,
2903 WM8996_IN1_VU, WM8996_IN1_VU);
2904 regmap_update_bits(wm8996->regmap, WM8996_RIGHT_LINE_INPUT_VOLUME,
2905 WM8996_IN1_VU, WM8996_IN1_VU);
2906
2907 regmap_update_bits(wm8996->regmap, WM8996_DAC1_LEFT_VOLUME,
2908 WM8996_DAC1_VU, WM8996_DAC1_VU);
2909 regmap_update_bits(wm8996->regmap, WM8996_DAC1_RIGHT_VOLUME,
2910 WM8996_DAC1_VU, WM8996_DAC1_VU);
2911 regmap_update_bits(wm8996->regmap, WM8996_DAC2_LEFT_VOLUME,
2912 WM8996_DAC2_VU, WM8996_DAC2_VU);
2913 regmap_update_bits(wm8996->regmap, WM8996_DAC2_RIGHT_VOLUME,
2914 WM8996_DAC2_VU, WM8996_DAC2_VU);
2915
2916 regmap_update_bits(wm8996->regmap, WM8996_OUTPUT1_LEFT_VOLUME,
2917 WM8996_DAC1_VU, WM8996_DAC1_VU);
2918 regmap_update_bits(wm8996->regmap, WM8996_OUTPUT1_RIGHT_VOLUME,
2919 WM8996_DAC1_VU, WM8996_DAC1_VU);
2920 regmap_update_bits(wm8996->regmap, WM8996_OUTPUT2_LEFT_VOLUME,
2921 WM8996_DAC2_VU, WM8996_DAC2_VU);
2922 regmap_update_bits(wm8996->regmap, WM8996_OUTPUT2_RIGHT_VOLUME,
2923 WM8996_DAC2_VU, WM8996_DAC2_VU);
2924
2925 regmap_update_bits(wm8996->regmap, WM8996_DSP1_TX_LEFT_VOLUME,
2926 WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
2927 regmap_update_bits(wm8996->regmap, WM8996_DSP1_TX_RIGHT_VOLUME,
2928 WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
2929 regmap_update_bits(wm8996->regmap, WM8996_DSP2_TX_LEFT_VOLUME,
2930 WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
2931 regmap_update_bits(wm8996->regmap, WM8996_DSP2_TX_RIGHT_VOLUME,
2932 WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
2933
2934 regmap_update_bits(wm8996->regmap, WM8996_DSP1_RX_LEFT_VOLUME,
2935 WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
2936 regmap_update_bits(wm8996->regmap, WM8996_DSP1_RX_RIGHT_VOLUME,
2937 WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
2938 regmap_update_bits(wm8996->regmap, WM8996_DSP2_RX_LEFT_VOLUME,
2939 WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
2940 regmap_update_bits(wm8996->regmap, WM8996_DSP2_RX_RIGHT_VOLUME,
2941 WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
2942
2943 /* No support currently for the underclocked TDM modes and
2944 * pick a default TDM layout with each channel pair working with
2945 * slots 0 and 1. */
2946 regmap_update_bits(wm8996->regmap,
2947 WM8996_AIF1RX_CHANNEL_0_CONFIGURATION,
2948 WM8996_AIF1RX_CHAN0_SLOTS_MASK |
2949 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2950 1 << WM8996_AIF1RX_CHAN0_SLOTS_SHIFT | 0);
2951 regmap_update_bits(wm8996->regmap,
2952 WM8996_AIF1RX_CHANNEL_1_CONFIGURATION,
2953 WM8996_AIF1RX_CHAN1_SLOTS_MASK |
2954 WM8996_AIF1RX_CHAN1_START_SLOT_MASK,
2955 1 << WM8996_AIF1RX_CHAN1_SLOTS_SHIFT | 1);
2956 regmap_update_bits(wm8996->regmap,
2957 WM8996_AIF1RX_CHANNEL_2_CONFIGURATION,
2958 WM8996_AIF1RX_CHAN2_SLOTS_MASK |
2959 WM8996_AIF1RX_CHAN2_START_SLOT_MASK,
2960 1 << WM8996_AIF1RX_CHAN2_SLOTS_SHIFT | 0);
2961 regmap_update_bits(wm8996->regmap,
2962 WM8996_AIF1RX_CHANNEL_3_CONFIGURATION,
2963 WM8996_AIF1RX_CHAN3_SLOTS_MASK |
2964 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2965 1 << WM8996_AIF1RX_CHAN3_SLOTS_SHIFT | 1);
2966 regmap_update_bits(wm8996->regmap,
2967 WM8996_AIF1RX_CHANNEL_4_CONFIGURATION,
2968 WM8996_AIF1RX_CHAN4_SLOTS_MASK |
2969 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2970 1 << WM8996_AIF1RX_CHAN4_SLOTS_SHIFT | 0);
2971 regmap_update_bits(wm8996->regmap,
2972 WM8996_AIF1RX_CHANNEL_5_CONFIGURATION,
2973 WM8996_AIF1RX_CHAN5_SLOTS_MASK |
2974 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2975 1 << WM8996_AIF1RX_CHAN5_SLOTS_SHIFT | 1);
2976
2977 regmap_update_bits(wm8996->regmap,
2978 WM8996_AIF2RX_CHANNEL_0_CONFIGURATION,
2979 WM8996_AIF2RX_CHAN0_SLOTS_MASK |
2980 WM8996_AIF2RX_CHAN0_START_SLOT_MASK,
2981 1 << WM8996_AIF2RX_CHAN0_SLOTS_SHIFT | 0);
2982 regmap_update_bits(wm8996->regmap,
2983 WM8996_AIF2RX_CHANNEL_1_CONFIGURATION,
2984 WM8996_AIF2RX_CHAN1_SLOTS_MASK |
2985 WM8996_AIF2RX_CHAN1_START_SLOT_MASK,
2986 1 << WM8996_AIF2RX_CHAN1_SLOTS_SHIFT | 1);
2987
2988 regmap_update_bits(wm8996->regmap,
2989 WM8996_AIF1TX_CHANNEL_0_CONFIGURATION,
2990 WM8996_AIF1TX_CHAN0_SLOTS_MASK |
2991 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2992 1 << WM8996_AIF1TX_CHAN0_SLOTS_SHIFT | 0);
2993 regmap_update_bits(wm8996->regmap,
2994 WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
2995 WM8996_AIF1TX_CHAN1_SLOTS_MASK |
2996 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2997 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2998 regmap_update_bits(wm8996->regmap,
2999 WM8996_AIF1TX_CHANNEL_2_CONFIGURATION,
3000 WM8996_AIF1TX_CHAN2_SLOTS_MASK |
3001 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
3002 1 << WM8996_AIF1TX_CHAN2_SLOTS_SHIFT | 0);
3003 regmap_update_bits(wm8996->regmap,
3004 WM8996_AIF1TX_CHANNEL_3_CONFIGURATION,
3005 WM8996_AIF1TX_CHAN3_SLOTS_MASK |
3006 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
3007 1 << WM8996_AIF1TX_CHAN3_SLOTS_SHIFT | 1);
3008 regmap_update_bits(wm8996->regmap,
3009 WM8996_AIF1TX_CHANNEL_4_CONFIGURATION,
3010 WM8996_AIF1TX_CHAN4_SLOTS_MASK |
3011 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
3012 1 << WM8996_AIF1TX_CHAN4_SLOTS_SHIFT | 0);
3013 regmap_update_bits(wm8996->regmap,
3014 WM8996_AIF1TX_CHANNEL_5_CONFIGURATION,
3015 WM8996_AIF1TX_CHAN5_SLOTS_MASK |
3016 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
3017 1 << WM8996_AIF1TX_CHAN5_SLOTS_SHIFT | 1);
3018
3019 regmap_update_bits(wm8996->regmap,
3020 WM8996_AIF2TX_CHANNEL_0_CONFIGURATION,
3021 WM8996_AIF2TX_CHAN0_SLOTS_MASK |
3022 WM8996_AIF2TX_CHAN0_START_SLOT_MASK,
3023 1 << WM8996_AIF2TX_CHAN0_SLOTS_SHIFT | 0);
3024 regmap_update_bits(wm8996->regmap,
3025 WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
3026 WM8996_AIF2TX_CHAN1_SLOTS_MASK |
3027 WM8996_AIF2TX_CHAN1_START_SLOT_MASK,
3028 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
3029
3030 /* If the TX LRCLK pins are not in LRCLK mode configure the
3031 * AIFs to source their clocks from the RX LRCLKs.
3032 */
3033 ret = regmap_read(wm8996->regmap, WM8996_GPIO_1, &reg);
3034 if (ret != 0) {
3035 dev_err(&i2c->dev, "Failed to read GPIO1: %d\n", ret);
3036 goto err_regmap;
3037 }
3038
3039 if (reg & WM8996_GP1_FN_MASK)
3040 regmap_update_bits(wm8996->regmap, WM8996_AIF1_TX_LRCLK_2,
3041 WM8996_AIF1TX_LRCLK_MODE,
3042 WM8996_AIF1TX_LRCLK_MODE);
3043
3044 ret = regmap_read(wm8996->regmap, WM8996_GPIO_2, &reg);
3045 if (ret != 0) {
3046 dev_err(&i2c->dev, "Failed to read GPIO2: %d\n", ret);
3047 goto err_regmap;
3048 }
3049
3050 if (reg & WM8996_GP2_FN_MASK)
3051 regmap_update_bits(wm8996->regmap, WM8996_AIF2_TX_LRCLK_2,
3052 WM8996_AIF2TX_LRCLK_MODE,
3053 WM8996_AIF2TX_LRCLK_MODE);
3054
3215 wm8996_init_gpio(wm8996); 3055 wm8996_init_gpio(wm8996);
3216 3056
3217 ret = snd_soc_register_codec(&i2c->dev, 3057 ret = snd_soc_register_codec(&i2c->dev,
@@ -3225,7 +3065,6 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3225err_gpiolib: 3065err_gpiolib:
3226 wm8996_free_gpio(wm8996); 3066 wm8996_free_gpio(wm8996);
3227err_regmap: 3067err_regmap:
3228 regmap_exit(wm8996->regmap);
3229err_enable: 3068err_enable:
3230 if (wm8996->pdata.ldo_ena > 0) 3069 if (wm8996->pdata.ldo_ena > 0)
3231 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 3070 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
@@ -3241,14 +3080,18 @@ err:
3241static __devexit int wm8996_i2c_remove(struct i2c_client *client) 3080static __devexit int wm8996_i2c_remove(struct i2c_client *client)
3242{ 3081{
3243 struct wm8996_priv *wm8996 = i2c_get_clientdata(client); 3082 struct wm8996_priv *wm8996 = i2c_get_clientdata(client);
3083 int i;
3244 3084
3245 snd_soc_unregister_codec(&client->dev); 3085 snd_soc_unregister_codec(&client->dev);
3246 wm8996_free_gpio(wm8996); 3086 wm8996_free_gpio(wm8996);
3247 regmap_exit(wm8996->regmap);
3248 if (wm8996->pdata.ldo_ena > 0) { 3087 if (wm8996->pdata.ldo_ena > 0) {
3249 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 3088 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
3250 gpio_free(wm8996->pdata.ldo_ena); 3089 gpio_free(wm8996->pdata.ldo_ena);
3251 } 3090 }
3091 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
3092 regulator_unregister_notifier(wm8996->supplies[i].consumer,
3093 &wm8996->disable_nb[i]);
3094
3252 return 0; 3095 return 0;
3253} 3096}
3254 3097
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 9328270df16c..2de74e1ea225 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Author: Mark Brown 4 * Author: Mark Brown
5 * 5 *
6 * Copyright 2009 Wolfson Microelectronics plc 6 * Copyright 2009-12 Wolfson Microelectronics plc
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 4b263b6edf13..2c2346fdd637 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC WM9090 driver 2 * ALSA SoC WM9090 driver
3 * 3 *
4 * Copyright 2009, 2010 Wolfson Microelectronics 4 * Copyright 2009-12 Wolfson Microelectronics
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index a1541414d904..c6d2076a796b 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm9712.c -- ALSA Soc WM9712 codec support 2 * wm9712.c -- ALSA Soc WM9712 codec support
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC. 4 * Copyright 2006-12 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood <lrg@slimlogic.co.uk> 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
@@ -148,7 +148,7 @@ SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 1),
148 148
149SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN, 15, 1, 1), 149SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN, 15, 1, 1),
150SOC_ENUM("Capture Volume Steps", wm9712_enum[6]), 150SOC_ENUM("Capture Volume Steps", wm9712_enum[6]),
151SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1), 151SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 0),
152SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), 152SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
153 153
154SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv), 154SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv),
@@ -272,7 +272,7 @@ SOC_DAPM_ENUM("Route", wm9712_enum[9]);
272 272
273/* Mic select */ 273/* Mic select */
274static const struct snd_kcontrol_new wm9712_mic_src_controls = 274static const struct snd_kcontrol_new wm9712_mic_src_controls =
275SOC_DAPM_ENUM("Route", wm9712_enum[7]); 275SOC_DAPM_ENUM("Mic Source Select", wm9712_enum[7]);
276 276
277/* diff select */ 277/* diff select */
278static const struct snd_kcontrol_new wm9712_diff_sel_controls = 278static const struct snd_kcontrol_new wm9712_diff_sel_controls =
@@ -291,7 +291,9 @@ SND_SOC_DAPM_MUX("Left Capture Select", SND_SOC_NOPM, 0, 0,
291 &wm9712_capture_selectl_controls), 291 &wm9712_capture_selectl_controls),
292SND_SOC_DAPM_MUX("Right Capture Select", SND_SOC_NOPM, 0, 0, 292SND_SOC_DAPM_MUX("Right Capture Select", SND_SOC_NOPM, 0, 0,
293 &wm9712_capture_selectr_controls), 293 &wm9712_capture_selectr_controls),
294SND_SOC_DAPM_MUX("Mic Select Source", SND_SOC_NOPM, 0, 0, 294SND_SOC_DAPM_MUX("Left Mic Select Source", SND_SOC_NOPM, 0, 0,
295 &wm9712_mic_src_controls),
296SND_SOC_DAPM_MUX("Right Mic Select Source", SND_SOC_NOPM, 0, 0,
295 &wm9712_mic_src_controls), 297 &wm9712_mic_src_controls),
296SND_SOC_DAPM_MUX("Differential Source", SND_SOC_NOPM, 0, 0, 298SND_SOC_DAPM_MUX("Differential Source", SND_SOC_NOPM, 0, 0,
297 &wm9712_diff_sel_controls), 299 &wm9712_diff_sel_controls),
@@ -319,6 +321,7 @@ SND_SOC_DAPM_PGA("Out 3 PGA", AC97_INT_PAGING, 5, 1, NULL, 0),
319SND_SOC_DAPM_PGA("Line PGA", AC97_INT_PAGING, 2, 1, NULL, 0), 321SND_SOC_DAPM_PGA("Line PGA", AC97_INT_PAGING, 2, 1, NULL, 0),
320SND_SOC_DAPM_PGA("Phone PGA", AC97_INT_PAGING, 1, 1, NULL, 0), 322SND_SOC_DAPM_PGA("Phone PGA", AC97_INT_PAGING, 1, 1, NULL, 0),
321SND_SOC_DAPM_PGA("Mic PGA", AC97_INT_PAGING, 0, 1, NULL, 0), 323SND_SOC_DAPM_PGA("Mic PGA", AC97_INT_PAGING, 0, 1, NULL, 0),
324SND_SOC_DAPM_PGA("Differential Mic", SND_SOC_NOPM, 0, 0, NULL, 0),
322SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_INT_PAGING, 10, 1), 325SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_INT_PAGING, 10, 1),
323SND_SOC_DAPM_OUTPUT("MONOOUT"), 326SND_SOC_DAPM_OUTPUT("MONOOUT"),
324SND_SOC_DAPM_OUTPUT("HPOUTL"), 327SND_SOC_DAPM_OUTPUT("HPOUTL"),
@@ -379,6 +382,18 @@ static const struct snd_soc_dapm_route wm9712_audio_map[] = {
379 {"Mic PGA", NULL, "MIC1"}, 382 {"Mic PGA", NULL, "MIC1"},
380 {"Mic PGA", NULL, "MIC2"}, 383 {"Mic PGA", NULL, "MIC2"},
381 384
385 /* microphones */
386 {"Differential Mic", NULL, "MIC1"},
387 {"Differential Mic", NULL, "MIC2"},
388 {"Left Mic Select Source", "Mic 1", "MIC1"},
389 {"Left Mic Select Source", "Mic 2", "MIC2"},
390 {"Left Mic Select Source", "Stereo", "MIC1"},
391 {"Left Mic Select Source", "Differential", "Differential Mic"},
392 {"Right Mic Select Source", "Mic 1", "MIC1"},
393 {"Right Mic Select Source", "Mic 2", "MIC2"},
394 {"Right Mic Select Source", "Stereo", "MIC2"},
395 {"Right Mic Select Source", "Differential", "Differential Mic"},
396
382 /* left capture selector */ 397 /* left capture selector */
383 {"Left Capture Select", "Mic", "MIC1"}, 398 {"Left Capture Select", "Mic", "MIC1"},
384 {"Left Capture Select", "Speaker Mixer", "Speaker Mixer"}, 399 {"Left Capture Select", "Speaker Mixer", "Speaker Mixer"},
@@ -619,6 +634,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
619{ 634{
620 int ret = 0; 635 int ret = 0;
621 636
637 codec->control_data = codec; /* we don't use regmap! */
622 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 638 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
623 if (ret < 0) { 639 if (ret < 0) {
624 printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); 640 printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 2d22cc70d536..d0b8a3287a85 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm9713.c -- ALSA Soc WM9713 codec support 2 * wm9713.c -- ALSA Soc WM9713 codec support
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC. 4 * Copyright 2006-10 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood <lrg@slimlogic.co.uk> 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
@@ -1196,6 +1196,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
1196 if (wm9713 == NULL) 1196 if (wm9713 == NULL)
1197 return -ENOMEM; 1197 return -ENOMEM;
1198 snd_soc_codec_set_drvdata(codec, wm9713); 1198 snd_soc_codec_set_drvdata(codec, wm9713);
1199 codec->control_data = wm9713; /* we don't use regmap! */
1199 1200
1200 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 1201 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
1201 if (ret < 0) 1202 if (ret < 0)
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index dfe957a47f29..61baa48823cb 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm_hubs.c -- WM8993/4 common code 2 * wm_hubs.c -- WM8993/4 common code
3 * 3 *
4 * Copyright 2009 Wolfson Microelectronics plc 4 * Copyright 2009-12 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 95441bfc8190..ce5e5cd254dd 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -380,14 +380,20 @@ static void mcasp_start_tx(struct davinci_audio_dev *dev)
380static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) 380static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream)
381{ 381{
382 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 382 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
383 if (dev->txnumevt) /* enable FIFO */ 383 if (dev->txnumevt) { /* enable FIFO */
384 mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
385 FIFO_ENABLE);
384 mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, 386 mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
385 FIFO_ENABLE); 387 FIFO_ENABLE);
388 }
386 mcasp_start_tx(dev); 389 mcasp_start_tx(dev);
387 } else { 390 } else {
388 if (dev->rxnumevt) /* enable FIFO */ 391 if (dev->rxnumevt) { /* enable FIFO */
392 mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
393 FIFO_ENABLE);
389 mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, 394 mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
390 FIFO_ENABLE); 395 FIFO_ENABLE);
396 }
391 mcasp_start_rx(dev); 397 mcasp_start_rx(dev);
392 } 398 }
393} 399}
diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig
new file mode 100644
index 000000000000..e334900cf0b8
--- /dev/null
+++ b/sound/soc/dwc/Kconfig
@@ -0,0 +1,9 @@
1config SND_DESIGNWARE_I2S
2 tristate "Synopsys I2S Device Driver"
3 depends on CLKDEV_LOOKUP
4 help
5 Say Y or M if you want to add support for I2S driver for
6 Synopsys desigwnware I2S device. The device supports upto
7 maximum of 8 channels each for play and record.
8
9
diff --git a/sound/soc/dwc/Makefile b/sound/soc/dwc/Makefile
new file mode 100644
index 000000000000..319371f690f4
--- /dev/null
+++ b/sound/soc/dwc/Makefile
@@ -0,0 +1,3 @@
1# SYNOPSYS Platform Support
2obj-$(CONFIG_SND_DESIGNWARE_I2S) += designware_i2s.o
3
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
new file mode 100644
index 000000000000..1aa51300c564
--- /dev/null
+++ b/sound/soc/dwc/designware_i2s.c
@@ -0,0 +1,455 @@
1/*
2 * ALSA SoC Synopsys I2S Audio Layer
3 *
4 * sound/soc/spear/designware_i2s.c
5 *
6 * Copyright (C) 2010 ST Microelectronics
7 * Rajeev Kumar <rajeev-dlh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include <linux/clk.h>
15#include <linux/device.h>
16#include <linux/init.h>
17#include <linux/io.h>
18#include <linux/interrupt.h>
19#include <linux/module.h>
20#include <linux/slab.h>
21#include <sound/designware_i2s.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25
26/* common register for all channel */
27#define IER 0x000
28#define IRER 0x004
29#define ITER 0x008
30#define CER 0x00C
31#define CCR 0x010
32#define RXFFR 0x014
33#define TXFFR 0x018
34
35/* I2STxRxRegisters for all channels */
36#define LRBR_LTHR(x) (0x40 * x + 0x020)
37#define RRBR_RTHR(x) (0x40 * x + 0x024)
38#define RER(x) (0x40 * x + 0x028)
39#define TER(x) (0x40 * x + 0x02C)
40#define RCR(x) (0x40 * x + 0x030)
41#define TCR(x) (0x40 * x + 0x034)
42#define ISR(x) (0x40 * x + 0x038)
43#define IMR(x) (0x40 * x + 0x03C)
44#define ROR(x) (0x40 * x + 0x040)
45#define TOR(x) (0x40 * x + 0x044)
46#define RFCR(x) (0x40 * x + 0x048)
47#define TFCR(x) (0x40 * x + 0x04C)
48#define RFF(x) (0x40 * x + 0x050)
49#define TFF(x) (0x40 * x + 0x054)
50
51/* I2SCOMPRegisters */
52#define I2S_COMP_PARAM_2 0x01F0
53#define I2S_COMP_PARAM_1 0x01F4
54#define I2S_COMP_VERSION 0x01F8
55#define I2S_COMP_TYPE 0x01FC
56
57#define MAX_CHANNEL_NUM 8
58#define MIN_CHANNEL_NUM 2
59
60struct dw_i2s_dev {
61 void __iomem *i2s_base;
62 struct clk *clk;
63 int active;
64 unsigned int capability;
65 struct device *dev;
66
67 /* data related to DMA transfers b/w i2s and DMAC */
68 struct i2s_dma_data play_dma_data;
69 struct i2s_dma_data capture_dma_data;
70 struct i2s_clk_config_data config;
71 int (*i2s_clk_cfg)(struct i2s_clk_config_data *config);
72};
73
74static inline void i2s_write_reg(void __iomem *io_base, int reg, u32 val)
75{
76 writel(val, io_base + reg);
77}
78
79static inline u32 i2s_read_reg(void __iomem *io_base, int reg)
80{
81 return readl(io_base + reg);
82}
83
84static inline void i2s_disable_channels(struct dw_i2s_dev *dev, u32 stream)
85{
86 u32 i = 0;
87
88 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
89 for (i = 0; i < 4; i++)
90 i2s_write_reg(dev->i2s_base, TER(i), 0);
91 } else {
92 for (i = 0; i < 4; i++)
93 i2s_write_reg(dev->i2s_base, RER(i), 0);
94 }
95}
96
97static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream)
98{
99 u32 i = 0;
100
101 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
102 for (i = 0; i < 4; i++)
103 i2s_write_reg(dev->i2s_base, TOR(i), 0);
104 } else {
105 for (i = 0; i < 4; i++)
106 i2s_write_reg(dev->i2s_base, ROR(i), 0);
107 }
108}
109
110static void i2s_start(struct dw_i2s_dev *dev,
111 struct snd_pcm_substream *substream)
112{
113
114 i2s_write_reg(dev->i2s_base, IER, 1);
115
116 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
117 i2s_write_reg(dev->i2s_base, ITER, 1);
118 else
119 i2s_write_reg(dev->i2s_base, IRER, 1);
120
121 i2s_write_reg(dev->i2s_base, CER, 1);
122}
123
124static void i2s_stop(struct dw_i2s_dev *dev,
125 struct snd_pcm_substream *substream)
126{
127 u32 i = 0, irq;
128
129 i2s_clear_irqs(dev, substream->stream);
130 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
131 i2s_write_reg(dev->i2s_base, ITER, 0);
132
133 for (i = 0; i < 4; i++) {
134 irq = i2s_read_reg(dev->i2s_base, IMR(i));
135 i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x30);
136 }
137 } else {
138 i2s_write_reg(dev->i2s_base, IRER, 0);
139
140 for (i = 0; i < 4; i++) {
141 irq = i2s_read_reg(dev->i2s_base, IMR(i));
142 i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x03);
143 }
144 }
145
146 if (!dev->active) {
147 i2s_write_reg(dev->i2s_base, CER, 0);
148 i2s_write_reg(dev->i2s_base, IER, 0);
149 }
150}
151
152static int dw_i2s_startup(struct snd_pcm_substream *substream,
153 struct snd_soc_dai *cpu_dai)
154{
155 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
156 struct i2s_dma_data *dma_data = NULL;
157
158 if (!(dev->capability & DWC_I2S_RECORD) &&
159 (substream->stream == SNDRV_PCM_STREAM_CAPTURE))
160 return -EINVAL;
161
162 if (!(dev->capability & DWC_I2S_PLAY) &&
163 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
164 return -EINVAL;
165
166 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
167 dma_data = &dev->play_dma_data;
168 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
169 dma_data = &dev->capture_dma_data;
170
171 snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)dma_data);
172
173 return 0;
174}
175
176static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
177 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
178{
179 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
180 struct i2s_clk_config_data *config = &dev->config;
181 u32 ccr, xfer_resolution, ch_reg, irq;
182 int ret;
183
184 switch (params_format(params)) {
185 case SNDRV_PCM_FORMAT_S16_LE:
186 config->data_width = 16;
187 ccr = 0x00;
188 xfer_resolution = 0x02;
189 break;
190
191 case SNDRV_PCM_FORMAT_S24_LE:
192 config->data_width = 24;
193 ccr = 0x08;
194 xfer_resolution = 0x04;
195 break;
196
197 case SNDRV_PCM_FORMAT_S32_LE:
198 config->data_width = 32;
199 ccr = 0x10;
200 xfer_resolution = 0x05;
201 break;
202
203 default:
204 dev_err(dev->dev, "designware-i2s: unsuppted PCM fmt");
205 return -EINVAL;
206 }
207
208 config->chan_nr = params_channels(params);
209
210 switch (config->chan_nr) {
211 case EIGHT_CHANNEL_SUPPORT:
212 ch_reg = 3;
213 case SIX_CHANNEL_SUPPORT:
214 ch_reg = 2;
215 case FOUR_CHANNEL_SUPPORT:
216 ch_reg = 1;
217 case TWO_CHANNEL_SUPPORT:
218 ch_reg = 0;
219 break;
220 default:
221 dev_err(dev->dev, "channel not supported\n");
222 }
223
224 i2s_disable_channels(dev, substream->stream);
225
226 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
227 i2s_write_reg(dev->i2s_base, TCR(ch_reg), xfer_resolution);
228 i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02);
229 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
230 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30);
231 i2s_write_reg(dev->i2s_base, TER(ch_reg), 1);
232 } else {
233 i2s_write_reg(dev->i2s_base, RCR(ch_reg), xfer_resolution);
234 i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07);
235 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
236 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03);
237 i2s_write_reg(dev->i2s_base, RER(ch_reg), 1);
238 }
239
240 i2s_write_reg(dev->i2s_base, CCR, ccr);
241
242 config->sample_rate = params_rate(params);
243
244 if (!dev->i2s_clk_cfg)
245 return -EINVAL;
246
247 ret = dev->i2s_clk_cfg(config);
248 if (ret < 0) {
249 dev_err(dev->dev, "runtime audio clk config fail\n");
250 return ret;
251 }
252
253 return 0;
254}
255
256static void dw_i2s_shutdown(struct snd_pcm_substream *substream,
257 struct snd_soc_dai *dai)
258{
259 snd_soc_dai_set_dma_data(dai, substream, NULL);
260}
261
262static int dw_i2s_trigger(struct snd_pcm_substream *substream,
263 int cmd, struct snd_soc_dai *dai)
264{
265 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
266 int ret = 0;
267
268 switch (cmd) {
269 case SNDRV_PCM_TRIGGER_START:
270 case SNDRV_PCM_TRIGGER_RESUME:
271 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
272 dev->active++;
273 i2s_start(dev, substream);
274 break;
275
276 case SNDRV_PCM_TRIGGER_STOP:
277 case SNDRV_PCM_TRIGGER_SUSPEND:
278 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
279 dev->active--;
280 i2s_stop(dev, substream);
281 break;
282 default:
283 ret = -EINVAL;
284 break;
285 }
286 return ret;
287}
288
289static struct snd_soc_dai_ops dw_i2s_dai_ops = {
290 .startup = dw_i2s_startup,
291 .shutdown = dw_i2s_shutdown,
292 .hw_params = dw_i2s_hw_params,
293 .trigger = dw_i2s_trigger,
294};
295
296#ifdef CONFIG_PM
297
298static int dw_i2s_suspend(struct snd_soc_dai *dai)
299{
300 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
301
302 clk_disable(dev->clk);
303 return 0;
304}
305
306static int dw_i2s_resume(struct snd_soc_dai *dai)
307{
308 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
309
310 clk_enable(dev->clk);
311 return 0;
312}
313
314#else
315#define dw_i2s_suspend NULL
316#define dw_i2s_resume NULL
317#endif
318
319static int dw_i2s_probe(struct platform_device *pdev)
320{
321 const struct i2s_platform_data *pdata = pdev->dev.platform_data;
322 struct dw_i2s_dev *dev;
323 struct resource *res;
324 int ret;
325 unsigned int cap;
326 struct snd_soc_dai_driver *dw_i2s_dai;
327
328 if (!pdata) {
329 dev_err(&pdev->dev, "Invalid platform data\n");
330 return -EINVAL;
331 }
332
333 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
334 if (!res) {
335 dev_err(&pdev->dev, "no i2s resource defined\n");
336 return -ENODEV;
337 }
338
339 if (!devm_request_mem_region(&pdev->dev, res->start,
340 resource_size(res), pdev->name)) {
341 dev_err(&pdev->dev, "i2s region already claimed\n");
342 return -EBUSY;
343 }
344
345 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
346 if (!dev) {
347 dev_warn(&pdev->dev, "kzalloc fail\n");
348 return -ENOMEM;
349 }
350
351 dev->i2s_base = devm_ioremap(&pdev->dev, res->start,
352 resource_size(res));
353 if (!dev->i2s_base) {
354 dev_err(&pdev->dev, "ioremap fail for i2s_region\n");
355 return -ENOMEM;
356 }
357
358 cap = pdata->cap;
359 dev->capability = cap;
360 dev->i2s_clk_cfg = pdata->i2s_clk_cfg;
361
362 /* Set DMA slaves info */
363
364 dev->play_dma_data.data = pdata->play_dma_data;
365 dev->capture_dma_data.data = pdata->capture_dma_data;
366 dev->play_dma_data.addr = res->start + I2S_TXDMA;
367 dev->capture_dma_data.addr = res->start + I2S_RXDMA;
368 dev->play_dma_data.max_burst = 16;
369 dev->capture_dma_data.max_burst = 16;
370 dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
371 dev->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
372 dev->play_dma_data.filter = pdata->filter;
373 dev->capture_dma_data.filter = pdata->filter;
374
375 dev->clk = clk_get(&pdev->dev, NULL);
376 if (IS_ERR(dev->clk))
377 return PTR_ERR(dev->clk);
378
379 ret = clk_enable(dev->clk);
380 if (ret < 0)
381 goto err_clk_put;
382
383 dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL);
384 if (!dw_i2s_dai) {
385 dev_err(&pdev->dev, "mem allocation failed for dai driver\n");
386 ret = -ENOMEM;
387 goto err_clk_disable;
388 }
389
390 if (cap & DWC_I2S_PLAY) {
391 dev_dbg(&pdev->dev, " SPEAr: play supported\n");
392 dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM;
393 dw_i2s_dai->playback.channels_max = pdata->channel;
394 dw_i2s_dai->playback.formats = pdata->snd_fmts;
395 dw_i2s_dai->playback.rates = pdata->snd_rates;
396 }
397
398 if (cap & DWC_I2S_RECORD) {
399 dev_dbg(&pdev->dev, "SPEAr: record supported\n");
400 dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM;
401 dw_i2s_dai->capture.channels_max = pdata->channel;
402 dw_i2s_dai->capture.formats = pdata->snd_fmts;
403 dw_i2s_dai->capture.rates = pdata->snd_rates;
404 }
405
406 dw_i2s_dai->ops = &dw_i2s_dai_ops;
407 dw_i2s_dai->suspend = dw_i2s_suspend;
408 dw_i2s_dai->resume = dw_i2s_resume;
409
410 dev->dev = &pdev->dev;
411 dev_set_drvdata(&pdev->dev, dev);
412 ret = snd_soc_register_dai(&pdev->dev, dw_i2s_dai);
413 if (ret != 0) {
414 dev_err(&pdev->dev, "not able to register dai\n");
415 goto err_set_drvdata;
416 }
417
418 return 0;
419
420err_set_drvdata:
421 dev_set_drvdata(&pdev->dev, NULL);
422err_clk_disable:
423 clk_disable(dev->clk);
424err_clk_put:
425 clk_put(dev->clk);
426 return ret;
427}
428
429static int dw_i2s_remove(struct platform_device *pdev)
430{
431 struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
432
433 snd_soc_unregister_dai(&pdev->dev);
434 dev_set_drvdata(&pdev->dev, NULL);
435
436 clk_put(dev->clk);
437
438 return 0;
439}
440
441static struct platform_driver dw_i2s_driver = {
442 .probe = dw_i2s_probe,
443 .remove = dw_i2s_remove,
444 .driver = {
445 .name = "designware-i2s",
446 .owner = THIS_MODULE,
447 },
448};
449
450module_platform_driver(dw_i2s_driver);
451
452MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>");
453MODULE_DESCRIPTION("DESIGNWARE I2S SoC Interface");
454MODULE_LICENSE("GPL");
455MODULE_ALIAS("platform:designware_i2s");
diff --git a/sound/soc/ep93xx/ep93xx-ac97.c b/sound/soc/ep93xx/ep93xx-ac97.c
index bdffab33e160..c3521653cfd3 100644
--- a/sound/soc/ep93xx/ep93xx-ac97.c
+++ b/sound/soc/ep93xx/ep93xx-ac97.c
@@ -21,7 +21,7 @@
21#include <sound/ac97_codec.h> 21#include <sound/ac97_codec.h>
22#include <sound/soc.h> 22#include <sound/soc.h>
23 23
24#include <mach/dma.h> 24#include <linux/platform_data/dma-ep93xx.h>
25#include "ep93xx-pcm.h" 25#include "ep93xx-pcm.h"
26 26
27/* 27/*
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c
index 8df8f6dc474f..ac4a7515e7be 100644
--- a/sound/soc/ep93xx/ep93xx-i2s.c
+++ b/sound/soc/ep93xx/ep93xx-i2s.c
@@ -28,7 +28,7 @@
28 28
29#include <mach/hardware.h> 29#include <mach/hardware.h>
30#include <mach/ep93xx-regs.h> 30#include <mach/ep93xx-regs.h>
31#include <mach/dma.h> 31#include <linux/platform_data/dma-ep93xx.h>
32 32
33#include "ep93xx-pcm.h" 33#include "ep93xx-pcm.h"
34 34
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index 162dbb74f4cc..665d9c94cc17 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -25,7 +25,7 @@
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/dmaengine_pcm.h> 26#include <sound/dmaengine_pcm.h>
27 27
28#include <mach/dma.h> 28#include <linux/platform_data/dma-ep93xx.h>
29#include <mach/hardware.h> 29#include <mach/hardware.h>
30#include <mach/ep93xx-regs.h> 30#include <mach/ep93xx-regs.h>
31 31
@@ -136,7 +136,7 @@ static struct snd_pcm_ops ep93xx_pcm_ops = {
136 .hw_params = ep93xx_pcm_hw_params, 136 .hw_params = ep93xx_pcm_hw_params,
137 .hw_free = ep93xx_pcm_hw_free, 137 .hw_free = ep93xx_pcm_hw_free,
138 .trigger = snd_dmaengine_pcm_trigger, 138 .trigger = snd_dmaengine_pcm_trigger,
139 .pointer = snd_dmaengine_pcm_pointer, 139 .pointer = snd_dmaengine_pcm_pointer_no_residue,
140 .mmap = ep93xx_pcm_mmap, 140 .mmap = ep93xx_pcm_mmap,
141}; 141};
142 142
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 080327414c6b..e7c800ebbd75 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -156,7 +156,7 @@ static void __init audmux_debugfs_init(void)
156 return; 156 return;
157 } 157 }
158 158
159 for (i = 0; i < MX31_AUDMUX_PORT6_SSI_PINS_6 + 1; i++) { 159 for (i = 0; i < MX31_AUDMUX_PORT7_SSI_PINS_7 + 1; i++) {
160 snprintf(buf, sizeof(buf), "ssi%d", i); 160 snprintf(buf, sizeof(buf), "ssi%d", i);
161 if (!debugfs_create_file(buf, 0444, audmux_debugfs_root, 161 if (!debugfs_create_file(buf, 0444, audmux_debugfs_root,
162 (void *)i, &audmux_debugfs_fops)) 162 (void *)i, &audmux_debugfs_fops))
diff --git a/sound/soc/fsl/imx-audmux.h b/sound/soc/fsl/imx-audmux.h
index 04ebbab8d7b9..b8ff44b9dafa 100644
--- a/sound/soc/fsl/imx-audmux.h
+++ b/sound/soc/fsl/imx-audmux.h
@@ -14,6 +14,7 @@
14#define MX31_AUDMUX_PORT4_SSI_PINS_4 3 14#define MX31_AUDMUX_PORT4_SSI_PINS_4 3
15#define MX31_AUDMUX_PORT5_SSI_PINS_5 4 15#define MX31_AUDMUX_PORT5_SSI_PINS_5 4
16#define MX31_AUDMUX_PORT6_SSI_PINS_6 5 16#define MX31_AUDMUX_PORT6_SSI_PINS_6 5
17#define MX31_AUDMUX_PORT7_SSI_PINS_7 6
17 18
18#define MX51_AUDMUX_PORT1_SSI0 0 19#define MX51_AUDMUX_PORT1_SSI0 0
19#define MX51_AUDMUX_PORT2_SSI1 1 20#define MX51_AUDMUX_PORT2_SSI1 1
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c
index f59c34943662..549b31fdc9dd 100644
--- a/sound/soc/fsl/imx-mc13783.c
+++ b/sound/soc/fsl/imx-mc13783.c
@@ -111,22 +111,39 @@ static int __devinit imx_mc13783_probe(struct platform_device *pdev)
111 return ret; 111 return ret;
112 } 112 }
113 113
114 imx_audmux_v2_configure_port(MX31_AUDMUX_PORT4_SSI_PINS_4, 114 if (machine_is_mx31_3ds()) {
115 IMX_AUDMUX_V2_PTCR_SYN, 115 imx_audmux_v2_configure_port(MX31_AUDMUX_PORT4_SSI_PINS_4,
116 IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0) | 116 IMX_AUDMUX_V2_PTCR_SYN,
117 IMX_AUDMUX_V2_PDCR_MODE(1) | 117 IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0) |
118 IMX_AUDMUX_V2_PDCR_INMMASK(0xfc)); 118 IMX_AUDMUX_V2_PDCR_MODE(1) |
119 imx_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0, 119 IMX_AUDMUX_V2_PDCR_INMMASK(0xfc));
120 IMX_AUDMUX_V2_PTCR_SYN | 120 imx_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0,
121 IMX_AUDMUX_V2_PTCR_TFSDIR | 121 IMX_AUDMUX_V2_PTCR_SYN |
122 IMX_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) | 122 IMX_AUDMUX_V2_PTCR_TFSDIR |
123 IMX_AUDMUX_V2_PTCR_TCLKDIR | 123 IMX_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) |
124 IMX_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) | 124 IMX_AUDMUX_V2_PTCR_TCLKDIR |
125 IMX_AUDMUX_V2_PTCR_RFSDIR | 125 IMX_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) |
126 IMX_AUDMUX_V2_PTCR_RFSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) | 126 IMX_AUDMUX_V2_PTCR_RFSDIR |
127 IMX_AUDMUX_V2_PTCR_RCLKDIR | 127 IMX_AUDMUX_V2_PTCR_RFSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) |
128 IMX_AUDMUX_V2_PTCR_RCSEL(MX31_AUDMUX_PORT4_SSI_PINS_4), 128 IMX_AUDMUX_V2_PTCR_RCLKDIR |
129 IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT4_SSI_PINS_4)); 129 IMX_AUDMUX_V2_PTCR_RCSEL(MX31_AUDMUX_PORT4_SSI_PINS_4),
130 IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT4_SSI_PINS_4));
131 } else if (machine_is_mx27_3ds()) {
132 imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
133 IMX_AUDMUX_V1_PCR_SYN |
134 IMX_AUDMUX_V1_PCR_TFSDIR |
135 IMX_AUDMUX_V1_PCR_TCLKDIR |
136 IMX_AUDMUX_V1_PCR_RFSDIR |
137 IMX_AUDMUX_V1_PCR_RCLKDIR |
138 IMX_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
139 IMX_AUDMUX_V1_PCR_RFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
140 IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4)
141 );
142 imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR3_SSI_PINS_4,
143 IMX_AUDMUX_V1_PCR_SYN |
144 IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
145 );
146 }
130 147
131 return ret; 148 return ret;
132} 149}
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index f3c0a5ef35c8..89a7755b6f56 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -30,7 +30,7 @@
30#include <sound/soc.h> 30#include <sound/soc.h>
31#include <sound/dmaengine_pcm.h> 31#include <sound/dmaengine_pcm.h>
32 32
33#include <mach/dma.h> 33#include <linux/platform_data/dma-imx.h>
34 34
35#include "imx-pcm.h" 35#include "imx-pcm.h"
36 36
@@ -141,7 +141,7 @@ static struct snd_pcm_ops imx_pcm_ops = {
141 .ioctl = snd_pcm_lib_ioctl, 141 .ioctl = snd_pcm_lib_ioctl,
142 .hw_params = snd_imx_pcm_hw_params, 142 .hw_params = snd_imx_pcm_hw_params,
143 .trigger = snd_dmaengine_pcm_trigger, 143 .trigger = snd_dmaengine_pcm_trigger,
144 .pointer = snd_dmaengine_pcm_pointer, 144 .pointer = snd_dmaengine_pcm_pointer_no_residue,
145 .mmap = snd_imx_pcm_mmap, 145 .mmap = snd_imx_pcm_mmap,
146}; 146};
147 147
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index ee27ba3933bd..22c6130957ba 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -30,7 +30,7 @@
30#include <asm/fiq.h> 30#include <asm/fiq.h>
31 31
32#include <mach/irqs.h> 32#include <mach/irqs.h>
33#include <mach/ssi.h> 33#include <linux/platform_data/asoc-imx-ssi.h>
34 34
35#include "imx-ssi.h" 35#include "imx-ssi.h"
36 36
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c
index 3a729caeb8c8..199408ec4261 100644
--- a/sound/soc/fsl/imx-sgtl5000.c
+++ b/sound/soc/fsl/imx-sgtl5000.c
@@ -94,9 +94,8 @@ static int __devinit imx_sgtl5000_probe(struct platform_device *pdev)
94 dev_err(&pdev->dev, "audmux internal port setup failed\n"); 94 dev_err(&pdev->dev, "audmux internal port setup failed\n");
95 return ret; 95 return ret;
96 } 96 }
97 imx_audmux_v2_configure_port(ext_port, 97 ret = imx_audmux_v2_configure_port(ext_port,
98 IMX_AUDMUX_V2_PTCR_SYN | 98 IMX_AUDMUX_V2_PTCR_SYN,
99 IMX_AUDMUX_V2_PTCR_TCSEL(int_port),
100 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)); 99 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
101 if (ret) { 100 if (ret) {
102 dev_err(&pdev->dev, "audmux external port setup failed\n"); 101 dev_err(&pdev->dev, "audmux external port setup failed\n");
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index 28dd76c7cb1c..e6a17baca1ee 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -47,7 +47,7 @@
47#include <sound/pcm_params.h> 47#include <sound/pcm_params.h>
48#include <sound/soc.h> 48#include <sound/soc.h>
49 49
50#include <mach/ssi.h> 50#include <linux/platform_data/asoc-imx-ssi.h>
51#include <mach/hardware.h> 51#include <mach/hardware.h>
52 52
53#include "imx-ssi.h" 53#include "imx-ssi.h"
@@ -380,13 +380,14 @@ static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
380static struct snd_soc_dai_driver imx_ssi_dai = { 380static struct snd_soc_dai_driver imx_ssi_dai = {
381 .probe = imx_ssi_dai_probe, 381 .probe = imx_ssi_dai_probe,
382 .playback = { 382 .playback = {
383 .channels_min = 1, 383 /* The SSI does not support monaural audio. */
384 .channels_min = 2,
384 .channels_max = 2, 385 .channels_max = 2,
385 .rates = SNDRV_PCM_RATE_8000_96000, 386 .rates = SNDRV_PCM_RATE_8000_96000,
386 .formats = SNDRV_PCM_FMTBIT_S16_LE, 387 .formats = SNDRV_PCM_FMTBIT_S16_LE,
387 }, 388 },
388 .capture = { 389 .capture = {
389 .channels_min = 1, 390 .channels_min = 2,
390 .channels_max = 2, 391 .channels_max = 2,
391 .rates = SNDRV_PCM_RATE_8000_96000, 392 .rates = SNDRV_PCM_RATE_8000_96000,
392 .formats = SNDRV_PCM_FMTBIT_S16_LE, 393 .formats = SNDRV_PCM_FMTBIT_S16_LE,
diff --git a/sound/soc/fsl/imx-ssi.h b/sound/soc/fsl/imx-ssi.h
index 5744e86ca878..dc114bdedce5 100644
--- a/sound/soc/fsl/imx-ssi.h
+++ b/sound/soc/fsl/imx-ssi.h
@@ -186,7 +186,7 @@
186#define DRV_NAME "imx-ssi" 186#define DRV_NAME "imx-ssi"
187 187
188#include <linux/dmaengine.h> 188#include <linux/dmaengine.h>
189#include <mach/dma.h> 189#include <linux/platform_data/dma-imx.h>
190#include "imx-pcm.h" 190#include "imx-pcm.h"
191 191
192struct imx_ssi { 192struct imx_ssi {
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index fa4556750451..542538d10ab7 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -21,7 +21,7 @@
21#include <sound/pcm.h> 21#include <sound/pcm.h>
22#include <sound/pcm_params.h> 22#include <sound/pcm_params.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <plat/audio.h> 24#include <linux/platform_data/asoc-kirkwood.h>
25#include "kirkwood.h" 25#include "kirkwood.h"
26 26
27#define DRV_NAME "kirkwood-i2s" 27#define DRV_NAME "kirkwood-i2s"
@@ -458,7 +458,13 @@ static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev)
458 } 458 }
459 clk_prepare_enable(priv->clk); 459 clk_prepare_enable(priv->clk);
460 460
461 return snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai); 461 err = snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai);
462 if (!err)
463 return 0;
464 dev_err(&pdev->dev, "snd_soc_register_dai failed\n");
465
466 clk_disable_unprepare(priv->clk);
467 clk_put(priv->clk);
462 468
463err_ioremap: 469err_ioremap:
464 iounmap(priv->io); 470 iounmap(priv->io);
diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c
index 80bd59c33be4..c28540aeea25 100644
--- a/sound/soc/kirkwood/kirkwood-openrd.c
+++ b/sound/soc/kirkwood/kirkwood-openrd.c
@@ -17,7 +17,7 @@
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <sound/soc.h> 18#include <sound/soc.h>
19#include <mach/kirkwood.h> 19#include <mach/kirkwood.h>
20#include <plat/audio.h> 20#include <linux/platform_data/asoc-kirkwood.h>
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
22#include "../codecs/cs42l51.h" 22#include "../codecs/cs42l51.h"
23 23
diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c
index f8983635f7ef..c67bbc574987 100644
--- a/sound/soc/kirkwood/kirkwood-t5325.c
+++ b/sound/soc/kirkwood/kirkwood-t5325.c
@@ -16,7 +16,7 @@
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <sound/soc.h> 17#include <sound/soc.h>
18#include <mach/kirkwood.h> 18#include <mach/kirkwood.h>
19#include <plat/audio.h> 19#include <linux/platform_data/asoc-kirkwood.h>
20#include <asm/mach-types.h> 20#include <asm/mach-types.h>
21#include "../codecs/alc5623.h" 21#include "../codecs/alc5623.h"
22 22
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig
index 99a997f19bb9..b6fa77678d97 100644
--- a/sound/soc/mxs/Kconfig
+++ b/sound/soc/mxs/Kconfig
@@ -10,7 +10,7 @@ menuconfig SND_MXS_SOC
10if SND_MXS_SOC 10if SND_MXS_SOC
11 11
12config SND_SOC_MXS_SGTL5000 12config SND_SOC_MXS_SGTL5000
13 tristate "SoC Audio support for i.MX boards with sgtl5000" 13 tristate "SoC Audio support for MXS boards with sgtl5000"
14 depends on I2C 14 depends on I2C
15 select SND_SOC_SGTL5000 15 select SND_SOC_SGTL5000
16 help 16 help
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
index 373dec90579f..f82d766cbf9e 100644
--- a/sound/soc/mxs/mxs-pcm.c
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -141,7 +141,7 @@ static struct snd_pcm_ops mxs_pcm_ops = {
141 .ioctl = snd_pcm_lib_ioctl, 141 .ioctl = snd_pcm_lib_ioctl,
142 .hw_params = snd_mxs_pcm_hw_params, 142 .hw_params = snd_mxs_pcm_hw_params,
143 .trigger = snd_dmaengine_pcm_trigger, 143 .trigger = snd_dmaengine_pcm_trigger,
144 .pointer = snd_dmaengine_pcm_pointer, 144 .pointer = snd_dmaengine_pcm_pointer_no_residue,
145 .mmap = snd_mxs_pcm_mmap, 145 .mmap = snd_mxs_pcm_mmap,
146}; 146};
147 147
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index aba71bfa33b1..b3030718c228 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -394,9 +394,14 @@ static int mxs_saif_hw_params(struct snd_pcm_substream *substream,
394 struct snd_soc_dai *cpu_dai) 394 struct snd_soc_dai *cpu_dai)
395{ 395{
396 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); 396 struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai);
397 struct mxs_saif *master_saif;
397 u32 scr, stat; 398 u32 scr, stat;
398 int ret; 399 int ret;
399 400
401 master_saif = mxs_saif_get_master(saif);
402 if (!master_saif)
403 return -EINVAL;
404
400 /* mclk should already be set */ 405 /* mclk should already be set */
401 if (!saif->mclk && saif->mclk_in_use) { 406 if (!saif->mclk && saif->mclk_in_use) {
402 dev_err(cpu_dai->dev, "set mclk first\n"); 407 dev_err(cpu_dai->dev, "set mclk first\n");
@@ -420,6 +425,25 @@ static int mxs_saif_hw_params(struct snd_pcm_substream *substream,
420 return ret; 425 return ret;
421 } 426 }
422 427
428 /* prepare clk in hw_param, enable in trigger */
429 clk_prepare(saif->clk);
430 if (saif != master_saif) {
431 /*
432 * Set an initial clock rate for the saif internal logic to work
433 * properly. This is important when working in EXTMASTER mode
434 * that uses the other saif's BITCLK&LRCLK but it still needs a
435 * basic clock which should be fast enough for the internal
436 * logic.
437 */
438 clk_enable(saif->clk);
439 ret = clk_set_rate(saif->clk, 24000000);
440 clk_disable(saif->clk);
441 if (ret)
442 return ret;
443
444 clk_prepare(master_saif->clk);
445 }
446
423 scr = __raw_readl(saif->base + SAIF_CTRL); 447 scr = __raw_readl(saif->base + SAIF_CTRL);
424 448
425 scr &= ~BM_SAIF_CTRL_WORD_LENGTH; 449 scr &= ~BM_SAIF_CTRL_WORD_LENGTH;
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
index 3e6e8764b2e6..215113b05f7d 100644
--- a/sound/soc/mxs/mxs-sgtl5000.c
+++ b/sound/soc/mxs/mxs-sgtl5000.c
@@ -133,7 +133,7 @@ static int __devinit mxs_sgtl5000_probe_dt(struct platform_device *pdev)
133 mxs_sgtl5000_dai[i].codec_name = NULL; 133 mxs_sgtl5000_dai[i].codec_name = NULL;
134 mxs_sgtl5000_dai[i].codec_of_node = codec_np; 134 mxs_sgtl5000_dai[i].codec_of_node = codec_np;
135 mxs_sgtl5000_dai[i].cpu_dai_name = NULL; 135 mxs_sgtl5000_dai[i].cpu_dai_name = NULL;
136 mxs_sgtl5000_dai[i].cpu_dai_of_node = saif_np[i]; 136 mxs_sgtl5000_dai[i].cpu_of_node = saif_np[i];
137 mxs_sgtl5000_dai[i].platform_name = NULL; 137 mxs_sgtl5000_dai[i].platform_name = NULL;
138 mxs_sgtl5000_dai[i].platform_of_node = saif_np[i]; 138 mxs_sgtl5000_dai[i].platform_of_node = saif_np[i];
139 } 139 }
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index 009533ab8d18..a52e87d28b6e 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -27,7 +27,7 @@
27#include <asm/mach-types.h> 27#include <asm/mach-types.h>
28#include <mach/hardware.h> 28#include <mach/hardware.h>
29#include <mach/gpio.h> 29#include <mach/gpio.h>
30#include <plat/mcbsp.h> 30#include <linux/platform_data/asoc-ti-mcbsp.h>
31 31
32#include "omap-mcbsp.h" 32#include "omap-mcbsp.h"
33#include "omap-pcm.h" 33#include "omap-pcm.h"
@@ -59,7 +59,7 @@ static int am3517evm_hw_params(struct snd_pcm_substream *substream,
59 return ret; 59 return ret;
60 } 60 }
61 61
62 snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0, 62 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0,
63 SND_SOC_CLOCK_IN); 63 SND_SOC_CLOCK_IN);
64 if (ret < 0) { 64 if (ret < 0) {
65 printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n"); 65 printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n");
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 7d4fa8ed6699..dc0ee7626626 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -32,8 +32,8 @@
32 32
33#include <asm/mach-types.h> 33#include <asm/mach-types.h>
34 34
35#include <plat/board-ams-delta.h> 35#include <mach/board-ams-delta.h>
36#include <plat/mcbsp.h> 36#include <linux/platform_data/asoc-ti-mcbsp.h>
37 37
38#include "omap-mcbsp.h" 38#include "omap-mcbsp.h"
39#include "omap-pcm.h" 39#include "omap-pcm.h"
diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c
index e8357819175b..5ed871676ed0 100644
--- a/sound/soc/omap/igep0020.c
+++ b/sound/soc/omap/igep0020.c
@@ -29,7 +29,7 @@
29#include <asm/mach-types.h> 29#include <asm/mach-types.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/gpio.h> 31#include <mach/gpio.h>
32#include <plat/mcbsp.h> 32#include <linux/platform_data/asoc-ti-mcbsp.h>
33 33
34#include "omap-mcbsp.h" 34#include "omap-mcbsp.h"
35#include "omap-pcm.h" 35#include "omap-pcm.h"
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c
index 34835e8a9160..a681a9a8b846 100644
--- a/sound/soc/omap/mcbsp.c
+++ b/sound/soc/omap/mcbsp.c
@@ -25,7 +25,9 @@
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27 27
28#include <plat/mcbsp.h> 28#include <linux/platform_data/asoc-ti-mcbsp.h>
29
30#include <plat/cpu.h>
29 31
30#include "mcbsp.h" 32#include "mcbsp.h"
31 33
@@ -745,7 +747,7 @@ int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux)
745{ 747{
746 const char *signal, *src; 748 const char *signal, *src;
747 749
748 if (mcbsp->pdata->mux_signal) 750 if (!mcbsp->pdata->mux_signal)
749 return -EINVAL; 751 return -EINVAL;
750 752
751 switch (mux) { 753 switch (mux) {
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index abac4b690750..521bfc3d2b2b 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -32,7 +32,7 @@
32#include <mach/hardware.h> 32#include <mach/hardware.h>
33#include <linux/gpio.h> 33#include <linux/gpio.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <plat/mcbsp.h> 35#include <linux/platform_data/asoc-ti-mcbsp.h>
36 36
37#include "omap-mcbsp.h" 37#include "omap-mcbsp.h"
38#include "omap-pcm.h" 38#include "omap-pcm.h"
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
index 9d93793d3077..45909ca889fa 100644
--- a/sound/soc/omap/omap-abe-twl6040.c
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -31,10 +31,6 @@
31#include <sound/soc.h> 31#include <sound/soc.h>
32#include <sound/jack.h> 32#include <sound/jack.h>
33 33
34#include <asm/mach-types.h>
35#include <plat/hardware.h>
36#include <plat/mux.h>
37
38#include "omap-dmic.h" 34#include "omap-dmic.h"
39#include "omap-mcpdm.h" 35#include "omap-mcpdm.h"
40#include "omap-pcm.h" 36#include "omap-pcm.h"
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 1046083e90a0..1b18627763ce 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -32,8 +32,9 @@
32#include <sound/initval.h> 32#include <sound/initval.h>
33#include <sound/soc.h> 33#include <sound/soc.h>
34 34
35#include <plat/cpu.h>
35#include <plat/dma.h> 36#include <plat/dma.h>
36#include <plat/mcbsp.h> 37#include <linux/platform_data/asoc-ti-mcbsp.h>
37#include "mcbsp.h" 38#include "mcbsp.h"
38#include "omap-mcbsp.h" 39#include "omap-mcbsp.h"
39#include "omap-pcm.h" 40#include "omap-pcm.h"
@@ -820,3 +821,4 @@ module_platform_driver(asoc_mcbsp_driver);
820MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>"); 821MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
821MODULE_DESCRIPTION("OMAP I2S SoC Interface"); 822MODULE_DESCRIPTION("OMAP I2S SoC Interface");
822MODULE_LICENSE("GPL"); 823MODULE_LICENSE("GPL");
824MODULE_ALIAS("platform:omap-mcbsp");
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 59d47ab5b15d..ea053c3d2ab1 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -45,6 +45,8 @@
45#include "omap-mcpdm.h" 45#include "omap-mcpdm.h"
46#include "omap-pcm.h" 46#include "omap-pcm.h"
47 47
48#define OMAP44XX_MCPDM_L3_BASE 0x49032000
49
48struct omap_mcpdm { 50struct omap_mcpdm {
49 struct device *dev; 51 struct device *dev;
50 unsigned long phys_base; 52 unsigned long phys_base;
@@ -527,6 +529,7 @@ static struct platform_driver asoc_mcpdm_driver = {
527 529
528module_platform_driver(asoc_mcpdm_driver); 530module_platform_driver(asoc_mcpdm_driver);
529 531
532MODULE_ALIAS("platform:omap-mcpdm");
530MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>"); 533MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
531MODULE_DESCRIPTION("OMAP PDM SoC Interface"); 534MODULE_DESCRIPTION("OMAP PDM SoC Interface");
532MODULE_LICENSE("GPL"); 535MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 5a649da9122a..b30994179885 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -30,6 +30,7 @@
30#include <sound/pcm_params.h> 30#include <sound/pcm_params.h>
31#include <sound/soc.h> 31#include <sound/soc.h>
32 32
33#include <plat/cpu.h>
33#include <plat/dma.h> 34#include <plat/dma.h>
34#include "omap-pcm.h" 35#include "omap-pcm.h"
35 36
@@ -441,3 +442,4 @@ module_platform_driver(omap_pcm_driver);
441MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>"); 442MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>");
442MODULE_DESCRIPTION("OMAP PCM DMA module"); 443MODULE_DESCRIPTION("OMAP PCM DMA module");
443MODULE_LICENSE("GPL"); 444MODULE_LICENSE("GPL");
445MODULE_ALIAS("platform:omap-pcm-audio");
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
index 2830dfd05661..e263188841b6 100644
--- a/sound/soc/omap/omap3beagle.c
+++ b/sound/soc/omap/omap3beagle.c
@@ -29,7 +29,7 @@
29#include <asm/mach-types.h> 29#include <asm/mach-types.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/gpio.h> 31#include <mach/gpio.h>
32#include <plat/mcbsp.h> 32#include <linux/platform_data/asoc-ti-mcbsp.h>
33 33
34#include "omap-mcbsp.h" 34#include "omap-mcbsp.h"
35#include "omap-pcm.h" 35#include "omap-pcm.h"
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
index 3d468c9179d7..d632bfbb6983 100644
--- a/sound/soc/omap/omap3evm.c
+++ b/sound/soc/omap/omap3evm.c
@@ -27,7 +27,7 @@
27#include <asm/mach-types.h> 27#include <asm/mach-types.h>
28#include <mach/hardware.h> 28#include <mach/hardware.h>
29#include <mach/gpio.h> 29#include <mach/gpio.h>
30#include <plat/mcbsp.h> 30#include <linux/platform_data/asoc-ti-mcbsp.h>
31 31
32#include "omap-mcbsp.h" 32#include "omap-mcbsp.h"
33#include "omap-pcm.h" 33#include "omap-pcm.h"
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 4c3a0978578a..43d950a79ff9 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -31,7 +31,7 @@
31#include <sound/soc.h> 31#include <sound/soc.h>
32 32
33#include <asm/mach-types.h> 33#include <asm/mach-types.h>
34#include <plat/mcbsp.h> 34#include <linux/platform_data/asoc-ti-mcbsp.h>
35 35
36#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
37#include "omap-pcm.h" 37#include "omap-pcm.h"
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index b1a9d64cbc56..3960e8df9c76 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -31,7 +31,7 @@
31#include <mach/hardware.h> 31#include <mach/hardware.h>
32#include <linux/gpio.h> 32#include <linux/gpio.h>
33#include <linux/module.h> 33#include <linux/module.h>
34#include <plat/mcbsp.h> 34#include <linux/platform_data/asoc-ti-mcbsp.h>
35 35
36#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
37#include "omap-pcm.h" 37#include "omap-pcm.h"
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
index 6ac3e0c3c282..502bce299885 100644
--- a/sound/soc/omap/overo.c
+++ b/sound/soc/omap/overo.c
@@ -29,7 +29,7 @@
29#include <asm/mach-types.h> 29#include <asm/mach-types.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/gpio.h> 31#include <mach/gpio.h>
32#include <plat/mcbsp.h> 32#include <linux/platform_data/asoc-ti-mcbsp.h>
33 33
34#include "omap-mcbsp.h" 34#include "omap-mcbsp.h"
35#include "omap-pcm.h" 35#include "omap-pcm.h"
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 2712dd232b6d..d921ddbe3ecb 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -31,7 +31,7 @@
31#include <sound/jack.h> 31#include <sound/jack.h>
32#include <sound/pcm.h> 32#include <sound/pcm.h>
33#include <sound/soc.h> 33#include <sound/soc.h>
34#include <plat/mcbsp.h> 34#include <linux/platform_data/asoc-ti-mcbsp.h>
35#include "../codecs/tpa6130a2.h" 35#include "../codecs/tpa6130a2.h"
36 36
37#include <asm/mach-types.h> 37#include <asm/mach-types.h>
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
index 0e283226e2bf..597cae769cea 100644
--- a/sound/soc/omap/sdp3430.c
+++ b/sound/soc/omap/sdp3430.c
@@ -33,7 +33,8 @@
33#include <asm/mach-types.h> 33#include <asm/mach-types.h>
34#include <mach/hardware.h> 34#include <mach/hardware.h>
35#include <mach/gpio.h> 35#include <mach/gpio.h>
36#include <plat/mcbsp.h> 36#include <linux/platform_data/gpio-omap.h>
37#include <linux/platform_data/asoc-ti-mcbsp.h>
37 38
38/* Register descriptions for twl4030 codec part */ 39/* Register descriptions for twl4030 codec part */
39#include <linux/mfd/twl4030-audio.h> 40#include <linux/mfd/twl4030-audio.h>
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 920e0d9e03db..23de2b21d696 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -29,7 +29,7 @@
29#include <mach/hardware.h> 29#include <mach/hardware.h>
30#include <mach/gpio.h> 30#include <mach/gpio.h>
31#include <mach/board-zoom.h> 31#include <mach/board-zoom.h>
32#include <plat/mcbsp.h> 32#include <linux/platform_data/asoc-ti-mcbsp.h>
33 33
34/* Register descriptions for twl4030 codec part */ 34/* Register descriptions for twl4030 codec part */
35#include <linux/mfd/twl4030-audio.h> 35#include <linux/mfd/twl4030-audio.h>
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index a0f7d3cfa470..4d2e46fae77c 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -8,6 +8,15 @@ config SND_PXA2XX_SOC
8 the PXA2xx AC97, I2S or SSP interface. You will also need 8 the PXA2xx AC97, I2S or SSP interface. You will also need
9 to select the audio interfaces to support below. 9 to select the audio interfaces to support below.
10 10
11config SND_MMP_SOC
12 bool "Soc Audio for Marvell MMP chips"
13 depends on ARCH_MMP
14 select SND_SOC_DMAENGINE_PCM
15 select SND_ARM
16 help
17 Say Y if you want to add support for codecs attached to
18 the MMP SSPA interface.
19
11config SND_PXA2XX_AC97 20config SND_PXA2XX_AC97
12 tristate 21 tristate
13 select SND_AC97_CODEC 22 select SND_AC97_CODEC
@@ -26,6 +35,9 @@ config SND_PXA_SOC_SSP
26 tristate 35 tristate
27 select PXA_SSP 36 select PXA_SSP
28 37
38config SND_MMP_SOC_SSPA
39 tristate
40
29config SND_PXA2XX_SOC_CORGI 41config SND_PXA2XX_SOC_CORGI
30 tristate "SoC Audio support for Sharp Zaurus SL-C7x0" 42 tristate "SoC Audio support for Sharp Zaurus SL-C7x0"
31 depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx 43 depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx
@@ -138,6 +150,26 @@ config SND_SOC_TAVOREVB3
138 Say Y if you want to add support for SoC audio on the 150 Say Y if you want to add support for SoC audio on the
139 Marvell Saarb reference platform. 151 Marvell Saarb reference platform.
140 152
153config SND_PXA910_SOC
154 tristate "SoC Audio for Marvell PXA910 chip"
155 depends on ARCH_MMP && SND
156 select SND_PCM
157 help
158 Say Y if you want to add support for SoC audio on the
159 Marvell PXA910 reference platform.
160
161config SND_SOC_TTC_DKB
162 bool "SoC Audio support for TTC DKB"
163 depends on SND_PXA910_SOC && MACH_TTC_DKB
164 select PXA_SSP
165 select SND_PXA_SOC_SSP
166 select SND_MMP_SOC
167 select MFD_88PM860X
168 select SND_SOC_88PM860X
169 help
170 Say Y if you want to add support for SoC audio on TTC DKB
171
172
141config SND_SOC_ZYLONITE 173config SND_SOC_ZYLONITE
142 tristate "SoC Audio support for Marvell Zylonite" 174 tristate "SoC Audio support for Marvell Zylonite"
143 depends on SND_PXA2XX_SOC && MACH_ZYLONITE 175 depends on SND_PXA2XX_SOC && MACH_ZYLONITE
@@ -194,3 +226,13 @@ config SND_PXA2XX_SOC_IMOTE2
194 help 226 help
195 Say Y if you want to add support for SoC audio on the 227 Say Y if you want to add support for SoC audio on the
196 IMote 2. 228 IMote 2.
229
230config SND_MMP_SOC_BROWNSTONE
231 tristate "SoC Audio support for Marvell Brownstone"
232 depends on SND_MMP_SOC && MACH_BROWNSTONE
233 select SND_MMP_SOC_SSPA
234 select MFD_WM8994
235 select SND_SOC_WM8994
236 help
237 Say Y if you want to add support for SoC audio on the
238 Marvell Brownstone reference platform.
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index af357623be9d..d8a265d2d5d7 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -3,11 +3,15 @@ snd-soc-pxa2xx-objs := pxa2xx-pcm.o
3snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o 3snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o
4snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o 4snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o
5snd-soc-pxa-ssp-objs := pxa-ssp.o 5snd-soc-pxa-ssp-objs := pxa-ssp.o
6snd-soc-mmp-objs := mmp-pcm.o
7snd-soc-mmp-sspa-objs := mmp-sspa.o
6 8
7obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o 9obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o
8obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o 10obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o
9obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o 11obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o
10obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o 12obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o
13obj-$(CONFIG_SND_MMP_SOC) += snd-soc-mmp.o
14obj-$(CONFIG_SND_MMP_SOC_SSPA) += snd-soc-mmp-sspa.o
11 15
12# PXA Machine Support 16# PXA Machine Support
13snd-soc-corgi-objs := corgi.o 17snd-soc-corgi-objs := corgi.o
@@ -28,6 +32,8 @@ snd-soc-mioa701-objs := mioa701_wm9713.o
28snd-soc-z2-objs := z2.o 32snd-soc-z2-objs := z2.o
29snd-soc-imote2-objs := imote2.o 33snd-soc-imote2-objs := imote2.o
30snd-soc-raumfeld-objs := raumfeld.o 34snd-soc-raumfeld-objs := raumfeld.o
35snd-soc-brownstone-objs := brownstone.o
36snd-soc-ttc-dkb-objs := ttc-dkb.o
31 37
32obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o 38obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
33obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o 39obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o
@@ -47,3 +53,5 @@ obj-$(CONFIG_SND_SOC_TAVOREVB3) += snd-soc-tavorevb3.o
47obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o 53obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
48obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o 54obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o
49obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o 55obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o
56obj-$(CONFIG_SND_MMP_SOC_BROWNSTONE) += snd-soc-brownstone.o
57obj-$(CONFIG_SND_SOC_TTC_DKB) += snd-soc-ttc-dkb.o
diff --git a/sound/soc/pxa/brownstone.c b/sound/soc/pxa/brownstone.c
new file mode 100644
index 000000000000..5e666e03d333
--- /dev/null
+++ b/sound/soc/pxa/brownstone.c
@@ -0,0 +1,174 @@
1/*
2 * linux/sound/soc/pxa/brownstone.c
3 *
4 * Copyright (C) 2011 Marvell International Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 */
12
13#include <linux/module.h>
14#include <sound/core.h>
15#include <sound/pcm.h>
16#include <sound/soc.h>
17#include <sound/jack.h>
18
19#include "../codecs/wm8994.h"
20#include "mmp-sspa.h"
21
22static const struct snd_kcontrol_new brownstone_dapm_control[] = {
23 SOC_DAPM_PIN_SWITCH("Ext Spk"),
24};
25
26static const struct snd_soc_dapm_widget brownstone_dapm_widgets[] = {
27 SND_SOC_DAPM_SPK("Ext Spk", NULL),
28 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
29 SND_SOC_DAPM_MIC("Headset Mic", NULL),
30 SND_SOC_DAPM_MIC("Main Mic", NULL),
31};
32
33static const struct snd_soc_dapm_route brownstone_audio_map[] = {
34 {"Ext Spk", NULL, "SPKOUTLP"},
35 {"Ext Spk", NULL, "SPKOUTLN"},
36 {"Ext Spk", NULL, "SPKOUTRP"},
37 {"Ext Spk", NULL, "SPKOUTRN"},
38
39 {"Headset Stereophone", NULL, "HPOUT1L"},
40 {"Headset Stereophone", NULL, "HPOUT1R"},
41
42 {"IN1RN", NULL, "Headset Mic"},
43
44 {"DMIC1DAT", NULL, "MICBIAS1"},
45 {"MICBIAS1", NULL, "Main Mic"},
46};
47
48static int brownstone_wm8994_init(struct snd_soc_pcm_runtime *rtd)
49{
50 struct snd_soc_codec *codec = rtd->codec;
51 struct snd_soc_dapm_context *dapm = &codec->dapm;
52
53 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
54 snd_soc_dapm_enable_pin(dapm, "Headset Stereophone");
55 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
56 snd_soc_dapm_enable_pin(dapm, "Main Mic");
57
58 /* set endpoints to not connected */
59 snd_soc_dapm_nc_pin(dapm, "HPOUT2P");
60 snd_soc_dapm_nc_pin(dapm, "HPOUT2N");
61 snd_soc_dapm_nc_pin(dapm, "LINEOUT1N");
62 snd_soc_dapm_nc_pin(dapm, "LINEOUT1P");
63 snd_soc_dapm_nc_pin(dapm, "LINEOUT2N");
64 snd_soc_dapm_nc_pin(dapm, "LINEOUT2P");
65 snd_soc_dapm_nc_pin(dapm, "IN1LN");
66 snd_soc_dapm_nc_pin(dapm, "IN1LP");
67 snd_soc_dapm_nc_pin(dapm, "IN1RP");
68 snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN");
69 snd_soc_dapm_nc_pin(dapm, "IN2RN");
70 snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
71 snd_soc_dapm_nc_pin(dapm, "IN2LN");
72
73 snd_soc_dapm_sync(dapm);
74
75 return 0;
76}
77
78static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream,
79 struct snd_pcm_hw_params *params)
80{
81 struct snd_soc_pcm_runtime *rtd = substream->private_data;
82 struct snd_soc_dai *codec_dai = rtd->codec_dai;
83 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
84 int freq_out, sspa_mclk, sysclk;
85 int sspa_div;
86
87 if (params_rate(params) > 11025) {
88 freq_out = params_rate(params) * 512;
89 sysclk = params_rate(params) * 256;
90 sspa_mclk = params_rate(params) * 64;
91 } else {
92 freq_out = params_rate(params) * 1024;
93 sysclk = params_rate(params) * 512;
94 sspa_mclk = params_rate(params) * 64;
95 }
96 sspa_div = freq_out;
97 do_div(sspa_div, sspa_mclk);
98
99 snd_soc_dai_set_sysclk(cpu_dai, MMP_SSPA_CLK_AUDIO, freq_out, 0);
100 snd_soc_dai_set_pll(cpu_dai, MMP_SYSCLK, 0, freq_out, sysclk);
101 snd_soc_dai_set_pll(cpu_dai, MMP_SSPA_CLK, 0, freq_out, sspa_mclk);
102
103 /* set wm8994 sysclk */
104 snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, sysclk, 0);
105
106 return 0;
107}
108
109/* machine stream operations */
110static struct snd_soc_ops brownstone_ops = {
111 .hw_params = brownstone_wm8994_hw_params,
112};
113
114static struct snd_soc_dai_link brownstone_wm8994_dai[] = {
115{
116 .name = "WM8994",
117 .stream_name = "WM8994 HiFi",
118 .cpu_dai_name = "mmp-sspa-dai.0",
119 .codec_dai_name = "wm8994-aif1",
120 .platform_name = "mmp-pcm-audio",
121 .codec_name = "wm8994-codec",
122 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
123 SND_SOC_DAIFMT_CBS_CFS,
124 .ops = &brownstone_ops,
125 .init = brownstone_wm8994_init,
126},
127};
128
129/* audio machine driver */
130static struct snd_soc_card brownstone = {
131 .name = "brownstone",
132 .dai_link = brownstone_wm8994_dai,
133 .num_links = ARRAY_SIZE(brownstone_wm8994_dai),
134
135 .controls = brownstone_dapm_control,
136 .num_controls = ARRAY_SIZE(brownstone_dapm_control),
137 .dapm_widgets = brownstone_dapm_widgets,
138 .num_dapm_widgets = ARRAY_SIZE(brownstone_dapm_widgets),
139 .dapm_routes = brownstone_audio_map,
140 .num_dapm_routes = ARRAY_SIZE(brownstone_audio_map),
141};
142
143static int __devinit brownstone_probe(struct platform_device *pdev)
144{
145 int ret;
146
147 brownstone.dev = &pdev->dev;
148 ret = snd_soc_register_card(&brownstone);
149 if (ret)
150 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
151 ret);
152 return ret;
153}
154
155static int __devexit brownstone_remove(struct platform_device *pdev)
156{
157 snd_soc_unregister_card(&brownstone);
158 return 0;
159}
160
161static struct platform_driver mmp_driver = {
162 .driver = {
163 .name = "brownstone-audio",
164 .owner = THIS_MODULE,
165 },
166 .probe = brownstone_probe,
167 .remove = __devexit_p(brownstone_remove),
168};
169
170module_platform_driver(mmp_driver);
171
172MODULE_AUTHOR("Leo Yan <leoy@marvell.com>");
173MODULE_DESCRIPTION("ALSA SoC Brownstone");
174MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 9c585af59b5f..8687c1c65d29 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -186,36 +186,27 @@ static struct snd_soc_card mioa701 = {
186 .num_links = ARRAY_SIZE(mioa701_dai), 186 .num_links = ARRAY_SIZE(mioa701_dai),
187}; 187};
188 188
189static struct platform_device *mioa701_snd_device; 189static int __devinit mioa701_wm9713_probe(struct platform_device *pdev)
190
191static int mioa701_wm9713_probe(struct platform_device *pdev)
192{ 190{
193 int ret; 191 int rc;
194 192
195 if (!machine_is_mioa701()) 193 if (!machine_is_mioa701())
196 return -ENODEV; 194 return -ENODEV;
197 195
198 dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will" 196 mioa701.dev = &pdev->dev;
199 "lead to overheating and possible destruction of your device." 197 rc = snd_soc_register_card(&mioa701);
200 "Do not use without a good knowledge of mio's board design!\n"); 198 if (!rc)
201 199 dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will"
202 mioa701_snd_device = platform_device_alloc("soc-audio", -1); 200 "lead to overheating and possible destruction of your device."
203 if (!mioa701_snd_device) 201 " Do not use without a good knowledge of mio's board design!\n");
204 return -ENOMEM; 202 return rc;
205
206 platform_set_drvdata(mioa701_snd_device, &mioa701);
207
208 ret = platform_device_add(mioa701_snd_device);
209 if (!ret)
210 return 0;
211
212 platform_device_put(mioa701_snd_device);
213 return ret;
214} 203}
215 204
216static int __devexit mioa701_wm9713_remove(struct platform_device *pdev) 205static int __devexit mioa701_wm9713_remove(struct platform_device *pdev)
217{ 206{
218 platform_device_unregister(mioa701_snd_device); 207 struct snd_soc_card *card = platform_get_drvdata(pdev);
208
209 snd_soc_unregister_card(card);
219 return 0; 210 return 0;
220} 211}
221 212
diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c
new file mode 100644
index 000000000000..73ac5463c9e4
--- /dev/null
+++ b/sound/soc/pxa/mmp-pcm.c
@@ -0,0 +1,297 @@
1/*
2 * linux/sound/soc/pxa/mmp-pcm.c
3 *
4 * Copyright (C) 2011 Marvell International Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 */
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/platform_device.h>
15#include <linux/slab.h>
16#include <linux/dma-mapping.h>
17#include <linux/dmaengine.h>
18#include <linux/platform_data/mmp_audio.h>
19#include <sound/pxa2xx-lib.h>
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24#include <mach/sram.h>
25#include <sound/dmaengine_pcm.h>
26
27struct mmp_dma_data {
28 int ssp_id;
29 struct resource *dma_res;
30};
31
32#define MMP_PCM_INFO (SNDRV_PCM_INFO_MMAP | \
33 SNDRV_PCM_INFO_MMAP_VALID | \
34 SNDRV_PCM_INFO_INTERLEAVED | \
35 SNDRV_PCM_INFO_PAUSE | \
36 SNDRV_PCM_INFO_RESUME)
37
38#define MMP_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
39 SNDRV_PCM_FMTBIT_S24_LE | \
40 SNDRV_PCM_FMTBIT_S32_LE)
41
42static struct snd_pcm_hardware mmp_pcm_hardware[] = {
43 {
44 .info = MMP_PCM_INFO,
45 .formats = MMP_PCM_FORMATS,
46 .period_bytes_min = 1024,
47 .period_bytes_max = 2048,
48 .periods_min = 2,
49 .periods_max = 32,
50 .buffer_bytes_max = 4096,
51 .fifo_size = 32,
52 },
53 {
54 .info = MMP_PCM_INFO,
55 .formats = MMP_PCM_FORMATS,
56 .period_bytes_min = 1024,
57 .period_bytes_max = 2048,
58 .periods_min = 2,
59 .periods_max = 32,
60 .buffer_bytes_max = 4096,
61 .fifo_size = 32,
62 },
63};
64
65static int mmp_pcm_hw_params(struct snd_pcm_substream *substream,
66 struct snd_pcm_hw_params *params)
67{
68 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
69 struct snd_soc_pcm_runtime *rtd = substream->private_data;
70 struct pxa2xx_pcm_dma_params *dma_params;
71 struct dma_slave_config slave_config;
72 int ret;
73
74 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
75 if (!dma_params)
76 return 0;
77
78 ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config);
79 if (ret)
80 return ret;
81
82 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
83 slave_config.dst_addr = dma_params->dev_addr;
84 slave_config.dst_maxburst = 4;
85 } else {
86 slave_config.src_addr = dma_params->dev_addr;
87 slave_config.src_maxburst = 4;
88 }
89
90 ret = dmaengine_slave_config(chan, &slave_config);
91 if (ret)
92 return ret;
93
94 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
95
96 return 0;
97}
98
99static bool filter(struct dma_chan *chan, void *param)
100{
101 struct mmp_dma_data *dma_data = param;
102 bool found = false;
103 char *devname;
104
105 devname = kasprintf(GFP_KERNEL, "%s.%d", dma_data->dma_res->name,
106 dma_data->ssp_id);
107 if ((strcmp(dev_name(chan->device->dev), devname) == 0) &&
108 (chan->chan_id == dma_data->dma_res->start)) {
109 found = true;
110 }
111
112 kfree(devname);
113 return found;
114}
115
116static int mmp_pcm_open(struct snd_pcm_substream *substream)
117{
118 struct snd_soc_pcm_runtime *rtd = substream->private_data;
119 struct platform_device *pdev = to_platform_device(rtd->platform->dev);
120 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
121 struct mmp_dma_data *dma_data;
122 struct resource *r;
123 int ret;
124
125 r = platform_get_resource(pdev, IORESOURCE_DMA, substream->stream);
126 if (!r)
127 return -EBUSY;
128
129 snd_soc_set_runtime_hwparams(substream,
130 &mmp_pcm_hardware[substream->stream]);
131 dma_data = devm_kzalloc(&pdev->dev,
132 sizeof(struct mmp_dma_data), GFP_KERNEL);
133 if (dma_data == NULL)
134 return -ENOMEM;
135
136 dma_data->dma_res = r;
137 dma_data->ssp_id = cpu_dai->id;
138
139 ret = snd_dmaengine_pcm_open(substream, filter, dma_data);
140 if (ret) {
141 devm_kfree(&pdev->dev, dma_data);
142 return ret;
143 }
144
145 snd_dmaengine_pcm_set_data(substream, dma_data);
146 return 0;
147}
148
149static int mmp_pcm_close(struct snd_pcm_substream *substream)
150{
151 struct mmp_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
152 struct snd_soc_pcm_runtime *rtd = substream->private_data;
153 struct platform_device *pdev = to_platform_device(rtd->platform->dev);
154
155 snd_dmaengine_pcm_close(substream);
156 devm_kfree(&pdev->dev, dma_data);
157 return 0;
158}
159
160static int mmp_pcm_mmap(struct snd_pcm_substream *substream,
161 struct vm_area_struct *vma)
162{
163 struct snd_pcm_runtime *runtime = substream->runtime;
164 unsigned long off = vma->vm_pgoff;
165
166 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
167 return remap_pfn_range(vma, vma->vm_start,
168 __phys_to_pfn(runtime->dma_addr) + off,
169 vma->vm_end - vma->vm_start, vma->vm_page_prot);
170}
171
172struct snd_pcm_ops mmp_pcm_ops = {
173 .open = mmp_pcm_open,
174 .close = mmp_pcm_close,
175 .ioctl = snd_pcm_lib_ioctl,
176 .hw_params = mmp_pcm_hw_params,
177 .trigger = snd_dmaengine_pcm_trigger,
178 .pointer = snd_dmaengine_pcm_pointer,
179 .mmap = mmp_pcm_mmap,
180};
181
182static void mmp_pcm_free_dma_buffers(struct snd_pcm *pcm)
183{
184 struct snd_pcm_substream *substream;
185 struct snd_dma_buffer *buf;
186 int stream;
187 struct gen_pool *gpool;
188
189 gpool = sram_get_gpool("asram");
190 if (!gpool)
191 return;
192
193 for (stream = 0; stream < 2; stream++) {
194 size_t size = mmp_pcm_hardware[stream].buffer_bytes_max;
195
196 substream = pcm->streams[stream].substream;
197 if (!substream)
198 continue;
199
200 buf = &substream->dma_buffer;
201 if (!buf->area)
202 continue;
203 gen_pool_free(gpool, (unsigned long)buf->area, size);
204 buf->area = NULL;
205 }
206
207 return;
208}
209
210static int mmp_pcm_preallocate_dma_buffer(struct snd_pcm_substream *substream,
211 int stream)
212{
213 struct snd_dma_buffer *buf = &substream->dma_buffer;
214 size_t size = mmp_pcm_hardware[stream].buffer_bytes_max;
215 struct gen_pool *gpool;
216
217 buf->dev.type = SNDRV_DMA_TYPE_DEV;
218 buf->dev.dev = substream->pcm->card->dev;
219 buf->private_data = NULL;
220
221 gpool = sram_get_gpool("asram");
222 if (!gpool)
223 return -ENOMEM;
224
225 buf->area = (unsigned char *)gen_pool_alloc(gpool, size);
226 if (!buf->area)
227 return -ENOMEM;
228 buf->addr = gen_pool_virt_to_phys(gpool, (unsigned long)buf->area);
229 buf->bytes = size;
230 return 0;
231}
232
233int mmp_pcm_new(struct snd_soc_pcm_runtime *rtd)
234{
235 struct snd_pcm_substream *substream;
236 struct snd_pcm *pcm = rtd->pcm;
237 int ret = 0, stream;
238
239 for (stream = 0; stream < 2; stream++) {
240 substream = pcm->streams[stream].substream;
241
242 ret = mmp_pcm_preallocate_dma_buffer(substream, stream);
243 if (ret)
244 goto err;
245 }
246
247 return 0;
248
249err:
250 mmp_pcm_free_dma_buffers(pcm);
251 return ret;
252}
253
254struct snd_soc_platform_driver mmp_soc_platform = {
255 .ops = &mmp_pcm_ops,
256 .pcm_new = mmp_pcm_new,
257 .pcm_free = mmp_pcm_free_dma_buffers,
258};
259
260static __devinit int mmp_pcm_probe(struct platform_device *pdev)
261{
262 struct mmp_audio_platdata *pdata = pdev->dev.platform_data;
263
264 if (pdata) {
265 mmp_pcm_hardware[SNDRV_PCM_STREAM_PLAYBACK].buffer_bytes_max =
266 pdata->buffer_max_playback;
267 mmp_pcm_hardware[SNDRV_PCM_STREAM_PLAYBACK].period_bytes_max =
268 pdata->period_max_playback;
269 mmp_pcm_hardware[SNDRV_PCM_STREAM_CAPTURE].buffer_bytes_max =
270 pdata->buffer_max_capture;
271 mmp_pcm_hardware[SNDRV_PCM_STREAM_CAPTURE].period_bytes_max =
272 pdata->period_max_capture;
273 }
274 return snd_soc_register_platform(&pdev->dev, &mmp_soc_platform);
275}
276
277static int __devexit mmp_pcm_remove(struct platform_device *pdev)
278{
279 snd_soc_unregister_platform(&pdev->dev);
280 return 0;
281}
282
283static struct platform_driver mmp_pcm_driver = {
284 .driver = {
285 .name = "mmp-pcm-audio",
286 .owner = THIS_MODULE,
287 },
288
289 .probe = mmp_pcm_probe,
290 .remove = __devexit_p(mmp_pcm_remove),
291};
292
293module_platform_driver(mmp_pcm_driver);
294
295MODULE_AUTHOR("Leo Yan <leoy@marvell.com>");
296MODULE_DESCRIPTION("MMP Soc Audio DMA module");
297MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c
new file mode 100644
index 000000000000..4d6cb8a30fc8
--- /dev/null
+++ b/sound/soc/pxa/mmp-sspa.c
@@ -0,0 +1,480 @@
1/*
2 * linux/sound/soc/pxa/mmp-sspa.c
3 * Base on pxa2xx-ssp.c
4 *
5 * Copyright (C) 2011 Marvell International Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/delay.h>
26#include <linux/clk.h>
27#include <linux/slab.h>
28#include <linux/pxa2xx_ssp.h>
29#include <linux/io.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/initval.h>
33#include <sound/pcm_params.h>
34#include <sound/soc.h>
35#include <sound/pxa2xx-lib.h>
36#include "mmp-sspa.h"
37
38/*
39 * SSPA audio private data
40 */
41struct sspa_priv {
42 struct ssp_device *sspa;
43 struct pxa2xx_pcm_dma_params *dma_params;
44 struct clk *audio_clk;
45 struct clk *sysclk;
46 int dai_fmt;
47 int running_cnt;
48};
49
50static void mmp_sspa_write_reg(struct ssp_device *sspa, u32 reg, u32 val)
51{
52 __raw_writel(val, sspa->mmio_base + reg);
53}
54
55static u32 mmp_sspa_read_reg(struct ssp_device *sspa, u32 reg)
56{
57 return __raw_readl(sspa->mmio_base + reg);
58}
59
60static void mmp_sspa_tx_enable(struct ssp_device *sspa)
61{
62 unsigned int sspa_sp;
63
64 sspa_sp = mmp_sspa_read_reg(sspa, SSPA_TXSP);
65 sspa_sp |= SSPA_SP_S_EN;
66 sspa_sp |= SSPA_SP_WEN;
67 mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp);
68}
69
70static void mmp_sspa_tx_disable(struct ssp_device *sspa)
71{
72 unsigned int sspa_sp;
73
74 sspa_sp = mmp_sspa_read_reg(sspa, SSPA_TXSP);
75 sspa_sp &= ~SSPA_SP_S_EN;
76 sspa_sp |= SSPA_SP_WEN;
77 mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp);
78}
79
80static void mmp_sspa_rx_enable(struct ssp_device *sspa)
81{
82 unsigned int sspa_sp;
83
84 sspa_sp = mmp_sspa_read_reg(sspa, SSPA_RXSP);
85 sspa_sp |= SSPA_SP_S_EN;
86 sspa_sp |= SSPA_SP_WEN;
87 mmp_sspa_write_reg(sspa, SSPA_RXSP, sspa_sp);
88}
89
90static void mmp_sspa_rx_disable(struct ssp_device *sspa)
91{
92 unsigned int sspa_sp;
93
94 sspa_sp = mmp_sspa_read_reg(sspa, SSPA_RXSP);
95 sspa_sp &= ~SSPA_SP_S_EN;
96 sspa_sp |= SSPA_SP_WEN;
97 mmp_sspa_write_reg(sspa, SSPA_RXSP, sspa_sp);
98}
99
100static int mmp_sspa_startup(struct snd_pcm_substream *substream,
101 struct snd_soc_dai *dai)
102{
103 struct sspa_priv *priv = snd_soc_dai_get_drvdata(dai);
104
105 clk_enable(priv->sysclk);
106 clk_enable(priv->sspa->clk);
107
108 return 0;
109}
110
111static void mmp_sspa_shutdown(struct snd_pcm_substream *substream,
112 struct snd_soc_dai *dai)
113{
114 struct sspa_priv *priv = snd_soc_dai_get_drvdata(dai);
115
116 clk_disable(priv->sspa->clk);
117 clk_disable(priv->sysclk);
118
119 return;
120}
121
122/*
123 * Set the SSP ports SYSCLK.
124 */
125static int mmp_sspa_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
126 int clk_id, unsigned int freq, int dir)
127{
128 struct sspa_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
129 int ret = 0;
130
131 switch (clk_id) {
132 case MMP_SSPA_CLK_AUDIO:
133 ret = clk_set_rate(priv->audio_clk, freq);
134 if (ret)
135 return ret;
136 break;
137 case MMP_SSPA_CLK_PLL:
138 case MMP_SSPA_CLK_VCXO:
139 /* not support yet */
140 return -EINVAL;
141 default:
142 return -EINVAL;
143 }
144
145 return 0;
146}
147
148static int mmp_sspa_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
149 int source, unsigned int freq_in,
150 unsigned int freq_out)
151{
152 struct sspa_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
153 int ret = 0;
154
155 switch (pll_id) {
156 case MMP_SYSCLK:
157 ret = clk_set_rate(priv->sysclk, freq_out);
158 if (ret)
159 return ret;
160 break;
161 case MMP_SSPA_CLK:
162 ret = clk_set_rate(priv->sspa->clk, freq_out);
163 if (ret)
164 return ret;
165 break;
166 default:
167 return -ENODEV;
168 }
169
170 return 0;
171}
172
173/*
174 * Set up the sspa dai format. The sspa port must be inactive
175 * before calling this function as the physical
176 * interface format is changed.
177 */
178static int mmp_sspa_set_dai_fmt(struct snd_soc_dai *cpu_dai,
179 unsigned int fmt)
180{
181 struct sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(cpu_dai);
182 struct ssp_device *sspa = sspa_priv->sspa;
183 u32 sspa_sp, sspa_ctrl;
184
185 /* check if we need to change anything at all */
186 if (sspa_priv->dai_fmt == fmt)
187 return 0;
188
189 /* we can only change the settings if the port is not in use */
190 if ((mmp_sspa_read_reg(sspa, SSPA_TXSP) & SSPA_SP_S_EN) ||
191 (mmp_sspa_read_reg(sspa, SSPA_RXSP) & SSPA_SP_S_EN)) {
192 dev_err(&sspa->pdev->dev,
193 "can't change hardware dai format: stream is in use\n");
194 return -EINVAL;
195 }
196
197 /* reset port settings */
198 sspa_sp = SSPA_SP_WEN | SSPA_SP_S_RST | SSPA_SP_FFLUSH;
199 sspa_ctrl = 0;
200
201 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
202 case SND_SOC_DAIFMT_CBS_CFS:
203 sspa_sp |= SSPA_SP_MSL;
204 break;
205 case SND_SOC_DAIFMT_CBM_CFM:
206 break;
207 default:
208 return -EINVAL;
209 }
210
211 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
212 case SND_SOC_DAIFMT_NB_NF:
213 sspa_sp |= SSPA_SP_FSP;
214 break;
215 default:
216 return -EINVAL;
217 }
218
219 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
220 case SND_SOC_DAIFMT_I2S:
221 sspa_sp |= SSPA_TXSP_FPER(63);
222 sspa_sp |= SSPA_SP_FWID(31);
223 sspa_ctrl |= SSPA_CTL_XDATDLY(1);
224 break;
225 default:
226 return -EINVAL;
227 }
228
229 mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp);
230 mmp_sspa_write_reg(sspa, SSPA_RXSP, sspa_sp);
231
232 sspa_sp &= ~(SSPA_SP_S_RST | SSPA_SP_FFLUSH);
233 mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp);
234 mmp_sspa_write_reg(sspa, SSPA_RXSP, sspa_sp);
235
236 /*
237 * FIXME: hw issue, for the tx serial port,
238 * can not config the master/slave mode;
239 * so must clean this bit.
240 * The master/slave mode has been set in the
241 * rx port.
242 */
243 sspa_sp &= ~SSPA_SP_MSL;
244 mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp);
245
246 mmp_sspa_write_reg(sspa, SSPA_TXCTL, sspa_ctrl);
247 mmp_sspa_write_reg(sspa, SSPA_RXCTL, sspa_ctrl);
248
249 /* Since we are configuring the timings for the format by hand
250 * we have to defer some things until hw_params() where we
251 * know parameters like the sample size.
252 */
253 sspa_priv->dai_fmt = fmt;
254 return 0;
255}
256
257/*
258 * Set the SSPA audio DMA parameters and sample size.
259 * Can be called multiple times by oss emulation.
260 */
261static int mmp_sspa_hw_params(struct snd_pcm_substream *substream,
262 struct snd_pcm_hw_params *params,
263 struct snd_soc_dai *dai)
264{
265 struct snd_soc_pcm_runtime *rtd = substream->private_data;
266 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
267 struct sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(dai);
268 struct ssp_device *sspa = sspa_priv->sspa;
269 struct pxa2xx_pcm_dma_params *dma_params;
270 u32 sspa_ctrl;
271
272 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
273 sspa_ctrl = mmp_sspa_read_reg(sspa, SSPA_TXCTL);
274 else
275 sspa_ctrl = mmp_sspa_read_reg(sspa, SSPA_RXCTL);
276
277 sspa_ctrl &= ~SSPA_CTL_XFRLEN1_MASK;
278 sspa_ctrl |= SSPA_CTL_XFRLEN1(params_channels(params) - 1);
279 sspa_ctrl &= ~SSPA_CTL_XWDLEN1_MASK;
280 sspa_ctrl |= SSPA_CTL_XWDLEN1(SSPA_CTL_32_BITS);
281 sspa_ctrl &= ~SSPA_CTL_XSSZ1_MASK;
282
283 switch (params_format(params)) {
284 case SNDRV_PCM_FORMAT_S8:
285 sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_8_BITS);
286 break;
287 case SNDRV_PCM_FORMAT_S16_LE:
288 sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_16_BITS);
289 break;
290 case SNDRV_PCM_FORMAT_S20_3LE:
291 sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_20_BITS);
292 break;
293 case SNDRV_PCM_FORMAT_S24_3LE:
294 sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_24_BITS);
295 break;
296 case SNDRV_PCM_FORMAT_S32_LE:
297 sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_32_BITS);
298 break;
299 default:
300 return -EINVAL;
301 }
302
303 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
304 mmp_sspa_write_reg(sspa, SSPA_TXCTL, sspa_ctrl);
305 mmp_sspa_write_reg(sspa, SSPA_TXFIFO_LL, 0x1);
306 } else {
307 mmp_sspa_write_reg(sspa, SSPA_RXCTL, sspa_ctrl);
308 mmp_sspa_write_reg(sspa, SSPA_RXFIFO_UL, 0x0);
309 }
310
311 dma_params = &sspa_priv->dma_params[substream->stream];
312 dma_params->dev_addr = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
313 (sspa->phys_base + SSPA_TXD) :
314 (sspa->phys_base + SSPA_RXD);
315 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_params);
316 return 0;
317}
318
319static int mmp_sspa_trigger(struct snd_pcm_substream *substream, int cmd,
320 struct snd_soc_dai *dai)
321{
322 struct sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(dai);
323 struct ssp_device *sspa = sspa_priv->sspa;
324 int ret = 0;
325
326 switch (cmd) {
327 case SNDRV_PCM_TRIGGER_START:
328 case SNDRV_PCM_TRIGGER_RESUME:
329 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
330 /*
331 * whatever playback or capture, must enable rx.
332 * this is a hw issue, so need check if rx has been
333 * enabled or not; if has been enabled by another
334 * stream, do not enable again.
335 */
336 if (!sspa_priv->running_cnt)
337 mmp_sspa_rx_enable(sspa);
338
339 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
340 mmp_sspa_tx_enable(sspa);
341
342 sspa_priv->running_cnt++;
343 break;
344
345 case SNDRV_PCM_TRIGGER_STOP:
346 case SNDRV_PCM_TRIGGER_SUSPEND:
347 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
348 sspa_priv->running_cnt--;
349
350 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
351 mmp_sspa_tx_disable(sspa);
352
353 /* have no capture stream, disable rx port */
354 if (!sspa_priv->running_cnt)
355 mmp_sspa_rx_disable(sspa);
356 break;
357
358 default:
359 ret = -EINVAL;
360 }
361
362 return ret;
363}
364
365static int mmp_sspa_probe(struct snd_soc_dai *dai)
366{
367 struct sspa_priv *priv = dev_get_drvdata(dai->dev);
368
369 snd_soc_dai_set_drvdata(dai, priv);
370 return 0;
371
372}
373
374#define MMP_SSPA_RATES SNDRV_PCM_RATE_8000_192000
375#define MMP_SSPA_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
376 SNDRV_PCM_FMTBIT_S16_LE | \
377 SNDRV_PCM_FMTBIT_S24_LE | \
378 SNDRV_PCM_FMTBIT_S24_LE | \
379 SNDRV_PCM_FMTBIT_S32_LE)
380
381static struct snd_soc_dai_ops mmp_sspa_dai_ops = {
382 .startup = mmp_sspa_startup,
383 .shutdown = mmp_sspa_shutdown,
384 .trigger = mmp_sspa_trigger,
385 .hw_params = mmp_sspa_hw_params,
386 .set_sysclk = mmp_sspa_set_dai_sysclk,
387 .set_pll = mmp_sspa_set_dai_pll,
388 .set_fmt = mmp_sspa_set_dai_fmt,
389};
390
391struct snd_soc_dai_driver mmp_sspa_dai = {
392 .probe = mmp_sspa_probe,
393 .playback = {
394 .channels_min = 1,
395 .channels_max = 128,
396 .rates = MMP_SSPA_RATES,
397 .formats = MMP_SSPA_FORMATS,
398 },
399 .capture = {
400 .channels_min = 1,
401 .channels_max = 2,
402 .rates = MMP_SSPA_RATES,
403 .formats = MMP_SSPA_FORMATS,
404 },
405 .ops = &mmp_sspa_dai_ops,
406};
407
408static __devinit int asoc_mmp_sspa_probe(struct platform_device *pdev)
409{
410 struct sspa_priv *priv;
411 struct resource *res;
412
413 priv = devm_kzalloc(&pdev->dev,
414 sizeof(struct sspa_priv), GFP_KERNEL);
415 if (!priv)
416 return -ENOMEM;
417
418 priv->sspa = devm_kzalloc(&pdev->dev,
419 sizeof(struct ssp_device), GFP_KERNEL);
420 if (priv->sspa == NULL)
421 return -ENOMEM;
422
423 priv->dma_params = devm_kzalloc(&pdev->dev,
424 2 * sizeof(struct pxa2xx_pcm_dma_params), GFP_KERNEL);
425 if (priv->dma_params == NULL)
426 return -ENOMEM;
427
428 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
429 if (res == NULL)
430 return -ENOMEM;
431
432 priv->sspa->mmio_base = devm_request_and_ioremap(&pdev->dev, res);
433 if (priv->sspa->mmio_base == NULL)
434 return -ENODEV;
435
436 priv->sspa->clk = devm_clk_get(&pdev->dev, NULL);
437 if (IS_ERR(priv->sspa->clk))
438 return PTR_ERR(priv->sspa->clk);
439
440 priv->audio_clk = clk_get(NULL, "mmp-audio");
441 if (IS_ERR(priv->audio_clk))
442 return PTR_ERR(priv->audio_clk);
443
444 priv->sysclk = clk_get(NULL, "mmp-sysclk");
445 if (IS_ERR(priv->sysclk)) {
446 clk_put(priv->audio_clk);
447 return PTR_ERR(priv->sysclk);
448 }
449 clk_enable(priv->audio_clk);
450 priv->dai_fmt = (unsigned int) -1;
451 platform_set_drvdata(pdev, priv);
452
453 return snd_soc_register_dai(&pdev->dev, &mmp_sspa_dai);
454}
455
456static int __devexit asoc_mmp_sspa_remove(struct platform_device *pdev)
457{
458 struct sspa_priv *priv = platform_get_drvdata(pdev);
459
460 clk_disable(priv->audio_clk);
461 clk_put(priv->audio_clk);
462 clk_put(priv->sysclk);
463 snd_soc_unregister_dai(&pdev->dev);
464 return 0;
465}
466
467static struct platform_driver asoc_mmp_sspa_driver = {
468 .driver = {
469 .name = "mmp-sspa-dai",
470 .owner = THIS_MODULE,
471 },
472 .probe = asoc_mmp_sspa_probe,
473 .remove = __devexit_p(asoc_mmp_sspa_remove),
474};
475
476module_platform_driver(asoc_mmp_sspa_driver);
477
478MODULE_AUTHOR("Leo Yan <leoy@marvell.com>");
479MODULE_DESCRIPTION("MMP SSPA SoC Interface");
480MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/mmp-sspa.h b/sound/soc/pxa/mmp-sspa.h
new file mode 100644
index 000000000000..ea365cb9e784
--- /dev/null
+++ b/sound/soc/pxa/mmp-sspa.h
@@ -0,0 +1,92 @@
1/*
2 * linux/sound/soc/pxa/mmp-sspa.h
3 *
4 * Copyright (C) 2011 Marvell International Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21#ifndef _MMP_SSPA_H
22#define _MMP_SSPA_H
23
24/*
25 * SSPA Registers
26 */
27#define SSPA_RXD (0x00)
28#define SSPA_RXID (0x04)
29#define SSPA_RXCTL (0x08)
30#define SSPA_RXSP (0x0c)
31#define SSPA_RXFIFO_UL (0x10)
32#define SSPA_RXINT_MASK (0x14)
33#define SSPA_RXC (0x18)
34#define SSPA_RXFIFO_NOFS (0x1c)
35#define SSPA_RXFIFO_SIZE (0x20)
36
37#define SSPA_TXD (0x80)
38#define SSPA_TXID (0x84)
39#define SSPA_TXCTL (0x88)
40#define SSPA_TXSP (0x8c)
41#define SSPA_TXFIFO_LL (0x90)
42#define SSPA_TXINT_MASK (0x94)
43#define SSPA_TXC (0x98)
44#define SSPA_TXFIFO_NOFS (0x9c)
45#define SSPA_TXFIFO_SIZE (0xa0)
46
47/* SSPA Control Register */
48#define SSPA_CTL_XPH (1 << 31) /* Read Phase */
49#define SSPA_CTL_XFIG (1 << 15) /* Transmit Zeros when FIFO Empty */
50#define SSPA_CTL_JST (1 << 3) /* Audio Sample Justification */
51#define SSPA_CTL_XFRLEN2_MASK (7 << 24)
52#define SSPA_CTL_XFRLEN2(x) ((x) << 24) /* Transmit Frame Length in Phase 2 */
53#define SSPA_CTL_XWDLEN2_MASK (7 << 21)
54#define SSPA_CTL_XWDLEN2(x) ((x) << 21) /* Transmit Word Length in Phase 2 */
55#define SSPA_CTL_XDATDLY(x) ((x) << 19) /* Tansmit Data Delay */
56#define SSPA_CTL_XSSZ2_MASK (7 << 16)
57#define SSPA_CTL_XSSZ2(x) ((x) << 16) /* Transmit Sample Audio Size */
58#define SSPA_CTL_XFRLEN1_MASK (7 << 8)
59#define SSPA_CTL_XFRLEN1(x) ((x) << 8) /* Transmit Frame Length in Phase 1 */
60#define SSPA_CTL_XWDLEN1_MASK (7 << 5)
61#define SSPA_CTL_XWDLEN1(x) ((x) << 5) /* Transmit Word Length in Phase 1 */
62#define SSPA_CTL_XSSZ1_MASK (7 << 0)
63#define SSPA_CTL_XSSZ1(x) ((x) << 0) /* XSSZ1 */
64
65#define SSPA_CTL_8_BITS (0x0) /* Sample Size */
66#define SSPA_CTL_12_BITS (0x1)
67#define SSPA_CTL_16_BITS (0x2)
68#define SSPA_CTL_20_BITS (0x3)
69#define SSPA_CTL_24_BITS (0x4)
70#define SSPA_CTL_32_BITS (0x5)
71
72/* SSPA Serial Port Register */
73#define SSPA_SP_WEN (1 << 31) /* Write Configuration Enable */
74#define SSPA_SP_MSL (1 << 18) /* Master Slave Configuration */
75#define SSPA_SP_CLKP (1 << 17) /* CLKP Polarity Clock Edge Select */
76#define SSPA_SP_FSP (1 << 16) /* FSP Polarity Clock Edge Select */
77#define SSPA_SP_FFLUSH (1 << 2) /* FIFO Flush */
78#define SSPA_SP_S_RST (1 << 1) /* Active High Reset Signal */
79#define SSPA_SP_S_EN (1 << 0) /* Serial Clock Domain Enable */
80#define SSPA_SP_FWID(x) ((x) << 20) /* Frame-Sync Width */
81#define SSPA_TXSP_FPER(x) ((x) << 4) /* Frame-Sync Active */
82
83/* sspa clock sources */
84#define MMP_SSPA_CLK_PLL 0
85#define MMP_SSPA_CLK_VCXO 1
86#define MMP_SSPA_CLK_AUDIO 3
87
88/* sspa pll id */
89#define MMP_SYSCLK 0
90#define MMP_SSPA_CLK 1
91
92#endif /* _MMP_SSPA_H */
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index db24bc685bd3..aa3da91907c6 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -25,7 +25,7 @@
25 25
26#include <asm/mach-types.h> 26#include <asm/mach-types.h>
27#include <mach/audio.h> 27#include <mach/audio.h>
28#include <mach/palmasoc.h> 28#include <linux/platform_data/asoc-palm27x.h>
29 29
30#include "../codecs/wm9712.h" 30#include "../codecs/wm9712.h"
31#include "pxa2xx-ac97.h" 31#include "pxa2xx-ac97.h"
diff --git a/sound/soc/pxa/ttc-dkb.c b/sound/soc/pxa/ttc-dkb.c
new file mode 100644
index 000000000000..935491a8a770
--- /dev/null
+++ b/sound/soc/pxa/ttc-dkb.c
@@ -0,0 +1,173 @@
1/*
2 * linux/sound/soc/pxa/ttc_dkb.c
3 *
4 * Copyright (C) 2012 Marvell International Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21#include <linux/module.h>
22#include <linux/moduleparam.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/soc.h>
26#include <sound/jack.h>
27#include <asm/mach-types.h>
28#include <sound/pcm_params.h>
29#include "../codecs/88pm860x-codec.h"
30
31static struct snd_soc_jack hs_jack, mic_jack;
32
33static struct snd_soc_jack_pin hs_jack_pins[] = {
34 { .pin = "Headset Stereophone", .mask = SND_JACK_HEADPHONE, },
35};
36
37static struct snd_soc_jack_pin mic_jack_pins[] = {
38 { .pin = "Headset Mic 2", .mask = SND_JACK_MICROPHONE, },
39};
40
41/* ttc machine dapm widgets */
42static const struct snd_soc_dapm_widget ttc_dapm_widgets[] = {
43 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
44 SND_SOC_DAPM_LINE("Lineout Out 1", NULL),
45 SND_SOC_DAPM_LINE("Lineout Out 2", NULL),
46 SND_SOC_DAPM_SPK("Ext Speaker", NULL),
47 SND_SOC_DAPM_MIC("Ext Mic 1", NULL),
48 SND_SOC_DAPM_MIC("Headset Mic 2", NULL),
49 SND_SOC_DAPM_MIC("Ext Mic 3", NULL),
50};
51
52/* ttc machine audio map */
53static const struct snd_soc_dapm_route ttc_audio_map[] = {
54 {"Headset Stereophone", NULL, "HS1"},
55 {"Headset Stereophone", NULL, "HS2"},
56
57 {"Ext Speaker", NULL, "LSP"},
58 {"Ext Speaker", NULL, "LSN"},
59
60 {"Lineout Out 1", NULL, "LINEOUT1"},
61 {"Lineout Out 2", NULL, "LINEOUT2"},
62
63 {"MIC1P", NULL, "Mic1 Bias"},
64 {"MIC1N", NULL, "Mic1 Bias"},
65 {"Mic1 Bias", NULL, "Ext Mic 1"},
66
67 {"MIC2P", NULL, "Mic1 Bias"},
68 {"MIC2N", NULL, "Mic1 Bias"},
69 {"Mic1 Bias", NULL, "Headset Mic 2"},
70
71 {"MIC3P", NULL, "Mic3 Bias"},
72 {"MIC3N", NULL, "Mic3 Bias"},
73 {"Mic3 Bias", NULL, "Ext Mic 3"},
74};
75
76static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd)
77{
78 struct snd_soc_codec *codec = rtd->codec;
79 struct snd_soc_dapm_context *dapm = &codec->dapm;
80
81 /* connected pins */
82 snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
83 snd_soc_dapm_enable_pin(dapm, "Ext Mic 1");
84 snd_soc_dapm_enable_pin(dapm, "Ext Mic 3");
85 snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
86 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
87
88 /* Headset jack detection */
89 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE
90 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2,
91 &hs_jack);
92 snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
93 hs_jack_pins);
94 snd_soc_jack_new(codec, "Microphone Jack", SND_JACK_MICROPHONE,
95 &mic_jack);
96 snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
97 mic_jack_pins);
98
99 /* headphone, microphone detection & headset short detection */
100 pm860x_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADPHONE,
101 SND_JACK_BTN_0, SND_JACK_BTN_1, SND_JACK_BTN_2);
102 pm860x_mic_jack_detect(codec, &hs_jack, SND_JACK_MICROPHONE);
103
104 return 0;
105}
106
107/* ttc/td-dkb digital audio interface glue - connects codec <--> CPU */
108static struct snd_soc_dai_link ttc_pm860x_hifi_dai[] = {
109{
110 .name = "88pm860x i2s",
111 .stream_name = "audio playback",
112 .codec_name = "88pm860x-codec",
113 .platform_name = "mmp-pcm-audio",
114 .cpu_dai_name = "pxa-ssp-dai.1",
115 .codec_dai_name = "88pm860x-i2s",
116 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
117 SND_SOC_DAIFMT_CBM_CFM,
118 .init = ttc_pm860x_init,
119},
120};
121
122/* ttc/td audio machine driver */
123static struct snd_soc_card ttc_dkb_card = {
124 .name = "ttc-dkb-hifi",
125 .dai_link = ttc_pm860x_hifi_dai,
126 .num_links = ARRAY_SIZE(ttc_pm860x_hifi_dai),
127
128 .dapm_widgets = ttc_dapm_widgets,
129 .num_dapm_widgets = ARRAY_SIZE(ttc_dapm_widgets),
130 .dapm_routes = ttc_audio_map,
131 .num_dapm_routes = ARRAY_SIZE(ttc_audio_map),
132};
133
134static int __devinit ttc_dkb_probe(struct platform_device *pdev)
135{
136 struct snd_soc_card *card = &ttc_dkb_card;
137 int ret;
138
139 card->dev = &pdev->dev;
140
141 ret = snd_soc_register_card(card);
142 if (ret)
143 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
144 ret);
145
146 return ret;
147}
148
149static int __devexit ttc_dkb_remove(struct platform_device *pdev)
150{
151 struct snd_soc_card *card = platform_get_drvdata(pdev);
152
153 snd_soc_unregister_card(card);
154
155 return 0;
156}
157
158static struct platform_driver ttc_dkb_driver = {
159 .driver = {
160 .name = "ttc-dkb-audio",
161 .owner = THIS_MODULE,
162 },
163 .probe = ttc_dkb_probe,
164 .remove = __devexit_p(ttc_dkb_remove),
165};
166
167module_platform_driver(ttc_dkb_driver);
168
169/* Module information */
170MODULE_AUTHOR("Qiao Zhou, <zhouqiao@marvell.com>");
171MODULE_DESCRIPTION("ALSA SoC TTC DKB");
172MODULE_LICENSE("GPL");
173MODULE_ALIAS("platform:ttc-dkb-audio");
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index 3d04c1fa6781..14fbcd30cae5 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -21,7 +21,7 @@
21 21
22#include <mach/dma.h> 22#include <mach/dma.h>
23#include <plat/regs-ac97.h> 23#include <plat/regs-ac97.h>
24#include <plat/audio.h> 24#include <linux/platform_data/asoc-s3c.h>
25 25
26#include "dma.h" 26#include "dma.h"
27 27
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index f3ebc38c10fe..b70964ea448c 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -34,9 +34,7 @@ static const struct snd_pcm_hardware dma_hardware = {
34 .info = SNDRV_PCM_INFO_INTERLEAVED | 34 .info = SNDRV_PCM_INFO_INTERLEAVED |
35 SNDRV_PCM_INFO_BLOCK_TRANSFER | 35 SNDRV_PCM_INFO_BLOCK_TRANSFER |
36 SNDRV_PCM_INFO_MMAP | 36 SNDRV_PCM_INFO_MMAP |
37 SNDRV_PCM_INFO_MMAP_VALID | 37 SNDRV_PCM_INFO_MMAP_VALID,
38 SNDRV_PCM_INFO_PAUSE |
39 SNDRV_PCM_INFO_RESUME,
40 .formats = SNDRV_PCM_FMTBIT_S16_LE | 38 .formats = SNDRV_PCM_FMTBIT_S16_LE |
41 SNDRV_PCM_FMTBIT_U16_LE | 39 SNDRV_PCM_FMTBIT_U16_LE |
42 SNDRV_PCM_FMTBIT_U8 | 40 SNDRV_PCM_FMTBIT_U8 |
@@ -248,15 +246,11 @@ static int dma_trigger(struct snd_pcm_substream *substream, int cmd)
248 246
249 switch (cmd) { 247 switch (cmd) {
250 case SNDRV_PCM_TRIGGER_START: 248 case SNDRV_PCM_TRIGGER_START:
251 case SNDRV_PCM_TRIGGER_RESUME:
252 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
253 prtd->state |= ST_RUNNING; 249 prtd->state |= ST_RUNNING;
254 prtd->params->ops->trigger(prtd->params->ch); 250 prtd->params->ops->trigger(prtd->params->ch);
255 break; 251 break;
256 252
257 case SNDRV_PCM_TRIGGER_STOP: 253 case SNDRV_PCM_TRIGGER_STOP:
258 case SNDRV_PCM_TRIGGER_SUSPEND:
259 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
260 prtd->state &= ~ST_RUNNING; 254 prtd->state &= ~ST_RUNNING;
261 prtd->params->ops->stop(prtd->params->ch); 255 prtd->params->ops->stop(prtd->params->ch);
262 break; 256 break;
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 6ac7b8281a02..40b00a13dcd1 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -20,7 +20,7 @@
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/pcm_params.h> 21#include <sound/pcm_params.h>
22 22
23#include <plat/audio.h> 23#include <linux/platform_data/asoc-s3c.h>
24 24
25#include "dma.h" 25#include "dma.h"
26#include "idma.h" 26#include "idma.h"
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c
index c82c646b8a08..ee52c8a00779 100644
--- a/sound/soc/samsung/littlemill.c
+++ b/sound/soc/samsung/littlemill.c
@@ -211,6 +211,11 @@ static int bbclk_ev(struct snd_soc_dapm_widget *w,
211 return 0; 211 return 0;
212} 212}
213 213
214static const struct snd_kcontrol_new controls[] = {
215 SOC_DAPM_PIN_SWITCH("WM1250 Input"),
216 SOC_DAPM_PIN_SWITCH("WM1250 Output"),
217};
218
214static struct snd_soc_dapm_widget widgets[] = { 219static struct snd_soc_dapm_widget widgets[] = {
215 SND_SOC_DAPM_HP("Headphone", NULL), 220 SND_SOC_DAPM_HP("Headphone", NULL),
216 221
@@ -282,6 +287,8 @@ static struct snd_soc_card littlemill = {
282 .set_bias_level = littlemill_set_bias_level, 287 .set_bias_level = littlemill_set_bias_level,
283 .set_bias_level_post = littlemill_set_bias_level_post, 288 .set_bias_level_post = littlemill_set_bias_level_post,
284 289
290 .controls = controls,
291 .num_controls = ARRAY_SIZE(controls),
285 .dapm_widgets = widgets, 292 .dapm_widgets = widgets,
286 .num_dapm_widgets = ARRAY_SIZE(widgets), 293 .num_dapm_widgets = ARRAY_SIZE(widgets),
287 .dapm_routes = audio_paths, 294 .dapm_routes = audio_paths,
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index b7b2a1f91425..c86081992dfd 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -19,8 +19,8 @@
19#include <sound/soc.h> 19#include <sound/soc.h>
20#include <sound/pcm_params.h> 20#include <sound/pcm_params.h>
21 21
22#include <plat/audio.h> 22#include <linux/platform_data/asoc-s3c.h>
23#include <plat/dma.h> 23#include <mach/dma.h>
24 24
25#include "dma.h" 25#include "dma.h"
26#include "pcm.h" 26#include "pcm.h"
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 79fbeea99d46..ac7701b3c5dc 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -25,7 +25,6 @@
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27 27
28#include <mach/regs-gpio.h>
29#include <mach/dma.h> 28#include <mach/dma.h>
30 29
31#include "dma.h" 30#include "dma.h"
@@ -83,12 +82,9 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
83 82
84 s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk; 83 s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk;
85 84
86 /* Configure the I2S pins in correct mode */ 85 /* Configure the I2S pins (GPE0...GPE4) in correct mode */
87 s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK); 86 s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2),
88 s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK); 87 S3C_GPIO_PULL_NONE);
89 s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK);
90 s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI);
91 s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO);
92 88
93 return 0; 89 return 0;
94} 90}
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index c4aa4d412fbf..0aae3a3883dc 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -23,7 +23,6 @@
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25 25
26#include <mach/regs-gpio.h>
27#include <mach/dma.h> 26#include <mach/dma.h>
28#include <plat/regs-iis.h> 27#include <plat/regs-iis.h>
29 28
@@ -391,12 +390,9 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai)
391 } 390 }
392 clk_enable(s3c24xx_i2s.iis_clk); 391 clk_enable(s3c24xx_i2s.iis_clk);
393 392
394 /* Configure the I2S pins in correct mode */ 393 /* Configure the I2S pins (GPE0...GPE4) in correct mode */
395 s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK); 394 s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2),
396 s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK); 395 S3C_GPIO_PULL_NONE);
397 s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK);
398 s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI);
399 s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO);
400 396
401 writel(S3C2410_IISCON_IISEN, s3c24xx_i2s.regs + S3C2410_IISCON); 397 writel(S3C2410_IISCON_IISEN, s3c24xx_i2s.regs + S3C2410_IISCON);
402 398
diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c
index 656d5afe4ca9..335a7d8a4a8d 100644
--- a/sound/soc/samsung/s3c24xx_simtec.c
+++ b/sound/soc/samsung/s3c24xx_simtec.c
@@ -13,7 +13,7 @@
13 13
14#include <sound/soc.h> 14#include <sound/soc.h>
15 15
16#include <plat/audio-simtec.h> 16#include <linux/platform_data/asoc-s3c24xx_simtec.h>
17 17
18#include "s3c24xx-i2s.h" 18#include "s3c24xx-i2s.h"
19#include "s3c24xx_simtec.h" 19#include "s3c24xx_simtec.h"
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c
index 8eb309f23d18..48dd4dd9ee08 100644
--- a/sound/soc/samsung/smdk_wm8994.c
+++ b/sound/soc/samsung/smdk_wm8994.c
@@ -149,31 +149,41 @@ static struct snd_soc_card smdk = {
149 .num_links = ARRAY_SIZE(smdk_dai), 149 .num_links = ARRAY_SIZE(smdk_dai),
150}; 150};
151 151
152static struct platform_device *smdk_snd_device;
153 152
154static int __init smdk_audio_init(void) 153static int __devinit smdk_audio_probe(struct platform_device *pdev)
155{ 154{
156 int ret; 155 int ret;
156 struct snd_soc_card *card = &smdk;
157 157
158 smdk_snd_device = platform_device_alloc("soc-audio", -1); 158 card->dev = &pdev->dev;
159 if (!smdk_snd_device) 159 ret = snd_soc_register_card(card);
160 return -ENOMEM;
161 160
162 platform_set_drvdata(smdk_snd_device, &smdk);
163
164 ret = platform_device_add(smdk_snd_device);
165 if (ret) 161 if (ret)
166 platform_device_put(smdk_snd_device); 162 dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret);
167 163
168 return ret; 164 return ret;
169} 165}
170module_init(smdk_audio_init);
171 166
172static void __exit smdk_audio_exit(void) 167static int __devexit smdk_audio_remove(struct platform_device *pdev)
173{ 168{
174 platform_device_unregister(smdk_snd_device); 169 struct snd_soc_card *card = platform_get_drvdata(pdev);
170
171 snd_soc_unregister_card(card);
172
173 return 0;
175} 174}
176module_exit(smdk_audio_exit); 175
176static struct platform_driver smdk_audio_driver = {
177 .driver = {
178 .name = "smdk-audio",
179 .owner = THIS_MODULE,
180 },
181 .probe = smdk_audio_probe,
182 .remove = __devexit_p(smdk_audio_remove),
183};
184
185module_platform_driver(smdk_audio_driver);
177 186
178MODULE_DESCRIPTION("ALSA SoC SMDK WM8994"); 187MODULE_DESCRIPTION("ALSA SoC SMDK WM8994");
179MODULE_LICENSE("GPL"); 188MODULE_LICENSE("GPL");
189MODULE_ALIAS("platform:smdk-audio");
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index a5a56a120345..bc24c7af02b2 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -17,7 +17,7 @@
17#include <sound/soc.h> 17#include <sound/soc.h>
18#include <sound/pcm_params.h> 18#include <sound/pcm_params.h>
19 19
20#include <plat/audio.h> 20#include <linux/platform_data/asoc-s3c.h>
21#include <mach/dma.h> 21#include <mach/dma.h>
22 22
23#include "dma.h" 23#include "dma.h"
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 2ef98536f1da..0540408a9fa9 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -247,7 +247,7 @@ struct fsi_priv {
247struct fsi_stream_handler { 247struct fsi_stream_handler {
248 int (*init)(struct fsi_priv *fsi, struct fsi_stream *io); 248 int (*init)(struct fsi_priv *fsi, struct fsi_stream *io);
249 int (*quit)(struct fsi_priv *fsi, struct fsi_stream *io); 249 int (*quit)(struct fsi_priv *fsi, struct fsi_stream *io);
250 int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io); 250 int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev);
251 int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io); 251 int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io);
252 int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io); 252 int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io);
253 void (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io, 253 void (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io,
@@ -571,16 +571,16 @@ static int fsi_stream_transfer(struct fsi_stream *io)
571#define fsi_stream_stop(fsi, io)\ 571#define fsi_stream_stop(fsi, io)\
572 fsi_stream_handler_call(io, start_stop, fsi, io, 0) 572 fsi_stream_handler_call(io, start_stop, fsi, io, 0)
573 573
574static int fsi_stream_probe(struct fsi_priv *fsi) 574static int fsi_stream_probe(struct fsi_priv *fsi, struct device *dev)
575{ 575{
576 struct fsi_stream *io; 576 struct fsi_stream *io;
577 int ret1, ret2; 577 int ret1, ret2;
578 578
579 io = &fsi->playback; 579 io = &fsi->playback;
580 ret1 = fsi_stream_handler_call(io, probe, fsi, io); 580 ret1 = fsi_stream_handler_call(io, probe, fsi, io, dev);
581 581
582 io = &fsi->capture; 582 io = &fsi->capture;
583 ret2 = fsi_stream_handler_call(io, probe, fsi, io); 583 ret2 = fsi_stream_handler_call(io, probe, fsi, io, dev);
584 584
585 if (ret1 < 0) 585 if (ret1 < 0)
586 return ret1; 586 return ret1;
@@ -1089,13 +1089,10 @@ static void fsi_dma_do_tasklet(unsigned long data)
1089{ 1089{
1090 struct fsi_stream *io = (struct fsi_stream *)data; 1090 struct fsi_stream *io = (struct fsi_stream *)data;
1091 struct fsi_priv *fsi = fsi_stream_to_priv(io); 1091 struct fsi_priv *fsi = fsi_stream_to_priv(io);
1092 struct dma_chan *chan;
1093 struct snd_soc_dai *dai; 1092 struct snd_soc_dai *dai;
1094 struct dma_async_tx_descriptor *desc; 1093 struct dma_async_tx_descriptor *desc;
1095 struct scatterlist sg;
1096 struct snd_pcm_runtime *runtime; 1094 struct snd_pcm_runtime *runtime;
1097 enum dma_data_direction dir; 1095 enum dma_data_direction dir;
1098 dma_cookie_t cookie;
1099 int is_play = fsi_stream_is_play(fsi, io); 1096 int is_play = fsi_stream_is_play(fsi, io);
1100 int len; 1097 int len;
1101 dma_addr_t buf; 1098 dma_addr_t buf;
@@ -1104,7 +1101,6 @@ static void fsi_dma_do_tasklet(unsigned long data)
1104 return; 1101 return;
1105 1102
1106 dai = fsi_get_dai(io->substream); 1103 dai = fsi_get_dai(io->substream);
1107 chan = io->chan;
1108 runtime = io->substream->runtime; 1104 runtime = io->substream->runtime;
1109 dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; 1105 dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
1110 len = samples_to_bytes(runtime, io->period_samples); 1106 len = samples_to_bytes(runtime, io->period_samples);
@@ -1112,14 +1108,8 @@ static void fsi_dma_do_tasklet(unsigned long data)
1112 1108
1113 dma_sync_single_for_device(dai->dev, buf, len, dir); 1109 dma_sync_single_for_device(dai->dev, buf, len, dir);
1114 1110
1115 sg_init_table(&sg, 1); 1111 desc = dmaengine_prep_slave_single(io->chan, buf, len, dir,
1116 sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)), 1112 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
1117 len , offset_in_page(buf));
1118 sg_dma_address(&sg) = buf;
1119 sg_dma_len(&sg) = len;
1120
1121 desc = dmaengine_prep_slave_sg(chan, &sg, 1, dir,
1122 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
1123 if (!desc) { 1113 if (!desc) {
1124 dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n"); 1114 dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n");
1125 return; 1115 return;
@@ -1128,13 +1118,12 @@ static void fsi_dma_do_tasklet(unsigned long data)
1128 desc->callback = fsi_dma_complete; 1118 desc->callback = fsi_dma_complete;
1129 desc->callback_param = io; 1119 desc->callback_param = io;
1130 1120
1131 cookie = desc->tx_submit(desc); 1121 if (dmaengine_submit(desc) < 0) {
1132 if (cookie < 0) {
1133 dev_err(dai->dev, "tx_submit() fail\n"); 1122 dev_err(dai->dev, "tx_submit() fail\n");
1134 return; 1123 return;
1135 } 1124 }
1136 1125
1137 dma_async_issue_pending(chan); 1126 dma_async_issue_pending(io->chan);
1138 1127
1139 /* 1128 /*
1140 * FIXME 1129 * FIXME
@@ -1184,7 +1173,7 @@ static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
1184 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); 1173 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
1185} 1174}
1186 1175
1187static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io) 1176static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev)
1188{ 1177{
1189 dma_cap_mask_t mask; 1178 dma_cap_mask_t mask;
1190 1179
@@ -1192,8 +1181,19 @@ static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io)
1192 dma_cap_set(DMA_SLAVE, mask); 1181 dma_cap_set(DMA_SLAVE, mask);
1193 1182
1194 io->chan = dma_request_channel(mask, fsi_dma_filter, &io->slave); 1183 io->chan = dma_request_channel(mask, fsi_dma_filter, &io->slave);
1195 if (!io->chan) 1184 if (!io->chan) {
1196 return -EIO; 1185
1186 /* switch to PIO handler */
1187 if (fsi_stream_is_play(fsi, io))
1188 fsi->playback.handler = &fsi_pio_push_handler;
1189 else
1190 fsi->capture.handler = &fsi_pio_pop_handler;
1191
1192 dev_info(dev, "switch handler (dma => pio)\n");
1193
1194 /* probe again */
1195 return fsi_stream_probe(fsi, dev);
1196 }
1197 1197
1198 tasklet_init(&io->tasklet, fsi_dma_do_tasklet, (unsigned long)io); 1198 tasklet_init(&io->tasklet, fsi_dma_do_tasklet, (unsigned long)io);
1199 1199
@@ -1631,8 +1631,8 @@ static void fsi_handler_init(struct fsi_priv *fsi)
1631 fsi->capture.priv = fsi; 1631 fsi->capture.priv = fsi;
1632 1632
1633 if (fsi->info->tx_id) { 1633 if (fsi->info->tx_id) {
1634 fsi->playback.slave.slave_id = fsi->info->tx_id; 1634 fsi->playback.slave.shdma_slave.slave_id = fsi->info->tx_id;
1635 fsi->playback.handler = &fsi_dma_push_handler; 1635 fsi->playback.handler = &fsi_dma_push_handler;
1636 } 1636 }
1637} 1637}
1638 1638
@@ -1683,7 +1683,7 @@ static int fsi_probe(struct platform_device *pdev)
1683 master->fsia.master = master; 1683 master->fsia.master = master;
1684 master->fsia.info = &info->port_a; 1684 master->fsia.info = &info->port_a;
1685 fsi_handler_init(&master->fsia); 1685 fsi_handler_init(&master->fsia);
1686 ret = fsi_stream_probe(&master->fsia); 1686 ret = fsi_stream_probe(&master->fsia, &pdev->dev);
1687 if (ret < 0) { 1687 if (ret < 0) {
1688 dev_err(&pdev->dev, "FSIA stream probe failed\n"); 1688 dev_err(&pdev->dev, "FSIA stream probe failed\n");
1689 goto exit_iounmap; 1689 goto exit_iounmap;
@@ -1694,7 +1694,7 @@ static int fsi_probe(struct platform_device *pdev)
1694 master->fsib.master = master; 1694 master->fsib.master = master;
1695 master->fsib.info = &info->port_b; 1695 master->fsib.info = &info->port_b;
1696 fsi_handler_init(&master->fsib); 1696 fsi_handler_init(&master->fsib);
1697 ret = fsi_stream_probe(&master->fsib); 1697 ret = fsi_stream_probe(&master->fsib, &pdev->dev);
1698 if (ret < 0) { 1698 if (ret < 0) {
1699 dev_err(&pdev->dev, "FSIB stream probe failed\n"); 1699 dev_err(&pdev->dev, "FSIB stream probe failed\n");
1700 goto exit_fsia; 1700 goto exit_fsia;
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
index 5cfcc655e95f..488f9becb44f 100644
--- a/sound/soc/sh/siu_pcm.c
+++ b/sound/soc/sh/siu_pcm.c
@@ -330,12 +330,9 @@ static bool filter(struct dma_chan *chan, void *slave)
330{ 330{
331 struct sh_dmae_slave *param = slave; 331 struct sh_dmae_slave *param = slave;
332 332
333 pr_debug("%s: slave ID %d\n", __func__, param->slave_id); 333 pr_debug("%s: slave ID %d\n", __func__, param->shdma_slave.slave_id);
334 334
335 if (unlikely(param->dma_dev != chan->device->dev)) 335 chan->private = &param->shdma_slave;
336 return false;
337
338 chan->private = param;
339 return true; 336 return true;
340} 337}
341 338
@@ -360,16 +357,15 @@ static int siu_pcm_open(struct snd_pcm_substream *ss)
360 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) { 357 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) {
361 siu_stream = &port_info->playback; 358 siu_stream = &port_info->playback;
362 param = &siu_stream->param; 359 param = &siu_stream->param;
363 param->slave_id = port ? pdata->dma_slave_tx_b : 360 param->shdma_slave.slave_id = port ? pdata->dma_slave_tx_b :
364 pdata->dma_slave_tx_a; 361 pdata->dma_slave_tx_a;
365 } else { 362 } else {
366 siu_stream = &port_info->capture; 363 siu_stream = &port_info->capture;
367 param = &siu_stream->param; 364 param = &siu_stream->param;
368 param->slave_id = port ? pdata->dma_slave_rx_b : 365 param->shdma_slave.slave_id = port ? pdata->dma_slave_rx_b :
369 pdata->dma_slave_rx_a; 366 pdata->dma_slave_rx_a;
370 } 367 }
371 368
372 param->dma_dev = pdata->dma_dev;
373 /* Get DMA channel */ 369 /* Get DMA channel */
374 siu_stream->chan = dma_request_channel(mask, filter, param); 370 siu_stream->chan = dma_request_channel(mask, filter, param);
375 if (!siu_stream->chan) { 371 if (!siu_stream->chan) {
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index b37ee8077ed1..cf3d0b0c71b9 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -591,7 +591,7 @@ int snd_soc_suspend(struct device *dev)
591 591
592 /* close any waiting streams and save state */ 592 /* close any waiting streams and save state */
593 for (i = 0; i < card->num_rtd; i++) { 593 for (i = 0; i < card->num_rtd; i++) {
594 flush_delayed_work_sync(&card->rtd[i].delayed_work); 594 flush_delayed_work(&card->rtd[i].delayed_work);
595 card->rtd[i].codec->dapm.suspend_bias_level = card->rtd[i].codec->dapm.bias_level; 595 card->rtd[i].codec->dapm.suspend_bias_level = card->rtd[i].codec->dapm.bias_level;
596 } 596 }
597 597
@@ -812,19 +812,21 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
812 812
813 /* Find CPU DAI from registered DAIs*/ 813 /* Find CPU DAI from registered DAIs*/
814 list_for_each_entry(cpu_dai, &dai_list, list) { 814 list_for_each_entry(cpu_dai, &dai_list, list) {
815 if (dai_link->cpu_dai_of_node) { 815 if (dai_link->cpu_of_node &&
816 if (cpu_dai->dev->of_node != dai_link->cpu_dai_of_node) 816 (cpu_dai->dev->of_node != dai_link->cpu_of_node))
817 continue; 817 continue;
818 } else { 818 if (dai_link->cpu_name &&
819 if (strcmp(cpu_dai->name, dai_link->cpu_dai_name)) 819 strcmp(dev_name(cpu_dai->dev), dai_link->cpu_name))
820 continue; 820 continue;
821 } 821 if (dai_link->cpu_dai_name &&
822 strcmp(cpu_dai->name, dai_link->cpu_dai_name))
823 continue;
822 824
823 rtd->cpu_dai = cpu_dai; 825 rtd->cpu_dai = cpu_dai;
824 } 826 }
825 827
826 if (!rtd->cpu_dai) { 828 if (!rtd->cpu_dai) {
827 dev_dbg(card->dev, "CPU DAI %s not registered\n", 829 dev_err(card->dev, "CPU DAI %s not registered\n",
828 dai_link->cpu_dai_name); 830 dai_link->cpu_dai_name);
829 return -EPROBE_DEFER; 831 return -EPROBE_DEFER;
830 } 832 }
@@ -855,14 +857,14 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
855 } 857 }
856 858
857 if (!rtd->codec_dai) { 859 if (!rtd->codec_dai) {
858 dev_dbg(card->dev, "CODEC DAI %s not registered\n", 860 dev_err(card->dev, "CODEC DAI %s not registered\n",
859 dai_link->codec_dai_name); 861 dai_link->codec_dai_name);
860 return -EPROBE_DEFER; 862 return -EPROBE_DEFER;
861 } 863 }
862 } 864 }
863 865
864 if (!rtd->codec) { 866 if (!rtd->codec) {
865 dev_dbg(card->dev, "CODEC %s not registered\n", 867 dev_err(card->dev, "CODEC %s not registered\n",
866 dai_link->codec_name); 868 dai_link->codec_name);
867 return -EPROBE_DEFER; 869 return -EPROBE_DEFER;
868 } 870 }
@@ -886,7 +888,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
886 rtd->platform = platform; 888 rtd->platform = platform;
887 } 889 }
888 if (!rtd->platform) { 890 if (!rtd->platform) {
889 dev_dbg(card->dev, "platform %s not registered\n", 891 dev_err(card->dev, "platform %s not registered\n",
890 dai_link->platform_name); 892 dai_link->platform_name);
891 return -EPROBE_DEFER; 893 return -EPROBE_DEFER;
892 } 894 }
@@ -896,6 +898,28 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
896 return 0; 898 return 0;
897} 899}
898 900
901static int soc_remove_platform(struct snd_soc_platform *platform)
902{
903 int ret;
904
905 if (platform->driver->remove) {
906 ret = platform->driver->remove(platform);
907 if (ret < 0)
908 pr_err("asoc: failed to remove %s: %d\n",
909 platform->name, ret);
910 }
911
912 /* Make sure all DAPM widgets are freed */
913 snd_soc_dapm_free(&platform->dapm);
914
915 soc_cleanup_platform_debugfs(platform);
916 platform->probed = 0;
917 list_del(&platform->card_list);
918 module_put(platform->dev->driver->owner);
919
920 return 0;
921}
922
899static void soc_remove_codec(struct snd_soc_codec *codec) 923static void soc_remove_codec(struct snd_soc_codec *codec)
900{ 924{
901 int err; 925 int err;
@@ -917,11 +941,9 @@ static void soc_remove_codec(struct snd_soc_codec *codec)
917 module_put(codec->dev->driver->owner); 941 module_put(codec->dev->driver->owner);
918} 942}
919 943
920static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order) 944static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order)
921{ 945{
922 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 946 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
923 struct snd_soc_codec *codec = rtd->codec;
924 struct snd_soc_platform *platform = rtd->platform;
925 struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai; 947 struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai;
926 int err; 948 int err;
927 949
@@ -946,30 +968,6 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order)
946 list_del(&codec_dai->card_list); 968 list_del(&codec_dai->card_list);
947 } 969 }
948 970
949 /* remove the platform */
950 if (platform && platform->probed &&
951 platform->driver->remove_order == order) {
952 if (platform->driver->remove) {
953 err = platform->driver->remove(platform);
954 if (err < 0)
955 pr_err("asoc: failed to remove %s: %d\n",
956 platform->name, err);
957 }
958
959 /* Make sure all DAPM widgets are freed */
960 snd_soc_dapm_free(&platform->dapm);
961
962 soc_cleanup_platform_debugfs(platform);
963 platform->probed = 0;
964 list_del(&platform->card_list);
965 module_put(platform->dev->driver->owner);
966 }
967
968 /* remove the CODEC */
969 if (codec && codec->probed &&
970 codec->driver->remove_order == order)
971 soc_remove_codec(codec);
972
973 /* remove the cpu_dai */ 971 /* remove the cpu_dai */
974 if (cpu_dai && cpu_dai->probed && 972 if (cpu_dai && cpu_dai->probed &&
975 cpu_dai->driver->remove_order == order) { 973 cpu_dai->driver->remove_order == order) {
@@ -981,7 +979,43 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order)
981 } 979 }
982 cpu_dai->probed = 0; 980 cpu_dai->probed = 0;
983 list_del(&cpu_dai->card_list); 981 list_del(&cpu_dai->card_list);
984 module_put(cpu_dai->dev->driver->owner); 982
983 if (!cpu_dai->codec) {
984 snd_soc_dapm_free(&cpu_dai->dapm);
985 module_put(cpu_dai->dev->driver->owner);
986 }
987 }
988}
989
990static void soc_remove_link_components(struct snd_soc_card *card, int num,
991 int order)
992{
993 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
994 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
995 struct snd_soc_dai *codec_dai = rtd->codec_dai;
996 struct snd_soc_platform *platform = rtd->platform;
997 struct snd_soc_codec *codec;
998
999 /* remove the platform */
1000 if (platform && platform->probed &&
1001 platform->driver->remove_order == order) {
1002 soc_remove_platform(platform);
1003 }
1004
1005 /* remove the CODEC-side CODEC */
1006 if (codec_dai) {
1007 codec = codec_dai->codec;
1008 if (codec && codec->probed &&
1009 codec->driver->remove_order == order)
1010 soc_remove_codec(codec);
1011 }
1012
1013 /* remove any CPU-side CODEC */
1014 if (cpu_dai) {
1015 codec = cpu_dai->codec;
1016 if (codec && codec->probed &&
1017 codec->driver->remove_order == order)
1018 soc_remove_codec(codec);
985 } 1019 }
986} 1020}
987 1021
@@ -992,8 +1026,15 @@ static void soc_remove_dai_links(struct snd_soc_card *card)
992 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; 1026 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
993 order++) { 1027 order++) {
994 for (dai = 0; dai < card->num_rtd; dai++) 1028 for (dai = 0; dai < card->num_rtd; dai++)
995 soc_remove_dai_link(card, dai, order); 1029 soc_remove_link_dais(card, dai, order);
1030 }
1031
1032 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1033 order++) {
1034 for (dai = 0; dai < card->num_rtd; dai++)
1035 soc_remove_link_components(card, dai, order);
996 } 1036 }
1037
997 card->num_rtd = 0; 1038 card->num_rtd = 0;
998} 1039}
999 1040
@@ -1054,6 +1095,10 @@ static int soc_probe_codec(struct snd_soc_card *card,
1054 } 1095 }
1055 } 1096 }
1056 1097
1098 /* If the driver didn't set I/O up try regmap */
1099 if (!codec->write && dev_get_regmap(codec->dev, NULL))
1100 snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
1101
1057 if (driver->controls) 1102 if (driver->controls)
1058 snd_soc_add_codec_controls(codec, driver->controls, 1103 snd_soc_add_codec_controls(codec, driver->controls,
1059 driver->num_controls); 1104 driver->num_controls);
@@ -1230,7 +1275,44 @@ out:
1230 return 0; 1275 return 0;
1231} 1276}
1232 1277
1233static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order) 1278static int soc_probe_link_components(struct snd_soc_card *card, int num,
1279 int order)
1280{
1281 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1282 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1283 struct snd_soc_dai *codec_dai = rtd->codec_dai;
1284 struct snd_soc_platform *platform = rtd->platform;
1285 int ret;
1286
1287 /* probe the CPU-side component, if it is a CODEC */
1288 if (cpu_dai->codec &&
1289 !cpu_dai->codec->probed &&
1290 cpu_dai->codec->driver->probe_order == order) {
1291 ret = soc_probe_codec(card, cpu_dai->codec);
1292 if (ret < 0)
1293 return ret;
1294 }
1295
1296 /* probe the CODEC-side component */
1297 if (!codec_dai->codec->probed &&
1298 codec_dai->codec->driver->probe_order == order) {
1299 ret = soc_probe_codec(card, codec_dai->codec);
1300 if (ret < 0)
1301 return ret;
1302 }
1303
1304 /* probe the platform */
1305 if (!platform->probed &&
1306 platform->driver->probe_order == order) {
1307 ret = soc_probe_platform(card, platform);
1308 if (ret < 0)
1309 return ret;
1310 }
1311
1312 return 0;
1313}
1314
1315static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1234{ 1316{
1235 struct snd_soc_dai_link *dai_link = &card->dai_link[num]; 1317 struct snd_soc_dai_link *dai_link = &card->dai_link[num];
1236 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 1318 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
@@ -1255,11 +1337,14 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
1255 /* probe the cpu_dai */ 1337 /* probe the cpu_dai */
1256 if (!cpu_dai->probed && 1338 if (!cpu_dai->probed &&
1257 cpu_dai->driver->probe_order == order) { 1339 cpu_dai->driver->probe_order == order) {
1258 cpu_dai->dapm.card = card; 1340 if (!cpu_dai->codec) {
1259 if (!try_module_get(cpu_dai->dev->driver->owner)) 1341 cpu_dai->dapm.card = card;
1260 return -ENODEV; 1342 if (!try_module_get(cpu_dai->dev->driver->owner))
1343 return -ENODEV;
1261 1344
1262 snd_soc_dapm_new_dai_widgets(&cpu_dai->dapm, cpu_dai); 1345 list_add(&cpu_dai->dapm.list, &card->dapm_list);
1346 snd_soc_dapm_new_dai_widgets(&cpu_dai->dapm, cpu_dai);
1347 }
1263 1348
1264 if (cpu_dai->driver->probe) { 1349 if (cpu_dai->driver->probe) {
1265 ret = cpu_dai->driver->probe(cpu_dai); 1350 ret = cpu_dai->driver->probe(cpu_dai);
@@ -1275,22 +1360,6 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
1275 list_add(&cpu_dai->card_list, &card->dai_dev_list); 1360 list_add(&cpu_dai->card_list, &card->dai_dev_list);
1276 } 1361 }
1277 1362
1278 /* probe the CODEC */
1279 if (!codec->probed &&
1280 codec->driver->probe_order == order) {
1281 ret = soc_probe_codec(card, codec);
1282 if (ret < 0)
1283 return ret;
1284 }
1285
1286 /* probe the platform */
1287 if (!platform->probed &&
1288 platform->driver->probe_order == order) {
1289 ret = soc_probe_platform(card, platform);
1290 if (ret < 0)
1291 return ret;
1292 }
1293
1294 /* probe the CODEC DAI */ 1363 /* probe the CODEC DAI */
1295 if (!codec_dai->probed && codec_dai->driver->probe_order == order) { 1364 if (!codec_dai->probed && codec_dai->driver->probe_order == order) {
1296 if (codec_dai->driver->probe) { 1365 if (codec_dai->driver->probe) {
@@ -1412,6 +1481,8 @@ static int soc_check_aux_dev(struct snd_soc_card *card, int num)
1412 return 0; 1481 return 0;
1413 } 1482 }
1414 1483
1484 dev_err(card->dev, "%s not registered\n", aux_dev->codec_name);
1485
1415 return -EPROBE_DEFER; 1486 return -EPROBE_DEFER;
1416} 1487}
1417 1488
@@ -1565,14 +1636,27 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1565 goto card_probe_error; 1636 goto card_probe_error;
1566 } 1637 }
1567 1638
1568 /* early DAI link probe */ 1639 /* probe all components used by DAI links on this card */
1569 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; 1640 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1570 order++) { 1641 order++) {
1571 for (i = 0; i < card->num_links; i++) { 1642 for (i = 0; i < card->num_links; i++) {
1572 ret = soc_probe_dai_link(card, i, order); 1643 ret = soc_probe_link_components(card, i, order);
1573 if (ret < 0) { 1644 if (ret < 0) {
1574 pr_err("asoc: failed to instantiate card %s: %d\n", 1645 pr_err("asoc: failed to instantiate card %s: %d\n",
1575 card->name, ret); 1646 card->name, ret);
1647 goto probe_dai_err;
1648 }
1649 }
1650 }
1651
1652 /* probe all DAI links on this card */
1653 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1654 order++) {
1655 for (i = 0; i < card->num_links; i++) {
1656 ret = soc_probe_link_dais(card, i, order);
1657 if (ret < 0) {
1658 pr_err("asoc: failed to instantiate card %s: %d\n",
1659 card->name, ret);
1576 goto probe_dai_err; 1660 goto probe_dai_err;
1577 } 1661 }
1578 } 1662 }
@@ -1764,7 +1848,7 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
1764 /* make sure any delayed work runs */ 1848 /* make sure any delayed work runs */
1765 for (i = 0; i < card->num_rtd; i++) { 1849 for (i = 0; i < card->num_rtd; i++) {
1766 struct snd_soc_pcm_runtime *rtd = &card->rtd[i]; 1850 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
1767 flush_delayed_work_sync(&rtd->delayed_work); 1851 flush_delayed_work(&rtd->delayed_work);
1768 } 1852 }
1769 1853
1770 /* remove auxiliary devices */ 1854 /* remove auxiliary devices */
@@ -1808,7 +1892,7 @@ int snd_soc_poweroff(struct device *dev)
1808 * now, we're shutting down so no imminent restart. */ 1892 * now, we're shutting down so no imminent restart. */
1809 for (i = 0; i < card->num_rtd; i++) { 1893 for (i = 0; i < card->num_rtd; i++) {
1810 struct snd_soc_pcm_runtime *rtd = &card->rtd[i]; 1894 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
1811 flush_delayed_work_sync(&rtd->delayed_work); 1895 flush_delayed_work(&rtd->delayed_work);
1812 } 1896 }
1813 1897
1814 snd_soc_dapm_shutdown(card); 1898 snd_soc_dapm_shutdown(card);
@@ -2790,6 +2874,104 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
2790EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); 2874EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
2791 2875
2792/** 2876/**
2877 * snd_soc_info_volsw_range - single mixer info callback with range.
2878 * @kcontrol: mixer control
2879 * @uinfo: control element information
2880 *
2881 * Callback to provide information, within a range, about a single
2882 * mixer control.
2883 *
2884 * returns 0 for success.
2885 */
2886int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol,
2887 struct snd_ctl_elem_info *uinfo)
2888{
2889 struct soc_mixer_control *mc =
2890 (struct soc_mixer_control *)kcontrol->private_value;
2891 int platform_max;
2892 int min = mc->min;
2893
2894 if (!mc->platform_max)
2895 mc->platform_max = mc->max;
2896 platform_max = mc->platform_max;
2897
2898 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2899 uinfo->count = 1;
2900 uinfo->value.integer.min = 0;
2901 uinfo->value.integer.max = platform_max - min;
2902
2903 return 0;
2904}
2905EXPORT_SYMBOL_GPL(snd_soc_info_volsw_range);
2906
2907/**
2908 * snd_soc_put_volsw_range - single mixer put value callback with range.
2909 * @kcontrol: mixer control
2910 * @ucontrol: control element information
2911 *
2912 * Callback to set the value, within a range, for a single mixer control.
2913 *
2914 * Returns 0 for success.
2915 */
2916int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
2917 struct snd_ctl_elem_value *ucontrol)
2918{
2919 struct soc_mixer_control *mc =
2920 (struct soc_mixer_control *)kcontrol->private_value;
2921 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2922 unsigned int reg = mc->reg;
2923 unsigned int shift = mc->shift;
2924 int min = mc->min;
2925 int max = mc->max;
2926 unsigned int mask = (1 << fls(max)) - 1;
2927 unsigned int invert = mc->invert;
2928 unsigned int val, val_mask;
2929
2930 val = ((ucontrol->value.integer.value[0] + min) & mask);
2931 if (invert)
2932 val = max - val;
2933 val_mask = mask << shift;
2934 val = val << shift;
2935
2936 return snd_soc_update_bits_locked(codec, reg, val_mask, val);
2937}
2938EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range);
2939
2940/**
2941 * snd_soc_get_volsw_range - single mixer get callback with range
2942 * @kcontrol: mixer control
2943 * @ucontrol: control element information
2944 *
2945 * Callback to get the value, within a range, of a single mixer control.
2946 *
2947 * Returns 0 for success.
2948 */
2949int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol,
2950 struct snd_ctl_elem_value *ucontrol)
2951{
2952 struct soc_mixer_control *mc =
2953 (struct soc_mixer_control *)kcontrol->private_value;
2954 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2955 unsigned int reg = mc->reg;
2956 unsigned int shift = mc->shift;
2957 int min = mc->min;
2958 int max = mc->max;
2959 unsigned int mask = (1 << fls(max)) - 1;
2960 unsigned int invert = mc->invert;
2961
2962 ucontrol->value.integer.value[0] =
2963 (snd_soc_read(codec, reg) >> shift) & mask;
2964 if (invert)
2965 ucontrol->value.integer.value[0] =
2966 max - ucontrol->value.integer.value[0];
2967 ucontrol->value.integer.value[0] =
2968 ucontrol->value.integer.value[0] - min;
2969
2970 return 0;
2971}
2972EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range);
2973
2974/**
2793 * snd_soc_limit_volume - Set new limit to an existing volume control. 2975 * snd_soc_limit_volume - Set new limit to an existing volume control.
2794 * 2976 *
2795 * @codec: where to look for the control 2977 * @codec: where to look for the control
@@ -3346,6 +3528,12 @@ int snd_soc_register_card(struct snd_soc_card *card)
3346 link->name); 3528 link->name);
3347 return -EINVAL; 3529 return -EINVAL;
3348 } 3530 }
3531 /* Codec DAI name must be specified */
3532 if (!link->codec_dai_name) {
3533 dev_err(card->dev, "codec_dai_name not set for %s\n",
3534 link->name);
3535 return -EINVAL;
3536 }
3349 3537
3350 /* 3538 /*
3351 * Platform may be specified by either name or OF node, but 3539 * Platform may be specified by either name or OF node, but
@@ -3358,12 +3546,24 @@ int snd_soc_register_card(struct snd_soc_card *card)
3358 } 3546 }
3359 3547
3360 /* 3548 /*
3361 * CPU DAI must be specified by 1 of name or OF node, 3549 * CPU device may be specified by either name or OF node, but
3362 * not both or neither. 3550 * can be left unspecified, and will be matched based on DAI
3551 * name alone..
3552 */
3553 if (link->cpu_name && link->cpu_of_node) {
3554 dev_err(card->dev,
3555 "Neither/both cpu name/of_node are set for %s\n",
3556 link->name);
3557 return -EINVAL;
3558 }
3559 /*
3560 * At least one of CPU DAI name or CPU device name/node must be
3561 * specified
3363 */ 3562 */
3364 if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) { 3563 if (!link->cpu_dai_name &&
3564 !(link->cpu_name || link->cpu_of_node)) {
3365 dev_err(card->dev, 3565 dev_err(card->dev,
3366 "Neither/both cpu_dai name/of_node are set for %s\n", 3566 "Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
3367 link->name); 3567 link->name);
3368 return -EINVAL; 3568 return -EINVAL;
3369 } 3569 }
@@ -3938,6 +4138,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
3938 dev_err(card->dev, 4138 dev_err(card->dev,
3939 "Property '%s' index %d could not be read: %d\n", 4139 "Property '%s' index %d could not be read: %d\n",
3940 propname, 2 * i, ret); 4140 propname, 2 * i, ret);
4141 kfree(routes);
3941 return -EINVAL; 4142 return -EINVAL;
3942 } 4143 }
3943 ret = of_property_read_string_index(np, propname, 4144 ret = of_property_read_string_index(np, propname,
@@ -3946,6 +4147,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
3946 dev_err(card->dev, 4147 dev_err(card->dev,
3947 "Property '%s' index %d could not be read: %d\n", 4148 "Property '%s' index %d could not be read: %d\n",
3948 propname, (2 * i) + 1, ret); 4149 propname, (2 * i) + 1, ret);
4150 kfree(routes);
3949 return -EINVAL; 4151 return -EINVAL;
3950 } 4152 }
3951 } 4153 }
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 89eae93445cf..f90139b5f50d 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -35,6 +35,7 @@
35#include <linux/debugfs.h> 35#include <linux/debugfs.h>
36#include <linux/pm_runtime.h> 36#include <linux/pm_runtime.h>
37#include <linux/regulator/consumer.h> 37#include <linux/regulator/consumer.h>
38#include <linux/clk.h>
38#include <linux/slab.h> 39#include <linux/slab.h>
39#include <sound/core.h> 40#include <sound/core.h>
40#include <sound/pcm.h> 41#include <sound/pcm.h>
@@ -51,6 +52,7 @@ static int dapm_up_seq[] = {
51 [snd_soc_dapm_pre] = 0, 52 [snd_soc_dapm_pre] = 0,
52 [snd_soc_dapm_supply] = 1, 53 [snd_soc_dapm_supply] = 1,
53 [snd_soc_dapm_regulator_supply] = 1, 54 [snd_soc_dapm_regulator_supply] = 1,
55 [snd_soc_dapm_clock_supply] = 1,
54 [snd_soc_dapm_micbias] = 2, 56 [snd_soc_dapm_micbias] = 2,
55 [snd_soc_dapm_dai_link] = 2, 57 [snd_soc_dapm_dai_link] = 2,
56 [snd_soc_dapm_dai] = 3, 58 [snd_soc_dapm_dai] = 3,
@@ -92,6 +94,7 @@ static int dapm_down_seq[] = {
92 [snd_soc_dapm_aif_out] = 10, 94 [snd_soc_dapm_aif_out] = 10,
93 [snd_soc_dapm_dai] = 10, 95 [snd_soc_dapm_dai] = 10,
94 [snd_soc_dapm_dai_link] = 11, 96 [snd_soc_dapm_dai_link] = 11,
97 [snd_soc_dapm_clock_supply] = 12,
95 [snd_soc_dapm_regulator_supply] = 12, 98 [snd_soc_dapm_regulator_supply] = 12,
96 [snd_soc_dapm_supply] = 12, 99 [snd_soc_dapm_supply] = 12,
97 [snd_soc_dapm_post] = 13, 100 [snd_soc_dapm_post] = 13,
@@ -290,7 +293,10 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm,
290 level); 293 level);
291 else 294 else
292 dapm->bias_level = level; 295 dapm->bias_level = level;
296 } else if (!card || dapm != &card->dapm) {
297 dapm->bias_level = level;
293 } 298 }
299
294 if (ret != 0) 300 if (ret != 0)
295 goto out; 301 goto out;
296 302
@@ -321,11 +327,10 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
321 327
322 val = soc_widget_read(w, reg); 328 val = soc_widget_read(w, reg);
323 val = (val >> shift) & mask; 329 val = (val >> shift) & mask;
330 if (invert)
331 val = max - val;
324 332
325 if ((invert && !val) || (!invert && val)) 333 p->connect = !!val;
326 p->connect = 1;
327 else
328 p->connect = 0;
329 } 334 }
330 break; 335 break;
331 case snd_soc_dapm_mux: { 336 case snd_soc_dapm_mux: {
@@ -391,6 +396,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
391 case snd_soc_dapm_vmid: 396 case snd_soc_dapm_vmid:
392 case snd_soc_dapm_supply: 397 case snd_soc_dapm_supply:
393 case snd_soc_dapm_regulator_supply: 398 case snd_soc_dapm_regulator_supply:
399 case snd_soc_dapm_clock_supply:
394 case snd_soc_dapm_aif_in: 400 case snd_soc_dapm_aif_in:
395 case snd_soc_dapm_aif_out: 401 case snd_soc_dapm_aif_out:
396 case snd_soc_dapm_dai: 402 case snd_soc_dapm_dai:
@@ -764,6 +770,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
764 switch (widget->id) { 770 switch (widget->id) {
765 case snd_soc_dapm_supply: 771 case snd_soc_dapm_supply:
766 case snd_soc_dapm_regulator_supply: 772 case snd_soc_dapm_regulator_supply:
773 case snd_soc_dapm_clock_supply:
767 return 0; 774 return 0;
768 default: 775 default:
769 break; 776 break;
@@ -850,6 +857,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
850 switch (widget->id) { 857 switch (widget->id) {
851 case snd_soc_dapm_supply: 858 case snd_soc_dapm_supply:
852 case snd_soc_dapm_regulator_supply: 859 case snd_soc_dapm_regulator_supply:
860 case snd_soc_dapm_clock_supply:
853 return 0; 861 return 0;
854 default: 862 default:
855 break; 863 break;
@@ -996,6 +1004,27 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
996} 1004}
997EXPORT_SYMBOL_GPL(dapm_regulator_event); 1005EXPORT_SYMBOL_GPL(dapm_regulator_event);
998 1006
1007/*
1008 * Handler for clock supply widget.
1009 */
1010int dapm_clock_event(struct snd_soc_dapm_widget *w,
1011 struct snd_kcontrol *kcontrol, int event)
1012{
1013 if (!w->clk)
1014 return -EIO;
1015
1016#ifdef CONFIG_HAVE_CLK
1017 if (SND_SOC_DAPM_EVENT_ON(event)) {
1018 return clk_enable(w->clk);
1019 } else {
1020 clk_disable(w->clk);
1021 return 0;
1022 }
1023#endif
1024 return 0;
1025}
1026EXPORT_SYMBOL_GPL(dapm_clock_event);
1027
999static int dapm_widget_power_check(struct snd_soc_dapm_widget *w) 1028static int dapm_widget_power_check(struct snd_soc_dapm_widget *w)
1000{ 1029{
1001 if (w->power_checked) 1030 if (w->power_checked)
@@ -1487,6 +1516,7 @@ static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power,
1487 switch (w->id) { 1516 switch (w->id) {
1488 case snd_soc_dapm_supply: 1517 case snd_soc_dapm_supply:
1489 case snd_soc_dapm_regulator_supply: 1518 case snd_soc_dapm_regulator_supply:
1519 case snd_soc_dapm_clock_supply:
1490 /* Supplies can't affect their outputs, only their inputs */ 1520 /* Supplies can't affect their outputs, only their inputs */
1491 break; 1521 break;
1492 default: 1522 default:
@@ -1545,7 +1575,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1545 struct snd_soc_dapm_context *d; 1575 struct snd_soc_dapm_context *d;
1546 LIST_HEAD(up_list); 1576 LIST_HEAD(up_list);
1547 LIST_HEAD(down_list); 1577 LIST_HEAD(down_list);
1548 LIST_HEAD(async_domain); 1578 ASYNC_DOMAIN_EXCLUSIVE(async_domain);
1549 enum snd_soc_bias_level bias; 1579 enum snd_soc_bias_level bias;
1550 1580
1551 trace_snd_soc_dapm_start(card); 1581 trace_snd_soc_dapm_start(card);
@@ -1570,7 +1600,15 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1570 } 1600 }
1571 1601
1572 list_for_each_entry(w, &card->widgets, list) { 1602 list_for_each_entry(w, &card->widgets, list) {
1573 list_del_init(&w->dirty); 1603 switch (w->id) {
1604 case snd_soc_dapm_pre:
1605 case snd_soc_dapm_post:
1606 /* These widgets always need to be powered */
1607 break;
1608 default:
1609 list_del_init(&w->dirty);
1610 break;
1611 }
1574 1612
1575 if (w->power) { 1613 if (w->power) {
1576 d = w->dapm; 1614 d = w->dapm;
@@ -1587,6 +1625,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1587 break; 1625 break;
1588 case snd_soc_dapm_supply: 1626 case snd_soc_dapm_supply:
1589 case snd_soc_dapm_regulator_supply: 1627 case snd_soc_dapm_regulator_supply:
1628 case snd_soc_dapm_clock_supply:
1590 case snd_soc_dapm_micbias: 1629 case snd_soc_dapm_micbias:
1591 if (d->target_bias_level < SND_SOC_BIAS_STANDBY) 1630 if (d->target_bias_level < SND_SOC_BIAS_STANDBY)
1592 d->target_bias_level = SND_SOC_BIAS_STANDBY; 1631 d->target_bias_level = SND_SOC_BIAS_STANDBY;
@@ -1941,6 +1980,7 @@ static ssize_t dapm_widget_show(struct device *dev,
1941 case snd_soc_dapm_mixer_named_ctl: 1980 case snd_soc_dapm_mixer_named_ctl:
1942 case snd_soc_dapm_supply: 1981 case snd_soc_dapm_supply:
1943 case snd_soc_dapm_regulator_supply: 1982 case snd_soc_dapm_regulator_supply:
1983 case snd_soc_dapm_clock_supply:
1944 if (w->name) 1984 if (w->name)
1945 count += sprintf(buf + count, "%s: %s\n", 1985 count += sprintf(buf + count, "%s: %s\n",
1946 w->name, w->power ? "On":"Off"); 1986 w->name, w->power ? "On":"Off");
@@ -2187,6 +2227,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
2187 case snd_soc_dapm_post: 2227 case snd_soc_dapm_post:
2188 case snd_soc_dapm_supply: 2228 case snd_soc_dapm_supply:
2189 case snd_soc_dapm_regulator_supply: 2229 case snd_soc_dapm_regulator_supply:
2230 case snd_soc_dapm_clock_supply:
2190 case snd_soc_dapm_aif_in: 2231 case snd_soc_dapm_aif_in:
2191 case snd_soc_dapm_aif_out: 2232 case snd_soc_dapm_aif_out:
2192 case snd_soc_dapm_dai: 2233 case snd_soc_dapm_dai:
@@ -2221,6 +2262,10 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
2221 path->connect = 0; 2262 path->connect = 0;
2222 return 0; 2263 return 0;
2223 } 2264 }
2265
2266 dapm_mark_dirty(wsource, "Route added");
2267 dapm_mark_dirty(wsink, "Route added");
2268
2224 return 0; 2269 return 0;
2225 2270
2226err: 2271err:
@@ -2230,6 +2275,59 @@ err:
2230 return ret; 2275 return ret;
2231} 2276}
2232 2277
2278static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm,
2279 const struct snd_soc_dapm_route *route)
2280{
2281 struct snd_soc_dapm_path *path, *p;
2282 const char *sink;
2283 const char *source;
2284 char prefixed_sink[80];
2285 char prefixed_source[80];
2286
2287 if (route->control) {
2288 dev_err(dapm->dev,
2289 "Removal of routes with controls not supported\n");
2290 return -EINVAL;
2291 }
2292
2293 if (dapm->codec && dapm->codec->name_prefix) {
2294 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
2295 dapm->codec->name_prefix, route->sink);
2296 sink = prefixed_sink;
2297 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
2298 dapm->codec->name_prefix, route->source);
2299 source = prefixed_source;
2300 } else {
2301 sink = route->sink;
2302 source = route->source;
2303 }
2304
2305 path = NULL;
2306 list_for_each_entry(p, &dapm->card->paths, list) {
2307 if (strcmp(p->source->name, source) != 0)
2308 continue;
2309 if (strcmp(p->sink->name, sink) != 0)
2310 continue;
2311 path = p;
2312 break;
2313 }
2314
2315 if (path) {
2316 dapm_mark_dirty(path->source, "Route removed");
2317 dapm_mark_dirty(path->sink, "Route removed");
2318
2319 list_del(&path->list);
2320 list_del(&path->list_sink);
2321 list_del(&path->list_source);
2322 kfree(path);
2323 } else {
2324 dev_warn(dapm->dev, "Route %s->%s does not exist\n",
2325 source, sink);
2326 }
2327
2328 return 0;
2329}
2330
2233/** 2331/**
2234 * snd_soc_dapm_add_routes - Add routes between DAPM widgets 2332 * snd_soc_dapm_add_routes - Add routes between DAPM widgets
2235 * @dapm: DAPM context 2333 * @dapm: DAPM context
@@ -2246,15 +2344,15 @@ err:
2246int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, 2344int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
2247 const struct snd_soc_dapm_route *route, int num) 2345 const struct snd_soc_dapm_route *route, int num)
2248{ 2346{
2249 int i, ret = 0; 2347 int i, r, ret = 0;
2250 2348
2251 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); 2349 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
2252 for (i = 0; i < num; i++) { 2350 for (i = 0; i < num; i++) {
2253 ret = snd_soc_dapm_add_route(dapm, route); 2351 r = snd_soc_dapm_add_route(dapm, route);
2254 if (ret < 0) { 2352 if (r < 0) {
2255 dev_err(dapm->dev, "Failed to add route %s->%s\n", 2353 dev_err(dapm->dev, "Failed to add route %s->%s\n",
2256 route->source, route->sink); 2354 route->source, route->sink);
2257 break; 2355 ret = r;
2258 } 2356 }
2259 route++; 2357 route++;
2260 } 2358 }
@@ -2264,6 +2362,30 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
2264} 2362}
2265EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes); 2363EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes);
2266 2364
2365/**
2366 * snd_soc_dapm_del_routes - Remove routes between DAPM widgets
2367 * @dapm: DAPM context
2368 * @route: audio routes
2369 * @num: number of routes
2370 *
2371 * Removes routes from the DAPM context.
2372 */
2373int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm,
2374 const struct snd_soc_dapm_route *route, int num)
2375{
2376 int i, ret = 0;
2377
2378 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
2379 for (i = 0; i < num; i++) {
2380 snd_soc_dapm_del_route(dapm, route);
2381 route++;
2382 }
2383 mutex_unlock(&dapm->card->dapm_mutex);
2384
2385 return ret;
2386}
2387EXPORT_SYMBOL_GPL(snd_soc_dapm_del_routes);
2388
2267static int snd_soc_dapm_weak_route(struct snd_soc_dapm_context *dapm, 2389static int snd_soc_dapm_weak_route(struct snd_soc_dapm_context *dapm,
2268 const struct snd_soc_dapm_route *route) 2390 const struct snd_soc_dapm_route *route)
2269{ 2391{
@@ -2434,23 +2556,20 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
2434 (struct soc_mixer_control *)kcontrol->private_value; 2556 (struct soc_mixer_control *)kcontrol->private_value;
2435 unsigned int reg = mc->reg; 2557 unsigned int reg = mc->reg;
2436 unsigned int shift = mc->shift; 2558 unsigned int shift = mc->shift;
2437 unsigned int rshift = mc->rshift;
2438 int max = mc->max; 2559 int max = mc->max;
2439 unsigned int invert = mc->invert;
2440 unsigned int mask = (1 << fls(max)) - 1; 2560 unsigned int mask = (1 << fls(max)) - 1;
2561 unsigned int invert = mc->invert;
2562
2563 if (snd_soc_volsw_is_stereo(mc))
2564 dev_warn(widget->dapm->dev,
2565 "Control '%s' is stereo, which is not supported\n",
2566 kcontrol->id.name);
2441 2567
2442 ucontrol->value.integer.value[0] = 2568 ucontrol->value.integer.value[0] =
2443 (snd_soc_read(widget->codec, reg) >> shift) & mask; 2569 (snd_soc_read(widget->codec, reg) >> shift) & mask;
2444 if (shift != rshift) 2570 if (invert)
2445 ucontrol->value.integer.value[1] =
2446 (snd_soc_read(widget->codec, reg) >> rshift) & mask;
2447 if (invert) {
2448 ucontrol->value.integer.value[0] = 2571 ucontrol->value.integer.value[0] =
2449 max - ucontrol->value.integer.value[0]; 2572 max - ucontrol->value.integer.value[0];
2450 if (shift != rshift)
2451 ucontrol->value.integer.value[1] =
2452 max - ucontrol->value.integer.value[1];
2453 }
2454 2573
2455 return 0; 2574 return 0;
2456} 2575}
@@ -2484,20 +2603,19 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2484 struct snd_soc_dapm_update update; 2603 struct snd_soc_dapm_update update;
2485 int wi; 2604 int wi;
2486 2605
2606 if (snd_soc_volsw_is_stereo(mc))
2607 dev_warn(widget->dapm->dev,
2608 "Control '%s' is stereo, which is not supported\n",
2609 kcontrol->id.name);
2610
2487 val = (ucontrol->value.integer.value[0] & mask); 2611 val = (ucontrol->value.integer.value[0] & mask);
2612 connect = !!val;
2488 2613
2489 if (invert) 2614 if (invert)
2490 val = max - val; 2615 val = max - val;
2491 mask = mask << shift; 2616 mask = mask << shift;
2492 val = val << shift; 2617 val = val << shift;
2493 2618
2494 if (val)
2495 /* new connection */
2496 connect = invert ? 0 : 1;
2497 else
2498 /* old connection must be powered down */
2499 connect = invert ? 1 : 0;
2500
2501 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2619 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2502 2620
2503 change = snd_soc_test_bits(widget->codec, reg, mask, val); 2621 change = snd_soc_test_bits(widget->codec, reg, mask, val);
@@ -2873,6 +2991,19 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2873 return NULL; 2991 return NULL;
2874 } 2992 }
2875 break; 2993 break;
2994 case snd_soc_dapm_clock_supply:
2995#ifdef CONFIG_CLKDEV_LOOKUP
2996 w->clk = devm_clk_get(dapm->dev, w->name);
2997 if (IS_ERR(w->clk)) {
2998 ret = PTR_ERR(w->clk);
2999 dev_err(dapm->dev, "Failed to request %s: %d\n",
3000 w->name, ret);
3001 return NULL;
3002 }
3003#else
3004 return NULL;
3005#endif
3006 break;
2876 default: 3007 default:
2877 break; 3008 break;
2878 } 3009 }
@@ -2924,6 +3055,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2924 break; 3055 break;
2925 case snd_soc_dapm_supply: 3056 case snd_soc_dapm_supply:
2926 case snd_soc_dapm_regulator_supply: 3057 case snd_soc_dapm_regulator_supply:
3058 case snd_soc_dapm_clock_supply:
2927 w->power_check = dapm_supply_check_power; 3059 w->power_check = dapm_supply_check_power;
2928 break; 3060 break;
2929 case snd_soc_dapm_dai: 3061 case snd_soc_dapm_dai:
@@ -3538,10 +3670,13 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
3538 3670
3539static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm) 3671static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
3540{ 3672{
3673 struct snd_soc_card *card = dapm->card;
3541 struct snd_soc_dapm_widget *w; 3674 struct snd_soc_dapm_widget *w;
3542 LIST_HEAD(down_list); 3675 LIST_HEAD(down_list);
3543 int powerdown = 0; 3676 int powerdown = 0;
3544 3677
3678 mutex_lock(&card->dapm_mutex);
3679
3545 list_for_each_entry(w, &dapm->card->widgets, list) { 3680 list_for_each_entry(w, &dapm->card->widgets, list) {
3546 if (w->dapm != dapm) 3681 if (w->dapm != dapm)
3547 continue; 3682 continue;
@@ -3564,6 +3699,8 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
3564 snd_soc_dapm_set_bias_level(dapm, 3699 snd_soc_dapm_set_bias_level(dapm,
3565 SND_SOC_BIAS_STANDBY); 3700 SND_SOC_BIAS_STANDBY);
3566 } 3701 }
3702
3703 mutex_unlock(&card->dapm_mutex);
3567} 3704}
3568 3705
3569/* 3706/*
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c
index 475695234b3d..5df529eda251 100644
--- a/sound/soc/soc-dmaengine-pcm.c
+++ b/sound/soc/soc-dmaengine-pcm.c
@@ -30,6 +30,7 @@
30 30
31struct dmaengine_pcm_runtime_data { 31struct dmaengine_pcm_runtime_data {
32 struct dma_chan *dma_chan; 32 struct dma_chan *dma_chan;
33 dma_cookie_t cookie;
33 34
34 unsigned int pos; 35 unsigned int pos;
35 36
@@ -153,7 +154,7 @@ static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
153 154
154 desc->callback = dmaengine_pcm_dma_complete; 155 desc->callback = dmaengine_pcm_dma_complete;
155 desc->callback_param = substream; 156 desc->callback_param = substream;
156 dmaengine_submit(desc); 157 prtd->cookie = dmaengine_submit(desc);
157 158
158 return 0; 159 return 0;
159} 160}
@@ -200,6 +201,20 @@ int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
200EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger); 201EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger);
201 202
202/** 203/**
204 * snd_dmaengine_pcm_pointer_no_residue - dmaengine based PCM pointer implementation
205 * @substream: PCM substream
206 *
207 * This function is deprecated and should not be used by new drivers, as its
208 * results may be unreliable.
209 */
210snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream)
211{
212 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
213 return bytes_to_frames(substream->runtime, prtd->pos);
214}
215EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer_no_residue);
216
217/**
203 * snd_dmaengine_pcm_pointer - dmaengine based PCM pointer implementation 218 * snd_dmaengine_pcm_pointer - dmaengine based PCM pointer implementation
204 * @substream: PCM substream 219 * @substream: PCM substream
205 * 220 *
@@ -209,7 +224,19 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger);
209snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream) 224snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream)
210{ 225{
211 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); 226 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
212 return bytes_to_frames(substream->runtime, prtd->pos); 227 struct dma_tx_state state;
228 enum dma_status status;
229 unsigned int buf_size;
230 unsigned int pos = 0;
231
232 status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state);
233 if (status == DMA_IN_PROGRESS || status == DMA_PAUSED) {
234 buf_size = snd_pcm_lib_buffer_bytes(substream);
235 if (state.residue > 0 && state.residue <= buf_size)
236 pos = buf_size - state.residue;
237 }
238
239 return bytes_to_frames(substream->runtime, pos);
213} 240}
214EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer); 241EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer);
215 242
@@ -243,7 +270,7 @@ static int dmaengine_pcm_request_channel(struct dmaengine_pcm_runtime_data *prtd
243 * Note that this function will use private_data field of the substream's 270 * Note that this function will use private_data field of the substream's
244 * runtime. So it is not availabe to your pcm driver implementation. If you need 271 * runtime. So it is not availabe to your pcm driver implementation. If you need
245 * to keep additional data attached to a substream use 272 * to keep additional data attached to a substream use
246 * snd_dmaeinge_pcm_{set,get}_data. 273 * snd_dmaengine_pcm_{set,get}_data.
247 */ 274 */
248int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, 275int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
249 dma_filter_fn filter_fn, void *filter_data) 276 dma_filter_fn filter_fn, void *filter_data)
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index 4d8dc6a27d4d..29183ef2b93d 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -142,11 +142,16 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
142 case SND_SOC_REGMAP: 142 case SND_SOC_REGMAP:
143 /* Device has made its own regmap arrangements */ 143 /* Device has made its own regmap arrangements */
144 codec->using_regmap = true; 144 codec->using_regmap = true;
145 145 if (!codec->control_data)
146 ret = regmap_get_val_bytes(codec->control_data); 146 codec->control_data = dev_get_regmap(codec->dev, NULL);
147 /* Errors are legitimate for non-integer byte multiples */ 147
148 if (ret > 0) 148 if (codec->control_data) {
149 codec->val_bytes = ret; 149 ret = regmap_get_val_bytes(codec->control_data);
150 /* Errors are legitimate for non-integer byte
151 * multiples */
152 if (ret > 0)
153 codec->val_bytes = ret;
154 }
150 break; 155 break;
151 156
152 default: 157 default:
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 7f8b3b7428bb..0c172938b82a 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -103,7 +103,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
103 } 103 }
104 104
105 /* Report before the DAPM sync to help users updating micbias status */ 105 /* Report before the DAPM sync to help users updating micbias status */
106 blocking_notifier_call_chain(&jack->notifier, status, jack); 106 blocking_notifier_call_chain(&jack->notifier, jack->status, jack);
107 107
108 snd_soc_dapm_sync(dapm); 108 snd_soc_dapm_sync(dapm);
109 109
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 48fd15b312c1..ef22d0bd9e9e 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1955,10 +1955,8 @@ static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream)
1955 fe->dpcm[stream].runtime = fe_substream->runtime; 1955 fe->dpcm[stream].runtime = fe_substream->runtime;
1956 1956
1957 if (dpcm_path_get(fe, stream, &list) <= 0) { 1957 if (dpcm_path_get(fe, stream, &list) <= 0) {
1958 dev_warn(fe->dev, "asoc: %s no valid %s route\n", 1958 dev_dbg(fe->dev, "asoc: %s no valid %s route\n",
1959 fe->dai_link->name, stream ? "capture" : "playback"); 1959 fe->dai_link->name, stream ? "capture" : "playback");
1960 mutex_unlock(&fe->card->mutex);
1961 return -EINVAL;
1962 } 1960 }
1963 1961
1964 /* calculate valid and active FE <-> BE dpcms */ 1962 /* calculate valid and active FE <-> BE dpcms */
@@ -2003,7 +2001,6 @@ static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream)
2003/* create a new pcm */ 2001/* create a new pcm */
2004int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) 2002int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2005{ 2003{
2006 struct snd_soc_codec *codec = rtd->codec;
2007 struct snd_soc_platform *platform = rtd->platform; 2004 struct snd_soc_platform *platform = rtd->platform;
2008 struct snd_soc_dai *codec_dai = rtd->codec_dai; 2005 struct snd_soc_dai *codec_dai = rtd->codec_dai;
2009 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 2006 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
@@ -2042,7 +2039,8 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2042 capture, &pcm); 2039 capture, &pcm);
2043 } 2040 }
2044 if (ret < 0) { 2041 if (ret < 0) {
2045 printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name); 2042 dev_err(rtd->card->dev, "can't create pcm for %s\n",
2043 rtd->dai_link->name);
2046 return ret; 2044 return ret;
2047 } 2045 }
2048 dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num, new_name); 2046 dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num, new_name);
@@ -2099,14 +2097,14 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2099 if (platform->driver->pcm_new) { 2097 if (platform->driver->pcm_new) {
2100 ret = platform->driver->pcm_new(rtd); 2098 ret = platform->driver->pcm_new(rtd);
2101 if (ret < 0) { 2099 if (ret < 0) {
2102 pr_err("asoc: platform pcm constructor failed\n"); 2100 dev_err(platform->dev, "pcm constructor failed\n");
2103 return ret; 2101 return ret;
2104 } 2102 }
2105 } 2103 }
2106 2104
2107 pcm->private_free = platform->driver->pcm_free; 2105 pcm->private_free = platform->driver->pcm_free;
2108out: 2106out:
2109 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name, 2107 dev_info(rtd->card->dev, " %s <-> %s mapping ok\n", codec_dai->name,
2110 cpu_dai->name); 2108 cpu_dai->name);
2111 return ret; 2109 return ret;
2112} 2110}
diff --git a/sound/soc/spear/spdif_in.c b/sound/soc/spear/spdif_in.c
new file mode 100644
index 000000000000..c7c4b20395bb
--- /dev/null
+++ b/sound/soc/spear/spdif_in.c
@@ -0,0 +1,297 @@
1/*
2 * ALSA SoC SPDIF In Audio Layer for spear processors
3 *
4 * Copyright (C) 2012 ST Microelectronics
5 * Vipin Kumar <vipin.kumar@st.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/io.h>
18#include <linux/ioport.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24#include <sound/spear_dma.h>
25#include <sound/spear_spdif.h>
26#include "spdif_in_regs.h"
27
28struct spdif_in_params {
29 u32 format;
30};
31
32struct spdif_in_dev {
33 struct clk *clk;
34 struct spear_dma_data dma_params;
35 struct spdif_in_params saved_params;
36 void *io_base;
37 struct device *dev;
38 void (*reset_perip)(void);
39 int irq;
40};
41
42static void spdif_in_configure(struct spdif_in_dev *host)
43{
44 u32 ctrl = SPDIF_IN_PRTYEN | SPDIF_IN_STATEN | SPDIF_IN_USREN |
45 SPDIF_IN_VALEN | SPDIF_IN_BLKEN;
46 ctrl |= SPDIF_MODE_16BIT | SPDIF_FIFO_THRES_16;
47
48 writel(ctrl, host->io_base + SPDIF_IN_CTRL);
49 writel(0xF, host->io_base + SPDIF_IN_IRQ_MASK);
50}
51
52static int spdif_in_startup(struct snd_pcm_substream *substream,
53 struct snd_soc_dai *cpu_dai)
54{
55 struct spdif_in_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
56
57 if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
58 return -EINVAL;
59
60 snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&host->dma_params);
61 return 0;
62}
63
64static void spdif_in_shutdown(struct snd_pcm_substream *substream,
65 struct snd_soc_dai *dai)
66{
67 struct spdif_in_dev *host = snd_soc_dai_get_drvdata(dai);
68
69 if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
70 return;
71
72 writel(0x0, host->io_base + SPDIF_IN_IRQ_MASK);
73 snd_soc_dai_set_dma_data(dai, substream, NULL);
74}
75
76static void spdif_in_format(struct spdif_in_dev *host, u32 format)
77{
78 u32 ctrl = readl(host->io_base + SPDIF_IN_CTRL);
79
80 switch (format) {
81 case SNDRV_PCM_FORMAT_S16_LE:
82 ctrl |= SPDIF_XTRACT_16BIT;
83 break;
84
85 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
86 ctrl &= ~SPDIF_XTRACT_16BIT;
87 break;
88 }
89
90 writel(ctrl, host->io_base + SPDIF_IN_CTRL);
91}
92
93static int spdif_in_hw_params(struct snd_pcm_substream *substream,
94 struct snd_pcm_hw_params *params,
95 struct snd_soc_dai *dai)
96{
97 struct spdif_in_dev *host = snd_soc_dai_get_drvdata(dai);
98 u32 format;
99
100 if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
101 return -EINVAL;
102
103 format = params_format(params);
104 host->saved_params.format = format;
105
106 return 0;
107}
108
109static int spdif_in_trigger(struct snd_pcm_substream *substream, int cmd,
110 struct snd_soc_dai *dai)
111{
112 struct spdif_in_dev *host = snd_soc_dai_get_drvdata(dai);
113 u32 ctrl;
114 int ret = 0;
115
116 if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
117 return -EINVAL;
118
119 switch (cmd) {
120 case SNDRV_PCM_TRIGGER_START:
121 case SNDRV_PCM_TRIGGER_RESUME:
122 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
123 clk_enable(host->clk);
124 spdif_in_configure(host);
125 spdif_in_format(host, host->saved_params.format);
126
127 ctrl = readl(host->io_base + SPDIF_IN_CTRL);
128 ctrl |= SPDIF_IN_SAMPLE | SPDIF_IN_ENB;
129 writel(ctrl, host->io_base + SPDIF_IN_CTRL);
130 writel(0xF, host->io_base + SPDIF_IN_IRQ_MASK);
131 break;
132
133 case SNDRV_PCM_TRIGGER_STOP:
134 case SNDRV_PCM_TRIGGER_SUSPEND:
135 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
136 ctrl = readl(host->io_base + SPDIF_IN_CTRL);
137 ctrl &= ~(SPDIF_IN_SAMPLE | SPDIF_IN_ENB);
138 writel(ctrl, host->io_base + SPDIF_IN_CTRL);
139 writel(0x0, host->io_base + SPDIF_IN_IRQ_MASK);
140
141 if (host->reset_perip)
142 host->reset_perip();
143 clk_disable(host->clk);
144 break;
145
146 default:
147 ret = -EINVAL;
148 break;
149 }
150 return ret;
151}
152
153static struct snd_soc_dai_ops spdif_in_dai_ops = {
154 .startup = spdif_in_startup,
155 .shutdown = spdif_in_shutdown,
156 .trigger = spdif_in_trigger,
157 .hw_params = spdif_in_hw_params,
158};
159
160struct snd_soc_dai_driver spdif_in_dai = {
161 .capture = {
162 .channels_min = 2,
163 .channels_max = 2,
164 .rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
165 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | \
166 SNDRV_PCM_RATE_192000),
167 .formats = SNDRV_PCM_FMTBIT_S16_LE | \
168 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
169 },
170 .ops = &spdif_in_dai_ops,
171};
172
173static irqreturn_t spdif_in_irq(int irq, void *arg)
174{
175 struct spdif_in_dev *host = (struct spdif_in_dev *)arg;
176
177 u32 irq_status = readl(host->io_base + SPDIF_IN_IRQ);
178
179 if (!irq_status)
180 return IRQ_NONE;
181
182 if (irq_status & SPDIF_IRQ_FIFOWRITE)
183 dev_err(host->dev, "spdif in: fifo write error");
184 if (irq_status & SPDIF_IRQ_EMPTYFIFOREAD)
185 dev_err(host->dev, "spdif in: empty fifo read error");
186 if (irq_status & SPDIF_IRQ_FIFOFULL)
187 dev_err(host->dev, "spdif in: fifo full error");
188 if (irq_status & SPDIF_IRQ_OUTOFRANGE)
189 dev_err(host->dev, "spdif in: out of range error");
190
191 writel(0, host->io_base + SPDIF_IN_IRQ);
192
193 return IRQ_HANDLED;
194}
195
196static int spdif_in_probe(struct platform_device *pdev)
197{
198 struct spdif_in_dev *host;
199 struct spear_spdif_platform_data *pdata;
200 struct resource *res, *res_fifo;
201 int ret;
202
203 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
204 if (!res)
205 return -EINVAL;
206
207 res_fifo = platform_get_resource(pdev, IORESOURCE_IO, 0);
208 if (!res_fifo)
209 return -EINVAL;
210
211 if (!devm_request_mem_region(&pdev->dev, res->start,
212 resource_size(res), pdev->name)) {
213 dev_warn(&pdev->dev, "Failed to get memory resourse\n");
214 return -ENOENT;
215 }
216
217 host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
218 if (!host) {
219 dev_warn(&pdev->dev, "kzalloc fail\n");
220 return -ENOMEM;
221 }
222
223 host->io_base = devm_ioremap(&pdev->dev, res->start,
224 resource_size(res));
225 if (!host->io_base) {
226 dev_warn(&pdev->dev, "ioremap failed\n");
227 return -ENOMEM;
228 }
229
230 host->irq = platform_get_irq(pdev, 0);
231 if (host->irq < 0)
232 return -EINVAL;
233
234 host->clk = clk_get(&pdev->dev, NULL);
235 if (IS_ERR(host->clk))
236 return PTR_ERR(host->clk);
237
238 pdata = dev_get_platdata(&pdev->dev);
239
240 if (!pdata)
241 return -EINVAL;
242
243 host->dma_params.data = pdata->dma_params;
244 host->dma_params.addr = res_fifo->start;
245 host->dma_params.max_burst = 16;
246 host->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
247 host->dma_params.filter = pdata->filter;
248 host->reset_perip = pdata->reset_perip;
249
250 host->dev = &pdev->dev;
251 dev_set_drvdata(&pdev->dev, host);
252
253 ret = devm_request_irq(&pdev->dev, host->irq, spdif_in_irq, 0,
254 "spdif-in", host);
255 if (ret) {
256 clk_put(host->clk);
257 dev_warn(&pdev->dev, "request_irq failed\n");
258 return ret;
259 }
260
261 ret = snd_soc_register_dai(&pdev->dev, &spdif_in_dai);
262 if (ret != 0) {
263 clk_put(host->clk);
264 return ret;
265 }
266
267 return 0;
268}
269
270static int spdif_in_remove(struct platform_device *pdev)
271{
272 struct spdif_in_dev *host = dev_get_drvdata(&pdev->dev);
273
274 snd_soc_unregister_dai(&pdev->dev);
275 dev_set_drvdata(&pdev->dev, NULL);
276
277 clk_put(host->clk);
278
279 return 0;
280}
281
282
283static struct platform_driver spdif_in_driver = {
284 .probe = spdif_in_probe,
285 .remove = spdif_in_remove,
286 .driver = {
287 .name = "spdif-in",
288 .owner = THIS_MODULE,
289 },
290};
291
292module_platform_driver(spdif_in_driver);
293
294MODULE_AUTHOR("Vipin Kumar <vipin.kumar@st.com>");
295MODULE_DESCRIPTION("SPEAr SPDIF IN SoC Interface");
296MODULE_LICENSE("GPL");
297MODULE_ALIAS("platform:spdif_in");
diff --git a/sound/soc/spear/spdif_in_regs.h b/sound/soc/spear/spdif_in_regs.h
new file mode 100644
index 000000000000..37af7bc66b7f
--- /dev/null
+++ b/sound/soc/spear/spdif_in_regs.h
@@ -0,0 +1,60 @@
1/*
2 * SPEAr SPDIF IN controller header file
3 *
4 * Copyright (ST) 2011 Vipin Kumar (vipin.kumar@st.com)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef SPDIF_IN_REGS_H
22#define SPDIF_IN_REGS_H
23
24#define SPDIF_IN_CTRL 0x00
25 #define SPDIF_IN_PRTYEN (1 << 20)
26 #define SPDIF_IN_STATEN (1 << 19)
27 #define SPDIF_IN_USREN (1 << 18)
28 #define SPDIF_IN_VALEN (1 << 17)
29 #define SPDIF_IN_BLKEN (1 << 16)
30
31 #define SPDIF_MODE_24BIT (8 << 12)
32 #define SPDIF_MODE_23BIT (7 << 12)
33 #define SPDIF_MODE_22BIT (6 << 12)
34 #define SPDIF_MODE_21BIT (5 << 12)
35 #define SPDIF_MODE_20BIT (4 << 12)
36 #define SPDIF_MODE_19BIT (3 << 12)
37 #define SPDIF_MODE_18BIT (2 << 12)
38 #define SPDIF_MODE_17BIT (1 << 12)
39 #define SPDIF_MODE_16BIT (0 << 12)
40 #define SPDIF_MODE_MASK (0x0F << 12)
41
42 #define SPDIF_IN_VALID (1 << 11)
43 #define SPDIF_IN_SAMPLE (1 << 10)
44 #define SPDIF_DATA_SWAP (1 << 9)
45 #define SPDIF_IN_ENB (1 << 8)
46 #define SPDIF_DATA_REVERT (1 << 7)
47 #define SPDIF_XTRACT_16BIT (1 << 6)
48 #define SPDIF_FIFO_THRES_16 (16 << 0)
49
50#define SPDIF_IN_IRQ_MASK 0x04
51#define SPDIF_IN_IRQ 0x08
52 #define SPDIF_IRQ_FIFOWRITE (1 << 0)
53 #define SPDIF_IRQ_EMPTYFIFOREAD (1 << 1)
54 #define SPDIF_IRQ_FIFOFULL (1 << 2)
55 #define SPDIF_IRQ_OUTOFRANGE (1 << 3)
56
57#define SPDIF_IN_STA 0x0C
58 #define SPDIF_IN_LOCK (0x1 << 0)
59
60#endif /* SPDIF_IN_REGS_H */
diff --git a/sound/soc/spear/spdif_out.c b/sound/soc/spear/spdif_out.c
new file mode 100644
index 000000000000..5eac4cda2fd7
--- /dev/null
+++ b/sound/soc/spear/spdif_out.c
@@ -0,0 +1,389 @@
1/*
2 * ALSA SoC SPDIF Out Audio Layer for spear processors
3 *
4 * Copyright (C) 2012 ST Microelectronics
5 * Vipin Kumar <vipin.kumar@st.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/io.h>
18#include <linux/ioport.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <sound/soc.h>
22#include <sound/spear_dma.h>
23#include <sound/spear_spdif.h>
24#include "spdif_out_regs.h"
25
26struct spdif_out_params {
27 u32 rate;
28 u32 core_freq;
29 u32 mute;
30};
31
32struct spdif_out_dev {
33 struct clk *clk;
34 struct spear_dma_data dma_params;
35 struct spdif_out_params saved_params;
36 u32 running;
37 void __iomem *io_base;
38};
39
40static void spdif_out_configure(struct spdif_out_dev *host)
41{
42 writel(SPDIF_OUT_RESET, host->io_base + SPDIF_OUT_SOFT_RST);
43 mdelay(1);
44 writel(readl(host->io_base + SPDIF_OUT_SOFT_RST) & ~SPDIF_OUT_RESET,
45 host->io_base + SPDIF_OUT_SOFT_RST);
46
47 writel(SPDIF_OUT_FDMA_TRIG_16 | SPDIF_OUT_MEMFMT_16_16 |
48 SPDIF_OUT_VALID_HW | SPDIF_OUT_USER_HW |
49 SPDIF_OUT_CHNLSTA_HW | SPDIF_OUT_PARITY_HW,
50 host->io_base + SPDIF_OUT_CFG);
51
52 writel(0x7F, host->io_base + SPDIF_OUT_INT_STA_CLR);
53 writel(0x7F, host->io_base + SPDIF_OUT_INT_EN_CLR);
54}
55
56static int spdif_out_startup(struct snd_pcm_substream *substream,
57 struct snd_soc_dai *cpu_dai)
58{
59 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
60 int ret;
61
62 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
63 return -EINVAL;
64
65 snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&host->dma_params);
66
67 ret = clk_enable(host->clk);
68 if (ret)
69 return ret;
70
71 host->running = true;
72 spdif_out_configure(host);
73
74 return 0;
75}
76
77static void spdif_out_shutdown(struct snd_pcm_substream *substream,
78 struct snd_soc_dai *dai)
79{
80 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(dai);
81
82 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
83 return;
84
85 clk_disable(host->clk);
86 host->running = false;
87 snd_soc_dai_set_dma_data(dai, substream, NULL);
88}
89
90static void spdif_out_clock(struct spdif_out_dev *host, u32 core_freq,
91 u32 rate)
92{
93 u32 divider, ctrl;
94
95 clk_set_rate(host->clk, core_freq);
96 divider = DIV_ROUND_CLOSEST(clk_get_rate(host->clk), (rate * 128));
97
98 ctrl = readl(host->io_base + SPDIF_OUT_CTRL);
99 ctrl &= ~SPDIF_DIVIDER_MASK;
100 ctrl |= (divider << SPDIF_DIVIDER_SHIFT) & SPDIF_DIVIDER_MASK;
101 writel(ctrl, host->io_base + SPDIF_OUT_CTRL);
102}
103
104static int spdif_out_hw_params(struct snd_pcm_substream *substream,
105 struct snd_pcm_hw_params *params,
106 struct snd_soc_dai *dai)
107{
108 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(dai);
109 u32 rate, core_freq;
110
111 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
112 return -EINVAL;
113
114 rate = params_rate(params);
115
116 switch (rate) {
117 case 8000:
118 case 16000:
119 case 32000:
120 case 64000:
121 /*
122 * The clock is multiplied by 10 to bring it to feasible range
123 * of frequencies for sscg
124 */
125 core_freq = 64000 * 128 * 10; /* 81.92 MHz */
126 break;
127 case 5512:
128 case 11025:
129 case 22050:
130 case 44100:
131 case 88200:
132 case 176400:
133 core_freq = 176400 * 128; /* 22.5792 MHz */
134 break;
135 case 48000:
136 case 96000:
137 case 192000:
138 default:
139 core_freq = 192000 * 128; /* 24.576 MHz */
140 break;
141 }
142
143 spdif_out_clock(host, core_freq, rate);
144 host->saved_params.core_freq = core_freq;
145 host->saved_params.rate = rate;
146
147 return 0;
148}
149
150static int spdif_out_trigger(struct snd_pcm_substream *substream, int cmd,
151 struct snd_soc_dai *dai)
152{
153 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(dai);
154 u32 ctrl;
155 int ret = 0;
156
157 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
158 return -EINVAL;
159
160 switch (cmd) {
161 case SNDRV_PCM_TRIGGER_START:
162 case SNDRV_PCM_TRIGGER_RESUME:
163 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
164 ctrl = readl(host->io_base + SPDIF_OUT_CTRL);
165 ctrl &= ~SPDIF_OPMODE_MASK;
166 if (!host->saved_params.mute)
167 ctrl |= SPDIF_OPMODE_AUD_DATA |
168 SPDIF_STATE_NORMAL;
169 else
170 ctrl |= SPDIF_OPMODE_MUTE_PCM;
171 writel(ctrl, host->io_base + SPDIF_OUT_CTRL);
172 break;
173
174 case SNDRV_PCM_TRIGGER_STOP:
175 case SNDRV_PCM_TRIGGER_SUSPEND:
176 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
177 ctrl = readl(host->io_base + SPDIF_OUT_CTRL);
178 ctrl &= ~SPDIF_OPMODE_MASK;
179 ctrl |= SPDIF_OPMODE_OFF;
180 writel(ctrl, host->io_base + SPDIF_OUT_CTRL);
181 break;
182
183 default:
184 ret = -EINVAL;
185 break;
186 }
187 return ret;
188}
189
190static int spdif_digital_mute(struct snd_soc_dai *dai, int mute)
191{
192 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(dai);
193 u32 val;
194
195 host->saved_params.mute = mute;
196 val = readl(host->io_base + SPDIF_OUT_CTRL);
197 val &= ~SPDIF_OPMODE_MASK;
198
199 if (mute)
200 val |= SPDIF_OPMODE_MUTE_PCM;
201 else {
202 if (host->running)
203 val |= SPDIF_OPMODE_AUD_DATA | SPDIF_STATE_NORMAL;
204 else
205 val |= SPDIF_OPMODE_OFF;
206 }
207
208 writel(val, host->io_base + SPDIF_OUT_CTRL);
209 return 0;
210}
211
212static int spdif_mute_get(struct snd_kcontrol *kcontrol,
213 struct snd_ctl_elem_value *ucontrol)
214{
215 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
216 struct snd_soc_card *card = codec->card;
217 struct snd_soc_pcm_runtime *rtd = card->rtd;
218 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
219 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
220
221 ucontrol->value.integer.value[0] = host->saved_params.mute;
222 return 0;
223}
224
225static int spdif_mute_put(struct snd_kcontrol *kcontrol,
226 struct snd_ctl_elem_value *ucontrol)
227{
228 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
229 struct snd_soc_card *card = codec->card;
230 struct snd_soc_pcm_runtime *rtd = card->rtd;
231 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
232 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
233
234 if (host->saved_params.mute == ucontrol->value.integer.value[0])
235 return 0;
236
237 spdif_digital_mute(cpu_dai, ucontrol->value.integer.value[0]);
238
239 return 1;
240}
241static const struct snd_kcontrol_new spdif_out_controls[] = {
242 SOC_SINGLE_BOOL_EXT("IEC958 Playback Switch", 0,
243 spdif_mute_get, spdif_mute_put),
244};
245
246int spdif_soc_dai_probe(struct snd_soc_dai *dai)
247{
248 return snd_soc_add_dai_controls(dai, spdif_out_controls,
249 ARRAY_SIZE(spdif_out_controls));
250}
251
252static const struct snd_soc_dai_ops spdif_out_dai_ops = {
253 .digital_mute = spdif_digital_mute,
254 .startup = spdif_out_startup,
255 .shutdown = spdif_out_shutdown,
256 .trigger = spdif_out_trigger,
257 .hw_params = spdif_out_hw_params,
258};
259
260static struct snd_soc_dai_driver spdif_out_dai = {
261 .playback = {
262 .channels_min = 2,
263 .channels_max = 2,
264 .rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
265 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | \
266 SNDRV_PCM_RATE_192000),
267 .formats = SNDRV_PCM_FMTBIT_S16_LE,
268 },
269 .probe = spdif_soc_dai_probe,
270 .ops = &spdif_out_dai_ops,
271};
272
273static int spdif_out_probe(struct platform_device *pdev)
274{
275 struct spdif_out_dev *host;
276 struct spear_spdif_platform_data *pdata;
277 struct resource *res;
278 int ret;
279
280 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
281 if (!res)
282 return -EINVAL;
283
284 if (!devm_request_mem_region(&pdev->dev, res->start,
285 resource_size(res), pdev->name)) {
286 dev_warn(&pdev->dev, "Failed to get memory resourse\n");
287 return -ENOENT;
288 }
289
290 host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
291 if (!host) {
292 dev_warn(&pdev->dev, "kzalloc fail\n");
293 return -ENOMEM;
294 }
295
296 host->io_base = devm_ioremap(&pdev->dev, res->start,
297 resource_size(res));
298 if (!host->io_base) {
299 dev_warn(&pdev->dev, "ioremap failed\n");
300 return -ENOMEM;
301 }
302
303 host->clk = clk_get(&pdev->dev, NULL);
304 if (IS_ERR(host->clk))
305 return PTR_ERR(host->clk);
306
307 pdata = dev_get_platdata(&pdev->dev);
308
309 host->dma_params.data = pdata->dma_params;
310 host->dma_params.addr = res->start + SPDIF_OUT_FIFO_DATA;
311 host->dma_params.max_burst = 16;
312 host->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
313 host->dma_params.filter = pdata->filter;
314
315 dev_set_drvdata(&pdev->dev, host);
316
317 ret = snd_soc_register_dai(&pdev->dev, &spdif_out_dai);
318 if (ret != 0) {
319 clk_put(host->clk);
320 return ret;
321 }
322
323 return 0;
324}
325
326static int spdif_out_remove(struct platform_device *pdev)
327{
328 struct spdif_out_dev *host = dev_get_drvdata(&pdev->dev);
329
330 snd_soc_unregister_dai(&pdev->dev);
331 dev_set_drvdata(&pdev->dev, NULL);
332
333 clk_put(host->clk);
334
335 return 0;
336}
337
338#ifdef CONFIG_PM
339static int spdif_out_suspend(struct device *dev)
340{
341 struct platform_device *pdev = to_platform_device(dev);
342 struct spdif_out_dev *host = dev_get_drvdata(&pdev->dev);
343
344 if (host->running)
345 clk_disable(host->clk);
346
347 return 0;
348}
349
350static int spdif_out_resume(struct device *dev)
351{
352 struct platform_device *pdev = to_platform_device(dev);
353 struct spdif_out_dev *host = dev_get_drvdata(&pdev->dev);
354
355 if (host->running) {
356 clk_enable(host->clk);
357 spdif_out_configure(host);
358 spdif_out_clock(host, host->saved_params.core_freq,
359 host->saved_params.rate);
360 }
361 return 0;
362}
363
364static SIMPLE_DEV_PM_OPS(spdif_out_dev_pm_ops, spdif_out_suspend, \
365 spdif_out_resume);
366
367#define SPDIF_OUT_DEV_PM_OPS (&spdif_out_dev_pm_ops)
368
369#else
370#define SPDIF_OUT_DEV_PM_OPS NULL
371
372#endif
373
374static struct platform_driver spdif_out_driver = {
375 .probe = spdif_out_probe,
376 .remove = spdif_out_remove,
377 .driver = {
378 .name = "spdif-out",
379 .owner = THIS_MODULE,
380 .pm = SPDIF_OUT_DEV_PM_OPS,
381 },
382};
383
384module_platform_driver(spdif_out_driver);
385
386MODULE_AUTHOR("Vipin Kumar <vipin.kumar@st.com>");
387MODULE_DESCRIPTION("SPEAr SPDIF OUT SoC Interface");
388MODULE_LICENSE("GPL");
389MODULE_ALIAS("platform:spdif_out");
diff --git a/sound/soc/spear/spdif_out_regs.h b/sound/soc/spear/spdif_out_regs.h
new file mode 100644
index 000000000000..a5e53324b452
--- /dev/null
+++ b/sound/soc/spear/spdif_out_regs.h
@@ -0,0 +1,79 @@
1/*
2 * SPEAr SPDIF OUT controller header file
3 *
4 * Copyright (ST) 2011 Vipin Kumar (vipin.kumar@st.com)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef SPDIF_OUT_REGS_H
22#define SPDIF_OUT_REGS_H
23
24#define SPDIF_OUT_SOFT_RST 0x00
25 #define SPDIF_OUT_RESET (1 << 0)
26#define SPDIF_OUT_FIFO_DATA 0x04
27#define SPDIF_OUT_INT_STA 0x08
28#define SPDIF_OUT_INT_STA_CLR 0x0C
29 #define SPDIF_INT_UNDERFLOW (1 << 0)
30 #define SPDIF_INT_EODATA (1 << 1)
31 #define SPDIF_INT_EOBLOCK (1 << 2)
32 #define SPDIF_INT_EOLATENCY (1 << 3)
33 #define SPDIF_INT_EOPD_DATA (1 << 4)
34 #define SPDIF_INT_MEMFULLREAD (1 << 5)
35 #define SPDIF_INT_EOPD_PAUSE (1 << 6)
36
37#define SPDIF_OUT_INT_EN 0x10
38#define SPDIF_OUT_INT_EN_SET 0x14
39#define SPDIF_OUT_INT_EN_CLR 0x18
40#define SPDIF_OUT_CTRL 0x1C
41 #define SPDIF_OPMODE_MASK (7 << 0)
42 #define SPDIF_OPMODE_OFF (0 << 0)
43 #define SPDIF_OPMODE_MUTE_PCM (1 << 0)
44 #define SPDIF_OPMODE_MUTE_PAUSE (2 << 0)
45 #define SPDIF_OPMODE_AUD_DATA (3 << 0)
46 #define SPDIF_OPMODE_ENCODE (4 << 0)
47 #define SPDIF_STATE_NORMAL (1 << 3)
48 #define SPDIF_DIVIDER_MASK (0xff << 5)
49 #define SPDIF_DIVIDER_SHIFT (5)
50 #define SPDIF_SAMPLEREAD_MASK (0x1ffff << 15)
51 #define SPDIF_SAMPLEREAD_SHIFT (15)
52#define SPDIF_OUT_STA 0x20
53#define SPDIF_OUT_PA_PB 0x24
54#define SPDIF_OUT_PC_PD 0x28
55#define SPDIF_OUT_CL1 0x2C
56#define SPDIF_OUT_CR1 0x30
57#define SPDIF_OUT_CL2_CR2_UV 0x34
58#define SPDIF_OUT_PAUSE_LAT 0x38
59#define SPDIF_OUT_FRMLEN_BRST 0x3C
60#define SPDIF_OUT_CFG 0x40
61 #define SPDIF_OUT_MEMFMT_16_0 (0 << 5)
62 #define SPDIF_OUT_MEMFMT_16_16 (1 << 5)
63 #define SPDIF_OUT_VALID_DMA (0 << 3)
64 #define SPDIF_OUT_VALID_HW (1 << 3)
65 #define SPDIF_OUT_USER_DMA (0 << 2)
66 #define SPDIF_OUT_USER_HW (1 << 2)
67 #define SPDIF_OUT_CHNLSTA_DMA (0 << 1)
68 #define SPDIF_OUT_CHNLSTA_HW (1 << 1)
69 #define SPDIF_OUT_PARITY_HW (0 << 0)
70 #define SPDIF_OUT_PARITY_DMA (1 << 0)
71 #define SPDIF_OUT_FDMA_TRIG_2 (2 << 8)
72 #define SPDIF_OUT_FDMA_TRIG_6 (6 << 8)
73 #define SPDIF_OUT_FDMA_TRIG_8 (8 << 8)
74 #define SPDIF_OUT_FDMA_TRIG_10 (10 << 8)
75 #define SPDIF_OUT_FDMA_TRIG_12 (12 << 8)
76 #define SPDIF_OUT_FDMA_TRIG_16 (16 << 8)
77 #define SPDIF_OUT_FDMA_TRIG_18 (18 << 8)
78
79#endif /* SPDIF_OUT_REGS_H */
diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c
new file mode 100644
index 000000000000..8c7f23729446
--- /dev/null
+++ b/sound/soc/spear/spear_pcm.c
@@ -0,0 +1,214 @@
1/*
2 * ALSA PCM interface for ST SPEAr Processors
3 *
4 * sound/soc/spear/spear_pcm.c
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Rajeev Kumar<rajeev-dlh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include <linux/module.h>
15#include <linux/dmaengine.h>
16#include <linux/dma-mapping.h>
17#include <linux/init.h>
18#include <linux/platform_device.h>
19#include <linux/scatterlist.h>
20#include <linux/slab.h>
21#include <sound/core.h>
22#include <sound/dmaengine_pcm.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/spear_dma.h>
27
28struct snd_pcm_hardware spear_pcm_hardware = {
29 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
30 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
31 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
32 .buffer_bytes_max = 16 * 1024, /* max buffer size */
33 .period_bytes_min = 2 * 1024, /* 1 msec data minimum period size */
34 .period_bytes_max = 2 * 1024, /* maximum period size */
35 .periods_min = 1, /* min # periods */
36 .periods_max = 8, /* max # of periods */
37 .fifo_size = 0, /* fifo size in bytes */
38};
39
40static int spear_pcm_hw_params(struct snd_pcm_substream *substream,
41 struct snd_pcm_hw_params *params)
42{
43 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
44
45 return 0;
46}
47
48static int spear_pcm_hw_free(struct snd_pcm_substream *substream)
49{
50 snd_pcm_set_runtime_buffer(substream, NULL);
51
52 return 0;
53}
54
55static int spear_pcm_open(struct snd_pcm_substream *substream)
56{
57 struct snd_soc_pcm_runtime *rtd = substream->private_data;
58
59 struct spear_dma_data *dma_data = (struct spear_dma_data *)
60 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
61 int ret;
62
63 ret = snd_soc_set_runtime_hwparams(substream, &spear_pcm_hardware);
64 if (ret)
65 return ret;
66
67 ret = snd_dmaengine_pcm_open(substream, dma_data->filter, dma_data);
68 if (ret)
69 return ret;
70
71 snd_dmaengine_pcm_set_data(substream, dma_data);
72
73 return 0;
74}
75
76static int spear_pcm_close(struct snd_pcm_substream *substream)
77{
78
79 snd_dmaengine_pcm_close(substream);
80
81 return 0;
82}
83
84static int spear_pcm_mmap(struct snd_pcm_substream *substream,
85 struct vm_area_struct *vma)
86{
87 struct snd_pcm_runtime *runtime = substream->runtime;
88
89 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
90 runtime->dma_area, runtime->dma_addr,
91 runtime->dma_bytes);
92}
93
94static struct snd_pcm_ops spear_pcm_ops = {
95 .open = spear_pcm_open,
96 .close = spear_pcm_close,
97 .ioctl = snd_pcm_lib_ioctl,
98 .hw_params = spear_pcm_hw_params,
99 .hw_free = spear_pcm_hw_free,
100 .trigger = snd_dmaengine_pcm_trigger,
101 .pointer = snd_dmaengine_pcm_pointer,
102 .mmap = spear_pcm_mmap,
103};
104
105static int
106spear_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream,
107 size_t size)
108{
109 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
110 struct snd_dma_buffer *buf = &substream->dma_buffer;
111
112 buf->dev.type = SNDRV_DMA_TYPE_DEV;
113 buf->dev.dev = pcm->card->dev;
114 buf->private_data = NULL;
115
116 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
117 &buf->addr, GFP_KERNEL);
118 if (!buf->area)
119 return -ENOMEM;
120
121 dev_info(buf->dev.dev,
122 " preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
123 (void *)buf->area, (void *)buf->addr, size);
124
125 buf->bytes = size;
126 return 0;
127}
128
129static void spear_pcm_free(struct snd_pcm *pcm)
130{
131 struct snd_pcm_substream *substream;
132 struct snd_dma_buffer *buf;
133 int stream;
134
135 for (stream = 0; stream < 2; stream++) {
136 substream = pcm->streams[stream].substream;
137 if (!substream)
138 continue;
139
140 buf = &substream->dma_buffer;
141 if (!buf || !buf->area)
142 continue;
143
144 dma_free_writecombine(pcm->card->dev, buf->bytes,
145 buf->area, buf->addr);
146 buf->area = NULL;
147 }
148}
149
150static u64 spear_pcm_dmamask = DMA_BIT_MASK(32);
151
152static int spear_pcm_new(struct snd_card *card,
153 struct snd_soc_dai *dai, struct snd_pcm *pcm)
154{
155 int ret;
156
157 if (!card->dev->dma_mask)
158 card->dev->dma_mask = &spear_pcm_dmamask;
159 if (!card->dev->coherent_dma_mask)
160 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
161
162 if (dai->driver->playback.channels_min) {
163 ret = spear_pcm_preallocate_dma_buffer(pcm,
164 SNDRV_PCM_STREAM_PLAYBACK,
165 spear_pcm_hardware.buffer_bytes_max);
166 if (ret)
167 return ret;
168 }
169
170 if (dai->driver->capture.channels_min) {
171 ret = spear_pcm_preallocate_dma_buffer(pcm,
172 SNDRV_PCM_STREAM_CAPTURE,
173 spear_pcm_hardware.buffer_bytes_max);
174 if (ret)
175 return ret;
176 }
177
178 return 0;
179}
180
181struct snd_soc_platform_driver spear_soc_platform = {
182 .ops = &spear_pcm_ops,
183 .pcm_new = spear_pcm_new,
184 .pcm_free = spear_pcm_free,
185};
186
187static int __devinit spear_soc_platform_probe(struct platform_device *pdev)
188{
189 return snd_soc_register_platform(&pdev->dev, &spear_soc_platform);
190}
191
192static int __devexit spear_soc_platform_remove(struct platform_device *pdev)
193{
194 snd_soc_unregister_platform(&pdev->dev);
195
196 return 0;
197}
198
199static struct platform_driver spear_pcm_driver = {
200 .driver = {
201 .name = "spear-pcm-audio",
202 .owner = THIS_MODULE,
203 },
204
205 .probe = spear_soc_platform_probe,
206 .remove = __devexit_p(spear_soc_platform_remove),
207};
208
209module_platform_driver(spear_pcm_driver);
210
211MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>");
212MODULE_DESCRIPTION("SPEAr PCM DMA module");
213MODULE_LICENSE("GPL");
214MODULE_ALIAS("platform:spear-pcm-audio");
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index 76dc230f2bb0..19e5fe7cc403 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -1,7 +1,8 @@
1config SND_SOC_TEGRA 1config SND_SOC_TEGRA
2 tristate "SoC Audio for the Tegra System-on-Chip" 2 tristate "SoC Audio for the Tegra System-on-Chip"
3 depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA 3 depends on ARCH_TEGRA && TEGRA20_APB_DMA
4 select REGMAP_MMIO 4 select REGMAP_MMIO
5 select SND_SOC_DMAENGINE_PCM if TEGRA20_APB_DMA
5 help 6 help
6 Say Y or M here if you want support for SoC audio on Tegra. 7 Say Y or M here if you want support for SoC audio on Tegra.
7 8
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c
index 1647dbfe74b5..0832e8afd73c 100644
--- a/sound/soc/tegra/tegra20_i2s.c
+++ b/sound/soc/tegra/tegra20_i2s.c
@@ -46,18 +46,6 @@
46 46
47#define DRV_NAME "tegra20-i2s" 47#define DRV_NAME "tegra20-i2s"
48 48
49static inline void tegra20_i2s_write(struct tegra20_i2s *i2s, u32 reg, u32 val)
50{
51 regmap_write(i2s->regmap, reg, val);
52}
53
54static inline u32 tegra20_i2s_read(struct tegra20_i2s *i2s, u32 reg)
55{
56 u32 val;
57 regmap_read(i2s->regmap, reg, &val);
58 return val;
59}
60
61static int tegra20_i2s_runtime_suspend(struct device *dev) 49static int tegra20_i2s_runtime_suspend(struct device *dev)
62{ 50{
63 struct tegra20_i2s *i2s = dev_get_drvdata(dev); 51 struct tegra20_i2s *i2s = dev_get_drvdata(dev);
@@ -85,6 +73,7 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
85 unsigned int fmt) 73 unsigned int fmt)
86{ 74{
87 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); 75 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
76 unsigned int mask, val;
88 77
89 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 78 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
90 case SND_SOC_DAIFMT_NB_NF: 79 case SND_SOC_DAIFMT_NB_NF:
@@ -93,10 +82,10 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
93 return -EINVAL; 82 return -EINVAL;
94 } 83 }
95 84
96 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_MASTER_ENABLE; 85 mask = TEGRA20_I2S_CTRL_MASTER_ENABLE;
97 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 86 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
98 case SND_SOC_DAIFMT_CBS_CFS: 87 case SND_SOC_DAIFMT_CBS_CFS:
99 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_MASTER_ENABLE; 88 val = TEGRA20_I2S_CTRL_MASTER_ENABLE;
100 break; 89 break;
101 case SND_SOC_DAIFMT_CBM_CFM: 90 case SND_SOC_DAIFMT_CBM_CFM:
102 break; 91 break;
@@ -104,33 +93,35 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
104 return -EINVAL; 93 return -EINVAL;
105 } 94 }
106 95
107 i2s->reg_ctrl &= ~(TEGRA20_I2S_CTRL_BIT_FORMAT_MASK | 96 mask |= TEGRA20_I2S_CTRL_BIT_FORMAT_MASK |
108 TEGRA20_I2S_CTRL_LRCK_MASK); 97 TEGRA20_I2S_CTRL_LRCK_MASK;
109 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 98 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
110 case SND_SOC_DAIFMT_DSP_A: 99 case SND_SOC_DAIFMT_DSP_A:
111 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; 100 val |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP;
112 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; 101 val |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
113 break; 102 break;
114 case SND_SOC_DAIFMT_DSP_B: 103 case SND_SOC_DAIFMT_DSP_B:
115 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; 104 val |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP;
116 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_R_LOW; 105 val |= TEGRA20_I2S_CTRL_LRCK_R_LOW;
117 break; 106 break;
118 case SND_SOC_DAIFMT_I2S: 107 case SND_SOC_DAIFMT_I2S:
119 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S; 108 val |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S;
120 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; 109 val |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
121 break; 110 break;
122 case SND_SOC_DAIFMT_RIGHT_J: 111 case SND_SOC_DAIFMT_RIGHT_J:
123 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM; 112 val |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM;
124 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; 113 val |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
125 break; 114 break;
126 case SND_SOC_DAIFMT_LEFT_J: 115 case SND_SOC_DAIFMT_LEFT_J:
127 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM; 116 val |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM;
128 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; 117 val |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
129 break; 118 break;
130 default: 119 default:
131 return -EINVAL; 120 return -EINVAL;
132 } 121 }
133 122
123 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, mask, val);
124
134 return 0; 125 return 0;
135} 126}
136 127
@@ -138,29 +129,34 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream,
138 struct snd_pcm_hw_params *params, 129 struct snd_pcm_hw_params *params,
139 struct snd_soc_dai *dai) 130 struct snd_soc_dai *dai)
140{ 131{
141 struct device *dev = substream->pcm->card->dev; 132 struct device *dev = dai->dev;
142 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); 133 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
143 u32 reg; 134 unsigned int mask, val;
144 int ret, sample_size, srate, i2sclock, bitcnt; 135 int ret, sample_size, srate, i2sclock, bitcnt;
145 136
146 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_BIT_SIZE_MASK; 137 mask = TEGRA20_I2S_CTRL_BIT_SIZE_MASK;
147 switch (params_format(params)) { 138 switch (params_format(params)) {
148 case SNDRV_PCM_FORMAT_S16_LE: 139 case SNDRV_PCM_FORMAT_S16_LE:
149 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_16; 140 val = TEGRA20_I2S_CTRL_BIT_SIZE_16;
150 sample_size = 16; 141 sample_size = 16;
151 break; 142 break;
152 case SNDRV_PCM_FORMAT_S24_LE: 143 case SNDRV_PCM_FORMAT_S24_LE:
153 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_24; 144 val = TEGRA20_I2S_CTRL_BIT_SIZE_24;
154 sample_size = 24; 145 sample_size = 24;
155 break; 146 break;
156 case SNDRV_PCM_FORMAT_S32_LE: 147 case SNDRV_PCM_FORMAT_S32_LE:
157 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_32; 148 val = TEGRA20_I2S_CTRL_BIT_SIZE_32;
158 sample_size = 32; 149 sample_size = 32;
159 break; 150 break;
160 default: 151 default:
161 return -EINVAL; 152 return -EINVAL;
162 } 153 }
163 154
155 mask |= TEGRA20_I2S_CTRL_FIFO_FORMAT_MASK;
156 val |= TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED;
157
158 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, mask, val);
159
164 srate = params_rate(params); 160 srate = params_rate(params);
165 161
166 /* Final "* 2" required by Tegra hardware */ 162 /* Final "* 2" required by Tegra hardware */
@@ -175,42 +171,44 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream,
175 bitcnt = (i2sclock / (2 * srate)) - 1; 171 bitcnt = (i2sclock / (2 * srate)) - 1;
176 if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US) 172 if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US)
177 return -EINVAL; 173 return -EINVAL;
178 reg = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; 174 val = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT;
179 175
180 if (i2sclock % (2 * srate)) 176 if (i2sclock % (2 * srate))
181 reg |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE; 177 val |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE;
182 178
183 tegra20_i2s_write(i2s, TEGRA20_I2S_TIMING, reg); 179 regmap_write(i2s->regmap, TEGRA20_I2S_TIMING, val);
184 180
185 tegra20_i2s_write(i2s, TEGRA20_I2S_FIFO_SCR, 181 regmap_write(i2s->regmap, TEGRA20_I2S_FIFO_SCR,
186 TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | 182 TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS |
187 TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); 183 TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS);
188 184
189 return 0; 185 return 0;
190} 186}
191 187
192static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s) 188static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s)
193{ 189{
194 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO1_ENABLE; 190 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL,
195 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); 191 TEGRA20_I2S_CTRL_FIFO1_ENABLE,
192 TEGRA20_I2S_CTRL_FIFO1_ENABLE);
196} 193}
197 194
198static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s) 195static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s)
199{ 196{
200 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO1_ENABLE; 197 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL,
201 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); 198 TEGRA20_I2S_CTRL_FIFO1_ENABLE, 0);
202} 199}
203 200
204static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s) 201static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s)
205{ 202{
206 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO2_ENABLE; 203 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL,
207 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); 204 TEGRA20_I2S_CTRL_FIFO2_ENABLE,
205 TEGRA20_I2S_CTRL_FIFO2_ENABLE);
208} 206}
209 207
210static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s) 208static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s)
211{ 209{
212 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO2_ENABLE; 210 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL,
213 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); 211 TEGRA20_I2S_CTRL_FIFO2_ENABLE, 0);
214} 212}
215 213
216static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 214static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -261,12 +259,14 @@ static const struct snd_soc_dai_ops tegra20_i2s_dai_ops = {
261static const struct snd_soc_dai_driver tegra20_i2s_dai_template = { 259static const struct snd_soc_dai_driver tegra20_i2s_dai_template = {
262 .probe = tegra20_i2s_probe, 260 .probe = tegra20_i2s_probe,
263 .playback = { 261 .playback = {
262 .stream_name = "Playback",
264 .channels_min = 2, 263 .channels_min = 2,
265 .channels_max = 2, 264 .channels_max = 2,
266 .rates = SNDRV_PCM_RATE_8000_96000, 265 .rates = SNDRV_PCM_RATE_8000_96000,
267 .formats = SNDRV_PCM_FMTBIT_S16_LE, 266 .formats = SNDRV_PCM_FMTBIT_S16_LE,
268 }, 267 },
269 .capture = { 268 .capture = {
269 .stream_name = "Capture",
270 .channels_min = 2, 270 .channels_min = 2,
271 .channels_max = 2, 271 .channels_max = 2,
272 .rates = SNDRV_PCM_RATE_8000_96000, 272 .rates = SNDRV_PCM_RATE_8000_96000,
@@ -412,8 +412,6 @@ static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev)
412 i2s->playback_dma_data.width = 32; 412 i2s->playback_dma_data.width = 32;
413 i2s->playback_dma_data.req_sel = dma_ch; 413 i2s->playback_dma_data.req_sel = dma_ch;
414 414
415 i2s->reg_ctrl = TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED;
416
417 pm_runtime_enable(&pdev->dev); 415 pm_runtime_enable(&pdev->dev);
418 if (!pm_runtime_enabled(&pdev->dev)) { 416 if (!pm_runtime_enabled(&pdev->dev)) {
419 ret = tegra20_i2s_runtime_resume(&pdev->dev); 417 ret = tegra20_i2s_runtime_resume(&pdev->dev);
diff --git a/sound/soc/tegra/tegra20_i2s.h b/sound/soc/tegra/tegra20_i2s.h
index a57efc6a597e..c27069d24d77 100644
--- a/sound/soc/tegra/tegra20_i2s.h
+++ b/sound/soc/tegra/tegra20_i2s.h
@@ -158,7 +158,6 @@ struct tegra20_i2s {
158 struct tegra_pcm_dma_params capture_dma_data; 158 struct tegra_pcm_dma_params capture_dma_data;
159 struct tegra_pcm_dma_params playback_dma_data; 159 struct tegra_pcm_dma_params playback_dma_data;
160 struct regmap *regmap; 160 struct regmap *regmap;
161 u32 reg_ctrl;
162}; 161};
163 162
164#endif 163#endif
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c
index 2262e4fdec2a..3ebc8670ba00 100644
--- a/sound/soc/tegra/tegra20_spdif.c
+++ b/sound/soc/tegra/tegra20_spdif.c
@@ -37,19 +37,6 @@
37 37
38#define DRV_NAME "tegra20-spdif" 38#define DRV_NAME "tegra20-spdif"
39 39
40static inline void tegra20_spdif_write(struct tegra20_spdif *spdif, u32 reg,
41 u32 val)
42{
43 regmap_write(spdif->regmap, reg, val);
44}
45
46static inline u32 tegra20_spdif_read(struct tegra20_spdif *spdif, u32 reg)
47{
48 u32 val;
49 regmap_read(spdif->regmap, reg, &val);
50 return val;
51}
52
53static int tegra20_spdif_runtime_suspend(struct device *dev) 40static int tegra20_spdif_runtime_suspend(struct device *dev)
54{ 41{
55 struct tegra20_spdif *spdif = dev_get_drvdata(dev); 42 struct tegra20_spdif *spdif = dev_get_drvdata(dev);
@@ -77,21 +64,24 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream,
77 struct snd_pcm_hw_params *params, 64 struct snd_pcm_hw_params *params,
78 struct snd_soc_dai *dai) 65 struct snd_soc_dai *dai)
79{ 66{
80 struct device *dev = substream->pcm->card->dev; 67 struct device *dev = dai->dev;
81 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai); 68 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
69 unsigned int mask, val;
82 int ret, spdifclock; 70 int ret, spdifclock;
83 71
84 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_PACK; 72 mask = TEGRA20_SPDIF_CTRL_PACK |
85 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_BIT_MODE_MASK; 73 TEGRA20_SPDIF_CTRL_BIT_MODE_MASK;
86 switch (params_format(params)) { 74 switch (params_format(params)) {
87 case SNDRV_PCM_FORMAT_S16_LE: 75 case SNDRV_PCM_FORMAT_S16_LE:
88 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_PACK; 76 val = TEGRA20_SPDIF_CTRL_PACK |
89 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT; 77 TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT;
90 break; 78 break;
91 default: 79 default:
92 return -EINVAL; 80 return -EINVAL;
93 } 81 }
94 82
83 regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, mask, val);
84
95 switch (params_rate(params)) { 85 switch (params_rate(params)) {
96 case 32000: 86 case 32000:
97 spdifclock = 4096000; 87 spdifclock = 4096000;
@@ -129,14 +119,15 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream,
129 119
130static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif) 120static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif)
131{ 121{
132 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_TX_EN; 122 regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL,
133 tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl); 123 TEGRA20_SPDIF_CTRL_TX_EN,
124 TEGRA20_SPDIF_CTRL_TX_EN);
134} 125}
135 126
136static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif) 127static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif)
137{ 128{
138 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_TX_EN; 129 regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL,
139 tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl); 130 TEGRA20_SPDIF_CTRL_TX_EN, 0);
140} 131}
141 132
142static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd, 133static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -181,6 +172,7 @@ static struct snd_soc_dai_driver tegra20_spdif_dai = {
181 .name = DRV_NAME, 172 .name = DRV_NAME,
182 .probe = tegra20_spdif_probe, 173 .probe = tegra20_spdif_probe,
183 .playback = { 174 .playback = {
175 .stream_name = "Playback",
184 .channels_min = 2, 176 .channels_min = 2,
185 .channels_max = 2, 177 .channels_max = 2,
186 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | 178 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
diff --git a/sound/soc/tegra/tegra20_spdif.h b/sound/soc/tegra/tegra20_spdif.h
index ed756527efea..b48d699fd583 100644
--- a/sound/soc/tegra/tegra20_spdif.h
+++ b/sound/soc/tegra/tegra20_spdif.h
@@ -465,7 +465,6 @@ struct tegra20_spdif {
465 struct tegra_pcm_dma_params capture_dma_data; 465 struct tegra_pcm_dma_params capture_dma_data;
466 struct tegra_pcm_dma_params playback_dma_data; 466 struct tegra_pcm_dma_params playback_dma_data;
467 struct regmap *regmap; 467 struct regmap *regmap;
468 u32 reg_ctrl;
469}; 468};
470 469
471#endif 470#endif
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index d308faaae148..44184228d1f0 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -44,18 +44,6 @@
44 44
45#define DRV_NAME "tegra30-i2s" 45#define DRV_NAME "tegra30-i2s"
46 46
47static inline void tegra30_i2s_write(struct tegra30_i2s *i2s, u32 reg, u32 val)
48{
49 regmap_write(i2s->regmap, reg, val);
50}
51
52static inline u32 tegra30_i2s_read(struct tegra30_i2s *i2s, u32 reg)
53{
54 u32 val;
55 regmap_read(i2s->regmap, reg, &val);
56 return val;
57}
58
59static int tegra30_i2s_runtime_suspend(struct device *dev) 47static int tegra30_i2s_runtime_suspend(struct device *dev)
60{ 48{
61 struct tegra30_i2s *i2s = dev_get_drvdata(dev); 49 struct tegra30_i2s *i2s = dev_get_drvdata(dev);
@@ -128,6 +116,7 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
128 unsigned int fmt) 116 unsigned int fmt)
129{ 117{
130 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); 118 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
119 unsigned int mask, val;
131 120
132 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 121 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
133 case SND_SOC_DAIFMT_NB_NF: 122 case SND_SOC_DAIFMT_NB_NF:
@@ -136,10 +125,10 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
136 return -EINVAL; 125 return -EINVAL;
137 } 126 }
138 127
139 i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_MASTER_ENABLE; 128 mask = TEGRA30_I2S_CTRL_MASTER_ENABLE;
140 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 129 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
141 case SND_SOC_DAIFMT_CBS_CFS: 130 case SND_SOC_DAIFMT_CBS_CFS:
142 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_MASTER_ENABLE; 131 val = TEGRA30_I2S_CTRL_MASTER_ENABLE;
143 break; 132 break;
144 case SND_SOC_DAIFMT_CBM_CFM: 133 case SND_SOC_DAIFMT_CBM_CFM:
145 break; 134 break;
@@ -147,33 +136,37 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
147 return -EINVAL; 136 return -EINVAL;
148 } 137 }
149 138
150 i2s->reg_ctrl &= ~(TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK | 139 mask |= TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK |
151 TEGRA30_I2S_CTRL_LRCK_MASK); 140 TEGRA30_I2S_CTRL_LRCK_MASK;
152 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 141 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
153 case SND_SOC_DAIFMT_DSP_A: 142 case SND_SOC_DAIFMT_DSP_A:
154 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; 143 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC;
155 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; 144 val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
156 break; 145 break;
157 case SND_SOC_DAIFMT_DSP_B: 146 case SND_SOC_DAIFMT_DSP_B:
158 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; 147 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC;
159 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_R_LOW; 148 val |= TEGRA30_I2S_CTRL_LRCK_R_LOW;
160 break; 149 break;
161 case SND_SOC_DAIFMT_I2S: 150 case SND_SOC_DAIFMT_I2S:
162 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; 151 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
163 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; 152 val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
164 break; 153 break;
165 case SND_SOC_DAIFMT_RIGHT_J: 154 case SND_SOC_DAIFMT_RIGHT_J:
166 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; 155 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
167 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; 156 val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
168 break; 157 break;
169 case SND_SOC_DAIFMT_LEFT_J: 158 case SND_SOC_DAIFMT_LEFT_J:
170 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; 159 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
171 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; 160 val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
172 break; 161 break;
173 default: 162 default:
174 return -EINVAL; 163 return -EINVAL;
175 } 164 }
176 165
166 pm_runtime_get_sync(dai->dev);
167 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val);
168 pm_runtime_put(dai->dev);
169
177 return 0; 170 return 0;
178} 171}
179 172
@@ -181,24 +174,26 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
181 struct snd_pcm_hw_params *params, 174 struct snd_pcm_hw_params *params,
182 struct snd_soc_dai *dai) 175 struct snd_soc_dai *dai)
183{ 176{
184 struct device *dev = substream->pcm->card->dev; 177 struct device *dev = dai->dev;
185 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); 178 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
186 u32 val; 179 unsigned int mask, val, reg;
187 int ret, sample_size, srate, i2sclock, bitcnt; 180 int ret, sample_size, srate, i2sclock, bitcnt;
188 181
189 if (params_channels(params) != 2) 182 if (params_channels(params) != 2)
190 return -EINVAL; 183 return -EINVAL;
191 184
192 i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_BIT_SIZE_MASK; 185 mask = TEGRA30_I2S_CTRL_BIT_SIZE_MASK;
193 switch (params_format(params)) { 186 switch (params_format(params)) {
194 case SNDRV_PCM_FORMAT_S16_LE: 187 case SNDRV_PCM_FORMAT_S16_LE:
195 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_BIT_SIZE_16; 188 val = TEGRA30_I2S_CTRL_BIT_SIZE_16;
196 sample_size = 16; 189 sample_size = 16;
197 break; 190 break;
198 default: 191 default:
199 return -EINVAL; 192 return -EINVAL;
200 } 193 }
201 194
195 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val);
196
202 srate = params_rate(params); 197 srate = params_rate(params);
203 198
204 /* Final "* 2" required by Tegra hardware */ 199 /* Final "* 2" required by Tegra hardware */
@@ -219,7 +214,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
219 if (i2sclock % (2 * srate)) 214 if (i2sclock % (2 * srate))
220 val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE; 215 val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE;
221 216
222 tegra30_i2s_write(i2s, TEGRA30_I2S_TIMING, val); 217 regmap_write(i2s->regmap, TEGRA30_I2S_TIMING, val);
223 218
224 val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | 219 val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) |
225 (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) | 220 (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) |
@@ -229,15 +224,17 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
229 224
230 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 225 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
231 val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX; 226 val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX;
232 tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_RX_CTRL, val); 227 reg = TEGRA30_I2S_CIF_RX_CTRL;
233 } else { 228 } else {
234 val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX; 229 val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX;
235 tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_TX_CTRL, val); 230 reg = TEGRA30_I2S_CIF_RX_CTRL;
236 } 231 }
237 232
233 regmap_write(i2s->regmap, reg, val);
234
238 val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) | 235 val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) |
239 (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT); 236 (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT);
240 tegra30_i2s_write(i2s, TEGRA30_I2S_OFFSET, val); 237 regmap_write(i2s->regmap, TEGRA30_I2S_OFFSET, val);
241 238
242 return 0; 239 return 0;
243} 240}
@@ -245,29 +242,31 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
245static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s) 242static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s)
246{ 243{
247 tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif); 244 tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif);
248 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_TX; 245 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
249 tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); 246 TEGRA30_I2S_CTRL_XFER_EN_TX,
247 TEGRA30_I2S_CTRL_XFER_EN_TX);
250} 248}
251 249
252static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s) 250static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s)
253{ 251{
254 tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif); 252 tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif);
255 i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_TX; 253 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
256 tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); 254 TEGRA30_I2S_CTRL_XFER_EN_TX, 0);
257} 255}
258 256
259static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s) 257static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s)
260{ 258{
261 tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif); 259 tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif);
262 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_RX; 260 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
263 tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); 261 TEGRA30_I2S_CTRL_XFER_EN_RX,
262 TEGRA30_I2S_CTRL_XFER_EN_RX);
264} 263}
265 264
266static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s) 265static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s)
267{ 266{
268 tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif); 267 tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif);
269 i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_RX; 268 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
270 tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); 269 TEGRA30_I2S_CTRL_XFER_EN_RX, 0);
271} 270}
272 271
273static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 272static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -320,12 +319,14 @@ static struct snd_soc_dai_ops tegra30_i2s_dai_ops = {
320static const struct snd_soc_dai_driver tegra30_i2s_dai_template = { 319static const struct snd_soc_dai_driver tegra30_i2s_dai_template = {
321 .probe = tegra30_i2s_probe, 320 .probe = tegra30_i2s_probe,
322 .playback = { 321 .playback = {
322 .stream_name = "Playback",
323 .channels_min = 2, 323 .channels_min = 2,
324 .channels_max = 2, 324 .channels_max = 2,
325 .rates = SNDRV_PCM_RATE_8000_96000, 325 .rates = SNDRV_PCM_RATE_8000_96000,
326 .formats = SNDRV_PCM_FMTBIT_S16_LE, 326 .formats = SNDRV_PCM_FMTBIT_S16_LE,
327 }, 327 },
328 .capture = { 328 .capture = {
329 .stream_name = "Capture",
329 .channels_min = 2, 330 .channels_min = 2,
330 .channels_max = 2, 331 .channels_max = 2,
331 .rates = SNDRV_PCM_RATE_8000_96000, 332 .rates = SNDRV_PCM_RATE_8000_96000,
diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h
index 91adf29c7a87..34dc47b9581c 100644
--- a/sound/soc/tegra/tegra30_i2s.h
+++ b/sound/soc/tegra/tegra30_i2s.h
@@ -236,7 +236,6 @@ struct tegra30_i2s {
236 enum tegra30_ahub_txcif playback_fifo_cif; 236 enum tegra30_ahub_txcif playback_fifo_cif;
237 struct tegra_pcm_dma_params playback_dma_data; 237 struct tegra_pcm_dma_params playback_dma_data;
238 struct regmap *regmap; 238 struct regmap *regmap;
239 u32 reg_ctrl;
240}; 239};
241 240
242#endif 241#endif
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index 32de7006daf0..76cb1b363b71 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver 2* tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver
3 * 3 *
4 * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net> 4 * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
5 * Copyright (C) 2012 - NVIDIA, Inc. 5 * Copyright (C) 2012 - NVIDIA, Inc.
@@ -33,11 +33,8 @@
33 33
34#define DRV_NAME "tegra-alc5632" 34#define DRV_NAME "tegra-alc5632"
35 35
36#define GPIO_HP_DET BIT(0)
37
38struct tegra_alc5632 { 36struct tegra_alc5632 {
39 struct tegra_asoc_utils_data util_data; 37 struct tegra_asoc_utils_data util_data;
40 int gpio_requested;
41 int gpio_hp_det; 38 int gpio_hp_det;
42}; 39};
43 40
@@ -46,7 +43,7 @@ static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream,
46{ 43{
47 struct snd_soc_pcm_runtime *rtd = substream->private_data; 44 struct snd_soc_pcm_runtime *rtd = substream->private_data;
48 struct snd_soc_dai *codec_dai = rtd->codec_dai; 45 struct snd_soc_dai *codec_dai = rtd->codec_dai;
49 struct snd_soc_codec *codec = rtd->codec; 46 struct snd_soc_codec *codec = codec_dai->codec;
50 struct snd_soc_card *card = codec->card; 47 struct snd_soc_card *card = codec->card;
51 struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card); 48 struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card);
52 int srate, mclk; 49 int srate, mclk;
@@ -92,7 +89,6 @@ static struct snd_soc_jack_gpio tegra_alc5632_hp_jack_gpio = {
92 .name = "Headset detection", 89 .name = "Headset detection",
93 .report = SND_JACK_HEADSET, 90 .report = SND_JACK_HEADSET,
94 .debounce_time = 150, 91 .debounce_time = 150,
95 .invert = 1,
96}; 92};
97 93
98static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = { 94static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = {
@@ -108,9 +104,9 @@ static const struct snd_kcontrol_new tegra_alc5632_controls[] = {
108 104
109static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) 105static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
110{ 106{
111 struct snd_soc_codec *codec = rtd->codec; 107 struct snd_soc_dai *codec_dai = rtd->codec_dai;
108 struct snd_soc_codec *codec = codec_dai->codec;
112 struct snd_soc_dapm_context *dapm = &codec->dapm; 109 struct snd_soc_dapm_context *dapm = &codec->dapm;
113 struct device_node *np = codec->card->dev->of_node;
114 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card); 110 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card);
115 111
116 snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, 112 snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
@@ -119,14 +115,11 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
119 ARRAY_SIZE(tegra_alc5632_hs_jack_pins), 115 ARRAY_SIZE(tegra_alc5632_hs_jack_pins),
120 tegra_alc5632_hs_jack_pins); 116 tegra_alc5632_hs_jack_pins);
121 117
122 machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
123
124 if (gpio_is_valid(machine->gpio_hp_det)) { 118 if (gpio_is_valid(machine->gpio_hp_det)) {
125 tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det; 119 tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det;
126 snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack, 120 snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack,
127 1, 121 1,
128 &tegra_alc5632_hp_jack_gpio); 122 &tegra_alc5632_hp_jack_gpio);
129 machine->gpio_requested |= GPIO_HP_DET;
130 } 123 }
131 124
132 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); 125 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
@@ -159,6 +152,7 @@ static struct snd_soc_card snd_soc_tegra_alc5632 = {
159 152
160static __devinit int tegra_alc5632_probe(struct platform_device *pdev) 153static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
161{ 154{
155 struct device_node *np = pdev->dev.of_node;
162 struct snd_soc_card *card = &snd_soc_tegra_alc5632; 156 struct snd_soc_card *card = &snd_soc_tegra_alc5632;
163 struct tegra_alc5632 *alc5632; 157 struct tegra_alc5632 *alc5632;
164 int ret; 158 int ret;
@@ -181,6 +175,10 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
181 goto err; 175 goto err;
182 } 176 }
183 177
178 alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
179 if (alc5632->gpio_hp_det == -EPROBE_DEFER)
180 return -EPROBE_DEFER;
181
184 ret = snd_soc_of_parse_card_name(card, "nvidia,model"); 182 ret = snd_soc_of_parse_card_name(card, "nvidia,model");
185 if (ret) 183 if (ret)
186 goto err; 184 goto err;
@@ -199,16 +197,16 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
199 goto err; 197 goto err;
200 } 198 }
201 199
202 tegra_alc5632_dai.cpu_dai_of_node = of_parse_phandle( 200 tegra_alc5632_dai.cpu_of_node = of_parse_phandle(
203 pdev->dev.of_node, "nvidia,i2s-controller", 0); 201 pdev->dev.of_node, "nvidia,i2s-controller", 0);
204 if (!tegra_alc5632_dai.cpu_dai_of_node) { 202 if (!tegra_alc5632_dai.cpu_of_node) {
205 dev_err(&pdev->dev, 203 dev_err(&pdev->dev,
206 "Property 'nvidia,i2s-controller' missing or invalid\n"); 204 "Property 'nvidia,i2s-controller' missing or invalid\n");
207 ret = -EINVAL; 205 ret = -EINVAL;
208 goto err; 206 goto err;
209 } 207 }
210 208
211 tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_dai_of_node; 209 tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_of_node;
212 210
213 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); 211 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
214 if (ret) 212 if (ret)
@@ -234,11 +232,8 @@ static int __devexit tegra_alc5632_remove(struct platform_device *pdev)
234 struct snd_soc_card *card = platform_get_drvdata(pdev); 232 struct snd_soc_card *card = platform_get_drvdata(pdev);
235 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card); 233 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card);
236 234
237 if (machine->gpio_requested & GPIO_HP_DET) 235 snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack, 1,
238 snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack, 236 &tegra_alc5632_hp_jack_gpio);
239 1,
240 &tegra_alc5632_hp_jack_gpio);
241 machine->gpio_requested = 0;
242 237
243 snd_soc_unregister_card(card); 238 snd_soc_unregister_card(card);
244 239
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 127348dc09b1..e18733963cb4 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -36,6 +36,7 @@
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/dmaengine_pcm.h>
39 40
40#include "tegra_pcm.h" 41#include "tegra_pcm.h"
41 42
@@ -56,214 +57,96 @@ static const struct snd_pcm_hardware tegra_pcm_hardware = {
56 .fifo_size = 4, 57 .fifo_size = 4,
57}; 58};
58 59
59static void tegra_pcm_queue_dma(struct tegra_runtime_data *prtd)
60{
61 struct snd_pcm_substream *substream = prtd->substream;
62 struct snd_dma_buffer *buf = &substream->dma_buffer;
63 struct tegra_dma_req *dma_req;
64 unsigned long addr;
65
66 dma_req = &prtd->dma_req[prtd->dma_req_idx];
67 prtd->dma_req_idx = 1 - prtd->dma_req_idx;
68
69 addr = buf->addr + prtd->dma_pos;
70 prtd->dma_pos += dma_req->size;
71 if (prtd->dma_pos >= prtd->dma_pos_end)
72 prtd->dma_pos = 0;
73
74 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
75 dma_req->source_addr = addr;
76 else
77 dma_req->dest_addr = addr;
78
79 tegra_dma_enqueue_req(prtd->dma_chan, dma_req);
80}
81
82static void dma_complete_callback(struct tegra_dma_req *req)
83{
84 struct tegra_runtime_data *prtd = (struct tegra_runtime_data *)req->dev;
85 struct snd_pcm_substream *substream = prtd->substream;
86 struct snd_pcm_runtime *runtime = substream->runtime;
87
88 spin_lock(&prtd->lock);
89
90 if (!prtd->running) {
91 spin_unlock(&prtd->lock);
92 return;
93 }
94
95 if (++prtd->period_index >= runtime->periods)
96 prtd->period_index = 0;
97
98 tegra_pcm_queue_dma(prtd);
99
100 spin_unlock(&prtd->lock);
101
102 snd_pcm_period_elapsed(substream);
103}
104
105static void setup_dma_tx_request(struct tegra_dma_req *req,
106 struct tegra_pcm_dma_params * dmap)
107{
108 req->complete = dma_complete_callback;
109 req->to_memory = false;
110 req->dest_addr = dmap->addr;
111 req->dest_wrap = dmap->wrap;
112 req->source_bus_width = 32;
113 req->source_wrap = 0;
114 req->dest_bus_width = dmap->width;
115 req->req_sel = dmap->req_sel;
116}
117
118static void setup_dma_rx_request(struct tegra_dma_req *req,
119 struct tegra_pcm_dma_params * dmap)
120{
121 req->complete = dma_complete_callback;
122 req->to_memory = true;
123 req->source_addr = dmap->addr;
124 req->dest_wrap = 0;
125 req->source_bus_width = dmap->width;
126 req->source_wrap = dmap->wrap;
127 req->dest_bus_width = 32;
128 req->req_sel = dmap->req_sel;
129}
130
131static int tegra_pcm_open(struct snd_pcm_substream *substream) 60static int tegra_pcm_open(struct snd_pcm_substream *substream)
132{ 61{
133 struct snd_pcm_runtime *runtime = substream->runtime;
134 struct tegra_runtime_data *prtd;
135 struct snd_soc_pcm_runtime *rtd = substream->private_data; 62 struct snd_soc_pcm_runtime *rtd = substream->private_data;
136 struct tegra_pcm_dma_params * dmap; 63 struct device *dev = rtd->platform->dev;
137 int ret = 0; 64 int ret;
138
139 prtd = kzalloc(sizeof(struct tegra_runtime_data), GFP_KERNEL);
140 if (prtd == NULL)
141 return -ENOMEM;
142
143 runtime->private_data = prtd;
144 prtd->substream = substream;
145
146 spin_lock_init(&prtd->lock);
147
148 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
149 dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
150 setup_dma_tx_request(&prtd->dma_req[0], dmap);
151 setup_dma_tx_request(&prtd->dma_req[1], dmap);
152 } else {
153 dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
154 setup_dma_rx_request(&prtd->dma_req[0], dmap);
155 setup_dma_rx_request(&prtd->dma_req[1], dmap);
156 }
157
158 prtd->dma_req[0].dev = prtd;
159 prtd->dma_req[1].dev = prtd;
160
161 prtd->dma_chan = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT);
162 if (prtd->dma_chan == NULL) {
163 ret = -ENOMEM;
164 goto err;
165 }
166 65
167 /* Set HW params now that initialization is complete */ 66 /* Set HW params now that initialization is complete */
168 snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware); 67 snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware);
169 68
170 /* Ensure that buffer size is a multiple of period size */ 69 ret = snd_dmaengine_pcm_open(substream, NULL, NULL);
171 ret = snd_pcm_hw_constraint_integer(runtime, 70 if (ret) {
172 SNDRV_PCM_HW_PARAM_PERIODS); 71 dev_err(dev, "dmaengine pcm open failed with err %d\n", ret);
173 if (ret < 0) 72 return ret;
174 goto err;
175
176 return 0;
177
178err:
179 if (prtd->dma_chan) {
180 tegra_dma_free_channel(prtd->dma_chan);
181 } 73 }
182 74
183 kfree(prtd); 75 return 0;
184
185 return ret;
186} 76}
187 77
188static int tegra_pcm_close(struct snd_pcm_substream *substream) 78static int tegra_pcm_close(struct snd_pcm_substream *substream)
189{ 79{
190 struct snd_pcm_runtime *runtime = substream->runtime; 80 snd_dmaengine_pcm_close(substream);
191 struct tegra_runtime_data *prtd = runtime->private_data;
192
193 tegra_dma_free_channel(prtd->dma_chan);
194
195 kfree(prtd);
196
197 return 0; 81 return 0;
198} 82}
199 83
200static int tegra_pcm_hw_params(struct snd_pcm_substream *substream, 84static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
201 struct snd_pcm_hw_params *params) 85 struct snd_pcm_hw_params *params)
202{ 86{
203 struct snd_pcm_runtime *runtime = substream->runtime; 87 struct snd_soc_pcm_runtime *rtd = substream->private_data;
204 struct tegra_runtime_data *prtd = runtime->private_data; 88 struct device *dev = rtd->platform->dev;
89 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
90 struct tegra_pcm_dma_params *dmap;
91 struct dma_slave_config slave_config;
92 int ret;
93
94 dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
95
96 ret = snd_hwparams_to_dma_slave_config(substream, params,
97 &slave_config);
98 if (ret) {
99 dev_err(dev, "hw params config failed with err %d\n", ret);
100 return ret;
101 }
205 102
206 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 103 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
104 slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
105 slave_config.dst_addr = dmap->addr;
106 slave_config.dst_maxburst = 4;
107 } else {
108 slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
109 slave_config.src_addr = dmap->addr;
110 slave_config.src_maxburst = 4;
111 }
112 slave_config.slave_id = dmap->req_sel;
207 113
208 prtd->dma_req[0].size = params_period_bytes(params); 114 ret = dmaengine_slave_config(chan, &slave_config);
209 prtd->dma_req[1].size = prtd->dma_req[0].size; 115 if (ret < 0) {
116 dev_err(dev, "dma slave config failed with err %d\n", ret);
117 return ret;
118 }
210 119
120 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
211 return 0; 121 return 0;
212} 122}
213 123
214static int tegra_pcm_hw_free(struct snd_pcm_substream *substream) 124static int tegra_pcm_hw_free(struct snd_pcm_substream *substream)
215{ 125{
216 snd_pcm_set_runtime_buffer(substream, NULL); 126 snd_pcm_set_runtime_buffer(substream, NULL);
217
218 return 0; 127 return 0;
219} 128}
220 129
221static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 130static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
222{ 131{
223 struct snd_pcm_runtime *runtime = substream->runtime;
224 struct tegra_runtime_data *prtd = runtime->private_data;
225 unsigned long flags;
226
227 switch (cmd) { 132 switch (cmd) {
228 case SNDRV_PCM_TRIGGER_START: 133 case SNDRV_PCM_TRIGGER_START:
229 prtd->dma_pos = 0;
230 prtd->dma_pos_end = frames_to_bytes(runtime, runtime->periods * runtime->period_size);
231 prtd->period_index = 0;
232 prtd->dma_req_idx = 0;
233 /* Fall-through */
234 case SNDRV_PCM_TRIGGER_RESUME: 134 case SNDRV_PCM_TRIGGER_RESUME:
235 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 135 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
236 spin_lock_irqsave(&prtd->lock, flags); 136 return snd_dmaengine_pcm_trigger(substream,
237 prtd->running = 1; 137 SNDRV_PCM_TRIGGER_START);
238 spin_unlock_irqrestore(&prtd->lock, flags); 138
239 tegra_pcm_queue_dma(prtd);
240 tegra_pcm_queue_dma(prtd);
241 break;
242 case SNDRV_PCM_TRIGGER_STOP: 139 case SNDRV_PCM_TRIGGER_STOP:
243 case SNDRV_PCM_TRIGGER_SUSPEND: 140 case SNDRV_PCM_TRIGGER_SUSPEND:
244 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 141 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
245 spin_lock_irqsave(&prtd->lock, flags); 142 return snd_dmaengine_pcm_trigger(substream,
246 prtd->running = 0; 143 SNDRV_PCM_TRIGGER_STOP);
247 spin_unlock_irqrestore(&prtd->lock, flags);
248 tegra_dma_dequeue_req(prtd->dma_chan, &prtd->dma_req[0]);
249 tegra_dma_dequeue_req(prtd->dma_chan, &prtd->dma_req[1]);
250 break;
251 default: 144 default:
252 return -EINVAL; 145 return -EINVAL;
253 } 146 }
254
255 return 0; 147 return 0;
256} 148}
257 149
258static snd_pcm_uframes_t tegra_pcm_pointer(struct snd_pcm_substream *substream)
259{
260 struct snd_pcm_runtime *runtime = substream->runtime;
261 struct tegra_runtime_data *prtd = runtime->private_data;
262
263 return prtd->period_index * runtime->period_size;
264}
265
266
267static int tegra_pcm_mmap(struct snd_pcm_substream *substream, 150static int tegra_pcm_mmap(struct snd_pcm_substream *substream,
268 struct vm_area_struct *vma) 151 struct vm_area_struct *vma)
269{ 152{
@@ -282,7 +165,7 @@ static struct snd_pcm_ops tegra_pcm_ops = {
282 .hw_params = tegra_pcm_hw_params, 165 .hw_params = tegra_pcm_hw_params,
283 .hw_free = tegra_pcm_hw_free, 166 .hw_free = tegra_pcm_hw_free,
284 .trigger = tegra_pcm_trigger, 167 .trigger = tegra_pcm_trigger,
285 .pointer = tegra_pcm_pointer, 168 .pointer = snd_dmaengine_pcm_pointer,
286 .mmap = tegra_pcm_mmap, 169 .mmap = tegra_pcm_mmap,
287}; 170};
288 171
diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h
index 985d418a35e7..b40279b9f413 100644
--- a/sound/soc/tegra/tegra_pcm.h
+++ b/sound/soc/tegra/tegra_pcm.h
@@ -40,18 +40,6 @@ struct tegra_pcm_dma_params {
40 unsigned long req_sel; 40 unsigned long req_sel;
41}; 41};
42 42
43struct tegra_runtime_data {
44 struct snd_pcm_substream *substream;
45 spinlock_t lock;
46 int running;
47 int dma_pos;
48 int dma_pos_end;
49 int period_index;
50 int dma_req_idx;
51 struct tegra_dma_req dma_req[2];
52 struct tegra_dma_channel *dma_chan;
53};
54
55int tegra_pcm_platform_register(struct device *dev); 43int tegra_pcm_platform_register(struct device *dev);
56void tegra_pcm_platform_unregister(struct device *dev); 44void tegra_pcm_platform_unregister(struct device *dev);
57 45
diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c
index 4e77026807a2..ea9166d5c4eb 100644
--- a/sound/soc/tegra/tegra_wm8753.c
+++ b/sound/soc/tegra/tegra_wm8753.c
@@ -57,7 +57,7 @@ static int tegra_wm8753_hw_params(struct snd_pcm_substream *substream,
57{ 57{
58 struct snd_soc_pcm_runtime *rtd = substream->private_data; 58 struct snd_soc_pcm_runtime *rtd = substream->private_data;
59 struct snd_soc_dai *codec_dai = rtd->codec_dai; 59 struct snd_soc_dai *codec_dai = rtd->codec_dai;
60 struct snd_soc_codec *codec = rtd->codec; 60 struct snd_soc_codec *codec = codec_dai->codec;
61 struct snd_soc_card *card = codec->card; 61 struct snd_soc_card *card = codec->card;
62 struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); 62 struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card);
63 int srate, mclk; 63 int srate, mclk;
@@ -157,9 +157,9 @@ static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev)
157 goto err; 157 goto err;
158 } 158 }
159 159
160 tegra_wm8753_dai.cpu_dai_of_node = of_parse_phandle( 160 tegra_wm8753_dai.cpu_of_node = of_parse_phandle(
161 pdev->dev.of_node, "nvidia,i2s-controller", 0); 161 pdev->dev.of_node, "nvidia,i2s-controller", 0);
162 if (!tegra_wm8753_dai.cpu_dai_of_node) { 162 if (!tegra_wm8753_dai.cpu_of_node) {
163 dev_err(&pdev->dev, 163 dev_err(&pdev->dev,
164 "Property 'nvidia,i2s-controller' missing or invalid\n"); 164 "Property 'nvidia,i2s-controller' missing or invalid\n");
165 ret = -EINVAL; 165 ret = -EINVAL;
@@ -167,7 +167,7 @@ static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev)
167 } 167 }
168 168
169 tegra_wm8753_dai.platform_of_node = 169 tegra_wm8753_dai.platform_of_node =
170 tegra_wm8753_dai.cpu_dai_of_node; 170 tegra_wm8753_dai.cpu_of_node;
171 171
172 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); 172 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
173 if (ret) 173 if (ret)
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index 3b6da91188a9..d4f14e492341 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -28,8 +28,6 @@
28 * 28 *
29 */ 29 */
30 30
31#include <asm/mach-types.h>
32
33#include <linux/module.h> 31#include <linux/module.h>
34#include <linux/platform_device.h> 32#include <linux/platform_device.h>
35#include <linux/slab.h> 33#include <linux/slab.h>
@@ -50,16 +48,9 @@
50 48
51#define DRV_NAME "tegra-snd-wm8903" 49#define DRV_NAME "tegra-snd-wm8903"
52 50
53#define GPIO_SPKR_EN BIT(0)
54#define GPIO_HP_MUTE BIT(1)
55#define GPIO_INT_MIC_EN BIT(2)
56#define GPIO_EXT_MIC_EN BIT(3)
57#define GPIO_HP_DET BIT(4)
58
59struct tegra_wm8903 { 51struct tegra_wm8903 {
60 struct tegra_wm8903_platform_data pdata; 52 struct tegra_wm8903_platform_data pdata;
61 struct tegra_asoc_utils_data util_data; 53 struct tegra_asoc_utils_data util_data;
62 int gpio_requested;
63}; 54};
64 55
65static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream, 56static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream,
@@ -67,8 +58,7 @@ static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream,
67{ 58{
68 struct snd_soc_pcm_runtime *rtd = substream->private_data; 59 struct snd_soc_pcm_runtime *rtd = substream->private_data;
69 struct snd_soc_dai *codec_dai = rtd->codec_dai; 60 struct snd_soc_dai *codec_dai = rtd->codec_dai;
70 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 61 struct snd_soc_codec *codec = codec_dai->codec;
71 struct snd_soc_codec *codec = rtd->codec;
72 struct snd_soc_card *card = codec->card; 62 struct snd_soc_card *card = codec->card;
73 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 63 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
74 int srate, mclk; 64 int srate, mclk;
@@ -95,24 +85,6 @@ static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream,
95 return err; 85 return err;
96 } 86 }
97 87
98 err = snd_soc_dai_set_fmt(codec_dai,
99 SND_SOC_DAIFMT_I2S |
100 SND_SOC_DAIFMT_NB_NF |
101 SND_SOC_DAIFMT_CBS_CFS);
102 if (err < 0) {
103 dev_err(card->dev, "codec_dai fmt not set\n");
104 return err;
105 }
106
107 err = snd_soc_dai_set_fmt(cpu_dai,
108 SND_SOC_DAIFMT_I2S |
109 SND_SOC_DAIFMT_NB_NF |
110 SND_SOC_DAIFMT_CBS_CFS);
111 if (err < 0) {
112 dev_err(card->dev, "cpu_dai fmt not set\n");
113 return err;
114 }
115
116 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, 88 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
117 SND_SOC_CLOCK_IN); 89 SND_SOC_CLOCK_IN);
118 if (err < 0) { 90 if (err < 0) {
@@ -160,7 +132,7 @@ static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w,
160 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 132 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
161 struct tegra_wm8903_platform_data *pdata = &machine->pdata; 133 struct tegra_wm8903_platform_data *pdata = &machine->pdata;
162 134
163 if (!(machine->gpio_requested & GPIO_SPKR_EN)) 135 if (!gpio_is_valid(pdata->gpio_spkr_en))
164 return 0; 136 return 0;
165 137
166 gpio_set_value_cansleep(pdata->gpio_spkr_en, 138 gpio_set_value_cansleep(pdata->gpio_spkr_en,
@@ -177,7 +149,7 @@ static int tegra_wm8903_event_hp(struct snd_soc_dapm_widget *w,
177 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 149 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
178 struct tegra_wm8903_platform_data *pdata = &machine->pdata; 150 struct tegra_wm8903_platform_data *pdata = &machine->pdata;
179 151
180 if (!(machine->gpio_requested & GPIO_HP_MUTE)) 152 if (!gpio_is_valid(pdata->gpio_hp_mute))
181 return 0; 153 return 0;
182 154
183 gpio_set_value_cansleep(pdata->gpio_hp_mute, 155 gpio_set_value_cansleep(pdata->gpio_hp_mute,
@@ -203,122 +175,18 @@ static const struct snd_soc_dapm_route harmony_audio_map[] = {
203 {"IN1L", NULL, "Mic Jack"}, 175 {"IN1L", NULL, "Mic Jack"},
204}; 176};
205 177
206static const struct snd_soc_dapm_route seaboard_audio_map[] = {
207 {"Headphone Jack", NULL, "HPOUTR"},
208 {"Headphone Jack", NULL, "HPOUTL"},
209 {"Int Spk", NULL, "ROP"},
210 {"Int Spk", NULL, "RON"},
211 {"Int Spk", NULL, "LOP"},
212 {"Int Spk", NULL, "LON"},
213 {"Mic Jack", NULL, "MICBIAS"},
214 {"IN1R", NULL, "Mic Jack"},
215};
216
217static const struct snd_soc_dapm_route kaen_audio_map[] = {
218 {"Headphone Jack", NULL, "HPOUTR"},
219 {"Headphone Jack", NULL, "HPOUTL"},
220 {"Int Spk", NULL, "ROP"},
221 {"Int Spk", NULL, "RON"},
222 {"Int Spk", NULL, "LOP"},
223 {"Int Spk", NULL, "LON"},
224 {"Mic Jack", NULL, "MICBIAS"},
225 {"IN2R", NULL, "Mic Jack"},
226};
227
228static const struct snd_soc_dapm_route aebl_audio_map[] = {
229 {"Headphone Jack", NULL, "HPOUTR"},
230 {"Headphone Jack", NULL, "HPOUTL"},
231 {"Int Spk", NULL, "LINEOUTR"},
232 {"Int Spk", NULL, "LINEOUTL"},
233 {"Mic Jack", NULL, "MICBIAS"},
234 {"IN1R", NULL, "Mic Jack"},
235};
236
237static const struct snd_kcontrol_new tegra_wm8903_controls[] = { 178static const struct snd_kcontrol_new tegra_wm8903_controls[] = {
238 SOC_DAPM_PIN_SWITCH("Int Spk"), 179 SOC_DAPM_PIN_SWITCH("Int Spk"),
239}; 180};
240 181
241static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) 182static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
242{ 183{
243 struct snd_soc_codec *codec = rtd->codec; 184 struct snd_soc_dai *codec_dai = rtd->codec_dai;
185 struct snd_soc_codec *codec = codec_dai->codec;
244 struct snd_soc_dapm_context *dapm = &codec->dapm; 186 struct snd_soc_dapm_context *dapm = &codec->dapm;
245 struct snd_soc_card *card = codec->card; 187 struct snd_soc_card *card = codec->card;
246 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 188 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
247 struct tegra_wm8903_platform_data *pdata = &machine->pdata; 189 struct tegra_wm8903_platform_data *pdata = &machine->pdata;
248 struct device_node *np = card->dev->of_node;
249 int ret;
250
251 if (card->dev->platform_data) {
252 memcpy(pdata, card->dev->platform_data, sizeof(*pdata));
253 } else if (np) {
254 /*
255 * This part must be in init() rather than probe() in order to
256 * guarantee that the WM8903 has been probed, and hence its
257 * GPIO controller registered, which is a pre-condition for
258 * of_get_named_gpio() to be able to map the phandles in the
259 * properties to the controller node. Given this, all
260 * pdata handling is in init() for consistency.
261 */
262 pdata->gpio_spkr_en = of_get_named_gpio(np,
263 "nvidia,spkr-en-gpios", 0);
264 pdata->gpio_hp_mute = of_get_named_gpio(np,
265 "nvidia,hp-mute-gpios", 0);
266 pdata->gpio_hp_det = of_get_named_gpio(np,
267 "nvidia,hp-det-gpios", 0);
268 pdata->gpio_int_mic_en = of_get_named_gpio(np,
269 "nvidia,int-mic-en-gpios", 0);
270 pdata->gpio_ext_mic_en = of_get_named_gpio(np,
271 "nvidia,ext-mic-en-gpios", 0);
272 } else {
273 dev_err(card->dev, "No platform data supplied\n");
274 return -EINVAL;
275 }
276
277 if (gpio_is_valid(pdata->gpio_spkr_en)) {
278 ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
279 if (ret) {
280 dev_err(card->dev, "cannot get spkr_en gpio\n");
281 return ret;
282 }
283 machine->gpio_requested |= GPIO_SPKR_EN;
284
285 gpio_direction_output(pdata->gpio_spkr_en, 0);
286 }
287
288 if (gpio_is_valid(pdata->gpio_hp_mute)) {
289 ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
290 if (ret) {
291 dev_err(card->dev, "cannot get hp_mute gpio\n");
292 return ret;
293 }
294 machine->gpio_requested |= GPIO_HP_MUTE;
295
296 gpio_direction_output(pdata->gpio_hp_mute, 1);
297 }
298
299 if (gpio_is_valid(pdata->gpio_int_mic_en)) {
300 ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
301 if (ret) {
302 dev_err(card->dev, "cannot get int_mic_en gpio\n");
303 return ret;
304 }
305 machine->gpio_requested |= GPIO_INT_MIC_EN;
306
307 /* Disable int mic; enable signal is active-high */
308 gpio_direction_output(pdata->gpio_int_mic_en, 0);
309 }
310
311 if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
312 ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
313 if (ret) {
314 dev_err(card->dev, "cannot get ext_mic_en gpio\n");
315 return ret;
316 }
317 machine->gpio_requested |= GPIO_EXT_MIC_EN;
318
319 /* Enable ext mic; enable signal is active-low */
320 gpio_direction_output(pdata->gpio_ext_mic_en, 0);
321 }
322 190
323 if (gpio_is_valid(pdata->gpio_hp_det)) { 191 if (gpio_is_valid(pdata->gpio_hp_det)) {
324 tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det; 192 tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det;
@@ -330,7 +198,6 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
330 snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack, 198 snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack,
331 1, 199 1,
332 &tegra_wm8903_hp_jack_gpio); 200 &tegra_wm8903_hp_jack_gpio);
333 machine->gpio_requested |= GPIO_HP_DET;
334 } 201 }
335 202
336 snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, 203 snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
@@ -366,6 +233,9 @@ static struct snd_soc_dai_link tegra_wm8903_dai = {
366 .codec_dai_name = "wm8903-hifi", 233 .codec_dai_name = "wm8903-hifi",
367 .init = tegra_wm8903_init, 234 .init = tegra_wm8903_init,
368 .ops = &tegra_wm8903_ops, 235 .ops = &tegra_wm8903_ops,
236 .dai_fmt = SND_SOC_DAIFMT_I2S |
237 SND_SOC_DAIFMT_NB_NF |
238 SND_SOC_DAIFMT_CBS_CFS,
369}; 239};
370 240
371static struct snd_soc_card snd_soc_tegra_wm8903 = { 241static struct snd_soc_card snd_soc_tegra_wm8903 = {
@@ -385,8 +255,10 @@ static struct snd_soc_card snd_soc_tegra_wm8903 = {
385 255
386static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) 256static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
387{ 257{
258 struct device_node *np = pdev->dev.of_node;
388 struct snd_soc_card *card = &snd_soc_tegra_wm8903; 259 struct snd_soc_card *card = &snd_soc_tegra_wm8903;
389 struct tegra_wm8903 *machine; 260 struct tegra_wm8903 *machine;
261 struct tegra_wm8903_platform_data *pdata;
390 int ret; 262 int ret;
391 263
392 if (!pdev->dev.platform_data && !pdev->dev.of_node) { 264 if (!pdev->dev.platform_data && !pdev->dev.of_node) {
@@ -401,12 +273,42 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
401 ret = -ENOMEM; 273 ret = -ENOMEM;
402 goto err; 274 goto err;
403 } 275 }
276 pdata = &machine->pdata;
404 277
405 card->dev = &pdev->dev; 278 card->dev = &pdev->dev;
406 platform_set_drvdata(pdev, card); 279 platform_set_drvdata(pdev, card);
407 snd_soc_card_set_drvdata(card, machine); 280 snd_soc_card_set_drvdata(card, machine);
408 281
409 if (pdev->dev.of_node) { 282 if (pdev->dev.platform_data) {
283 memcpy(pdata, card->dev->platform_data, sizeof(*pdata));
284 } else if (np) {
285 pdata->gpio_spkr_en = of_get_named_gpio(np,
286 "nvidia,spkr-en-gpios", 0);
287 if (pdata->gpio_spkr_en == -EPROBE_DEFER)
288 return -EPROBE_DEFER;
289
290 pdata->gpio_hp_mute = of_get_named_gpio(np,
291 "nvidia,hp-mute-gpios", 0);
292 if (pdata->gpio_hp_mute == -EPROBE_DEFER)
293 return -EPROBE_DEFER;
294
295 pdata->gpio_hp_det = of_get_named_gpio(np,
296 "nvidia,hp-det-gpios", 0);
297 if (pdata->gpio_hp_det == -EPROBE_DEFER)
298 return -EPROBE_DEFER;
299
300 pdata->gpio_int_mic_en = of_get_named_gpio(np,
301 "nvidia,int-mic-en-gpios", 0);
302 if (pdata->gpio_int_mic_en == -EPROBE_DEFER)
303 return -EPROBE_DEFER;
304
305 pdata->gpio_ext_mic_en = of_get_named_gpio(np,
306 "nvidia,ext-mic-en-gpios", 0);
307 if (pdata->gpio_ext_mic_en == -EPROBE_DEFER)
308 return -EPROBE_DEFER;
309 }
310
311 if (np) {
410 ret = snd_soc_of_parse_card_name(card, "nvidia,model"); 312 ret = snd_soc_of_parse_card_name(card, "nvidia,model");
411 if (ret) 313 if (ret)
412 goto err; 314 goto err;
@@ -417,8 +319,8 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
417 goto err; 319 goto err;
418 320
419 tegra_wm8903_dai.codec_name = NULL; 321 tegra_wm8903_dai.codec_name = NULL;
420 tegra_wm8903_dai.codec_of_node = of_parse_phandle( 322 tegra_wm8903_dai.codec_of_node = of_parse_phandle(np,
421 pdev->dev.of_node, "nvidia,audio-codec", 0); 323 "nvidia,audio-codec", 0);
422 if (!tegra_wm8903_dai.codec_of_node) { 324 if (!tegra_wm8903_dai.codec_of_node) {
423 dev_err(&pdev->dev, 325 dev_err(&pdev->dev,
424 "Property 'nvidia,audio-codec' missing or invalid\n"); 326 "Property 'nvidia,audio-codec' missing or invalid\n");
@@ -427,9 +329,9 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
427 } 329 }
428 330
429 tegra_wm8903_dai.cpu_dai_name = NULL; 331 tegra_wm8903_dai.cpu_dai_name = NULL;
430 tegra_wm8903_dai.cpu_dai_of_node = of_parse_phandle( 332 tegra_wm8903_dai.cpu_of_node = of_parse_phandle(np,
431 pdev->dev.of_node, "nvidia,i2s-controller", 0); 333 "nvidia,i2s-controller", 0);
432 if (!tegra_wm8903_dai.cpu_dai_of_node) { 334 if (!tegra_wm8903_dai.cpu_of_node) {
433 dev_err(&pdev->dev, 335 dev_err(&pdev->dev,
434 "Property 'nvidia,i2s-controller' missing or invalid\n"); 336 "Property 'nvidia,i2s-controller' missing or invalid\n");
435 ret = -EINVAL; 337 ret = -EINVAL;
@@ -438,20 +340,47 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
438 340
439 tegra_wm8903_dai.platform_name = NULL; 341 tegra_wm8903_dai.platform_name = NULL;
440 tegra_wm8903_dai.platform_of_node = 342 tegra_wm8903_dai.platform_of_node =
441 tegra_wm8903_dai.cpu_dai_of_node; 343 tegra_wm8903_dai.cpu_of_node;
442 } else { 344 } else {
443 if (machine_is_harmony()) { 345 card->dapm_routes = harmony_audio_map;
444 card->dapm_routes = harmony_audio_map; 346 card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map);
445 card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map); 347 }
446 } else if (machine_is_seaboard()) { 348
447 card->dapm_routes = seaboard_audio_map; 349 if (gpio_is_valid(pdata->gpio_spkr_en)) {
448 card->num_dapm_routes = ARRAY_SIZE(seaboard_audio_map); 350 ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_spkr_en,
449 } else if (machine_is_kaen()) { 351 GPIOF_OUT_INIT_LOW, "spkr_en");
450 card->dapm_routes = kaen_audio_map; 352 if (ret) {
451 card->num_dapm_routes = ARRAY_SIZE(kaen_audio_map); 353 dev_err(card->dev, "cannot get spkr_en gpio\n");
452 } else { 354 return ret;
453 card->dapm_routes = aebl_audio_map; 355 }
454 card->num_dapm_routes = ARRAY_SIZE(aebl_audio_map); 356 }
357
358 if (gpio_is_valid(pdata->gpio_hp_mute)) {
359 ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_hp_mute,
360 GPIOF_OUT_INIT_HIGH, "hp_mute");
361 if (ret) {
362 dev_err(card->dev, "cannot get hp_mute gpio\n");
363 return ret;
364 }
365 }
366
367 if (gpio_is_valid(pdata->gpio_int_mic_en)) {
368 /* Disable int mic; enable signal is active-high */
369 ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_int_mic_en,
370 GPIOF_OUT_INIT_LOW, "int_mic_en");
371 if (ret) {
372 dev_err(card->dev, "cannot get int_mic_en gpio\n");
373 return ret;
374 }
375 }
376
377 if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
378 /* Enable ext mic; enable signal is active-low */
379 ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_ext_mic_en,
380 GPIOF_OUT_INIT_LOW, "ext_mic_en");
381 if (ret) {
382 dev_err(card->dev, "cannot get ext_mic_en gpio\n");
383 return ret;
455 } 384 }
456 } 385 }
457 386
@@ -478,21 +407,9 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev)
478{ 407{
479 struct snd_soc_card *card = platform_get_drvdata(pdev); 408 struct snd_soc_card *card = platform_get_drvdata(pdev);
480 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 409 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
481 struct tegra_wm8903_platform_data *pdata = &machine->pdata;
482 410
483 if (machine->gpio_requested & GPIO_HP_DET) 411 snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack, 1,
484 snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack, 412 &tegra_wm8903_hp_jack_gpio);
485 1,
486 &tegra_wm8903_hp_jack_gpio);
487 if (machine->gpio_requested & GPIO_EXT_MIC_EN)
488 gpio_free(pdata->gpio_ext_mic_en);
489 if (machine->gpio_requested & GPIO_INT_MIC_EN)
490 gpio_free(pdata->gpio_int_mic_en);
491 if (machine->gpio_requested & GPIO_HP_MUTE)
492 gpio_free(pdata->gpio_hp_mute);
493 if (machine->gpio_requested & GPIO_SPKR_EN)
494 gpio_free(pdata->gpio_spkr_en);
495 machine->gpio_requested = 0;
496 413
497 snd_soc_unregister_card(card); 414 snd_soc_unregister_card(card);
498 415
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
index 4a8d5b672c9f..e69a4f7000d6 100644
--- a/sound/soc/tegra/trimslice.c
+++ b/sound/soc/tegra/trimslice.c
@@ -52,8 +52,7 @@ static int trimslice_asoc_hw_params(struct snd_pcm_substream *substream,
52{ 52{
53 struct snd_soc_pcm_runtime *rtd = substream->private_data; 53 struct snd_soc_pcm_runtime *rtd = substream->private_data;
54 struct snd_soc_dai *codec_dai = rtd->codec_dai; 54 struct snd_soc_dai *codec_dai = rtd->codec_dai;
55 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 55 struct snd_soc_codec *codec = codec_dai->codec;
56 struct snd_soc_codec *codec = rtd->codec;
57 struct snd_soc_card *card = codec->card; 56 struct snd_soc_card *card = codec->card;
58 struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card); 57 struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card);
59 int srate, mclk; 58 int srate, mclk;
@@ -68,24 +67,6 @@ static int trimslice_asoc_hw_params(struct snd_pcm_substream *substream,
68 return err; 67 return err;
69 } 68 }
70 69
71 err = snd_soc_dai_set_fmt(codec_dai,
72 SND_SOC_DAIFMT_I2S |
73 SND_SOC_DAIFMT_NB_NF |
74 SND_SOC_DAIFMT_CBS_CFS);
75 if (err < 0) {
76 dev_err(card->dev, "codec_dai fmt not set\n");
77 return err;
78 }
79
80 err = snd_soc_dai_set_fmt(cpu_dai,
81 SND_SOC_DAIFMT_I2S |
82 SND_SOC_DAIFMT_NB_NF |
83 SND_SOC_DAIFMT_CBS_CFS);
84 if (err < 0) {
85 dev_err(card->dev, "cpu_dai fmt not set\n");
86 return err;
87 }
88
89 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, 70 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
90 SND_SOC_CLOCK_IN); 71 SND_SOC_CLOCK_IN);
91 if (err < 0) { 72 if (err < 0) {
@@ -121,6 +102,9 @@ static struct snd_soc_dai_link trimslice_tlv320aic23_dai = {
121 .cpu_dai_name = "tegra20-i2s.0", 102 .cpu_dai_name = "tegra20-i2s.0",
122 .codec_dai_name = "tlv320aic23-hifi", 103 .codec_dai_name = "tlv320aic23-hifi",
123 .ops = &trimslice_asoc_ops, 104 .ops = &trimslice_asoc_ops,
105 .dai_fmt = SND_SOC_DAIFMT_I2S |
106 SND_SOC_DAIFMT_NB_NF |
107 SND_SOC_DAIFMT_CBS_CFS,
124}; 108};
125 109
126static struct snd_soc_card snd_soc_trimslice = { 110static struct snd_soc_card snd_soc_trimslice = {
@@ -162,9 +146,9 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
162 } 146 }
163 147
164 trimslice_tlv320aic23_dai.cpu_dai_name = NULL; 148 trimslice_tlv320aic23_dai.cpu_dai_name = NULL;
165 trimslice_tlv320aic23_dai.cpu_dai_of_node = of_parse_phandle( 149 trimslice_tlv320aic23_dai.cpu_of_node = of_parse_phandle(
166 pdev->dev.of_node, "nvidia,i2s-controller", 0); 150 pdev->dev.of_node, "nvidia,i2s-controller", 0);
167 if (!trimslice_tlv320aic23_dai.cpu_dai_of_node) { 151 if (!trimslice_tlv320aic23_dai.cpu_of_node) {
168 dev_err(&pdev->dev, 152 dev_err(&pdev->dev,
169 "Property 'nvidia,i2s-controller' missing or invalid\n"); 153 "Property 'nvidia,i2s-controller' missing or invalid\n");
170 ret = -EINVAL; 154 ret = -EINVAL;
@@ -173,7 +157,7 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
173 157
174 trimslice_tlv320aic23_dai.platform_name = NULL; 158 trimslice_tlv320aic23_dai.platform_name = NULL;
175 trimslice_tlv320aic23_dai.platform_of_node = 159 trimslice_tlv320aic23_dai.platform_of_node =
176 trimslice_tlv320aic23_dai.cpu_dai_of_node; 160 trimslice_tlv320aic23_dai.cpu_of_node;
177 } 161 }
178 162
179 ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev); 163 ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev);
diff --git a/sound/soc/ux500/Kconfig b/sound/soc/ux500/Kconfig
index 44cf43404cd9..069330d82be5 100644
--- a/sound/soc/ux500/Kconfig
+++ b/sound/soc/ux500/Kconfig
@@ -12,3 +12,21 @@ menuconfig SND_SOC_UX500
12config SND_SOC_UX500_PLAT_MSP_I2S 12config SND_SOC_UX500_PLAT_MSP_I2S
13 tristate 13 tristate
14 depends on SND_SOC_UX500 14 depends on SND_SOC_UX500
15
16config SND_SOC_UX500_PLAT_DMA
17 tristate "Platform - DB8500 (DMA)"
18 depends on SND_SOC_UX500
19 select SND_SOC_DMAENGINE_PCM
20 help
21 Say Y if you want to enable the Ux500 platform-driver.
22
23+config SND_SOC_UX500_MACH_MOP500
24+ tristate "Machine - MOP500 (Ux500 + AB8500)"
25 depends on AB8500_CORE && AB8500_GPADC && SND_SOC_UX500
26 select SND_SOC_AB8500_CODEC
27 select SND_SOC_UX500_PLAT_MSP_I2S
28 select SND_SOC_UX500_PLAT_DMA
29 help
30 Select this to enable the MOP500 machine-driver.
31 This will enable platform-drivers for: Ux500
32 This will enable codec-drivers for: AB8500
diff --git a/sound/soc/ux500/Makefile b/sound/soc/ux500/Makefile
index 19974c5a2ea1..cce0c11a4d86 100644
--- a/sound/soc/ux500/Makefile
+++ b/sound/soc/ux500/Makefile
@@ -2,3 +2,9 @@
2 2
3snd-soc-ux500-plat-msp-i2s-objs := ux500_msp_dai.o ux500_msp_i2s.o 3snd-soc-ux500-plat-msp-i2s-objs := ux500_msp_dai.o ux500_msp_i2s.o
4obj-$(CONFIG_SND_SOC_UX500_PLAT_MSP_I2S) += snd-soc-ux500-plat-msp-i2s.o 4obj-$(CONFIG_SND_SOC_UX500_PLAT_MSP_I2S) += snd-soc-ux500-plat-msp-i2s.o
5
6snd-soc-ux500-plat-dma-objs := ux500_pcm.o
7obj-$(CONFIG_SND_SOC_UX500_PLAT_DMA) += snd-soc-ux500-plat-dma.o
8
9snd-soc-ux500-mach-mop500-objs := mop500.o mop500_ab8500.o
10obj-$(CONFIG_SND_SOC_UX500_MACH_MOP500) += snd-soc-ux500-mach-mop500.o
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
new file mode 100644
index 000000000000..356611d9654d
--- /dev/null
+++ b/sound/soc/ux500/mop500.c
@@ -0,0 +1,150 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja (ola.o.lilja@stericsson.com)
5 * for ST-Ericsson.
6 *
7 * License terms:
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as published
11 * by the Free Software Foundation.
12 */
13
14#include <asm/mach-types.h>
15
16#include <linux/module.h>
17#include <linux/io.h>
18#include <linux/spi/spi.h>
19#include <linux/of.h>
20
21#include <sound/soc.h>
22#include <sound/initval.h>
23
24#include "ux500_pcm.h"
25#include "ux500_msp_dai.h"
26
27#include <mop500_ab8500.h>
28
29/* Define the whole MOP500 soundcard, linking platform to the codec-drivers */
30struct snd_soc_dai_link mop500_dai_links[] = {
31 {
32 .name = "ab8500_0",
33 .stream_name = "ab8500_0",
34 .cpu_dai_name = "ux500-msp-i2s.1",
35 .codec_dai_name = "ab8500-codec-dai.0",
36 .platform_name = "ux500-pcm.0",
37 .codec_name = "ab8500-codec.0",
38 .init = mop500_ab8500_machine_init,
39 .ops = mop500_ab8500_ops,
40 },
41 {
42 .name = "ab8500_1",
43 .stream_name = "ab8500_1",
44 .cpu_dai_name = "ux500-msp-i2s.3",
45 .codec_dai_name = "ab8500-codec-dai.1",
46 .platform_name = "ux500-pcm.0",
47 .codec_name = "ab8500-codec.0",
48 .init = NULL,
49 .ops = mop500_ab8500_ops,
50 },
51};
52
53static struct snd_soc_card mop500_card = {
54 .name = "MOP500-card",
55 .probe = NULL,
56 .dai_link = mop500_dai_links,
57 .num_links = ARRAY_SIZE(mop500_dai_links),
58};
59
60static int __devinit mop500_of_probe(struct platform_device *pdev,
61 struct device_node *np)
62{
63 struct device_node *codec_np, *msp_np[2];
64 int i;
65
66 msp_np[0] = of_parse_phandle(np, "stericsson,cpu-dai", 0);
67 msp_np[1] = of_parse_phandle(np, "stericsson,cpu-dai", 1);
68 codec_np = of_parse_phandle(np, "stericsson,audio-codec", 0);
69
70 if (!(msp_np[0] && msp_np[1] && codec_np)) {
71 dev_err(&pdev->dev, "Phandle missing or invalid\n");
72 return -EINVAL;
73 }
74
75 for (i = 0; i < 2; i++) {
76 mop500_dai_links[i].cpu_of_node = msp_np[i];
77 mop500_dai_links[i].cpu_dai_name = NULL;
78 mop500_dai_links[i].codec_of_node = codec_np;
79 mop500_dai_links[i].codec_name = NULL;
80 }
81
82 snd_soc_of_parse_card_name(&mop500_card, "stericsson,card-name");
83
84 return 0;
85}
86static int __devinit mop500_probe(struct platform_device *pdev)
87{
88 struct device_node *np = pdev->dev.of_node;
89 int ret;
90
91 dev_dbg(&pdev->dev, "%s: Enter.\n", __func__);
92
93 mop500_card.dev = &pdev->dev;
94
95 if (np) {
96 ret = mop500_of_probe(pdev, np);
97 if (ret)
98 return ret;
99 }
100
101 dev_dbg(&pdev->dev, "%s: Card %s: Set platform drvdata.\n",
102 __func__, mop500_card.name);
103 platform_set_drvdata(pdev, &mop500_card);
104
105 snd_soc_card_set_drvdata(&mop500_card, NULL);
106
107 dev_dbg(&pdev->dev, "%s: Card %s: num_links = %d\n",
108 __func__, mop500_card.name, mop500_card.num_links);
109 dev_dbg(&pdev->dev, "%s: Card %s: DAI-link 0: name = %s\n",
110 __func__, mop500_card.name, mop500_card.dai_link[0].name);
111 dev_dbg(&pdev->dev, "%s: Card %s: DAI-link 0: stream_name = %s\n",
112 __func__, mop500_card.name,
113 mop500_card.dai_link[0].stream_name);
114
115 ret = snd_soc_register_card(&mop500_card);
116 if (ret)
117 dev_err(&pdev->dev,
118 "Error: snd_soc_register_card failed (%d)!\n", ret);
119
120 return ret;
121}
122
123static int __devexit mop500_remove(struct platform_device *pdev)
124{
125 struct snd_soc_card *mop500_card = platform_get_drvdata(pdev);
126
127 pr_debug("%s: Enter.\n", __func__);
128
129 snd_soc_unregister_card(mop500_card);
130 mop500_ab8500_remove(mop500_card);
131
132 return 0;
133}
134
135static const struct of_device_id snd_soc_mop500_match[] = {
136 { .compatible = "stericsson,snd-soc-mop500", },
137 {},
138};
139
140static struct platform_driver snd_soc_mop500_driver = {
141 .driver = {
142 .owner = THIS_MODULE,
143 .name = "snd-soc-mop500",
144 .of_match_table = snd_soc_mop500_match,
145 },
146 .probe = mop500_probe,
147 .remove = __devexit_p(mop500_remove),
148};
149
150module_platform_driver(snd_soc_mop500_driver);
diff --git a/sound/soc/ux500/mop500_ab8500.c b/sound/soc/ux500/mop500_ab8500.c
new file mode 100644
index 000000000000..78cce236693e
--- /dev/null
+++ b/sound/soc/ux500/mop500_ab8500.c
@@ -0,0 +1,431 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
5 * Kristoffer Karlsson <kristoffer.karlsson@stericsson.com>
6 * for ST-Ericsson.
7 *
8 * License terms:
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 published
12 * by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/device.h>
17#include <linux/io.h>
18#include <linux/clk.h>
19
20#include <mach/hardware.h>
21
22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26
27#include "ux500_pcm.h"
28#include "ux500_msp_dai.h"
29#include "../codecs/ab8500-codec.h"
30
31#define TX_SLOT_MONO 0x0008
32#define TX_SLOT_STEREO 0x000a
33#define RX_SLOT_MONO 0x0001
34#define RX_SLOT_STEREO 0x0003
35#define TX_SLOT_8CH 0x00FF
36#define RX_SLOT_8CH 0x00FF
37
38#define DEF_TX_SLOTS TX_SLOT_STEREO
39#define DEF_RX_SLOTS RX_SLOT_MONO
40
41#define DRIVERMODE_NORMAL 0
42#define DRIVERMODE_CODEC_ONLY 1
43
44/* Slot configuration */
45static unsigned int tx_slots = DEF_TX_SLOTS;
46static unsigned int rx_slots = DEF_RX_SLOTS;
47
48/* Clocks */
49static const char * const enum_mclk[] = {
50 "SYSCLK",
51 "ULPCLK"
52};
53enum mclk {
54 MCLK_SYSCLK,
55 MCLK_ULPCLK,
56};
57
58static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_mclk, enum_mclk);
59
60/* Private data for machine-part MOP500<->AB8500 */
61struct mop500_ab8500_drvdata {
62 /* Clocks */
63 enum mclk mclk_sel;
64 struct clk *clk_ptr_intclk;
65 struct clk *clk_ptr_sysclk;
66 struct clk *clk_ptr_ulpclk;
67};
68
69static inline const char *get_mclk_str(enum mclk mclk_sel)
70{
71 switch (mclk_sel) {
72 case MCLK_SYSCLK:
73 return "SYSCLK";
74 case MCLK_ULPCLK:
75 return "ULPCLK";
76 default:
77 return "Unknown";
78 }
79}
80
81static int mop500_ab8500_set_mclk(struct device *dev,
82 struct mop500_ab8500_drvdata *drvdata)
83{
84 int status;
85 struct clk *clk_ptr;
86
87 if (IS_ERR(drvdata->clk_ptr_intclk)) {
88 dev_err(dev,
89 "%s: ERROR: intclk not initialized!\n", __func__);
90 return -EIO;
91 }
92
93 switch (drvdata->mclk_sel) {
94 case MCLK_SYSCLK:
95 clk_ptr = drvdata->clk_ptr_sysclk;
96 break;
97 case MCLK_ULPCLK:
98 clk_ptr = drvdata->clk_ptr_ulpclk;
99 break;
100 default:
101 return -EINVAL;
102 }
103
104 if (IS_ERR(clk_ptr)) {
105 dev_err(dev, "%s: ERROR: %s not initialized!\n", __func__,
106 get_mclk_str(drvdata->mclk_sel));
107 return -EIO;
108 }
109
110 status = clk_set_parent(drvdata->clk_ptr_intclk, clk_ptr);
111 if (status)
112 dev_err(dev,
113 "%s: ERROR: Setting intclk parent to %s failed (ret = %d)!",
114 __func__, get_mclk_str(drvdata->mclk_sel), status);
115 else
116 dev_dbg(dev,
117 "%s: intclk parent changed to %s.\n",
118 __func__, get_mclk_str(drvdata->mclk_sel));
119
120 return status;
121}
122
123/*
124 * Control-events
125 */
126
127static int mclk_input_control_get(struct snd_kcontrol *kcontrol,
128 struct snd_ctl_elem_value *ucontrol)
129{
130 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
131 struct mop500_ab8500_drvdata *drvdata =
132 snd_soc_card_get_drvdata(codec->card);
133
134 ucontrol->value.enumerated.item[0] = drvdata->mclk_sel;
135
136 return 0;
137}
138
139static int mclk_input_control_put(struct snd_kcontrol *kcontrol,
140 struct snd_ctl_elem_value *ucontrol)
141{
142 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
143 struct mop500_ab8500_drvdata *drvdata =
144 snd_soc_card_get_drvdata(codec->card);
145 unsigned int val = ucontrol->value.enumerated.item[0];
146
147 if (val > (unsigned int)MCLK_ULPCLK)
148 return -EINVAL;
149 if (drvdata->mclk_sel == val)
150 return 0;
151
152 drvdata->mclk_sel = val;
153
154 return 1;
155}
156
157/*
158 * Controls
159 */
160
161static struct snd_kcontrol_new mop500_ab8500_ctrls[] = {
162 SOC_ENUM_EXT("Master Clock Select",
163 soc_enum_mclk,
164 mclk_input_control_get, mclk_input_control_put),
165 /* Digital interface - Clocks */
166 SOC_SINGLE("Digital Interface Master Generator Switch",
167 AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENMASTGEN,
168 1, 0),
169 SOC_SINGLE("Digital Interface 0 Bit-clock Switch",
170 AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENFSBITCLK0,
171 1, 0),
172 SOC_SINGLE("Digital Interface 1 Bit-clock Switch",
173 AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENFSBITCLK1,
174 1, 0),
175 SOC_DAPM_PIN_SWITCH("Headset Left"),
176 SOC_DAPM_PIN_SWITCH("Headset Right"),
177 SOC_DAPM_PIN_SWITCH("Earpiece"),
178 SOC_DAPM_PIN_SWITCH("Speaker Left"),
179 SOC_DAPM_PIN_SWITCH("Speaker Right"),
180 SOC_DAPM_PIN_SWITCH("LineOut Left"),
181 SOC_DAPM_PIN_SWITCH("LineOut Right"),
182 SOC_DAPM_PIN_SWITCH("Vibra 1"),
183 SOC_DAPM_PIN_SWITCH("Vibra 2"),
184 SOC_DAPM_PIN_SWITCH("Mic 1"),
185 SOC_DAPM_PIN_SWITCH("Mic 2"),
186 SOC_DAPM_PIN_SWITCH("LineIn Left"),
187 SOC_DAPM_PIN_SWITCH("LineIn Right"),
188 SOC_DAPM_PIN_SWITCH("DMic 1"),
189 SOC_DAPM_PIN_SWITCH("DMic 2"),
190 SOC_DAPM_PIN_SWITCH("DMic 3"),
191 SOC_DAPM_PIN_SWITCH("DMic 4"),
192 SOC_DAPM_PIN_SWITCH("DMic 5"),
193 SOC_DAPM_PIN_SWITCH("DMic 6"),
194};
195
196/* ASoC */
197
198int mop500_ab8500_startup(struct snd_pcm_substream *substream)
199{
200 struct snd_soc_pcm_runtime *rtd = substream->private_data;
201
202 /* Set audio-clock source */
203 return mop500_ab8500_set_mclk(rtd->card->dev,
204 snd_soc_card_get_drvdata(rtd->card));
205}
206
207void mop500_ab8500_shutdown(struct snd_pcm_substream *substream)
208{
209 struct snd_soc_pcm_runtime *rtd = substream->private_data;
210 struct device *dev = rtd->card->dev;
211
212 dev_dbg(dev, "%s: Enter\n", __func__);
213
214 /* Reset slots configuration to default(s) */
215 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
216 tx_slots = DEF_TX_SLOTS;
217 else
218 rx_slots = DEF_RX_SLOTS;
219}
220
221int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
222 struct snd_pcm_hw_params *params)
223{
224 struct snd_soc_pcm_runtime *rtd = substream->private_data;
225 struct snd_soc_dai *codec_dai = rtd->codec_dai;
226 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
227 struct device *dev = rtd->card->dev;
228 unsigned int fmt;
229 int channels, ret = 0, driver_mode, slots;
230 unsigned int sw_codec, sw_cpu;
231 bool is_playback;
232
233 dev_dbg(dev, "%s: Enter\n", __func__);
234
235 dev_dbg(dev, "%s: substream->pcm->name = %s\n"
236 "substream->pcm->id = %s.\n"
237 "substream->name = %s.\n"
238 "substream->number = %d.\n",
239 __func__,
240 substream->pcm->name,
241 substream->pcm->id,
242 substream->name,
243 substream->number);
244
245 channels = params_channels(params);
246
247 switch (params_format(params)) {
248 case SNDRV_PCM_FORMAT_S32_LE:
249 sw_cpu = 32;
250 break;
251
252 case SNDRV_PCM_FORMAT_S16_LE:
253 sw_cpu = 16;
254 break;
255
256 default:
257 return -EINVAL;
258 }
259
260 /* Setup codec depending on driver-mode */
261 if (channels == 8)
262 driver_mode = DRIVERMODE_CODEC_ONLY;
263 else
264 driver_mode = DRIVERMODE_NORMAL;
265 dev_dbg(dev, "%s: Driver-mode: %s.\n", __func__,
266 (driver_mode == DRIVERMODE_NORMAL) ? "NORMAL" : "CODEC_ONLY");
267
268 /* Setup format */
269
270 if (driver_mode == DRIVERMODE_NORMAL) {
271 fmt = SND_SOC_DAIFMT_DSP_A |
272 SND_SOC_DAIFMT_CBM_CFM |
273 SND_SOC_DAIFMT_NB_NF |
274 SND_SOC_DAIFMT_CONT;
275 } else {
276 fmt = SND_SOC_DAIFMT_DSP_A |
277 SND_SOC_DAIFMT_CBM_CFM |
278 SND_SOC_DAIFMT_NB_NF |
279 SND_SOC_DAIFMT_GATED;
280 }
281
282 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
283 if (ret < 0) {
284 dev_err(dev,
285 "%s: ERROR: snd_soc_dai_set_fmt failed for codec_dai (ret = %d)!\n",
286 __func__, ret);
287 return ret;
288 }
289
290 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
291 if (ret < 0) {
292 dev_err(dev,
293 "%s: ERROR: snd_soc_dai_set_fmt failed for cpu_dai (ret = %d)!\n",
294 __func__, ret);
295 return ret;
296 }
297
298 /* Setup TDM-slots */
299
300 is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
301 switch (channels) {
302 case 1:
303 slots = 16;
304 tx_slots = (is_playback) ? TX_SLOT_MONO : 0;
305 rx_slots = (is_playback) ? 0 : RX_SLOT_MONO;
306 break;
307 case 2:
308 slots = 16;
309 tx_slots = (is_playback) ? TX_SLOT_STEREO : 0;
310 rx_slots = (is_playback) ? 0 : RX_SLOT_STEREO;
311 break;
312 case 8:
313 slots = 16;
314 tx_slots = (is_playback) ? TX_SLOT_8CH : 0;
315 rx_slots = (is_playback) ? 0 : RX_SLOT_8CH;
316 break;
317 default:
318 return -EINVAL;
319 }
320
321 if (driver_mode == DRIVERMODE_NORMAL)
322 sw_codec = sw_cpu;
323 else
324 sw_codec = 20;
325
326 dev_dbg(dev, "%s: CPU-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__,
327 tx_slots, rx_slots);
328 ret = snd_soc_dai_set_tdm_slot(cpu_dai, tx_slots, rx_slots, slots,
329 sw_cpu);
330 if (ret)
331 return ret;
332
333 dev_dbg(dev, "%s: CODEC-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__,
334 tx_slots, rx_slots);
335 ret = snd_soc_dai_set_tdm_slot(codec_dai, tx_slots, rx_slots, slots,
336 sw_codec);
337 if (ret)
338 return ret;
339
340 return 0;
341}
342
343struct snd_soc_ops mop500_ab8500_ops[] = {
344 {
345 .hw_params = mop500_ab8500_hw_params,
346 .startup = mop500_ab8500_startup,
347 .shutdown = mop500_ab8500_shutdown,
348 }
349};
350
351int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd)
352{
353 struct snd_soc_codec *codec = rtd->codec;
354 struct device *dev = rtd->card->dev;
355 struct mop500_ab8500_drvdata *drvdata;
356 int ret;
357
358 dev_dbg(dev, "%s Enter.\n", __func__);
359
360 /* Create driver private-data struct */
361 drvdata = devm_kzalloc(dev, sizeof(struct mop500_ab8500_drvdata),
362 GFP_KERNEL);
363 snd_soc_card_set_drvdata(rtd->card, drvdata);
364
365 /* Setup clocks */
366
367 drvdata->clk_ptr_sysclk = clk_get(dev, "sysclk");
368 if (IS_ERR(drvdata->clk_ptr_sysclk))
369 dev_warn(dev, "%s: WARNING: clk_get failed for 'sysclk'!\n",
370 __func__);
371 drvdata->clk_ptr_ulpclk = clk_get(dev, "ulpclk");
372 if (IS_ERR(drvdata->clk_ptr_ulpclk))
373 dev_warn(dev, "%s: WARNING: clk_get failed for 'ulpclk'!\n",
374 __func__);
375 drvdata->clk_ptr_intclk = clk_get(dev, "intclk");
376 if (IS_ERR(drvdata->clk_ptr_intclk))
377 dev_warn(dev, "%s: WARNING: clk_get failed for 'intclk'!\n",
378 __func__);
379
380 /* Set intclk default parent to ulpclk */
381 drvdata->mclk_sel = MCLK_ULPCLK;
382 ret = mop500_ab8500_set_mclk(dev, drvdata);
383 if (ret < 0)
384 dev_warn(dev, "%s: WARNING: mop500_ab8500_set_mclk!\n",
385 __func__);
386
387 drvdata->mclk_sel = MCLK_ULPCLK;
388
389 /* Add controls */
390 ret = snd_soc_add_codec_controls(codec, mop500_ab8500_ctrls,
391 ARRAY_SIZE(mop500_ab8500_ctrls));
392 if (ret < 0) {
393 pr_err("%s: Failed to add machine-controls (%d)!\n",
394 __func__, ret);
395 return ret;
396 }
397
398 ret = snd_soc_dapm_disable_pin(&codec->dapm, "Earpiece");
399 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Speaker Left");
400 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Speaker Right");
401 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineOut Left");
402 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineOut Right");
403 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Vibra 1");
404 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Vibra 2");
405 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Mic 1");
406 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Mic 2");
407 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineIn Left");
408 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineIn Right");
409 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 1");
410 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 2");
411 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 3");
412 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 4");
413 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 5");
414 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 6");
415
416 return ret;
417}
418
419void mop500_ab8500_remove(struct snd_soc_card *card)
420{
421 struct mop500_ab8500_drvdata *drvdata = snd_soc_card_get_drvdata(card);
422
423 if (drvdata->clk_ptr_sysclk != NULL)
424 clk_put(drvdata->clk_ptr_sysclk);
425 if (drvdata->clk_ptr_ulpclk != NULL)
426 clk_put(drvdata->clk_ptr_ulpclk);
427 if (drvdata->clk_ptr_intclk != NULL)
428 clk_put(drvdata->clk_ptr_intclk);
429
430 snd_soc_card_set_drvdata(card, drvdata);
431}
diff --git a/sound/soc/ux500/mop500_ab8500.h b/sound/soc/ux500/mop500_ab8500.h
new file mode 100644
index 000000000000..cca5b33964b6
--- /dev/null
+++ b/sound/soc/ux500/mop500_ab8500.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>
5 * for ST-Ericsson.
6 *
7 * License terms:
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as published
11 * by the Free Software Foundation.
12 */
13
14#ifndef MOP500_AB8500_H
15#define MOP500_AB8500_H
16
17extern struct snd_soc_ops mop500_ab8500_ops[];
18
19int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *runtime);
20void mop500_ab8500_remove(struct snd_soc_card *card);
21
22#endif
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 93c6c40e724c..45e43b4057b0 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -21,7 +21,7 @@
21#include <linux/mfd/dbx500-prcmu.h> 21#include <linux/mfd/dbx500-prcmu.h>
22 22
23#include <mach/hardware.h> 23#include <mach/hardware.h>
24#include <mach/board-mop500-msp.h> 24#include <mach/msp.h>
25 25
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dai.h> 27#include <sound/soc-dai.h>
@@ -830,14 +830,20 @@ static int __devexit ux500_msp_drv_remove(struct platform_device *pdev)
830 return 0; 830 return 0;
831} 831}
832 832
833static const struct of_device_id ux500_msp_i2s_match[] = {
834 { .compatible = "stericsson,ux500-msp-i2s", },
835 {},
836};
837
833static struct platform_driver msp_i2s_driver = { 838static struct platform_driver msp_i2s_driver = {
834 .driver = { 839 .driver = {
835 .name = "ux500-msp-i2s", 840 .name = "ux500-msp-i2s",
836 .owner = THIS_MODULE, 841 .owner = THIS_MODULE,
842 .of_match_table = ux500_msp_i2s_match,
837 }, 843 },
838 .probe = ux500_msp_drv_probe, 844 .probe = ux500_msp_drv_probe,
839 .remove = ux500_msp_drv_remove, 845 .remove = ux500_msp_drv_remove,
840}; 846};
841module_platform_driver(msp_i2s_driver); 847module_platform_driver(msp_i2s_driver);
842 848
843MODULE_LICENSE("GPLv2"); 849MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index 496dec10c96e..e5c79ca42518 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -15,16 +15,21 @@
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/pinctrl/consumer.h>
18#include <linux/delay.h> 19#include <linux/delay.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/of.h>
20 22
21#include <mach/hardware.h> 23#include <mach/hardware.h>
22#include <mach/board-mop500-msp.h> 24#include <mach/msp.h>
23 25
24#include <sound/soc.h> 26#include <sound/soc.h>
25 27
26#include "ux500_msp_i2s.h" 28#include "ux500_msp_i2s.h"
27 29
30/* MSP1/3 Tx/Rx usage protection */
31static DEFINE_SPINLOCK(msp_rxtx_lock);
32
28 /* Protocol desciptors */ 33 /* Protocol desciptors */
29static const struct msp_protdesc prot_descs[] = { 34static const struct msp_protdesc prot_descs[] = {
30 { /* I2S */ 35 { /* I2S */
@@ -352,17 +357,23 @@ static int configure_multichannel(struct ux500_msp *msp,
352 357
353static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config) 358static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
354{ 359{
355 int status = 0; 360 int status = 0, retval = 0;
356 u32 reg_val_DMACR, reg_val_GCR; 361 u32 reg_val_DMACR, reg_val_GCR;
362 unsigned long flags;
357 363
358 /* Check msp state whether in RUN or CONFIGURED Mode */ 364 /* Check msp state whether in RUN or CONFIGURED Mode */
359 if ((msp->msp_state == MSP_STATE_IDLE) && (msp->plat_init)) { 365 if (msp->msp_state == MSP_STATE_IDLE) {
360 status = msp->plat_init(); 366 spin_lock_irqsave(&msp_rxtx_lock, flags);
361 if (status) { 367 if (msp->pinctrl_rxtx_ref == 0 &&
362 dev_err(msp->dev, "%s: ERROR: Failed to init MSP (%d)!\n", 368 !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_def))) {
363 __func__, status); 369 retval = pinctrl_select_state(msp->pinctrl_p,
364 return status; 370 msp->pinctrl_def);
371 if (retval)
372 pr_err("could not set MSP defstate\n");
365 } 373 }
374 if (!retval)
375 msp->pinctrl_rxtx_ref++;
376 spin_unlock_irqrestore(&msp_rxtx_lock, flags);
366 } 377 }
367 378
368 /* Configure msp with protocol dependent settings */ 379 /* Configure msp with protocol dependent settings */
@@ -620,7 +631,8 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
620 631
621int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) 632int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
622{ 633{
623 int status = 0; 634 int status = 0, retval = 0;
635 unsigned long flags;
624 636
625 dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir); 637 dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir);
626 638
@@ -631,12 +643,19 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
631 writel((readl(msp->registers + MSP_GCR) & 643 writel((readl(msp->registers + MSP_GCR) &
632 (~(FRAME_GEN_ENABLE | SRG_ENABLE))), 644 (~(FRAME_GEN_ENABLE | SRG_ENABLE))),
633 msp->registers + MSP_GCR); 645 msp->registers + MSP_GCR);
634 if (msp->plat_exit) 646
635 status = msp->plat_exit(); 647 spin_lock_irqsave(&msp_rxtx_lock, flags);
636 if (status) 648 WARN_ON(!msp->pinctrl_rxtx_ref);
637 dev_warn(msp->dev, 649 msp->pinctrl_rxtx_ref--;
638 "%s: WARN: ux500_msp_i2s_exit failed (%d)!\n", 650 if (msp->pinctrl_rxtx_ref == 0 &&
639 __func__, status); 651 !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_sleep))) {
652 retval = pinctrl_select_state(msp->pinctrl_p,
653 msp->pinctrl_sleep);
654 if (retval)
655 pr_err("could not set MSP sleepstate\n");
656 }
657 spin_unlock_irqrestore(&msp_rxtx_lock, flags);
658
640 writel(0, msp->registers + MSP_GCR); 659 writel(0, msp->registers + MSP_GCR);
641 writel(0, msp->registers + MSP_TCF); 660 writel(0, msp->registers + MSP_TCF);
642 writel(0, msp->registers + MSP_RCF); 661 writel(0, msp->registers + MSP_RCF);
@@ -663,21 +682,33 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
663 struct ux500_msp **msp_p, 682 struct ux500_msp **msp_p,
664 struct msp_i2s_platform_data *platform_data) 683 struct msp_i2s_platform_data *platform_data)
665{ 684{
666 int ret = 0;
667 struct resource *res = NULL; 685 struct resource *res = NULL;
668 struct i2s_controller *i2s_cont; 686 struct i2s_controller *i2s_cont;
687 struct device_node *np = pdev->dev.of_node;
669 struct ux500_msp *msp; 688 struct ux500_msp *msp;
670 689
671 dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__,
672 pdev->name, platform_data->id);
673
674 *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL); 690 *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL);
675 msp = *msp_p; 691 msp = *msp_p;
676 692
693 if (np) {
694 if (!platform_data) {
695 platform_data = devm_kzalloc(&pdev->dev,
696 sizeof(struct msp_i2s_platform_data), GFP_KERNEL);
697 if (!platform_data)
698 ret = -ENOMEM;
699 }
700 } else
701 if (!platform_data)
702 ret = -EINVAL;
703
704 if (ret)
705 goto err_res;
706
707 dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__,
708 pdev->name, platform_data->id);
709
677 msp->id = platform_data->id; 710 msp->id = platform_data->id;
678 msp->dev = &pdev->dev; 711 msp->dev = &pdev->dev;
679 msp->plat_init = platform_data->msp_i2s_init;
680 msp->plat_exit = platform_data->msp_i2s_exit;
681 msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx; 712 msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx;
682 msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx; 713 msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx;
683 714
@@ -685,15 +716,14 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
685 if (res == NULL) { 716 if (res == NULL) {
686 dev_err(&pdev->dev, "%s: ERROR: Unable to get resource!\n", 717 dev_err(&pdev->dev, "%s: ERROR: Unable to get resource!\n",
687 __func__); 718 __func__);
688 ret = -ENOMEM; 719 return -ENOMEM;
689 goto err_res;
690 } 720 }
691 721
692 msp->registers = ioremap(res->start, (res->end - res->start + 1)); 722 msp->registers = devm_ioremap(&pdev->dev, res->start,
723 resource_size(res));
693 if (msp->registers == NULL) { 724 if (msp->registers == NULL) {
694 dev_err(&pdev->dev, "%s: ERROR: ioremap failed!\n", __func__); 725 dev_err(&pdev->dev, "%s: ERROR: ioremap failed!\n", __func__);
695 ret = -ENOMEM; 726 return -ENOMEM;
696 goto err_res;
697 } 727 }
698 728
699 msp->msp_state = MSP_STATE_IDLE; 729 msp->msp_state = MSP_STATE_IDLE;
@@ -705,7 +735,7 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
705 dev_err(&pdev->dev, 735 dev_err(&pdev->dev,
706 "%s: ERROR: Failed to allocate I2S-controller!\n", 736 "%s: ERROR: Failed to allocate I2S-controller!\n",
707 __func__); 737 __func__);
708 goto err_i2s_cont; 738 return -ENOMEM;
709 } 739 }
710 i2s_cont->dev.parent = &pdev->dev; 740 i2s_cont->dev.parent = &pdev->dev;
711 i2s_cont->data = (void *)msp; 741 i2s_cont->data = (void *)msp;
@@ -715,15 +745,26 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
715 dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name); 745 dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name);
716 msp->i2s_cont = i2s_cont; 746 msp->i2s_cont = i2s_cont;
717 747
718 return 0; 748 msp->pinctrl_p = pinctrl_get(msp->dev);
719 749 if (IS_ERR(msp->pinctrl_p))
720err_i2s_cont: 750 dev_err(&pdev->dev, "could not get MSP pinctrl\n");
721 iounmap(msp->registers); 751 else {
722 752 msp->pinctrl_def = pinctrl_lookup_state(msp->pinctrl_p,
723err_res: 753 PINCTRL_STATE_DEFAULT);
724 devm_kfree(&pdev->dev, msp); 754 if (IS_ERR(msp->pinctrl_def)) {
755 dev_err(&pdev->dev,
756 "could not get MSP defstate (%li)\n",
757 PTR_ERR(msp->pinctrl_def));
758 }
759 msp->pinctrl_sleep = pinctrl_lookup_state(msp->pinctrl_p,
760 PINCTRL_STATE_SLEEP);
761 if (IS_ERR(msp->pinctrl_sleep))
762 dev_err(&pdev->dev,
763 "could not get MSP idlestate (%li)\n",
764 PTR_ERR(msp->pinctrl_def));
765 }
725 766
726 return ret; 767 return 0;
727} 768}
728 769
729void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev, 770void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
@@ -732,11 +773,6 @@ void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
732 dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id); 773 dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id);
733 774
734 device_unregister(&msp->i2s_cont->dev); 775 device_unregister(&msp->i2s_cont->dev);
735 devm_kfree(&pdev->dev, msp->i2s_cont);
736
737 iounmap(msp->registers);
738
739 devm_kfree(&pdev->dev, msp);
740} 776}
741 777
742MODULE_LICENSE("GPLv2"); 778MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h
index 7f71b4a0d4bc..1311c0df7628 100644
--- a/sound/soc/ux500/ux500_msp_i2s.h
+++ b/sound/soc/ux500/ux500_msp_i2s.h
@@ -17,7 +17,7 @@
17 17
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19 19
20#include <mach/board-mop500-msp.h> 20#include <mach/msp.h>
21 21
22#define MSP_INPUT_FREQ_APB 48000000 22#define MSP_INPUT_FREQ_APB 48000000
23 23
@@ -524,14 +524,18 @@ struct ux500_msp {
524 struct dma_chan *rx_pipeid; 524 struct dma_chan *rx_pipeid;
525 enum msp_state msp_state; 525 enum msp_state msp_state;
526 int (*transfer) (struct ux500_msp *msp, struct i2s_message *message); 526 int (*transfer) (struct ux500_msp *msp, struct i2s_message *message);
527 int (*plat_init) (void);
528 int (*plat_exit) (void);
529 struct timer_list notify_timer; 527 struct timer_list notify_timer;
530 int def_elem_len; 528 int def_elem_len;
531 unsigned int dir_busy; 529 unsigned int dir_busy;
532 int loopback_enable; 530 int loopback_enable;
533 u32 backup_regs[MAX_MSP_BACKUP_REGS]; 531 u32 backup_regs[MAX_MSP_BACKUP_REGS];
534 unsigned int f_bitclk; 532 unsigned int f_bitclk;
533 /* Pin modes */
534 struct pinctrl *pinctrl_p;
535 struct pinctrl_state *pinctrl_def;
536 struct pinctrl_state *pinctrl_sleep;
537 /* Reference Count */
538 int pinctrl_rxtx_ref;
535}; 539};
536 540
537struct ux500_msp_dma_params { 541struct ux500_msp_dma_params {
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c
new file mode 100644
index 000000000000..1a04e248453c
--- /dev/null
+++ b/sound/soc/ux500/ux500_pcm.c
@@ -0,0 +1,318 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
5 * Roger Nilsson <roger.xr.nilsson@stericsson.com>
6 * for ST-Ericsson.
7 *
8 * License terms:
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 published
12 * by the Free Software Foundation.
13 */
14
15#include <asm/page.h>
16
17#include <linux/module.h>
18#include <linux/dma-mapping.h>
19#include <linux/dmaengine.h>
20#include <linux/slab.h>
21
22#include <plat/ste_dma40.h>
23
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/dmaengine_pcm.h>
28
29#include "ux500_msp_i2s.h"
30#include "ux500_pcm.h"
31
32static struct snd_pcm_hardware ux500_pcm_hw_playback = {
33 .info = SNDRV_PCM_INFO_INTERLEAVED |
34 SNDRV_PCM_INFO_MMAP |
35 SNDRV_PCM_INFO_RESUME |
36 SNDRV_PCM_INFO_PAUSE,
37 .formats = SNDRV_PCM_FMTBIT_S16_LE |
38 SNDRV_PCM_FMTBIT_U16_LE |
39 SNDRV_PCM_FMTBIT_S16_BE |
40 SNDRV_PCM_FMTBIT_U16_BE,
41 .rates = SNDRV_PCM_RATE_KNOT,
42 .rate_min = UX500_PLATFORM_MIN_RATE_PLAYBACK,
43 .rate_max = UX500_PLATFORM_MAX_RATE_PLAYBACK,
44 .channels_min = UX500_PLATFORM_MIN_CHANNELS,
45 .channels_max = UX500_PLATFORM_MAX_CHANNELS,
46 .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
47 .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN,
48 .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX,
49 .periods_min = UX500_PLATFORM_PERIODS_MIN,
50 .periods_max = UX500_PLATFORM_PERIODS_MAX,
51};
52
53static struct snd_pcm_hardware ux500_pcm_hw_capture = {
54 .info = SNDRV_PCM_INFO_INTERLEAVED |
55 SNDRV_PCM_INFO_MMAP |
56 SNDRV_PCM_INFO_RESUME |
57 SNDRV_PCM_INFO_PAUSE,
58 .formats = SNDRV_PCM_FMTBIT_S16_LE |
59 SNDRV_PCM_FMTBIT_U16_LE |
60 SNDRV_PCM_FMTBIT_S16_BE |
61 SNDRV_PCM_FMTBIT_U16_BE,
62 .rates = SNDRV_PCM_RATE_KNOT,
63 .rate_min = UX500_PLATFORM_MIN_RATE_CAPTURE,
64 .rate_max = UX500_PLATFORM_MAX_RATE_CAPTURE,
65 .channels_min = UX500_PLATFORM_MIN_CHANNELS,
66 .channels_max = UX500_PLATFORM_MAX_CHANNELS,
67 .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
68 .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN,
69 .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX,
70 .periods_min = UX500_PLATFORM_PERIODS_MIN,
71 .periods_max = UX500_PLATFORM_PERIODS_MAX,
72};
73
74static void ux500_pcm_dma_hw_free(struct device *dev,
75 struct snd_pcm_substream *substream)
76{
77 struct snd_pcm_runtime *runtime = substream->runtime;
78 struct snd_dma_buffer *buf = runtime->dma_buffer_p;
79
80 if (runtime->dma_area == NULL)
81 return;
82
83 if (buf != &substream->dma_buffer) {
84 dma_free_coherent(buf->dev.dev, buf->bytes, buf->area,
85 buf->addr);
86 kfree(runtime->dma_buffer_p);
87 }
88
89 snd_pcm_set_runtime_buffer(substream, NULL);
90}
91
92static int ux500_pcm_open(struct snd_pcm_substream *substream)
93{
94 int stream_id = substream->pstr->stream;
95 struct snd_pcm_runtime *runtime = substream->runtime;
96 struct snd_soc_pcm_runtime *rtd = substream->private_data;
97 struct snd_soc_dai *dai = rtd->cpu_dai;
98 struct device *dev = dai->dev;
99 int ret;
100 struct ux500_msp_dma_params *dma_params;
101 u16 per_data_width, mem_data_width;
102 struct stedma40_chan_cfg *dma_cfg;
103
104 dev_dbg(dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id,
105 snd_pcm_stream_str(substream));
106
107 dev_dbg(dev, "%s: Set runtime hwparams.\n", __func__);
108 if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
109 snd_soc_set_runtime_hwparams(substream,
110 &ux500_pcm_hw_playback);
111 else
112 snd_soc_set_runtime_hwparams(substream,
113 &ux500_pcm_hw_capture);
114
115 /* ensure that buffer size is a multiple of period size */
116 ret = snd_pcm_hw_constraint_integer(runtime,
117 SNDRV_PCM_HW_PARAM_PERIODS);
118 if (ret < 0) {
119 dev_err(dev, "%s: Error: snd_pcm_hw_constraints failed (%d)\n",
120 __func__, ret);
121 return ret;
122 }
123
124 dev_dbg(dev, "%s: Set hw-struct for %s.\n", __func__,
125 snd_pcm_stream_str(substream));
126 runtime->hw = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ?
127 ux500_pcm_hw_playback : ux500_pcm_hw_capture;
128
129 mem_data_width = STEDMA40_HALFWORD_WIDTH;
130
131 dma_params = snd_soc_dai_get_dma_data(dai, substream);
132 switch (dma_params->data_size) {
133 case 32:
134 per_data_width = STEDMA40_WORD_WIDTH;
135 break;
136 case 16:
137 per_data_width = STEDMA40_HALFWORD_WIDTH;
138 break;
139 case 8:
140 per_data_width = STEDMA40_BYTE_WIDTH;
141 break;
142 default:
143 per_data_width = STEDMA40_WORD_WIDTH;
144 dev_warn(rtd->platform->dev,
145 "%s: Unknown data-size (%d)! Assuming 32 bits.\n",
146 __func__, dma_params->data_size);
147 }
148
149 dma_cfg = dma_params->dma_cfg;
150
151 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
152 dma_cfg->src_info.data_width = mem_data_width;
153 dma_cfg->dst_info.data_width = per_data_width;
154 } else {
155 dma_cfg->src_info.data_width = per_data_width;
156 dma_cfg->dst_info.data_width = mem_data_width;
157 }
158
159
160 ret = snd_dmaengine_pcm_open(substream, stedma40_filter, dma_cfg);
161 if (ret) {
162 dev_dbg(dai->dev,
163 "%s: ERROR: snd_dmaengine_pcm_open failed (%d)!\n",
164 __func__, ret);
165 return ret;
166 }
167
168 snd_dmaengine_pcm_set_data(substream, dma_cfg);
169
170 return 0;
171}
172
173static int ux500_pcm_close(struct snd_pcm_substream *substream)
174{
175 struct snd_soc_pcm_runtime *rtd = substream->private_data;
176 struct snd_soc_dai *dai = rtd->cpu_dai;
177
178 dev_dbg(dai->dev, "%s: Enter\n", __func__);
179
180 snd_dmaengine_pcm_close(substream);
181
182 return 0;
183}
184
185static int ux500_pcm_hw_params(struct snd_pcm_substream *substream,
186 struct snd_pcm_hw_params *hw_params)
187{
188 struct snd_pcm_runtime *runtime = substream->runtime;
189 struct snd_dma_buffer *buf = runtime->dma_buffer_p;
190 struct snd_soc_pcm_runtime *rtd = substream->private_data;
191 int ret = 0;
192 int size;
193
194 dev_dbg(rtd->platform->dev, "%s: Enter\n", __func__);
195
196 size = params_buffer_bytes(hw_params);
197
198 if (buf) {
199 if (buf->bytes >= size)
200 goto out;
201 ux500_pcm_dma_hw_free(NULL, substream);
202 }
203
204 if (substream->dma_buffer.area != NULL &&
205 substream->dma_buffer.bytes >= size) {
206 buf = &substream->dma_buffer;
207 } else {
208 buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL);
209 if (!buf)
210 goto nomem;
211
212 buf->dev.type = SNDRV_DMA_TYPE_DEV;
213 buf->dev.dev = NULL;
214 buf->area = dma_alloc_coherent(NULL, size, &buf->addr,
215 GFP_KERNEL);
216 buf->bytes = size;
217 buf->private_data = NULL;
218
219 if (!buf->area)
220 goto free;
221 }
222 snd_pcm_set_runtime_buffer(substream, buf);
223 ret = 1;
224 out:
225 runtime->dma_bytes = size;
226 return ret;
227
228 free:
229 kfree(buf);
230 nomem:
231 return -ENOMEM;
232}
233
234static int ux500_pcm_hw_free(struct snd_pcm_substream *substream)
235{
236 struct snd_soc_pcm_runtime *rtd = substream->private_data;
237
238 dev_dbg(rtd->platform->dev, "%s: Enter\n", __func__);
239
240 ux500_pcm_dma_hw_free(NULL, substream);
241
242 return 0;
243}
244
245static int ux500_pcm_mmap(struct snd_pcm_substream *substream,
246 struct vm_area_struct *vma)
247{
248 struct snd_pcm_runtime *runtime = substream->runtime;
249 struct snd_soc_pcm_runtime *rtd = substream->private_data;
250
251 dev_dbg(rtd->platform->dev, "%s: Enter.\n", __func__);
252
253 return dma_mmap_coherent(NULL, vma, runtime->dma_area,
254 runtime->dma_addr, runtime->dma_bytes);
255}
256
257static struct snd_pcm_ops ux500_pcm_ops = {
258 .open = ux500_pcm_open,
259 .close = ux500_pcm_close,
260 .ioctl = snd_pcm_lib_ioctl,
261 .hw_params = ux500_pcm_hw_params,
262 .hw_free = ux500_pcm_hw_free,
263 .trigger = snd_dmaengine_pcm_trigger,
264 .pointer = snd_dmaengine_pcm_pointer_no_residue,
265 .mmap = ux500_pcm_mmap
266};
267
268int ux500_pcm_new(struct snd_soc_pcm_runtime *rtd)
269{
270 struct snd_pcm *pcm = rtd->pcm;
271
272 dev_dbg(rtd->platform->dev, "%s: Enter (id = '%s').\n", __func__,
273 pcm->id);
274
275 pcm->info_flags = 0;
276
277 return 0;
278}
279
280static struct snd_soc_platform_driver ux500_pcm_soc_drv = {
281 .ops = &ux500_pcm_ops,
282 .pcm_new = ux500_pcm_new,
283};
284
285static int __devexit ux500_pcm_drv_probe(struct platform_device *pdev)
286{
287 int ret;
288
289 ret = snd_soc_register_platform(&pdev->dev, &ux500_pcm_soc_drv);
290 if (ret < 0) {
291 dev_err(&pdev->dev,
292 "%s: ERROR: Failed to register platform '%s' (%d)!\n",
293 __func__, pdev->name, ret);
294 return ret;
295 }
296
297 return 0;
298}
299
300static int __devinit ux500_pcm_drv_remove(struct platform_device *pdev)
301{
302 snd_soc_unregister_platform(&pdev->dev);
303
304 return 0;
305}
306
307static struct platform_driver ux500_pcm_driver = {
308 .driver = {
309 .name = "ux500-pcm",
310 .owner = THIS_MODULE,
311 },
312
313 .probe = ux500_pcm_drv_probe,
314 .remove = __devexit_p(ux500_pcm_drv_remove),
315};
316module_platform_driver(ux500_pcm_driver);
317
318MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h
new file mode 100644
index 000000000000..77ed44d371e9
--- /dev/null
+++ b/sound/soc/ux500/ux500_pcm.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
5 * Roger Nilsson <roger.xr.nilsson@stericsson.com>
6 * for ST-Ericsson.
7 *
8 * License terms:
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 published
12 * by the Free Software Foundation.
13 */
14#ifndef UX500_PCM_H
15#define UX500_PCM_H
16
17#include <asm/page.h>
18
19#include <linux/workqueue.h>
20
21#define UX500_PLATFORM_MIN_RATE_PLAYBACK 8000
22#define UX500_PLATFORM_MAX_RATE_PLAYBACK 48000
23#define UX500_PLATFORM_MIN_RATE_CAPTURE 8000
24#define UX500_PLATFORM_MAX_RATE_CAPTURE 48000
25
26#define UX500_PLATFORM_MIN_CHANNELS 1
27#define UX500_PLATFORM_MAX_CHANNELS 8
28
29#define UX500_PLATFORM_PERIODS_BYTES_MIN 128
30#define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE)
31#define UX500_PLATFORM_PERIODS_MIN 2
32#define UX500_PLATFORM_PERIODS_MAX 48
33#define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE)
34
35#endif
diff --git a/sound/sound_firmware.c b/sound/sound_firmware.c
index 7e96249536b4..37711a5d0d6b 100644
--- a/sound/sound_firmware.c
+++ b/sound/sound_firmware.c
@@ -23,14 +23,14 @@ static int do_mod_firmware_load(const char *fn, char **fp)
23 if (l <= 0 || l > 131072) 23 if (l <= 0 || l > 131072)
24 { 24 {
25 printk(KERN_INFO "Invalid firmware '%s'\n", fn); 25 printk(KERN_INFO "Invalid firmware '%s'\n", fn);
26 filp_close(filp, current->files); 26 filp_close(filp, NULL);
27 return 0; 27 return 0;
28 } 28 }
29 dp = vmalloc(l); 29 dp = vmalloc(l);
30 if (dp == NULL) 30 if (dp == NULL)
31 { 31 {
32 printk(KERN_INFO "Out of memory loading '%s'.\n", fn); 32 printk(KERN_INFO "Out of memory loading '%s'.\n", fn);
33 filp_close(filp, current->files); 33 filp_close(filp, NULL);
34 return 0; 34 return 0;
35 } 35 }
36 pos = 0; 36 pos = 0;
@@ -38,10 +38,10 @@ static int do_mod_firmware_load(const char *fn, char **fp)
38 { 38 {
39 printk(KERN_INFO "Failed to read '%s'.\n", fn); 39 printk(KERN_INFO "Failed to read '%s'.\n", fn);
40 vfree(dp); 40 vfree(dp);
41 filp_close(filp, current->files); 41 filp_close(filp, NULL);
42 return 0; 42 return 0;
43 } 43 }
44 filp_close(filp, current->files); 44 filp_close(filp, NULL);
45 *fp = dp; 45 *fp = dp;
46 return (int) l; 46 return (int) l;
47} 47}
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index 64aed432ae22..7da0d0aa72cb 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -485,7 +485,7 @@ static int __devinit snd_probe(struct usb_interface *intf,
485 const struct usb_device_id *id) 485 const struct usb_device_id *id)
486{ 486{
487 int ret; 487 int ret;
488 struct snd_card *card; 488 struct snd_card *card = NULL;
489 struct usb_device *device = interface_to_usbdev(intf); 489 struct usb_device *device = interface_to_usbdev(intf);
490 490
491 ret = create_card(device, intf, &card); 491 ret = create_card(device, intf, &card);
diff --git a/sound/usb/card.c b/sound/usb/card.c
index d5b5c3388e28..4a469f0cb6d4 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -553,7 +553,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
553 struct snd_usb_audio *chip) 553 struct snd_usb_audio *chip)
554{ 554{
555 struct snd_card *card; 555 struct snd_card *card;
556 struct list_head *p; 556 struct list_head *p, *n;
557 557
558 if (chip == (void *)-1L) 558 if (chip == (void *)-1L)
559 return; 559 return;
@@ -570,7 +570,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
570 snd_usb_stream_disconnect(p); 570 snd_usb_stream_disconnect(p);
571 } 571 }
572 /* release the endpoint resources */ 572 /* release the endpoint resources */
573 list_for_each(p, &chip->ep_list) { 573 list_for_each_safe(p, n, &chip->ep_list) {
574 snd_usb_endpoint_free(p); 574 snd_usb_endpoint_free(p);
575 } 575 }
576 /* release the midi resources */ 576 /* release the midi resources */
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index 379baad3d5ad..5e634a2eb282 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -111,7 +111,8 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
111 return 0; 111 return 0;
112 112
113 /* If a clock source can't tell us whether it's valid, we assume it is */ 113 /* If a clock source can't tell us whether it's valid, we assume it is */
114 if (!uac2_control_is_readable(cs_desc->bmControls, UAC2_CS_CONTROL_CLOCK_VALID)) 114 if (!uac2_control_is_readable(cs_desc->bmControls,
115 UAC2_CS_CONTROL_CLOCK_VALID - 1))
115 return 1; 116 return 1;
116 117
117 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, 118 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 0f647d22cb4a..060dccb9ec75 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -141,7 +141,7 @@ int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep)
141 * 141 *
142 * For implicit feedback, next_packet_size() is unused. 142 * For implicit feedback, next_packet_size() is unused.
143 */ 143 */
144static int next_packet_size(struct snd_usb_endpoint *ep) 144int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep)
145{ 145{
146 unsigned long flags; 146 unsigned long flags;
147 int ret; 147 int ret;
@@ -177,15 +177,6 @@ static void retire_inbound_urb(struct snd_usb_endpoint *ep,
177 ep->retire_data_urb(ep->data_subs, urb); 177 ep->retire_data_urb(ep->data_subs, urb);
178} 178}
179 179
180static void prepare_outbound_urb_sizes(struct snd_usb_endpoint *ep,
181 struct snd_urb_ctx *ctx)
182{
183 int i;
184
185 for (i = 0; i < ctx->packets; ++i)
186 ctx->packet_size[i] = next_packet_size(ep);
187}
188
189/* 180/*
190 * Prepare a PLAYBACK urb for submission to the bus. 181 * Prepare a PLAYBACK urb for submission to the bus.
191 */ 182 */
@@ -206,7 +197,13 @@ static void prepare_outbound_urb(struct snd_usb_endpoint *ep,
206 /* no data provider, so send silence */ 197 /* no data provider, so send silence */
207 unsigned int offs = 0; 198 unsigned int offs = 0;
208 for (i = 0; i < ctx->packets; ++i) { 199 for (i = 0; i < ctx->packets; ++i) {
209 int counts = ctx->packet_size[i]; 200 int counts;
201
202 if (ctx->packet_size[i])
203 counts = ctx->packet_size[i];
204 else
205 counts = snd_usb_endpoint_next_packet_size(ep);
206
210 urb->iso_frame_desc[i].offset = offs * ep->stride; 207 urb->iso_frame_desc[i].offset = offs * ep->stride;
211 urb->iso_frame_desc[i].length = counts * ep->stride; 208 urb->iso_frame_desc[i].length = counts * ep->stride;
212 offs += counts; 209 offs += counts;
@@ -370,7 +367,6 @@ static void snd_complete_urb(struct urb *urb)
370 goto exit_clear; 367 goto exit_clear;
371 } 368 }
372 369
373 prepare_outbound_urb_sizes(ep, ctx);
374 prepare_outbound_urb(ep, ctx); 370 prepare_outbound_urb(ep, ctx);
375 } else { 371 } else {
376 retire_inbound_urb(ep, ctx); 372 retire_inbound_urb(ep, ctx);
@@ -799,7 +795,9 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
799/** 795/**
800 * snd_usb_endpoint_start: start an snd_usb_endpoint 796 * snd_usb_endpoint_start: start an snd_usb_endpoint
801 * 797 *
802 * @ep: the endpoint to start 798 * @ep: the endpoint to start
799 * @can_sleep: flag indicating whether the operation is executed in
800 * non-atomic context
803 * 801 *
804 * A call to this function will increment the use count of the endpoint. 802 * A call to this function will increment the use count of the endpoint.
805 * In case it is not already running, the URBs for this endpoint will be 803 * In case it is not already running, the URBs for this endpoint will be
@@ -809,7 +807,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
809 * 807 *
810 * Returns an error if the URB submission failed, 0 in all other cases. 808 * Returns an error if the URB submission failed, 0 in all other cases.
811 */ 809 */
812int snd_usb_endpoint_start(struct snd_usb_endpoint *ep) 810int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep)
813{ 811{
814 int err; 812 int err;
815 unsigned int i; 813 unsigned int i;
@@ -822,8 +820,9 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
822 return 0; 820 return 0;
823 821
824 /* just to be sure */ 822 /* just to be sure */
825 deactivate_urbs(ep, 0, 1); 823 deactivate_urbs(ep, 0, can_sleep);
826 wait_clear_urbs(ep); 824 if (can_sleep)
825 wait_clear_urbs(ep);
827 826
828 ep->active_mask = 0; 827 ep->active_mask = 0;
829 ep->unlink_mask = 0; 828 ep->unlink_mask = 0;
@@ -854,7 +853,6 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
854 goto __error; 853 goto __error;
855 854
856 if (usb_pipeout(ep->pipe)) { 855 if (usb_pipeout(ep->pipe)) {
857 prepare_outbound_urb_sizes(ep, urb->context);
858 prepare_outbound_urb(ep, urb->context); 856 prepare_outbound_urb(ep, urb->context);
859 } else { 857 } else {
860 prepare_inbound_urb(ep, urb->context); 858 prepare_inbound_urb(ep, urb->context);
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
index ee2723fb174f..cbbbdf226d66 100644
--- a/sound/usb/endpoint.h
+++ b/sound/usb/endpoint.h
@@ -13,7 +13,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
13 struct audioformat *fmt, 13 struct audioformat *fmt,
14 struct snd_usb_endpoint *sync_ep); 14 struct snd_usb_endpoint *sync_ep);
15 15
16int snd_usb_endpoint_start(struct snd_usb_endpoint *ep); 16int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep);
17void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, 17void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep,
18 int force, int can_sleep, int wait); 18 int force, int can_sleep, int wait);
19int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); 19int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep);
@@ -21,6 +21,7 @@ int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep);
21void snd_usb_endpoint_free(struct list_head *head); 21void snd_usb_endpoint_free(struct list_head *head);
22 22
23int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep); 23int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep);
24int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep);
24 25
25void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, 26void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep,
26 struct snd_usb_endpoint *sender, 27 struct snd_usb_endpoint *sender,
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 41f4b6911920..690000db0ec0 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -42,6 +42,13 @@
42 42
43extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; 43extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl;
44 44
45struct std_mono_table {
46 unsigned int unitid, control, cmask;
47 int val_type;
48 const char *name;
49 snd_kcontrol_tlv_rw_t *tlv_callback;
50};
51
45/* private_free callback */ 52/* private_free callback */
46static void usb_mixer_elem_free(struct snd_kcontrol *kctl) 53static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
47{ 54{
@@ -114,6 +121,25 @@ static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
114} 121}
115 122
116/* 123/*
124 * Create a set of standard UAC controls from a table
125 */
126static int snd_create_std_mono_table(struct usb_mixer_interface *mixer,
127 struct std_mono_table *t)
128{
129 int err;
130
131 while (t->name != NULL) {
132 err = snd_create_std_mono_ctl(mixer, t->unitid, t->control,
133 t->cmask, t->val_type, t->name, t->tlv_callback);
134 if (err < 0)
135 return err;
136 t++;
137 }
138
139 return 0;
140}
141
142/*
117 * Sound Blaster remote control configuration 143 * Sound Blaster remote control configuration
118 * 144 *
119 * format of remote control data: 145 * format of remote control data:
@@ -916,61 +942,6 @@ static int snd_ftu_create_mixer(struct usb_mixer_interface *mixer)
916 return 0; 942 return 0;
917} 943}
918 944
919
920/*
921 * Create mixer for Electrix Ebox-44
922 *
923 * The mixer units from this device are corrupt, and even where they
924 * are valid they presents mono controls as L and R channels of
925 * stereo. So we create a good mixer in code.
926 */
927
928static int snd_ebox44_create_mixer(struct usb_mixer_interface *mixer)
929{
930 int err;
931
932 err = snd_create_std_mono_ctl(mixer, 4, 1, 0x0, USB_MIXER_INV_BOOLEAN,
933 "Headphone Playback Switch", NULL);
934 if (err < 0)
935 return err;
936 err = snd_create_std_mono_ctl(mixer, 4, 2, 0x1, USB_MIXER_S16,
937 "Headphone A Mix Playback Volume", NULL);
938 if (err < 0)
939 return err;
940 err = snd_create_std_mono_ctl(mixer, 4, 2, 0x2, USB_MIXER_S16,
941 "Headphone B Mix Playback Volume", NULL);
942 if (err < 0)
943 return err;
944
945 err = snd_create_std_mono_ctl(mixer, 7, 1, 0x0, USB_MIXER_INV_BOOLEAN,
946 "Output Playback Switch", NULL);
947 if (err < 0)
948 return err;
949 err = snd_create_std_mono_ctl(mixer, 7, 2, 0x1, USB_MIXER_S16,
950 "Output A Playback Volume", NULL);
951 if (err < 0)
952 return err;
953 err = snd_create_std_mono_ctl(mixer, 7, 2, 0x2, USB_MIXER_S16,
954 "Output B Playback Volume", NULL);
955 if (err < 0)
956 return err;
957
958 err = snd_create_std_mono_ctl(mixer, 10, 1, 0x0, USB_MIXER_INV_BOOLEAN,
959 "Input Capture Switch", NULL);
960 if (err < 0)
961 return err;
962 err = snd_create_std_mono_ctl(mixer, 10, 2, 0x1, USB_MIXER_S16,
963 "Input A Capture Volume", NULL);
964 if (err < 0)
965 return err;
966 err = snd_create_std_mono_ctl(mixer, 10, 2, 0x2, USB_MIXER_S16,
967 "Input B Capture Volume", NULL);
968 if (err < 0)
969 return err;
970
971 return 0;
972}
973
974void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, 945void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
975 unsigned char samplerate_id) 946 unsigned char samplerate_id)
976{ 947{
@@ -990,6 +961,81 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
990 } 961 }
991} 962}
992 963
964/*
965 * The mixer units for Ebox-44 are corrupt, and even where they
966 * are valid they presents mono controls as L and R channels of
967 * stereo. So we provide a good mixer here.
968 */
969struct std_mono_table ebox44_table[] = {
970 {
971 .unitid = 4,
972 .control = 1,
973 .cmask = 0x0,
974 .val_type = USB_MIXER_INV_BOOLEAN,
975 .name = "Headphone Playback Switch"
976 },
977 {
978 .unitid = 4,
979 .control = 2,
980 .cmask = 0x1,
981 .val_type = USB_MIXER_S16,
982 .name = "Headphone A Mix Playback Volume"
983 },
984 {
985 .unitid = 4,
986 .control = 2,
987 .cmask = 0x2,
988 .val_type = USB_MIXER_S16,
989 .name = "Headphone B Mix Playback Volume"
990 },
991
992 {
993 .unitid = 7,
994 .control = 1,
995 .cmask = 0x0,
996 .val_type = USB_MIXER_INV_BOOLEAN,
997 .name = "Output Playback Switch"
998 },
999 {
1000 .unitid = 7,
1001 .control = 2,
1002 .cmask = 0x1,
1003 .val_type = USB_MIXER_S16,
1004 .name = "Output A Playback Volume"
1005 },
1006 {
1007 .unitid = 7,
1008 .control = 2,
1009 .cmask = 0x2,
1010 .val_type = USB_MIXER_S16,
1011 .name = "Output B Playback Volume"
1012 },
1013
1014 {
1015 .unitid = 10,
1016 .control = 1,
1017 .cmask = 0x0,
1018 .val_type = USB_MIXER_INV_BOOLEAN,
1019 .name = "Input Capture Switch"
1020 },
1021 {
1022 .unitid = 10,
1023 .control = 2,
1024 .cmask = 0x1,
1025 .val_type = USB_MIXER_S16,
1026 .name = "Input A Capture Volume"
1027 },
1028 {
1029 .unitid = 10,
1030 .control = 2,
1031 .cmask = 0x2,
1032 .val_type = USB_MIXER_S16,
1033 .name = "Input B Capture Volume"
1034 },
1035
1036 {}
1037};
1038
993int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) 1039int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
994{ 1040{
995 int err = 0; 1041 int err = 0;
@@ -1035,7 +1081,8 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
1035 break; 1081 break;
1036 1082
1037 case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */ 1083 case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */
1038 err = snd_ebox44_create_mixer(mixer); 1084 /* detection is disabled in mixer_maps.c */
1085 err = snd_create_std_mono_table(mixer, ebox44_table);
1039 break; 1086 break;
1040 } 1087 }
1041 1088
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index a1298f379428..f782ce19bf5a 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -212,7 +212,7 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
212 } 212 }
213} 213}
214 214
215static int start_endpoints(struct snd_usb_substream *subs) 215static int start_endpoints(struct snd_usb_substream *subs, int can_sleep)
216{ 216{
217 int err; 217 int err;
218 218
@@ -225,7 +225,7 @@ static int start_endpoints(struct snd_usb_substream *subs)
225 snd_printdd(KERN_DEBUG "Starting data EP @%p\n", ep); 225 snd_printdd(KERN_DEBUG "Starting data EP @%p\n", ep);
226 226
227 ep->data_subs = subs; 227 ep->data_subs = subs;
228 err = snd_usb_endpoint_start(ep); 228 err = snd_usb_endpoint_start(ep, can_sleep);
229 if (err < 0) { 229 if (err < 0) {
230 clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags); 230 clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags);
231 return err; 231 return err;
@@ -236,10 +236,25 @@ static int start_endpoints(struct snd_usb_substream *subs)
236 !test_and_set_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags)) { 236 !test_and_set_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags)) {
237 struct snd_usb_endpoint *ep = subs->sync_endpoint; 237 struct snd_usb_endpoint *ep = subs->sync_endpoint;
238 238
239 if (subs->data_endpoint->iface != subs->sync_endpoint->iface ||
240 subs->data_endpoint->alt_idx != subs->sync_endpoint->alt_idx) {
241 err = usb_set_interface(subs->dev,
242 subs->sync_endpoint->iface,
243 subs->sync_endpoint->alt_idx);
244 if (err < 0) {
245 snd_printk(KERN_ERR
246 "%d:%d:%d: cannot set interface (%d)\n",
247 subs->dev->devnum,
248 subs->sync_endpoint->iface,
249 subs->sync_endpoint->alt_idx, err);
250 return -EIO;
251 }
252 }
253
239 snd_printdd(KERN_DEBUG "Starting sync EP @%p\n", ep); 254 snd_printdd(KERN_DEBUG "Starting sync EP @%p\n", ep);
240 255
241 ep->sync_slave = subs->data_endpoint; 256 ep->sync_slave = subs->data_endpoint;
242 err = snd_usb_endpoint_start(ep); 257 err = snd_usb_endpoint_start(ep, can_sleep);
243 if (err < 0) { 258 if (err < 0) {
244 clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags); 259 clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags);
245 return err; 260 return err;
@@ -547,7 +562,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
547 /* for playback, submit the URBs now; otherwise, the first hwptr_done 562 /* for playback, submit the URBs now; otherwise, the first hwptr_done
548 * updates for all URBs would happen at the same time when starting */ 563 * updates for all URBs would happen at the same time when starting */
549 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) 564 if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
550 return start_endpoints(subs); 565 return start_endpoints(subs, 1);
551 566
552 return 0; 567 return 0;
553} 568}
@@ -1029,6 +1044,7 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
1029 struct urb *urb) 1044 struct urb *urb)
1030{ 1045{
1031 struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; 1046 struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
1047 struct snd_usb_endpoint *ep = subs->data_endpoint;
1032 struct snd_urb_ctx *ctx = urb->context; 1048 struct snd_urb_ctx *ctx = urb->context;
1033 unsigned int counts, frames, bytes; 1049 unsigned int counts, frames, bytes;
1034 int i, stride, period_elapsed = 0; 1050 int i, stride, period_elapsed = 0;
@@ -1040,7 +1056,11 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
1040 urb->number_of_packets = 0; 1056 urb->number_of_packets = 0;
1041 spin_lock_irqsave(&subs->lock, flags); 1057 spin_lock_irqsave(&subs->lock, flags);
1042 for (i = 0; i < ctx->packets; i++) { 1058 for (i = 0; i < ctx->packets; i++) {
1043 counts = ctx->packet_size[i]; 1059 if (ctx->packet_size[i])
1060 counts = ctx->packet_size[i];
1061 else
1062 counts = snd_usb_endpoint_next_packet_size(ep);
1063
1044 /* set up descriptor */ 1064 /* set up descriptor */
1045 urb->iso_frame_desc[i].offset = frames * stride; 1065 urb->iso_frame_desc[i].offset = frames * stride;
1046 urb->iso_frame_desc[i].length = counts * stride; 1066 urb->iso_frame_desc[i].length = counts * stride;
@@ -1091,7 +1111,16 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
1091 subs->hwptr_done += bytes; 1111 subs->hwptr_done += bytes;
1092 if (subs->hwptr_done >= runtime->buffer_size * stride) 1112 if (subs->hwptr_done >= runtime->buffer_size * stride)
1093 subs->hwptr_done -= runtime->buffer_size * stride; 1113 subs->hwptr_done -= runtime->buffer_size * stride;
1114
1115 /* update delay with exact number of samples queued */
1116 runtime->delay = subs->last_delay;
1094 runtime->delay += frames; 1117 runtime->delay += frames;
1118 subs->last_delay = runtime->delay;
1119
1120 /* realign last_frame_number */
1121 subs->last_frame_number = usb_get_current_frame_number(subs->dev);
1122 subs->last_frame_number &= 0xFF; /* keep 8 LSBs */
1123
1095 spin_unlock_irqrestore(&subs->lock, flags); 1124 spin_unlock_irqrestore(&subs->lock, flags);
1096 urb->transfer_buffer_length = bytes; 1125 urb->transfer_buffer_length = bytes;
1097 if (period_elapsed) 1126 if (period_elapsed)
@@ -1109,12 +1138,32 @@ static void retire_playback_urb(struct snd_usb_substream *subs,
1109 struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; 1138 struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
1110 int stride = runtime->frame_bits >> 3; 1139 int stride = runtime->frame_bits >> 3;
1111 int processed = urb->transfer_buffer_length / stride; 1140 int processed = urb->transfer_buffer_length / stride;
1141 int est_delay;
1142
1143 /* ignore the delay accounting when procssed=0 is given, i.e.
1144 * silent payloads are procssed before handling the actual data
1145 */
1146 if (!processed)
1147 return;
1112 1148
1113 spin_lock_irqsave(&subs->lock, flags); 1149 spin_lock_irqsave(&subs->lock, flags);
1114 if (processed > runtime->delay) 1150 est_delay = snd_usb_pcm_delay(subs, runtime->rate);
1115 runtime->delay = 0; 1151 /* update delay with exact number of samples played */
1152 if (processed > subs->last_delay)
1153 subs->last_delay = 0;
1116 else 1154 else
1117 runtime->delay -= processed; 1155 subs->last_delay -= processed;
1156 runtime->delay = subs->last_delay;
1157
1158 /*
1159 * Report when delay estimate is off by more than 2ms.
1160 * The error should be lower than 2ms since the estimate relies
1161 * on two reads of a counter updated every ms.
1162 */
1163 if (abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2)
1164 snd_printk(KERN_DEBUG "delay: estimated %d, actual %d\n",
1165 est_delay, subs->last_delay);
1166
1118 spin_unlock_irqrestore(&subs->lock, flags); 1167 spin_unlock_irqrestore(&subs->lock, flags);
1119} 1168}
1120 1169
@@ -1172,7 +1221,7 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream
1172 1221
1173 switch (cmd) { 1222 switch (cmd) {
1174 case SNDRV_PCM_TRIGGER_START: 1223 case SNDRV_PCM_TRIGGER_START:
1175 err = start_endpoints(subs); 1224 err = start_endpoints(subs, 0);
1176 if (err < 0) 1225 if (err < 0)
1177 return err; 1226 return err;
1178 1227