aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-04 19:26:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-04 19:26:56 -0400
commit977dbfcf8e9ff1783355b260d93101af315de18a (patch)
treeb586ca678499d1ccc2d199a97d65996c630b25d8 /sound
parentaa7054f5a5a9ff728ce291cb103afa19f4f849eb (diff)
parentb054087dbacee30a9dddaef2c9a96312146be04e (diff)
Merge tag 'sound-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "Changes are seen in a wide range of codes, mainly due to ASoC DAPM requirements; HD-audio shows a high peak in diffstat, it's just a removal of bunch of old static quirks. Some highlights: - HDPM: Updates for AIO/RayDAT support, TCO/sync support - RME96: Add PCM sync support - HD-audio: * A few HDMI/DP audio updates (CA assignment fix, stream switching fix, Intel DP device list support) * Device specific fixes (ASUS/CXT HP mic support, Thinkpad mic improvements, Chromebook fixes, STAC9228 Dell fixes) * Replace the all static quirks for AD codecs with the generic parser * WAKEEN support for handling irqs in the power saving mode - USB-audio: Clean up implicit fb handling and related codes - DAPM is now mandatory for ASoC CODEC drivers; all existing drivers have had some level of DAPM support added. In addition, a lot of cleanups and improvements in DAPM. - Support for ASoC cross-platform compile test - New drivers and support for Analog Devices ADAU1702 and ADAU1401(a), Asahi Kasei Microdevices AK4554, Atmel AT91ASM9x5 and WM8904 based machines, Freescale S/PDIF and SSI AC'97, Renesas R-Car SoCs, Samsung Exynos5420 SoCs, Texas Instruments PCM1681 and PCM1792A and Wolfson Microelectronics WM8997 - DT bindings for kirkwood and i.MX S/PDIF - Clean up and bug fixes: ssm2602, rt5640 and sgtl5000. - Core helpers for bitbanged AC'97 reset" * tag 'sound-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (375 commits) ALSA: hda - Re-setup HDMI pin and audio infoframe on stream switches ALSA: hda - hdmi: Fallback to ALSA allocation when selecting CA ASoC: mxs-sgtl5000: Configure the dai_links as unidirectional ASoC: soc-pcm: Allow to specify unidirectional dai_link ASoC: fsl_spdif: Staticse non-exported symbols ASoC: ssm2602: Fix cache sync ASoC: Remove unused sysfs_registered field from snd_soc_codec struct ASoC: Remove unused debugfs_dapm field from snd_soc_{platform,codec} struct ASoC: Remove unused control_type field from snd_soc_codec struct ASoC: fsl: Add one blank space after ':=' in Makefile ASoC: fsl: Add wrapping for dev_dbg() in fsl_spdif.c ASoC: rt5640: change widget sequence for depop ASoC: dapm: Fix auto-disable for inverted controls ASoC: fsl: Drop SND_SOC_FSL_UTILS from SND_SOC_IMX_SPDIF ASoC: Samsung: Do not queue cyclic buffers multiple times ASoC: ep93xx-i2s: Remove unnecessary dev_set_drvdata() ASoC: designware_i2s: Remove unnecessary dev_set_drvdata() ASoC: fsl_spdif: remove redundant dev_err call in fsl_spdif_probe() ASoC: fsl: Add S/PDIF machine driver ASoc: kirkwood: Use the Kirkwood audio driver in Dove boards ...
Diffstat (limited to 'sound')
-rw-r--r--sound/arm/pxa2xx-ac97.c26
-rw-r--r--sound/arm/pxa2xx-pcm-lib.c52
-rw-r--r--sound/arm/pxa2xx-pcm.c5
-rw-r--r--sound/arm/pxa2xx-pcm.h6
-rw-r--r--sound/core/Kconfig3
-rw-r--r--sound/core/Makefile3
-rw-r--r--sound/core/pcm_dmaengine.c (renamed from sound/soc/soc-dmaengine-pcm.c)0
-rw-r--r--sound/core/pcm_lib.c4
-rw-r--r--sound/drivers/dummy.c2
-rw-r--r--sound/firewire/speakers.c4
-rw-r--r--sound/isa/gus/interwave.c3
-rw-r--r--sound/oss/dmabuf.c3
-rw-r--r--sound/pci/hda/Kconfig9
-rw-r--r--sound/pci/hda/hda_codec.c64
-rw-r--r--sound/pci/hda/hda_codec.h21
-rw-r--r--sound/pci/hda/hda_generic.c79
-rw-r--r--sound/pci/hda/hda_generic.h1
-rw-r--r--sound/pci/hda/hda_hwdep.c6
-rw-r--r--sound/pci/hda/hda_intel.c34
-rw-r--r--sound/pci/hda/hda_jack.c22
-rw-r--r--sound/pci/hda/hda_jack.h13
-rw-r--r--sound/pci/hda/hda_proc.c33
-rw-r--r--sound/pci/hda/patch_analog.c4528
-rw-r--r--sound/pci/hda/patch_conexant.c79
-rw-r--r--sound/pci/hda/patch_hdmi.c61
-rw-r--r--sound/pci/hda/patch_realtek.c190
-rw-r--r--sound/pci/hda/patch_sigmatel.c14
-rw-r--r--sound/pci/hda/patch_via.c2
-rw-r--r--sound/pci/rme96.c307
-rw-r--r--sound/pci/rme9652/hdspm.c779
-rw-r--r--sound/soc/Kconfig5
-rw-r--r--sound/soc/Makefile4
-rw-r--r--sound/soc/atmel/Kconfig21
-rw-r--r--sound/soc/atmel/Makefile4
-rw-r--r--sound/soc/atmel/atmel-pcm-dma.c118
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c36
-rw-r--r--sound/soc/atmel/atmel_wm8904.c254
-rw-r--r--sound/soc/atmel/sam9x5_wm8731.c208
-rw-r--r--sound/soc/au1x/db1200.c4
-rw-r--r--sound/soc/au1x/psc-ac97.c3
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.h1
-rw-r--r--sound/soc/cirrus/ep93xx-ac97.c3
-rw-r--r--sound/soc/cirrus/ep93xx-i2s.c5
-rw-r--r--sound/soc/codecs/Kconfig19
-rw-r--r--sound/soc/codecs/Makefile8
-rw-r--r--sound/soc/codecs/ac97.c15
-rw-r--r--sound/soc/codecs/ad1980.c43
-rw-r--r--sound/soc/codecs/ad73311.c22
-rw-r--r--sound/soc/codecs/adau1701.c25
-rw-r--r--sound/soc/codecs/adav80x.c13
-rw-r--r--sound/soc/codecs/ads117x.c29
-rw-r--r--sound/soc/codecs/ak4104.c34
-rw-r--r--sound/soc/codecs/ak4554.c106
-rw-r--r--sound/soc/codecs/ak5386.c17
-rw-r--r--sound/soc/codecs/arizona.c69
-rw-r--r--sound/soc/codecs/arizona.h5
-rw-r--r--sound/soc/codecs/bt-sco.c22
-rw-r--r--sound/soc/codecs/cs4270.c20
-rw-r--r--sound/soc/codecs/cs4271.c30
-rw-r--r--sound/soc/codecs/dmic.c17
-rw-r--r--sound/soc/codecs/hdmi.c30
-rw-r--r--sound/soc/codecs/lm4857.c107
-rw-r--r--sound/soc/codecs/max9768.c16
-rw-r--r--sound/soc/codecs/max98090.c10
-rw-r--r--sound/soc/codecs/max9877.c294
-rw-r--r--sound/soc/codecs/mc13783.c1
-rw-r--r--sound/soc/codecs/pcm1681.c339
-rw-r--r--sound/soc/codecs/pcm1792a.c257
-rw-r--r--sound/soc/codecs/pcm1792a.h26
-rw-r--r--sound/soc/codecs/pcm3008.c150
-rw-r--r--sound/soc/codecs/rt5640.c235
-rw-r--r--sound/soc/codecs/rt5640.h12
-rw-r--r--sound/soc/codecs/sgtl5000.c10
-rw-r--r--sound/soc/codecs/si476x.c14
-rw-r--r--sound/soc/codecs/spdif_receiver.c17
-rw-r--r--sound/soc/codecs/spdif_transmitter.c18
-rw-r--r--sound/soc/codecs/ssm2602.c3
-rw-r--r--sound/soc/codecs/sta32x.c10
-rw-r--r--sound/soc/codecs/tlv320aic26.c51
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c22
-rw-r--r--sound/soc/codecs/tlv320aic3x.c56
-rw-r--r--sound/soc/codecs/twl4030.c2
-rw-r--r--sound/soc/codecs/twl6040.c7
-rw-r--r--sound/soc/codecs/uda134x.c88
-rw-r--r--sound/soc/codecs/wl1273.c17
-rw-r--r--sound/soc/codecs/wm0010.c12
-rw-r--r--sound/soc/codecs/wm5102.c53
-rw-r--r--sound/soc/codecs/wm5110.c35
-rw-r--r--sound/soc/codecs/wm8350.c6
-rw-r--r--sound/soc/codecs/wm8727.c17
-rw-r--r--sound/soc/codecs/wm8731.c60
-rw-r--r--sound/soc/codecs/wm8753.c5
-rw-r--r--sound/soc/codecs/wm8782.c17
-rw-r--r--sound/soc/codecs/wm8903.c4
-rw-r--r--sound/soc/codecs/wm8904.c3
-rw-r--r--sound/soc/codecs/wm8960.c10
-rw-r--r--sound/soc/codecs/wm8962.c9
-rw-r--r--sound/soc/codecs/wm8994.c39
-rw-r--r--sound/soc/codecs/wm8995.c5
-rw-r--r--sound/soc/codecs/wm8997.c1175
-rw-r--r--sound/soc/codecs/wm8997.h23
-rw-r--r--sound/soc/codecs/wm_adsp.c124
-rw-r--r--sound/soc/codecs/wm_adsp.h3
-rw-r--r--sound/soc/codecs/wm_hubs.c8
-rw-r--r--sound/soc/dwc/designware_i2s.c5
-rw-r--r--sound/soc/fsl/Kconfig23
-rw-r--r--sound/soc/fsl/Makefile4
-rw-r--r--sound/soc/fsl/fsl_spdif.c1225
-rw-r--r--sound/soc/fsl/fsl_spdif.h191
-rw-r--r--sound/soc/fsl/fsl_ssi.c501
-rw-r--r--sound/soc/fsl/imx-audmux.c78
-rw-r--r--sound/soc/fsl/imx-audmux.h52
-rw-r--r--sound/soc/fsl/imx-mc13783.c1
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c4
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c20
-rw-r--r--sound/soc/fsl/imx-pcm.h26
-rw-r--r--sound/soc/fsl/imx-sgtl5000.c4
-rw-r--r--sound/soc/fsl/imx-spdif.c148
-rw-r--r--sound/soc/fsl/imx-ssi.c11
-rw-r--r--sound/soc/fsl/imx-ssi.h1
-rw-r--r--sound/soc/fsl/imx-wm8962.c3
-rw-r--r--sound/soc/generic/simple-card.c2
-rw-r--r--sound/soc/kirkwood/Kconfig13
-rw-r--r--sound/soc/kirkwood/Makefile4
-rw-r--r--sound/soc/kirkwood/kirkwood-dma.c108
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c93
-rw-r--r--sound/soc/kirkwood/kirkwood-openrd.c6
-rw-r--r--sound/soc/kirkwood/kirkwood-t5325.c6
-rw-r--r--sound/soc/kirkwood/kirkwood.h11
-rw-r--r--sound/soc/mxs/Kconfig3
-rw-r--r--sound/soc/mxs/mxs-saif.c1
-rw-r--r--sound/soc/mxs/mxs-sgtl5000.c32
-rw-r--r--sound/soc/nuc900/nuc900-ac97.c3
-rw-r--r--sound/soc/omap/Kconfig8
-rw-r--r--sound/soc/omap/mcbsp.c2
-rw-r--r--sound/soc/omap/omap-abe-twl6040.c133
-rw-r--r--sound/soc/omap/omap-dmic.c9
-rw-r--r--sound/soc/omap/omap-mcbsp.c5
-rw-r--r--sound/soc/omap/omap-mcpdm.c3
-rw-r--r--sound/soc/pxa/Kconfig2
-rw-r--r--sound/soc/pxa/brownstone.c1
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c7
-rw-r--r--sound/soc/pxa/mmp-pcm.c7
-rw-r--r--sound/soc/pxa/mmp-sspa.c15
-rw-r--r--sound/soc/pxa/pxa-ssp.c76
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c67
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c28
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c21
-rw-r--r--sound/soc/pxa/ttc-dkb.c1
-rw-r--r--sound/soc/s6000/s6105-ipcam.c2
-rw-r--r--sound/soc/samsung/ac97.c11
-rw-r--r--sound/soc/samsung/dma.c19
-rw-r--r--sound/soc/samsung/dma.h4
-rw-r--r--sound/soc/samsung/i2s-regs.h51
-rw-r--r--sound/soc/samsung/i2s.c193
-rw-r--r--sound/soc/samsung/pcm.c4
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c4
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c4
-rw-r--r--sound/soc/samsung/smdk_wm8994.c58
-rw-r--r--sound/soc/samsung/spdif.c12
-rw-r--r--sound/soc/sh/Kconfig7
-rw-r--r--sound/soc/sh/Makefile3
-rw-r--r--sound/soc/sh/fsi.c51
-rw-r--r--sound/soc/sh/rcar/Makefile2
-rw-r--r--sound/soc/sh/rcar/adg.c234
-rw-r--r--sound/soc/sh/rcar/core.c861
-rw-r--r--sound/soc/sh/rcar/gen.c280
-rw-r--r--sound/soc/sh/rcar/rsnd.h302
-rw-r--r--sound/soc/sh/rcar/scu.c236
-rw-r--r--sound/soc/sh/rcar/ssi.c728
-rw-r--r--sound/soc/soc-compress.c13
-rw-r--r--sound/soc/soc-core.c253
-rw-r--r--sound/soc/soc-dapm.c819
-rw-r--r--sound/soc/soc-jack.c4
-rw-r--r--sound/soc/soc-pcm.c25
-rw-r--r--sound/soc/spear/Kconfig2
-rw-r--r--sound/soc/tegra/Kconfig14
-rw-r--r--sound/soc/tegra/tegra20_ac97.c8
-rw-r--r--sound/soc/tegra/tegra_alc5632.c2
-rw-r--r--sound/soc/tegra/tegra_rt5640.c1
-rw-r--r--sound/soc/tegra/tegra_wm8753.c2
-rw-r--r--sound/soc/tegra/trimslice.c2
-rw-r--r--sound/soc/txx9/txx9aclc-ac97.c3
-rw-r--r--sound/soc/ux500/mop500.c1
-rw-r--r--sound/usb/6fire/firmware.c4
-rw-r--r--sound/usb/endpoint.c3
-rw-r--r--sound/usb/pcm.c243
-rw-r--r--sound/usb/usx2y/usbusx2y.c8
188 files changed, 11349 insertions, 7001 deletions
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index ce431e6e07cf..5066a3768b28 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -14,12 +14,14 @@
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/dmaengine.h>
17 18
18#include <sound/core.h> 19#include <sound/core.h>
19#include <sound/pcm.h> 20#include <sound/pcm.h>
20#include <sound/ac97_codec.h> 21#include <sound/ac97_codec.h>
21#include <sound/initval.h> 22#include <sound/initval.h>
22#include <sound/pxa2xx-lib.h> 23#include <sound/pxa2xx-lib.h>
24#include <sound/dmaengine_pcm.h>
23 25
24#include <mach/regs-ac97.h> 26#include <mach/regs-ac97.h>
25#include <mach/audio.h> 27#include <mach/audio.h>
@@ -41,20 +43,20 @@ static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
41 .reset = pxa2xx_ac97_reset, 43 .reset = pxa2xx_ac97_reset,
42}; 44};
43 45
44static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = { 46static unsigned long pxa2xx_ac97_pcm_out_req = 12;
45 .name = "AC97 PCM out", 47static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_out = {
46 .dev_addr = __PREG(PCDR), 48 .addr = __PREG(PCDR),
47 .drcmr = &DRCMR(12), 49 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
48 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | 50 .maxburst = 32,
49 DCMD_BURST32 | DCMD_WIDTH4, 51 .filter_data = &pxa2xx_ac97_pcm_out_req,
50}; 52};
51 53
52static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_in = { 54static unsigned long pxa2xx_ac97_pcm_in_req = 11;
53 .name = "AC97 PCM in", 55static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_in = {
54 .dev_addr = __PREG(PCDR), 56 .addr = __PREG(PCDR),
55 .drcmr = &DRCMR(11), 57 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
56 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 58 .maxburst = 32,
57 DCMD_BURST32 | DCMD_WIDTH4, 59 .filter_data = &pxa2xx_ac97_pcm_in_req,
58}; 60};
59 61
60static struct snd_pcm *pxa2xx_ac97_pcm; 62static struct snd_pcm *pxa2xx_ac97_pcm;
diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c
index 823359ed95e1..a61d7a9a995e 100644
--- a/sound/arm/pxa2xx-pcm-lib.c
+++ b/sound/arm/pxa2xx-pcm-lib.c
@@ -7,11 +7,13 @@
7#include <linux/slab.h> 7#include <linux/slab.h>
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/dma-mapping.h> 9#include <linux/dma-mapping.h>
10#include <linux/dmaengine.h>
10 11
11#include <sound/core.h> 12#include <sound/core.h>
12#include <sound/pcm.h> 13#include <sound/pcm.h>
13#include <sound/pcm_params.h> 14#include <sound/pcm_params.h>
14#include <sound/pxa2xx-lib.h> 15#include <sound/pxa2xx-lib.h>
16#include <sound/dmaengine_pcm.h>
15 17
16#include <mach/dma.h> 18#include <mach/dma.h>
17 19
@@ -43,6 +45,35 @@ int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
43 size_t period = params_period_bytes(params); 45 size_t period = params_period_bytes(params);
44 pxa_dma_desc *dma_desc; 46 pxa_dma_desc *dma_desc;
45 dma_addr_t dma_buff_phys, next_desc_phys; 47 dma_addr_t dma_buff_phys, next_desc_phys;
48 u32 dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG;
49
50 /* temporary transition hack */
51 switch (rtd->params->addr_width) {
52 case DMA_SLAVE_BUSWIDTH_1_BYTE:
53 dcmd |= DCMD_WIDTH1;
54 break;
55 case DMA_SLAVE_BUSWIDTH_2_BYTES:
56 dcmd |= DCMD_WIDTH2;
57 break;
58 case DMA_SLAVE_BUSWIDTH_4_BYTES:
59 dcmd |= DCMD_WIDTH4;
60 break;
61 default:
62 /* can't happen */
63 break;
64 }
65
66 switch (rtd->params->maxburst) {
67 case 8:
68 dcmd |= DCMD_BURST8;
69 break;
70 case 16:
71 dcmd |= DCMD_BURST16;
72 break;
73 case 32:
74 dcmd |= DCMD_BURST32;
75 break;
76 }
46 77
47 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 78 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
48 runtime->dma_bytes = totsize; 79 runtime->dma_bytes = totsize;
@@ -55,14 +86,14 @@ int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
55 dma_desc->ddadr = next_desc_phys; 86 dma_desc->ddadr = next_desc_phys;
56 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 87 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
57 dma_desc->dsadr = dma_buff_phys; 88 dma_desc->dsadr = dma_buff_phys;
58 dma_desc->dtadr = rtd->params->dev_addr; 89 dma_desc->dtadr = rtd->params->addr;
59 } else { 90 } else {
60 dma_desc->dsadr = rtd->params->dev_addr; 91 dma_desc->dsadr = rtd->params->addr;
61 dma_desc->dtadr = dma_buff_phys; 92 dma_desc->dtadr = dma_buff_phys;
62 } 93 }
63 if (period > totsize) 94 if (period > totsize)
64 period = totsize; 95 period = totsize;
65 dma_desc->dcmd = rtd->params->dcmd | period | DCMD_ENDIRQEN; 96 dma_desc->dcmd = dcmd | period | DCMD_ENDIRQEN;
66 dma_desc++; 97 dma_desc++;
67 dma_buff_phys += period; 98 dma_buff_phys += period;
68 } while (totsize -= period); 99 } while (totsize -= period);
@@ -76,8 +107,10 @@ int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
76{ 107{
77 struct pxa2xx_runtime_data *rtd = substream->runtime->private_data; 108 struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
78 109
79 if (rtd && rtd->params && rtd->params->drcmr) 110 if (rtd && rtd->params && rtd->params->filter_data) {
80 *rtd->params->drcmr = 0; 111 unsigned long req = *(unsigned long *) rtd->params->filter_data;
112 DRCMR(req) = 0;
113 }
81 114
82 snd_pcm_set_runtime_buffer(substream, NULL); 115 snd_pcm_set_runtime_buffer(substream, NULL);
83 return 0; 116 return 0;
@@ -136,6 +169,7 @@ EXPORT_SYMBOL(pxa2xx_pcm_pointer);
136int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream) 169int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
137{ 170{
138 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; 171 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
172 unsigned long req;
139 173
140 if (!prtd || !prtd->params) 174 if (!prtd || !prtd->params)
141 return 0; 175 return 0;
@@ -146,7 +180,8 @@ int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
146 DCSR(prtd->dma_ch) &= ~DCSR_RUN; 180 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
147 DCSR(prtd->dma_ch) = 0; 181 DCSR(prtd->dma_ch) = 0;
148 DCMD(prtd->dma_ch) = 0; 182 DCMD(prtd->dma_ch) = 0;
149 *prtd->params->drcmr = prtd->dma_ch | DRCMR_MAPVLD; 183 req = *(unsigned long *) prtd->params->filter_data;
184 DRCMR(req) = prtd->dma_ch | DRCMR_MAPVLD;
150 185
151 return 0; 186 return 0;
152} 187}
@@ -155,7 +190,6 @@ EXPORT_SYMBOL(__pxa2xx_pcm_prepare);
155void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id) 190void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
156{ 191{
157 struct snd_pcm_substream *substream = dev_id; 192 struct snd_pcm_substream *substream = dev_id;
158 struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
159 int dcsr; 193 int dcsr;
160 194
161 dcsr = DCSR(dma_ch); 195 dcsr = DCSR(dma_ch);
@@ -164,8 +198,8 @@ void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
164 if (dcsr & DCSR_ENDINTR) { 198 if (dcsr & DCSR_ENDINTR) {
165 snd_pcm_period_elapsed(substream); 199 snd_pcm_period_elapsed(substream);
166 } else { 200 } else {
167 printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n", 201 printk(KERN_ERR "DMA error on channel %d (DCSR=%#x)\n",
168 rtd->params->name, dma_ch, dcsr); 202 dma_ch, dcsr);
169 snd_pcm_stream_lock(substream); 203 snd_pcm_stream_lock(substream);
170 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); 204 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
171 snd_pcm_stream_unlock(substream); 205 snd_pcm_stream_unlock(substream);
diff --git a/sound/arm/pxa2xx-pcm.c b/sound/arm/pxa2xx-pcm.c
index 26422a3584ea..69a2455b4472 100644
--- a/sound/arm/pxa2xx-pcm.c
+++ b/sound/arm/pxa2xx-pcm.c
@@ -11,8 +11,11 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/dmaengine.h>
15
14#include <sound/core.h> 16#include <sound/core.h>
15#include <sound/pxa2xx-lib.h> 17#include <sound/pxa2xx-lib.h>
18#include <sound/dmaengine_pcm.h>
16 19
17#include "pxa2xx-pcm.h" 20#include "pxa2xx-pcm.h"
18 21
@@ -40,7 +43,7 @@ static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
40 43
41 rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 44 rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
42 client->playback_params : client->capture_params; 45 client->playback_params : client->capture_params;
43 ret = pxa_request_dma(rtd->params->name, DMA_PRIO_LOW, 46 ret = pxa_request_dma("dma", DMA_PRIO_LOW,
44 pxa2xx_pcm_dma_irq, substream); 47 pxa2xx_pcm_dma_irq, substream);
45 if (ret < 0) 48 if (ret < 0)
46 goto err2; 49 goto err2;
diff --git a/sound/arm/pxa2xx-pcm.h b/sound/arm/pxa2xx-pcm.h
index 65f86b56ba42..2a8fc08d52a1 100644
--- a/sound/arm/pxa2xx-pcm.h
+++ b/sound/arm/pxa2xx-pcm.h
@@ -13,14 +13,14 @@
13 13
14struct pxa2xx_runtime_data { 14struct pxa2xx_runtime_data {
15 int dma_ch; 15 int dma_ch;
16 struct pxa2xx_pcm_dma_params *params; 16 struct snd_dmaengine_dai_dma_data *params;
17 pxa_dma_desc *dma_desc_array; 17 pxa_dma_desc *dma_desc_array;
18 dma_addr_t dma_desc_array_phys; 18 dma_addr_t dma_desc_array_phys;
19}; 19};
20 20
21struct pxa2xx_pcm_client { 21struct pxa2xx_pcm_client {
22 struct pxa2xx_pcm_dma_params *playback_params; 22 struct snd_dmaengine_dai_dma_data *playback_params;
23 struct pxa2xx_pcm_dma_params *capture_params; 23 struct snd_dmaengine_dai_dma_data *capture_params;
24 int (*startup)(struct snd_pcm_substream *); 24 int (*startup)(struct snd_pcm_substream *);
25 void (*shutdown)(struct snd_pcm_substream *); 25 void (*shutdown)(struct snd_pcm_substream *);
26 int (*prepare)(struct snd_pcm_substream *); 26 int (*prepare)(struct snd_pcm_substream *);
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index c0c2f57a0d6f..313f22e9d929 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -6,6 +6,9 @@ config SND_PCM
6 tristate 6 tristate
7 select SND_TIMER 7 select SND_TIMER
8 8
9config SND_DMAENGINE_PCM
10 tristate
11
9config SND_HWDEP 12config SND_HWDEP
10 tristate 13 tristate
11 14
diff --git a/sound/core/Makefile b/sound/core/Makefile
index 43d4117428ac..5e890cfed423 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -13,6 +13,8 @@ snd-$(CONFIG_SND_JACK) += jack.o
13snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \ 13snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
14 pcm_memory.o 14 pcm_memory.o
15 15
16snd-pcm-dmaengine-objs := pcm_dmaengine.o
17
16snd-page-alloc-y := memalloc.o 18snd-page-alloc-y := memalloc.o
17snd-page-alloc-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o 19snd-page-alloc-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o
18 20
@@ -30,6 +32,7 @@ obj-$(CONFIG_SND_TIMER) += snd-timer.o
30obj-$(CONFIG_SND_HRTIMER) += snd-hrtimer.o 32obj-$(CONFIG_SND_HRTIMER) += snd-hrtimer.o
31obj-$(CONFIG_SND_RTCTIMER) += snd-rtctimer.o 33obj-$(CONFIG_SND_RTCTIMER) += snd-rtctimer.o
32obj-$(CONFIG_SND_PCM) += snd-pcm.o snd-page-alloc.o 34obj-$(CONFIG_SND_PCM) += snd-pcm.o snd-page-alloc.o
35obj-$(CONFIG_SND_DMAENGINE_PCM) += snd-pcm-dmaengine.o
33obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o 36obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o
34 37
35obj-$(CONFIG_SND_OSSEMUL) += oss/ 38obj-$(CONFIG_SND_OSSEMUL) += oss/
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/core/pcm_dmaengine.c
index aa924d9b7986..aa924d9b7986 100644
--- a/sound/soc/soc-dmaengine-pcm.c
+++ b/sound/core/pcm_dmaengine.c
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 82bb029d4414..6e03b465e44e 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -184,7 +184,7 @@ static void xrun(struct snd_pcm_substream *substream)
184 do { \ 184 do { \
185 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \ 185 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \
186 xrun_log_show(substream); \ 186 xrun_log_show(substream); \
187 if (printk_ratelimit()) { \ 187 if (snd_printd_ratelimit()) { \
188 snd_printd("PCM: " fmt, ##args); \ 188 snd_printd("PCM: " fmt, ##args); \
189 } \ 189 } \
190 dump_stack_on_xrun(substream); \ 190 dump_stack_on_xrun(substream); \
@@ -342,7 +342,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
342 return -EPIPE; 342 return -EPIPE;
343 } 343 }
344 if (pos >= runtime->buffer_size) { 344 if (pos >= runtime->buffer_size) {
345 if (printk_ratelimit()) { 345 if (snd_printd_ratelimit()) {
346 char name[16]; 346 char name[16];
347 snd_pcm_debug_name(substream, name, sizeof(name)); 347 snd_pcm_debug_name(substream, name, sizeof(name));
348 xrun_log_show(substream); 348 xrun_log_show(substream);
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 11048cc744d0..915b4d7fbb23 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -1022,7 +1022,7 @@ static void dummy_proc_write(struct snd_info_entry *entry,
1022 if (i >= ARRAY_SIZE(fields)) 1022 if (i >= ARRAY_SIZE(fields))
1023 continue; 1023 continue;
1024 snd_info_get_str(item, ptr, sizeof(item)); 1024 snd_info_get_str(item, ptr, sizeof(item));
1025 if (strict_strtoull(item, 0, &val)) 1025 if (kstrtoull(item, 0, &val))
1026 continue; 1026 continue;
1027 if (fields[i].size == sizeof(int)) 1027 if (fields[i].size == sizeof(int))
1028 *get_dummy_int_ptr(dummy, fields[i].offset) = val; 1028 *get_dummy_int_ptr(dummy, fields[i].offset) = val;
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c
index 2c6386503940..fe9e6e2f2c5b 100644
--- a/sound/firewire/speakers.c
+++ b/sound/firewire/speakers.c
@@ -49,7 +49,6 @@ struct fwspk {
49 struct snd_card *card; 49 struct snd_card *card;
50 struct fw_unit *unit; 50 struct fw_unit *unit;
51 const struct device_info *device_info; 51 const struct device_info *device_info;
52 struct snd_pcm_substream *pcm;
53 struct mutex mutex; 52 struct mutex mutex;
54 struct cmp_connection connection; 53 struct cmp_connection connection;
55 struct amdtp_out_stream stream; 54 struct amdtp_out_stream stream;
@@ -363,8 +362,7 @@ static int fwspk_create_pcm(struct fwspk *fwspk)
363 return err; 362 return err;
364 pcm->private_data = fwspk; 363 pcm->private_data = fwspk;
365 strcpy(pcm->name, fwspk->device_info->short_name); 364 strcpy(pcm->name, fwspk->device_info->short_name);
366 fwspk->pcm = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 365 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ops);
367 fwspk->pcm->ops = &ops;
368 return 0; 366 return 0;
369} 367}
370 368
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 9942691cc0ca..afef0d738078 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -443,8 +443,7 @@ static void snd_interwave_detect_memory(struct snd_gus_card *gus)
443 for (i = 0; i < 8; ++i) 443 for (i = 0; i < 8; ++i)
444 iwave[i] = snd_gf1_peek(gus, bank_pos + i); 444 iwave[i] = snd_gf1_peek(gus, bank_pos + i);
445#ifdef CONFIG_SND_DEBUG_ROM 445#ifdef CONFIG_SND_DEBUG_ROM
446 printk(KERN_DEBUG "ROM at 0x%06x = %*phC\n", bank_pos, 446 printk(KERN_DEBUG "ROM at 0x%06x = %8phC\n", bank_pos, iwave);
447 8, iwave);
448#endif 447#endif
449 if (strncmp(iwave, "INTRWAVE", 8)) 448 if (strncmp(iwave, "INTRWAVE", 8))
450 continue; /* first check */ 449 continue; /* first check */
diff --git a/sound/oss/dmabuf.c b/sound/oss/dmabuf.c
index a59c88818f48..461d94cfecbe 100644
--- a/sound/oss/dmabuf.c
+++ b/sound/oss/dmabuf.c
@@ -557,7 +557,6 @@ int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
557 unsigned long flags; 557 unsigned long flags;
558 int err = 0, n = 0; 558 int err = 0, n = 0;
559 struct dma_buffparms *dmap = adev->dmap_in; 559 struct dma_buffparms *dmap = adev->dmap_in;
560 int go;
561 560
562 if (!(adev->open_mode & OPEN_READ)) 561 if (!(adev->open_mode & OPEN_READ))
563 return -EIO; 562 return -EIO;
@@ -584,7 +583,7 @@ int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
584 spin_unlock_irqrestore(&dmap->lock,flags); 583 spin_unlock_irqrestore(&dmap->lock,flags);
585 return -EAGAIN; 584 return -EAGAIN;
586 } 585 }
587 if ((go = adev->go)) 586 if (adev->go)
588 timeout = dmabuf_timeout(dmap); 587 timeout = dmabuf_timeout(dmap);
589 588
590 spin_unlock_irqrestore(&dmap->lock,flags); 589 spin_unlock_irqrestore(&dmap->lock,flags);
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 59c5e9c03d53..8de66ccd7279 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -152,14 +152,9 @@ config SND_HDA_CODEC_HDMI
152 This module is automatically loaded at probing. 152 This module is automatically loaded at probing.
153 153
154config SND_HDA_I915 154config SND_HDA_I915
155 bool "Build Display HD-audio controller/codec power well support for i915 cards" 155 bool
156 default y
156 depends on DRM_I915 157 depends on DRM_I915
157 help
158 Say Y here to include full HDMI and DisplayPort HD-audio controller/codec
159 power-well support for Intel Haswell graphics cards based on the i915 driver.
160
161 Note that this option must be enabled for Intel Haswell C+ stepping machines, otherwise
162 the GPU audio controller/codecs will not be initialized or damaged when exit from S3 mode.
163 158
164config SND_HDA_CODEC_CIRRUS 159config SND_HDA_CODEC_CIRRUS
165 bool "Build Cirrus Logic codec support" 160 bool "Build Cirrus Logic codec support"
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 8a005f0e5ca4..5b6c4e3c92ca 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -666,6 +666,64 @@ int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
666} 666}
667EXPORT_SYMBOL_HDA(snd_hda_get_conn_index); 667EXPORT_SYMBOL_HDA(snd_hda_get_conn_index);
668 668
669
670/* return DEVLIST_LEN parameter of the given widget */
671static unsigned int get_num_devices(struct hda_codec *codec, hda_nid_t nid)
672{
673 unsigned int wcaps = get_wcaps(codec, nid);
674 unsigned int parm;
675
676 if (!codec->dp_mst || !(wcaps & AC_WCAP_DIGITAL) ||
677 get_wcaps_type(wcaps) != AC_WID_PIN)
678 return 0;
679
680 parm = snd_hda_param_read(codec, nid, AC_PAR_DEVLIST_LEN);
681 if (parm == -1 && codec->bus->rirb_error)
682 parm = 0;
683 return parm & AC_DEV_LIST_LEN_MASK;
684}
685
686/**
687 * snd_hda_get_devices - copy device list without cache
688 * @codec: the HDA codec
689 * @nid: NID of the pin to parse
690 * @dev_list: device list array
691 * @max_devices: max. number of devices to store
692 *
693 * Copy the device list. This info is dynamic and so not cached.
694 * Currently called only from hda_proc.c, so not exported.
695 */
696int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
697 u8 *dev_list, int max_devices)
698{
699 unsigned int parm;
700 int i, dev_len, devices;
701
702 parm = get_num_devices(codec, nid);
703 if (!parm) /* not multi-stream capable */
704 return 0;
705
706 dev_len = parm + 1;
707 dev_len = dev_len < max_devices ? dev_len : max_devices;
708
709 devices = 0;
710 while (devices < dev_len) {
711 parm = snd_hda_codec_read(codec, nid, 0,
712 AC_VERB_GET_DEVICE_LIST, devices);
713 if (parm == -1 && codec->bus->rirb_error)
714 break;
715
716 for (i = 0; i < 8; i++) {
717 dev_list[devices] = (u8)parm;
718 parm >>= 4;
719 devices++;
720 if (devices >= dev_len)
721 break;
722 }
723 }
724 return devices;
725}
726
669/** 727/**
670 * snd_hda_queue_unsol_event - add an unsolicited event to queue 728 * snd_hda_queue_unsol_event - add an unsolicited event to queue
671 * @bus: the BUS 729 * @bus: the BUS
@@ -1216,11 +1274,13 @@ static void hda_jackpoll_work(struct work_struct *work)
1216{ 1274{
1217 struct hda_codec *codec = 1275 struct hda_codec *codec =
1218 container_of(work, struct hda_codec, jackpoll_work.work); 1276 container_of(work, struct hda_codec, jackpoll_work.work);
1219 if (!codec->jackpoll_interval)
1220 return;
1221 1277
1222 snd_hda_jack_set_dirty_all(codec); 1278 snd_hda_jack_set_dirty_all(codec);
1223 snd_hda_jack_poll_all(codec); 1279 snd_hda_jack_poll_all(codec);
1280
1281 if (!codec->jackpoll_interval)
1282 return;
1283
1224 queue_delayed_work(codec->bus->workq, &codec->jackpoll_work, 1284 queue_delayed_work(codec->bus->workq, &codec->jackpoll_work,
1225 codec->jackpoll_interval); 1285 codec->jackpoll_interval);
1226} 1286}
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 701c2e069b10..7aa9870040c1 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -94,6 +94,8 @@ enum {
94#define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32 94#define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32
95#define AC_VERB_GET_HDMI_CP_CTRL 0x0f33 95#define AC_VERB_GET_HDMI_CP_CTRL 0x0f33
96#define AC_VERB_GET_HDMI_CHAN_SLOT 0x0f34 96#define AC_VERB_GET_HDMI_CHAN_SLOT 0x0f34
97#define AC_VERB_GET_DEVICE_SEL 0xf35
98#define AC_VERB_GET_DEVICE_LIST 0xf36
97 99
98/* 100/*
99 * SET verbs 101 * SET verbs
@@ -133,6 +135,7 @@ enum {
133#define AC_VERB_SET_HDMI_DIP_XMIT 0x732 135#define AC_VERB_SET_HDMI_DIP_XMIT 0x732
134#define AC_VERB_SET_HDMI_CP_CTRL 0x733 136#define AC_VERB_SET_HDMI_CP_CTRL 0x733
135#define AC_VERB_SET_HDMI_CHAN_SLOT 0x734 137#define AC_VERB_SET_HDMI_CHAN_SLOT 0x734
138#define AC_VERB_SET_DEVICE_SEL 0x735
136 139
137/* 140/*
138 * Parameter IDs 141 * Parameter IDs
@@ -154,6 +157,7 @@ enum {
154#define AC_PAR_GPIO_CAP 0x11 157#define AC_PAR_GPIO_CAP 0x11
155#define AC_PAR_AMP_OUT_CAP 0x12 158#define AC_PAR_AMP_OUT_CAP 0x12
156#define AC_PAR_VOL_KNB_CAP 0x13 159#define AC_PAR_VOL_KNB_CAP 0x13
160#define AC_PAR_DEVLIST_LEN 0x15
157#define AC_PAR_HDMI_LPCM_CAP 0x20 161#define AC_PAR_HDMI_LPCM_CAP 0x20
158 162
159/* 163/*
@@ -251,6 +255,11 @@ enum {
251#define AC_UNSOL_RES_TAG_SHIFT 26 255#define AC_UNSOL_RES_TAG_SHIFT 26
252#define AC_UNSOL_RES_SUBTAG (0x1f<<21) 256#define AC_UNSOL_RES_SUBTAG (0x1f<<21)
253#define AC_UNSOL_RES_SUBTAG_SHIFT 21 257#define AC_UNSOL_RES_SUBTAG_SHIFT 21
258#define AC_UNSOL_RES_DE (0x3f<<15) /* Device Entry
259 * (for DP1.2 MST)
260 */
261#define AC_UNSOL_RES_DE_SHIFT 15
262#define AC_UNSOL_RES_IA (1<<2) /* Inactive (for DP1.2 MST) */
254#define AC_UNSOL_RES_ELDV (1<<1) /* ELD Data valid (for HDMI) */ 263#define AC_UNSOL_RES_ELDV (1<<1) /* ELD Data valid (for HDMI) */
255#define AC_UNSOL_RES_PD (1<<0) /* pinsense detect */ 264#define AC_UNSOL_RES_PD (1<<0) /* pinsense detect */
256#define AC_UNSOL_RES_CP_STATE (1<<1) /* content protection */ 265#define AC_UNSOL_RES_CP_STATE (1<<1) /* content protection */
@@ -352,6 +361,10 @@ enum {
352#define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */ 361#define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */
353#define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */ 362#define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */
354 363
364/* Display pin's device list length */
365#define AC_DEV_LIST_LEN_MASK 0x3f
366#define AC_MAX_DEV_LIST_LEN 64
367
355/* 368/*
356 * Control Parameters 369 * Control Parameters
357 */ 370 */
@@ -460,6 +473,11 @@ enum {
460#define AC_DEFCFG_PORT_CONN (0x3<<30) 473#define AC_DEFCFG_PORT_CONN (0x3<<30)
461#define AC_DEFCFG_PORT_CONN_SHIFT 30 474#define AC_DEFCFG_PORT_CONN_SHIFT 30
462 475
476/* Display pin's device list entry */
477#define AC_DE_PD (1<<0)
478#define AC_DE_ELDV (1<<1)
479#define AC_DE_IA (1<<2)
480
463/* device device types (0x0-0xf) */ 481/* device device types (0x0-0xf) */
464enum { 482enum {
465 AC_JACK_LINE_OUT, 483 AC_JACK_LINE_OUT,
@@ -885,6 +903,7 @@ struct hda_codec {
885 unsigned int pcm_format_first:1; /* PCM format must be set first */ 903 unsigned int pcm_format_first:1; /* PCM format must be set first */
886 unsigned int epss:1; /* supporting EPSS? */ 904 unsigned int epss:1; /* supporting EPSS? */
887 unsigned int cached_write:1; /* write only to caches */ 905 unsigned int cached_write:1; /* write only to caches */
906 unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */
888#ifdef CONFIG_PM 907#ifdef CONFIG_PM
889 unsigned int power_on :1; /* current (global) power-state */ 908 unsigned int power_on :1; /* current (global) power-state */
890 unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ 909 unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */
@@ -972,6 +991,8 @@ int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums,
972 const hda_nid_t *list); 991 const hda_nid_t *list);
973int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, 992int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
974 hda_nid_t nid, int recursive); 993 hda_nid_t nid, int recursive);
994int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
995 u8 *dev_list, int max_devices);
975int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, 996int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
976 u32 *ratesp, u64 *formatsp, unsigned int *bpsp); 997 u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
977 998
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index e3c7ba8d7582..ac41e9cdc976 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -142,6 +142,9 @@ static void parse_user_hints(struct hda_codec *codec)
142 val = snd_hda_get_bool_hint(codec, "primary_hp"); 142 val = snd_hda_get_bool_hint(codec, "primary_hp");
143 if (val >= 0) 143 if (val >= 0)
144 spec->no_primary_hp = !val; 144 spec->no_primary_hp = !val;
145 val = snd_hda_get_bool_hint(codec, "multi_io");
146 if (val >= 0)
147 spec->no_multi_io = !val;
145 val = snd_hda_get_bool_hint(codec, "multi_cap_vol"); 148 val = snd_hda_get_bool_hint(codec, "multi_cap_vol");
146 if (val >= 0) 149 if (val >= 0)
147 spec->multi_cap_vol = !!val; 150 spec->multi_cap_vol = !!val;
@@ -813,6 +816,8 @@ static void resume_path_from_idx(struct hda_codec *codec, int path_idx)
813 816
814static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol, 817static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol,
815 struct snd_ctl_elem_value *ucontrol); 818 struct snd_ctl_elem_value *ucontrol);
819static int hda_gen_bind_mute_put(struct snd_kcontrol *kcontrol,
820 struct snd_ctl_elem_value *ucontrol);
816 821
817enum { 822enum {
818 HDA_CTL_WIDGET_VOL, 823 HDA_CTL_WIDGET_VOL,
@@ -830,7 +835,13 @@ static const struct snd_kcontrol_new control_templates[] = {
830 .put = hda_gen_mixer_mute_put, /* replaced */ 835 .put = hda_gen_mixer_mute_put, /* replaced */
831 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0), 836 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0),
832 }, 837 },
833 HDA_BIND_MUTE(NULL, 0, 0, 0), 838 {
839 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
840 .info = snd_hda_mixer_amp_switch_info,
841 .get = snd_hda_mixer_bind_switch_get,
842 .put = hda_gen_bind_mute_put, /* replaced */
843 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0),
844 },
834}; 845};
835 846
836/* add dynamic controls from template */ 847/* add dynamic controls from template */
@@ -937,8 +948,8 @@ static int add_stereo_sw(struct hda_codec *codec, const char *pfx,
937} 948}
938 949
939/* playback mute control with the software mute bit check */ 950/* playback mute control with the software mute bit check */
940static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol, 951static void sync_auto_mute_bits(struct snd_kcontrol *kcontrol,
941 struct snd_ctl_elem_value *ucontrol) 952 struct snd_ctl_elem_value *ucontrol)
942{ 953{
943 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 954 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
944 struct hda_gen_spec *spec = codec->spec; 955 struct hda_gen_spec *spec = codec->spec;
@@ -949,10 +960,22 @@ static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol,
949 ucontrol->value.integer.value[0] &= enabled; 960 ucontrol->value.integer.value[0] &= enabled;
950 ucontrol->value.integer.value[1] &= enabled; 961 ucontrol->value.integer.value[1] &= enabled;
951 } 962 }
963}
952 964
965static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol,
966 struct snd_ctl_elem_value *ucontrol)
967{
968 sync_auto_mute_bits(kcontrol, ucontrol);
953 return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 969 return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
954} 970}
955 971
972static int hda_gen_bind_mute_put(struct snd_kcontrol *kcontrol,
973 struct snd_ctl_elem_value *ucontrol)
974{
975 sync_auto_mute_bits(kcontrol, ucontrol);
976 return snd_hda_mixer_bind_switch_put(kcontrol, ucontrol);
977}
978
956/* any ctl assigned to the path with the given index? */ 979/* any ctl assigned to the path with the given index? */
957static bool path_has_mixer(struct hda_codec *codec, int path_idx, int ctl_type) 980static bool path_has_mixer(struct hda_codec *codec, int path_idx, int ctl_type)
958{ 981{
@@ -1541,7 +1564,8 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
1541 cfg->speaker_pins, 1564 cfg->speaker_pins,
1542 spec->multiout.extra_out_nid, 1565 spec->multiout.extra_out_nid,
1543 spec->speaker_paths); 1566 spec->speaker_paths);
1544 if (fill_mio_first && cfg->line_outs == 1 && 1567 if (!spec->no_multi_io &&
1568 fill_mio_first && cfg->line_outs == 1 &&
1545 cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 1569 cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
1546 err = fill_multi_ios(codec, cfg->line_out_pins[0], true); 1570 err = fill_multi_ios(codec, cfg->line_out_pins[0], true);
1547 if (!err) 1571 if (!err)
@@ -1554,7 +1578,7 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
1554 spec->private_dac_nids, spec->out_paths, 1578 spec->private_dac_nids, spec->out_paths,
1555 spec->main_out_badness); 1579 spec->main_out_badness);
1556 1580
1557 if (fill_mio_first && 1581 if (!spec->no_multi_io && fill_mio_first &&
1558 cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 1582 cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
1559 /* try to fill multi-io first */ 1583 /* try to fill multi-io first */
1560 err = fill_multi_ios(codec, cfg->line_out_pins[0], false); 1584 err = fill_multi_ios(codec, cfg->line_out_pins[0], false);
@@ -1582,7 +1606,8 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
1582 return err; 1606 return err;
1583 badness += err; 1607 badness += err;
1584 } 1608 }
1585 if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 1609 if (!spec->no_multi_io &&
1610 cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
1586 err = fill_multi_ios(codec, cfg->line_out_pins[0], false); 1611 err = fill_multi_ios(codec, cfg->line_out_pins[0], false);
1587 if (err < 0) 1612 if (err < 0)
1588 return err; 1613 return err;
@@ -1600,7 +1625,8 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
1600 check_aamix_out_path(codec, spec->speaker_paths[0]); 1625 check_aamix_out_path(codec, spec->speaker_paths[0]);
1601 } 1626 }
1602 1627
1603 if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 1628 if (!spec->no_multi_io &&
1629 cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
1604 if (count_multiio_pins(codec, cfg->hp_pins[0]) >= 2) 1630 if (count_multiio_pins(codec, cfg->hp_pins[0]) >= 2)
1605 spec->multi_ios = 1; /* give badness */ 1631 spec->multi_ios = 1; /* give badness */
1606 1632
@@ -3724,7 +3750,8 @@ static int mux_select(struct hda_codec *codec, unsigned int adc_idx,
3724/* check each pin in the given array; returns true if any of them is plugged */ 3750/* check each pin in the given array; returns true if any of them is plugged */
3725static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) 3751static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
3726{ 3752{
3727 int i, present = 0; 3753 int i;
3754 bool present = false;
3728 3755
3729 for (i = 0; i < num_pins; i++) { 3756 for (i = 0; i < num_pins; i++) {
3730 hda_nid_t nid = pins[i]; 3757 hda_nid_t nid = pins[i];
@@ -3733,14 +3760,15 @@ static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
3733 /* don't detect pins retasked as inputs */ 3760 /* don't detect pins retasked as inputs */
3734 if (snd_hda_codec_get_pin_target(codec, nid) & AC_PINCTL_IN_EN) 3761 if (snd_hda_codec_get_pin_target(codec, nid) & AC_PINCTL_IN_EN)
3735 continue; 3762 continue;
3736 present |= snd_hda_jack_detect(codec, nid); 3763 if (snd_hda_jack_detect_state(codec, nid) == HDA_JACK_PRESENT)
3764 present = true;
3737 } 3765 }
3738 return present; 3766 return present;
3739} 3767}
3740 3768
3741/* standard HP/line-out auto-mute helper */ 3769/* standard HP/line-out auto-mute helper */
3742static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, 3770static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
3743 bool mute) 3771 int *paths, bool mute)
3744{ 3772{
3745 struct hda_gen_spec *spec = codec->spec; 3773 struct hda_gen_spec *spec = codec->spec;
3746 int i; 3774 int i;
@@ -3752,10 +3780,19 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
3752 break; 3780 break;
3753 3781
3754 if (spec->auto_mute_via_amp) { 3782 if (spec->auto_mute_via_amp) {
3783 struct nid_path *path;
3784 hda_nid_t mute_nid;
3785
3786 path = snd_hda_get_path_from_idx(codec, paths[i]);
3787 if (!path)
3788 continue;
3789 mute_nid = get_amp_nid_(path->ctls[NID_PATH_MUTE_CTL]);
3790 if (!mute_nid)
3791 continue;
3755 if (mute) 3792 if (mute)
3756 spec->mute_bits |= (1ULL << nid); 3793 spec->mute_bits |= (1ULL << mute_nid);
3757 else 3794 else
3758 spec->mute_bits &= ~(1ULL << nid); 3795 spec->mute_bits &= ~(1ULL << mute_nid);
3759 set_pin_eapd(codec, nid, !mute); 3796 set_pin_eapd(codec, nid, !mute);
3760 continue; 3797 continue;
3761 } 3798 }
@@ -3786,14 +3823,19 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
3786void snd_hda_gen_update_outputs(struct hda_codec *codec) 3823void snd_hda_gen_update_outputs(struct hda_codec *codec)
3787{ 3824{
3788 struct hda_gen_spec *spec = codec->spec; 3825 struct hda_gen_spec *spec = codec->spec;
3826 int *paths;
3789 int on; 3827 int on;
3790 3828
3791 /* Control HP pins/amps depending on master_mute state; 3829 /* Control HP pins/amps depending on master_mute state;
3792 * in general, HP pins/amps control should be enabled in all cases, 3830 * in general, HP pins/amps control should be enabled in all cases,
3793 * but currently set only for master_mute, just to be safe 3831 * but currently set only for master_mute, just to be safe
3794 */ 3832 */
3833 if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)
3834 paths = spec->out_paths;
3835 else
3836 paths = spec->hp_paths;
3795 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), 3837 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
3796 spec->autocfg.hp_pins, spec->master_mute); 3838 spec->autocfg.hp_pins, paths, spec->master_mute);
3797 3839
3798 if (!spec->automute_speaker) 3840 if (!spec->automute_speaker)
3799 on = 0; 3841 on = 0;
@@ -3801,8 +3843,12 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec)
3801 on = spec->hp_jack_present | spec->line_jack_present; 3843 on = spec->hp_jack_present | spec->line_jack_present;
3802 on |= spec->master_mute; 3844 on |= spec->master_mute;
3803 spec->speaker_muted = on; 3845 spec->speaker_muted = on;
3846 if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
3847 paths = spec->out_paths;
3848 else
3849 paths = spec->speaker_paths;
3804 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), 3850 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
3805 spec->autocfg.speaker_pins, on); 3851 spec->autocfg.speaker_pins, paths, on);
3806 3852
3807 /* toggle line-out mutes if needed, too */ 3853 /* toggle line-out mutes if needed, too */
3808 /* if LO is a copy of either HP or Speaker, don't need to handle it */ 3854 /* if LO is a copy of either HP or Speaker, don't need to handle it */
@@ -3815,8 +3861,9 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec)
3815 on = spec->hp_jack_present; 3861 on = spec->hp_jack_present;
3816 on |= spec->master_mute; 3862 on |= spec->master_mute;
3817 spec->line_out_muted = on; 3863 spec->line_out_muted = on;
3864 paths = spec->out_paths;
3818 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), 3865 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
3819 spec->autocfg.line_out_pins, on); 3866 spec->autocfg.line_out_pins, paths, on);
3820} 3867}
3821EXPORT_SYMBOL_HDA(snd_hda_gen_update_outputs); 3868EXPORT_SYMBOL_HDA(snd_hda_gen_update_outputs);
3822 3869
@@ -3887,7 +3934,7 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *ja
3887 /* don't detect pins retasked as outputs */ 3934 /* don't detect pins retasked as outputs */
3888 if (snd_hda_codec_get_pin_target(codec, pin) & AC_PINCTL_OUT_EN) 3935 if (snd_hda_codec_get_pin_target(codec, pin) & AC_PINCTL_OUT_EN)
3889 continue; 3936 continue;
3890 if (snd_hda_jack_detect(codec, pin)) { 3937 if (snd_hda_jack_detect_state(codec, pin) == HDA_JACK_PRESENT) {
3891 mux_select(codec, 0, spec->am_entry[i].idx); 3938 mux_select(codec, 0, spec->am_entry[i].idx);
3892 return; 3939 return;
3893 } 3940 }
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index e199a852388b..48d44026705b 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -220,6 +220,7 @@ struct hda_gen_spec {
220 unsigned int hp_mic:1; /* Allow HP as a mic-in */ 220 unsigned int hp_mic:1; /* Allow HP as a mic-in */
221 unsigned int suppress_hp_mic_detect:1; /* Don't detect HP/mic */ 221 unsigned int suppress_hp_mic_detect:1; /* Don't detect HP/mic */
222 unsigned int no_primary_hp:1; /* Don't prefer HP pins to speaker pins */ 222 unsigned int no_primary_hp:1; /* Don't prefer HP pins to speaker pins */
223 unsigned int no_multi_io:1; /* Don't try multi I/O config */
223 unsigned int multi_cap_vol:1; /* allow multiple capture xxx volumes */ 224 unsigned int multi_cap_vol:1; /* allow multiple capture xxx volumes */
224 unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */ 225 unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */
225 unsigned int own_eapd_ctl:1; /* set EAPD by own function */ 226 unsigned int own_eapd_ctl:1; /* set EAPD by own function */
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index ce67608734b5..fe0bda19de15 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -295,7 +295,7 @@ static ssize_t type##_store(struct device *dev, \
295 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ 295 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
296 struct hda_codec *codec = hwdep->private_data; \ 296 struct hda_codec *codec = hwdep->private_data; \
297 unsigned long val; \ 297 unsigned long val; \
298 int err = strict_strtoul(buf, 0, &val); \ 298 int err = kstrtoul(buf, 0, &val); \
299 if (err < 0) \ 299 if (err < 0) \
300 return err; \ 300 return err; \
301 codec->type = val; \ 301 codec->type = val; \
@@ -654,7 +654,7 @@ int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp)
654 p = snd_hda_get_hint(codec, key); 654 p = snd_hda_get_hint(codec, key);
655 if (!p) 655 if (!p)
656 ret = -ENOENT; 656 ret = -ENOENT;
657 else if (strict_strtoul(p, 0, &val)) 657 else if (kstrtoul(p, 0, &val))
658 ret = -EINVAL; 658 ret = -EINVAL;
659 else { 659 else {
660 *valp = val; 660 *valp = val;
@@ -751,7 +751,7 @@ static void parse_##name##_mode(char *buf, struct hda_bus *bus, \
751 struct hda_codec **codecp) \ 751 struct hda_codec **codecp) \
752{ \ 752{ \
753 unsigned long val; \ 753 unsigned long val; \
754 if (!strict_strtoul(buf, 0, &val)) \ 754 if (!kstrtoul(buf, 0, &val)) \
755 (*codecp)->name = val; \ 755 (*codecp)->name = val; \
756} 756}
757 757
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 8860dd529520..c6c98298ac39 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1160,7 +1160,7 @@ static int azx_reset(struct azx *chip, int full_reset)
1160 goto __skip; 1160 goto __skip;
1161 1161
1162 /* clear STATESTS */ 1162 /* clear STATESTS */
1163 azx_writeb(chip, STATESTS, STATESTS_INT_MASK); 1163 azx_writew(chip, STATESTS, STATESTS_INT_MASK);
1164 1164
1165 /* reset controller */ 1165 /* reset controller */
1166 azx_enter_link_reset(chip); 1166 azx_enter_link_reset(chip);
@@ -1242,7 +1242,7 @@ static void azx_int_clear(struct azx *chip)
1242 } 1242 }
1243 1243
1244 /* clear STATESTS */ 1244 /* clear STATESTS */
1245 azx_writeb(chip, STATESTS, STATESTS_INT_MASK); 1245 azx_writew(chip, STATESTS, STATESTS_INT_MASK);
1246 1246
1247 /* clear rirb status */ 1247 /* clear rirb status */
1248 azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); 1248 azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
@@ -1451,8 +1451,8 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
1451 1451
1452#if 0 1452#if 0
1453 /* clear state status int */ 1453 /* clear state status int */
1454 if (azx_readb(chip, STATESTS) & 0x04) 1454 if (azx_readw(chip, STATESTS) & 0x04)
1455 azx_writeb(chip, STATESTS, 0x04); 1455 azx_writew(chip, STATESTS, 0x04);
1456#endif 1456#endif
1457 spin_unlock(&chip->reg_lock); 1457 spin_unlock(&chip->reg_lock);
1458 1458
@@ -2971,6 +2971,10 @@ static int azx_runtime_suspend(struct device *dev)
2971 struct snd_card *card = dev_get_drvdata(dev); 2971 struct snd_card *card = dev_get_drvdata(dev);
2972 struct azx *chip = card->private_data; 2972 struct azx *chip = card->private_data;
2973 2973
2974 /* enable controller wake up event */
2975 azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) |
2976 STATESTS_INT_MASK);
2977
2974 azx_stop_chip(chip); 2978 azx_stop_chip(chip);
2975 azx_enter_link_reset(chip); 2979 azx_enter_link_reset(chip);
2976 azx_clear_irq_pending(chip); 2980 azx_clear_irq_pending(chip);
@@ -2983,11 +2987,31 @@ static int azx_runtime_resume(struct device *dev)
2983{ 2987{
2984 struct snd_card *card = dev_get_drvdata(dev); 2988 struct snd_card *card = dev_get_drvdata(dev);
2985 struct azx *chip = card->private_data; 2989 struct azx *chip = card->private_data;
2990 struct hda_bus *bus;
2991 struct hda_codec *codec;
2992 int status;
2986 2993
2987 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) 2994 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
2988 hda_display_power(true); 2995 hda_display_power(true);
2996
2997 /* Read STATESTS before controller reset */
2998 status = azx_readw(chip, STATESTS);
2999
2989 azx_init_pci(chip); 3000 azx_init_pci(chip);
2990 azx_init_chip(chip, 1); 3001 azx_init_chip(chip, 1);
3002
3003 bus = chip->bus;
3004 if (status && bus) {
3005 list_for_each_entry(codec, &bus->codec_list, list)
3006 if (status & (1 << codec->addr))
3007 queue_delayed_work(codec->bus->workq,
3008 &codec->jackpoll_work, codec->jackpoll_interval);
3009 }
3010
3011 /* disable controller Wake Up event*/
3012 azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
3013 ~STATESTS_INT_MASK);
3014
2991 return 0; 3015 return 0;
2992} 3016}
2993 3017
@@ -3831,11 +3855,13 @@ static int azx_probe_continue(struct azx *chip)
3831 3855
3832 /* Request power well for Haswell HDA controller and codec */ 3856 /* Request power well for Haswell HDA controller and codec */
3833 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { 3857 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
3858#ifdef CONFIG_SND_HDA_I915
3834 err = hda_i915_init(); 3859 err = hda_i915_init();
3835 if (err < 0) { 3860 if (err < 0) {
3836 snd_printk(KERN_ERR SFX "Error request power-well from i915\n"); 3861 snd_printk(KERN_ERR SFX "Error request power-well from i915\n");
3837 goto out_free; 3862 goto out_free;
3838 } 3863 }
3864#endif
3839 hda_display_power(true); 3865 hda_display_power(true);
3840 } 3866 }
3841 3867
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 3fd2973183e2..05b3e3e9108f 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -194,18 +194,24 @@ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
194EXPORT_SYMBOL_HDA(snd_hda_pin_sense); 194EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
195 195
196/** 196/**
197 * snd_hda_jack_detect - query pin Presence Detect status 197 * snd_hda_jack_detect_state - query pin Presence Detect status
198 * @codec: the CODEC to sense 198 * @codec: the CODEC to sense
199 * @nid: the pin NID to sense 199 * @nid: the pin NID to sense
200 * 200 *
201 * Query and return the pin's Presence Detect status. 201 * Query and return the pin's Presence Detect status, as either
202 * HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT or HDA_JACK_PHANTOM.
202 */ 203 */
203int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) 204int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid)
204{ 205{
205 u32 sense = snd_hda_pin_sense(codec, nid); 206 struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
206 return get_jack_plug_state(sense); 207 if (jack && jack->phantom_jack)
208 return HDA_JACK_PHANTOM;
209 else if (snd_hda_pin_sense(codec, nid) & AC_PINSENSE_PRESENCE)
210 return HDA_JACK_PRESENT;
211 else
212 return HDA_JACK_NOT_PRESENT;
207} 213}
208EXPORT_SYMBOL_HDA(snd_hda_jack_detect); 214EXPORT_SYMBOL_HDA(snd_hda_jack_detect_state);
209 215
210/** 216/**
211 * snd_hda_jack_detect_enable - enable the jack-detection 217 * snd_hda_jack_detect_enable - enable the jack-detection
@@ -247,8 +253,8 @@ EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable);
247int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid, 253int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
248 hda_nid_t gating_nid) 254 hda_nid_t gating_nid)
249{ 255{
250 struct hda_jack_tbl *gated = snd_hda_jack_tbl_get(codec, gated_nid); 256 struct hda_jack_tbl *gated = snd_hda_jack_tbl_new(codec, gated_nid);
251 struct hda_jack_tbl *gating = snd_hda_jack_tbl_get(codec, gating_nid); 257 struct hda_jack_tbl *gating = snd_hda_jack_tbl_new(codec, gating_nid);
252 258
253 if (!gated || !gating) 259 if (!gated || !gating)
254 return -EINVAL; 260 return -EINVAL;
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index ec12abd45263..379420c44eef 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -75,7 +75,18 @@ int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
75 hda_nid_t gating_nid); 75 hda_nid_t gating_nid);
76 76
77u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); 77u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
78int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); 78
79/* the jack state returned from snd_hda_jack_detect_state() */
80enum {
81 HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT, HDA_JACK_PHANTOM,
82};
83
84int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid);
85
86static inline bool snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
87{
88 return snd_hda_jack_detect_state(codec, nid) != HDA_JACK_NOT_PRESENT;
89}
79 90
80bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid); 91bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
81 92
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 9760f001916d..a8cb22eec89e 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -582,6 +582,36 @@ static void print_gpio(struct snd_info_buffer *buffer,
582 print_nid_array(buffer, codec, nid, &codec->nids); 582 print_nid_array(buffer, codec, nid, &codec->nids);
583} 583}
584 584
585static void print_device_list(struct snd_info_buffer *buffer,
586 struct hda_codec *codec, hda_nid_t nid)
587{
588 int i, curr = -1;
589 u8 dev_list[AC_MAX_DEV_LIST_LEN];
590 int devlist_len;
591
592 devlist_len = snd_hda_get_devices(codec, nid, dev_list,
593 AC_MAX_DEV_LIST_LEN);
594 snd_iprintf(buffer, " Devices: %d\n", devlist_len);
595 if (devlist_len <= 0)
596 return;
597
598 curr = snd_hda_codec_read(codec, nid, 0,
599 AC_VERB_GET_DEVICE_SEL, 0);
600
601 for (i = 0; i < devlist_len; i++) {
602 if (i == curr)
603 snd_iprintf(buffer, " *");
604 else
605 snd_iprintf(buffer, " ");
606
607 snd_iprintf(buffer,
608 "Dev %02d: PD = %d, ELDV = %d, IA = %d\n", i,
609 !!(dev_list[i] & AC_DE_PD),
610 !!(dev_list[i] & AC_DE_ELDV),
611 !!(dev_list[i] & AC_DE_IA));
612 }
613}
614
585static void print_codec_info(struct snd_info_entry *entry, 615static void print_codec_info(struct snd_info_entry *entry,
586 struct snd_info_buffer *buffer) 616 struct snd_info_buffer *buffer)
587{ 617{
@@ -751,6 +781,9 @@ static void print_codec_info(struct snd_info_entry *entry,
751 (wid_caps & AC_WCAP_DELAY) >> 781 (wid_caps & AC_WCAP_DELAY) >>
752 AC_WCAP_DELAY_SHIFT); 782 AC_WCAP_DELAY_SHIFT);
753 783
784 if (wid_type == AC_WID_PIN && codec->dp_mst)
785 print_device_list(buffer, codec, nid);
786
754 if (wid_caps & AC_WCAP_CONN_LIST) 787 if (wid_caps & AC_WCAP_CONN_LIST)
755 print_conn_list(buffer, codec, nid, wid_type, 788 print_conn_list(buffer, codec, nid, wid_type,
756 conn, conn_len); 789 conn, conn_len);
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index d97f0d61a15b..0cbdd87dde6d 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -32,7 +32,6 @@
32#include "hda_jack.h" 32#include "hda_jack.h"
33#include "hda_generic.h" 33#include "hda_generic.h"
34 34
35#define ENABLE_AD_STATIC_QUIRKS
36 35
37struct ad198x_spec { 36struct ad198x_spec {
38 struct hda_gen_spec gen; 37 struct hda_gen_spec gen;
@@ -43,114 +42,8 @@ struct ad198x_spec {
43 hda_nid_t eapd_nid; 42 hda_nid_t eapd_nid;
44 43
45 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 44 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
46
47#ifdef ENABLE_AD_STATIC_QUIRKS
48 const struct snd_kcontrol_new *mixers[6];
49 int num_mixers;
50 const struct hda_verb *init_verbs[6]; /* initialization verbs
51 * don't forget NULL termination!
52 */
53 unsigned int num_init_verbs;
54
55 /* playback */
56 struct hda_multi_out multiout; /* playback set-up
57 * max_channels, dacs must be set
58 * dig_out_nid and hp_nid are optional
59 */
60 unsigned int cur_eapd;
61 unsigned int need_dac_fix;
62
63 /* capture */
64 unsigned int num_adc_nids;
65 const hda_nid_t *adc_nids;
66 hda_nid_t dig_in_nid; /* digital-in NID; optional */
67
68 /* capture source */
69 const struct hda_input_mux *input_mux;
70 const hda_nid_t *capsrc_nids;
71 unsigned int cur_mux[3];
72
73 /* channel model */
74 const struct hda_channel_mode *channel_mode;
75 int num_channel_mode;
76
77 /* PCM information */
78 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
79
80 unsigned int spdif_route;
81
82 unsigned int jack_present: 1;
83 unsigned int inv_jack_detect: 1;/* inverted jack-detection */
84 unsigned int analog_beep: 1; /* analog beep input present */
85 unsigned int avoid_init_slave_vol:1;
86
87#ifdef CONFIG_PM
88 struct hda_loopback_check loopback;
89#endif
90 /* for virtual master */
91 hda_nid_t vmaster_nid;
92 const char * const *slave_vols;
93 const char * const *slave_sws;
94#endif /* ENABLE_AD_STATIC_QUIRKS */
95};
96
97#ifdef ENABLE_AD_STATIC_QUIRKS
98/*
99 * input MUX handling (common part)
100 */
101static int ad198x_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
102{
103 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
104 struct ad198x_spec *spec = codec->spec;
105
106 return snd_hda_input_mux_info(spec->input_mux, uinfo);
107}
108
109static int ad198x_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
110{
111 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
112 struct ad198x_spec *spec = codec->spec;
113 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
114
115 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
116 return 0;
117}
118
119static int ad198x_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
120{
121 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
122 struct ad198x_spec *spec = codec->spec;
123 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
124
125 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
126 spec->capsrc_nids[adc_idx],
127 &spec->cur_mux[adc_idx]);
128}
129
130/*
131 * initialization (common callbacks)
132 */
133static int ad198x_init(struct hda_codec *codec)
134{
135 struct ad198x_spec *spec = codec->spec;
136 int i;
137
138 for (i = 0; i < spec->num_init_verbs; i++)
139 snd_hda_sequence_write(codec, spec->init_verbs[i]);
140 return 0;
141}
142
143static const char * const ad_slave_pfxs[] = {
144 "Front", "Surround", "Center", "LFE", "Side",
145 "Headphone", "Mono", "Speaker", "IEC958",
146 NULL
147}; 45};
148 46
149static const char * const ad1988_6stack_fp_slave_pfxs[] = {
150 "Front", "Surround", "Center", "LFE", "Side", "IEC958",
151 NULL
152};
153#endif /* ENABLE_AD_STATIC_QUIRKS */
154 47
155#ifdef CONFIG_SND_HDA_INPUT_BEEP 48#ifdef CONFIG_SND_HDA_INPUT_BEEP
156/* additional beep mixers; the actual parameters are overwritten at build */ 49/* additional beep mixers; the actual parameters are overwritten at build */
@@ -160,12 +53,6 @@ static const struct snd_kcontrol_new ad_beep_mixer[] = {
160 { } /* end */ 53 { } /* end */
161}; 54};
162 55
163static const struct snd_kcontrol_new ad_beep2_mixer[] = {
164 HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT),
165 HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT),
166 { } /* end */
167};
168
169#define set_beep_amp(spec, nid, idx, dir) \ 56#define set_beep_amp(spec, nid, idx, dir) \
170 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */ 57 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */
171#else 58#else
@@ -181,8 +68,7 @@ static int create_beep_ctls(struct hda_codec *codec)
181 if (!spec->beep_amp) 68 if (!spec->beep_amp)
182 return 0; 69 return 0;
183 70
184 knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer; 71 for (knew = ad_beep_mixer ; knew->name; knew++) {
185 for ( ; knew->name; knew++) {
186 int err; 72 int err;
187 struct snd_kcontrol *kctl; 73 struct snd_kcontrol *kctl;
188 kctl = snd_ctl_new1(knew, codec); 74 kctl = snd_ctl_new1(knew, codec);
@@ -199,268 +85,6 @@ static int create_beep_ctls(struct hda_codec *codec)
199#define create_beep_ctls(codec) 0 85#define create_beep_ctls(codec) 0
200#endif 86#endif
201 87
202#ifdef ENABLE_AD_STATIC_QUIRKS
203static int ad198x_build_controls(struct hda_codec *codec)
204{
205 struct ad198x_spec *spec = codec->spec;
206 struct snd_kcontrol *kctl;
207 unsigned int i;
208 int err;
209
210 for (i = 0; i < spec->num_mixers; i++) {
211 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
212 if (err < 0)
213 return err;
214 }
215 if (spec->multiout.dig_out_nid) {
216 err = snd_hda_create_spdif_out_ctls(codec,
217 spec->multiout.dig_out_nid,
218 spec->multiout.dig_out_nid);
219 if (err < 0)
220 return err;
221 err = snd_hda_create_spdif_share_sw(codec,
222 &spec->multiout);
223 if (err < 0)
224 return err;
225 spec->multiout.share_spdif = 1;
226 }
227 if (spec->dig_in_nid) {
228 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
229 if (err < 0)
230 return err;
231 }
232
233 /* create beep controls if needed */
234 err = create_beep_ctls(codec);
235 if (err < 0)
236 return err;
237
238 /* if we have no master control, let's create it */
239 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
240 unsigned int vmaster_tlv[4];
241 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
242 HDA_OUTPUT, vmaster_tlv);
243 err = __snd_hda_add_vmaster(codec, "Master Playback Volume",
244 vmaster_tlv,
245 (spec->slave_vols ?
246 spec->slave_vols : ad_slave_pfxs),
247 "Playback Volume",
248 !spec->avoid_init_slave_vol, NULL);
249 if (err < 0)
250 return err;
251 }
252 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
253 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
254 NULL,
255 (spec->slave_sws ?
256 spec->slave_sws : ad_slave_pfxs),
257 "Playback Switch");
258 if (err < 0)
259 return err;
260 }
261
262 /* assign Capture Source enums to NID */
263 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
264 if (!kctl)
265 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
266 for (i = 0; kctl && i < kctl->count; i++) {
267 err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]);
268 if (err < 0)
269 return err;
270 }
271
272 /* assign IEC958 enums to NID */
273 kctl = snd_hda_find_mixer_ctl(codec,
274 SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source");
275 if (kctl) {
276 err = snd_hda_add_nid(codec, kctl, 0,
277 spec->multiout.dig_out_nid);
278 if (err < 0)
279 return err;
280 }
281
282 return 0;
283}
284
285#ifdef CONFIG_PM
286static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid)
287{
288 struct ad198x_spec *spec = codec->spec;
289 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
290}
291#endif
292
293/*
294 * Analog playback callbacks
295 */
296static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
297 struct hda_codec *codec,
298 struct snd_pcm_substream *substream)
299{
300 struct ad198x_spec *spec = codec->spec;
301 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
302 hinfo);
303}
304
305static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
306 struct hda_codec *codec,
307 unsigned int stream_tag,
308 unsigned int format,
309 struct snd_pcm_substream *substream)
310{
311 struct ad198x_spec *spec = codec->spec;
312 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
313 format, substream);
314}
315
316static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
317 struct hda_codec *codec,
318 struct snd_pcm_substream *substream)
319{
320 struct ad198x_spec *spec = codec->spec;
321 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
322}
323
324/*
325 * Digital out
326 */
327static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
328 struct hda_codec *codec,
329 struct snd_pcm_substream *substream)
330{
331 struct ad198x_spec *spec = codec->spec;
332 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
333}
334
335static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
336 struct hda_codec *codec,
337 struct snd_pcm_substream *substream)
338{
339 struct ad198x_spec *spec = codec->spec;
340 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
341}
342
343static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
344 struct hda_codec *codec,
345 unsigned int stream_tag,
346 unsigned int format,
347 struct snd_pcm_substream *substream)
348{
349 struct ad198x_spec *spec = codec->spec;
350 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
351 format, substream);
352}
353
354static int ad198x_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
355 struct hda_codec *codec,
356 struct snd_pcm_substream *substream)
357{
358 struct ad198x_spec *spec = codec->spec;
359 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
360}
361
362/*
363 * Analog capture
364 */
365static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
366 struct hda_codec *codec,
367 unsigned int stream_tag,
368 unsigned int format,
369 struct snd_pcm_substream *substream)
370{
371 struct ad198x_spec *spec = codec->spec;
372 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
373 stream_tag, 0, format);
374 return 0;
375}
376
377static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
378 struct hda_codec *codec,
379 struct snd_pcm_substream *substream)
380{
381 struct ad198x_spec *spec = codec->spec;
382 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
383 return 0;
384}
385
386/*
387 */
388static const struct hda_pcm_stream ad198x_pcm_analog_playback = {
389 .substreams = 1,
390 .channels_min = 2,
391 .channels_max = 6, /* changed later */
392 .nid = 0, /* fill later */
393 .ops = {
394 .open = ad198x_playback_pcm_open,
395 .prepare = ad198x_playback_pcm_prepare,
396 .cleanup = ad198x_playback_pcm_cleanup,
397 },
398};
399
400static const struct hda_pcm_stream ad198x_pcm_analog_capture = {
401 .substreams = 1,
402 .channels_min = 2,
403 .channels_max = 2,
404 .nid = 0, /* fill later */
405 .ops = {
406 .prepare = ad198x_capture_pcm_prepare,
407 .cleanup = ad198x_capture_pcm_cleanup
408 },
409};
410
411static const struct hda_pcm_stream ad198x_pcm_digital_playback = {
412 .substreams = 1,
413 .channels_min = 2,
414 .channels_max = 2,
415 .nid = 0, /* fill later */
416 .ops = {
417 .open = ad198x_dig_playback_pcm_open,
418 .close = ad198x_dig_playback_pcm_close,
419 .prepare = ad198x_dig_playback_pcm_prepare,
420 .cleanup = ad198x_dig_playback_pcm_cleanup
421 },
422};
423
424static const struct hda_pcm_stream ad198x_pcm_digital_capture = {
425 .substreams = 1,
426 .channels_min = 2,
427 .channels_max = 2,
428 /* NID is set in alc_build_pcms */
429};
430
431static int ad198x_build_pcms(struct hda_codec *codec)
432{
433 struct ad198x_spec *spec = codec->spec;
434 struct hda_pcm *info = spec->pcm_rec;
435
436 codec->num_pcms = 1;
437 codec->pcm_info = info;
438
439 info->name = "AD198x Analog";
440 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback;
441 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
442 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
443 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
444 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
445 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
446
447 if (spec->multiout.dig_out_nid) {
448 info++;
449 codec->num_pcms++;
450 codec->spdif_status_reset = 1;
451 info->name = "AD198x Digital";
452 info->pcm_type = HDA_PCM_TYPE_SPDIF;
453 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
454 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
455 if (spec->dig_in_nid) {
456 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
457 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
458 }
459 }
460
461 return 0;
462}
463#endif /* ENABLE_AD_STATIC_QUIRKS */
464 88
465static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front, 89static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
466 hda_nid_t hp) 90 hda_nid_t hp)
@@ -507,18 +131,6 @@ static void ad198x_shutup(struct hda_codec *codec)
507 ad198x_power_eapd(codec); 131 ad198x_power_eapd(codec);
508} 132}
509 133
510static void ad198x_free(struct hda_codec *codec)
511{
512 struct ad198x_spec *spec = codec->spec;
513
514 if (!spec)
515 return;
516
517 snd_hda_gen_spec_free(&spec->gen);
518 kfree(spec);
519 snd_hda_detach_beep_device(codec);
520}
521
522#ifdef CONFIG_PM 134#ifdef CONFIG_PM
523static int ad198x_suspend(struct hda_codec *codec) 135static int ad198x_suspend(struct hda_codec *codec)
524{ 136{
@@ -527,65 +139,6 @@ static int ad198x_suspend(struct hda_codec *codec)
527} 139}
528#endif 140#endif
529 141
530#ifdef ENABLE_AD_STATIC_QUIRKS
531static const struct hda_codec_ops ad198x_patch_ops = {
532 .build_controls = ad198x_build_controls,
533 .build_pcms = ad198x_build_pcms,
534 .init = ad198x_init,
535 .free = ad198x_free,
536#ifdef CONFIG_PM
537 .check_power_status = ad198x_check_power_status,
538 .suspend = ad198x_suspend,
539#endif
540 .reboot_notify = ad198x_shutup,
541};
542
543
544/*
545 * EAPD control
546 * the private value = nid
547 */
548#define ad198x_eapd_info snd_ctl_boolean_mono_info
549
550static int ad198x_eapd_get(struct snd_kcontrol *kcontrol,
551 struct snd_ctl_elem_value *ucontrol)
552{
553 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
554 struct ad198x_spec *spec = codec->spec;
555 if (codec->inv_eapd)
556 ucontrol->value.integer.value[0] = ! spec->cur_eapd;
557 else
558 ucontrol->value.integer.value[0] = spec->cur_eapd;
559 return 0;
560}
561
562static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
563 struct snd_ctl_elem_value *ucontrol)
564{
565 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
566 struct ad198x_spec *spec = codec->spec;
567 hda_nid_t nid = kcontrol->private_value & 0xff;
568 unsigned int eapd;
569 eapd = !!ucontrol->value.integer.value[0];
570 if (codec->inv_eapd)
571 eapd = !eapd;
572 if (eapd == spec->cur_eapd)
573 return 0;
574 spec->cur_eapd = eapd;
575 snd_hda_codec_write_cache(codec, nid,
576 0, AC_VERB_SET_EAPD_BTLENABLE,
577 eapd ? 0x02 : 0x00);
578 return 1;
579}
580
581static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
582 struct snd_ctl_elem_info *uinfo);
583static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
584 struct snd_ctl_elem_value *ucontrol);
585static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
586 struct snd_ctl_elem_value *ucontrol);
587#endif /* ENABLE_AD_STATIC_QUIRKS */
588
589 142
590/* 143/*
591 * Automatic parse of I/O pins from the BIOS configuration 144 * Automatic parse of I/O pins from the BIOS configuration
@@ -646,537 +199,6 @@ static int ad198x_parse_auto_config(struct hda_codec *codec)
646 * AD1986A specific 199 * AD1986A specific
647 */ 200 */
648 201
649#ifdef ENABLE_AD_STATIC_QUIRKS
650#define AD1986A_SPDIF_OUT 0x02
651#define AD1986A_FRONT_DAC 0x03
652#define AD1986A_SURR_DAC 0x04
653#define AD1986A_CLFE_DAC 0x05
654#define AD1986A_ADC 0x06
655
656static const hda_nid_t ad1986a_dac_nids[3] = {
657 AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
658};
659static const hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
660static const hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 };
661
662static const struct hda_input_mux ad1986a_capture_source = {
663 .num_items = 7,
664 .items = {
665 { "Mic", 0x0 },
666 { "CD", 0x1 },
667 { "Aux", 0x3 },
668 { "Line", 0x4 },
669 { "Mix", 0x5 },
670 { "Mono", 0x6 },
671 { "Phone", 0x7 },
672 },
673};
674
675
676static const struct hda_bind_ctls ad1986a_bind_pcm_vol = {
677 .ops = &snd_hda_bind_vol,
678 .values = {
679 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
680 HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
681 HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
682 0
683 },
684};
685
686static const struct hda_bind_ctls ad1986a_bind_pcm_sw = {
687 .ops = &snd_hda_bind_sw,
688 .values = {
689 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
690 HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
691 HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
692 0
693 },
694};
695
696/*
697 * mixers
698 */
699static const struct snd_kcontrol_new ad1986a_mixers[] = {
700 /*
701 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
702 */
703 HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol),
704 HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw),
705 HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
706 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
707 HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
708 HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
709 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
710 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
711 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
712 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
713 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
714 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
715 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
716 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
717 HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
718 HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
719 HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
720 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
721 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
722 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
723 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
724 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
725 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
726 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
727 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
728 {
729 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
730 .name = "Capture Source",
731 .info = ad198x_mux_enum_info,
732 .get = ad198x_mux_enum_get,
733 .put = ad198x_mux_enum_put,
734 },
735 HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
736 { } /* end */
737};
738
739/* additional mixers for 3stack mode */
740static const struct snd_kcontrol_new ad1986a_3st_mixers[] = {
741 {
742 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
743 .name = "Channel Mode",
744 .info = ad198x_ch_mode_info,
745 .get = ad198x_ch_mode_get,
746 .put = ad198x_ch_mode_put,
747 },
748 { } /* end */
749};
750
751/* laptop model - 2ch only */
752static const hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC };
753
754/* master controls both pins 0x1a and 0x1b */
755static const struct hda_bind_ctls ad1986a_laptop_master_vol = {
756 .ops = &snd_hda_bind_vol,
757 .values = {
758 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
759 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
760 0,
761 },
762};
763
764static const struct hda_bind_ctls ad1986a_laptop_master_sw = {
765 .ops = &snd_hda_bind_sw,
766 .values = {
767 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
768 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
769 0,
770 },
771};
772
773static const struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
774 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
775 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
776 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
777 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
778 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
779 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
780 HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
781 HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
782 HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
783 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
784 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
785 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
786 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
787 /*
788 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
789 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */
790 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
791 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
792 {
793 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
794 .name = "Capture Source",
795 .info = ad198x_mux_enum_info,
796 .get = ad198x_mux_enum_get,
797 .put = ad198x_mux_enum_put,
798 },
799 { } /* end */
800};
801
802/* laptop-eapd model - 2ch only */
803
804static const struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
805 .num_items = 3,
806 .items = {
807 { "Mic", 0x0 },
808 { "Internal Mic", 0x4 },
809 { "Mix", 0x5 },
810 },
811};
812
813static const struct hda_input_mux ad1986a_automic_capture_source = {
814 .num_items = 2,
815 .items = {
816 { "Mic", 0x0 },
817 { "Mix", 0x5 },
818 },
819};
820
821static const struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = {
822 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
823 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
824 { } /* end */
825};
826
827static const struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
828 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
829 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
830 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
831 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
832 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
833 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
834 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
835 {
836 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
837 .name = "Capture Source",
838 .info = ad198x_mux_enum_info,
839 .get = ad198x_mux_enum_get,
840 .put = ad198x_mux_enum_put,
841 },
842 {
843 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
844 .name = "External Amplifier",
845 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
846 .info = ad198x_eapd_info,
847 .get = ad198x_eapd_get,
848 .put = ad198x_eapd_put,
849 .private_value = 0x1b, /* port-D */
850 },
851 { } /* end */
852};
853
854static const struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = {
855 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT),
856 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT),
857 { } /* end */
858};
859
860/* re-connect the mic boost input according to the jack sensing */
861static void ad1986a_automic(struct hda_codec *codec)
862{
863 unsigned int present;
864 present = snd_hda_jack_detect(codec, 0x1f);
865 /* 0 = 0x1f, 2 = 0x1d, 4 = mixed */
866 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_CONNECT_SEL,
867 present ? 0 : 2);
868}
869
870#define AD1986A_MIC_EVENT 0x36
871
872static void ad1986a_automic_unsol_event(struct hda_codec *codec,
873 unsigned int res)
874{
875 if ((res >> 26) != AD1986A_MIC_EVENT)
876 return;
877 ad1986a_automic(codec);
878}
879
880static int ad1986a_automic_init(struct hda_codec *codec)
881{
882 ad198x_init(codec);
883 ad1986a_automic(codec);
884 return 0;
885}
886
887/* laptop-automute - 2ch only */
888
889static void ad1986a_update_hp(struct hda_codec *codec)
890{
891 struct ad198x_spec *spec = codec->spec;
892 unsigned int mute;
893
894 if (spec->jack_present)
895 mute = HDA_AMP_MUTE; /* mute internal speaker */
896 else
897 /* unmute internal speaker if necessary */
898 mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0);
899 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
900 HDA_AMP_MUTE, mute);
901}
902
903static void ad1986a_hp_automute(struct hda_codec *codec)
904{
905 struct ad198x_spec *spec = codec->spec;
906
907 spec->jack_present = snd_hda_jack_detect(codec, 0x1a);
908 if (spec->inv_jack_detect)
909 spec->jack_present = !spec->jack_present;
910 ad1986a_update_hp(codec);
911}
912
913#define AD1986A_HP_EVENT 0x37
914
915static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
916{
917 if ((res >> 26) != AD1986A_HP_EVENT)
918 return;
919 ad1986a_hp_automute(codec);
920}
921
922static int ad1986a_hp_init(struct hda_codec *codec)
923{
924 ad198x_init(codec);
925 ad1986a_hp_automute(codec);
926 return 0;
927}
928
929/* bind hp and internal speaker mute (with plug check) */
930static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol,
931 struct snd_ctl_elem_value *ucontrol)
932{
933 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
934 int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
935 if (change)
936 ad1986a_update_hp(codec);
937 return change;
938}
939
940static const struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
941 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
942 {
943 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
944 .name = "Master Playback Switch",
945 .subdevice = HDA_SUBDEV_AMP_FLAG,
946 .info = snd_hda_mixer_amp_switch_info,
947 .get = snd_hda_mixer_amp_switch_get,
948 .put = ad1986a_hp_master_sw_put,
949 .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
950 },
951 { } /* end */
952};
953
954
955/*
956 * initialization verbs
957 */
958static const struct hda_verb ad1986a_init_verbs[] = {
959 /* Front, Surround, CLFE DAC; mute as default */
960 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
961 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
962 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
963 /* Downmix - off */
964 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
965 /* HP, Line-Out, Surround, CLFE selectors */
966 {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
967 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
968 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
969 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
970 /* Mono selector */
971 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
972 /* Mic selector: Mic 1/2 pin */
973 {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
974 /* Line-in selector: Line-in */
975 {0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
976 /* Mic 1/2 swap */
977 {0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
978 /* Record selector: mic */
979 {0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
980 /* Mic, Phone, CD, Aux, Line-In amp; mute as default */
981 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
982 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
983 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
984 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
985 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
986 /* PC beep */
987 {0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
988 /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
989 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
990 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
991 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
992 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
993 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
994 /* HP Pin */
995 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
996 /* Front, Surround, CLFE Pins */
997 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
998 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
999 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1000 /* Mono Pin */
1001 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1002 /* Mic Pin */
1003 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1004 /* Line, Aux, CD, Beep-In Pin */
1005 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1006 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1007 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1008 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1009 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1010 { } /* end */
1011};
1012
1013static const struct hda_verb ad1986a_ch2_init[] = {
1014 /* Surround out -> Line In */
1015 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1016 /* Line-in selectors */
1017 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 },
1018 /* CLFE -> Mic in */
1019 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1020 /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */
1021 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
1022 { } /* end */
1023};
1024
1025static const struct hda_verb ad1986a_ch4_init[] = {
1026 /* Surround out -> Surround */
1027 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1028 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
1029 /* CLFE -> Mic in */
1030 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1031 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
1032 { } /* end */
1033};
1034
1035static const struct hda_verb ad1986a_ch6_init[] = {
1036 /* Surround out -> Surround out */
1037 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1038 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
1039 /* CLFE -> CLFE */
1040 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1041 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 },
1042 { } /* end */
1043};
1044
1045static const struct hda_channel_mode ad1986a_modes[3] = {
1046 { 2, ad1986a_ch2_init },
1047 { 4, ad1986a_ch4_init },
1048 { 6, ad1986a_ch6_init },
1049};
1050
1051/* eapd initialization */
1052static const struct hda_verb ad1986a_eapd_init_verbs[] = {
1053 {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
1054 {}
1055};
1056
1057static const struct hda_verb ad1986a_automic_verbs[] = {
1058 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1059 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1060 /*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/
1061 {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
1062 {0x1f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_MIC_EVENT},
1063 {}
1064};
1065
1066/* Ultra initialization */
1067static const struct hda_verb ad1986a_ultra_init[] = {
1068 /* eapd initialization */
1069 { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
1070 /* CLFE -> Mic in */
1071 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2 },
1072 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1073 { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
1074 { } /* end */
1075};
1076
1077/* pin sensing on HP jack */
1078static const struct hda_verb ad1986a_hp_init_verbs[] = {
1079 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT},
1080 {}
1081};
1082
1083static void ad1986a_samsung_p50_unsol_event(struct hda_codec *codec,
1084 unsigned int res)
1085{
1086 switch (res >> 26) {
1087 case AD1986A_HP_EVENT:
1088 ad1986a_hp_automute(codec);
1089 break;
1090 case AD1986A_MIC_EVENT:
1091 ad1986a_automic(codec);
1092 break;
1093 }
1094}
1095
1096static int ad1986a_samsung_p50_init(struct hda_codec *codec)
1097{
1098 ad198x_init(codec);
1099 ad1986a_hp_automute(codec);
1100 ad1986a_automic(codec);
1101 return 0;
1102}
1103
1104
1105/* models */
1106enum {
1107 AD1986A_AUTO,
1108 AD1986A_6STACK,
1109 AD1986A_3STACK,
1110 AD1986A_LAPTOP,
1111 AD1986A_LAPTOP_EAPD,
1112 AD1986A_LAPTOP_AUTOMUTE,
1113 AD1986A_ULTRA,
1114 AD1986A_SAMSUNG,
1115 AD1986A_SAMSUNG_P50,
1116 AD1986A_MODELS
1117};
1118
1119static const char * const ad1986a_models[AD1986A_MODELS] = {
1120 [AD1986A_AUTO] = "auto",
1121 [AD1986A_6STACK] = "6stack",
1122 [AD1986A_3STACK] = "3stack",
1123 [AD1986A_LAPTOP] = "laptop",
1124 [AD1986A_LAPTOP_EAPD] = "laptop-eapd",
1125 [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute",
1126 [AD1986A_ULTRA] = "ultra",
1127 [AD1986A_SAMSUNG] = "samsung",
1128 [AD1986A_SAMSUNG_P50] = "samsung-p50",
1129};
1130
1131static const struct snd_pci_quirk ad1986a_cfg_tbl[] = {
1132 SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD),
1133 SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD),
1134 SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD),
1135 SND_PCI_QUIRK(0x1043, 0x1213, "ASUS A6J", AD1986A_LAPTOP_EAPD),
1136 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS U5F", AD1986A_LAPTOP_EAPD),
1137 SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD),
1138 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD),
1139 SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD),
1140 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS VX1", AD1986A_LAPTOP),
1141 SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK),
1142 SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK),
1143 SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP),
1144 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
1145 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
1146 SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
1147 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
1148 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40-10Q", AD1986A_3STACK),
1149 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
1150 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
1151 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50),
1152 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
1153 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_SAMSUNG),
1154 SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK),
1155 SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP),
1156 SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK),
1157 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_AUTOMUTE),
1158 SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP),
1159 {}
1160};
1161
1162#ifdef CONFIG_PM
1163static const struct hda_amp_list ad1986a_loopbacks[] = {
1164 { 0x13, HDA_OUTPUT, 0 }, /* Mic */
1165 { 0x14, HDA_OUTPUT, 0 }, /* Phone */
1166 { 0x15, HDA_OUTPUT, 0 }, /* CD */
1167 { 0x16, HDA_OUTPUT, 0 }, /* Aux */
1168 { 0x17, HDA_OUTPUT, 0 }, /* Line */
1169 { } /* end */
1170};
1171#endif
1172
1173static int is_jack_available(struct hda_codec *codec, hda_nid_t nid)
1174{
1175 unsigned int conf = snd_hda_codec_get_pincfg(codec, nid);
1176 return get_defcfg_connect(conf) != AC_JACK_PORT_NONE;
1177}
1178#endif /* ENABLE_AD_STATIC_QUIRKS */
1179
1180static int alloc_ad_spec(struct hda_codec *codec) 202static int alloc_ad_spec(struct hda_codec *codec)
1181{ 203{
1182 struct ad198x_spec *spec; 204 struct ad198x_spec *spec;
@@ -1203,6 +225,11 @@ static void ad_fixup_inv_jack_detect(struct hda_codec *codec,
1203 225
1204enum { 226enum {
1205 AD1986A_FIXUP_INV_JACK_DETECT, 227 AD1986A_FIXUP_INV_JACK_DETECT,
228 AD1986A_FIXUP_ULTRA,
229 AD1986A_FIXUP_SAMSUNG,
230 AD1986A_FIXUP_3STACK,
231 AD1986A_FIXUP_LAPTOP,
232 AD1986A_FIXUP_LAPTOP_IMIC,
1206}; 233};
1207 234
1208static const struct hda_fixup ad1986a_fixups[] = { 235static const struct hda_fixup ad1986a_fixups[] = {
@@ -1210,16 +237,86 @@ static const struct hda_fixup ad1986a_fixups[] = {
1210 .type = HDA_FIXUP_FUNC, 237 .type = HDA_FIXUP_FUNC,
1211 .v.func = ad_fixup_inv_jack_detect, 238 .v.func = ad_fixup_inv_jack_detect,
1212 }, 239 },
240 [AD1986A_FIXUP_ULTRA] = {
241 .type = HDA_FIXUP_PINS,
242 .v.pins = (const struct hda_pintbl[]) {
243 { 0x1b, 0x90170110 }, /* speaker */
244 { 0x1d, 0x90a7013e }, /* int mic */
245 {}
246 },
247 },
248 [AD1986A_FIXUP_SAMSUNG] = {
249 .type = HDA_FIXUP_PINS,
250 .v.pins = (const struct hda_pintbl[]) {
251 { 0x1b, 0x90170110 }, /* speaker */
252 { 0x1d, 0x90a7013e }, /* int mic */
253 { 0x20, 0x411111f0 }, /* N/A */
254 { 0x24, 0x411111f0 }, /* N/A */
255 {}
256 },
257 },
258 [AD1986A_FIXUP_3STACK] = {
259 .type = HDA_FIXUP_PINS,
260 .v.pins = (const struct hda_pintbl[]) {
261 { 0x1a, 0x02214021 }, /* headphone */
262 { 0x1b, 0x01014011 }, /* front */
263 { 0x1c, 0x01013012 }, /* surround */
264 { 0x1d, 0x01019015 }, /* clfe */
265 { 0x1e, 0x411111f0 }, /* N/A */
266 { 0x1f, 0x02a190f0 }, /* mic */
267 { 0x20, 0x018130f0 }, /* line-in */
268 {}
269 },
270 },
271 [AD1986A_FIXUP_LAPTOP] = {
272 .type = HDA_FIXUP_PINS,
273 .v.pins = (const struct hda_pintbl[]) {
274 { 0x1a, 0x02214021 }, /* headphone */
275 { 0x1b, 0x90170110 }, /* speaker */
276 { 0x1c, 0x411111f0 }, /* N/A */
277 { 0x1d, 0x411111f0 }, /* N/A */
278 { 0x1e, 0x411111f0 }, /* N/A */
279 { 0x1f, 0x02a191f0 }, /* mic */
280 { 0x20, 0x411111f0 }, /* N/A */
281 {}
282 },
283 },
284 [AD1986A_FIXUP_LAPTOP_IMIC] = {
285 .type = HDA_FIXUP_PINS,
286 .v.pins = (const struct hda_pintbl[]) {
287 { 0x1d, 0x90a7013e }, /* int mic */
288 {}
289 },
290 .chained_before = 1,
291 .chain_id = AD1986A_FIXUP_LAPTOP,
292 },
1213}; 293};
1214 294
1215static const struct snd_pci_quirk ad1986a_fixup_tbl[] = { 295static const struct snd_pci_quirk ad1986a_fixup_tbl[] = {
296 SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_FIXUP_LAPTOP_IMIC),
297 SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8100, "ASUS P5", AD1986A_FIXUP_3STACK),
298 SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8200, "ASUS M2", AD1986A_FIXUP_3STACK),
299 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_FIXUP_3STACK),
300 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_FIXUP_LAPTOP),
301 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_FIXUP_SAMSUNG),
302 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_FIXUP_ULTRA),
1216 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_FIXUP_INV_JACK_DETECT), 303 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_FIXUP_INV_JACK_DETECT),
304 SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_FIXUP_3STACK),
305 SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_FIXUP_3STACK),
306 {}
307};
308
309static const struct hda_model_fixup ad1986a_fixup_models[] = {
310 { .id = AD1986A_FIXUP_3STACK, .name = "3stack" },
311 { .id = AD1986A_FIXUP_LAPTOP, .name = "laptop" },
312 { .id = AD1986A_FIXUP_LAPTOP_IMIC, .name = "laptop-imic" },
313 { .id = AD1986A_FIXUP_LAPTOP_IMIC, .name = "laptop-eapd" }, /* alias */
1217 {} 314 {}
1218}; 315};
1219 316
1220/* 317/*
1221 */ 318 */
1222static int ad1986a_parse_auto_config(struct hda_codec *codec) 319static int patch_ad1986a(struct hda_codec *codec)
1223{ 320{
1224 int err; 321 int err;
1225 struct ad198x_spec *spec; 322 struct ad198x_spec *spec;
@@ -1244,7 +341,8 @@ static int ad1986a_parse_auto_config(struct hda_codec *codec)
1244 */ 341 */
1245 spec->gen.multiout.no_share_stream = 1; 342 spec->gen.multiout.no_share_stream = 1;
1246 343
1247 snd_hda_pick_fixup(codec, NULL, ad1986a_fixup_tbl, ad1986a_fixups); 344 snd_hda_pick_fixup(codec, ad1986a_fixup_models, ad1986a_fixup_tbl,
345 ad1986a_fixups);
1248 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 346 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1249 347
1250 err = ad198x_parse_auto_config(codec); 348 err = ad198x_parse_auto_config(codec);
@@ -1258,330 +356,11 @@ static int ad1986a_parse_auto_config(struct hda_codec *codec)
1258 return 0; 356 return 0;
1259} 357}
1260 358
1261#ifdef ENABLE_AD_STATIC_QUIRKS
1262static int patch_ad1986a(struct hda_codec *codec)
1263{
1264 struct ad198x_spec *spec;
1265 int err, board_config;
1266
1267 board_config = snd_hda_check_board_config(codec, AD1986A_MODELS,
1268 ad1986a_models,
1269 ad1986a_cfg_tbl);
1270 if (board_config < 0) {
1271 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
1272 codec->chip_name);
1273 board_config = AD1986A_AUTO;
1274 }
1275
1276 if (board_config == AD1986A_AUTO)
1277 return ad1986a_parse_auto_config(codec);
1278
1279 err = alloc_ad_spec(codec);
1280 if (err < 0)
1281 return err;
1282 spec = codec->spec;
1283
1284 err = snd_hda_attach_beep_device(codec, 0x19);
1285 if (err < 0) {
1286 ad198x_free(codec);
1287 return err;
1288 }
1289 set_beep_amp(spec, 0x18, 0, HDA_OUTPUT);
1290
1291 spec->multiout.max_channels = 6;
1292 spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
1293 spec->multiout.dac_nids = ad1986a_dac_nids;
1294 spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
1295 spec->num_adc_nids = 1;
1296 spec->adc_nids = ad1986a_adc_nids;
1297 spec->capsrc_nids = ad1986a_capsrc_nids;
1298 spec->input_mux = &ad1986a_capture_source;
1299 spec->num_mixers = 1;
1300 spec->mixers[0] = ad1986a_mixers;
1301 spec->num_init_verbs = 1;
1302 spec->init_verbs[0] = ad1986a_init_verbs;
1303#ifdef CONFIG_PM
1304 spec->loopback.amplist = ad1986a_loopbacks;
1305#endif
1306 spec->vmaster_nid = 0x1b;
1307 codec->inv_eapd = 1; /* AD1986A has the inverted EAPD implementation */
1308
1309 codec->patch_ops = ad198x_patch_ops;
1310
1311 /* override some parameters */
1312 switch (board_config) {
1313 case AD1986A_3STACK:
1314 spec->num_mixers = 2;
1315 spec->mixers[1] = ad1986a_3st_mixers;
1316 spec->num_init_verbs = 2;
1317 spec->init_verbs[1] = ad1986a_ch2_init;
1318 spec->channel_mode = ad1986a_modes;
1319 spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
1320 spec->need_dac_fix = 1;
1321 spec->multiout.max_channels = 2;
1322 spec->multiout.num_dacs = 1;
1323 break;
1324 case AD1986A_LAPTOP:
1325 spec->mixers[0] = ad1986a_laptop_mixers;
1326 spec->multiout.max_channels = 2;
1327 spec->multiout.num_dacs = 1;
1328 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1329 break;
1330 case AD1986A_LAPTOP_EAPD:
1331 spec->num_mixers = 3;
1332 spec->mixers[0] = ad1986a_laptop_master_mixers;
1333 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1334 spec->mixers[2] = ad1986a_laptop_intmic_mixers;
1335 spec->num_init_verbs = 2;
1336 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1337 spec->multiout.max_channels = 2;
1338 spec->multiout.num_dacs = 1;
1339 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1340 if (!is_jack_available(codec, 0x25))
1341 spec->multiout.dig_out_nid = 0;
1342 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1343 break;
1344 case AD1986A_SAMSUNG:
1345 spec->num_mixers = 2;
1346 spec->mixers[0] = ad1986a_laptop_master_mixers;
1347 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1348 spec->num_init_verbs = 3;
1349 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1350 spec->init_verbs[2] = ad1986a_automic_verbs;
1351 spec->multiout.max_channels = 2;
1352 spec->multiout.num_dacs = 1;
1353 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1354 if (!is_jack_available(codec, 0x25))
1355 spec->multiout.dig_out_nid = 0;
1356 spec->input_mux = &ad1986a_automic_capture_source;
1357 codec->patch_ops.unsol_event = ad1986a_automic_unsol_event;
1358 codec->patch_ops.init = ad1986a_automic_init;
1359 break;
1360 case AD1986A_SAMSUNG_P50:
1361 spec->num_mixers = 2;
1362 spec->mixers[0] = ad1986a_automute_master_mixers;
1363 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1364 spec->num_init_verbs = 4;
1365 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1366 spec->init_verbs[2] = ad1986a_automic_verbs;
1367 spec->init_verbs[3] = ad1986a_hp_init_verbs;
1368 spec->multiout.max_channels = 2;
1369 spec->multiout.num_dacs = 1;
1370 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1371 if (!is_jack_available(codec, 0x25))
1372 spec->multiout.dig_out_nid = 0;
1373 spec->input_mux = &ad1986a_automic_capture_source;
1374 codec->patch_ops.unsol_event = ad1986a_samsung_p50_unsol_event;
1375 codec->patch_ops.init = ad1986a_samsung_p50_init;
1376 break;
1377 case AD1986A_LAPTOP_AUTOMUTE:
1378 spec->num_mixers = 3;
1379 spec->mixers[0] = ad1986a_automute_master_mixers;
1380 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1381 spec->mixers[2] = ad1986a_laptop_intmic_mixers;
1382 spec->num_init_verbs = 3;
1383 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1384 spec->init_verbs[2] = ad1986a_hp_init_verbs;
1385 spec->multiout.max_channels = 2;
1386 spec->multiout.num_dacs = 1;
1387 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1388 if (!is_jack_available(codec, 0x25))
1389 spec->multiout.dig_out_nid = 0;
1390 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1391 codec->patch_ops.unsol_event = ad1986a_hp_unsol_event;
1392 codec->patch_ops.init = ad1986a_hp_init;
1393 /* Lenovo N100 seems to report the reversed bit
1394 * for HP jack-sensing
1395 */
1396 spec->inv_jack_detect = 1;
1397 break;
1398 case AD1986A_ULTRA:
1399 spec->mixers[0] = ad1986a_laptop_eapd_mixers;
1400 spec->num_init_verbs = 2;
1401 spec->init_verbs[1] = ad1986a_ultra_init;
1402 spec->multiout.max_channels = 2;
1403 spec->multiout.num_dacs = 1;
1404 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1405 spec->multiout.dig_out_nid = 0;
1406 break;
1407 }
1408
1409 /* AD1986A has a hardware problem that it can't share a stream
1410 * with multiple output pins. The copy of front to surrounds
1411 * causes noisy or silent outputs at a certain timing, e.g.
1412 * changing the volume.
1413 * So, let's disable the shared stream.
1414 */
1415 spec->multiout.no_share_stream = 1;
1416
1417 codec->no_trigger_sense = 1;
1418 codec->no_sticky_stream = 1;
1419
1420 return 0;
1421}
1422#else /* ENABLE_AD_STATIC_QUIRKS */
1423#define patch_ad1986a ad1986a_parse_auto_config
1424#endif /* ENABLE_AD_STATIC_QUIRKS */
1425 359
1426/* 360/*
1427 * AD1983 specific 361 * AD1983 specific
1428 */ 362 */
1429 363
1430#ifdef ENABLE_AD_STATIC_QUIRKS
1431#define AD1983_SPDIF_OUT 0x02
1432#define AD1983_DAC 0x03
1433#define AD1983_ADC 0x04
1434
1435static const hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
1436static const hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
1437static const hda_nid_t ad1983_capsrc_nids[1] = { 0x15 };
1438
1439static const struct hda_input_mux ad1983_capture_source = {
1440 .num_items = 4,
1441 .items = {
1442 { "Mic", 0x0 },
1443 { "Line", 0x1 },
1444 { "Mix", 0x2 },
1445 { "Mix Mono", 0x3 },
1446 },
1447};
1448
1449/*
1450 * SPDIF playback route
1451 */
1452static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1453{
1454 static const char * const texts[] = { "PCM", "ADC" };
1455
1456 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1457 uinfo->count = 1;
1458 uinfo->value.enumerated.items = 2;
1459 if (uinfo->value.enumerated.item > 1)
1460 uinfo->value.enumerated.item = 1;
1461 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1462 return 0;
1463}
1464
1465static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1466{
1467 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1468 struct ad198x_spec *spec = codec->spec;
1469
1470 ucontrol->value.enumerated.item[0] = spec->spdif_route;
1471 return 0;
1472}
1473
1474static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1475{
1476 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1477 struct ad198x_spec *spec = codec->spec;
1478
1479 if (ucontrol->value.enumerated.item[0] > 1)
1480 return -EINVAL;
1481 if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
1482 spec->spdif_route = ucontrol->value.enumerated.item[0];
1483 snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0,
1484 AC_VERB_SET_CONNECT_SEL,
1485 spec->spdif_route);
1486 return 1;
1487 }
1488 return 0;
1489}
1490
1491static const struct snd_kcontrol_new ad1983_mixers[] = {
1492 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1493 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1494 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1495 HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1496 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1497 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1498 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1499 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1500 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1501 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1502 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1503 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1504 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0c, 0x0, HDA_OUTPUT),
1505 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1506 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1507 {
1508 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1509 .name = "Capture Source",
1510 .info = ad198x_mux_enum_info,
1511 .get = ad198x_mux_enum_get,
1512 .put = ad198x_mux_enum_put,
1513 },
1514 {
1515 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1516 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1517 .info = ad1983_spdif_route_info,
1518 .get = ad1983_spdif_route_get,
1519 .put = ad1983_spdif_route_put,
1520 },
1521 { } /* end */
1522};
1523
1524static const struct hda_verb ad1983_init_verbs[] = {
1525 /* Front, HP, Mono; mute as default */
1526 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1527 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1529 /* Beep, PCM, Mic, Line-In: mute */
1530 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1531 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1532 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1533 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1534 /* Front, HP selectors; from Mix */
1535 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1536 {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1537 /* Mono selector; from Mix */
1538 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1539 /* Mic selector; Mic */
1540 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
1541 /* Line-in selector: Line-in */
1542 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
1543 /* Mic boost: 0dB */
1544 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1545 /* Record selector: mic */
1546 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1547 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1548 /* SPDIF route: PCM */
1549 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1550 /* Front Pin */
1551 {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1552 /* HP Pin */
1553 {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1554 /* Mono Pin */
1555 {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1556 /* Mic Pin */
1557 {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1558 /* Line Pin */
1559 {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1560 { } /* end */
1561};
1562
1563#ifdef CONFIG_PM
1564static const struct hda_amp_list ad1983_loopbacks[] = {
1565 { 0x12, HDA_OUTPUT, 0 }, /* Mic */
1566 { 0x13, HDA_OUTPUT, 0 }, /* Line */
1567 { } /* end */
1568};
1569#endif
1570
1571/* models */
1572enum {
1573 AD1983_AUTO,
1574 AD1983_BASIC,
1575 AD1983_MODELS
1576};
1577
1578static const char * const ad1983_models[AD1983_MODELS] = {
1579 [AD1983_AUTO] = "auto",
1580 [AD1983_BASIC] = "basic",
1581};
1582#endif /* ENABLE_AD_STATIC_QUIRKS */
1583
1584
1585/* 364/*
1586 * SPDIF mux control for AD1983 auto-parser 365 * SPDIF mux control for AD1983 auto-parser
1587 */ 366 */
@@ -1656,7 +435,7 @@ static int ad1983_add_spdif_mux_ctl(struct hda_codec *codec)
1656 return 0; 435 return 0;
1657} 436}
1658 437
1659static int ad1983_parse_auto_config(struct hda_codec *codec) 438static int patch_ad1983(struct hda_codec *codec)
1660{ 439{
1661 struct ad198x_spec *spec; 440 struct ad198x_spec *spec;
1662 int err; 441 int err;
@@ -1681,432 +460,11 @@ static int ad1983_parse_auto_config(struct hda_codec *codec)
1681 return err; 460 return err;
1682} 461}
1683 462
1684#ifdef ENABLE_AD_STATIC_QUIRKS
1685static int patch_ad1983(struct hda_codec *codec)
1686{
1687 struct ad198x_spec *spec;
1688 int board_config;
1689 int err;
1690
1691 board_config = snd_hda_check_board_config(codec, AD1983_MODELS,
1692 ad1983_models, NULL);
1693 if (board_config < 0) {
1694 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
1695 codec->chip_name);
1696 board_config = AD1983_AUTO;
1697 }
1698
1699 if (board_config == AD1983_AUTO)
1700 return ad1983_parse_auto_config(codec);
1701
1702 err = alloc_ad_spec(codec);
1703 if (err < 0)
1704 return err;
1705 spec = codec->spec;
1706
1707 err = snd_hda_attach_beep_device(codec, 0x10);
1708 if (err < 0) {
1709 ad198x_free(codec);
1710 return err;
1711 }
1712 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
1713
1714 spec->multiout.max_channels = 2;
1715 spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
1716 spec->multiout.dac_nids = ad1983_dac_nids;
1717 spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
1718 spec->num_adc_nids = 1;
1719 spec->adc_nids = ad1983_adc_nids;
1720 spec->capsrc_nids = ad1983_capsrc_nids;
1721 spec->input_mux = &ad1983_capture_source;
1722 spec->num_mixers = 1;
1723 spec->mixers[0] = ad1983_mixers;
1724 spec->num_init_verbs = 1;
1725 spec->init_verbs[0] = ad1983_init_verbs;
1726 spec->spdif_route = 0;
1727#ifdef CONFIG_PM
1728 spec->loopback.amplist = ad1983_loopbacks;
1729#endif
1730 spec->vmaster_nid = 0x05;
1731
1732 codec->patch_ops = ad198x_patch_ops;
1733
1734 codec->no_trigger_sense = 1;
1735 codec->no_sticky_stream = 1;
1736
1737 return 0;
1738}
1739#else /* ENABLE_AD_STATIC_QUIRKS */
1740#define patch_ad1983 ad1983_parse_auto_config
1741#endif /* ENABLE_AD_STATIC_QUIRKS */
1742
1743 463
1744/* 464/*
1745 * AD1981 HD specific 465 * AD1981 HD specific
1746 */ 466 */
1747 467
1748#ifdef ENABLE_AD_STATIC_QUIRKS
1749#define AD1981_SPDIF_OUT 0x02
1750#define AD1981_DAC 0x03
1751#define AD1981_ADC 0x04
1752
1753static const hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
1754static const hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
1755static const hda_nid_t ad1981_capsrc_nids[1] = { 0x15 };
1756
1757/* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
1758static const struct hda_input_mux ad1981_capture_source = {
1759 .num_items = 7,
1760 .items = {
1761 { "Front Mic", 0x0 },
1762 { "Line", 0x1 },
1763 { "Mix", 0x2 },
1764 { "Mix Mono", 0x3 },
1765 { "CD", 0x4 },
1766 { "Mic", 0x6 },
1767 { "Aux", 0x7 },
1768 },
1769};
1770
1771static const struct snd_kcontrol_new ad1981_mixers[] = {
1772 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1773 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1774 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1775 HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1776 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1777 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1778 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1779 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1780 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1781 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1782 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1783 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1784 HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
1785 HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1786 HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1787 HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1788 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1789 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1790 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1791 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
1792 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1793 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1794 {
1795 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1796 .name = "Capture Source",
1797 .info = ad198x_mux_enum_info,
1798 .get = ad198x_mux_enum_get,
1799 .put = ad198x_mux_enum_put,
1800 },
1801 /* identical with AD1983 */
1802 {
1803 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1804 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1805 .info = ad1983_spdif_route_info,
1806 .get = ad1983_spdif_route_get,
1807 .put = ad1983_spdif_route_put,
1808 },
1809 { } /* end */
1810};
1811
1812static const struct hda_verb ad1981_init_verbs[] = {
1813 /* Front, HP, Mono; mute as default */
1814 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1815 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1816 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1817 /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
1818 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1819 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1820 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1821 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1822 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1823 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1824 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1825 /* Front, HP selectors; from Mix */
1826 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1827 {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1828 /* Mono selector; from Mix */
1829 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1830 /* Mic Mixer; select Front Mic */
1831 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1832 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1833 /* Mic boost: 0dB */
1834 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1835 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1836 /* Record selector: Front mic */
1837 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1838 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1839 /* SPDIF route: PCM */
1840 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1841 /* Front Pin */
1842 {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1843 /* HP Pin */
1844 {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1845 /* Mono Pin */
1846 {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1847 /* Front & Rear Mic Pins */
1848 {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1849 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1850 /* Line Pin */
1851 {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1852 /* Digital Beep */
1853 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
1854 /* Line-Out as Input: disabled */
1855 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1856 { } /* end */
1857};
1858
1859#ifdef CONFIG_PM
1860static const struct hda_amp_list ad1981_loopbacks[] = {
1861 { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
1862 { 0x13, HDA_OUTPUT, 0 }, /* Line */
1863 { 0x1b, HDA_OUTPUT, 0 }, /* Aux */
1864 { 0x1c, HDA_OUTPUT, 0 }, /* Mic */
1865 { 0x1d, HDA_OUTPUT, 0 }, /* CD */
1866 { } /* end */
1867};
1868#endif
1869
1870/*
1871 * Patch for HP nx6320
1872 *
1873 * nx6320 uses EAPD in the reverse way - EAPD-on means the internal
1874 * speaker output enabled _and_ mute-LED off.
1875 */
1876
1877#define AD1981_HP_EVENT 0x37
1878#define AD1981_MIC_EVENT 0x38
1879
1880static const struct hda_verb ad1981_hp_init_verbs[] = {
1881 {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */
1882 /* pin sensing on HP and Mic jacks */
1883 {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1884 {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1885 {}
1886};
1887
1888/* turn on/off EAPD (+ mute HP) as a master switch */
1889static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1890 struct snd_ctl_elem_value *ucontrol)
1891{
1892 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1893 struct ad198x_spec *spec = codec->spec;
1894
1895 if (! ad198x_eapd_put(kcontrol, ucontrol))
1896 return 0;
1897 /* change speaker pin appropriately */
1898 snd_hda_set_pin_ctl(codec, 0x05, spec->cur_eapd ? PIN_OUT : 0);
1899 /* toggle HP mute appropriately */
1900 snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
1901 HDA_AMP_MUTE,
1902 spec->cur_eapd ? 0 : HDA_AMP_MUTE);
1903 return 1;
1904}
1905
1906/* bind volumes of both NID 0x05 and 0x06 */
1907static const struct hda_bind_ctls ad1981_hp_bind_master_vol = {
1908 .ops = &snd_hda_bind_vol,
1909 .values = {
1910 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
1911 HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT),
1912 0
1913 },
1914};
1915
1916/* mute internal speaker if HP is plugged */
1917static void ad1981_hp_automute(struct hda_codec *codec)
1918{
1919 unsigned int present;
1920
1921 present = snd_hda_jack_detect(codec, 0x06);
1922 snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0,
1923 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
1924}
1925
1926/* toggle input of built-in and mic jack appropriately */
1927static void ad1981_hp_automic(struct hda_codec *codec)
1928{
1929 static const struct hda_verb mic_jack_on[] = {
1930 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1931 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1932 {}
1933 };
1934 static const struct hda_verb mic_jack_off[] = {
1935 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1936 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1937 {}
1938 };
1939 unsigned int present;
1940
1941 present = snd_hda_jack_detect(codec, 0x08);
1942 if (present)
1943 snd_hda_sequence_write(codec, mic_jack_on);
1944 else
1945 snd_hda_sequence_write(codec, mic_jack_off);
1946}
1947
1948/* unsolicited event for HP jack sensing */
1949static void ad1981_hp_unsol_event(struct hda_codec *codec,
1950 unsigned int res)
1951{
1952 res >>= 26;
1953 switch (res) {
1954 case AD1981_HP_EVENT:
1955 ad1981_hp_automute(codec);
1956 break;
1957 case AD1981_MIC_EVENT:
1958 ad1981_hp_automic(codec);
1959 break;
1960 }
1961}
1962
1963static const struct hda_input_mux ad1981_hp_capture_source = {
1964 .num_items = 3,
1965 .items = {
1966 { "Mic", 0x0 },
1967 { "Dock Mic", 0x1 },
1968 { "Mix", 0x2 },
1969 },
1970};
1971
1972static const struct snd_kcontrol_new ad1981_hp_mixers[] = {
1973 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1974 {
1975 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1976 .subdevice = HDA_SUBDEV_NID_FLAG | 0x05,
1977 .name = "Master Playback Switch",
1978 .info = ad198x_eapd_info,
1979 .get = ad198x_eapd_get,
1980 .put = ad1981_hp_master_sw_put,
1981 .private_value = 0x05,
1982 },
1983 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1984 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1985#if 0
1986 /* FIXME: analog mic/line loopback doesn't work with my tests...
1987 * (although recording is OK)
1988 */
1989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1990 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1991 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1992 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1993 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1994 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1995 /* FIXME: does this laptop have analog CD connection? */
1996 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1997 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1998#endif
1999 HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
2000 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
2001 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
2002 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
2003 {
2004 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2005 .name = "Capture Source",
2006 .info = ad198x_mux_enum_info,
2007 .get = ad198x_mux_enum_get,
2008 .put = ad198x_mux_enum_put,
2009 },
2010 { } /* end */
2011};
2012
2013/* initialize jack-sensing, too */
2014static int ad1981_hp_init(struct hda_codec *codec)
2015{
2016 ad198x_init(codec);
2017 ad1981_hp_automute(codec);
2018 ad1981_hp_automic(codec);
2019 return 0;
2020}
2021
2022/* configuration for Toshiba Laptops */
2023static const struct hda_verb ad1981_toshiba_init_verbs[] = {
2024 {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
2025 /* pin sensing on HP and Mic jacks */
2026 {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
2027 {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
2028 {}
2029};
2030
2031static const struct snd_kcontrol_new ad1981_toshiba_mixers[] = {
2032 HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT),
2033 HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT),
2034 { }
2035};
2036
2037/* configuration for Lenovo Thinkpad T60 */
2038static const struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
2039 HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
2040 HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
2041 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
2042 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
2043 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
2044 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
2045 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
2046 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
2047 HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
2048 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
2049 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
2050 {
2051 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2052 .name = "Capture Source",
2053 .info = ad198x_mux_enum_info,
2054 .get = ad198x_mux_enum_get,
2055 .put = ad198x_mux_enum_put,
2056 },
2057 /* identical with AD1983 */
2058 {
2059 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2060 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
2061 .info = ad1983_spdif_route_info,
2062 .get = ad1983_spdif_route_get,
2063 .put = ad1983_spdif_route_put,
2064 },
2065 { } /* end */
2066};
2067
2068static const struct hda_input_mux ad1981_thinkpad_capture_source = {
2069 .num_items = 3,
2070 .items = {
2071 { "Mic", 0x0 },
2072 { "Mix", 0x2 },
2073 { "CD", 0x4 },
2074 },
2075};
2076
2077/* models */
2078enum {
2079 AD1981_AUTO,
2080 AD1981_BASIC,
2081 AD1981_HP,
2082 AD1981_THINKPAD,
2083 AD1981_TOSHIBA,
2084 AD1981_MODELS
2085};
2086
2087static const char * const ad1981_models[AD1981_MODELS] = {
2088 [AD1981_AUTO] = "auto",
2089 [AD1981_HP] = "hp",
2090 [AD1981_THINKPAD] = "thinkpad",
2091 [AD1981_BASIC] = "basic",
2092 [AD1981_TOSHIBA] = "toshiba"
2093};
2094
2095static const struct snd_pci_quirk ad1981_cfg_tbl[] = {
2096 SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
2097 SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD),
2098 /* All HP models */
2099 SND_PCI_QUIRK_VENDOR(0x103c, "HP nx", AD1981_HP),
2100 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
2101 /* Lenovo Thinkpad T60/X60/Z6xx */
2102 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1981_THINKPAD),
2103 /* HP nx6320 (reversed SSID, H/W bug) */
2104 SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP),
2105 {}
2106};
2107#endif /* ENABLE_AD_STATIC_QUIRKS */
2108
2109
2110/* follow EAPD via vmaster hook */ 468/* follow EAPD via vmaster hook */
2111static void ad_vmaster_eapd_hook(void *private_data, int enabled) 469static void ad_vmaster_eapd_hook(void *private_data, int enabled)
2112{ 470{
@@ -2172,7 +530,7 @@ static const struct snd_pci_quirk ad1981_fixup_tbl[] = {
2172 {} 530 {}
2173}; 531};
2174 532
2175static int ad1981_parse_auto_config(struct hda_codec *codec) 533static int patch_ad1981(struct hda_codec *codec)
2176{ 534{
2177 struct ad198x_spec *spec; 535 struct ad198x_spec *spec;
2178 int err; 536 int err;
@@ -2205,110 +563,6 @@ static int ad1981_parse_auto_config(struct hda_codec *codec)
2205 return err; 563 return err;
2206} 564}
2207 565
2208#ifdef ENABLE_AD_STATIC_QUIRKS
2209static int patch_ad1981(struct hda_codec *codec)
2210{
2211 struct ad198x_spec *spec;
2212 int err, board_config;
2213
2214 board_config = snd_hda_check_board_config(codec, AD1981_MODELS,
2215 ad1981_models,
2216 ad1981_cfg_tbl);
2217 if (board_config < 0) {
2218 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
2219 codec->chip_name);
2220 board_config = AD1981_AUTO;
2221 }
2222
2223 if (board_config == AD1981_AUTO)
2224 return ad1981_parse_auto_config(codec);
2225
2226 err = alloc_ad_spec(codec);
2227 if (err < 0)
2228 return -ENOMEM;
2229 spec = codec->spec;
2230
2231 err = snd_hda_attach_beep_device(codec, 0x10);
2232 if (err < 0) {
2233 ad198x_free(codec);
2234 return err;
2235 }
2236 set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT);
2237
2238 spec->multiout.max_channels = 2;
2239 spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
2240 spec->multiout.dac_nids = ad1981_dac_nids;
2241 spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
2242 spec->num_adc_nids = 1;
2243 spec->adc_nids = ad1981_adc_nids;
2244 spec->capsrc_nids = ad1981_capsrc_nids;
2245 spec->input_mux = &ad1981_capture_source;
2246 spec->num_mixers = 1;
2247 spec->mixers[0] = ad1981_mixers;
2248 spec->num_init_verbs = 1;
2249 spec->init_verbs[0] = ad1981_init_verbs;
2250 spec->spdif_route = 0;
2251#ifdef CONFIG_PM
2252 spec->loopback.amplist = ad1981_loopbacks;
2253#endif
2254 spec->vmaster_nid = 0x05;
2255
2256 codec->patch_ops = ad198x_patch_ops;
2257
2258 /* override some parameters */
2259 switch (board_config) {
2260 case AD1981_HP:
2261 spec->mixers[0] = ad1981_hp_mixers;
2262 spec->num_init_verbs = 2;
2263 spec->init_verbs[1] = ad1981_hp_init_verbs;
2264 if (!is_jack_available(codec, 0x0a))
2265 spec->multiout.dig_out_nid = 0;
2266 spec->input_mux = &ad1981_hp_capture_source;
2267
2268 codec->patch_ops.init = ad1981_hp_init;
2269 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
2270 /* set the upper-limit for mixer amp to 0dB for avoiding the
2271 * possible damage by overloading
2272 */
2273 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
2274 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
2275 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2276 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2277 (1 << AC_AMPCAP_MUTE_SHIFT));
2278 break;
2279 case AD1981_THINKPAD:
2280 spec->mixers[0] = ad1981_thinkpad_mixers;
2281 spec->input_mux = &ad1981_thinkpad_capture_source;
2282 /* set the upper-limit for mixer amp to 0dB for avoiding the
2283 * possible damage by overloading
2284 */
2285 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
2286 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
2287 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2288 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2289 (1 << AC_AMPCAP_MUTE_SHIFT));
2290 break;
2291 case AD1981_TOSHIBA:
2292 spec->mixers[0] = ad1981_hp_mixers;
2293 spec->mixers[1] = ad1981_toshiba_mixers;
2294 spec->num_init_verbs = 2;
2295 spec->init_verbs[1] = ad1981_toshiba_init_verbs;
2296 spec->multiout.dig_out_nid = 0;
2297 spec->input_mux = &ad1981_hp_capture_source;
2298 codec->patch_ops.init = ad1981_hp_init;
2299 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
2300 break;
2301 }
2302
2303 codec->no_trigger_sense = 1;
2304 codec->no_sticky_stream = 1;
2305
2306 return 0;
2307}
2308#else /* ENABLE_AD_STATIC_QUIRKS */
2309#define patch_ad1981 ad1981_parse_auto_config
2310#endif /* ENABLE_AD_STATIC_QUIRKS */
2311
2312 566
2313/* 567/*
2314 * AD1988 568 * AD1988
@@ -2395,90 +649,7 @@ static int patch_ad1981(struct hda_codec *codec)
2395 * E/F quad mic array 649 * E/F quad mic array
2396 */ 650 */
2397 651
2398
2399#ifdef ENABLE_AD_STATIC_QUIRKS 652#ifdef ENABLE_AD_STATIC_QUIRKS
2400/* models */
2401enum {
2402 AD1988_AUTO,
2403 AD1988_6STACK,
2404 AD1988_6STACK_DIG,
2405 AD1988_3STACK,
2406 AD1988_3STACK_DIG,
2407 AD1988_LAPTOP,
2408 AD1988_LAPTOP_DIG,
2409 AD1988_MODEL_LAST,
2410};
2411
2412/* reivision id to check workarounds */
2413#define AD1988A_REV2 0x100200
2414
2415#define is_rev2(codec) \
2416 ((codec)->vendor_id == 0x11d41988 && \
2417 (codec)->revision_id == AD1988A_REV2)
2418
2419/*
2420 * mixers
2421 */
2422
2423static const hda_nid_t ad1988_6stack_dac_nids[4] = {
2424 0x04, 0x06, 0x05, 0x0a
2425};
2426
2427static const hda_nid_t ad1988_3stack_dac_nids[3] = {
2428 0x04, 0x05, 0x0a
2429};
2430
2431/* for AD1988A revision-2, DAC2-4 are swapped */
2432static const hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
2433 0x04, 0x05, 0x0a, 0x06
2434};
2435
2436static const hda_nid_t ad1988_alt_dac_nid[1] = {
2437 0x03
2438};
2439
2440static const hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
2441 0x04, 0x0a, 0x06
2442};
2443
2444static const hda_nid_t ad1988_adc_nids[3] = {
2445 0x08, 0x09, 0x0f
2446};
2447
2448static const hda_nid_t ad1988_capsrc_nids[3] = {
2449 0x0c, 0x0d, 0x0e
2450};
2451
2452#define AD1988_SPDIF_OUT 0x02
2453#define AD1988_SPDIF_OUT_HDMI 0x0b
2454#define AD1988_SPDIF_IN 0x07
2455
2456static const hda_nid_t ad1989b_slave_dig_outs[] = {
2457 AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0
2458};
2459
2460static const struct hda_input_mux ad1988_6stack_capture_source = {
2461 .num_items = 5,
2462 .items = {
2463 { "Front Mic", 0x1 }, /* port-B */
2464 { "Line", 0x2 }, /* port-C */
2465 { "Mic", 0x4 }, /* port-E */
2466 { "CD", 0x5 },
2467 { "Mix", 0x9 },
2468 },
2469};
2470
2471static const struct hda_input_mux ad1988_laptop_capture_source = {
2472 .num_items = 3,
2473 .items = {
2474 { "Mic/Line", 0x1 }, /* port-B */
2475 { "CD", 0x5 },
2476 { "Mix", 0x9 },
2477 },
2478};
2479
2480/*
2481 */
2482static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, 653static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
2483 struct snd_ctl_elem_info *uinfo) 654 struct snd_ctl_elem_info *uinfo)
2484{ 655{
@@ -2509,569 +680,6 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
2509 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 680 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
2510 return err; 681 return err;
2511} 682}
2512
2513/* 6-stack mode */
2514static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
2515 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2516 HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2517 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
2518 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
2519 HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2520 { } /* end */
2521};
2522
2523static const struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
2524 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2525 HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
2526 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
2527 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT),
2528 HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2529 { } /* end */
2530};
2531
2532static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2533 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2534 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2535 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
2536 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
2537 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
2538 HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
2539 HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2540 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2541
2542 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2543 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2544 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2545 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2546 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2547 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2548 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2549 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2550
2551 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2552 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2553
2554 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2555 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2556 { } /* end */
2557};
2558
2559/* 3-stack mode */
2560static const struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
2561 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2562 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2563 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
2564 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
2565 { } /* end */
2566};
2567
2568static const struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
2569 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2570 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2571 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT),
2572 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT),
2573 { } /* end */
2574};
2575
2576static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2577 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2578 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2579 HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
2580 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
2581 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT),
2582 HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2583 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2584
2585 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2586 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2587 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2588 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2589 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2590 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2591 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2592 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2593
2594 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2595 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2596
2597 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2598 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2599 {
2600 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2601 .name = "Channel Mode",
2602 .info = ad198x_ch_mode_info,
2603 .get = ad198x_ch_mode_get,
2604 .put = ad198x_ch_mode_put,
2605 },
2606
2607 { } /* end */
2608};
2609
2610/* laptop mode */
2611static const struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2612 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2613 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2614 HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
2615 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2616
2617 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2618 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2619 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2620 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2621 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2622 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2623
2624 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2625 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2626
2627 HDA_CODEC_VOLUME("Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2628
2629 {
2630 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2631 .name = "External Amplifier",
2632 .subdevice = HDA_SUBDEV_NID_FLAG | 0x12,
2633 .info = ad198x_eapd_info,
2634 .get = ad198x_eapd_get,
2635 .put = ad198x_eapd_put,
2636 .private_value = 0x12, /* port-D */
2637 },
2638
2639 { } /* end */
2640};
2641
2642/* capture */
2643static const struct snd_kcontrol_new ad1988_capture_mixers[] = {
2644 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2645 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2646 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
2647 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
2648 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT),
2649 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT),
2650 {
2651 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2652 /* The multiple "Capture Source" controls confuse alsamixer
2653 * So call somewhat different..
2654 */
2655 /* .name = "Capture Source", */
2656 .name = "Input Source",
2657 .count = 3,
2658 .info = ad198x_mux_enum_info,
2659 .get = ad198x_mux_enum_get,
2660 .put = ad198x_mux_enum_put,
2661 },
2662 { } /* end */
2663};
2664
2665static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
2666 struct snd_ctl_elem_info *uinfo)
2667{
2668 static const char * const texts[] = {
2669 "PCM", "ADC1", "ADC2", "ADC3"
2670 };
2671 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2672 uinfo->count = 1;
2673 uinfo->value.enumerated.items = 4;
2674 if (uinfo->value.enumerated.item >= 4)
2675 uinfo->value.enumerated.item = 3;
2676 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2677 return 0;
2678}
2679
2680static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
2681 struct snd_ctl_elem_value *ucontrol)
2682{
2683 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2684 unsigned int sel;
2685
2686 sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE,
2687 AC_AMP_GET_INPUT);
2688 if (!(sel & 0x80))
2689 ucontrol->value.enumerated.item[0] = 0;
2690 else {
2691 sel = snd_hda_codec_read(codec, 0x0b, 0,
2692 AC_VERB_GET_CONNECT_SEL, 0);
2693 if (sel < 3)
2694 sel++;
2695 else
2696 sel = 0;
2697 ucontrol->value.enumerated.item[0] = sel;
2698 }
2699 return 0;
2700}
2701
2702static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
2703 struct snd_ctl_elem_value *ucontrol)
2704{
2705 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2706 unsigned int val, sel;
2707 int change;
2708
2709 val = ucontrol->value.enumerated.item[0];
2710 if (val > 3)
2711 return -EINVAL;
2712 if (!val) {
2713 sel = snd_hda_codec_read(codec, 0x1d, 0,
2714 AC_VERB_GET_AMP_GAIN_MUTE,
2715 AC_AMP_GET_INPUT);
2716 change = sel & 0x80;
2717 if (change) {
2718 snd_hda_codec_write_cache(codec, 0x1d, 0,
2719 AC_VERB_SET_AMP_GAIN_MUTE,
2720 AMP_IN_UNMUTE(0));
2721 snd_hda_codec_write_cache(codec, 0x1d, 0,
2722 AC_VERB_SET_AMP_GAIN_MUTE,
2723 AMP_IN_MUTE(1));
2724 }
2725 } else {
2726 sel = snd_hda_codec_read(codec, 0x1d, 0,
2727 AC_VERB_GET_AMP_GAIN_MUTE,
2728 AC_AMP_GET_INPUT | 0x01);
2729 change = sel & 0x80;
2730 if (change) {
2731 snd_hda_codec_write_cache(codec, 0x1d, 0,
2732 AC_VERB_SET_AMP_GAIN_MUTE,
2733 AMP_IN_MUTE(0));
2734 snd_hda_codec_write_cache(codec, 0x1d, 0,
2735 AC_VERB_SET_AMP_GAIN_MUTE,
2736 AMP_IN_UNMUTE(1));
2737 }
2738 sel = snd_hda_codec_read(codec, 0x0b, 0,
2739 AC_VERB_GET_CONNECT_SEL, 0) + 1;
2740 change |= sel != val;
2741 if (change)
2742 snd_hda_codec_write_cache(codec, 0x0b, 0,
2743 AC_VERB_SET_CONNECT_SEL,
2744 val - 1);
2745 }
2746 return change;
2747}
2748
2749static const struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2750 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2751 {
2752 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2753 .name = "IEC958 Playback Source",
2754 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
2755 .info = ad1988_spdif_playback_source_info,
2756 .get = ad1988_spdif_playback_source_get,
2757 .put = ad1988_spdif_playback_source_put,
2758 },
2759 { } /* end */
2760};
2761
2762static const struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
2763 HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
2764 { } /* end */
2765};
2766
2767static const struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
2768 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2769 HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
2770 { } /* end */
2771};
2772
2773/*
2774 * initialization verbs
2775 */
2776
2777/*
2778 * for 6-stack (+dig)
2779 */
2780static const struct hda_verb ad1988_6stack_init_verbs[] = {
2781 /* Front, Surround, CLFE, side DAC; unmute as default */
2782 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2783 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2784 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2785 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2786 /* Port-A front headphon path */
2787 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2788 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2790 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2791 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2792 /* Port-D line-out path */
2793 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2794 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2795 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2796 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2797 /* Port-F surround path */
2798 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2799 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2800 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2801 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2802 /* Port-G CLFE path */
2803 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2804 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2805 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2806 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2807 /* Port-H side path */
2808 {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2809 {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2810 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2811 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2812 /* Mono out path */
2813 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2814 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2815 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2816 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2817 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2818 /* Port-B front mic-in path */
2819 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2820 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2821 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2822 /* Port-C line-in path */
2823 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2824 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2825 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2826 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2827 /* Port-E mic-in path */
2828 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2829 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2830 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2831 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2832 /* Analog CD Input */
2833 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2834 /* Analog Mix output amp */
2835 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2836
2837 { }
2838};
2839
2840static const struct hda_verb ad1988_6stack_fp_init_verbs[] = {
2841 /* Headphone; unmute as default */
2842 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2843 /* Port-A front headphon path */
2844 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2845 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2846 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2847 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2848 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2849
2850 { }
2851};
2852
2853static const struct hda_verb ad1988_capture_init_verbs[] = {
2854 /* mute analog mix */
2855 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2856 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2857 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2858 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2859 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2860 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2861 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2862 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2863 /* select ADCs - front-mic */
2864 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2865 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2866 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2867
2868 { }
2869};
2870
2871static const struct hda_verb ad1988_spdif_init_verbs[] = {
2872 /* SPDIF out sel */
2873 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2874 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
2875 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2876 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2877 /* SPDIF out pin */
2878 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2879
2880 { }
2881};
2882
2883static const struct hda_verb ad1988_spdif_in_init_verbs[] = {
2884 /* unmute SPDIF input pin */
2885 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2886 { }
2887};
2888
2889/* AD1989 has no ADC -> SPDIF route */
2890static const struct hda_verb ad1989_spdif_init_verbs[] = {
2891 /* SPDIF-1 out pin */
2892 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2893 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2894 /* SPDIF-2/HDMI out pin */
2895 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2896 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2897 { }
2898};
2899
2900/*
2901 * verbs for 3stack (+dig)
2902 */
2903static const struct hda_verb ad1988_3stack_ch2_init[] = {
2904 /* set port-C to line-in */
2905 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2906 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2907 /* set port-E to mic-in */
2908 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2909 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2910 { } /* end */
2911};
2912
2913static const struct hda_verb ad1988_3stack_ch6_init[] = {
2914 /* set port-C to surround out */
2915 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2916 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2917 /* set port-E to CLFE out */
2918 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2919 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2920 { } /* end */
2921};
2922
2923static const struct hda_channel_mode ad1988_3stack_modes[2] = {
2924 { 2, ad1988_3stack_ch2_init },
2925 { 6, ad1988_3stack_ch6_init },
2926};
2927
2928static const struct hda_verb ad1988_3stack_init_verbs[] = {
2929 /* Front, Surround, CLFE, side DAC; unmute as default */
2930 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2931 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2932 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2933 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2934 /* Port-A front headphon path */
2935 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2936 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2937 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2938 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2939 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2940 /* Port-D line-out path */
2941 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2942 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2943 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2944 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2945 /* Mono out path */
2946 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2947 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2948 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2949 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2950 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2951 /* Port-B front mic-in path */
2952 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2953 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2954 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2955 /* Port-C line-in/surround path - 6ch mode as default */
2956 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2957 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2958 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2959 {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
2960 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2961 /* Port-E mic-in/CLFE path - 6ch mode as default */
2962 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2963 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2964 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2965 {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */
2966 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2967 /* mute analog mix */
2968 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2969 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2970 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2971 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2972 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2973 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2974 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2975 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2976 /* select ADCs - front-mic */
2977 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2978 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2979 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2980 /* Analog Mix output amp */
2981 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2982 { }
2983};
2984
2985/*
2986 * verbs for laptop mode (+dig)
2987 */
2988static const struct hda_verb ad1988_laptop_hp_on[] = {
2989 /* unmute port-A and mute port-D */
2990 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2991 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2992 { } /* end */
2993};
2994static const struct hda_verb ad1988_laptop_hp_off[] = {
2995 /* mute port-A and unmute port-D */
2996 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2997 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2998 { } /* end */
2999};
3000
3001#define AD1988_HP_EVENT 0x01
3002
3003static const struct hda_verb ad1988_laptop_init_verbs[] = {
3004 /* Front, Surround, CLFE, side DAC; unmute as default */
3005 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3006 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3007 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3008 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3009 /* Port-A front headphon path */
3010 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
3011 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3012 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3013 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3014 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3015 /* unsolicited event for pin-sense */
3016 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
3017 /* Port-D line-out path + EAPD */
3018 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3019 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3020 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3021 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3022 {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
3023 /* Mono out path */
3024 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
3025 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3026 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3027 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3028 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
3029 /* Port-B mic-in path */
3030 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3031 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3032 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3033 /* Port-C docking station - try to output */
3034 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3035 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3036 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3037 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
3038 /* mute analog mix */
3039 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3040 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3041 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3042 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3043 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3044 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
3045 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3046 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3047 /* select ADCs - mic */
3048 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
3049 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
3050 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
3051 /* Analog Mix output amp */
3052 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3053 { }
3054};
3055
3056static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
3057{
3058 if ((res >> 26) != AD1988_HP_EVENT)
3059 return;
3060 if (snd_hda_jack_detect(codec, 0x11))
3061 snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
3062 else
3063 snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
3064}
3065
3066#ifdef CONFIG_PM
3067static const struct hda_amp_list ad1988_loopbacks[] = {
3068 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3069 { 0x20, HDA_INPUT, 1 }, /* Line */
3070 { 0x20, HDA_INPUT, 4 }, /* Mic */
3071 { 0x20, HDA_INPUT, 6 }, /* CD */
3072 { } /* end */
3073};
3074#endif
3075#endif /* ENABLE_AD_STATIC_QUIRKS */ 683#endif /* ENABLE_AD_STATIC_QUIRKS */
3076 684
3077static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol, 685static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol,
@@ -3220,7 +828,34 @@ static int ad1988_add_spdif_mux_ctl(struct hda_codec *codec)
3220/* 828/*
3221 */ 829 */
3222 830
3223static int ad1988_parse_auto_config(struct hda_codec *codec) 831enum {
832 AD1988_FIXUP_6STACK_DIG,
833};
834
835static const struct hda_fixup ad1988_fixups[] = {
836 [AD1988_FIXUP_6STACK_DIG] = {
837 .type = HDA_FIXUP_PINS,
838 .v.pins = (const struct hda_pintbl[]) {
839 { 0x11, 0x02214130 }, /* front-hp */
840 { 0x12, 0x01014010 }, /* line-out */
841 { 0x14, 0x02a19122 }, /* front-mic */
842 { 0x15, 0x01813021 }, /* line-in */
843 { 0x16, 0x01011012 }, /* line-out */
844 { 0x17, 0x01a19020 }, /* mic */
845 { 0x1b, 0x0145f1f0 }, /* SPDIF */
846 { 0x24, 0x01016011 }, /* line-out */
847 { 0x25, 0x01012013 }, /* line-out */
848 { }
849 }
850 },
851};
852
853static const struct hda_model_fixup ad1988_fixup_models[] = {
854 { .id = AD1988_FIXUP_6STACK_DIG, .name = "6stack-dig" },
855 {}
856};
857
858static int patch_ad1988(struct hda_codec *codec)
3224{ 859{
3225 struct ad198x_spec *spec; 860 struct ad198x_spec *spec;
3226 int err; 861 int err;
@@ -3234,12 +869,19 @@ static int ad1988_parse_auto_config(struct hda_codec *codec)
3234 spec->gen.mixer_merge_nid = 0x21; 869 spec->gen.mixer_merge_nid = 0x21;
3235 spec->gen.beep_nid = 0x10; 870 spec->gen.beep_nid = 0x10;
3236 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 871 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
872
873 snd_hda_pick_fixup(codec, ad1988_fixup_models, NULL, ad1988_fixups);
874 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
875
3237 err = ad198x_parse_auto_config(codec); 876 err = ad198x_parse_auto_config(codec);
3238 if (err < 0) 877 if (err < 0)
3239 goto error; 878 goto error;
3240 err = ad1988_add_spdif_mux_ctl(codec); 879 err = ad1988_add_spdif_mux_ctl(codec);
3241 if (err < 0) 880 if (err < 0)
3242 goto error; 881 goto error;
882
883 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
884
3243 return 0; 885 return 0;
3244 886
3245 error: 887 error:
@@ -3247,169 +889,6 @@ static int ad1988_parse_auto_config(struct hda_codec *codec)
3247 return err; 889 return err;
3248} 890}
3249 891
3250/*
3251 */
3252
3253#ifdef ENABLE_AD_STATIC_QUIRKS
3254static const char * const ad1988_models[AD1988_MODEL_LAST] = {
3255 [AD1988_6STACK] = "6stack",
3256 [AD1988_6STACK_DIG] = "6stack-dig",
3257 [AD1988_3STACK] = "3stack",
3258 [AD1988_3STACK_DIG] = "3stack-dig",
3259 [AD1988_LAPTOP] = "laptop",
3260 [AD1988_LAPTOP_DIG] = "laptop-dig",
3261 [AD1988_AUTO] = "auto",
3262};
3263
3264static const struct snd_pci_quirk ad1988_cfg_tbl[] = {
3265 SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
3266 SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
3267 SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
3268 SND_PCI_QUIRK(0x1043, 0x82c0, "Asus M3N-HT Deluxe", AD1988_6STACK_DIG),
3269 SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG),
3270 {}
3271};
3272
3273static int patch_ad1988(struct hda_codec *codec)
3274{
3275 struct ad198x_spec *spec;
3276 int err, board_config;
3277
3278 board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
3279 ad1988_models, ad1988_cfg_tbl);
3280 if (board_config < 0) {
3281 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3282 codec->chip_name);
3283 board_config = AD1988_AUTO;
3284 }
3285
3286 if (board_config == AD1988_AUTO)
3287 return ad1988_parse_auto_config(codec);
3288
3289 err = alloc_ad_spec(codec);
3290 if (err < 0)
3291 return err;
3292 spec = codec->spec;
3293
3294 if (is_rev2(codec))
3295 snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
3296
3297 err = snd_hda_attach_beep_device(codec, 0x10);
3298 if (err < 0) {
3299 ad198x_free(codec);
3300 return err;
3301 }
3302 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3303
3304 if (!spec->multiout.hp_nid)
3305 spec->multiout.hp_nid = ad1988_alt_dac_nid[0];
3306 switch (board_config) {
3307 case AD1988_6STACK:
3308 case AD1988_6STACK_DIG:
3309 spec->multiout.max_channels = 8;
3310 spec->multiout.num_dacs = 4;
3311 if (is_rev2(codec))
3312 spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
3313 else
3314 spec->multiout.dac_nids = ad1988_6stack_dac_nids;
3315 spec->input_mux = &ad1988_6stack_capture_source;
3316 spec->num_mixers = 2;
3317 if (is_rev2(codec))
3318 spec->mixers[0] = ad1988_6stack_mixers1_rev2;
3319 else
3320 spec->mixers[0] = ad1988_6stack_mixers1;
3321 spec->mixers[1] = ad1988_6stack_mixers2;
3322 spec->num_init_verbs = 1;
3323 spec->init_verbs[0] = ad1988_6stack_init_verbs;
3324 if (board_config == AD1988_6STACK_DIG) {
3325 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3326 spec->dig_in_nid = AD1988_SPDIF_IN;
3327 }
3328 break;
3329 case AD1988_3STACK:
3330 case AD1988_3STACK_DIG:
3331 spec->multiout.max_channels = 6;
3332 spec->multiout.num_dacs = 3;
3333 if (is_rev2(codec))
3334 spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
3335 else
3336 spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3337 spec->input_mux = &ad1988_6stack_capture_source;
3338 spec->channel_mode = ad1988_3stack_modes;
3339 spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
3340 spec->num_mixers = 2;
3341 if (is_rev2(codec))
3342 spec->mixers[0] = ad1988_3stack_mixers1_rev2;
3343 else
3344 spec->mixers[0] = ad1988_3stack_mixers1;
3345 spec->mixers[1] = ad1988_3stack_mixers2;
3346 spec->num_init_verbs = 1;
3347 spec->init_verbs[0] = ad1988_3stack_init_verbs;
3348 if (board_config == AD1988_3STACK_DIG)
3349 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3350 break;
3351 case AD1988_LAPTOP:
3352 case AD1988_LAPTOP_DIG:
3353 spec->multiout.max_channels = 2;
3354 spec->multiout.num_dacs = 1;
3355 spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3356 spec->input_mux = &ad1988_laptop_capture_source;
3357 spec->num_mixers = 1;
3358 spec->mixers[0] = ad1988_laptop_mixers;
3359 codec->inv_eapd = 1; /* inverted EAPD */
3360 spec->num_init_verbs = 1;
3361 spec->init_verbs[0] = ad1988_laptop_init_verbs;
3362 if (board_config == AD1988_LAPTOP_DIG)
3363 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3364 break;
3365 }
3366
3367 spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
3368 spec->adc_nids = ad1988_adc_nids;
3369 spec->capsrc_nids = ad1988_capsrc_nids;
3370 spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
3371 spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
3372 if (spec->multiout.dig_out_nid) {
3373 if (codec->vendor_id >= 0x11d4989a) {
3374 spec->mixers[spec->num_mixers++] =
3375 ad1989_spdif_out_mixers;
3376 spec->init_verbs[spec->num_init_verbs++] =
3377 ad1989_spdif_init_verbs;
3378 codec->slave_dig_outs = ad1989b_slave_dig_outs;
3379 } else {
3380 spec->mixers[spec->num_mixers++] =
3381 ad1988_spdif_out_mixers;
3382 spec->init_verbs[spec->num_init_verbs++] =
3383 ad1988_spdif_init_verbs;
3384 }
3385 }
3386 if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) {
3387 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
3388 spec->init_verbs[spec->num_init_verbs++] =
3389 ad1988_spdif_in_init_verbs;
3390 }
3391
3392 codec->patch_ops = ad198x_patch_ops;
3393 switch (board_config) {
3394 case AD1988_LAPTOP:
3395 case AD1988_LAPTOP_DIG:
3396 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
3397 break;
3398 }
3399#ifdef CONFIG_PM
3400 spec->loopback.amplist = ad1988_loopbacks;
3401#endif
3402 spec->vmaster_nid = 0x04;
3403
3404 codec->no_trigger_sense = 1;
3405 codec->no_sticky_stream = 1;
3406
3407 return 0;
3408}
3409#else /* ENABLE_AD_STATIC_QUIRKS */
3410#define patch_ad1988 ad1988_parse_auto_config
3411#endif /* ENABLE_AD_STATIC_QUIRKS */
3412
3413 892
3414/* 893/*
3415 * AD1884 / AD1984 894 * AD1884 / AD1984
@@ -3423,167 +902,19 @@ static int patch_ad1988(struct hda_codec *codec)
3423 * 902 *
3424 * AD1984 = AD1884 + two digital mic-ins 903 * AD1984 = AD1884 + two digital mic-ins
3425 * 904 *
3426 * FIXME: 905 * AD1883 / AD1884A / AD1984A / AD1984B
3427 * For simplicity, we share the single DAC for both HP and line-outs 906 *
3428 * right now. The inidividual playbacks could be easily implemented, 907 * port-B (0x14) - front mic-in
3429 * but no build-up framework is given, so far. 908 * port-E (0x1c) - rear mic-in
3430 */ 909 * port-F (0x16) - CD / ext out
3431 910 * port-C (0x15) - rear line-in
3432#ifdef ENABLE_AD_STATIC_QUIRKS 911 * port-D (0x12) - rear line-out
3433static const hda_nid_t ad1884_dac_nids[1] = { 912 * port-A (0x11) - front hp-out
3434 0x04, 913 *
3435}; 914 * AD1984A = AD1884A + digital-mic
3436 915 * AD1883 = equivalent with AD1984A
3437static const hda_nid_t ad1884_adc_nids[2] = { 916 * AD1984B = AD1984A + extra SPDIF-out
3438 0x08, 0x09,
3439};
3440
3441static const hda_nid_t ad1884_capsrc_nids[2] = {
3442 0x0c, 0x0d,
3443};
3444
3445#define AD1884_SPDIF_OUT 0x02
3446
3447static const struct hda_input_mux ad1884_capture_source = {
3448 .num_items = 4,
3449 .items = {
3450 { "Front Mic", 0x0 },
3451 { "Mic", 0x1 },
3452 { "CD", 0x2 },
3453 { "Mix", 0x3 },
3454 },
3455};
3456
3457static const struct snd_kcontrol_new ad1884_base_mixers[] = {
3458 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3459 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3460 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3461 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3462 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3463 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3464 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3465 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3466 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3467 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3468 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3469 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3470 HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3471 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3472 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3473 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3474 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3475 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3476 {
3477 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3478 /* The multiple "Capture Source" controls confuse alsamixer
3479 * So call somewhat different..
3480 */
3481 /* .name = "Capture Source", */
3482 .name = "Input Source",
3483 .count = 2,
3484 .info = ad198x_mux_enum_info,
3485 .get = ad198x_mux_enum_get,
3486 .put = ad198x_mux_enum_put,
3487 },
3488 /* SPDIF controls */
3489 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3490 {
3491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3492 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3493 /* identical with ad1983 */
3494 .info = ad1983_spdif_route_info,
3495 .get = ad1983_spdif_route_get,
3496 .put = ad1983_spdif_route_put,
3497 },
3498 { } /* end */
3499};
3500
3501static const struct snd_kcontrol_new ad1984_dmic_mixers[] = {
3502 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
3503 HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
3504 HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
3505 HDA_INPUT),
3506 HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
3507 HDA_INPUT),
3508 { } /* end */
3509};
3510
3511/*
3512 * initialization verbs
3513 */ 917 */
3514static const struct hda_verb ad1884_init_verbs[] = {
3515 /* DACs; mute as default */
3516 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3517 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3518 /* Port-A (HP) mixer */
3519 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3520 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3521 /* Port-A pin */
3522 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3523 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3524 /* HP selector - select DAC2 */
3525 {0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
3526 /* Port-D (Line-out) mixer */
3527 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3528 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3529 /* Port-D pin */
3530 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3531 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3532 /* Mono-out mixer */
3533 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3534 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3535 /* Mono-out pin */
3536 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3537 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3538 /* Mono selector */
3539 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
3540 /* Port-B (front mic) pin */
3541 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3542 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3543 /* Port-C (rear mic) pin */
3544 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3545 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3546 /* Analog mixer; mute as default */
3547 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3548 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3549 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3550 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3551 /* Analog Mix output amp */
3552 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3553 /* SPDIF output selector */
3554 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3555 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3556 { } /* end */
3557};
3558
3559#ifdef CONFIG_PM
3560static const struct hda_amp_list ad1884_loopbacks[] = {
3561 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3562 { 0x20, HDA_INPUT, 1 }, /* Mic */
3563 { 0x20, HDA_INPUT, 2 }, /* CD */
3564 { 0x20, HDA_INPUT, 4 }, /* Docking */
3565 { } /* end */
3566};
3567#endif
3568
3569static const char * const ad1884_slave_vols[] = {
3570 "PCM", "Mic", "Mono", "Front Mic", "Mic", "CD",
3571 "Internal Mic", "Dock Mic", /* "Beep", */ "IEC958",
3572 NULL
3573};
3574
3575enum {
3576 AD1884_AUTO,
3577 AD1884_BASIC,
3578 AD1884_MODELS
3579};
3580
3581static const char * const ad1884_models[AD1884_MODELS] = {
3582 [AD1884_AUTO] = "auto",
3583 [AD1884_BASIC] = "basic",
3584};
3585#endif /* ENABLE_AD_STATIC_QUIRKS */
3586
3587 918
3588/* set the upper-limit for mixer amp to 0dB for avoiding the possible 919/* set the upper-limit for mixer amp to 0dB for avoiding the possible
3589 * damage by overloading 920 * damage by overloading
@@ -3599,14 +930,34 @@ static void ad1884_fixup_amp_override(struct hda_codec *codec,
3599 (1 << AC_AMPCAP_MUTE_SHIFT)); 930 (1 << AC_AMPCAP_MUTE_SHIFT));
3600} 931}
3601 932
933/* toggle GPIO1 according to the mute state */
934static void ad1884_vmaster_hp_gpio_hook(void *private_data, int enabled)
935{
936 struct hda_codec *codec = private_data;
937 struct ad198x_spec *spec = codec->spec;
938
939 if (spec->eapd_nid)
940 ad_vmaster_eapd_hook(private_data, enabled);
941 snd_hda_codec_update_cache(codec, 0x01, 0,
942 AC_VERB_SET_GPIO_DATA,
943 enabled ? 0x00 : 0x02);
944}
945
3602static void ad1884_fixup_hp_eapd(struct hda_codec *codec, 946static void ad1884_fixup_hp_eapd(struct hda_codec *codec,
3603 const struct hda_fixup *fix, int action) 947 const struct hda_fixup *fix, int action)
3604{ 948{
3605 struct ad198x_spec *spec = codec->spec; 949 struct ad198x_spec *spec = codec->spec;
950 static const struct hda_verb gpio_init_verbs[] = {
951 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
952 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
953 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
954 {},
955 };
3606 956
3607 switch (action) { 957 switch (action) {
3608 case HDA_FIXUP_ACT_PRE_PROBE: 958 case HDA_FIXUP_ACT_PRE_PROBE:
3609 spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; 959 spec->gen.vmaster_mute.hook = ad1884_vmaster_hp_gpio_hook;
960 snd_hda_sequence_write_cache(codec, gpio_init_verbs);
3610 break; 961 break;
3611 case HDA_FIXUP_ACT_PROBE: 962 case HDA_FIXUP_ACT_PROBE:
3612 if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) 963 if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
@@ -3617,9 +968,18 @@ static void ad1884_fixup_hp_eapd(struct hda_codec *codec,
3617 } 968 }
3618} 969}
3619 970
971/* set magic COEFs for dmic */
972static const struct hda_verb ad1884_dmic_init_verbs[] = {
973 {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
974 {0x01, AC_VERB_SET_PROC_COEF, 0x08},
975 {}
976};
977
3620enum { 978enum {
3621 AD1884_FIXUP_AMP_OVERRIDE, 979 AD1884_FIXUP_AMP_OVERRIDE,
3622 AD1884_FIXUP_HP_EAPD, 980 AD1884_FIXUP_HP_EAPD,
981 AD1884_FIXUP_DMIC_COEF,
982 AD1884_FIXUP_HP_TOUCHSMART,
3623}; 983};
3624 984
3625static const struct hda_fixup ad1884_fixups[] = { 985static const struct hda_fixup ad1884_fixups[] = {
@@ -3633,15 +993,27 @@ static const struct hda_fixup ad1884_fixups[] = {
3633 .chained = true, 993 .chained = true,
3634 .chain_id = AD1884_FIXUP_AMP_OVERRIDE, 994 .chain_id = AD1884_FIXUP_AMP_OVERRIDE,
3635 }, 995 },
996 [AD1884_FIXUP_DMIC_COEF] = {
997 .type = HDA_FIXUP_VERBS,
998 .v.verbs = ad1884_dmic_init_verbs,
999 },
1000 [AD1884_FIXUP_HP_TOUCHSMART] = {
1001 .type = HDA_FIXUP_VERBS,
1002 .v.verbs = ad1884_dmic_init_verbs,
1003 .chained = true,
1004 .chain_id = AD1884_FIXUP_HP_EAPD,
1005 },
3636}; 1006};
3637 1007
3638static const struct snd_pci_quirk ad1884_fixup_tbl[] = { 1008static const struct snd_pci_quirk ad1884_fixup_tbl[] = {
1009 SND_PCI_QUIRK(0x103c, 0x2a82, "HP Touchsmart", AD1884_FIXUP_HP_TOUCHSMART),
3639 SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1884_FIXUP_HP_EAPD), 1010 SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1884_FIXUP_HP_EAPD),
1011 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1884_FIXUP_DMIC_COEF),
3640 {} 1012 {}
3641}; 1013};
3642 1014
3643 1015
3644static int ad1884_parse_auto_config(struct hda_codec *codec) 1016static int patch_ad1884(struct hda_codec *codec)
3645{ 1017{
3646 struct ad198x_spec *spec; 1018 struct ad198x_spec *spec;
3647 int err; 1019 int err;
@@ -3674,1170 +1046,6 @@ static int ad1884_parse_auto_config(struct hda_codec *codec)
3674 return err; 1046 return err;
3675} 1047}
3676 1048
3677#ifdef ENABLE_AD_STATIC_QUIRKS
3678static int patch_ad1884_basic(struct hda_codec *codec)
3679{
3680 struct ad198x_spec *spec;
3681 int err;
3682
3683 err = alloc_ad_spec(codec);
3684 if (err < 0)
3685 return err;
3686 spec = codec->spec;
3687
3688 err = snd_hda_attach_beep_device(codec, 0x10);
3689 if (err < 0) {
3690 ad198x_free(codec);
3691 return err;
3692 }
3693 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3694
3695 spec->multiout.max_channels = 2;
3696 spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
3697 spec->multiout.dac_nids = ad1884_dac_nids;
3698 spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3699 spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
3700 spec->adc_nids = ad1884_adc_nids;
3701 spec->capsrc_nids = ad1884_capsrc_nids;
3702 spec->input_mux = &ad1884_capture_source;
3703 spec->num_mixers = 1;
3704 spec->mixers[0] = ad1884_base_mixers;
3705 spec->num_init_verbs = 1;
3706 spec->init_verbs[0] = ad1884_init_verbs;
3707 spec->spdif_route = 0;
3708#ifdef CONFIG_PM
3709 spec->loopback.amplist = ad1884_loopbacks;
3710#endif
3711 spec->vmaster_nid = 0x04;
3712 /* we need to cover all playback volumes */
3713 spec->slave_vols = ad1884_slave_vols;
3714 /* slaves may contain input volumes, so we can't raise to 0dB blindly */
3715 spec->avoid_init_slave_vol = 1;
3716
3717 codec->patch_ops = ad198x_patch_ops;
3718
3719 codec->no_trigger_sense = 1;
3720 codec->no_sticky_stream = 1;
3721
3722 return 0;
3723}
3724
3725static int patch_ad1884(struct hda_codec *codec)
3726{
3727 int board_config;
3728
3729 board_config = snd_hda_check_board_config(codec, AD1884_MODELS,
3730 ad1884_models, NULL);
3731 if (board_config < 0) {
3732 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3733 codec->chip_name);
3734 board_config = AD1884_AUTO;
3735 }
3736
3737 if (board_config == AD1884_AUTO)
3738 return ad1884_parse_auto_config(codec);
3739 else
3740 return patch_ad1884_basic(codec);
3741}
3742#else /* ENABLE_AD_STATIC_QUIRKS */
3743#define patch_ad1884 ad1884_parse_auto_config
3744#endif /* ENABLE_AD_STATIC_QUIRKS */
3745
3746
3747#ifdef ENABLE_AD_STATIC_QUIRKS
3748/*
3749 * Lenovo Thinkpad T61/X61
3750 */
3751static const struct hda_input_mux ad1984_thinkpad_capture_source = {
3752 .num_items = 4,
3753 .items = {
3754 { "Mic", 0x0 },
3755 { "Internal Mic", 0x1 },
3756 { "Mix", 0x3 },
3757 { "Dock Mic", 0x4 },
3758 },
3759};
3760
3761
3762/*
3763 * Dell Precision T3400
3764 */
3765static const struct hda_input_mux ad1984_dell_desktop_capture_source = {
3766 .num_items = 3,
3767 .items = {
3768 { "Front Mic", 0x0 },
3769 { "Line-In", 0x1 },
3770 { "Mix", 0x3 },
3771 },
3772};
3773
3774
3775static const struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3776 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3777 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3778 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3779 HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3780 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3781 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3782 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3783 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3784 HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3785 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3786 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3787 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3788 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3789 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3790 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3791 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3792 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3793 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3794 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3795 {
3796 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3797 /* The multiple "Capture Source" controls confuse alsamixer
3798 * So call somewhat different..
3799 */
3800 /* .name = "Capture Source", */
3801 .name = "Input Source",
3802 .count = 2,
3803 .info = ad198x_mux_enum_info,
3804 .get = ad198x_mux_enum_get,
3805 .put = ad198x_mux_enum_put,
3806 },
3807 /* SPDIF controls */
3808 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3809 {
3810 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3811 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3812 /* identical with ad1983 */
3813 .info = ad1983_spdif_route_info,
3814 .get = ad1983_spdif_route_get,
3815 .put = ad1983_spdif_route_put,
3816 },
3817 { } /* end */
3818};
3819
3820/* additional verbs */
3821static const struct hda_verb ad1984_thinkpad_init_verbs[] = {
3822 /* Port-E (docking station mic) pin */
3823 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3824 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3825 /* docking mic boost */
3826 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3827 /* Analog PC Beeper - allow firmware/ACPI beeps */
3828 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3) | 0x1a},
3829 /* Analog mixer - docking mic; mute as default */
3830 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3831 /* enable EAPD bit */
3832 {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3833 { } /* end */
3834};
3835
3836/*
3837 * Dell Precision T3400
3838 */
3839static const struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3840 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3841 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3842 HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3843 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3844 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3845 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3846 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3847 HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
3848 HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
3849 HDA_CODEC_VOLUME("Line-In Boost Volume", 0x15, 0x0, HDA_INPUT),
3850 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3851 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3852 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3853 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3854 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3855 {
3856 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3857 /* The multiple "Capture Source" controls confuse alsamixer
3858 * So call somewhat different..
3859 */
3860 /* .name = "Capture Source", */
3861 .name = "Input Source",
3862 .count = 2,
3863 .info = ad198x_mux_enum_info,
3864 .get = ad198x_mux_enum_get,
3865 .put = ad198x_mux_enum_put,
3866 },
3867 { } /* end */
3868};
3869
3870/* Digial MIC ADC NID 0x05 + 0x06 */
3871static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
3872 struct hda_codec *codec,
3873 unsigned int stream_tag,
3874 unsigned int format,
3875 struct snd_pcm_substream *substream)
3876{
3877 snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3878 stream_tag, 0, format);
3879 return 0;
3880}
3881
3882static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3883 struct hda_codec *codec,
3884 struct snd_pcm_substream *substream)
3885{
3886 snd_hda_codec_cleanup_stream(codec, 0x05 + substream->number);
3887 return 0;
3888}
3889
3890static const struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3891 .substreams = 2,
3892 .channels_min = 2,
3893 .channels_max = 2,
3894 .nid = 0x05,
3895 .ops = {
3896 .prepare = ad1984_pcm_dmic_prepare,
3897 .cleanup = ad1984_pcm_dmic_cleanup
3898 },
3899};
3900
3901static int ad1984_build_pcms(struct hda_codec *codec)
3902{
3903 struct ad198x_spec *spec = codec->spec;
3904 struct hda_pcm *info;
3905 int err;
3906
3907 err = ad198x_build_pcms(codec);
3908 if (err < 0)
3909 return err;
3910
3911 info = spec->pcm_rec + codec->num_pcms;
3912 codec->num_pcms++;
3913 info->name = "AD1984 Digital Mic";
3914 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
3915 return 0;
3916}
3917
3918/* models */
3919enum {
3920 AD1984_AUTO,
3921 AD1984_BASIC,
3922 AD1984_THINKPAD,
3923 AD1984_DELL_DESKTOP,
3924 AD1984_MODELS
3925};
3926
3927static const char * const ad1984_models[AD1984_MODELS] = {
3928 [AD1984_AUTO] = "auto",
3929 [AD1984_BASIC] = "basic",
3930 [AD1984_THINKPAD] = "thinkpad",
3931 [AD1984_DELL_DESKTOP] = "dell_desktop",
3932};
3933
3934static const struct snd_pci_quirk ad1984_cfg_tbl[] = {
3935 /* Lenovo Thinkpad T61/X61 */
3936 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD),
3937 SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
3938 SND_PCI_QUIRK(0x1028, 0x0233, "Dell Latitude E6400", AD1984_DELL_DESKTOP),
3939 {}
3940};
3941
3942static int patch_ad1984(struct hda_codec *codec)
3943{
3944 struct ad198x_spec *spec;
3945 int board_config, err;
3946
3947 board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
3948 ad1984_models, ad1984_cfg_tbl);
3949 if (board_config < 0) {
3950 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3951 codec->chip_name);
3952 board_config = AD1984_AUTO;
3953 }
3954
3955 if (board_config == AD1984_AUTO)
3956 return ad1884_parse_auto_config(codec);
3957
3958 err = patch_ad1884_basic(codec);
3959 if (err < 0)
3960 return err;
3961 spec = codec->spec;
3962
3963 switch (board_config) {
3964 case AD1984_BASIC:
3965 /* additional digital mics */
3966 spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
3967 codec->patch_ops.build_pcms = ad1984_build_pcms;
3968 break;
3969 case AD1984_THINKPAD:
3970 if (codec->subsystem_id == 0x17aa20fb) {
3971 /* Thinpad X300 does not have the ability to do SPDIF,
3972 or attach to docking station to use SPDIF */
3973 spec->multiout.dig_out_nid = 0;
3974 } else
3975 spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3976 spec->input_mux = &ad1984_thinkpad_capture_source;
3977 spec->mixers[0] = ad1984_thinkpad_mixers;
3978 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3979 spec->analog_beep = 1;
3980 break;
3981 case AD1984_DELL_DESKTOP:
3982 spec->multiout.dig_out_nid = 0;
3983 spec->input_mux = &ad1984_dell_desktop_capture_source;
3984 spec->mixers[0] = ad1984_dell_desktop_mixers;
3985 break;
3986 }
3987 return 0;
3988}
3989#else /* ENABLE_AD_STATIC_QUIRKS */
3990#define patch_ad1984 ad1884_parse_auto_config
3991#endif /* ENABLE_AD_STATIC_QUIRKS */
3992
3993
3994/*
3995 * AD1883 / AD1884A / AD1984A / AD1984B
3996 *
3997 * port-B (0x14) - front mic-in
3998 * port-E (0x1c) - rear mic-in
3999 * port-F (0x16) - CD / ext out
4000 * port-C (0x15) - rear line-in
4001 * port-D (0x12) - rear line-out
4002 * port-A (0x11) - front hp-out
4003 *
4004 * AD1984A = AD1884A + digital-mic
4005 * AD1883 = equivalent with AD1984A
4006 * AD1984B = AD1984A + extra SPDIF-out
4007 *
4008 * FIXME:
4009 * We share the single DAC for both HP and line-outs (see AD1884/1984).
4010 */
4011
4012#ifdef ENABLE_AD_STATIC_QUIRKS
4013static const hda_nid_t ad1884a_dac_nids[1] = {
4014 0x03,
4015};
4016
4017#define ad1884a_adc_nids ad1884_adc_nids
4018#define ad1884a_capsrc_nids ad1884_capsrc_nids
4019
4020#define AD1884A_SPDIF_OUT 0x02
4021
4022static const struct hda_input_mux ad1884a_capture_source = {
4023 .num_items = 5,
4024 .items = {
4025 { "Front Mic", 0x0 },
4026 { "Mic", 0x4 },
4027 { "Line", 0x1 },
4028 { "CD", 0x2 },
4029 { "Mix", 0x3 },
4030 },
4031};
4032
4033static const struct snd_kcontrol_new ad1884a_base_mixers[] = {
4034 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4035 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4036 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
4037 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4038 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
4039 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
4040 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4041 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4042 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4043 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4044 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
4045 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4046 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4047 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4048 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
4049 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
4050 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4051 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x0, HDA_INPUT),
4052 HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4053 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4054 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4055 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
4056 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
4057 {
4058 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4059 /* The multiple "Capture Source" controls confuse alsamixer
4060 * So call somewhat different..
4061 */
4062 /* .name = "Capture Source", */
4063 .name = "Input Source",
4064 .count = 2,
4065 .info = ad198x_mux_enum_info,
4066 .get = ad198x_mux_enum_get,
4067 .put = ad198x_mux_enum_put,
4068 },
4069 /* SPDIF controls */
4070 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
4071 {
4072 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4073 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
4074 /* identical with ad1983 */
4075 .info = ad1983_spdif_route_info,
4076 .get = ad1983_spdif_route_get,
4077 .put = ad1983_spdif_route_put,
4078 },
4079 { } /* end */
4080};
4081
4082/*
4083 * initialization verbs
4084 */
4085static const struct hda_verb ad1884a_init_verbs[] = {
4086 /* DACs; unmute as default */
4087 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4088 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4089 /* Port-A (HP) mixer - route only from analog mixer */
4090 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4091 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4092 /* Port-A pin */
4093 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4094 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4095 /* Port-D (Line-out) mixer - route only from analog mixer */
4096 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4097 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4098 /* Port-D pin */
4099 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4100 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4101 /* Mono-out mixer - route only from analog mixer */
4102 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4103 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4104 /* Mono-out pin */
4105 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4106 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4107 /* Port-B (front mic) pin */
4108 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4109 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4110 /* Port-C (rear line-in) pin */
4111 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4112 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4113 /* Port-E (rear mic) pin */
4114 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4115 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4116 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* no boost */
4117 /* Port-F (CD) pin */
4118 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4119 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4120 /* Analog mixer; mute as default */
4121 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4122 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4123 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4124 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4125 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* aux */
4126 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4127 /* Analog Mix output amp */
4128 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4129 /* capture sources */
4130 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
4131 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4132 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4133 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4134 /* SPDIF output amp */
4135 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
4136 { } /* end */
4137};
4138
4139#ifdef CONFIG_PM
4140static const struct hda_amp_list ad1884a_loopbacks[] = {
4141 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
4142 { 0x20, HDA_INPUT, 1 }, /* Mic */
4143 { 0x20, HDA_INPUT, 2 }, /* CD */
4144 { 0x20, HDA_INPUT, 4 }, /* Docking */
4145 { } /* end */
4146};
4147#endif
4148
4149/*
4150 * Laptop model
4151 *
4152 * Port A: Headphone jack
4153 * Port B: MIC jack
4154 * Port C: Internal MIC
4155 * Port D: Dock Line Out (if enabled)
4156 * Port E: Dock Line In (if enabled)
4157 * Port F: Internal speakers
4158 */
4159
4160static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol,
4161 struct snd_ctl_elem_value *ucontrol)
4162{
4163 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4164 int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
4165 int mute = (!ucontrol->value.integer.value[0] &&
4166 !ucontrol->value.integer.value[1]);
4167 /* toggle GPIO1 according to the mute state */
4168 snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4169 mute ? 0x02 : 0x0);
4170 return ret;
4171}
4172
4173static const struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
4174 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4175 {
4176 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4177 .name = "Master Playback Switch",
4178 .subdevice = HDA_SUBDEV_AMP_FLAG,
4179 .info = snd_hda_mixer_amp_switch_info,
4180 .get = snd_hda_mixer_amp_switch_get,
4181 .put = ad1884a_mobile_master_sw_put,
4182 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4183 },
4184 HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4185 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4186 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4187 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4188 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4189 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4190 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4191 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4192 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4193 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4194 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
4195 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4196 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4197 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4198 { } /* end */
4199};
4200
4201static const struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
4202 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4203 /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4204 {
4205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4206 .name = "Master Playback Switch",
4207 .subdevice = HDA_SUBDEV_AMP_FLAG,
4208 .info = snd_hda_mixer_amp_switch_info,
4209 .get = snd_hda_mixer_amp_switch_get,
4210 .put = ad1884a_mobile_master_sw_put,
4211 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4212 },
4213 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4214 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4215 HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT),
4216 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT),
4217 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4218 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4219 { } /* end */
4220};
4221
4222/* mute internal speaker if HP is plugged */
4223static void ad1884a_hp_automute(struct hda_codec *codec)
4224{
4225 unsigned int present;
4226
4227 present = snd_hda_jack_detect(codec, 0x11);
4228 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
4229 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4230 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
4231 present ? 0x00 : 0x02);
4232}
4233
4234/* switch to external mic if plugged */
4235static void ad1884a_hp_automic(struct hda_codec *codec)
4236{
4237 unsigned int present;
4238
4239 present = snd_hda_jack_detect(codec, 0x14);
4240 snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL,
4241 present ? 0 : 1);
4242}
4243
4244#define AD1884A_HP_EVENT 0x37
4245#define AD1884A_MIC_EVENT 0x36
4246
4247/* unsolicited event for HP jack sensing */
4248static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4249{
4250 switch (res >> 26) {
4251 case AD1884A_HP_EVENT:
4252 ad1884a_hp_automute(codec);
4253 break;
4254 case AD1884A_MIC_EVENT:
4255 ad1884a_hp_automic(codec);
4256 break;
4257 }
4258}
4259
4260/* initialize jack-sensing, too */
4261static int ad1884a_hp_init(struct hda_codec *codec)
4262{
4263 ad198x_init(codec);
4264 ad1884a_hp_automute(codec);
4265 ad1884a_hp_automic(codec);
4266 return 0;
4267}
4268
4269/* mute internal speaker if HP or docking HP is plugged */
4270static void ad1884a_laptop_automute(struct hda_codec *codec)
4271{
4272 unsigned int present;
4273
4274 present = snd_hda_jack_detect(codec, 0x11);
4275 if (!present)
4276 present = snd_hda_jack_detect(codec, 0x12);
4277 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
4278 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4279 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
4280 present ? 0x00 : 0x02);
4281}
4282
4283/* switch to external mic if plugged */
4284static void ad1884a_laptop_automic(struct hda_codec *codec)
4285{
4286 unsigned int idx;
4287
4288 if (snd_hda_jack_detect(codec, 0x14))
4289 idx = 0;
4290 else if (snd_hda_jack_detect(codec, 0x1c))
4291 idx = 4;
4292 else
4293 idx = 1;
4294 snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, idx);
4295}
4296
4297/* unsolicited event for HP jack sensing */
4298static void ad1884a_laptop_unsol_event(struct hda_codec *codec,
4299 unsigned int res)
4300{
4301 switch (res >> 26) {
4302 case AD1884A_HP_EVENT:
4303 ad1884a_laptop_automute(codec);
4304 break;
4305 case AD1884A_MIC_EVENT:
4306 ad1884a_laptop_automic(codec);
4307 break;
4308 }
4309}
4310
4311/* initialize jack-sensing, too */
4312static int ad1884a_laptop_init(struct hda_codec *codec)
4313{
4314 ad198x_init(codec);
4315 ad1884a_laptop_automute(codec);
4316 ad1884a_laptop_automic(codec);
4317 return 0;
4318}
4319
4320/* additional verbs for laptop model */
4321static const struct hda_verb ad1884a_laptop_verbs[] = {
4322 /* Port-A (HP) pin - always unmuted */
4323 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4324 /* Port-F (int speaker) mixer - route only from analog mixer */
4325 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4326 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4327 /* Port-F (int speaker) pin */
4328 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4329 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4330 /* required for compaq 6530s/6531s speaker output */
4331 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4332 /* Port-C pin - internal mic-in */
4333 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4334 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4335 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4336 /* Port-D (docking line-out) pin - default unmuted */
4337 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4338 /* analog mix */
4339 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4340 /* unsolicited event for pin-sense */
4341 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4342 {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4343 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4344 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4345 /* allow to touch GPIO1 (for mute control) */
4346 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4347 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4348 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4349 { } /* end */
4350};
4351
4352static const struct hda_verb ad1884a_mobile_verbs[] = {
4353 /* DACs; unmute as default */
4354 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4355 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4356 /* Port-A (HP) mixer - route only from analog mixer */
4357 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4358 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4359 /* Port-A pin */
4360 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4361 /* Port-A (HP) pin - always unmuted */
4362 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4363 /* Port-B (mic jack) pin */
4364 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4365 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4366 /* Port-C (int mic) pin */
4367 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4368 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4369 /* Port-F (int speaker) mixer - route only from analog mixer */
4370 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4371 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4372 /* Port-F pin */
4373 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4374 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4375 /* Analog mixer; mute as default */
4376 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4377 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4378 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4379 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4380 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4381 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4382 /* Analog Mix output amp */
4383 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4384 /* capture sources */
4385 /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4386 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4387 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4388 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4389 /* unsolicited event for pin-sense */
4390 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4391 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4392 /* allow to touch GPIO1 (for mute control) */
4393 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4394 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4395 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4396 { } /* end */
4397};
4398
4399/*
4400 * Thinkpad X300
4401 * 0x11 - HP
4402 * 0x12 - speaker
4403 * 0x14 - mic-in
4404 * 0x17 - built-in mic
4405 */
4406
4407static const struct hda_verb ad1984a_thinkpad_verbs[] = {
4408 /* HP unmute */
4409 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4410 /* analog mix */
4411 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4412 /* turn on EAPD */
4413 {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4414 /* unsolicited event for pin-sense */
4415 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4416 /* internal mic - dmic */
4417 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4418 /* set magic COEFs for dmic */
4419 {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4420 {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4421 { } /* end */
4422};
4423
4424static const struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
4425 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4426 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4427 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4428 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4429 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4430 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4431 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4432 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4433 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4434 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4435 {
4436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4437 .name = "Capture Source",
4438 .info = ad198x_mux_enum_info,
4439 .get = ad198x_mux_enum_get,
4440 .put = ad198x_mux_enum_put,
4441 },
4442 { } /* end */
4443};
4444
4445static const struct hda_input_mux ad1984a_thinkpad_capture_source = {
4446 .num_items = 3,
4447 .items = {
4448 { "Mic", 0x0 },
4449 { "Internal Mic", 0x5 },
4450 { "Mix", 0x3 },
4451 },
4452};
4453
4454/* mute internal speaker if HP is plugged */
4455static void ad1984a_thinkpad_automute(struct hda_codec *codec)
4456{
4457 unsigned int present;
4458
4459 present = snd_hda_jack_detect(codec, 0x11);
4460 snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0,
4461 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4462}
4463
4464/* unsolicited event for HP jack sensing */
4465static void ad1984a_thinkpad_unsol_event(struct hda_codec *codec,
4466 unsigned int res)
4467{
4468 if ((res >> 26) != AD1884A_HP_EVENT)
4469 return;
4470 ad1984a_thinkpad_automute(codec);
4471}
4472
4473/* initialize jack-sensing, too */
4474static int ad1984a_thinkpad_init(struct hda_codec *codec)
4475{
4476 ad198x_init(codec);
4477 ad1984a_thinkpad_automute(codec);
4478 return 0;
4479}
4480
4481/*
4482 * Precision R5500
4483 * 0x12 - HP/line-out
4484 * 0x13 - speaker (mono)
4485 * 0x15 - mic-in
4486 */
4487
4488static const struct hda_verb ad1984a_precision_verbs[] = {
4489 /* Unmute main output path */
4490 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4491 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */
4492 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) + 0x17}, /* 0dB */
4493 /* Analog mixer; mute as default */
4494 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4495 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4496 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4497 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4498 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4499 /* Select mic as input */
4500 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
4501 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x27}, /* 0dB */
4502 /* Configure as mic */
4503 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4504 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4505 /* HP unmute */
4506 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4507 /* turn on EAPD */
4508 {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4509 /* unsolicited event for pin-sense */
4510 {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4511 { } /* end */
4512};
4513
4514static const struct snd_kcontrol_new ad1984a_precision_mixers[] = {
4515 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4516 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4517 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4518 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4519 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4520 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4521 HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
4522 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4523 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x13, 0x0, HDA_OUTPUT),
4524 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4525 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4526 { } /* end */
4527};
4528
4529
4530/* mute internal speaker if HP is plugged */
4531static void ad1984a_precision_automute(struct hda_codec *codec)
4532{
4533 unsigned int present;
4534
4535 present = snd_hda_jack_detect(codec, 0x12);
4536 snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
4537 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4538}
4539
4540
4541/* unsolicited event for HP jack sensing */
4542static void ad1984a_precision_unsol_event(struct hda_codec *codec,
4543 unsigned int res)
4544{
4545 if ((res >> 26) != AD1884A_HP_EVENT)
4546 return;
4547 ad1984a_precision_automute(codec);
4548}
4549
4550/* initialize jack-sensing, too */
4551static int ad1984a_precision_init(struct hda_codec *codec)
4552{
4553 ad198x_init(codec);
4554 ad1984a_precision_automute(codec);
4555 return 0;
4556}
4557
4558
4559/*
4560 * HP Touchsmart
4561 * port-A (0x11) - front hp-out
4562 * port-B (0x14) - unused
4563 * port-C (0x15) - unused
4564 * port-D (0x12) - rear line out
4565 * port-E (0x1c) - front mic-in
4566 * port-F (0x16) - Internal speakers
4567 * digital-mic (0x17) - Internal mic
4568 */
4569
4570static const struct hda_verb ad1984a_touchsmart_verbs[] = {
4571 /* DACs; unmute as default */
4572 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4573 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4574 /* Port-A (HP) mixer - route only from analog mixer */
4575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4576 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4577 /* Port-A pin */
4578 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4579 /* Port-A (HP) pin - always unmuted */
4580 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4581 /* Port-E (int speaker) mixer - route only from analog mixer */
4582 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03},
4583 /* Port-E pin */
4584 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4585 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4586 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4587 /* Port-F (int speaker) mixer - route only from analog mixer */
4588 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4589 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4590 /* Port-F pin */
4591 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4592 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4593 /* Analog mixer; mute as default */
4594 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4595 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4596 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4597 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4598 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4599 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4600 /* Analog Mix output amp */
4601 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4602 /* capture sources */
4603 /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4604 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4605 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4606 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4607 /* unsolicited event for pin-sense */
4608 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4609 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4610 /* allow to touch GPIO1 (for mute control) */
4611 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4612 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4613 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4614 /* internal mic - dmic */
4615 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4616 /* set magic COEFs for dmic */
4617 {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4618 {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4619 { } /* end */
4620};
4621
4622static const struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4623 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4624/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4625 {
4626 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4627 .subdevice = HDA_SUBDEV_AMP_FLAG,
4628 .name = "Master Playback Switch",
4629 .info = snd_hda_mixer_amp_switch_info,
4630 .get = snd_hda_mixer_amp_switch_get,
4631 .put = ad1884a_mobile_master_sw_put,
4632 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4633 },
4634 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4635 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4636 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4637 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4638 HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4639 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4640 { } /* end */
4641};
4642
4643/* switch to external mic if plugged */
4644static void ad1984a_touchsmart_automic(struct hda_codec *codec)
4645{
4646 if (snd_hda_jack_detect(codec, 0x1c))
4647 snd_hda_codec_write(codec, 0x0c, 0,
4648 AC_VERB_SET_CONNECT_SEL, 0x4);
4649 else
4650 snd_hda_codec_write(codec, 0x0c, 0,
4651 AC_VERB_SET_CONNECT_SEL, 0x5);
4652}
4653
4654
4655/* unsolicited event for HP jack sensing */
4656static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec,
4657 unsigned int res)
4658{
4659 switch (res >> 26) {
4660 case AD1884A_HP_EVENT:
4661 ad1884a_hp_automute(codec);
4662 break;
4663 case AD1884A_MIC_EVENT:
4664 ad1984a_touchsmart_automic(codec);
4665 break;
4666 }
4667}
4668
4669/* initialize jack-sensing, too */
4670static int ad1984a_touchsmart_init(struct hda_codec *codec)
4671{
4672 ad198x_init(codec);
4673 ad1884a_hp_automute(codec);
4674 ad1984a_touchsmart_automic(codec);
4675 return 0;
4676}
4677
4678
4679/*
4680 */
4681
4682enum {
4683 AD1884A_AUTO,
4684 AD1884A_DESKTOP,
4685 AD1884A_LAPTOP,
4686 AD1884A_MOBILE,
4687 AD1884A_THINKPAD,
4688 AD1984A_TOUCHSMART,
4689 AD1984A_PRECISION,
4690 AD1884A_MODELS
4691};
4692
4693static const char * const ad1884a_models[AD1884A_MODELS] = {
4694 [AD1884A_AUTO] = "auto",
4695 [AD1884A_DESKTOP] = "desktop",
4696 [AD1884A_LAPTOP] = "laptop",
4697 [AD1884A_MOBILE] = "mobile",
4698 [AD1884A_THINKPAD] = "thinkpad",
4699 [AD1984A_TOUCHSMART] = "touchsmart",
4700 [AD1984A_PRECISION] = "precision",
4701};
4702
4703static const struct snd_pci_quirk ad1884a_cfg_tbl[] = {
4704 SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION),
4705 SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
4706 SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
4707 SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
4708 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x3070, "HP", AD1884A_MOBILE),
4709 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30d0, "HP laptop", AD1884A_LAPTOP),
4710 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30e0, "HP laptop", AD1884A_LAPTOP),
4711 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
4712 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE),
4713 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
4714 SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART),
4715 {}
4716};
4717
4718static int patch_ad1884a(struct hda_codec *codec)
4719{
4720 struct ad198x_spec *spec;
4721 int err, board_config;
4722
4723 board_config = snd_hda_check_board_config(codec, AD1884A_MODELS,
4724 ad1884a_models,
4725 ad1884a_cfg_tbl);
4726 if (board_config < 0) {
4727 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4728 codec->chip_name);
4729 board_config = AD1884A_AUTO;
4730 }
4731
4732 if (board_config == AD1884A_AUTO)
4733 return ad1884_parse_auto_config(codec);
4734
4735 err = alloc_ad_spec(codec);
4736 if (err < 0)
4737 return err;
4738 spec = codec->spec;
4739
4740 err = snd_hda_attach_beep_device(codec, 0x10);
4741 if (err < 0) {
4742 ad198x_free(codec);
4743 return err;
4744 }
4745 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
4746
4747 spec->multiout.max_channels = 2;
4748 spec->multiout.num_dacs = ARRAY_SIZE(ad1884a_dac_nids);
4749 spec->multiout.dac_nids = ad1884a_dac_nids;
4750 spec->multiout.dig_out_nid = AD1884A_SPDIF_OUT;
4751 spec->num_adc_nids = ARRAY_SIZE(ad1884a_adc_nids);
4752 spec->adc_nids = ad1884a_adc_nids;
4753 spec->capsrc_nids = ad1884a_capsrc_nids;
4754 spec->input_mux = &ad1884a_capture_source;
4755 spec->num_mixers = 1;
4756 spec->mixers[0] = ad1884a_base_mixers;
4757 spec->num_init_verbs = 1;
4758 spec->init_verbs[0] = ad1884a_init_verbs;
4759 spec->spdif_route = 0;
4760#ifdef CONFIG_PM
4761 spec->loopback.amplist = ad1884a_loopbacks;
4762#endif
4763 codec->patch_ops = ad198x_patch_ops;
4764
4765 /* override some parameters */
4766 switch (board_config) {
4767 case AD1884A_LAPTOP:
4768 spec->mixers[0] = ad1884a_laptop_mixers;
4769 spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs;
4770 spec->multiout.dig_out_nid = 0;
4771 codec->patch_ops.unsol_event = ad1884a_laptop_unsol_event;
4772 codec->patch_ops.init = ad1884a_laptop_init;
4773 /* set the upper-limit for mixer amp to 0dB for avoiding the
4774 * possible damage by overloading
4775 */
4776 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4777 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4778 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4779 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4780 (1 << AC_AMPCAP_MUTE_SHIFT));
4781 break;
4782 case AD1884A_MOBILE:
4783 spec->mixers[0] = ad1884a_mobile_mixers;
4784 spec->init_verbs[0] = ad1884a_mobile_verbs;
4785 spec->multiout.dig_out_nid = 0;
4786 codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
4787 codec->patch_ops.init = ad1884a_hp_init;
4788 /* set the upper-limit for mixer amp to 0dB for avoiding the
4789 * possible damage by overloading
4790 */
4791 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4792 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4793 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4794 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4795 (1 << AC_AMPCAP_MUTE_SHIFT));
4796 break;
4797 case AD1884A_THINKPAD:
4798 spec->mixers[0] = ad1984a_thinkpad_mixers;
4799 spec->init_verbs[spec->num_init_verbs++] =
4800 ad1984a_thinkpad_verbs;
4801 spec->multiout.dig_out_nid = 0;
4802 spec->input_mux = &ad1984a_thinkpad_capture_source;
4803 codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
4804 codec->patch_ops.init = ad1984a_thinkpad_init;
4805 break;
4806 case AD1984A_PRECISION:
4807 spec->mixers[0] = ad1984a_precision_mixers;
4808 spec->init_verbs[spec->num_init_verbs++] =
4809 ad1984a_precision_verbs;
4810 spec->multiout.dig_out_nid = 0;
4811 codec->patch_ops.unsol_event = ad1984a_precision_unsol_event;
4812 codec->patch_ops.init = ad1984a_precision_init;
4813 break;
4814 case AD1984A_TOUCHSMART:
4815 spec->mixers[0] = ad1984a_touchsmart_mixers;
4816 spec->init_verbs[0] = ad1984a_touchsmart_verbs;
4817 spec->multiout.dig_out_nid = 0;
4818 codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event;
4819 codec->patch_ops.init = ad1984a_touchsmart_init;
4820 /* set the upper-limit for mixer amp to 0dB for avoiding the
4821 * possible damage by overloading
4822 */
4823 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4824 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4825 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4826 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4827 (1 << AC_AMPCAP_MUTE_SHIFT));
4828 break;
4829 }
4830
4831 codec->no_trigger_sense = 1;
4832 codec->no_sticky_stream = 1;
4833
4834 return 0;
4835}
4836#else /* ENABLE_AD_STATIC_QUIRKS */
4837#define patch_ad1884a ad1884_parse_auto_config
4838#endif /* ENABLE_AD_STATIC_QUIRKS */
4839
4840
4841/* 1049/*
4842 * AD1882 / AD1882A 1050 * AD1882 / AD1882A
4843 * 1051 *
@@ -4850,299 +1058,7 @@ static int patch_ad1884a(struct hda_codec *codec)
4850 * port-G - rear clfe-out (6stack) 1058 * port-G - rear clfe-out (6stack)
4851 */ 1059 */
4852 1060
4853#ifdef ENABLE_AD_STATIC_QUIRKS 1061static int patch_ad1882(struct hda_codec *codec)
4854static const hda_nid_t ad1882_dac_nids[3] = {
4855 0x04, 0x03, 0x05
4856};
4857
4858static const hda_nid_t ad1882_adc_nids[2] = {
4859 0x08, 0x09,
4860};
4861
4862static const hda_nid_t ad1882_capsrc_nids[2] = {
4863 0x0c, 0x0d,
4864};
4865
4866#define AD1882_SPDIF_OUT 0x02
4867
4868/* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
4869static const struct hda_input_mux ad1882_capture_source = {
4870 .num_items = 5,
4871 .items = {
4872 { "Front Mic", 0x1 },
4873 { "Mic", 0x4 },
4874 { "Line", 0x2 },
4875 { "CD", 0x3 },
4876 { "Mix", 0x7 },
4877 },
4878};
4879
4880/* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */
4881static const struct hda_input_mux ad1882a_capture_source = {
4882 .num_items = 5,
4883 .items = {
4884 { "Front Mic", 0x1 },
4885 { "Mic", 0x4},
4886 { "Line", 0x2 },
4887 { "Digital Mic", 0x06 },
4888 { "Mix", 0x7 },
4889 },
4890};
4891
4892static const struct snd_kcontrol_new ad1882_base_mixers[] = {
4893 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
4894 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
4895 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
4896 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
4897 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
4898 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4899 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
4900 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
4901
4902 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
4903 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
4904 HDA_CODEC_VOLUME("Line-In Boost Volume", 0x3a, 0x0, HDA_OUTPUT),
4905 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4906 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4907 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
4908 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
4909 {
4910 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4911 /* The multiple "Capture Source" controls confuse alsamixer
4912 * So call somewhat different..
4913 */
4914 /* .name = "Capture Source", */
4915 .name = "Input Source",
4916 .count = 2,
4917 .info = ad198x_mux_enum_info,
4918 .get = ad198x_mux_enum_get,
4919 .put = ad198x_mux_enum_put,
4920 },
4921 /* SPDIF controls */
4922 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
4923 {
4924 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4925 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
4926 /* identical with ad1983 */
4927 .info = ad1983_spdif_route_info,
4928 .get = ad1983_spdif_route_get,
4929 .put = ad1983_spdif_route_put,
4930 },
4931 { } /* end */
4932};
4933
4934static const struct snd_kcontrol_new ad1882_loopback_mixers[] = {
4935 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4936 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4937 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4938 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4939 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
4940 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
4941 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4942 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4943 { } /* end */
4944};
4945
4946static const struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
4947 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4948 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4949 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4950 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4951 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
4952 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4953 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4954 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4955 HDA_CODEC_VOLUME("Digital Mic Boost Volume", 0x1f, 0x0, HDA_INPUT),
4956 { } /* end */
4957};
4958
4959static const struct snd_kcontrol_new ad1882_3stack_mixers[] = {
4960 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4961 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
4962 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
4963 {
4964 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4965 .name = "Channel Mode",
4966 .info = ad198x_ch_mode_info,
4967 .get = ad198x_ch_mode_get,
4968 .put = ad198x_ch_mode_put,
4969 },
4970 { } /* end */
4971};
4972
4973/* simple auto-mute control for AD1882 3-stack board */
4974#define AD1882_HP_EVENT 0x01
4975
4976static void ad1882_3stack_automute(struct hda_codec *codec)
4977{
4978 bool mute = snd_hda_jack_detect(codec, 0x11);
4979 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4980 mute ? 0 : PIN_OUT);
4981}
4982
4983static int ad1882_3stack_automute_init(struct hda_codec *codec)
4984{
4985 ad198x_init(codec);
4986 ad1882_3stack_automute(codec);
4987 return 0;
4988}
4989
4990static void ad1882_3stack_unsol_event(struct hda_codec *codec, unsigned int res)
4991{
4992 switch (res >> 26) {
4993 case AD1882_HP_EVENT:
4994 ad1882_3stack_automute(codec);
4995 break;
4996 }
4997}
4998
4999static const struct snd_kcontrol_new ad1882_6stack_mixers[] = {
5000 HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5001 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
5002 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
5003 { } /* end */
5004};
5005
5006static const struct hda_verb ad1882_ch2_init[] = {
5007 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5008 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5009 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5010 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5011 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5012 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5013 { } /* end */
5014};
5015
5016static const struct hda_verb ad1882_ch4_init[] = {
5017 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5018 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5019 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5020 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5021 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5022 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5023 { } /* end */
5024};
5025
5026static const struct hda_verb ad1882_ch6_init[] = {
5027 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5028 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5029 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5030 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5031 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5032 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5033 { } /* end */
5034};
5035
5036static const struct hda_channel_mode ad1882_modes[3] = {
5037 { 2, ad1882_ch2_init },
5038 { 4, ad1882_ch4_init },
5039 { 6, ad1882_ch6_init },
5040};
5041
5042/*
5043 * initialization verbs
5044 */
5045static const struct hda_verb ad1882_init_verbs[] = {
5046 /* DACs; mute as default */
5047 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5048 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5049 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5050 /* Port-A (HP) mixer */
5051 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5052 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5053 /* Port-A pin */
5054 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5055 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5056 /* HP selector - select DAC2 */
5057 {0x37, AC_VERB_SET_CONNECT_SEL, 0x1},
5058 /* Port-D (Line-out) mixer */
5059 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5060 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5061 /* Port-D pin */
5062 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5063 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5064 /* Mono-out mixer */
5065 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5066 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5067 /* Mono-out pin */
5068 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5069 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5070 /* Port-B (front mic) pin */
5071 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5072 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5073 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
5074 /* Port-C (line-in) pin */
5075 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5076 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5077 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
5078 /* Port-C mixer - mute as input */
5079 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5080 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5081 /* Port-E (mic-in) pin */
5082 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5083 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5084 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
5085 /* Port-E mixer - mute as input */
5086 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5087 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5088 /* Port-F (surround) */
5089 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5090 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5091 /* Port-G (CLFE) */
5092 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5093 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5094 /* Analog mixer; mute as default */
5095 /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */
5096 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5097 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5098 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5099 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5100 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5101 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
5102 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
5103 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
5104 /* Analog Mix output amp */
5105 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
5106 /* SPDIF output selector */
5107 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
5108 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
5109 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
5110 { } /* end */
5111};
5112
5113static const struct hda_verb ad1882_3stack_automute_verbs[] = {
5114 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1882_HP_EVENT},
5115 { } /* end */
5116};
5117
5118#ifdef CONFIG_PM
5119static const struct hda_amp_list ad1882_loopbacks[] = {
5120 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
5121 { 0x20, HDA_INPUT, 1 }, /* Mic */
5122 { 0x20, HDA_INPUT, 4 }, /* Line */
5123 { 0x20, HDA_INPUT, 6 }, /* CD */
5124 { } /* end */
5125};
5126#endif
5127
5128/* models */
5129enum {
5130 AD1882_AUTO,
5131 AD1882_3STACK,
5132 AD1882_6STACK,
5133 AD1882_3STACK_AUTOMUTE,
5134 AD1882_MODELS
5135};
5136
5137static const char * const ad1882_models[AD1986A_MODELS] = {
5138 [AD1882_AUTO] = "auto",
5139 [AD1882_3STACK] = "3stack",
5140 [AD1882_6STACK] = "6stack",
5141 [AD1882_3STACK_AUTOMUTE] = "3stack-automute",
5142};
5143#endif /* ENABLE_AD_STATIC_QUIRKS */
5144
5145static int ad1882_parse_auto_config(struct hda_codec *codec)
5146{ 1062{
5147 struct ad198x_spec *spec; 1063 struct ad198x_spec *spec;
5148 int err; 1064 int err;
@@ -5169,110 +1085,20 @@ static int ad1882_parse_auto_config(struct hda_codec *codec)
5169 return err; 1085 return err;
5170} 1086}
5171 1087
5172#ifdef ENABLE_AD_STATIC_QUIRKS
5173static int patch_ad1882(struct hda_codec *codec)
5174{
5175 struct ad198x_spec *spec;
5176 int err, board_config;
5177
5178 board_config = snd_hda_check_board_config(codec, AD1882_MODELS,
5179 ad1882_models, NULL);
5180 if (board_config < 0) {
5181 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5182 codec->chip_name);
5183 board_config = AD1882_AUTO;
5184 }
5185
5186 if (board_config == AD1882_AUTO)
5187 return ad1882_parse_auto_config(codec);
5188
5189 err = alloc_ad_spec(codec);
5190 if (err < 0)
5191 return err;
5192 spec = codec->spec;
5193
5194 err = snd_hda_attach_beep_device(codec, 0x10);
5195 if (err < 0) {
5196 ad198x_free(codec);
5197 return err;
5198 }
5199 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
5200
5201 spec->multiout.max_channels = 6;
5202 spec->multiout.num_dacs = 3;
5203 spec->multiout.dac_nids = ad1882_dac_nids;
5204 spec->multiout.dig_out_nid = AD1882_SPDIF_OUT;
5205 spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
5206 spec->adc_nids = ad1882_adc_nids;
5207 spec->capsrc_nids = ad1882_capsrc_nids;
5208 if (codec->vendor_id == 0x11d41882)
5209 spec->input_mux = &ad1882_capture_source;
5210 else
5211 spec->input_mux = &ad1882a_capture_source;
5212 spec->num_mixers = 2;
5213 spec->mixers[0] = ad1882_base_mixers;
5214 if (codec->vendor_id == 0x11d41882)
5215 spec->mixers[1] = ad1882_loopback_mixers;
5216 else
5217 spec->mixers[1] = ad1882a_loopback_mixers;
5218 spec->num_init_verbs = 1;
5219 spec->init_verbs[0] = ad1882_init_verbs;
5220 spec->spdif_route = 0;
5221#ifdef CONFIG_PM
5222 spec->loopback.amplist = ad1882_loopbacks;
5223#endif
5224 spec->vmaster_nid = 0x04;
5225
5226 codec->patch_ops = ad198x_patch_ops;
5227
5228 /* override some parameters */
5229 switch (board_config) {
5230 default:
5231 case AD1882_3STACK:
5232 case AD1882_3STACK_AUTOMUTE:
5233 spec->num_mixers = 3;
5234 spec->mixers[2] = ad1882_3stack_mixers;
5235 spec->channel_mode = ad1882_modes;
5236 spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
5237 spec->need_dac_fix = 1;
5238 spec->multiout.max_channels = 2;
5239 spec->multiout.num_dacs = 1;
5240 if (board_config != AD1882_3STACK) {
5241 spec->init_verbs[spec->num_init_verbs++] =
5242 ad1882_3stack_automute_verbs;
5243 codec->patch_ops.unsol_event = ad1882_3stack_unsol_event;
5244 codec->patch_ops.init = ad1882_3stack_automute_init;
5245 }
5246 break;
5247 case AD1882_6STACK:
5248 spec->num_mixers = 3;
5249 spec->mixers[2] = ad1882_6stack_mixers;
5250 break;
5251 }
5252
5253 codec->no_trigger_sense = 1;
5254 codec->no_sticky_stream = 1;
5255
5256 return 0;
5257}
5258#else /* ENABLE_AD_STATIC_QUIRKS */
5259#define patch_ad1882 ad1882_parse_auto_config
5260#endif /* ENABLE_AD_STATIC_QUIRKS */
5261
5262 1088
5263/* 1089/*
5264 * patch entries 1090 * patch entries
5265 */ 1091 */
5266static const struct hda_codec_preset snd_hda_preset_analog[] = { 1092static const struct hda_codec_preset snd_hda_preset_analog[] = {
5267 { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a }, 1093 { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884 },
5268 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, 1094 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
5269 { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a }, 1095 { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884 },
5270 { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 }, 1096 { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 },
5271 { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884a }, 1097 { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884 },
5272 { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884a }, 1098 { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884 },
5273 { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, 1099 { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
5274 { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, 1100 { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
5275 { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 }, 1101 { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1884 },
5276 { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, 1102 { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
5277 { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, 1103 { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
5278 { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 }, 1104 { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index de00ce166470..4edd2d0f9a3c 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -66,6 +66,8 @@ struct conexant_spec {
66 hda_nid_t eapds[4]; 66 hda_nid_t eapds[4];
67 bool dynamic_eapd; 67 bool dynamic_eapd;
68 68
69 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
70
69#ifdef ENABLE_CXT_STATIC_QUIRKS 71#ifdef ENABLE_CXT_STATIC_QUIRKS
70 const struct snd_kcontrol_new *mixers[5]; 72 const struct snd_kcontrol_new *mixers[5];
71 int num_mixers; 73 int num_mixers;
@@ -3200,6 +3202,9 @@ static int cx_auto_init(struct hda_codec *codec)
3200 snd_hda_gen_init(codec); 3202 snd_hda_gen_init(codec);
3201 if (!spec->dynamic_eapd) 3203 if (!spec->dynamic_eapd)
3202 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); 3204 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
3205
3206 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
3207
3203 return 0; 3208 return 0;
3204} 3209}
3205 3210
@@ -3224,6 +3229,8 @@ enum {
3224 CXT_PINCFG_LEMOTE_A1205, 3229 CXT_PINCFG_LEMOTE_A1205,
3225 CXT_FIXUP_STEREO_DMIC, 3230 CXT_FIXUP_STEREO_DMIC,
3226 CXT_FIXUP_INC_MIC_BOOST, 3231 CXT_FIXUP_INC_MIC_BOOST,
3232 CXT_FIXUP_HEADPHONE_MIC_PIN,
3233 CXT_FIXUP_HEADPHONE_MIC,
3227}; 3234};
3228 3235
3229static void cxt_fixup_stereo_dmic(struct hda_codec *codec, 3236static void cxt_fixup_stereo_dmic(struct hda_codec *codec,
@@ -3246,6 +3253,59 @@ static void cxt5066_increase_mic_boost(struct hda_codec *codec,
3246 (0 << AC_AMPCAP_MUTE_SHIFT)); 3253 (0 << AC_AMPCAP_MUTE_SHIFT));
3247} 3254}
3248 3255
3256static void cxt_update_headset_mode(struct hda_codec *codec)
3257{
3258 /* The verbs used in this function were tested on a Conexant CX20751/2 codec. */
3259 int i;
3260 bool mic_mode = false;
3261 struct conexant_spec *spec = codec->spec;
3262 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
3263
3264 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
3265
3266 for (i = 0; i < cfg->num_inputs; i++)
3267 if (cfg->inputs[i].pin == mux_pin) {
3268 mic_mode = !!cfg->inputs[i].is_headphone_mic;
3269 break;
3270 }
3271
3272 if (mic_mode) {
3273 snd_hda_codec_write_cache(codec, 0x1c, 0, 0x410, 0x7c); /* enable merged mode for analog int-mic */
3274 spec->gen.hp_jack_present = false;
3275 } else {
3276 snd_hda_codec_write_cache(codec, 0x1c, 0, 0x410, 0x54); /* disable merged mode for analog int-mic */
3277 spec->gen.hp_jack_present = snd_hda_jack_detect(codec, spec->gen.autocfg.hp_pins[0]);
3278 }
3279
3280 snd_hda_gen_update_outputs(codec);
3281}
3282
3283static void cxt_update_headset_mode_hook(struct hda_codec *codec,
3284 struct snd_ctl_elem_value *ucontrol)
3285{
3286 cxt_update_headset_mode(codec);
3287}
3288
3289static void cxt_fixup_headphone_mic(struct hda_codec *codec,
3290 const struct hda_fixup *fix, int action)
3291{
3292 struct conexant_spec *spec = codec->spec;
3293
3294 switch (action) {
3295 case HDA_FIXUP_ACT_PRE_PROBE:
3296 spec->parse_flags |= HDA_PINCFG_HEADPHONE_MIC;
3297 break;
3298 case HDA_FIXUP_ACT_PROBE:
3299 spec->gen.cap_sync_hook = cxt_update_headset_mode_hook;
3300 spec->gen.automute_hook = cxt_update_headset_mode;
3301 break;
3302 case HDA_FIXUP_ACT_INIT:
3303 cxt_update_headset_mode(codec);
3304 break;
3305 }
3306}
3307
3308
3249/* ThinkPad X200 & co with cxt5051 */ 3309/* ThinkPad X200 & co with cxt5051 */
3250static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = { 3310static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = {
3251 { 0x16, 0x042140ff }, /* HP (seq# overridden) */ 3311 { 0x16, 0x042140ff }, /* HP (seq# overridden) */
@@ -3302,6 +3362,19 @@ static const struct hda_fixup cxt_fixups[] = {
3302 .type = HDA_FIXUP_FUNC, 3362 .type = HDA_FIXUP_FUNC,
3303 .v.func = cxt5066_increase_mic_boost, 3363 .v.func = cxt5066_increase_mic_boost,
3304 }, 3364 },
3365 [CXT_FIXUP_HEADPHONE_MIC_PIN] = {
3366 .type = HDA_FIXUP_PINS,
3367 .chained = true,
3368 .chain_id = CXT_FIXUP_HEADPHONE_MIC,
3369 .v.pins = (const struct hda_pintbl[]) {
3370 { 0x18, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
3371 { }
3372 }
3373 },
3374 [CXT_FIXUP_HEADPHONE_MIC] = {
3375 .type = HDA_FIXUP_FUNC,
3376 .v.func = cxt_fixup_headphone_mic,
3377 },
3305}; 3378};
3306 3379
3307static const struct snd_pci_quirk cxt5051_fixups[] = { 3380static const struct snd_pci_quirk cxt5051_fixups[] = {
@@ -3311,6 +3384,7 @@ static const struct snd_pci_quirk cxt5051_fixups[] = {
3311 3384
3312static const struct snd_pci_quirk cxt5066_fixups[] = { 3385static const struct snd_pci_quirk cxt5066_fixups[] = {
3313 SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC), 3386 SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC),
3387 SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
3314 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), 3388 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
3315 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410), 3389 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410),
3316 SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410), 3390 SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410),
@@ -3395,7 +3469,8 @@ static int patch_conexant_auto(struct hda_codec *codec)
3395 3469
3396 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 3470 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
3397 3471
3398 err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); 3472 err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL,
3473 spec->parse_flags);
3399 if (err < 0) 3474 if (err < 0)
3400 goto error; 3475 goto error;
3401 3476
@@ -3416,6 +3491,8 @@ static int patch_conexant_auto(struct hda_codec *codec)
3416 codec->bus->allow_bus_reset = 1; 3491 codec->bus->allow_bus_reset = 1;
3417 } 3492 }
3418 3493
3494 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
3495
3419 return 0; 3496 return 0;
3420 3497
3421 error: 3498 error:
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 9f3586276871..9a58893d52a7 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -67,6 +67,8 @@ struct hdmi_spec_per_pin {
67 struct delayed_work work; 67 struct delayed_work work;
68 struct snd_kcontrol *eld_ctl; 68 struct snd_kcontrol *eld_ctl;
69 int repoll_count; 69 int repoll_count;
70 bool setup; /* the stream has been set up by prepare callback */
71 int channels; /* current number of channels */
70 bool non_pcm; 72 bool non_pcm;
71 bool chmap_set; /* channel-map override by ALSA API? */ 73 bool chmap_set; /* channel-map override by ALSA API? */
72 unsigned char chmap[8]; /* ALSA API channel-map */ 74 unsigned char chmap[8]; /* ALSA API channel-map */
@@ -551,6 +553,17 @@ static int hdmi_channel_allocation(struct hdmi_eld *eld, int channels)
551 } 553 }
552 } 554 }
553 555
556 if (!ca) {
557 /* if there was no match, select the regular ALSA channel
558 * allocation with the matching number of channels */
559 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
560 if (channels == channel_allocations[i].channels) {
561 ca = channel_allocations[i].ca_index;
562 break;
563 }
564 }
565 }
566
554 snd_print_channel_allocation(eld->info.spk_alloc, buf, sizeof(buf)); 567 snd_print_channel_allocation(eld->info.spk_alloc, buf, sizeof(buf));
555 snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n", 568 snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n",
556 ca, channels, buf); 569 ca, channels, buf);
@@ -868,18 +881,19 @@ static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
868 return true; 881 return true;
869} 882}
870 883
871static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, 884static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
872 bool non_pcm, 885 struct hdmi_spec_per_pin *per_pin,
873 struct snd_pcm_substream *substream) 886 bool non_pcm)
874{ 887{
875 struct hdmi_spec *spec = codec->spec;
876 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
877 hda_nid_t pin_nid = per_pin->pin_nid; 888 hda_nid_t pin_nid = per_pin->pin_nid;
878 int channels = substream->runtime->channels; 889 int channels = per_pin->channels;
879 struct hdmi_eld *eld; 890 struct hdmi_eld *eld;
880 int ca; 891 int ca;
881 union audio_infoframe ai; 892 union audio_infoframe ai;
882 893
894 if (!channels)
895 return;
896
883 eld = &per_pin->sink_eld; 897 eld = &per_pin->sink_eld;
884 if (!eld->monitor_present) 898 if (!eld->monitor_present)
885 return; 899 return;
@@ -959,6 +973,7 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
959 int pin_nid; 973 int pin_nid;
960 int pin_idx; 974 int pin_idx;
961 struct hda_jack_tbl *jack; 975 struct hda_jack_tbl *jack;
976 int dev_entry = (res & AC_UNSOL_RES_DE) >> AC_UNSOL_RES_DE_SHIFT;
962 977
963 jack = snd_hda_jack_tbl_get_from_tag(codec, tag); 978 jack = snd_hda_jack_tbl_get_from_tag(codec, tag);
964 if (!jack) 979 if (!jack)
@@ -967,8 +982,8 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
967 jack->jack_dirty = 1; 982 jack->jack_dirty = 1;
968 983
969 _snd_printd(SND_PR_VERBOSE, 984 _snd_printd(SND_PR_VERBOSE,
970 "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", 985 "HDMI hot plug event: Codec=%d Pin=%d Device=%d Inactive=%d Presence_Detect=%d ELD_Valid=%d\n",
971 codec->addr, pin_nid, 986 codec->addr, pin_nid, dev_entry, !!(res & AC_UNSOL_RES_IA),
972 !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV)); 987 !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV));
973 988
974 pin_idx = pin_nid_to_pin_index(spec, pin_nid); 989 pin_idx = pin_nid_to_pin_index(spec, pin_nid);
@@ -1329,6 +1344,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
1329 eld_changed = true; 1344 eld_changed = true;
1330 } 1345 }
1331 if (update_eld) { 1346 if (update_eld) {
1347 bool old_eld_valid = pin_eld->eld_valid;
1332 pin_eld->eld_valid = eld->eld_valid; 1348 pin_eld->eld_valid = eld->eld_valid;
1333 eld_changed = pin_eld->eld_size != eld->eld_size || 1349 eld_changed = pin_eld->eld_size != eld->eld_size ||
1334 memcmp(pin_eld->eld_buffer, eld->eld_buffer, 1350 memcmp(pin_eld->eld_buffer, eld->eld_buffer,
@@ -1338,6 +1354,18 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
1338 eld->eld_size); 1354 eld->eld_size);
1339 pin_eld->eld_size = eld->eld_size; 1355 pin_eld->eld_size = eld->eld_size;
1340 pin_eld->info = eld->info; 1356 pin_eld->info = eld->info;
1357
1358 /* Haswell-specific workaround: re-setup when the transcoder is
1359 * changed during the stream playback
1360 */
1361 if (codec->vendor_id == 0x80862807 &&
1362 eld->eld_valid && !old_eld_valid && per_pin->setup) {
1363 snd_hda_codec_write(codec, pin_nid, 0,
1364 AC_VERB_SET_AMP_GAIN_MUTE,
1365 AMP_OUT_UNMUTE);
1366 hdmi_setup_audio_infoframe(codec, per_pin,
1367 per_pin->non_pcm);
1368 }
1341 } 1369 }
1342 mutex_unlock(&pin_eld->lock); 1370 mutex_unlock(&pin_eld->lock);
1343 1371
@@ -1510,14 +1538,17 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1510 hda_nid_t cvt_nid = hinfo->nid; 1538 hda_nid_t cvt_nid = hinfo->nid;
1511 struct hdmi_spec *spec = codec->spec; 1539 struct hdmi_spec *spec = codec->spec;
1512 int pin_idx = hinfo_to_pin_index(spec, hinfo); 1540 int pin_idx = hinfo_to_pin_index(spec, hinfo);
1513 hda_nid_t pin_nid = get_pin(spec, pin_idx)->pin_nid; 1541 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
1542 hda_nid_t pin_nid = per_pin->pin_nid;
1514 bool non_pcm; 1543 bool non_pcm;
1515 1544
1516 non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); 1545 non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
1546 per_pin->channels = substream->runtime->channels;
1547 per_pin->setup = true;
1517 1548
1518 hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels); 1549 hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
1519 1550
1520 hdmi_setup_audio_infoframe(codec, pin_idx, non_pcm, substream); 1551 hdmi_setup_audio_infoframe(codec, per_pin, non_pcm);
1521 1552
1522 return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); 1553 return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
1523} 1554}
@@ -1557,6 +1588,9 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
1557 snd_hda_spdif_ctls_unassign(codec, pin_idx); 1588 snd_hda_spdif_ctls_unassign(codec, pin_idx);
1558 per_pin->chmap_set = false; 1589 per_pin->chmap_set = false;
1559 memset(per_pin->chmap, 0, sizeof(per_pin->chmap)); 1590 memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
1591
1592 per_pin->setup = false;
1593 per_pin->channels = 0;
1560 } 1594 }
1561 1595
1562 return 0; 1596 return 0;
@@ -1692,8 +1726,7 @@ static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol,
1692 per_pin->chmap_set = true; 1726 per_pin->chmap_set = true;
1693 memcpy(per_pin->chmap, chmap, sizeof(chmap)); 1727 memcpy(per_pin->chmap, chmap, sizeof(chmap));
1694 if (prepared) 1728 if (prepared)
1695 hdmi_setup_audio_infoframe(codec, pin_idx, per_pin->non_pcm, 1729 hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
1696 substream);
1697 1730
1698 return 0; 1731 return 0;
1699} 1732}
@@ -1992,8 +2025,10 @@ static int patch_generic_hdmi(struct hda_codec *codec)
1992 return -EINVAL; 2025 return -EINVAL;
1993 } 2026 }
1994 codec->patch_ops = generic_hdmi_patch_ops; 2027 codec->patch_ops = generic_hdmi_patch_ops;
1995 if (codec->vendor_id == 0x80862807) 2028 if (codec->vendor_id == 0x80862807) {
1996 codec->patch_ops.set_power_state = haswell_set_power_state; 2029 codec->patch_ops.set_power_state = haswell_set_power_state;
2030 codec->dp_mst = true;
2031 }
1997 2032
1998 generic_hdmi_init_per_pins(codec); 2033 generic_hdmi_init_per_pins(codec);
1999 2034
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 389db4c2801b..9e9378cde8fa 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -282,6 +282,7 @@ static void alc_eapd_shutup(struct hda_codec *codec)
282{ 282{
283 alc_auto_setup_eapd(codec, false); 283 alc_auto_setup_eapd(codec, false);
284 msleep(200); 284 msleep(200);
285 snd_hda_shutup_pins(codec);
285} 286}
286 287
287/* generic EAPD initialization */ 288/* generic EAPD initialization */
@@ -826,7 +827,8 @@ static inline void alc_shutup(struct hda_codec *codec)
826 827
827 if (spec && spec->shutup) 828 if (spec && spec->shutup)
828 spec->shutup(codec); 829 spec->shutup(codec);
829 snd_hda_shutup_pins(codec); 830 else
831 snd_hda_shutup_pins(codec);
830} 832}
831 833
832#define alc_free snd_hda_gen_free 834#define alc_free snd_hda_gen_free
@@ -1853,8 +1855,10 @@ static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
1853 const struct hda_fixup *fix, int action) 1855 const struct hda_fixup *fix, int action)
1854{ 1856{
1855 struct alc_spec *spec = codec->spec; 1857 struct alc_spec *spec = codec->spec;
1856 if (action == HDA_FIXUP_ACT_PRE_PROBE) 1858 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1857 spec->gen.no_primary_hp = 1; 1859 spec->gen.no_primary_hp = 1;
1860 spec->gen.no_multi_io = 1;
1861 }
1858} 1862}
1859 1863
1860static const struct hda_fixup alc882_fixups[] = { 1864static const struct hda_fixup alc882_fixups[] = {
@@ -2533,6 +2537,7 @@ enum {
2533 ALC269_TYPE_ALC269VD, 2537 ALC269_TYPE_ALC269VD,
2534 ALC269_TYPE_ALC280, 2538 ALC269_TYPE_ALC280,
2535 ALC269_TYPE_ALC282, 2539 ALC269_TYPE_ALC282,
2540 ALC269_TYPE_ALC283,
2536 ALC269_TYPE_ALC284, 2541 ALC269_TYPE_ALC284,
2537 ALC269_TYPE_ALC286, 2542 ALC269_TYPE_ALC286,
2538}; 2543};
@@ -2558,6 +2563,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
2558 case ALC269_TYPE_ALC269VB: 2563 case ALC269_TYPE_ALC269VB:
2559 case ALC269_TYPE_ALC269VD: 2564 case ALC269_TYPE_ALC269VD:
2560 case ALC269_TYPE_ALC282: 2565 case ALC269_TYPE_ALC282:
2566 case ALC269_TYPE_ALC283:
2561 case ALC269_TYPE_ALC286: 2567 case ALC269_TYPE_ALC286:
2562 ssids = alc269_ssids; 2568 ssids = alc269_ssids;
2563 break; 2569 break;
@@ -2583,15 +2589,81 @@ static void alc269_shutup(struct hda_codec *codec)
2583{ 2589{
2584 struct alc_spec *spec = codec->spec; 2590 struct alc_spec *spec = codec->spec;
2585 2591
2586 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
2587 return;
2588
2589 if (spec->codec_variant == ALC269_TYPE_ALC269VB) 2592 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2590 alc269vb_toggle_power_output(codec, 0); 2593 alc269vb_toggle_power_output(codec, 0);
2591 if (spec->codec_variant == ALC269_TYPE_ALC269VB && 2594 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2592 (alc_get_coef0(codec) & 0x00ff) == 0x018) { 2595 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
2593 msleep(150); 2596 msleep(150);
2594 } 2597 }
2598 snd_hda_shutup_pins(codec);
2599}
2600
2601static void alc283_init(struct hda_codec *codec)
2602{
2603 struct alc_spec *spec = codec->spec;
2604 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2605 bool hp_pin_sense;
2606 int val;
2607
2608 if (!hp_pin)
2609 return;
2610 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2611
2612 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
2613 /* Headphone capless set to high power mode */
2614 alc_write_coef_idx(codec, 0x43, 0x9004);
2615
2616 snd_hda_codec_write(codec, hp_pin, 0,
2617 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2618
2619 if (hp_pin_sense)
2620 msleep(85);
2621
2622 snd_hda_codec_write(codec, hp_pin, 0,
2623 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2624
2625 if (hp_pin_sense)
2626 msleep(85);
2627 /* Index 0x46 Combo jack auto switch control 2 */
2628 /* 3k pull low control for Headset jack. */
2629 val = alc_read_coef_idx(codec, 0x46);
2630 alc_write_coef_idx(codec, 0x46, val & ~(3 << 12));
2631 /* Headphone capless set to normal mode */
2632 alc_write_coef_idx(codec, 0x43, 0x9614);
2633}
2634
2635static void alc283_shutup(struct hda_codec *codec)
2636{
2637 struct alc_spec *spec = codec->spec;
2638 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2639 bool hp_pin_sense;
2640 int val;
2641
2642 if (!hp_pin) {
2643 alc269_shutup(codec);
2644 return;
2645 }
2646
2647 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2648
2649 alc_write_coef_idx(codec, 0x43, 0x9004);
2650
2651 snd_hda_codec_write(codec, hp_pin, 0,
2652 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2653
2654 if (hp_pin_sense)
2655 msleep(85);
2656
2657 snd_hda_codec_write(codec, hp_pin, 0,
2658 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2659
2660 val = alc_read_coef_idx(codec, 0x46);
2661 alc_write_coef_idx(codec, 0x46, val | (3 << 12));
2662
2663 if (hp_pin_sense)
2664 msleep(85);
2665 snd_hda_shutup_pins(codec);
2666 alc_write_coef_idx(codec, 0x43, 0x9614);
2595} 2667}
2596 2668
2597static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg, 2669static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
@@ -2722,6 +2794,7 @@ static int alc269_resume(struct hda_codec *codec)
2722 hda_call_check_power_status(codec, 0x01); 2794 hda_call_check_power_status(codec, 0x01);
2723 if (spec->has_alc5505_dsp) 2795 if (spec->has_alc5505_dsp)
2724 alc5505_dsp_resume(codec); 2796 alc5505_dsp_resume(codec);
2797
2725 return 0; 2798 return 0;
2726} 2799}
2727#endif /* CONFIG_PM */ 2800#endif /* CONFIG_PM */
@@ -3261,6 +3334,28 @@ static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
3261 alc_fixup_headset_mode(codec, fix, action); 3334 alc_fixup_headset_mode(codec, fix, action);
3262} 3335}
3263 3336
3337/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
3338static int find_ext_mic_pin(struct hda_codec *codec)
3339{
3340 struct alc_spec *spec = codec->spec;
3341 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
3342 hda_nid_t nid;
3343 unsigned int defcfg;
3344 int i;
3345
3346 for (i = 0; i < cfg->num_inputs; i++) {
3347 if (cfg->inputs[i].type != AUTO_PIN_MIC)
3348 continue;
3349 nid = cfg->inputs[i].pin;
3350 defcfg = snd_hda_codec_get_pincfg(codec, nid);
3351 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
3352 continue;
3353 return nid;
3354 }
3355
3356 return 0;
3357}
3358
3264static void alc271_hp_gate_mic_jack(struct hda_codec *codec, 3359static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
3265 const struct hda_fixup *fix, 3360 const struct hda_fixup *fix,
3266 int action) 3361 int action)
@@ -3268,11 +3363,12 @@ static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
3268 struct alc_spec *spec = codec->spec; 3363 struct alc_spec *spec = codec->spec;
3269 3364
3270 if (action == HDA_FIXUP_ACT_PROBE) { 3365 if (action == HDA_FIXUP_ACT_PROBE) {
3271 if (snd_BUG_ON(!spec->gen.am_entry[1].pin || 3366 int mic_pin = find_ext_mic_pin(codec);
3272 !spec->gen.autocfg.hp_pins[0])) 3367 int hp_pin = spec->gen.autocfg.hp_pins[0];
3368
3369 if (snd_BUG_ON(!mic_pin || !hp_pin))
3273 return; 3370 return;
3274 snd_hda_jack_set_gating_jack(codec, spec->gen.am_entry[1].pin, 3371 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
3275 spec->gen.autocfg.hp_pins[0]);
3276 } 3372 }
3277} 3373}
3278 3374
@@ -3308,6 +3404,45 @@ static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
3308 } 3404 }
3309} 3405}
3310 3406
3407static void alc283_hp_automute_hook(struct hda_codec *codec,
3408 struct hda_jack_tbl *jack)
3409{
3410 struct alc_spec *spec = codec->spec;
3411 int vref;
3412
3413 msleep(200);
3414 snd_hda_gen_hp_automute(codec, jack);
3415
3416 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3417
3418 msleep(600);
3419 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3420 vref);
3421}
3422
3423static void alc283_chromebook_caps(struct hda_codec *codec)
3424{
3425 snd_hda_override_wcaps(codec, 0x03, 0);
3426}
3427
3428static void alc283_fixup_chromebook(struct hda_codec *codec,
3429 const struct hda_fixup *fix, int action)
3430{
3431 struct alc_spec *spec = codec->spec;
3432 int val;
3433
3434 switch (action) {
3435 case HDA_FIXUP_ACT_PRE_PROBE:
3436 alc283_chromebook_caps(codec);
3437 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
3438 /* MIC2-VREF control */
3439 /* Set to manual mode */
3440 val = alc_read_coef_idx(codec, 0x06);
3441 alc_write_coef_idx(codec, 0x06, val & ~0x000c);
3442 break;
3443 }
3444}
3445
3311enum { 3446enum {
3312 ALC269_FIXUP_SONY_VAIO, 3447 ALC269_FIXUP_SONY_VAIO,
3313 ALC275_FIXUP_SONY_VAIO_GPIO2, 3448 ALC275_FIXUP_SONY_VAIO_GPIO2,
@@ -3344,6 +3479,7 @@ enum {
3344 ALC269_FIXUP_ACER_AC700, 3479 ALC269_FIXUP_ACER_AC700,
3345 ALC269_FIXUP_LIMIT_INT_MIC_BOOST, 3480 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
3346 ALC269VB_FIXUP_ORDISSIMO_EVE2, 3481 ALC269VB_FIXUP_ORDISSIMO_EVE2,
3482 ALC283_FIXUP_CHROME_BOOK,
3347}; 3483};
3348 3484
3349static const struct hda_fixup alc269_fixups[] = { 3485static const struct hda_fixup alc269_fixups[] = {
@@ -3595,11 +3731,20 @@ static const struct hda_fixup alc269_fixups[] = {
3595 { } 3731 { }
3596 }, 3732 },
3597 }, 3733 },
3734 [ALC283_FIXUP_CHROME_BOOK] = {
3735 .type = HDA_FIXUP_FUNC,
3736 .v.func = alc283_fixup_chromebook,
3737 },
3598}; 3738};
3599 3739
3600static const struct snd_pci_quirk alc269_fixup_tbl[] = { 3740static const struct snd_pci_quirk alc269_fixup_tbl[] = {
3601 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), 3741 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
3602 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), 3742 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
3743 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
3744 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
3745 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
3746 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
3747 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
3603 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3748 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3604 SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3749 SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3605 SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3750 SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
@@ -3637,6 +3782,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
3637 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), 3782 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
3638 SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), 3783 SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
3639 SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), 3784 SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
3785 SND_PCI_QUIRK(0x103c, 0x21ed, "HP Falco Chromebook", ALC283_FIXUP_CHROME_BOOK),
3640 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), 3786 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
3641 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3787 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3642 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3788 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
@@ -3655,11 +3801,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
3655 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 3801 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
3656 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 3802 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
3657 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 3803 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
3658 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
3659 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
3660 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
3661 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
3662 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
3663 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), 3804 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
3664 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), 3805 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
3665 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), 3806 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
@@ -3670,8 +3811,16 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
3670 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), 3811 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
3671 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), 3812 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
3672 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), 3813 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
3673 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
3674 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), 3814 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
3815 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
3816 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3817 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3818 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3819 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3820 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3821 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3822 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3823 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3675 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), 3824 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
3676 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 3825 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
3677 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ 3826 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
@@ -3840,11 +3989,15 @@ static int patch_alc269(struct hda_codec *codec)
3840 case 0x10ec0290: 3989 case 0x10ec0290:
3841 spec->codec_variant = ALC269_TYPE_ALC280; 3990 spec->codec_variant = ALC269_TYPE_ALC280;
3842 break; 3991 break;
3843 case 0x10ec0233:
3844 case 0x10ec0282: 3992 case 0x10ec0282:
3845 case 0x10ec0283:
3846 spec->codec_variant = ALC269_TYPE_ALC282; 3993 spec->codec_variant = ALC269_TYPE_ALC282;
3847 break; 3994 break;
3995 case 0x10ec0233:
3996 case 0x10ec0283:
3997 spec->codec_variant = ALC269_TYPE_ALC283;
3998 spec->shutup = alc283_shutup;
3999 spec->init_hook = alc283_init;
4000 break;
3848 case 0x10ec0284: 4001 case 0x10ec0284:
3849 case 0x10ec0292: 4002 case 0x10ec0292:
3850 spec->codec_variant = ALC269_TYPE_ALC284; 4003 spec->codec_variant = ALC269_TYPE_ALC284;
@@ -3872,7 +4025,8 @@ static int patch_alc269(struct hda_codec *codec)
3872 codec->patch_ops.suspend = alc269_suspend; 4025 codec->patch_ops.suspend = alc269_suspend;
3873 codec->patch_ops.resume = alc269_resume; 4026 codec->patch_ops.resume = alc269_resume;
3874#endif 4027#endif
3875 spec->shutup = alc269_shutup; 4028 if (!spec->shutup)
4029 spec->shutup = alc269_shutup;
3876 4030
3877 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 4031 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
3878 4032
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 6d1924c19abf..fba0cef1c47f 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -158,6 +158,7 @@ enum {
158 STAC_D965_VERBS, 158 STAC_D965_VERBS,
159 STAC_DELL_3ST, 159 STAC_DELL_3ST,
160 STAC_DELL_BIOS, 160 STAC_DELL_BIOS,
161 STAC_DELL_BIOS_AMIC,
161 STAC_DELL_BIOS_SPDIF, 162 STAC_DELL_BIOS_SPDIF,
162 STAC_927X_DELL_DMIC, 163 STAC_927X_DELL_DMIC,
163 STAC_927X_VOLKNOB, 164 STAC_927X_VOLKNOB,
@@ -3231,8 +3232,6 @@ static const struct hda_fixup stac927x_fixups[] = {
3231 [STAC_DELL_BIOS] = { 3232 [STAC_DELL_BIOS] = {
3232 .type = HDA_FIXUP_PINS, 3233 .type = HDA_FIXUP_PINS,
3233 .v.pins = (const struct hda_pintbl[]) { 3234 .v.pins = (const struct hda_pintbl[]) {
3234 /* configure the analog microphone on some laptops */
3235 { 0x0c, 0x90a79130 },
3236 /* correct the front output jack as a hp out */ 3235 /* correct the front output jack as a hp out */
3237 { 0x0f, 0x0221101f }, 3236 { 0x0f, 0x0221101f },
3238 /* correct the front input jack as a mic */ 3237 /* correct the front input jack as a mic */
@@ -3242,6 +3241,16 @@ static const struct hda_fixup stac927x_fixups[] = {
3242 .chained = true, 3241 .chained = true,
3243 .chain_id = STAC_927X_DELL_DMIC, 3242 .chain_id = STAC_927X_DELL_DMIC,
3244 }, 3243 },
3244 [STAC_DELL_BIOS_AMIC] = {
3245 .type = HDA_FIXUP_PINS,
3246 .v.pins = (const struct hda_pintbl[]) {
3247 /* configure the analog microphone on some laptops */
3248 { 0x0c, 0x90a79130 },
3249 {}
3250 },
3251 .chained = true,
3252 .chain_id = STAC_DELL_BIOS,
3253 },
3245 [STAC_DELL_BIOS_SPDIF] = { 3254 [STAC_DELL_BIOS_SPDIF] = {
3246 .type = HDA_FIXUP_PINS, 3255 .type = HDA_FIXUP_PINS,
3247 .v.pins = (const struct hda_pintbl[]) { 3256 .v.pins = (const struct hda_pintbl[]) {
@@ -3270,6 +3279,7 @@ static const struct hda_model_fixup stac927x_models[] = {
3270 { .id = STAC_D965_5ST_NO_FP, .name = "5stack-no-fp" }, 3279 { .id = STAC_D965_5ST_NO_FP, .name = "5stack-no-fp" },
3271 { .id = STAC_DELL_3ST, .name = "dell-3stack" }, 3280 { .id = STAC_DELL_3ST, .name = "dell-3stack" },
3272 { .id = STAC_DELL_BIOS, .name = "dell-bios" }, 3281 { .id = STAC_DELL_BIOS, .name = "dell-bios" },
3282 { .id = STAC_DELL_BIOS_AMIC, .name = "dell-bios-amic" },
3273 { .id = STAC_927X_VOLKNOB, .name = "volknob" }, 3283 { .id = STAC_927X_VOLKNOB, .name = "volknob" },
3274 {} 3284 {}
3275}; 3285};
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index e2481baddc70..0bc20ef5687a 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -207,9 +207,9 @@ static void vt1708_stop_hp_work(struct hda_codec *codec)
207 return; 207 return;
208 if (spec->hp_work_active) { 208 if (spec->hp_work_active) {
209 snd_hda_codec_write(codec, 0x1, 0, 0xf81, 1); 209 snd_hda_codec_write(codec, 0x1, 0, 0xf81, 1);
210 codec->jackpoll_interval = 0;
210 cancel_delayed_work_sync(&codec->jackpoll_work); 211 cancel_delayed_work_sync(&codec->jackpoll_work);
211 spec->hp_work_active = false; 212 spec->hp_work_active = false;
212 codec->jackpoll_interval = 0;
213 } 213 }
214} 214}
215 215
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 2a8ad9d1a2ae..bb9ebc5543d7 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -28,6 +28,7 @@
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/pci.h> 29#include <linux/pci.h>
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/vmalloc.h>
31 32
32#include <sound/core.h> 33#include <sound/core.h>
33#include <sound/info.h> 34#include <sound/info.h>
@@ -198,6 +199,31 @@ MODULE_PARM_DESC(enable, "Enable RME Digi96 soundcard.");
198#define RME96_AD1852_VOL_BITS 14 199#define RME96_AD1852_VOL_BITS 14
199#define RME96_AD1855_VOL_BITS 10 200#define RME96_AD1855_VOL_BITS 10
200 201
202/* Defines for snd_rme96_trigger */
203#define RME96_TB_START_PLAYBACK 1
204#define RME96_TB_START_CAPTURE 2
205#define RME96_TB_STOP_PLAYBACK 4
206#define RME96_TB_STOP_CAPTURE 8
207#define RME96_TB_RESET_PLAYPOS 16
208#define RME96_TB_RESET_CAPTUREPOS 32
209#define RME96_TB_CLEAR_PLAYBACK_IRQ 64
210#define RME96_TB_CLEAR_CAPTURE_IRQ 128
211#define RME96_RESUME_PLAYBACK (RME96_TB_START_PLAYBACK)
212#define RME96_RESUME_CAPTURE (RME96_TB_START_CAPTURE)
213#define RME96_RESUME_BOTH (RME96_RESUME_PLAYBACK \
214 | RME96_RESUME_CAPTURE)
215#define RME96_START_PLAYBACK (RME96_TB_START_PLAYBACK \
216 | RME96_TB_RESET_PLAYPOS)
217#define RME96_START_CAPTURE (RME96_TB_START_CAPTURE \
218 | RME96_TB_RESET_CAPTUREPOS)
219#define RME96_START_BOTH (RME96_START_PLAYBACK \
220 | RME96_START_CAPTURE)
221#define RME96_STOP_PLAYBACK (RME96_TB_STOP_PLAYBACK \
222 | RME96_TB_CLEAR_PLAYBACK_IRQ)
223#define RME96_STOP_CAPTURE (RME96_TB_STOP_CAPTURE \
224 | RME96_TB_CLEAR_CAPTURE_IRQ)
225#define RME96_STOP_BOTH (RME96_STOP_PLAYBACK \
226 | RME96_STOP_CAPTURE)
201 227
202struct rme96 { 228struct rme96 {
203 spinlock_t lock; 229 spinlock_t lock;
@@ -214,6 +240,13 @@ struct rme96 {
214 240
215 u8 rev; /* card revision number */ 241 u8 rev; /* card revision number */
216 242
243#ifdef CONFIG_PM
244 u32 playback_pointer;
245 u32 capture_pointer;
246 void *playback_suspend_buffer;
247 void *capture_suspend_buffer;
248#endif
249
217 struct snd_pcm_substream *playback_substream; 250 struct snd_pcm_substream *playback_substream;
218 struct snd_pcm_substream *capture_substream; 251 struct snd_pcm_substream *capture_substream;
219 252
@@ -344,6 +377,8 @@ static struct snd_pcm_hardware snd_rme96_playback_spdif_info =
344{ 377{
345 .info = (SNDRV_PCM_INFO_MMAP_IOMEM | 378 .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
346 SNDRV_PCM_INFO_MMAP_VALID | 379 SNDRV_PCM_INFO_MMAP_VALID |
380 SNDRV_PCM_INFO_SYNC_START |
381 SNDRV_PCM_INFO_RESUME |
347 SNDRV_PCM_INFO_INTERLEAVED | 382 SNDRV_PCM_INFO_INTERLEAVED |
348 SNDRV_PCM_INFO_PAUSE), 383 SNDRV_PCM_INFO_PAUSE),
349 .formats = (SNDRV_PCM_FMTBIT_S16_LE | 384 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
@@ -373,6 +408,8 @@ static struct snd_pcm_hardware snd_rme96_capture_spdif_info =
373{ 408{
374 .info = (SNDRV_PCM_INFO_MMAP_IOMEM | 409 .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
375 SNDRV_PCM_INFO_MMAP_VALID | 410 SNDRV_PCM_INFO_MMAP_VALID |
411 SNDRV_PCM_INFO_SYNC_START |
412 SNDRV_PCM_INFO_RESUME |
376 SNDRV_PCM_INFO_INTERLEAVED | 413 SNDRV_PCM_INFO_INTERLEAVED |
377 SNDRV_PCM_INFO_PAUSE), 414 SNDRV_PCM_INFO_PAUSE),
378 .formats = (SNDRV_PCM_FMTBIT_S16_LE | 415 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
@@ -402,6 +439,8 @@ static struct snd_pcm_hardware snd_rme96_playback_adat_info =
402{ 439{
403 .info = (SNDRV_PCM_INFO_MMAP_IOMEM | 440 .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
404 SNDRV_PCM_INFO_MMAP_VALID | 441 SNDRV_PCM_INFO_MMAP_VALID |
442 SNDRV_PCM_INFO_SYNC_START |
443 SNDRV_PCM_INFO_RESUME |
405 SNDRV_PCM_INFO_INTERLEAVED | 444 SNDRV_PCM_INFO_INTERLEAVED |
406 SNDRV_PCM_INFO_PAUSE), 445 SNDRV_PCM_INFO_PAUSE),
407 .formats = (SNDRV_PCM_FMTBIT_S16_LE | 446 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
@@ -427,6 +466,8 @@ static struct snd_pcm_hardware snd_rme96_capture_adat_info =
427{ 466{
428 .info = (SNDRV_PCM_INFO_MMAP_IOMEM | 467 .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
429 SNDRV_PCM_INFO_MMAP_VALID | 468 SNDRV_PCM_INFO_MMAP_VALID |
469 SNDRV_PCM_INFO_SYNC_START |
470 SNDRV_PCM_INFO_RESUME |
430 SNDRV_PCM_INFO_INTERLEAVED | 471 SNDRV_PCM_INFO_INTERLEAVED |
431 SNDRV_PCM_INFO_PAUSE), 472 SNDRV_PCM_INFO_PAUSE),
432 .formats = (SNDRV_PCM_FMTBIT_S16_LE | 473 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
@@ -1045,54 +1086,35 @@ snd_rme96_capture_hw_params(struct snd_pcm_substream *substream,
1045} 1086}
1046 1087
1047static void 1088static void
1048snd_rme96_playback_start(struct rme96 *rme96, 1089snd_rme96_trigger(struct rme96 *rme96,
1049 int from_pause) 1090 int op)
1050{ 1091{
1051 if (!from_pause) { 1092 if (op & RME96_TB_RESET_PLAYPOS)
1052 writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS); 1093 writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS);
1053 } 1094 if (op & RME96_TB_RESET_CAPTUREPOS)
1054
1055 rme96->wcreg |= RME96_WCR_START;
1056 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1057}
1058
1059static void
1060snd_rme96_capture_start(struct rme96 *rme96,
1061 int from_pause)
1062{
1063 if (!from_pause) {
1064 writel(0, rme96->iobase + RME96_IO_RESET_REC_POS); 1095 writel(0, rme96->iobase + RME96_IO_RESET_REC_POS);
1065 } 1096 if (op & RME96_TB_CLEAR_PLAYBACK_IRQ) {
1066 1097 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
1067 rme96->wcreg |= RME96_WCR_START_2; 1098 if (rme96->rcreg & RME96_RCR_IRQ)
1099 writel(0, rme96->iobase + RME96_IO_CONFIRM_PLAY_IRQ);
1100 }
1101 if (op & RME96_TB_CLEAR_CAPTURE_IRQ) {
1102 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
1103 if (rme96->rcreg & RME96_RCR_IRQ_2)
1104 writel(0, rme96->iobase + RME96_IO_CONFIRM_REC_IRQ);
1105 }
1106 if (op & RME96_TB_START_PLAYBACK)
1107 rme96->wcreg |= RME96_WCR_START;
1108 if (op & RME96_TB_STOP_PLAYBACK)
1109 rme96->wcreg &= ~RME96_WCR_START;
1110 if (op & RME96_TB_START_CAPTURE)
1111 rme96->wcreg |= RME96_WCR_START_2;
1112 if (op & RME96_TB_STOP_CAPTURE)
1113 rme96->wcreg &= ~RME96_WCR_START_2;
1068 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); 1114 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1069} 1115}
1070 1116
1071static void
1072snd_rme96_playback_stop(struct rme96 *rme96)
1073{
1074 /*
1075 * Check if there is an unconfirmed IRQ, if so confirm it, or else
1076 * the hardware will not stop generating interrupts
1077 */
1078 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
1079 if (rme96->rcreg & RME96_RCR_IRQ) {
1080 writel(0, rme96->iobase + RME96_IO_CONFIRM_PLAY_IRQ);
1081 }
1082 rme96->wcreg &= ~RME96_WCR_START;
1083 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1084}
1085 1117
1086static void
1087snd_rme96_capture_stop(struct rme96 *rme96)
1088{
1089 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
1090 if (rme96->rcreg & RME96_RCR_IRQ_2) {
1091 writel(0, rme96->iobase + RME96_IO_CONFIRM_REC_IRQ);
1092 }
1093 rme96->wcreg &= ~RME96_WCR_START_2;
1094 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1095}
1096 1118
1097static irqreturn_t 1119static irqreturn_t
1098snd_rme96_interrupt(int irq, 1120snd_rme96_interrupt(int irq,
@@ -1155,6 +1177,7 @@ snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream)
1155 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1177 struct rme96 *rme96 = snd_pcm_substream_chip(substream);
1156 struct snd_pcm_runtime *runtime = substream->runtime; 1178 struct snd_pcm_runtime *runtime = substream->runtime;
1157 1179
1180 snd_pcm_set_sync(substream);
1158 spin_lock_irq(&rme96->lock); 1181 spin_lock_irq(&rme96->lock);
1159 if (rme96->playback_substream != NULL) { 1182 if (rme96->playback_substream != NULL) {
1160 spin_unlock_irq(&rme96->lock); 1183 spin_unlock_irq(&rme96->lock);
@@ -1191,6 +1214,7 @@ snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream)
1191 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1214 struct rme96 *rme96 = snd_pcm_substream_chip(substream);
1192 struct snd_pcm_runtime *runtime = substream->runtime; 1215 struct snd_pcm_runtime *runtime = substream->runtime;
1193 1216
1217 snd_pcm_set_sync(substream);
1194 runtime->hw = snd_rme96_capture_spdif_info; 1218 runtime->hw = snd_rme96_capture_spdif_info;
1195 if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG && 1219 if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
1196 (rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) 1220 (rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0)
@@ -1222,6 +1246,7 @@ snd_rme96_playback_adat_open(struct snd_pcm_substream *substream)
1222 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1246 struct rme96 *rme96 = snd_pcm_substream_chip(substream);
1223 struct snd_pcm_runtime *runtime = substream->runtime; 1247 struct snd_pcm_runtime *runtime = substream->runtime;
1224 1248
1249 snd_pcm_set_sync(substream);
1225 spin_lock_irq(&rme96->lock); 1250 spin_lock_irq(&rme96->lock);
1226 if (rme96->playback_substream != NULL) { 1251 if (rme96->playback_substream != NULL) {
1227 spin_unlock_irq(&rme96->lock); 1252 spin_unlock_irq(&rme96->lock);
@@ -1253,6 +1278,7 @@ snd_rme96_capture_adat_open(struct snd_pcm_substream *substream)
1253 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1278 struct rme96 *rme96 = snd_pcm_substream_chip(substream);
1254 struct snd_pcm_runtime *runtime = substream->runtime; 1279 struct snd_pcm_runtime *runtime = substream->runtime;
1255 1280
1281 snd_pcm_set_sync(substream);
1256 runtime->hw = snd_rme96_capture_adat_info; 1282 runtime->hw = snd_rme96_capture_adat_info;
1257 if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) { 1283 if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) {
1258 /* makes no sense to use analog input. Note that analog 1284 /* makes no sense to use analog input. Note that analog
@@ -1288,7 +1314,7 @@ snd_rme96_playback_close(struct snd_pcm_substream *substream)
1288 1314
1289 spin_lock_irq(&rme96->lock); 1315 spin_lock_irq(&rme96->lock);
1290 if (RME96_ISPLAYING(rme96)) { 1316 if (RME96_ISPLAYING(rme96)) {
1291 snd_rme96_playback_stop(rme96); 1317 snd_rme96_trigger(rme96, RME96_STOP_PLAYBACK);
1292 } 1318 }
1293 rme96->playback_substream = NULL; 1319 rme96->playback_substream = NULL;
1294 rme96->playback_periodsize = 0; 1320 rme96->playback_periodsize = 0;
@@ -1309,7 +1335,7 @@ snd_rme96_capture_close(struct snd_pcm_substream *substream)
1309 1335
1310 spin_lock_irq(&rme96->lock); 1336 spin_lock_irq(&rme96->lock);
1311 if (RME96_ISRECORDING(rme96)) { 1337 if (RME96_ISRECORDING(rme96)) {
1312 snd_rme96_capture_stop(rme96); 1338 snd_rme96_trigger(rme96, RME96_STOP_CAPTURE);
1313 } 1339 }
1314 rme96->capture_substream = NULL; 1340 rme96->capture_substream = NULL;
1315 rme96->capture_periodsize = 0; 1341 rme96->capture_periodsize = 0;
@@ -1324,7 +1350,7 @@ snd_rme96_playback_prepare(struct snd_pcm_substream *substream)
1324 1350
1325 spin_lock_irq(&rme96->lock); 1351 spin_lock_irq(&rme96->lock);
1326 if (RME96_ISPLAYING(rme96)) { 1352 if (RME96_ISPLAYING(rme96)) {
1327 snd_rme96_playback_stop(rme96); 1353 snd_rme96_trigger(rme96, RME96_STOP_PLAYBACK);
1328 } 1354 }
1329 writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS); 1355 writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS);
1330 spin_unlock_irq(&rme96->lock); 1356 spin_unlock_irq(&rme96->lock);
@@ -1338,7 +1364,7 @@ snd_rme96_capture_prepare(struct snd_pcm_substream *substream)
1338 1364
1339 spin_lock_irq(&rme96->lock); 1365 spin_lock_irq(&rme96->lock);
1340 if (RME96_ISRECORDING(rme96)) { 1366 if (RME96_ISRECORDING(rme96)) {
1341 snd_rme96_capture_stop(rme96); 1367 snd_rme96_trigger(rme96, RME96_STOP_CAPTURE);
1342 } 1368 }
1343 writel(0, rme96->iobase + RME96_IO_RESET_REC_POS); 1369 writel(0, rme96->iobase + RME96_IO_RESET_REC_POS);
1344 spin_unlock_irq(&rme96->lock); 1370 spin_unlock_irq(&rme96->lock);
@@ -1350,41 +1376,55 @@ snd_rme96_playback_trigger(struct snd_pcm_substream *substream,
1350 int cmd) 1376 int cmd)
1351{ 1377{
1352 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1378 struct rme96 *rme96 = snd_pcm_substream_chip(substream);
1379 struct snd_pcm_substream *s;
1380 bool sync;
1381
1382 snd_pcm_group_for_each_entry(s, substream) {
1383 if (snd_pcm_substream_chip(s) == rme96)
1384 snd_pcm_trigger_done(s, substream);
1385 }
1386
1387 sync = (rme96->playback_substream && rme96->capture_substream) &&
1388 (rme96->playback_substream->group ==
1389 rme96->capture_substream->group);
1353 1390
1354 switch (cmd) { 1391 switch (cmd) {
1355 case SNDRV_PCM_TRIGGER_START: 1392 case SNDRV_PCM_TRIGGER_START:
1356 if (!RME96_ISPLAYING(rme96)) { 1393 if (!RME96_ISPLAYING(rme96)) {
1357 if (substream != rme96->playback_substream) { 1394 if (substream != rme96->playback_substream)
1358 return -EBUSY; 1395 return -EBUSY;
1359 } 1396 snd_rme96_trigger(rme96, sync ? RME96_START_BOTH
1360 snd_rme96_playback_start(rme96, 0); 1397 : RME96_START_PLAYBACK);
1361 } 1398 }
1362 break; 1399 break;
1363 1400
1401 case SNDRV_PCM_TRIGGER_SUSPEND:
1364 case SNDRV_PCM_TRIGGER_STOP: 1402 case SNDRV_PCM_TRIGGER_STOP:
1365 if (RME96_ISPLAYING(rme96)) { 1403 if (RME96_ISPLAYING(rme96)) {
1366 if (substream != rme96->playback_substream) { 1404 if (substream != rme96->playback_substream)
1367 return -EBUSY; 1405 return -EBUSY;
1368 } 1406 snd_rme96_trigger(rme96, sync ? RME96_STOP_BOTH
1369 snd_rme96_playback_stop(rme96); 1407 : RME96_STOP_PLAYBACK);
1370 } 1408 }
1371 break; 1409 break;
1372 1410
1373 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1411 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1374 if (RME96_ISPLAYING(rme96)) { 1412 if (RME96_ISPLAYING(rme96))
1375 snd_rme96_playback_stop(rme96); 1413 snd_rme96_trigger(rme96, sync ? RME96_STOP_BOTH
1376 } 1414 : RME96_STOP_PLAYBACK);
1377 break; 1415 break;
1378 1416
1417 case SNDRV_PCM_TRIGGER_RESUME:
1379 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1418 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1380 if (!RME96_ISPLAYING(rme96)) { 1419 if (!RME96_ISPLAYING(rme96))
1381 snd_rme96_playback_start(rme96, 1); 1420 snd_rme96_trigger(rme96, sync ? RME96_RESUME_BOTH
1382 } 1421 : RME96_RESUME_PLAYBACK);
1383 break; 1422 break;
1384 1423
1385 default: 1424 default:
1386 return -EINVAL; 1425 return -EINVAL;
1387 } 1426 }
1427
1388 return 0; 1428 return 0;
1389} 1429}
1390 1430
@@ -1393,38 +1433,51 @@ snd_rme96_capture_trigger(struct snd_pcm_substream *substream,
1393 int cmd) 1433 int cmd)
1394{ 1434{
1395 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1435 struct rme96 *rme96 = snd_pcm_substream_chip(substream);
1436 struct snd_pcm_substream *s;
1437 bool sync;
1438
1439 snd_pcm_group_for_each_entry(s, substream) {
1440 if (snd_pcm_substream_chip(s) == rme96)
1441 snd_pcm_trigger_done(s, substream);
1442 }
1443
1444 sync = (rme96->playback_substream && rme96->capture_substream) &&
1445 (rme96->playback_substream->group ==
1446 rme96->capture_substream->group);
1396 1447
1397 switch (cmd) { 1448 switch (cmd) {
1398 case SNDRV_PCM_TRIGGER_START: 1449 case SNDRV_PCM_TRIGGER_START:
1399 if (!RME96_ISRECORDING(rme96)) { 1450 if (!RME96_ISRECORDING(rme96)) {
1400 if (substream != rme96->capture_substream) { 1451 if (substream != rme96->capture_substream)
1401 return -EBUSY; 1452 return -EBUSY;
1402 } 1453 snd_rme96_trigger(rme96, sync ? RME96_START_BOTH
1403 snd_rme96_capture_start(rme96, 0); 1454 : RME96_START_CAPTURE);
1404 } 1455 }
1405 break; 1456 break;
1406 1457
1458 case SNDRV_PCM_TRIGGER_SUSPEND:
1407 case SNDRV_PCM_TRIGGER_STOP: 1459 case SNDRV_PCM_TRIGGER_STOP:
1408 if (RME96_ISRECORDING(rme96)) { 1460 if (RME96_ISRECORDING(rme96)) {
1409 if (substream != rme96->capture_substream) { 1461 if (substream != rme96->capture_substream)
1410 return -EBUSY; 1462 return -EBUSY;
1411 } 1463 snd_rme96_trigger(rme96, sync ? RME96_STOP_BOTH
1412 snd_rme96_capture_stop(rme96); 1464 : RME96_STOP_CAPTURE);
1413 } 1465 }
1414 break; 1466 break;
1415 1467
1416 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1468 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1417 if (RME96_ISRECORDING(rme96)) { 1469 if (RME96_ISRECORDING(rme96))
1418 snd_rme96_capture_stop(rme96); 1470 snd_rme96_trigger(rme96, sync ? RME96_STOP_BOTH
1419 } 1471 : RME96_STOP_CAPTURE);
1420 break; 1472 break;
1421 1473
1474 case SNDRV_PCM_TRIGGER_RESUME:
1422 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1475 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1423 if (!RME96_ISRECORDING(rme96)) { 1476 if (!RME96_ISRECORDING(rme96))
1424 snd_rme96_capture_start(rme96, 1); 1477 snd_rme96_trigger(rme96, sync ? RME96_RESUME_BOTH
1425 } 1478 : RME96_RESUME_CAPTURE);
1426 break; 1479 break;
1427 1480
1428 default: 1481 default:
1429 return -EINVAL; 1482 return -EINVAL;
1430 } 1483 }
@@ -1505,8 +1558,7 @@ snd_rme96_free(void *private_data)
1505 return; 1558 return;
1506 } 1559 }
1507 if (rme96->irq >= 0) { 1560 if (rme96->irq >= 0) {
1508 snd_rme96_playback_stop(rme96); 1561 snd_rme96_trigger(rme96, RME96_STOP_BOTH);
1509 snd_rme96_capture_stop(rme96);
1510 rme96->areg &= ~RME96_AR_DAC_EN; 1562 rme96->areg &= ~RME96_AR_DAC_EN;
1511 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); 1563 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
1512 free_irq(rme96->irq, (void *)rme96); 1564 free_irq(rme96->irq, (void *)rme96);
@@ -1520,6 +1572,10 @@ snd_rme96_free(void *private_data)
1520 pci_release_regions(rme96->pci); 1572 pci_release_regions(rme96->pci);
1521 rme96->port = 0; 1573 rme96->port = 0;
1522 } 1574 }
1575#ifdef CONFIG_PM
1576 vfree(rme96->playback_suspend_buffer);
1577 vfree(rme96->capture_suspend_buffer);
1578#endif
1523 pci_disable_device(rme96->pci); 1579 pci_disable_device(rme96->pci);
1524} 1580}
1525 1581
@@ -1606,8 +1662,7 @@ snd_rme96_create(struct rme96 *rme96)
1606 rme96->capture_periodsize = 0; 1662 rme96->capture_periodsize = 0;
1607 1663
1608 /* make sure playback/capture is stopped, if by some reason active */ 1664 /* make sure playback/capture is stopped, if by some reason active */
1609 snd_rme96_playback_stop(rme96); 1665 snd_rme96_trigger(rme96, RME96_STOP_BOTH);
1610 snd_rme96_capture_stop(rme96);
1611 1666
1612 /* set default values in registers */ 1667 /* set default values in registers */
1613 rme96->wcreg = 1668 rme96->wcreg =
@@ -2319,6 +2374,87 @@ snd_rme96_create_switches(struct snd_card *card,
2319 * Card initialisation 2374 * Card initialisation
2320 */ 2375 */
2321 2376
2377#ifdef CONFIG_PM
2378
2379static int
2380snd_rme96_suspend(struct pci_dev *pci,
2381 pm_message_t state)
2382{
2383 struct snd_card *card = pci_get_drvdata(pci);
2384 struct rme96 *rme96 = card->private_data;
2385
2386 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2387 snd_pcm_suspend(rme96->playback_substream);
2388 snd_pcm_suspend(rme96->capture_substream);
2389
2390 /* save capture & playback pointers */
2391 rme96->playback_pointer = readl(rme96->iobase + RME96_IO_GET_PLAY_POS)
2392 & RME96_RCR_AUDIO_ADDR_MASK;
2393 rme96->capture_pointer = readl(rme96->iobase + RME96_IO_GET_REC_POS)
2394 & RME96_RCR_AUDIO_ADDR_MASK;
2395
2396 /* save playback and capture buffers */
2397 memcpy_fromio(rme96->playback_suspend_buffer,
2398 rme96->iobase + RME96_IO_PLAY_BUFFER, RME96_BUFFER_SIZE);
2399 memcpy_fromio(rme96->capture_suspend_buffer,
2400 rme96->iobase + RME96_IO_REC_BUFFER, RME96_BUFFER_SIZE);
2401
2402 /* disable the DAC */
2403 rme96->areg &= ~RME96_AR_DAC_EN;
2404 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
2405
2406 pci_disable_device(pci);
2407 pci_save_state(pci);
2408
2409 return 0;
2410}
2411
2412static int
2413snd_rme96_resume(struct pci_dev *pci)
2414{
2415 struct snd_card *card = pci_get_drvdata(pci);
2416 struct rme96 *rme96 = card->private_data;
2417
2418 pci_restore_state(pci);
2419 if (pci_enable_device(pci) < 0) {
2420 printk(KERN_ERR "rme96: pci_enable_device failed, disabling device\n");
2421 snd_card_disconnect(card);
2422 return -EIO;
2423 }
2424
2425 /* reset playback and record buffer pointers */
2426 writel(0, rme96->iobase + RME96_IO_SET_PLAY_POS
2427 + rme96->playback_pointer);
2428 writel(0, rme96->iobase + RME96_IO_SET_REC_POS
2429 + rme96->capture_pointer);
2430
2431 /* restore playback and capture buffers */
2432 memcpy_toio(rme96->iobase + RME96_IO_PLAY_BUFFER,
2433 rme96->playback_suspend_buffer, RME96_BUFFER_SIZE);
2434 memcpy_toio(rme96->iobase + RME96_IO_REC_BUFFER,
2435 rme96->capture_suspend_buffer, RME96_BUFFER_SIZE);
2436
2437 /* reset the ADC */
2438 writel(rme96->areg | RME96_AR_PD2,
2439 rme96->iobase + RME96_IO_ADDITIONAL_REG);
2440 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
2441
2442 /* reset and enable DAC, restore analog volume */
2443 snd_rme96_reset_dac(rme96);
2444 rme96->areg |= RME96_AR_DAC_EN;
2445 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
2446 if (RME96_HAS_ANALOG_OUT(rme96)) {
2447 usleep_range(3000, 10000);
2448 snd_rme96_apply_dac_volume(rme96);
2449 }
2450
2451 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2452
2453 return 0;
2454}
2455
2456#endif
2457
2322static void snd_rme96_card_free(struct snd_card *card) 2458static void snd_rme96_card_free(struct snd_card *card)
2323{ 2459{
2324 snd_rme96_free(card->private_data); 2460 snd_rme96_free(card->private_data);
@@ -2355,6 +2491,23 @@ snd_rme96_probe(struct pci_dev *pci,
2355 return err; 2491 return err;
2356 } 2492 }
2357 2493
2494#ifdef CONFIG_PM
2495 rme96->playback_suspend_buffer = vmalloc(RME96_BUFFER_SIZE);
2496 if (!rme96->playback_suspend_buffer) {
2497 snd_printk(KERN_ERR
2498 "Failed to allocate playback suspend buffer!\n");
2499 snd_card_free(card);
2500 return -ENOMEM;
2501 }
2502 rme96->capture_suspend_buffer = vmalloc(RME96_BUFFER_SIZE);
2503 if (!rme96->capture_suspend_buffer) {
2504 snd_printk(KERN_ERR
2505 "Failed to allocate capture suspend buffer!\n");
2506 snd_card_free(card);
2507 return -ENOMEM;
2508 }
2509#endif
2510
2358 strcpy(card->driver, "Digi96"); 2511 strcpy(card->driver, "Digi96");
2359 switch (rme96->pci->device) { 2512 switch (rme96->pci->device) {
2360 case PCI_DEVICE_ID_RME_DIGI96: 2513 case PCI_DEVICE_ID_RME_DIGI96:
@@ -2397,6 +2550,10 @@ static struct pci_driver rme96_driver = {
2397 .id_table = snd_rme96_ids, 2550 .id_table = snd_rme96_ids,
2398 .probe = snd_rme96_probe, 2551 .probe = snd_rme96_probe,
2399 .remove = snd_rme96_remove, 2552 .remove = snd_rme96_remove,
2553#ifdef CONFIG_PM
2554 .suspend = snd_rme96_suspend,
2555 .resume = snd_rme96_resume,
2556#endif
2400}; 2557};
2401 2558
2402module_pci_driver(rme96_driver); 2559module_pci_driver(rme96_driver);
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index bd501931ee23..3cde55b753e2 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -38,6 +38,97 @@
38 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 38 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
39 * 39 *
40 */ 40 */
41
42/* ************* Register Documentation *******************************************************
43 *
44 * Work in progress! Documentation is based on the code in this file.
45 *
46 * --------- HDSPM_controlRegister ---------
47 * :7654.3210:7654.3210:7654.3210:7654.3210: bit number per byte
48 * :||||.||||:||||.||||:||||.||||:||||.||||:
49 * :3322.2222:2222.1111:1111.1100:0000.0000: bit number
50 * :1098.7654:3210.9876:5432.1098:7654.3210: 0..31
51 * :||||.||||:||||.||||:||||.||||:||||.||||:
52 * :8421.8421:8421.8421:8421.8421:8421.8421: hex digit
53 * : . : . : . : x . : HDSPM_AudioInterruptEnable \_ setting both bits
54 * : . : . : . : . x: HDSPM_Start / enables audio IO
55 * : . : . : . : x. : HDSPM_ClockModeMaster - 1: Master, 0: Slave
56 * : . : . : . : .210 : HDSPM_LatencyMask - 3 Bit value for latency
57 * : . : . : . : . : 0:64, 1:128, 2:256, 3:512,
58 * : . : . : . : . : 4:1024, 5:2048, 6:4096, 7:8192
59 * :x . : . : . x:xx . : HDSPM_FrequencyMask
60 * : . : . : . :10 . : HDSPM_Frequency1|HDSPM_Frequency0: 1=32K,2=44.1K,3=48K,0=??
61 * : . : . : . x: . : <MADI> HDSPM_DoubleSpeed
62 * :x . : . : . : . : <MADI> HDSPM_QuadSpeed
63 * : . 3 : . 10: 2 . : . : HDSPM_SyncRefMask :
64 * : . : . x: . : . : HDSPM_SyncRef0
65 * : . : . x : . : . : HDSPM_SyncRef1
66 * : . : . : x . : . : <AES32> HDSPM_SyncRef2
67 * : . x : . : . : . : <AES32> HDSPM_SyncRef3
68 * : . : . 10: . : . : <MADI> sync ref: 0:WC, 1:Madi, 2:TCO, 3:SyncIn
69 * : . 3 : . 10: 2 . : . : <AES32> 0:WC, 1:AES1 ... 8:AES8, 9: TCO, 10:SyncIn?
70 * : . x : . : . : . : <MADIe> HDSPe_FLOAT_FORMAT
71 * : . : . : x . : . : <MADI> HDSPM_InputSelect0 : 0=optical,1=coax
72 * : . : . :x . : . : <MADI> HDSPM_InputSelect1
73 * : . : .x : . : . : <MADI> HDSPM_clr_tms
74 * : . : . : . x : . : <MADI> HDSPM_TX_64ch
75 * : . : . : . x : . : <AES32> HDSPM_Emphasis
76 * : . : . : .x : . : <MADI> HDSPM_AutoInp
77 * : . : . x : . : . : <MADI> HDSPM_SMUX
78 * : . : .x : . : . : <MADI> HDSPM_clr_tms
79 * : . : x. : . : . : <MADI> HDSPM_taxi_reset
80 * : . x: . : . : . : <MADI> HDSPM_LineOut
81 * : . x: . : . : . : <AES32> ??????????????????
82 * : . : x. : . : . : <AES32> HDSPM_WCK48
83 * : . : . : .x : . : <AES32> HDSPM_Dolby
84 * : . : x . : . : . : HDSPM_Midi0InterruptEnable
85 * : . :x . : . : . : HDSPM_Midi1InterruptEnable
86 * : . : x . : . : . : HDSPM_Midi2InterruptEnable
87 * : . x : . : . : . : <MADI> HDSPM_Midi3InterruptEnable
88 * : . x : . : . : . : <AES32> HDSPM_DS_DoubleWire
89 * : .x : . : . : . : <AES32> HDSPM_QS_DoubleWire
90 * : x. : . : . : . : <AES32> HDSPM_QS_QuadWire
91 * : . : . : . x : . : <AES32> HDSPM_Professional
92 * : x . : . : . : . : HDSPM_wclk_sel
93 * : . : . : . : . :
94 * :7654.3210:7654.3210:7654.3210:7654.3210: bit number per byte
95 * :||||.||||:||||.||||:||||.||||:||||.||||:
96 * :3322.2222:2222.1111:1111.1100:0000.0000: bit number
97 * :1098.7654:3210.9876:5432.1098:7654.3210: 0..31
98 * :||||.||||:||||.||||:||||.||||:||||.||||:
99 * :8421.8421:8421.8421:8421.8421:8421.8421:hex digit
100 *
101 *
102 *
103 * AIO / RayDAT only
104 *
105 * ------------ HDSPM_WR_SETTINGS ----------
106 * :3322.2222:2222.1111:1111.1100:0000.0000: bit number per byte
107 * :1098.7654:3210.9876:5432.1098:7654.3210:
108 * :||||.||||:||||.||||:||||.||||:||||.||||: bit number
109 * :7654.3210:7654.3210:7654.3210:7654.3210: 0..31
110 * :||||.||||:||||.||||:||||.||||:||||.||||:
111 * :8421.8421:8421.8421:8421.8421:8421.8421: hex digit
112 * : . : . : . : . x: HDSPM_c0Master 1: Master, 0: Slave
113 * : . : . : . : . x : HDSPM_c0_SyncRef0
114 * : . : . : . : . x : HDSPM_c0_SyncRef1
115 * : . : . : . : .x : HDSPM_c0_SyncRef2
116 * : . : . : . : x. : HDSPM_c0_SyncRef3
117 * : . : . : . : 3.210 : HDSPM_c0_SyncRefMask:
118 * : . : . : . : . : RayDat: 0:WC, 1:AES, 2:SPDIF, 3..6: ADAT1..4,
119 * : . : . : . : . : 9:TCO, 10:SyncIn
120 * : . : . : . : . : AIO: 0:WC, 1:AES, 2: SPDIF, 3: ATAT,
121 * : . : . : . : . : 9:TCO, 10:SyncIn
122 * : . : . : . : . :
123 * : . : . : . : . :
124 * :3322.2222:2222.1111:1111.1100:0000.0000: bit number per byte
125 * :1098.7654:3210.9876:5432.1098:7654.3210:
126 * :||||.||||:||||.||||:||||.||||:||||.||||: bit number
127 * :7654.3210:7654.3210:7654.3210:7654.3210: 0..31
128 * :||||.||||:||||.||||:||||.||||:||||.||||:
129 * :8421.8421:8421.8421:8421.8421:8421.8421: hex digit
130 *
131 */
41#include <linux/init.h> 132#include <linux/init.h>
42#include <linux/delay.h> 133#include <linux/delay.h>
43#include <linux/interrupt.h> 134#include <linux/interrupt.h>
@@ -95,7 +186,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
95#define HDSPM_controlRegister 64 186#define HDSPM_controlRegister 64
96#define HDSPM_interruptConfirmation 96 187#define HDSPM_interruptConfirmation 96
97#define HDSPM_control2Reg 256 /* not in specs ???????? */ 188#define HDSPM_control2Reg 256 /* not in specs ???????? */
98#define HDSPM_freqReg 256 /* for AES32 */ 189#define HDSPM_freqReg 256 /* for setting arbitrary clock values (DDS feature) */
99#define HDSPM_midiDataOut0 352 /* just believe in old code */ 190#define HDSPM_midiDataOut0 352 /* just believe in old code */
100#define HDSPM_midiDataOut1 356 191#define HDSPM_midiDataOut1 356
101#define HDSPM_eeprom_wr 384 /* for AES32 */ 192#define HDSPM_eeprom_wr 384 /* for AES32 */
@@ -258,6 +349,25 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
258 349
259#define HDSPM_wclk_sel (1<<30) 350#define HDSPM_wclk_sel (1<<30)
260 351
352/* additional control register bits for AIO*/
353#define HDSPM_c0_Wck48 0x20 /* also RayDAT */
354#define HDSPM_c0_Input0 0x1000
355#define HDSPM_c0_Input1 0x2000
356#define HDSPM_c0_Spdif_Opt 0x4000
357#define HDSPM_c0_Pro 0x8000
358#define HDSPM_c0_clr_tms 0x10000
359#define HDSPM_c0_AEB1 0x20000
360#define HDSPM_c0_AEB2 0x40000
361#define HDSPM_c0_LineOut 0x80000
362#define HDSPM_c0_AD_GAIN0 0x100000
363#define HDSPM_c0_AD_GAIN1 0x200000
364#define HDSPM_c0_DA_GAIN0 0x400000
365#define HDSPM_c0_DA_GAIN1 0x800000
366#define HDSPM_c0_PH_GAIN0 0x1000000
367#define HDSPM_c0_PH_GAIN1 0x2000000
368#define HDSPM_c0_Sym6db 0x4000000
369
370
261/* --- bit helper defines */ 371/* --- bit helper defines */
262#define HDSPM_LatencyMask (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2) 372#define HDSPM_LatencyMask (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2)
263#define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1|\ 373#define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1|\
@@ -341,11 +451,11 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
341#define HDSPM_madiLock (1<<3) /* MADI Locked =1, no=0 */ 451#define HDSPM_madiLock (1<<3) /* MADI Locked =1, no=0 */
342#define HDSPM_madiSync (1<<18) /* MADI is in sync */ 452#define HDSPM_madiSync (1<<18) /* MADI is in sync */
343 453
344#define HDSPM_tcoLock 0x00000020 /* Optional TCO locked status FOR HDSPe MADI! */ 454#define HDSPM_tcoLockMadi 0x00000020 /* Optional TCO locked status for HDSPe MADI*/
345#define HDSPM_tcoSync 0x10000000 /* Optional TCO sync status */ 455#define HDSPM_tcoSync 0x10000000 /* Optional TCO sync status for HDSPe MADI and AES32!*/
346 456
347#define HDSPM_syncInLock 0x00010000 /* Sync In lock status FOR HDSPe MADI! */ 457#define HDSPM_syncInLock 0x00010000 /* Sync In lock status for HDSPe MADI! */
348#define HDSPM_syncInSync 0x00020000 /* Sync In sync status FOR HDSPe MADI! */ 458#define HDSPM_syncInSync 0x00020000 /* Sync In sync status for HDSPe MADI! */
349 459
350#define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */ 460#define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */
351 /* since 64byte accurate, last 6 bits are not used */ 461 /* since 64byte accurate, last 6 bits are not used */
@@ -363,7 +473,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
363 * Interrupt 473 * Interrupt
364 */ 474 */
365#define HDSPM_tco_detect 0x08000000 475#define HDSPM_tco_detect 0x08000000
366#define HDSPM_tco_lock 0x20000000 476#define HDSPM_tcoLockAes 0x20000000 /* Optional TCO locked status for HDSPe AES */
367 477
368#define HDSPM_s2_tco_detect 0x00000040 478#define HDSPM_s2_tco_detect 0x00000040
369#define HDSPM_s2_AEBO_D 0x00000080 479#define HDSPM_s2_AEBO_D 0x00000080
@@ -461,7 +571,9 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
461#define HDSPM_AES32_AUTOSYNC_FROM_AES6 6 571#define HDSPM_AES32_AUTOSYNC_FROM_AES6 6
462#define HDSPM_AES32_AUTOSYNC_FROM_AES7 7 572#define HDSPM_AES32_AUTOSYNC_FROM_AES7 7
463#define HDSPM_AES32_AUTOSYNC_FROM_AES8 8 573#define HDSPM_AES32_AUTOSYNC_FROM_AES8 8
464#define HDSPM_AES32_AUTOSYNC_FROM_NONE 9 574#define HDSPM_AES32_AUTOSYNC_FROM_TCO 9
575#define HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN 10
576#define HDSPM_AES32_AUTOSYNC_FROM_NONE 11
465 577
466/* status2 */ 578/* status2 */
467/* HDSPM_LockAES_bit is given by HDSPM_LockAES >> (AES# - 1) */ 579/* HDSPM_LockAES_bit is given by HDSPM_LockAES >> (AES# - 1) */
@@ -537,36 +649,39 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
537/* names for speed modes */ 649/* names for speed modes */
538static char *hdspm_speed_names[] = { "single", "double", "quad" }; 650static char *hdspm_speed_names[] = { "single", "double", "quad" };
539 651
540static char *texts_autosync_aes_tco[] = { "Word Clock", 652static const char *const texts_autosync_aes_tco[] = { "Word Clock",
541 "AES1", "AES2", "AES3", "AES4", 653 "AES1", "AES2", "AES3", "AES4",
542 "AES5", "AES6", "AES7", "AES8", 654 "AES5", "AES6", "AES7", "AES8",
543 "TCO" }; 655 "TCO", "Sync In"
544static char *texts_autosync_aes[] = { "Word Clock", 656};
657static const char *const texts_autosync_aes[] = { "Word Clock",
545 "AES1", "AES2", "AES3", "AES4", 658 "AES1", "AES2", "AES3", "AES4",
546 "AES5", "AES6", "AES7", "AES8" }; 659 "AES5", "AES6", "AES7", "AES8",
547static char *texts_autosync_madi_tco[] = { "Word Clock", 660 "Sync In"
661};
662static const char *const texts_autosync_madi_tco[] = { "Word Clock",
548 "MADI", "TCO", "Sync In" }; 663 "MADI", "TCO", "Sync In" };
549static char *texts_autosync_madi[] = { "Word Clock", 664static const char *const texts_autosync_madi[] = { "Word Clock",
550 "MADI", "Sync In" }; 665 "MADI", "Sync In" };
551 666
552static char *texts_autosync_raydat_tco[] = { 667static const char *const texts_autosync_raydat_tco[] = {
553 "Word Clock", 668 "Word Clock",
554 "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4", 669 "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4",
555 "AES", "SPDIF", "TCO", "Sync In" 670 "AES", "SPDIF", "TCO", "Sync In"
556}; 671};
557static char *texts_autosync_raydat[] = { 672static const char *const texts_autosync_raydat[] = {
558 "Word Clock", 673 "Word Clock",
559 "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4", 674 "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4",
560 "AES", "SPDIF", "Sync In" 675 "AES", "SPDIF", "Sync In"
561}; 676};
562static char *texts_autosync_aio_tco[] = { 677static const char *const texts_autosync_aio_tco[] = {
563 "Word Clock", 678 "Word Clock",
564 "ADAT", "AES", "SPDIF", "TCO", "Sync In" 679 "ADAT", "AES", "SPDIF", "TCO", "Sync In"
565}; 680};
566static char *texts_autosync_aio[] = { "Word Clock", 681static const char *const texts_autosync_aio[] = { "Word Clock",
567 "ADAT", "AES", "SPDIF", "Sync In" }; 682 "ADAT", "AES", "SPDIF", "Sync In" };
568 683
569static char *texts_freq[] = { 684static const char *const texts_freq[] = {
570 "No Lock", 685 "No Lock",
571 "32 kHz", 686 "32 kHz",
572 "44.1 kHz", 687 "44.1 kHz",
@@ -629,7 +744,8 @@ static char *texts_ports_aio_in_ss[] = {
629 "AES.L", "AES.R", 744 "AES.L", "AES.R",
630 "SPDIF.L", "SPDIF.R", 745 "SPDIF.L", "SPDIF.R",
631 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6", 746 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6",
632 "ADAT.7", "ADAT.8" 747 "ADAT.7", "ADAT.8",
748 "AEB.1", "AEB.2", "AEB.3", "AEB.4"
633}; 749};
634 750
635static char *texts_ports_aio_out_ss[] = { 751static char *texts_ports_aio_out_ss[] = {
@@ -638,14 +754,16 @@ static char *texts_ports_aio_out_ss[] = {
638 "SPDIF.L", "SPDIF.R", 754 "SPDIF.L", "SPDIF.R",
639 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6", 755 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6",
640 "ADAT.7", "ADAT.8", 756 "ADAT.7", "ADAT.8",
641 "Phone.L", "Phone.R" 757 "Phone.L", "Phone.R",
758 "AEB.1", "AEB.2", "AEB.3", "AEB.4"
642}; 759};
643 760
644static char *texts_ports_aio_in_ds[] = { 761static char *texts_ports_aio_in_ds[] = {
645 "Analogue.L", "Analogue.R", 762 "Analogue.L", "Analogue.R",
646 "AES.L", "AES.R", 763 "AES.L", "AES.R",
647 "SPDIF.L", "SPDIF.R", 764 "SPDIF.L", "SPDIF.R",
648 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4" 765 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
766 "AEB.1", "AEB.2", "AEB.3", "AEB.4"
649}; 767};
650 768
651static char *texts_ports_aio_out_ds[] = { 769static char *texts_ports_aio_out_ds[] = {
@@ -653,14 +771,16 @@ static char *texts_ports_aio_out_ds[] = {
653 "AES.L", "AES.R", 771 "AES.L", "AES.R",
654 "SPDIF.L", "SPDIF.R", 772 "SPDIF.L", "SPDIF.R",
655 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", 773 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
656 "Phone.L", "Phone.R" 774 "Phone.L", "Phone.R",
775 "AEB.1", "AEB.2", "AEB.3", "AEB.4"
657}; 776};
658 777
659static char *texts_ports_aio_in_qs[] = { 778static char *texts_ports_aio_in_qs[] = {
660 "Analogue.L", "Analogue.R", 779 "Analogue.L", "Analogue.R",
661 "AES.L", "AES.R", 780 "AES.L", "AES.R",
662 "SPDIF.L", "SPDIF.R", 781 "SPDIF.L", "SPDIF.R",
663 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4" 782 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
783 "AEB.1", "AEB.2", "AEB.3", "AEB.4"
664}; 784};
665 785
666static char *texts_ports_aio_out_qs[] = { 786static char *texts_ports_aio_out_qs[] = {
@@ -668,7 +788,8 @@ static char *texts_ports_aio_out_qs[] = {
668 "AES.L", "AES.R", 788 "AES.L", "AES.R",
669 "SPDIF.L", "SPDIF.R", 789 "SPDIF.L", "SPDIF.R",
670 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", 790 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
671 "Phone.L", "Phone.R" 791 "Phone.L", "Phone.R",
792 "AEB.1", "AEB.2", "AEB.3", "AEB.4"
672}; 793};
673 794
674static char *texts_ports_aes32[] = { 795static char *texts_ports_aes32[] = {
@@ -745,8 +866,8 @@ static char channel_map_aio_in_ss[HDSPM_MAX_CHANNELS] = {
745 8, 9, /* aes in, */ 866 8, 9, /* aes in, */
746 10, 11, /* spdif in */ 867 10, 11, /* spdif in */
747 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT in */ 868 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT in */
748 -1, -1, 869 2, 3, 4, 5, /* AEB */
749 -1, -1, -1, -1, -1, -1, -1, -1, 870 -1, -1, -1, -1, -1, -1,
750 -1, -1, -1, -1, -1, -1, -1, -1, 871 -1, -1, -1, -1, -1, -1, -1, -1,
751 -1, -1, -1, -1, -1, -1, -1, -1, 872 -1, -1, -1, -1, -1, -1, -1, -1,
752 -1, -1, -1, -1, -1, -1, -1, -1, 873 -1, -1, -1, -1, -1, -1, -1, -1,
@@ -760,7 +881,8 @@ static char channel_map_aio_out_ss[HDSPM_MAX_CHANNELS] = {
760 10, 11, /* spdif out */ 881 10, 11, /* spdif out */
761 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT out */ 882 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT out */
762 6, 7, /* phone out */ 883 6, 7, /* phone out */
763 -1, -1, -1, -1, -1, -1, -1, -1, 884 2, 3, 4, 5, /* AEB */
885 -1, -1, -1, -1,
764 -1, -1, -1, -1, -1, -1, -1, -1, 886 -1, -1, -1, -1, -1, -1, -1, -1,
765 -1, -1, -1, -1, -1, -1, -1, -1, 887 -1, -1, -1, -1, -1, -1, -1, -1,
766 -1, -1, -1, -1, -1, -1, -1, -1, 888 -1, -1, -1, -1, -1, -1, -1, -1,
@@ -773,7 +895,8 @@ static char channel_map_aio_in_ds[HDSPM_MAX_CHANNELS] = {
773 8, 9, /* aes in */ 895 8, 9, /* aes in */
774 10, 11, /* spdif in */ 896 10, 11, /* spdif in */
775 12, 14, 16, 18, /* adat in */ 897 12, 14, 16, 18, /* adat in */
776 -1, -1, -1, -1, -1, -1, 898 2, 3, 4, 5, /* AEB */
899 -1, -1,
777 -1, -1, -1, -1, -1, -1, -1, -1, 900 -1, -1, -1, -1, -1, -1, -1, -1,
778 -1, -1, -1, -1, -1, -1, -1, -1, 901 -1, -1, -1, -1, -1, -1, -1, -1,
779 -1, -1, -1, -1, -1, -1, -1, -1, 902 -1, -1, -1, -1, -1, -1, -1, -1,
@@ -788,7 +911,7 @@ static char channel_map_aio_out_ds[HDSPM_MAX_CHANNELS] = {
788 10, 11, /* spdif out */ 911 10, 11, /* spdif out */
789 12, 14, 16, 18, /* adat out */ 912 12, 14, 16, 18, /* adat out */
790 6, 7, /* phone out */ 913 6, 7, /* phone out */
791 -1, -1, -1, -1, 914 2, 3, 4, 5, /* AEB */
792 -1, -1, -1, -1, -1, -1, -1, -1, 915 -1, -1, -1, -1, -1, -1, -1, -1,
793 -1, -1, -1, -1, -1, -1, -1, -1, 916 -1, -1, -1, -1, -1, -1, -1, -1,
794 -1, -1, -1, -1, -1, -1, -1, -1, 917 -1, -1, -1, -1, -1, -1, -1, -1,
@@ -802,7 +925,8 @@ static char channel_map_aio_in_qs[HDSPM_MAX_CHANNELS] = {
802 8, 9, /* aes in */ 925 8, 9, /* aes in */
803 10, 11, /* spdif in */ 926 10, 11, /* spdif in */
804 12, 16, /* adat in */ 927 12, 16, /* adat in */
805 -1, -1, -1, -1, -1, -1, -1, -1, 928 2, 3, 4, 5, /* AEB */
929 -1, -1, -1, -1,
806 -1, -1, -1, -1, -1, -1, -1, -1, 930 -1, -1, -1, -1, -1, -1, -1, -1,
807 -1, -1, -1, -1, -1, -1, -1, -1, 931 -1, -1, -1, -1, -1, -1, -1, -1,
808 -1, -1, -1, -1, -1, -1, -1, -1, 932 -1, -1, -1, -1, -1, -1, -1, -1,
@@ -817,7 +941,8 @@ static char channel_map_aio_out_qs[HDSPM_MAX_CHANNELS] = {
817 10, 11, /* spdif out */ 941 10, 11, /* spdif out */
818 12, 16, /* adat out */ 942 12, 16, /* adat out */
819 6, 7, /* phone out */ 943 6, 7, /* phone out */
820 -1, -1, -1, -1, -1, -1, 944 2, 3, 4, 5, /* AEB */
945 -1, -1,
821 -1, -1, -1, -1, -1, -1, -1, -1, 946 -1, -1, -1, -1, -1, -1, -1, -1,
822 -1, -1, -1, -1, -1, -1, -1, -1, 947 -1, -1, -1, -1, -1, -1, -1, -1,
823 -1, -1, -1, -1, -1, -1, -1, -1, 948 -1, -1, -1, -1, -1, -1, -1, -1,
@@ -856,11 +981,11 @@ struct hdspm_midi {
856}; 981};
857 982
858struct hdspm_tco { 983struct hdspm_tco {
859 int input; 984 int input; /* 0: LTC, 1:Video, 2: WC*/
860 int framerate; 985 int framerate; /* 0=24, 1=25, 2=29.97, 3=29.97d, 4=30, 5=30d */
861 int wordclock; 986 int wordclock; /* 0=1:1, 1=44.1->48, 2=48->44.1 */
862 int samplerate; 987 int samplerate; /* 0=44.1, 1=48, 2= freq from app */
863 int pull; 988 int pull; /* 0=0, 1=+0.1%, 2=-0.1%, 3=+4%, 4=-4%*/
864 int term; /* 0 = off, 1 = on */ 989 int term; /* 0 = off, 1 = on */
865}; 990};
866 991
@@ -879,7 +1004,7 @@ struct hdspm {
879 1004
880 u32 control_register; /* cached value */ 1005 u32 control_register; /* cached value */
881 u32 control2_register; /* cached value */ 1006 u32 control2_register; /* cached value */
882 u32 settings_register; 1007 u32 settings_register; /* cached value for AIO / RayDat (sync reference, master/slave) */
883 1008
884 struct hdspm_midi midi[4]; 1009 struct hdspm_midi midi[4];
885 struct tasklet_struct midi_tasklet; 1010 struct tasklet_struct midi_tasklet;
@@ -941,7 +1066,7 @@ struct hdspm {
941 1066
942 struct hdspm_tco *tco; /* NULL if no TCO detected */ 1067 struct hdspm_tco *tco; /* NULL if no TCO detected */
943 1068
944 char **texts_autosync; 1069 const char *const *texts_autosync;
945 int texts_autosync_items; 1070 int texts_autosync_items;
946 1071
947 cycles_t last_interrupt; 1072 cycles_t last_interrupt;
@@ -976,12 +1101,24 @@ static inline void snd_hdspm_initialize_midi_flush(struct hdspm *hdspm);
976static inline int hdspm_get_pll_freq(struct hdspm *hdspm); 1101static inline int hdspm_get_pll_freq(struct hdspm *hdspm);
977static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm); 1102static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm);
978static int hdspm_autosync_ref(struct hdspm *hdspm); 1103static int hdspm_autosync_ref(struct hdspm *hdspm);
1104static int hdspm_set_toggle_setting(struct hdspm *hdspm, u32 regmask, int out);
979static int snd_hdspm_set_defaults(struct hdspm *hdspm); 1105static int snd_hdspm_set_defaults(struct hdspm *hdspm);
980static int hdspm_system_clock_mode(struct hdspm *hdspm); 1106static int hdspm_system_clock_mode(struct hdspm *hdspm);
981static void hdspm_set_sgbuf(struct hdspm *hdspm, 1107static void hdspm_set_sgbuf(struct hdspm *hdspm,
982 struct snd_pcm_substream *substream, 1108 struct snd_pcm_substream *substream,
983 unsigned int reg, int channels); 1109 unsigned int reg, int channels);
984 1110
1111static int hdspm_aes_sync_check(struct hdspm *hdspm, int idx);
1112static int hdspm_wc_sync_check(struct hdspm *hdspm);
1113static int hdspm_tco_sync_check(struct hdspm *hdspm);
1114static int hdspm_sync_in_sync_check(struct hdspm *hdspm);
1115
1116static int hdspm_get_aes_sample_rate(struct hdspm *hdspm, int index);
1117static int hdspm_get_tco_sample_rate(struct hdspm *hdspm);
1118static int hdspm_get_wc_sample_rate(struct hdspm *hdspm);
1119
1120
1121
985static inline int HDSPM_bit2freq(int n) 1122static inline int HDSPM_bit2freq(int n)
986{ 1123{
987 static const int bit2freq_tab[] = { 1124 static const int bit2freq_tab[] = {
@@ -992,6 +1129,12 @@ static inline int HDSPM_bit2freq(int n)
992 return bit2freq_tab[n]; 1129 return bit2freq_tab[n];
993} 1130}
994 1131
1132static bool hdspm_is_raydat_or_aio(struct hdspm *hdspm)
1133{
1134 return ((AIO == hdspm->io_type) || (RayDAT == hdspm->io_type));
1135}
1136
1137
995/* Write/read to/from HDSPM with Adresses in Bytes 1138/* Write/read to/from HDSPM with Adresses in Bytes
996 not words but only 32Bit writes are allowed */ 1139 not words but only 32Bit writes are allowed */
997 1140
@@ -1107,14 +1250,11 @@ static int hdspm_rate_multiplier(struct hdspm *hdspm, int rate)
1107 else if (hdspm->control_register & 1250 else if (hdspm->control_register &
1108 HDSPM_DoubleSpeed) 1251 HDSPM_DoubleSpeed)
1109 return rate * 2; 1252 return rate * 2;
1110 }; 1253 }
1111 return rate; 1254 return rate;
1112} 1255}
1113 1256
1114static int hdspm_tco_sync_check(struct hdspm *hdspm); 1257/* check for external sample rate, returns the sample rate in Hz*/
1115static int hdspm_sync_in_sync_check(struct hdspm *hdspm);
1116
1117/* check for external sample rate */
1118static int hdspm_external_sample_rate(struct hdspm *hdspm) 1258static int hdspm_external_sample_rate(struct hdspm *hdspm)
1119{ 1259{
1120 unsigned int status, status2, timecode; 1260 unsigned int status, status2, timecode;
@@ -1127,17 +1267,36 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
1127 timecode = hdspm_read(hdspm, HDSPM_timecodeRegister); 1267 timecode = hdspm_read(hdspm, HDSPM_timecodeRegister);
1128 1268
1129 syncref = hdspm_autosync_ref(hdspm); 1269 syncref = hdspm_autosync_ref(hdspm);
1270 switch (syncref) {
1271 case HDSPM_AES32_AUTOSYNC_FROM_WORD:
1272 /* Check WC sync and get sample rate */
1273 if (hdspm_wc_sync_check(hdspm))
1274 return HDSPM_bit2freq(hdspm_get_wc_sample_rate(hdspm));
1275 break;
1130 1276
1131 if (syncref == HDSPM_AES32_AUTOSYNC_FROM_WORD && 1277 case HDSPM_AES32_AUTOSYNC_FROM_AES1:
1132 status & HDSPM_AES32_wcLock) 1278 case HDSPM_AES32_AUTOSYNC_FROM_AES2:
1133 return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF); 1279 case HDSPM_AES32_AUTOSYNC_FROM_AES3:
1280 case HDSPM_AES32_AUTOSYNC_FROM_AES4:
1281 case HDSPM_AES32_AUTOSYNC_FROM_AES5:
1282 case HDSPM_AES32_AUTOSYNC_FROM_AES6:
1283 case HDSPM_AES32_AUTOSYNC_FROM_AES7:
1284 case HDSPM_AES32_AUTOSYNC_FROM_AES8:
1285 /* Check AES sync and get sample rate */
1286 if (hdspm_aes_sync_check(hdspm, syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1))
1287 return HDSPM_bit2freq(hdspm_get_aes_sample_rate(hdspm,
1288 syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1));
1289 break;
1134 1290
1135 if (syncref >= HDSPM_AES32_AUTOSYNC_FROM_AES1 && 1291
1136 syncref <= HDSPM_AES32_AUTOSYNC_FROM_AES8 && 1292 case HDSPM_AES32_AUTOSYNC_FROM_TCO:
1137 status2 & (HDSPM_LockAES >> 1293 /* Check TCO sync and get sample rate */
1138 (syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1))) 1294 if (hdspm_tco_sync_check(hdspm))
1139 return HDSPM_bit2freq((timecode >> (4*(syncref-HDSPM_AES32_AUTOSYNC_FROM_AES1))) & 0xF); 1295 return HDSPM_bit2freq(hdspm_get_tco_sample_rate(hdspm));
1140 return 0; 1296 break;
1297 default:
1298 return 0;
1299 } /* end switch(syncref) */
1141 break; 1300 break;
1142 1301
1143 case MADIface: 1302 case MADIface:
@@ -2129,6 +2288,9 @@ static int hdspm_get_wc_sample_rate(struct hdspm *hdspm)
2129 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1); 2288 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
2130 return (status >> 16) & 0xF; 2289 return (status >> 16) & 0xF;
2131 break; 2290 break;
2291 case AES32:
2292 status = hdspm_read(hdspm, HDSPM_statusRegister);
2293 return (status >> HDSPM_AES32_wcFreq_bit) & 0xF;
2132 default: 2294 default:
2133 break; 2295 break;
2134 } 2296 }
@@ -2152,6 +2314,9 @@ static int hdspm_get_tco_sample_rate(struct hdspm *hdspm)
2152 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1); 2314 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
2153 return (status >> 20) & 0xF; 2315 return (status >> 20) & 0xF;
2154 break; 2316 break;
2317 case AES32:
2318 status = hdspm_read(hdspm, HDSPM_statusRegister);
2319 return (status >> 1) & 0xF;
2155 default: 2320 default:
2156 break; 2321 break;
2157 } 2322 }
@@ -2183,6 +2348,23 @@ static int hdspm_get_sync_in_sample_rate(struct hdspm *hdspm)
2183 return 0; 2348 return 0;
2184} 2349}
2185 2350
2351/**
2352 * Returns the AES sample rate class for the given card.
2353 **/
2354static int hdspm_get_aes_sample_rate(struct hdspm *hdspm, int index)
2355{
2356 int timecode;
2357
2358 switch (hdspm->io_type) {
2359 case AES32:
2360 timecode = hdspm_read(hdspm, HDSPM_timecodeRegister);
2361 return (timecode >> (4*index)) & 0xF;
2362 break;
2363 default:
2364 break;
2365 }
2366 return 0;
2367}
2186 2368
2187/** 2369/**
2188 * Returns the sample rate class for input source <idx> for 2370 * Returns the sample rate class for input source <idx> for
@@ -2196,15 +2378,23 @@ static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx)
2196} 2378}
2197 2379
2198#define ENUMERATED_CTL_INFO(info, texts) \ 2380#define ENUMERATED_CTL_INFO(info, texts) \
2199{ \ 2381 snd_ctl_enum_info(info, 1, ARRAY_SIZE(texts), texts)
2200 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; \ 2382
2201 uinfo->count = 1; \
2202 uinfo->value.enumerated.items = ARRAY_SIZE(texts); \
2203 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) \
2204 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; \
2205 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); \
2206}
2207 2383
2384/* Helper function to query the external sample rate and return the
2385 * corresponding enum to be returned to userspace.
2386 */
2387static int hdspm_external_rate_to_enum(struct hdspm *hdspm)
2388{
2389 int rate = hdspm_external_sample_rate(hdspm);
2390 int i, selected_rate = 0;
2391 for (i = 1; i < 10; i++)
2392 if (HDSPM_bit2freq(i) == rate) {
2393 selected_rate = i;
2394 break;
2395 }
2396 return selected_rate;
2397}
2208 2398
2209 2399
2210#define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ 2400#define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \
@@ -2270,7 +2460,7 @@ static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol,
2270 default: 2460 default:
2271 ucontrol->value.enumerated.item[0] = 2461 ucontrol->value.enumerated.item[0] =
2272 hdspm_get_s1_sample_rate(hdspm, 2462 hdspm_get_s1_sample_rate(hdspm,
2273 ucontrol->id.index-1); 2463 kcontrol->private_value-1);
2274 } 2464 }
2275 break; 2465 break;
2276 2466
@@ -2289,28 +2479,24 @@ static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol,
2289 ucontrol->value.enumerated.item[0] = 2479 ucontrol->value.enumerated.item[0] =
2290 hdspm_get_sync_in_sample_rate(hdspm); 2480 hdspm_get_sync_in_sample_rate(hdspm);
2291 break; 2481 break;
2482 case 11: /* External Rate */
2483 ucontrol->value.enumerated.item[0] =
2484 hdspm_external_rate_to_enum(hdspm);
2485 break;
2292 default: /* AES1 to AES8 */ 2486 default: /* AES1 to AES8 */
2293 ucontrol->value.enumerated.item[0] = 2487 ucontrol->value.enumerated.item[0] =
2294 hdspm_get_s1_sample_rate(hdspm, 2488 hdspm_get_aes_sample_rate(hdspm,
2295 kcontrol->private_value-1); 2489 kcontrol->private_value -
2490 HDSPM_AES32_AUTOSYNC_FROM_AES1);
2296 break; 2491 break;
2297 } 2492 }
2298 break; 2493 break;
2299 2494
2300 case MADI: 2495 case MADI:
2301 case MADIface: 2496 case MADIface:
2302 { 2497 ucontrol->value.enumerated.item[0] =
2303 int rate = hdspm_external_sample_rate(hdspm); 2498 hdspm_external_rate_to_enum(hdspm);
2304 int i, selected_rate = 0;
2305 for (i = 1; i < 10; i++)
2306 if (HDSPM_bit2freq(i) == rate) {
2307 selected_rate = i;
2308 break;
2309 }
2310 ucontrol->value.enumerated.item[0] = selected_rate;
2311 }
2312 break; 2499 break;
2313
2314 default: 2500 default:
2315 break; 2501 break;
2316 } 2502 }
@@ -2359,33 +2545,17 @@ static int hdspm_system_clock_mode(struct hdspm *hdspm)
2359 **/ 2545 **/
2360static void hdspm_set_system_clock_mode(struct hdspm *hdspm, int mode) 2546static void hdspm_set_system_clock_mode(struct hdspm *hdspm, int mode)
2361{ 2547{
2362 switch (hdspm->io_type) { 2548 hdspm_set_toggle_setting(hdspm,
2363 case AIO: 2549 (hdspm_is_raydat_or_aio(hdspm)) ?
2364 case RayDAT: 2550 HDSPM_c0Master : HDSPM_ClockModeMaster,
2365 if (0 == mode) 2551 (0 == mode));
2366 hdspm->settings_register |= HDSPM_c0Master;
2367 else
2368 hdspm->settings_register &= ~HDSPM_c0Master;
2369
2370 hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
2371 break;
2372
2373 default:
2374 if (0 == mode)
2375 hdspm->control_register |= HDSPM_ClockModeMaster;
2376 else
2377 hdspm->control_register &= ~HDSPM_ClockModeMaster;
2378
2379 hdspm_write(hdspm, HDSPM_controlRegister,
2380 hdspm->control_register);
2381 }
2382} 2552}
2383 2553
2384 2554
2385static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol, 2555static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol,
2386 struct snd_ctl_elem_info *uinfo) 2556 struct snd_ctl_elem_info *uinfo)
2387{ 2557{
2388 static char *texts[] = { "Master", "AutoSync" }; 2558 static const char *const texts[] = { "Master", "AutoSync" };
2389 ENUMERATED_CTL_INFO(uinfo, texts); 2559 ENUMERATED_CTL_INFO(uinfo, texts);
2390 return 0; 2560 return 0;
2391} 2561}
@@ -2809,16 +2979,7 @@ static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol,
2809{ 2979{
2810 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 2980 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2811 2981
2812 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2982 snd_ctl_enum_info(uinfo, 1, hdspm->texts_autosync_items, hdspm->texts_autosync);
2813 uinfo->count = 1;
2814 uinfo->value.enumerated.items = hdspm->texts_autosync_items;
2815
2816 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2817 uinfo->value.enumerated.item =
2818 uinfo->value.enumerated.items - 1;
2819
2820 strcpy(uinfo->value.enumerated.name,
2821 hdspm->texts_autosync[uinfo->value.enumerated.item]);
2822 2983
2823 return 0; 2984 return 0;
2824} 2985}
@@ -2873,19 +3034,20 @@ static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol,
2873 3034
2874static int hdspm_autosync_ref(struct hdspm *hdspm) 3035static int hdspm_autosync_ref(struct hdspm *hdspm)
2875{ 3036{
3037 /* This looks at the autosync selected sync reference */
2876 if (AES32 == hdspm->io_type) { 3038 if (AES32 == hdspm->io_type) {
3039
2877 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); 3040 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
2878 unsigned int syncref = 3041 unsigned int syncref = (status >> HDSPM_AES32_syncref_bit) & 0xF;
2879 (status >> HDSPM_AES32_syncref_bit) & 0xF; 3042 if ((syncref >= HDSPM_AES32_AUTOSYNC_FROM_WORD) &&
2880 if (syncref == 0) 3043 (syncref <= HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN)) {
2881 return HDSPM_AES32_AUTOSYNC_FROM_WORD;
2882 if (syncref <= 8)
2883 return syncref; 3044 return syncref;
3045 }
2884 return HDSPM_AES32_AUTOSYNC_FROM_NONE; 3046 return HDSPM_AES32_AUTOSYNC_FROM_NONE;
3047
2885 } else if (MADI == hdspm->io_type) { 3048 } else if (MADI == hdspm->io_type) {
2886 /* This looks at the autosync selected sync reference */
2887 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
2888 3049
3050 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
2889 switch (status2 & HDSPM_SelSyncRefMask) { 3051 switch (status2 & HDSPM_SelSyncRefMask) {
2890 case HDSPM_SelSyncRef_WORD: 3052 case HDSPM_SelSyncRef_WORD:
2891 return HDSPM_AUTOSYNC_FROM_WORD; 3053 return HDSPM_AUTOSYNC_FROM_WORD;
@@ -2898,7 +3060,7 @@ static int hdspm_autosync_ref(struct hdspm *hdspm)
2898 case HDSPM_SelSyncRef_NVALID: 3060 case HDSPM_SelSyncRef_NVALID:
2899 return HDSPM_AUTOSYNC_FROM_NONE; 3061 return HDSPM_AUTOSYNC_FROM_NONE;
2900 default: 3062 default:
2901 return 0; 3063 return HDSPM_AUTOSYNC_FROM_NONE;
2902 } 3064 }
2903 3065
2904 } 3066 }
@@ -2912,31 +3074,15 @@ static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol,
2912 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 3074 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2913 3075
2914 if (AES32 == hdspm->io_type) { 3076 if (AES32 == hdspm->io_type) {
2915 static char *texts[] = { "WordClock", "AES1", "AES2", "AES3", 3077 static const char *const texts[] = { "WordClock", "AES1", "AES2", "AES3",
2916 "AES4", "AES5", "AES6", "AES7", "AES8", "None"}; 3078 "AES4", "AES5", "AES6", "AES7", "AES8", "TCO", "Sync In", "None"};
2917 3079
2918 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3080 ENUMERATED_CTL_INFO(uinfo, texts);
2919 uinfo->count = 1;
2920 uinfo->value.enumerated.items = 10;
2921 if (uinfo->value.enumerated.item >=
2922 uinfo->value.enumerated.items)
2923 uinfo->value.enumerated.item =
2924 uinfo->value.enumerated.items - 1;
2925 strcpy(uinfo->value.enumerated.name,
2926 texts[uinfo->value.enumerated.item]);
2927 } else if (MADI == hdspm->io_type) { 3081 } else if (MADI == hdspm->io_type) {
2928 static char *texts[] = {"Word Clock", "MADI", "TCO", 3082 static const char *const texts[] = {"Word Clock", "MADI", "TCO",
2929 "Sync In", "None" }; 3083 "Sync In", "None" };
2930 3084
2931 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3085 ENUMERATED_CTL_INFO(uinfo, texts);
2932 uinfo->count = 1;
2933 uinfo->value.enumerated.items = 5;
2934 if (uinfo->value.enumerated.item >=
2935 uinfo->value.enumerated.items)
2936 uinfo->value.enumerated.item =
2937 uinfo->value.enumerated.items - 1;
2938 strcpy(uinfo->value.enumerated.name,
2939 texts[uinfo->value.enumerated.item]);
2940 } 3086 }
2941 return 0; 3087 return 0;
2942} 3088}
@@ -2964,7 +3110,7 @@ static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol,
2964static int snd_hdspm_info_tco_video_input_format(struct snd_kcontrol *kcontrol, 3110static int snd_hdspm_info_tco_video_input_format(struct snd_kcontrol *kcontrol,
2965 struct snd_ctl_elem_info *uinfo) 3111 struct snd_ctl_elem_info *uinfo)
2966{ 3112{
2967 static char *texts[] = {"No video", "NTSC", "PAL"}; 3113 static const char *const texts[] = {"No video", "NTSC", "PAL"};
2968 ENUMERATED_CTL_INFO(uinfo, texts); 3114 ENUMERATED_CTL_INFO(uinfo, texts);
2969 return 0; 3115 return 0;
2970} 3116}
@@ -3010,7 +3156,7 @@ static int snd_hdspm_get_tco_video_input_format(struct snd_kcontrol *kcontrol,
3010static int snd_hdspm_info_tco_ltc_frames(struct snd_kcontrol *kcontrol, 3156static int snd_hdspm_info_tco_ltc_frames(struct snd_kcontrol *kcontrol,
3011 struct snd_ctl_elem_info *uinfo) 3157 struct snd_ctl_elem_info *uinfo)
3012{ 3158{
3013 static char *texts[] = {"No lock", "24 fps", "25 fps", "29.97 fps", 3159 static const char *const texts[] = {"No lock", "24 fps", "25 fps", "29.97 fps",
3014 "30 fps"}; 3160 "30 fps"};
3015 ENUMERATED_CTL_INFO(uinfo, texts); 3161 ENUMERATED_CTL_INFO(uinfo, texts);
3016 return 0; 3162 return 0;
@@ -3027,19 +3173,19 @@ static int hdspm_tco_ltc_frames(struct hdspm *hdspm)
3027 HDSPM_TCO1_LTC_Format_MSB)) { 3173 HDSPM_TCO1_LTC_Format_MSB)) {
3028 case 0: 3174 case 0:
3029 /* 24 fps */ 3175 /* 24 fps */
3030 ret = 1; 3176 ret = fps_24;
3031 break; 3177 break;
3032 case HDSPM_TCO1_LTC_Format_LSB: 3178 case HDSPM_TCO1_LTC_Format_LSB:
3033 /* 25 fps */ 3179 /* 25 fps */
3034 ret = 2; 3180 ret = fps_25;
3035 break; 3181 break;
3036 case HDSPM_TCO1_LTC_Format_MSB: 3182 case HDSPM_TCO1_LTC_Format_MSB:
3037 /* 25 fps */ 3183 /* 29.97 fps */
3038 ret = 3; 3184 ret = fps_2997;
3039 break; 3185 break;
3040 default: 3186 default:
3041 /* 30 fps */ 3187 /* 30 fps */
3042 ret = 4; 3188 ret = fps_30;
3043 break; 3189 break;
3044 } 3190 }
3045 } 3191 }
@@ -3067,16 +3213,35 @@ static int snd_hdspm_get_tco_ltc_frames(struct snd_kcontrol *kcontrol,
3067 3213
3068static int hdspm_toggle_setting(struct hdspm *hdspm, u32 regmask) 3214static int hdspm_toggle_setting(struct hdspm *hdspm, u32 regmask)
3069{ 3215{
3070 return (hdspm->control_register & regmask) ? 1 : 0; 3216 u32 reg;
3217
3218 if (hdspm_is_raydat_or_aio(hdspm))
3219 reg = hdspm->settings_register;
3220 else
3221 reg = hdspm->control_register;
3222
3223 return (reg & regmask) ? 1 : 0;
3071} 3224}
3072 3225
3073static int hdspm_set_toggle_setting(struct hdspm *hdspm, u32 regmask, int out) 3226static int hdspm_set_toggle_setting(struct hdspm *hdspm, u32 regmask, int out)
3074{ 3227{
3228 u32 *reg;
3229 u32 target_reg;
3230
3231 if (hdspm_is_raydat_or_aio(hdspm)) {
3232 reg = &(hdspm->settings_register);
3233 target_reg = HDSPM_WR_SETTINGS;
3234 } else {
3235 reg = &(hdspm->control_register);
3236 target_reg = HDSPM_controlRegister;
3237 }
3238
3075 if (out) 3239 if (out)
3076 hdspm->control_register |= regmask; 3240 *reg |= regmask;
3077 else 3241 else
3078 hdspm->control_register &= ~regmask; 3242 *reg &= ~regmask;
3079 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); 3243
3244 hdspm_write(hdspm, target_reg, *reg);
3080 3245
3081 return 0; 3246 return 0;
3082} 3247}
@@ -3141,7 +3306,7 @@ static int hdspm_set_input_select(struct hdspm * hdspm, int out)
3141static int snd_hdspm_info_input_select(struct snd_kcontrol *kcontrol, 3306static int snd_hdspm_info_input_select(struct snd_kcontrol *kcontrol,
3142 struct snd_ctl_elem_info *uinfo) 3307 struct snd_ctl_elem_info *uinfo)
3143{ 3308{
3144 static char *texts[] = { "optical", "coaxial" }; 3309 static const char *const texts[] = { "optical", "coaxial" };
3145 ENUMERATED_CTL_INFO(uinfo, texts); 3310 ENUMERATED_CTL_INFO(uinfo, texts);
3146 return 0; 3311 return 0;
3147} 3312}
@@ -3203,7 +3368,7 @@ static int hdspm_set_ds_wire(struct hdspm * hdspm, int ds)
3203static int snd_hdspm_info_ds_wire(struct snd_kcontrol *kcontrol, 3368static int snd_hdspm_info_ds_wire(struct snd_kcontrol *kcontrol,
3204 struct snd_ctl_elem_info *uinfo) 3369 struct snd_ctl_elem_info *uinfo)
3205{ 3370{
3206 static char *texts[] = { "Single", "Double" }; 3371 static const char *const texts[] = { "Single", "Double" };
3207 ENUMERATED_CTL_INFO(uinfo, texts); 3372 ENUMERATED_CTL_INFO(uinfo, texts);
3208 return 0; 3373 return 0;
3209} 3374}
@@ -3276,7 +3441,7 @@ static int hdspm_set_qs_wire(struct hdspm * hdspm, int mode)
3276static int snd_hdspm_info_qs_wire(struct snd_kcontrol *kcontrol, 3441static int snd_hdspm_info_qs_wire(struct snd_kcontrol *kcontrol,
3277 struct snd_ctl_elem_info *uinfo) 3442 struct snd_ctl_elem_info *uinfo)
3278{ 3443{
3279 static char *texts[] = { "Single", "Double", "Quad" }; 3444 static const char *const texts[] = { "Single", "Double", "Quad" };
3280 ENUMERATED_CTL_INFO(uinfo, texts); 3445 ENUMERATED_CTL_INFO(uinfo, texts);
3281 return 0; 3446 return 0;
3282} 3447}
@@ -3313,6 +3478,84 @@ static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol,
3313 return change; 3478 return change;
3314} 3479}
3315 3480
3481#define HDSPM_CONTROL_TRISTATE(xname, xindex) \
3482{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3483 .name = xname, \
3484 .private_value = xindex, \
3485 .info = snd_hdspm_info_tristate, \
3486 .get = snd_hdspm_get_tristate, \
3487 .put = snd_hdspm_put_tristate \
3488}
3489
3490static int hdspm_tristate(struct hdspm *hdspm, u32 regmask)
3491{
3492 u32 reg = hdspm->settings_register & (regmask * 3);
3493 return reg / regmask;
3494}
3495
3496static int hdspm_set_tristate(struct hdspm *hdspm, int mode, u32 regmask)
3497{
3498 hdspm->settings_register &= ~(regmask * 3);
3499 hdspm->settings_register |= (regmask * mode);
3500 hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
3501
3502 return 0;
3503}
3504
3505static int snd_hdspm_info_tristate(struct snd_kcontrol *kcontrol,
3506 struct snd_ctl_elem_info *uinfo)
3507{
3508 u32 regmask = kcontrol->private_value;
3509
3510 static const char *const texts_spdif[] = { "Optical", "Coaxial", "Internal" };
3511 static const char *const texts_levels[] = { "Hi Gain", "+4 dBu", "-10 dBV" };
3512
3513 switch (regmask) {
3514 case HDSPM_c0_Input0:
3515 ENUMERATED_CTL_INFO(uinfo, texts_spdif);
3516 break;
3517 default:
3518 ENUMERATED_CTL_INFO(uinfo, texts_levels);
3519 break;
3520 }
3521 return 0;
3522}
3523
3524static int snd_hdspm_get_tristate(struct snd_kcontrol *kcontrol,
3525 struct snd_ctl_elem_value *ucontrol)
3526{
3527 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
3528 u32 regmask = kcontrol->private_value;
3529
3530 spin_lock_irq(&hdspm->lock);
3531 ucontrol->value.enumerated.item[0] = hdspm_tristate(hdspm, regmask);
3532 spin_unlock_irq(&hdspm->lock);
3533 return 0;
3534}
3535
3536static int snd_hdspm_put_tristate(struct snd_kcontrol *kcontrol,
3537 struct snd_ctl_elem_value *ucontrol)
3538{
3539 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
3540 u32 regmask = kcontrol->private_value;
3541 int change;
3542 int val;
3543
3544 if (!snd_hdspm_use_is_exclusive(hdspm))
3545 return -EBUSY;
3546 val = ucontrol->value.integer.value[0];
3547 if (val < 0)
3548 val = 0;
3549 if (val > 2)
3550 val = 2;
3551
3552 spin_lock_irq(&hdspm->lock);
3553 change = val != hdspm_tristate(hdspm, regmask);
3554 hdspm_set_tristate(hdspm, val, regmask);
3555 spin_unlock_irq(&hdspm->lock);
3556 return change;
3557}
3558
3316#define HDSPM_MADI_SPEEDMODE(xname, xindex) \ 3559#define HDSPM_MADI_SPEEDMODE(xname, xindex) \
3317{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3560{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3318 .name = xname, \ 3561 .name = xname, \
@@ -3352,7 +3595,7 @@ static int hdspm_set_madi_speedmode(struct hdspm *hdspm, int mode)
3352static int snd_hdspm_info_madi_speedmode(struct snd_kcontrol *kcontrol, 3595static int snd_hdspm_info_madi_speedmode(struct snd_kcontrol *kcontrol,
3353 struct snd_ctl_elem_info *uinfo) 3596 struct snd_ctl_elem_info *uinfo)
3354{ 3597{
3355 static char *texts[] = { "Single", "Double", "Quad" }; 3598 static const char *const texts[] = { "Single", "Double", "Quad" };
3356 ENUMERATED_CTL_INFO(uinfo, texts); 3599 ENUMERATED_CTL_INFO(uinfo, texts);
3357 return 0; 3600 return 0;
3358} 3601}
@@ -3587,7 +3830,7 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol,
3587static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol, 3830static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol,
3588 struct snd_ctl_elem_info *uinfo) 3831 struct snd_ctl_elem_info *uinfo)
3589{ 3832{
3590 static char *texts[] = { "No Lock", "Lock", "Sync", "N/A" }; 3833 static const char *const texts[] = { "No Lock", "Lock", "Sync", "N/A" };
3591 ENUMERATED_CTL_INFO(uinfo, texts); 3834 ENUMERATED_CTL_INFO(uinfo, texts);
3592 return 0; 3835 return 0;
3593} 3836}
@@ -3595,7 +3838,7 @@ static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol,
3595static int snd_hdspm_tco_info_lock_check(struct snd_kcontrol *kcontrol, 3838static int snd_hdspm_tco_info_lock_check(struct snd_kcontrol *kcontrol,
3596 struct snd_ctl_elem_info *uinfo) 3839 struct snd_ctl_elem_info *uinfo)
3597{ 3840{
3598 static char *texts[] = { "No Lock", "Lock" }; 3841 static const char *const texts[] = { "No Lock", "Lock" };
3599 ENUMERATED_CTL_INFO(uinfo, texts); 3842 ENUMERATED_CTL_INFO(uinfo, texts);
3600 return 0; 3843 return 0;
3601} 3844}
@@ -3745,9 +3988,18 @@ static int hdspm_tco_sync_check(struct hdspm *hdspm)
3745 if (hdspm->tco) { 3988 if (hdspm->tco) {
3746 switch (hdspm->io_type) { 3989 switch (hdspm->io_type) {
3747 case MADI: 3990 case MADI:
3991 status = hdspm_read(hdspm, HDSPM_statusRegister);
3992 if (status & HDSPM_tcoLockMadi) {
3993 if (status & HDSPM_tcoSync)
3994 return 2;
3995 else
3996 return 1;
3997 }
3998 return 0;
3999 break;
3748 case AES32: 4000 case AES32:
3749 status = hdspm_read(hdspm, HDSPM_statusRegister); 4001 status = hdspm_read(hdspm, HDSPM_statusRegister);
3750 if (status & HDSPM_tcoLock) { 4002 if (status & HDSPM_tcoLockAes) {
3751 if (status & HDSPM_tcoSync) 4003 if (status & HDSPM_tcoSync)
3752 return 2; 4004 return 2;
3753 else 4005 else
@@ -3807,7 +4059,8 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol,
3807 case 5: /* SYNC IN */ 4059 case 5: /* SYNC IN */
3808 val = hdspm_sync_in_sync_check(hdspm); break; 4060 val = hdspm_sync_in_sync_check(hdspm); break;
3809 default: 4061 default:
3810 val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1); 4062 val = hdspm_s1_sync_check(hdspm,
4063 kcontrol->private_value-1);
3811 } 4064 }
3812 break; 4065 break;
3813 4066
@@ -3975,7 +4228,8 @@ static void hdspm_tco_write(struct hdspm *hdspm)
3975static int snd_hdspm_info_tco_sample_rate(struct snd_kcontrol *kcontrol, 4228static int snd_hdspm_info_tco_sample_rate(struct snd_kcontrol *kcontrol,
3976 struct snd_ctl_elem_info *uinfo) 4229 struct snd_ctl_elem_info *uinfo)
3977{ 4230{
3978 static char *texts[] = { "44.1 kHz", "48 kHz" }; 4231 /* TODO freq from app could be supported here, see tco->samplerate */
4232 static const char *const texts[] = { "44.1 kHz", "48 kHz" };
3979 ENUMERATED_CTL_INFO(uinfo, texts); 4233 ENUMERATED_CTL_INFO(uinfo, texts);
3980 return 0; 4234 return 0;
3981} 4235}
@@ -4021,7 +4275,8 @@ static int snd_hdspm_put_tco_sample_rate(struct snd_kcontrol *kcontrol,
4021static int snd_hdspm_info_tco_pull(struct snd_kcontrol *kcontrol, 4275static int snd_hdspm_info_tco_pull(struct snd_kcontrol *kcontrol,
4022 struct snd_ctl_elem_info *uinfo) 4276 struct snd_ctl_elem_info *uinfo)
4023{ 4277{
4024 static char *texts[] = { "0", "+ 0.1 %", "- 0.1 %", "+ 4 %", "- 4 %" }; 4278 static const char *const texts[] = { "0", "+ 0.1 %", "- 0.1 %",
4279 "+ 4 %", "- 4 %" };
4025 ENUMERATED_CTL_INFO(uinfo, texts); 4280 ENUMERATED_CTL_INFO(uinfo, texts);
4026 return 0; 4281 return 0;
4027} 4282}
@@ -4066,7 +4321,7 @@ static int snd_hdspm_put_tco_pull(struct snd_kcontrol *kcontrol,
4066static int snd_hdspm_info_tco_wck_conversion(struct snd_kcontrol *kcontrol, 4321static int snd_hdspm_info_tco_wck_conversion(struct snd_kcontrol *kcontrol,
4067 struct snd_ctl_elem_info *uinfo) 4322 struct snd_ctl_elem_info *uinfo)
4068{ 4323{
4069 static char *texts[] = { "1:1", "44.1 -> 48", "48 -> 44.1" }; 4324 static const char *const texts[] = { "1:1", "44.1 -> 48", "48 -> 44.1" };
4070 ENUMERATED_CTL_INFO(uinfo, texts); 4325 ENUMERATED_CTL_INFO(uinfo, texts);
4071 return 0; 4326 return 0;
4072} 4327}
@@ -4112,7 +4367,7 @@ static int snd_hdspm_put_tco_wck_conversion(struct snd_kcontrol *kcontrol,
4112static int snd_hdspm_info_tco_frame_rate(struct snd_kcontrol *kcontrol, 4367static int snd_hdspm_info_tco_frame_rate(struct snd_kcontrol *kcontrol,
4113 struct snd_ctl_elem_info *uinfo) 4368 struct snd_ctl_elem_info *uinfo)
4114{ 4369{
4115 static char *texts[] = { "24 fps", "25 fps", "29.97fps", 4370 static const char *const texts[] = { "24 fps", "25 fps", "29.97fps",
4116 "29.97 dfps", "30 fps", "30 dfps" }; 4371 "29.97 dfps", "30 fps", "30 dfps" };
4117 ENUMERATED_CTL_INFO(uinfo, texts); 4372 ENUMERATED_CTL_INFO(uinfo, texts);
4118 return 0; 4373 return 0;
@@ -4159,7 +4414,7 @@ static int snd_hdspm_put_tco_frame_rate(struct snd_kcontrol *kcontrol,
4159static int snd_hdspm_info_tco_sync_source(struct snd_kcontrol *kcontrol, 4414static int snd_hdspm_info_tco_sync_source(struct snd_kcontrol *kcontrol,
4160 struct snd_ctl_elem_info *uinfo) 4415 struct snd_ctl_elem_info *uinfo)
4161{ 4416{
4162 static char *texts[] = { "LTC", "Video", "WCK" }; 4417 static const char *const texts[] = { "LTC", "Video", "WCK" };
4163 ENUMERATED_CTL_INFO(uinfo, texts); 4418 ENUMERATED_CTL_INFO(uinfo, texts);
4164 return 0; 4419 return 0;
4165} 4420}
@@ -4284,7 +4539,6 @@ static struct snd_kcontrol_new snd_hdspm_controls_aio[] = {
4284 HDSPM_INTERNAL_CLOCK("Internal Clock", 0), 4539 HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
4285 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), 4540 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
4286 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), 4541 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
4287 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
4288 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), 4542 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
4289 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), 4543 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
4290 HDSPM_SYNC_CHECK("WC SyncCheck", 0), 4544 HDSPM_SYNC_CHECK("WC SyncCheck", 0),
@@ -4298,7 +4552,16 @@ static struct snd_kcontrol_new snd_hdspm_controls_aio[] = {
4298 HDSPM_AUTOSYNC_SAMPLE_RATE("SPDIF Frequency", 2), 4552 HDSPM_AUTOSYNC_SAMPLE_RATE("SPDIF Frequency", 2),
4299 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT Frequency", 3), 4553 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT Frequency", 3),
4300 HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 4), 4554 HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 4),
4301 HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 5) 4555 HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 5),
4556 HDSPM_CONTROL_TRISTATE("S/PDIF Input", HDSPM_c0_Input0),
4557 HDSPM_TOGGLE_SETTING("S/PDIF Out Optical", HDSPM_c0_Spdif_Opt),
4558 HDSPM_TOGGLE_SETTING("S/PDIF Out Professional", HDSPM_c0_Pro),
4559 HDSPM_TOGGLE_SETTING("ADAT internal (AEB/TEB)", HDSPM_c0_AEB1),
4560 HDSPM_TOGGLE_SETTING("XLR Breakout Cable", HDSPM_c0_Sym6db),
4561 HDSPM_TOGGLE_SETTING("Single Speed WordClock Out", HDSPM_c0_Wck48),
4562 HDSPM_CONTROL_TRISTATE("Input Level", HDSPM_c0_AD_GAIN0),
4563 HDSPM_CONTROL_TRISTATE("Output Level", HDSPM_c0_DA_GAIN0),
4564 HDSPM_CONTROL_TRISTATE("Phones Level", HDSPM_c0_PH_GAIN0)
4302 4565
4303 /* 4566 /*
4304 HDSPM_INPUT_SELECT("Input Select", 0), 4567 HDSPM_INPUT_SELECT("Input Select", 0),
@@ -4335,7 +4598,9 @@ static struct snd_kcontrol_new snd_hdspm_controls_raydat[] = {
4335 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT3 Frequency", 5), 4598 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT3 Frequency", 5),
4336 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT4 Frequency", 6), 4599 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT4 Frequency", 6),
4337 HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 7), 4600 HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 7),
4338 HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 8) 4601 HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 8),
4602 HDSPM_TOGGLE_SETTING("S/PDIF Out Professional", HDSPM_c0_Pro),
4603 HDSPM_TOGGLE_SETTING("Single Speed WordClock Out", HDSPM_c0_Wck48)
4339}; 4604};
4340 4605
4341static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = { 4606static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = {
@@ -4345,7 +4610,7 @@ static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = {
4345 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), 4610 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
4346 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0), 4611 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
4347 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), 4612 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
4348 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), 4613 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 11),
4349 HDSPM_SYNC_CHECK("WC Sync Check", 0), 4614 HDSPM_SYNC_CHECK("WC Sync Check", 0),
4350 HDSPM_SYNC_CHECK("AES1 Sync Check", 1), 4615 HDSPM_SYNC_CHECK("AES1 Sync Check", 1),
4351 HDSPM_SYNC_CHECK("AES2 Sync Check", 2), 4616 HDSPM_SYNC_CHECK("AES2 Sync Check", 2),
@@ -4501,77 +4766,22 @@ static int snd_hdspm_create_controls(struct snd_card *card,
4501 ------------------------------------------------------------*/ 4766 ------------------------------------------------------------*/
4502 4767
4503static void 4768static void
4504snd_hdspm_proc_read_madi(struct snd_info_entry * entry, 4769snd_hdspm_proc_read_tco(struct snd_info_entry *entry,
4505 struct snd_info_buffer *buffer) 4770 struct snd_info_buffer *buffer)
4506{ 4771{
4507 struct hdspm *hdspm = entry->private_data; 4772 struct hdspm *hdspm = entry->private_data;
4508 unsigned int status, status2, control, freq; 4773 unsigned int status, control;
4509
4510 char *pref_sync_ref;
4511 char *autosync_ref;
4512 char *system_clock_mode;
4513 char *insel;
4514 int x, x2;
4515
4516 /* TCO stuff */
4517 int a, ltc, frames, seconds, minutes, hours; 4774 int a, ltc, frames, seconds, minutes, hours;
4518 unsigned int period; 4775 unsigned int period;
4519 u64 freq_const = 0; 4776 u64 freq_const = 0;
4520 u32 rate; 4777 u32 rate;
4521 4778
4779 snd_iprintf(buffer, "--- TCO ---\n");
4780
4522 status = hdspm_read(hdspm, HDSPM_statusRegister); 4781 status = hdspm_read(hdspm, HDSPM_statusRegister);
4523 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
4524 control = hdspm->control_register; 4782 control = hdspm->control_register;
4525 freq = hdspm_read(hdspm, HDSPM_timecodeRegister);
4526 4783
4527 snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n",
4528 hdspm->card_name, hdspm->card->number + 1,
4529 hdspm->firmware_rev,
4530 (status2 & HDSPM_version0) |
4531 (status2 & HDSPM_version1) | (status2 &
4532 HDSPM_version2));
4533 4784
4534 snd_iprintf(buffer, "HW Serial: 0x%06x%06x\n",
4535 (hdspm_read(hdspm, HDSPM_midiStatusIn1)>>8) & 0xFFFFFF,
4536 hdspm->serial);
4537
4538 snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
4539 hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase);
4540
4541 snd_iprintf(buffer, "--- System ---\n");
4542
4543 snd_iprintf(buffer,
4544 "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n",
4545 status & HDSPM_audioIRQPending,
4546 (status & HDSPM_midi0IRQPending) ? 1 : 0,
4547 (status & HDSPM_midi1IRQPending) ? 1 : 0,
4548 hdspm->irq_count);
4549 snd_iprintf(buffer,
4550 "HW pointer: id = %d, rawptr = %d (%d->%d) "
4551 "estimated= %ld (bytes)\n",
4552 ((status & HDSPM_BufferID) ? 1 : 0),
4553 (status & HDSPM_BufferPositionMask),
4554 (status & HDSPM_BufferPositionMask) %
4555 (2 * (int)hdspm->period_bytes),
4556 ((status & HDSPM_BufferPositionMask) - 64) %
4557 (2 * (int)hdspm->period_bytes),
4558 (long) hdspm_hw_pointer(hdspm) * 4);
4559
4560 snd_iprintf(buffer,
4561 "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n",
4562 hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF,
4563 hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF,
4564 hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
4565 hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
4566 snd_iprintf(buffer,
4567 "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n",
4568 hdspm_read(hdspm, HDSPM_midiStatusIn2) & 0xFF,
4569 hdspm_read(hdspm, HDSPM_midiStatusOut2) & 0xFF);
4570 snd_iprintf(buffer,
4571 "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, "
4572 "status2=0x%x\n",
4573 hdspm->control_register, hdspm->control2_register,
4574 status, status2);
4575 if (status & HDSPM_tco_detect) { 4785 if (status & HDSPM_tco_detect) {
4576 snd_iprintf(buffer, "TCO module detected.\n"); 4786 snd_iprintf(buffer, "TCO module detected.\n");
4577 a = hdspm_read(hdspm, HDSPM_RD_TCO+4); 4787 a = hdspm_read(hdspm, HDSPM_RD_TCO+4);
@@ -4665,6 +4875,75 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
4665 } else { 4875 } else {
4666 snd_iprintf(buffer, "No TCO module detected.\n"); 4876 snd_iprintf(buffer, "No TCO module detected.\n");
4667 } 4877 }
4878}
4879
4880static void
4881snd_hdspm_proc_read_madi(struct snd_info_entry *entry,
4882 struct snd_info_buffer *buffer)
4883{
4884 struct hdspm *hdspm = entry->private_data;
4885 unsigned int status, status2, control, freq;
4886
4887 char *pref_sync_ref;
4888 char *autosync_ref;
4889 char *system_clock_mode;
4890 char *insel;
4891 int x, x2;
4892
4893 status = hdspm_read(hdspm, HDSPM_statusRegister);
4894 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
4895 control = hdspm->control_register;
4896 freq = hdspm_read(hdspm, HDSPM_timecodeRegister);
4897
4898 snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n",
4899 hdspm->card_name, hdspm->card->number + 1,
4900 hdspm->firmware_rev,
4901 (status2 & HDSPM_version0) |
4902 (status2 & HDSPM_version1) | (status2 &
4903 HDSPM_version2));
4904
4905 snd_iprintf(buffer, "HW Serial: 0x%06x%06x\n",
4906 (hdspm_read(hdspm, HDSPM_midiStatusIn1)>>8) & 0xFFFFFF,
4907 hdspm->serial);
4908
4909 snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
4910 hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase);
4911
4912 snd_iprintf(buffer, "--- System ---\n");
4913
4914 snd_iprintf(buffer,
4915 "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n",
4916 status & HDSPM_audioIRQPending,
4917 (status & HDSPM_midi0IRQPending) ? 1 : 0,
4918 (status & HDSPM_midi1IRQPending) ? 1 : 0,
4919 hdspm->irq_count);
4920 snd_iprintf(buffer,
4921 "HW pointer: id = %d, rawptr = %d (%d->%d) "
4922 "estimated= %ld (bytes)\n",
4923 ((status & HDSPM_BufferID) ? 1 : 0),
4924 (status & HDSPM_BufferPositionMask),
4925 (status & HDSPM_BufferPositionMask) %
4926 (2 * (int)hdspm->period_bytes),
4927 ((status & HDSPM_BufferPositionMask) - 64) %
4928 (2 * (int)hdspm->period_bytes),
4929 (long) hdspm_hw_pointer(hdspm) * 4);
4930
4931 snd_iprintf(buffer,
4932 "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n",
4933 hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF,
4934 hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF,
4935 hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
4936 hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
4937 snd_iprintf(buffer,
4938 "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n",
4939 hdspm_read(hdspm, HDSPM_midiStatusIn2) & 0xFF,
4940 hdspm_read(hdspm, HDSPM_midiStatusOut2) & 0xFF);
4941 snd_iprintf(buffer,
4942 "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, "
4943 "status2=0x%x\n",
4944 hdspm->control_register, hdspm->control2_register,
4945 status, status2);
4946
4668 4947
4669 snd_iprintf(buffer, "--- Settings ---\n"); 4948 snd_iprintf(buffer, "--- Settings ---\n");
4670 4949
@@ -4768,6 +5047,9 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
4768 (status & HDSPM_RX_64ch) ? "64 channels" : 5047 (status & HDSPM_RX_64ch) ? "64 channels" :
4769 "56 channels"); 5048 "56 channels");
4770 5049
5050 /* call readout function for TCO specific status */
5051 snd_hdspm_proc_read_tco(entry, buffer);
5052
4771 snd_iprintf(buffer, "\n"); 5053 snd_iprintf(buffer, "\n");
4772} 5054}
4773 5055
@@ -4909,11 +5191,18 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
4909 autosync_ref = "AES7"; break; 5191 autosync_ref = "AES7"; break;
4910 case HDSPM_AES32_AUTOSYNC_FROM_AES8: 5192 case HDSPM_AES32_AUTOSYNC_FROM_AES8:
4911 autosync_ref = "AES8"; break; 5193 autosync_ref = "AES8"; break;
5194 case HDSPM_AES32_AUTOSYNC_FROM_TCO:
5195 autosync_ref = "TCO"; break;
5196 case HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN:
5197 autosync_ref = "Sync In"; break;
4912 default: 5198 default:
4913 autosync_ref = "---"; break; 5199 autosync_ref = "---"; break;
4914 } 5200 }
4915 snd_iprintf(buffer, "AutoSync ref = %s\n", autosync_ref); 5201 snd_iprintf(buffer, "AutoSync ref = %s\n", autosync_ref);
4916 5202
5203 /* call readout function for TCO specific status */
5204 snd_hdspm_proc_read_tco(entry, buffer);
5205
4917 snd_iprintf(buffer, "\n"); 5206 snd_iprintf(buffer, "\n");
4918} 5207}
4919 5208
@@ -5097,7 +5386,7 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm)
5097 5386
5098 case AES32: 5387 case AES32:
5099 hdspm->control_register = 5388 hdspm->control_register =
5100 HDSPM_ClockModeMaster | /* Master Cloack Mode on */ 5389 HDSPM_ClockModeMaster | /* Master Clock Mode on */
5101 hdspm_encode_latency(7) | /* latency max=8192samples */ 5390 hdspm_encode_latency(7) | /* latency max=8192samples */
5102 HDSPM_SyncRef0 | /* AES1 is syncclock */ 5391 HDSPM_SyncRef0 | /* AES1 is syncclock */
5103 HDSPM_LineOut | /* Analog output in */ 5392 HDSPM_LineOut | /* Analog output in */
@@ -5123,9 +5412,8 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm)
5123 5412
5124 all_in_all_mixer(hdspm, 0 * UNITY_GAIN); 5413 all_in_all_mixer(hdspm, 0 * UNITY_GAIN);
5125 5414
5126 if (hdspm->io_type == AIO || hdspm->io_type == RayDAT) { 5415 if (hdspm_is_raydat_or_aio(hdspm))
5127 hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register); 5416 hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
5128 }
5129 5417
5130 /* set a default rate so that the channel map is set up. */ 5418 /* set a default rate so that the channel map is set up. */
5131 hdspm_set_rate(hdspm, 48000, 1); 5419 hdspm_set_rate(hdspm, 48000, 1);
@@ -5371,6 +5659,16 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
5371 */ 5659 */
5372 5660
5373 5661
5662 /* For AES cards, the float format bit is the same as the
5663 * preferred sync reference. Since we don't want to break
5664 * sync settings, we have to skip the remaining part of this
5665 * function.
5666 */
5667 if (hdspm->io_type == AES32) {
5668 return 0;
5669 }
5670
5671
5374 /* Switch to native float format if requested */ 5672 /* Switch to native float format if requested */
5375 if (SNDRV_PCM_FORMAT_FLOAT_LE == params_format(params)) { 5673 if (SNDRV_PCM_FORMAT_FLOAT_LE == params_format(params)) {
5376 if (!(hdspm->control_register & HDSPe_FLOAT_FORMAT)) 5674 if (!(hdspm->control_register & HDSPe_FLOAT_FORMAT))
@@ -6013,7 +6311,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
6013 ltc.format = fps_2997; 6311 ltc.format = fps_2997;
6014 break; 6312 break;
6015 default: 6313 default:
6016 ltc.format = 30; 6314 ltc.format = fps_30;
6017 break; 6315 break;
6018 } 6316 }
6019 if (i & HDSPM_TCO1_set_drop_frame_flag) { 6317 if (i & HDSPM_TCO1_set_drop_frame_flag) {
@@ -6479,10 +6777,6 @@ static int snd_hdspm_create(struct snd_card *card,
6479 break; 6777 break;
6480 6778
6481 case AIO: 6779 case AIO:
6482 if (0 == (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_AEBI_D)) {
6483 snd_printk(KERN_INFO "HDSPM: AEB input board found, but not supported\n");
6484 }
6485
6486 hdspm->ss_in_channels = AIO_IN_SS_CHANNELS; 6780 hdspm->ss_in_channels = AIO_IN_SS_CHANNELS;
6487 hdspm->ds_in_channels = AIO_IN_DS_CHANNELS; 6781 hdspm->ds_in_channels = AIO_IN_DS_CHANNELS;
6488 hdspm->qs_in_channels = AIO_IN_QS_CHANNELS; 6782 hdspm->qs_in_channels = AIO_IN_QS_CHANNELS;
@@ -6490,6 +6784,20 @@ static int snd_hdspm_create(struct snd_card *card,
6490 hdspm->ds_out_channels = AIO_OUT_DS_CHANNELS; 6784 hdspm->ds_out_channels = AIO_OUT_DS_CHANNELS;
6491 hdspm->qs_out_channels = AIO_OUT_QS_CHANNELS; 6785 hdspm->qs_out_channels = AIO_OUT_QS_CHANNELS;
6492 6786
6787 if (0 == (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_AEBI_D)) {
6788 snd_printk(KERN_INFO "HDSPM: AEB input board found\n");
6789 hdspm->ss_in_channels += 4;
6790 hdspm->ds_in_channels += 4;
6791 hdspm->qs_in_channels += 4;
6792 }
6793
6794 if (0 == (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_AEBO_D)) {
6795 snd_printk(KERN_INFO "HDSPM: AEB output board found\n");
6796 hdspm->ss_out_channels += 4;
6797 hdspm->ds_out_channels += 4;
6798 hdspm->qs_out_channels += 4;
6799 }
6800
6493 hdspm->channel_map_out_ss = channel_map_aio_out_ss; 6801 hdspm->channel_map_out_ss = channel_map_aio_out_ss;
6494 hdspm->channel_map_out_ds = channel_map_aio_out_ds; 6802 hdspm->channel_map_out_ds = channel_map_aio_out_ds;
6495 hdspm->channel_map_out_qs = channel_map_aio_out_qs; 6803 hdspm->channel_map_out_qs = channel_map_aio_out_qs;
@@ -6558,6 +6866,7 @@ static int snd_hdspm_create(struct snd_card *card,
6558 break; 6866 break;
6559 6867
6560 case MADI: 6868 case MADI:
6869 case AES32:
6561 if (hdspm_read(hdspm, HDSPM_statusRegister) & HDSPM_tco_detect) { 6870 if (hdspm_read(hdspm, HDSPM_statusRegister) & HDSPM_tco_detect) {
6562 hdspm->midiPorts++; 6871 hdspm->midiPorts++;
6563 hdspm->tco = kzalloc(sizeof(struct hdspm_tco), 6872 hdspm->tco = kzalloc(sizeof(struct hdspm_tco),
@@ -6565,7 +6874,7 @@ static int snd_hdspm_create(struct snd_card *card,
6565 if (NULL != hdspm->tco) { 6874 if (NULL != hdspm->tco) {
6566 hdspm_tco_write(hdspm); 6875 hdspm_tco_write(hdspm);
6567 } 6876 }
6568 snd_printk(KERN_INFO "HDSPM: MADI TCO module found\n"); 6877 snd_printk(KERN_INFO "HDSPM: MADI/AES TCO module found\n");
6569 } else { 6878 } else {
6570 hdspm->tco = NULL; 6879 hdspm->tco = NULL;
6571 } 6880 }
@@ -6580,10 +6889,12 @@ static int snd_hdspm_create(struct snd_card *card,
6580 case AES32: 6889 case AES32:
6581 if (hdspm->tco) { 6890 if (hdspm->tco) {
6582 hdspm->texts_autosync = texts_autosync_aes_tco; 6891 hdspm->texts_autosync = texts_autosync_aes_tco;
6583 hdspm->texts_autosync_items = 10; 6892 hdspm->texts_autosync_items =
6893 ARRAY_SIZE(texts_autosync_aes_tco);
6584 } else { 6894 } else {
6585 hdspm->texts_autosync = texts_autosync_aes; 6895 hdspm->texts_autosync = texts_autosync_aes;
6586 hdspm->texts_autosync_items = 9; 6896 hdspm->texts_autosync_items =
6897 ARRAY_SIZE(texts_autosync_aes);
6587 } 6898 }
6588 break; 6899 break;
6589 6900
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 45eeaa9f7fec..5138b8493051 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -26,12 +26,9 @@ if SND_SOC
26config SND_SOC_AC97_BUS 26config SND_SOC_AC97_BUS
27 bool 27 bool
28 28
29config SND_SOC_DMAENGINE_PCM
30 bool
31
32config SND_SOC_GENERIC_DMAENGINE_PCM 29config SND_SOC_GENERIC_DMAENGINE_PCM
33 bool 30 bool
34 select SND_SOC_DMAENGINE_PCM 31 select SND_DMAENGINE_PCM
35 32
36# All the supported SoCs 33# All the supported SoCs
37source "sound/soc/atmel/Kconfig" 34source "sound/soc/atmel/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index bc0261476d7a..61a64d281905 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,10 +1,6 @@
1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o 1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
2snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o 2snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o
3 3
4ifneq ($(CONFIG_SND_SOC_DMAENGINE_PCM),)
5snd-soc-core-objs += soc-dmaengine-pcm.o
6endif
7
8ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),) 4ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),)
9snd-soc-core-objs += soc-generic-dmaengine-pcm.o 5snd-soc-core-objs += soc-generic-dmaengine-pcm.o
10endif 6endif
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index 3fdd87fa18a9..e48d38a1b95c 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -13,6 +13,7 @@ config SND_ATMEL_SOC_PDC
13config SND_ATMEL_SOC_DMA 13config SND_ATMEL_SOC_DMA
14 tristate 14 tristate
15 depends on SND_ATMEL_SOC 15 depends on SND_ATMEL_SOC
16 select SND_SOC_GENERIC_DMAENGINE_PCM
16 17
17config SND_ATMEL_SOC_SSC 18config SND_ATMEL_SOC_SSC
18 tristate 19 tristate
@@ -32,6 +33,26 @@ config SND_AT91_SOC_SAM9G20_WM8731
32 Say Y if you want to add support for SoC audio on WM8731-based 33 Say Y if you want to add support for SoC audio on WM8731-based
33 AT91sam9g20 evaluation board. 34 AT91sam9g20 evaluation board.
34 35
36config SND_ATMEL_SOC_WM8904
37 tristate "Atmel ASoC driver for boards using WM8904 codec"
38 depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC
39 select SND_ATMEL_SOC_SSC
40 select SND_ATMEL_SOC_DMA
41 select SND_SOC_WM8904
42 help
43 Say Y if you want to add support for Atmel ASoC driver for boards using
44 WM8904 codec.
45
46config SND_AT91_SOC_SAM9X5_WM8731
47 tristate "SoC Audio support for WM8731-based at91sam9x5 board"
48 depends on ATMEL_SSC && SND_ATMEL_SOC && SOC_AT91SAM9X5
49 select SND_ATMEL_SOC_SSC
50 select SND_ATMEL_SOC_DMA
51 select SND_SOC_WM8731
52 help
53 Say Y if you want to add support for audio SoC on an
54 at91sam9x5 based board that is using WM8731 codec.
55
35config SND_AT91_SOC_AFEB9260 56config SND_AT91_SOC_AFEB9260
36 tristate "SoC Audio support for AFEB9260 board" 57 tristate "SoC Audio support for AFEB9260 board"
37 depends on ARCH_AT91 && ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC 58 depends on ARCH_AT91 && ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
index 41967ccb6f41..5baabc8bde3a 100644
--- a/sound/soc/atmel/Makefile
+++ b/sound/soc/atmel/Makefile
@@ -11,6 +11,10 @@ obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
11 11
12# AT91 Machine Support 12# AT91 Machine Support
13snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o 13snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o
14snd-atmel-soc-wm8904-objs := atmel_wm8904.o
15snd-soc-sam9x5-wm8731-objs := sam9x5_wm8731.o
14 16
15obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o 17obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o
18obj-$(CONFIG_SND_ATMEL_SOC_WM8904) += snd-atmel-soc-wm8904.o
19obj-$(CONFIG_SND_AT91_SOC_SAM9X5_WM8731) += snd-soc-sam9x5-wm8731.o
16obj-$(CONFIG_SND_AT91_SOC_AFEB9260) += snd-soc-afeb9260.o 20obj-$(CONFIG_SND_AT91_SOC_AFEB9260) += snd-soc-afeb9260.o
diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c
index d12826526798..06082e5e5dcb 100644
--- a/sound/soc/atmel/atmel-pcm-dma.c
+++ b/sound/soc/atmel/atmel-pcm-dma.c
@@ -91,138 +91,52 @@ static void atmel_pcm_dma_irq(u32 ssc_sr,
91 } 91 }
92} 92}
93 93
94/*--------------------------------------------------------------------------*\
95 * DMAENGINE operations
96\*--------------------------------------------------------------------------*/
97static bool filter(struct dma_chan *chan, void *slave)
98{
99 struct at_dma_slave *sl = slave;
100
101 if (sl->dma_dev == chan->device->dev) {
102 chan->private = sl;
103 return true;
104 } else {
105 return false;
106 }
107}
108
109static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream, 94static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream,
110 struct snd_pcm_hw_params *params, struct atmel_pcm_dma_params *prtd) 95 struct snd_pcm_hw_params *params, struct dma_slave_config *slave_config)
111{ 96{
97 struct snd_soc_pcm_runtime *rtd = substream->private_data;
98 struct atmel_pcm_dma_params *prtd;
112 struct ssc_device *ssc; 99 struct ssc_device *ssc;
113 struct dma_chan *dma_chan;
114 struct dma_slave_config slave_config;
115 int ret; 100 int ret;
116 101
102 prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
117 ssc = prtd->ssc; 103 ssc = prtd->ssc;
118 104
119 ret = snd_hwparams_to_dma_slave_config(substream, params, 105 ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config);
120 &slave_config);
121 if (ret) { 106 if (ret) {
122 pr_err("atmel-pcm: hwparams to dma slave configure failed\n"); 107 pr_err("atmel-pcm: hwparams to dma slave configure failed\n");
123 return ret; 108 return ret;
124 } 109 }
125 110
126 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 111 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
127 slave_config.dst_addr = (dma_addr_t)ssc->phybase + SSC_THR; 112 slave_config->dst_addr = ssc->phybase + SSC_THR;
128 slave_config.dst_maxburst = 1; 113 slave_config->dst_maxburst = 1;
129 } else { 114 } else {
130 slave_config.src_addr = (dma_addr_t)ssc->phybase + SSC_RHR; 115 slave_config->src_addr = ssc->phybase + SSC_RHR;
131 slave_config.src_maxburst = 1; 116 slave_config->src_maxburst = 1;
132 }
133
134 dma_chan = snd_dmaengine_pcm_get_chan(substream);
135 if (dmaengine_slave_config(dma_chan, &slave_config)) {
136 pr_err("atmel-pcm: failed to configure dma channel\n");
137 ret = -EBUSY;
138 return ret;
139 }
140
141 return 0;
142}
143
144static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
145 struct snd_pcm_hw_params *params)
146{
147 struct snd_soc_pcm_runtime *rtd = substream->private_data;
148 struct atmel_pcm_dma_params *prtd;
149 struct ssc_device *ssc;
150 struct at_dma_slave *sdata = NULL;
151 int ret;
152
153 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
154
155 prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
156 ssc = prtd->ssc;
157 if (ssc->pdev)
158 sdata = ssc->pdev->dev.platform_data;
159
160 ret = snd_dmaengine_pcm_open_request_chan(substream, filter, sdata);
161 if (ret) {
162 pr_err("atmel-pcm: dmaengine pcm open failed\n");
163 return -EINVAL;
164 }
165
166 ret = atmel_pcm_configure_dma(substream, params, prtd);
167 if (ret) {
168 pr_err("atmel-pcm: failed to configure dmai\n");
169 goto err;
170 } 117 }
171 118
172 prtd->dma_intr_handler = atmel_pcm_dma_irq; 119 prtd->dma_intr_handler = atmel_pcm_dma_irq;
173 120
174 return 0; 121 return 0;
175err:
176 snd_dmaengine_pcm_close_release_chan(substream);
177 return ret;
178} 122}
179 123
180static int atmel_pcm_dma_prepare(struct snd_pcm_substream *substream) 124static const struct snd_dmaengine_pcm_config atmel_dmaengine_pcm_config = {
181{ 125 .prepare_slave_config = atmel_pcm_configure_dma,
182 struct snd_soc_pcm_runtime *rtd = substream->private_data; 126 .pcm_hardware = &atmel_pcm_dma_hardware,
183 struct atmel_pcm_dma_params *prtd; 127 .prealloc_buffer_size = ATMEL_SSC_DMABUF_SIZE,
184
185 prtd = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
186
187 ssc_writex(prtd->ssc->regs, SSC_IER, prtd->mask->ssc_error);
188 ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_enable);
189
190 return 0;
191}
192
193static int atmel_pcm_open(struct snd_pcm_substream *substream)
194{
195 snd_soc_set_runtime_hwparams(substream, &atmel_pcm_dma_hardware);
196
197 return 0;
198}
199
200static struct snd_pcm_ops atmel_pcm_ops = {
201 .open = atmel_pcm_open,
202 .close = snd_dmaengine_pcm_close_release_chan,
203 .ioctl = snd_pcm_lib_ioctl,
204 .hw_params = atmel_pcm_hw_params,
205 .prepare = atmel_pcm_dma_prepare,
206 .trigger = snd_dmaengine_pcm_trigger,
207 .pointer = snd_dmaengine_pcm_pointer_no_residue,
208 .mmap = atmel_pcm_mmap,
209};
210
211static struct snd_soc_platform_driver atmel_soc_platform = {
212 .ops = &atmel_pcm_ops,
213 .pcm_new = atmel_pcm_new,
214 .pcm_free = atmel_pcm_free,
215}; 128};
216 129
217int atmel_pcm_dma_platform_register(struct device *dev) 130int atmel_pcm_dma_platform_register(struct device *dev)
218{ 131{
219 return snd_soc_register_platform(dev, &atmel_soc_platform); 132 return snd_dmaengine_pcm_register(dev, &atmel_dmaengine_pcm_config,
133 SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
220} 134}
221EXPORT_SYMBOL(atmel_pcm_dma_platform_register); 135EXPORT_SYMBOL(atmel_pcm_dma_platform_register);
222 136
223void atmel_pcm_dma_platform_unregister(struct device *dev) 137void atmel_pcm_dma_platform_unregister(struct device *dev)
224{ 138{
225 snd_soc_unregister_platform(dev); 139 snd_dmaengine_pcm_unregister(dev);
226} 140}
227EXPORT_SYMBOL(atmel_pcm_dma_platform_unregister); 141EXPORT_SYMBOL(atmel_pcm_dma_platform_unregister);
228 142
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index f3fdfa07fcb9..0ecf356027f6 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -73,6 +73,7 @@ static struct atmel_ssc_mask ssc_tx_mask = {
73 .ssc_disable = SSC_BIT(CR_TXDIS), 73 .ssc_disable = SSC_BIT(CR_TXDIS),
74 .ssc_endx = SSC_BIT(SR_ENDTX), 74 .ssc_endx = SSC_BIT(SR_ENDTX),
75 .ssc_endbuf = SSC_BIT(SR_TXBUFE), 75 .ssc_endbuf = SSC_BIT(SR_TXBUFE),
76 .ssc_error = SSC_BIT(SR_OVRUN),
76 .pdc_enable = ATMEL_PDC_TXTEN, 77 .pdc_enable = ATMEL_PDC_TXTEN,
77 .pdc_disable = ATMEL_PDC_TXTDIS, 78 .pdc_disable = ATMEL_PDC_TXTDIS,
78}; 79};
@@ -82,6 +83,7 @@ static struct atmel_ssc_mask ssc_rx_mask = {
82 .ssc_disable = SSC_BIT(CR_RXDIS), 83 .ssc_disable = SSC_BIT(CR_RXDIS),
83 .ssc_endx = SSC_BIT(SR_ENDRX), 84 .ssc_endx = SSC_BIT(SR_ENDRX),
84 .ssc_endbuf = SSC_BIT(SR_RXBUFF), 85 .ssc_endbuf = SSC_BIT(SR_RXBUFF),
86 .ssc_error = SSC_BIT(SR_OVRUN),
85 .pdc_enable = ATMEL_PDC_RXTEN, 87 .pdc_enable = ATMEL_PDC_RXTEN,
86 .pdc_disable = ATMEL_PDC_RXTDIS, 88 .pdc_disable = ATMEL_PDC_RXTDIS,
87}; 89};
@@ -196,15 +198,27 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream,
196 struct snd_soc_dai *dai) 198 struct snd_soc_dai *dai)
197{ 199{
198 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id]; 200 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
199 int dir_mask; 201 struct atmel_pcm_dma_params *dma_params;
202 int dir, dir_mask;
200 203
201 pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n", 204 pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n",
202 ssc_readl(ssc_p->ssc->regs, SR)); 205 ssc_readl(ssc_p->ssc->regs, SR));
203 206
204 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 207 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
208 dir = 0;
205 dir_mask = SSC_DIR_MASK_PLAYBACK; 209 dir_mask = SSC_DIR_MASK_PLAYBACK;
206 else 210 } else {
211 dir = 1;
207 dir_mask = SSC_DIR_MASK_CAPTURE; 212 dir_mask = SSC_DIR_MASK_CAPTURE;
213 }
214
215 dma_params = &ssc_dma_params[dai->id][dir];
216 dma_params->ssc = ssc_p->ssc;
217 dma_params->substream = substream;
218
219 ssc_p->dma_params[dir] = dma_params;
220
221 snd_soc_dai_set_dma_data(dai, substream, dma_params);
208 222
209 spin_lock_irq(&ssc_p->lock); 223 spin_lock_irq(&ssc_p->lock);
210 if (ssc_p->dir_mask & dir_mask) { 224 if (ssc_p->dir_mask & dir_mask) {
@@ -325,7 +339,6 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
325 struct snd_pcm_hw_params *params, 339 struct snd_pcm_hw_params *params,
326 struct snd_soc_dai *dai) 340 struct snd_soc_dai *dai)
327{ 341{
328 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
329 int id = dai->id; 342 int id = dai->id;
330 struct atmel_ssc_info *ssc_p = &ssc_info[id]; 343 struct atmel_ssc_info *ssc_p = &ssc_info[id];
331 struct atmel_pcm_dma_params *dma_params; 344 struct atmel_pcm_dma_params *dma_params;
@@ -344,19 +357,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
344 else 357 else
345 dir = 1; 358 dir = 1;
346 359
347 dma_params = &ssc_dma_params[id][dir]; 360 dma_params = ssc_p->dma_params[dir];
348 dma_params->ssc = ssc_p->ssc;
349 dma_params->substream = substream;
350
351 ssc_p->dma_params[dir] = dma_params;
352
353 /*
354 * The snd_soc_pcm_stream->dma_data field is only used to communicate
355 * the appropriate DMA parameters to the pcm driver hw_params()
356 * function. It should not be used for other purposes
357 * as it is common to all substreams.
358 */
359 snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_params);
360 361
361 channels = params_channels(params); 362 channels = params_channels(params);
362 363
@@ -648,6 +649,7 @@ static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
648 dma_params = ssc_p->dma_params[dir]; 649 dma_params = ssc_p->dma_params[dir];
649 650
650 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable); 651 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable);
652 ssc_writel(ssc_p->ssc->regs, IER, dma_params->mask->ssc_error);
651 653
652 pr_debug("%s enabled SSC_SR=0x%08x\n", 654 pr_debug("%s enabled SSC_SR=0x%08x\n",
653 dir ? "receive" : "transmit", 655 dir ? "receive" : "transmit",
diff --git a/sound/soc/atmel/atmel_wm8904.c b/sound/soc/atmel/atmel_wm8904.c
new file mode 100644
index 000000000000..7222380131ea
--- /dev/null
+++ b/sound/soc/atmel/atmel_wm8904.c
@@ -0,0 +1,254 @@
1/*
2 * atmel_wm8904 - Atmel ASoC driver for boards with WM8904 codec.
3 *
4 * Copyright (C) 2012 Atmel
5 *
6 * Author: Bo Shen <voice.shen@atmel.com>
7 *
8 * GPLv2 or later
9 */
10
11#include <linux/clk.h>
12#include <linux/module.h>
13#include <linux/of.h>
14#include <linux/of_device.h>
15#include <linux/pinctrl/consumer.h>
16
17#include <sound/soc.h>
18
19#include "../codecs/wm8904.h"
20#include "atmel_ssc_dai.h"
21
22#define MCLK_RATE 32768
23
24static struct clk *mclk;
25
26static const struct snd_soc_dapm_widget atmel_asoc_wm8904_dapm_widgets[] = {
27 SND_SOC_DAPM_HP("Headphone Jack", NULL),
28 SND_SOC_DAPM_MIC("Mic", NULL),
29 SND_SOC_DAPM_LINE("Line In Jack", NULL),
30};
31
32static int atmel_asoc_wm8904_hw_params(struct snd_pcm_substream *substream,
33 struct snd_pcm_hw_params *params)
34{
35 struct snd_soc_pcm_runtime *rtd = substream->private_data;
36 struct snd_soc_dai *codec_dai = rtd->codec_dai;
37 int ret;
38
39 ret = snd_soc_dai_set_pll(codec_dai, WM8904_FLL_MCLK, WM8904_FLL_MCLK,
40 32768, params_rate(params) * 256);
41 if (ret < 0) {
42 pr_err("%s - failed to set wm8904 codec PLL.", __func__);
43 return ret;
44 }
45
46 /*
47 * As here wm8904 use FLL output as its system clock
48 * so calling set_sysclk won't care freq parameter
49 * then we pass 0
50 */
51 ret = snd_soc_dai_set_sysclk(codec_dai, WM8904_CLK_FLL,
52 0, SND_SOC_CLOCK_IN);
53 if (ret < 0) {
54 pr_err("%s -failed to set wm8904 SYSCLK\n", __func__);
55 return ret;
56 }
57
58 return 0;
59}
60
61static struct snd_soc_ops atmel_asoc_wm8904_ops = {
62 .hw_params = atmel_asoc_wm8904_hw_params,
63};
64
65static int atmel_set_bias_level(struct snd_soc_card *card,
66 struct snd_soc_dapm_context *dapm,
67 enum snd_soc_bias_level level)
68{
69 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
70 switch (level) {
71 case SND_SOC_BIAS_PREPARE:
72 clk_prepare_enable(mclk);
73 break;
74 case SND_SOC_BIAS_OFF:
75 clk_disable_unprepare(mclk);
76 break;
77 default:
78 break;
79 }
80 }
81
82 return 0;
83};
84
85static struct snd_soc_dai_link atmel_asoc_wm8904_dailink = {
86 .name = "WM8904",
87 .stream_name = "WM8904 PCM",
88 .codec_dai_name = "wm8904-hifi",
89 .dai_fmt = SND_SOC_DAIFMT_I2S
90 | SND_SOC_DAIFMT_NB_NF
91 | SND_SOC_DAIFMT_CBM_CFM,
92 .ops = &atmel_asoc_wm8904_ops,
93};
94
95static struct snd_soc_card atmel_asoc_wm8904_card = {
96 .name = "atmel_asoc_wm8904",
97 .owner = THIS_MODULE,
98 .set_bias_level = atmel_set_bias_level,
99 .dai_link = &atmel_asoc_wm8904_dailink,
100 .num_links = 1,
101 .dapm_widgets = atmel_asoc_wm8904_dapm_widgets,
102 .num_dapm_widgets = ARRAY_SIZE(atmel_asoc_wm8904_dapm_widgets),
103 .fully_routed = true,
104};
105
106static int atmel_asoc_wm8904_dt_init(struct platform_device *pdev)
107{
108 struct device_node *np = pdev->dev.of_node;
109 struct device_node *codec_np, *cpu_np;
110 struct snd_soc_card *card = &atmel_asoc_wm8904_card;
111 struct snd_soc_dai_link *dailink = &atmel_asoc_wm8904_dailink;
112 int ret;
113
114 if (!np) {
115 dev_err(&pdev->dev, "only device tree supported\n");
116 return -EINVAL;
117 }
118
119 ret = snd_soc_of_parse_card_name(card, "atmel,model");
120 if (ret) {
121 dev_err(&pdev->dev, "failed to parse card name\n");
122 return ret;
123 }
124
125 ret = snd_soc_of_parse_audio_routing(card, "atmel,audio-routing");
126 if (ret) {
127 dev_err(&pdev->dev, "failed to parse audio routing\n");
128 return ret;
129 }
130
131 cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0);
132 if (!cpu_np) {
133 dev_err(&pdev->dev, "failed to get dai and pcm info\n");
134 ret = -EINVAL;
135 return ret;
136 }
137 dailink->cpu_of_node = cpu_np;
138 dailink->platform_of_node = cpu_np;
139 of_node_put(cpu_np);
140
141 codec_np = of_parse_phandle(np, "atmel,audio-codec", 0);
142 if (!codec_np) {
143 dev_err(&pdev->dev, "failed to get codec info\n");
144 ret = -EINVAL;
145 return ret;
146 }
147 dailink->codec_of_node = codec_np;
148 of_node_put(codec_np);
149
150 return 0;
151}
152
153static int atmel_asoc_wm8904_probe(struct platform_device *pdev)
154{
155 struct snd_soc_card *card = &atmel_asoc_wm8904_card;
156 struct snd_soc_dai_link *dailink = &atmel_asoc_wm8904_dailink;
157 struct clk *clk_src;
158 struct pinctrl *pinctrl;
159 int id, ret;
160
161 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
162 if (IS_ERR(pinctrl)) {
163 dev_err(&pdev->dev, "failed to request pinctrl\n");
164 return PTR_ERR(pinctrl);
165 }
166
167 card->dev = &pdev->dev;
168 ret = atmel_asoc_wm8904_dt_init(pdev);
169 if (ret) {
170 dev_err(&pdev->dev, "failed to init dt info\n");
171 return ret;
172 }
173
174 id = of_alias_get_id((struct device_node *)dailink->cpu_of_node, "ssc");
175 ret = atmel_ssc_set_audio(id);
176 if (ret != 0) {
177 dev_err(&pdev->dev, "failed to set SSC %d for audio\n", id);
178 return ret;
179 }
180
181 mclk = clk_get(NULL, "pck0");
182 if (IS_ERR(mclk)) {
183 dev_err(&pdev->dev, "failed to get pck0\n");
184 ret = PTR_ERR(mclk);
185 goto err_set_audio;
186 }
187
188 clk_src = clk_get(NULL, "clk32k");
189 if (IS_ERR(clk_src)) {
190 dev_err(&pdev->dev, "failed to get clk32k\n");
191 ret = PTR_ERR(clk_src);
192 goto err_set_audio;
193 }
194
195 ret = clk_set_parent(mclk, clk_src);
196 clk_put(clk_src);
197 if (ret != 0) {
198 dev_err(&pdev->dev, "failed to set MCLK parent\n");
199 goto err_set_audio;
200 }
201
202 dev_info(&pdev->dev, "setting pck0 to %dHz\n", MCLK_RATE);
203 clk_set_rate(mclk, MCLK_RATE);
204
205 ret = snd_soc_register_card(card);
206 if (ret) {
207 dev_err(&pdev->dev, "snd_soc_register_card failed\n");
208 goto err_set_audio;
209 }
210
211 return 0;
212
213err_set_audio:
214 atmel_ssc_put_audio(id);
215 return ret;
216}
217
218static int atmel_asoc_wm8904_remove(struct platform_device *pdev)
219{
220 struct snd_soc_card *card = platform_get_drvdata(pdev);
221 struct snd_soc_dai_link *dailink = &atmel_asoc_wm8904_dailink;
222 int id;
223
224 id = of_alias_get_id((struct device_node *)dailink->cpu_of_node, "ssc");
225
226 snd_soc_unregister_card(card);
227 atmel_ssc_put_audio(id);
228
229 return 0;
230}
231
232#ifdef CONFIG_OF
233static const struct of_device_id atmel_asoc_wm8904_dt_ids[] = {
234 { .compatible = "atmel,asoc-wm8904", },
235 { }
236};
237#endif
238
239static struct platform_driver atmel_asoc_wm8904_driver = {
240 .driver = {
241 .name = "atmel-wm8904-audio",
242 .owner = THIS_MODULE,
243 .of_match_table = of_match_ptr(atmel_asoc_wm8904_dt_ids),
244 },
245 .probe = atmel_asoc_wm8904_probe,
246 .remove = atmel_asoc_wm8904_remove,
247};
248
249module_platform_driver(atmel_asoc_wm8904_driver);
250
251/* Module information */
252MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>");
253MODULE_DESCRIPTION("ALSA SoC machine driver for Atmel EK with WM8904 codec");
254MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/sam9x5_wm8731.c b/sound/soc/atmel/sam9x5_wm8731.c
new file mode 100644
index 000000000000..992ae38d5a15
--- /dev/null
+++ b/sound/soc/atmel/sam9x5_wm8731.c
@@ -0,0 +1,208 @@
1/*
2 * sam9x5_wm8731 -- SoC audio for AT91SAM9X5-based boards
3 * that are using WM8731 as codec.
4 *
5 * Copyright (C) 2011 Atmel,
6 * Nicolas Ferre <nicolas.ferre@atmel.com>
7 *
8 * Copyright (C) 2013 Paratronic,
9 * Richard Genoud <richard.genoud@gmail.com>
10 *
11 * Based on sam9g20_wm8731.c by:
12 * Sedji Gaouaou <sedji.gaouaou@atmel.com>
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version.
18 *
19 */
20#include <linux/of.h>
21#include <linux/export.h>
22#include <linux/module.h>
23#include <linux/mod_devicetable.h>
24#include <linux/platform_device.h>
25#include <linux/device.h>
26
27#include <sound/soc.h>
28#include <sound/soc-dai.h>
29#include <sound/soc-dapm.h>
30
31#include "../codecs/wm8731.h"
32#include "atmel_ssc_dai.h"
33
34
35#define MCLK_RATE 12288000
36
37#define DRV_NAME "sam9x5-snd-wm8731"
38
39struct sam9x5_drvdata {
40 int ssc_id;
41};
42
43/*
44 * Logic for a wm8731 as connected on a at91sam9x5ek based board.
45 */
46static int sam9x5_wm8731_init(struct snd_soc_pcm_runtime *rtd)
47{
48 struct snd_soc_dai *codec_dai = rtd->codec_dai;
49 struct device *dev = rtd->dev;
50 int ret;
51
52 dev_dbg(dev, "ASoC: %s called\n", __func__);
53
54 /* set the codec system clock for DAC and ADC */
55 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL,
56 MCLK_RATE, SND_SOC_CLOCK_IN);
57 if (ret < 0) {
58 dev_err(dev, "ASoC: Failed to set WM8731 SYSCLK: %d\n", ret);
59 return ret;
60 }
61
62 return 0;
63}
64
65/*
66 * Audio paths on at91sam9x5ek board:
67 *
68 * |A| ------------> | | ---R----> Headphone Jack
69 * |T| <----\ | WM | ---L--/
70 * |9| ---> CLK <--> | 8731 | <--R----- Line In Jack
71 * |1| <------------ | | <--L--/
72 */
73static const struct snd_soc_dapm_widget sam9x5_dapm_widgets[] = {
74 SND_SOC_DAPM_HP("Headphone Jack", NULL),
75 SND_SOC_DAPM_LINE("Line In Jack", NULL),
76};
77
78static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
79{
80 struct device_node *np = pdev->dev.of_node;
81 struct device_node *codec_np, *cpu_np;
82 struct snd_soc_card *card;
83 struct snd_soc_dai_link *dai;
84 struct sam9x5_drvdata *priv;
85 int ret;
86
87 if (!np) {
88 dev_err(&pdev->dev, "No device node supplied\n");
89 return -EINVAL;
90 }
91
92 card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL);
93 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
94 dai = devm_kzalloc(&pdev->dev, sizeof(*dai), GFP_KERNEL);
95 if (!dai || !card || !priv) {
96 ret = -ENOMEM;
97 goto out;
98 }
99
100 card->dev = &pdev->dev;
101 card->owner = THIS_MODULE;
102 card->dai_link = dai;
103 card->num_links = 1;
104 card->dapm_widgets = sam9x5_dapm_widgets;
105 card->num_dapm_widgets = ARRAY_SIZE(sam9x5_dapm_widgets);
106 dai->name = "WM8731";
107 dai->stream_name = "WM8731 PCM";
108 dai->codec_dai_name = "wm8731-hifi";
109 dai->init = sam9x5_wm8731_init;
110 dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
111 | SND_SOC_DAIFMT_CBM_CFM;
112
113 ret = snd_soc_of_parse_card_name(card, "atmel,model");
114 if (ret) {
115 dev_err(&pdev->dev, "atmel,model node missing\n");
116 goto out;
117 }
118
119 ret = snd_soc_of_parse_audio_routing(card, "atmel,audio-routing");
120 if (ret) {
121 dev_err(&pdev->dev, "atmel,audio-routing node missing\n");
122 goto out;
123 }
124
125 codec_np = of_parse_phandle(np, "atmel,audio-codec", 0);
126 if (!codec_np) {
127 dev_err(&pdev->dev, "atmel,audio-codec node missing\n");
128 ret = -EINVAL;
129 goto out;
130 }
131
132 dai->codec_of_node = codec_np;
133
134 cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0);
135 if (!cpu_np) {
136 dev_err(&pdev->dev, "atmel,ssc-controller node missing\n");
137 ret = -EINVAL;
138 goto out;
139 }
140 dai->cpu_of_node = cpu_np;
141 dai->platform_of_node = cpu_np;
142
143 priv->ssc_id = of_alias_get_id(cpu_np, "ssc");
144
145 ret = atmel_ssc_set_audio(priv->ssc_id);
146 if (ret != 0) {
147 dev_err(&pdev->dev,
148 "ASoC: Failed to set SSC %d for audio: %d\n",
149 ret, priv->ssc_id);
150 goto out;
151 }
152
153 of_node_put(codec_np);
154 of_node_put(cpu_np);
155
156 platform_set_drvdata(pdev, card);
157
158 ret = snd_soc_register_card(card);
159 if (ret) {
160 dev_err(&pdev->dev,
161 "ASoC: Platform device allocation failed\n");
162 goto out_put_audio;
163 }
164
165 dev_dbg(&pdev->dev, "ASoC: %s ok\n", __func__);
166
167 return ret;
168
169out_put_audio:
170 atmel_ssc_put_audio(priv->ssc_id);
171out:
172 return ret;
173}
174
175static int sam9x5_wm8731_driver_remove(struct platform_device *pdev)
176{
177 struct snd_soc_card *card = platform_get_drvdata(pdev);
178 struct sam9x5_drvdata *priv = card->drvdata;
179
180 snd_soc_unregister_card(card);
181 atmel_ssc_put_audio(priv->ssc_id);
182
183 return 0;
184}
185
186static const struct of_device_id sam9x5_wm8731_of_match[] = {
187 { .compatible = "atmel,sam9x5-wm8731-audio", },
188 {},
189};
190MODULE_DEVICE_TABLE(of, sam9x5_wm8731_of_match);
191
192static struct platform_driver sam9x5_wm8731_driver = {
193 .driver = {
194 .name = DRV_NAME,
195 .owner = THIS_MODULE,
196 .of_match_table = of_match_ptr(sam9x5_wm8731_of_match),
197 },
198 .probe = sam9x5_wm8731_driver_probe,
199 .remove = sam9x5_wm8731_driver_remove,
200};
201module_platform_driver(sam9x5_wm8731_driver);
202
203/* Module information */
204MODULE_AUTHOR("Nicolas Ferre <nicolas.ferre@atmel.com>");
205MODULE_AUTHOR("Richard Genoud <richard.genoud@gmail.com>");
206MODULE_DESCRIPTION("ALSA SoC machine driver for AT91SAM9x5 - WM8731");
207MODULE_LICENSE("GPL");
208MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index a497a0cfeba1..decba87a074c 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -73,12 +73,14 @@ static struct snd_soc_dai_link db1300_ac97_dai = {
73 73
74static struct snd_soc_card db1300_ac97_machine = { 74static struct snd_soc_card db1300_ac97_machine = {
75 .name = "DB1300_AC97", 75 .name = "DB1300_AC97",
76 .owner = THIS_MODULE,
76 .dai_link = &db1300_ac97_dai, 77 .dai_link = &db1300_ac97_dai,
77 .num_links = 1, 78 .num_links = 1,
78}; 79};
79 80
80static struct snd_soc_card db1550_ac97_machine = { 81static struct snd_soc_card db1550_ac97_machine = {
81 .name = "DB1550_AC97", 82 .name = "DB1550_AC97",
83 .owner = THIS_MODULE,
82 .dai_link = &db1200_ac97_dai, 84 .dai_link = &db1200_ac97_dai,
83 .num_links = 1, 85 .num_links = 1,
84}; 86};
@@ -145,6 +147,7 @@ static struct snd_soc_dai_link db1300_i2s_dai = {
145 147
146static struct snd_soc_card db1300_i2s_machine = { 148static struct snd_soc_card db1300_i2s_machine = {
147 .name = "DB1300_I2S", 149 .name = "DB1300_I2S",
150 .owner = THIS_MODULE,
148 .dai_link = &db1300_i2s_dai, 151 .dai_link = &db1300_i2s_dai,
149 .num_links = 1, 152 .num_links = 1,
150}; 153};
@@ -161,6 +164,7 @@ static struct snd_soc_dai_link db1550_i2s_dai = {
161 164
162static struct snd_soc_card db1550_i2s_machine = { 165static struct snd_soc_card db1550_i2s_machine = {
163 .name = "DB1550_I2S", 166 .name = "DB1550_I2S",
167 .owner = THIS_MODULE,
164 .dai_link = &db1550_i2s_dai, 168 .dai_link = &db1550_i2s_dai,
165 .num_links = 1, 169 .num_links = 1,
166}; 170};
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index a822ab822bb7..986dcec79fa0 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -379,9 +379,6 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev)
379 mutex_init(&wd->lock); 379 mutex_init(&wd->lock);
380 380
381 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 381 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
382 if (!iores)
383 return -ENODEV;
384
385 wd->mmio = devm_ioremap_resource(&pdev->dev, iores); 382 wd->mmio = devm_ioremap_resource(&pdev->dev, iores);
386 if (IS_ERR(wd->mmio)) 383 if (IS_ERR(wd->mmio))
387 return PTR_ERR(wd->mmio); 384 return PTR_ERR(wd->mmio);
diff --git a/sound/soc/blackfin/bf5xx-ac97.h b/sound/soc/blackfin/bf5xx-ac97.h
index 0c3e22d90a8d..a680fdc9bb42 100644
--- a/sound/soc/blackfin/bf5xx-ac97.h
+++ b/sound/soc/blackfin/bf5xx-ac97.h
@@ -9,7 +9,6 @@
9#ifndef _BF5XX_AC97_H 9#ifndef _BF5XX_AC97_H
10#define _BF5XX_AC97_H 10#define _BF5XX_AC97_H
11 11
12extern struct snd_ac97 *ac97;
13/* Frame format in memory, only support stereo currently */ 12/* Frame format in memory, only support stereo currently */
14struct ac97_frame { 13struct ac97_frame {
15 u16 ac97_tag; /* slot 0 */ 14 u16 ac97_tag; /* slot 0 */
diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c
index 04491f0e8d1b..efa75b5086a4 100644
--- a/sound/soc/cirrus/ep93xx-ac97.c
+++ b/sound/soc/cirrus/ep93xx-ac97.c
@@ -363,9 +363,6 @@ static int ep93xx_ac97_probe(struct platform_device *pdev)
363 return -ENOMEM; 363 return -ENOMEM;
364 364
365 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 365 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
366 if (!res)
367 return -ENODEV;
368
369 info->regs = devm_ioremap_resource(&pdev->dev, res); 366 info->regs = devm_ioremap_resource(&pdev->dev, res);
370 if (IS_ERR(info->regs)) 367 if (IS_ERR(info->regs))
371 return PTR_ERR(info->regs); 368 return PTR_ERR(info->regs);
diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c
index 17ad70bca9fe..a57643d6402f 100644
--- a/sound/soc/cirrus/ep93xx-i2s.c
+++ b/sound/soc/cirrus/ep93xx-i2s.c
@@ -376,9 +376,6 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
376 return -ENOMEM; 376 return -ENOMEM;
377 377
378 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 378 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
379 if (!res)
380 return -ENODEV;
381
382 info->regs = devm_ioremap_resource(&pdev->dev, res); 379 info->regs = devm_ioremap_resource(&pdev->dev, res);
383 if (IS_ERR(info->regs)) 380 if (IS_ERR(info->regs))
384 return PTR_ERR(info->regs); 381 return PTR_ERR(info->regs);
@@ -411,7 +408,6 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
411 return 0; 408 return 0;
412 409
413fail_put_lrclk: 410fail_put_lrclk:
414 dev_set_drvdata(&pdev->dev, NULL);
415 clk_put(info->lrclk); 411 clk_put(info->lrclk);
416fail_put_sclk: 412fail_put_sclk:
417 clk_put(info->sclk); 413 clk_put(info->sclk);
@@ -426,7 +422,6 @@ static int ep93xx_i2s_remove(struct platform_device *pdev)
426 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev); 422 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev);
427 423
428 snd_soc_unregister_component(&pdev->dev); 424 snd_soc_unregister_component(&pdev->dev);
429 dev_set_drvdata(&pdev->dev, NULL);
430 clk_put(info->lrclk); 425 clk_put(info->lrclk);
431 clk_put(info->sclk); 426 clk_put(info->sclk);
432 clk_put(info->mclk); 427 clk_put(info->mclk);
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index badb6fbacaa6..15106c045478 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -10,6 +10,7 @@ config SND_SOC_I2C_AND_SPI
10 10
11config SND_SOC_ALL_CODECS 11config SND_SOC_ALL_CODECS
12 tristate "Build all ASoC CODEC drivers" 12 tristate "Build all ASoC CODEC drivers"
13 depends on COMPILE_TEST
13 select SND_SOC_88PM860X if MFD_88PM860X 14 select SND_SOC_88PM860X if MFD_88PM860X
14 select SND_SOC_L3 15 select SND_SOC_L3
15 select SND_SOC_AB8500_CODEC if ABX500_CORE 16 select SND_SOC_AB8500_CODEC if ABX500_CORE
@@ -20,6 +21,7 @@ config SND_SOC_ALL_CODECS
20 select SND_SOC_AD73311 21 select SND_SOC_AD73311
21 select SND_SOC_ADAU1373 if I2C 22 select SND_SOC_ADAU1373 if I2C
22 select SND_SOC_ADAV80X if SND_SOC_I2C_AND_SPI 23 select SND_SOC_ADAV80X if SND_SOC_I2C_AND_SPI
24 select SND_SOC_ADAU1701 if I2C
23 select SND_SOC_ADS117X 25 select SND_SOC_ADS117X
24 select SND_SOC_AK4104 if SPI_MASTER 26 select SND_SOC_AK4104 if SPI_MASTER
25 select SND_SOC_AK4535 if I2C 27 select SND_SOC_AK4535 if I2C
@@ -54,6 +56,8 @@ config SND_SOC_ALL_CODECS
54 select SND_SOC_MC13783 if MFD_MC13XXX 56 select SND_SOC_MC13783 if MFD_MC13XXX
55 select SND_SOC_ML26124 if I2C 57 select SND_SOC_ML26124 if I2C
56 select SND_SOC_HDMI_CODEC 58 select SND_SOC_HDMI_CODEC
59 select SND_SOC_PCM1681 if I2C
60 select SND_SOC_PCM1792A if SPI_MASTER
57 select SND_SOC_PCM3008 61 select SND_SOC_PCM3008
58 select SND_SOC_RT5631 if I2C 62 select SND_SOC_RT5631 if I2C
59 select SND_SOC_RT5640 if I2C 63 select SND_SOC_RT5640 if I2C
@@ -122,6 +126,7 @@ config SND_SOC_ALL_CODECS
122 select SND_SOC_WM8994 if MFD_WM8994 126 select SND_SOC_WM8994 if MFD_WM8994
123 select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI 127 select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI
124 select SND_SOC_WM8996 if I2C 128 select SND_SOC_WM8996 if I2C
129 select SND_SOC_WM8997 if MFD_WM8997
125 select SND_SOC_WM9081 if I2C 130 select SND_SOC_WM9081 if I2C
126 select SND_SOC_WM9090 if I2C 131 select SND_SOC_WM9090 if I2C
127 select SND_SOC_WM9705 if SND_SOC_AC97_BUS 132 select SND_SOC_WM9705 if SND_SOC_AC97_BUS
@@ -145,8 +150,10 @@ config SND_SOC_ARIZONA
145 tristate 150 tristate
146 default y if SND_SOC_WM5102=y 151 default y if SND_SOC_WM5102=y
147 default y if SND_SOC_WM5110=y 152 default y if SND_SOC_WM5110=y
153 default y if SND_SOC_WM8997=y
148 default m if SND_SOC_WM5102=m 154 default m if SND_SOC_WM5102=m
149 default m if SND_SOC_WM5110=m 155 default m if SND_SOC_WM5110=m
156 default m if SND_SOC_WM8997=m
150 157
151config SND_SOC_WM_HUBS 158config SND_SOC_WM_HUBS
152 tristate 159 tristate
@@ -198,6 +205,9 @@ config SND_SOC_AK4104
198config SND_SOC_AK4535 205config SND_SOC_AK4535
199 tristate 206 tristate
200 207
208config SND_SOC_AK4554
209 tristate
210
201config SND_SOC_AK4641 211config SND_SOC_AK4641
202 tristate 212 tristate
203 213
@@ -292,6 +302,12 @@ config SND_SOC_MAX9850
292config SND_SOC_HDMI_CODEC 302config SND_SOC_HDMI_CODEC
293 tristate 303 tristate
294 304
305config SND_SOC_PCM1681
306 tristate
307
308config SND_SOC_PCM1792A
309 tristate
310
295config SND_SOC_PCM3008 311config SND_SOC_PCM3008
296 tristate 312 tristate
297 313
@@ -500,6 +516,9 @@ config SND_SOC_WM8995
500config SND_SOC_WM8996 516config SND_SOC_WM8996
501 tristate 517 tristate
502 518
519config SND_SOC_WM8997
520 tristate
521
503config SND_SOC_WM9081 522config SND_SOC_WM9081
504 tristate 523 tristate
505 524
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 70fd8066f546..bc126764a44d 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -11,6 +11,7 @@ snd-soc-adav80x-objs := adav80x.o
11snd-soc-ads117x-objs := ads117x.o 11snd-soc-ads117x-objs := ads117x.o
12snd-soc-ak4104-objs := ak4104.o 12snd-soc-ak4104-objs := ak4104.o
13snd-soc-ak4535-objs := ak4535.o 13snd-soc-ak4535-objs := ak4535.o
14snd-soc-ak4554-objs := ak4554.o
14snd-soc-ak4641-objs := ak4641.o 15snd-soc-ak4641-objs := ak4641.o
15snd-soc-ak4642-objs := ak4642.o 16snd-soc-ak4642-objs := ak4642.o
16snd-soc-ak4671-objs := ak4671.o 17snd-soc-ak4671-objs := ak4671.o
@@ -42,6 +43,8 @@ snd-soc-max9850-objs := max9850.o
42snd-soc-mc13783-objs := mc13783.o 43snd-soc-mc13783-objs := mc13783.o
43snd-soc-ml26124-objs := ml26124.o 44snd-soc-ml26124-objs := ml26124.o
44snd-soc-hdmi-codec-objs := hdmi.o 45snd-soc-hdmi-codec-objs := hdmi.o
46snd-soc-pcm1681-objs := pcm1681.o
47snd-soc-pcm1792a-codec-objs := pcm1792a.o
45snd-soc-pcm3008-objs := pcm3008.o 48snd-soc-pcm3008-objs := pcm3008.o
46snd-soc-rt5631-objs := rt5631.o 49snd-soc-rt5631-objs := rt5631.o
47snd-soc-rt5640-objs := rt5640.o 50snd-soc-rt5640-objs := rt5640.o
@@ -114,6 +117,7 @@ snd-soc-wm8991-objs := wm8991.o
114snd-soc-wm8993-objs := wm8993.o 117snd-soc-wm8993-objs := wm8993.o
115snd-soc-wm8994-objs := wm8994.o wm8958-dsp2.o 118snd-soc-wm8994-objs := wm8994.o wm8958-dsp2.o
116snd-soc-wm8995-objs := wm8995.o 119snd-soc-wm8995-objs := wm8995.o
120snd-soc-wm8997-objs := wm8997.o
117snd-soc-wm9081-objs := wm9081.o 121snd-soc-wm9081-objs := wm9081.o
118snd-soc-wm9090-objs := wm9090.o 122snd-soc-wm9090-objs := wm9090.o
119snd-soc-wm9705-objs := wm9705.o 123snd-soc-wm9705-objs := wm9705.o
@@ -138,6 +142,7 @@ obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o
138obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o 142obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
139obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o 143obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
140obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 144obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
145obj-$(CONFIG_SND_SOC_AK4554) += snd-soc-ak4554.o
141obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o 146obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o
142obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 147obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
143obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 148obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
@@ -171,6 +176,8 @@ obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
171obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o 176obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
172obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o 177obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
173obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o 178obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
179obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o
180obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o
174obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 181obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
175obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o 182obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
176obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o 183obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
@@ -239,6 +246,7 @@ obj-$(CONFIG_SND_SOC_WM8991) += snd-soc-wm8991.o
239obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o 246obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
240obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o 247obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o
241obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o 248obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o
249obj-$(CONFIG_SND_SOC_WM8997) += snd-soc-wm8997.o
242obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o 250obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
243obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o 251obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o
244obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o 252obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index ec7351803c24..8d9ba4ba4bfe 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -23,6 +23,16 @@
23#include <sound/initval.h> 23#include <sound/initval.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25 25
26static const struct snd_soc_dapm_widget ac97_widgets[] = {
27 SND_SOC_DAPM_INPUT("RX"),
28 SND_SOC_DAPM_OUTPUT("TX"),
29};
30
31static const struct snd_soc_dapm_route ac97_routes[] = {
32 { "AC97 Capture", NULL, "RX" },
33 { "TX", NULL, "AC97 Playback" },
34};
35
26static int ac97_prepare(struct snd_pcm_substream *substream, 36static int ac97_prepare(struct snd_pcm_substream *substream,
27 struct snd_soc_dai *dai) 37 struct snd_soc_dai *dai)
28{ 38{
@@ -117,6 +127,11 @@ static struct snd_soc_codec_driver soc_codec_dev_ac97 = {
117 .probe = ac97_soc_probe, 127 .probe = ac97_soc_probe,
118 .suspend = ac97_soc_suspend, 128 .suspend = ac97_soc_suspend,
119 .resume = ac97_soc_resume, 129 .resume = ac97_soc_resume,
130
131 .dapm_widgets = ac97_widgets,
132 .num_dapm_widgets = ARRAY_SIZE(ac97_widgets),
133 .dapm_routes = ac97_routes,
134 .num_dapm_routes = ARRAY_SIZE(ac97_routes),
120}; 135};
121 136
122static int ac97_probe(struct platform_device *pdev) 137static int ac97_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 89fcf7d6e7b8..7257a8885f42 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -96,6 +96,44 @@ SOC_ENUM("Capture Source", ad1980_cap_src),
96SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0), 96SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0),
97}; 97};
98 98
99static const struct snd_soc_dapm_widget ad1980_dapm_widgets[] = {
100SND_SOC_DAPM_INPUT("MIC1"),
101SND_SOC_DAPM_INPUT("MIC2"),
102SND_SOC_DAPM_INPUT("CD_L"),
103SND_SOC_DAPM_INPUT("CD_R"),
104SND_SOC_DAPM_INPUT("AUX_L"),
105SND_SOC_DAPM_INPUT("AUX_R"),
106SND_SOC_DAPM_INPUT("LINE_IN_L"),
107SND_SOC_DAPM_INPUT("LINE_IN_R"),
108
109SND_SOC_DAPM_OUTPUT("LFE_OUT"),
110SND_SOC_DAPM_OUTPUT("CENTER_OUT"),
111SND_SOC_DAPM_OUTPUT("LINE_OUT_L"),
112SND_SOC_DAPM_OUTPUT("LINE_OUT_R"),
113SND_SOC_DAPM_OUTPUT("MONO_OUT"),
114SND_SOC_DAPM_OUTPUT("HP_OUT_L"),
115SND_SOC_DAPM_OUTPUT("HP_OUT_R"),
116};
117
118static const struct snd_soc_dapm_route ad1980_dapm_routes[] = {
119 { "Capture", NULL, "MIC1" },
120 { "Capture", NULL, "MIC2" },
121 { "Capture", NULL, "CD_L" },
122 { "Capture", NULL, "CD_R" },
123 { "Capture", NULL, "AUX_L" },
124 { "Capture", NULL, "AUX_R" },
125 { "Capture", NULL, "LINE_IN_L" },
126 { "Capture", NULL, "LINE_IN_R" },
127
128 { "LFE_OUT", NULL, "Playback" },
129 { "CENTER_OUT", NULL, "Playback" },
130 { "LINE_OUT_L", NULL, "Playback" },
131 { "LINE_OUT_R", NULL, "Playback" },
132 { "MONO_OUT", NULL, "Playback" },
133 { "HP_OUT_L", NULL, "Playback" },
134 { "HP_OUT_R", NULL, "Playback" },
135};
136
99static unsigned int ac97_read(struct snd_soc_codec *codec, 137static unsigned int ac97_read(struct snd_soc_codec *codec,
100 unsigned int reg) 138 unsigned int reg)
101{ 139{
@@ -253,6 +291,11 @@ static struct snd_soc_codec_driver soc_codec_dev_ad1980 = {
253 .reg_cache_step = 2, 291 .reg_cache_step = 2,
254 .write = ac97_write, 292 .write = ac97_write,
255 .read = ac97_read, 293 .read = ac97_read,
294
295 .dapm_widgets = ad1980_dapm_widgets,
296 .num_dapm_widgets = ARRAY_SIZE(ad1980_dapm_widgets),
297 .dapm_routes = ad1980_dapm_routes,
298 .num_dapm_routes = ARRAY_SIZE(ad1980_dapm_routes),
256}; 299};
257 300
258static int ad1980_probe(struct platform_device *pdev) 301static int ad1980_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index b1f2baf42b48..5fac8adbc136 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -23,6 +23,21 @@
23 23
24#include "ad73311.h" 24#include "ad73311.h"
25 25
26static const struct snd_soc_dapm_widget ad73311_dapm_widgets[] = {
27SND_SOC_DAPM_INPUT("VINP"),
28SND_SOC_DAPM_INPUT("VINN"),
29SND_SOC_DAPM_OUTPUT("VOUTN"),
30SND_SOC_DAPM_OUTPUT("VOUTP"),
31};
32
33static const struct snd_soc_dapm_route ad73311_dapm_routes[] = {
34 { "Capture", NULL, "VINP" },
35 { "Capture", NULL, "VINN" },
36
37 { "VOUTN", NULL, "Playback" },
38 { "VOUTP", NULL, "Playback" },
39};
40
26static struct snd_soc_dai_driver ad73311_dai = { 41static struct snd_soc_dai_driver ad73311_dai = {
27 .name = "ad73311-hifi", 42 .name = "ad73311-hifi",
28 .playback = { 43 .playback = {
@@ -39,7 +54,12 @@ static struct snd_soc_dai_driver ad73311_dai = {
39 .formats = SNDRV_PCM_FMTBIT_S16_LE, }, 54 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
40}; 55};
41 56
42static struct snd_soc_codec_driver soc_codec_dev_ad73311; 57static struct snd_soc_codec_driver soc_codec_dev_ad73311 = {
58 .dapm_widgets = ad73311_dapm_widgets,
59 .num_dapm_widgets = ARRAY_SIZE(ad73311_dapm_widgets),
60 .dapm_routes = ad73311_dapm_routes,
61 .num_dapm_routes = ARRAY_SIZE(ad73311_dapm_routes),
62};
43 63
44static int ad73311_probe(struct platform_device *pdev) 64static int ad73311_probe(struct platform_device *pdev)
45{ 65{
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index d1124a5b3471..ebff1128be59 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -91,7 +91,7 @@
91#define ADAU1701_OSCIPOW_OPD 0x04 91#define ADAU1701_OSCIPOW_OPD 0x04
92#define ADAU1701_DACSET_DACINIT 1 92#define ADAU1701_DACSET_DACINIT 1
93 93
94#define ADAU1707_CLKDIV_UNSET (-1UL) 94#define ADAU1707_CLKDIV_UNSET (-1U)
95 95
96#define ADAU1701_FIRMWARE "adau1701.bin" 96#define ADAU1701_FIRMWARE "adau1701.bin"
97 97
@@ -247,21 +247,21 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
247 gpio_is_valid(adau1701->gpio_pll_mode[1])) { 247 gpio_is_valid(adau1701->gpio_pll_mode[1])) {
248 switch (clkdiv) { 248 switch (clkdiv) {
249 case 64: 249 case 64:
250 gpio_set_value(adau1701->gpio_pll_mode[0], 0); 250 gpio_set_value_cansleep(adau1701->gpio_pll_mode[0], 0);
251 gpio_set_value(adau1701->gpio_pll_mode[1], 0); 251 gpio_set_value_cansleep(adau1701->gpio_pll_mode[1], 0);
252 break; 252 break;
253 case 256: 253 case 256:
254 gpio_set_value(adau1701->gpio_pll_mode[0], 0); 254 gpio_set_value_cansleep(adau1701->gpio_pll_mode[0], 0);
255 gpio_set_value(adau1701->gpio_pll_mode[1], 1); 255 gpio_set_value_cansleep(adau1701->gpio_pll_mode[1], 1);
256 break; 256 break;
257 case 384: 257 case 384:
258 gpio_set_value(adau1701->gpio_pll_mode[0], 1); 258 gpio_set_value_cansleep(adau1701->gpio_pll_mode[0], 1);
259 gpio_set_value(adau1701->gpio_pll_mode[1], 0); 259 gpio_set_value_cansleep(adau1701->gpio_pll_mode[1], 0);
260 break; 260 break;
261 case 0: /* fallback */ 261 case 0: /* fallback */
262 case 512: 262 case 512:
263 gpio_set_value(adau1701->gpio_pll_mode[0], 1); 263 gpio_set_value_cansleep(adau1701->gpio_pll_mode[0], 1);
264 gpio_set_value(adau1701->gpio_pll_mode[1], 1); 264 gpio_set_value_cansleep(adau1701->gpio_pll_mode[1], 1);
265 break; 265 break;
266 } 266 }
267 } 267 }
@@ -269,10 +269,10 @@ static int adau1701_reset(struct snd_soc_codec *codec, unsigned int clkdiv)
269 adau1701->pll_clkdiv = clkdiv; 269 adau1701->pll_clkdiv = clkdiv;
270 270
271 if (gpio_is_valid(adau1701->gpio_nreset)) { 271 if (gpio_is_valid(adau1701->gpio_nreset)) {
272 gpio_set_value(adau1701->gpio_nreset, 0); 272 gpio_set_value_cansleep(adau1701->gpio_nreset, 0);
273 /* minimum reset time is 20ns */ 273 /* minimum reset time is 20ns */
274 udelay(1); 274 udelay(1);
275 gpio_set_value(adau1701->gpio_nreset, 1); 275 gpio_set_value_cansleep(adau1701->gpio_nreset, 1);
276 /* power-up time may be as long as 85ms */ 276 /* power-up time may be as long as 85ms */
277 mdelay(85); 277 mdelay(85);
278 } 278 }
@@ -734,7 +734,10 @@ static int adau1701_i2c_remove(struct i2c_client *client)
734} 734}
735 735
736static const struct i2c_device_id adau1701_i2c_id[] = { 736static const struct i2c_device_id adau1701_i2c_id[] = {
737 { "adau1401", 0 },
738 { "adau1401a", 0 },
737 { "adau1701", 0 }, 739 { "adau1701", 0 },
740 { "adau1702", 0 },
738 { } 741 { }
739}; 742};
740MODULE_DEVICE_TABLE(i2c, adau1701_i2c_id); 743MODULE_DEVICE_TABLE(i2c, adau1701_i2c_id);
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index 3c839cc4e00e..15b012d0f226 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -868,6 +868,12 @@ static int adav80x_bus_remove(struct device *dev)
868} 868}
869 869
870#if defined(CONFIG_SPI_MASTER) 870#if defined(CONFIG_SPI_MASTER)
871static const struct spi_device_id adav80x_spi_id[] = {
872 { "adav801", 0 },
873 { }
874};
875MODULE_DEVICE_TABLE(spi, adav80x_spi_id);
876
871static int adav80x_spi_probe(struct spi_device *spi) 877static int adav80x_spi_probe(struct spi_device *spi)
872{ 878{
873 return adav80x_bus_probe(&spi->dev, SND_SOC_SPI); 879 return adav80x_bus_probe(&spi->dev, SND_SOC_SPI);
@@ -885,15 +891,16 @@ static struct spi_driver adav80x_spi_driver = {
885 }, 891 },
886 .probe = adav80x_spi_probe, 892 .probe = adav80x_spi_probe,
887 .remove = adav80x_spi_remove, 893 .remove = adav80x_spi_remove,
894 .id_table = adav80x_spi_id,
888}; 895};
889#endif 896#endif
890 897
891#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 898#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
892static const struct i2c_device_id adav80x_id[] = { 899static const struct i2c_device_id adav80x_i2c_id[] = {
893 { "adav803", 0 }, 900 { "adav803", 0 },
894 { } 901 { }
895}; 902};
896MODULE_DEVICE_TABLE(i2c, adav80x_id); 903MODULE_DEVICE_TABLE(i2c, adav80x_i2c_id);
897 904
898static int adav80x_i2c_probe(struct i2c_client *client, 905static int adav80x_i2c_probe(struct i2c_client *client,
899 const struct i2c_device_id *id) 906 const struct i2c_device_id *id)
@@ -913,7 +920,7 @@ static struct i2c_driver adav80x_i2c_driver = {
913 }, 920 },
914 .probe = adav80x_i2c_probe, 921 .probe = adav80x_i2c_probe,
915 .remove = adav80x_i2c_remove, 922 .remove = adav80x_i2c_remove,
916 .id_table = adav80x_id, 923 .id_table = adav80x_i2c_id,
917}; 924};
918#endif 925#endif
919 926
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c
index 506d474c4d22..8f388edff586 100644
--- a/sound/soc/codecs/ads117x.c
+++ b/sound/soc/codecs/ads117x.c
@@ -23,6 +23,28 @@
23#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000) 23#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000)
24#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) 24#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
25 25
26static const struct snd_soc_dapm_widget ads117x_dapm_widgets[] = {
27SND_SOC_DAPM_INPUT("Input1"),
28SND_SOC_DAPM_INPUT("Input2"),
29SND_SOC_DAPM_INPUT("Input3"),
30SND_SOC_DAPM_INPUT("Input4"),
31SND_SOC_DAPM_INPUT("Input5"),
32SND_SOC_DAPM_INPUT("Input6"),
33SND_SOC_DAPM_INPUT("Input7"),
34SND_SOC_DAPM_INPUT("Input8"),
35};
36
37static const struct snd_soc_dapm_route ads117x_dapm_routes[] = {
38 { "Capture", NULL, "Input1" },
39 { "Capture", NULL, "Input2" },
40 { "Capture", NULL, "Input3" },
41 { "Capture", NULL, "Input4" },
42 { "Capture", NULL, "Input5" },
43 { "Capture", NULL, "Input6" },
44 { "Capture", NULL, "Input7" },
45 { "Capture", NULL, "Input8" },
46};
47
26static struct snd_soc_dai_driver ads117x_dai = { 48static struct snd_soc_dai_driver ads117x_dai = {
27/* ADC */ 49/* ADC */
28 .name = "ads117x-hifi", 50 .name = "ads117x-hifi",
@@ -34,7 +56,12 @@ static struct snd_soc_dai_driver ads117x_dai = {
34 .formats = ADS117X_FORMATS,}, 56 .formats = ADS117X_FORMATS,},
35}; 57};
36 58
37static struct snd_soc_codec_driver soc_codec_dev_ads117x; 59static struct snd_soc_codec_driver soc_codec_dev_ads117x = {
60 .dapm_widgets = ads117x_dapm_widgets,
61 .num_dapm_widgets = ARRAY_SIZE(ads117x_dapm_widgets),
62 .dapm_routes = ads117x_dapm_routes,
63 .num_dapm_routes = ARRAY_SIZE(ads117x_dapm_routes),
64};
38 65
39static int ads117x_probe(struct platform_device *pdev) 66static int ads117x_probe(struct platform_device *pdev)
40{ 67{
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index c7cfdf957e4d..71059c07ae7b 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -51,6 +51,17 @@ struct ak4104_private {
51 struct regmap *regmap; 51 struct regmap *regmap;
52}; 52};
53 53
54static const struct snd_soc_dapm_widget ak4104_dapm_widgets[] = {
55SND_SOC_DAPM_PGA("TXE", AK4104_REG_TX, AK4104_TX_TXE, 0, NULL, 0),
56
57SND_SOC_DAPM_OUTPUT("TX"),
58};
59
60static const struct snd_soc_dapm_route ak4104_dapm_routes[] = {
61 { "TXE", NULL, "Playback" },
62 { "TX", NULL, "TXE" },
63};
64
54static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai, 65static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai,
55 unsigned int format) 66 unsigned int format)
56{ 67{
@@ -138,29 +149,11 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
138 if (ret < 0) 149 if (ret < 0)
139 return ret; 150 return ret;
140 151
141 /* enable transmitter */
142 ret = regmap_update_bits(ak4104->regmap, AK4104_REG_TX,
143 AK4104_TX_TXE, AK4104_TX_TXE);
144 if (ret < 0)
145 return ret;
146
147 return 0; 152 return 0;
148} 153}
149 154
150static int ak4104_hw_free(struct snd_pcm_substream *substream,
151 struct snd_soc_dai *dai)
152{
153 struct snd_soc_codec *codec = dai->codec;
154 struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec);
155
156 /* disable transmitter */
157 return regmap_update_bits(ak4104->regmap, AK4104_REG_TX,
158 AK4104_TX_TXE, 0);
159}
160
161static const struct snd_soc_dai_ops ak4101_dai_ops = { 155static const struct snd_soc_dai_ops ak4101_dai_ops = {
162 .hw_params = ak4104_hw_params, 156 .hw_params = ak4104_hw_params,
163 .hw_free = ak4104_hw_free,
164 .set_fmt = ak4104_set_dai_fmt, 157 .set_fmt = ak4104_set_dai_fmt,
165}; 158};
166 159
@@ -214,6 +207,11 @@ static int ak4104_remove(struct snd_soc_codec *codec)
214static struct snd_soc_codec_driver soc_codec_device_ak4104 = { 207static struct snd_soc_codec_driver soc_codec_device_ak4104 = {
215 .probe = ak4104_probe, 208 .probe = ak4104_probe,
216 .remove = ak4104_remove, 209 .remove = ak4104_remove,
210
211 .dapm_widgets = ak4104_dapm_widgets,
212 .num_dapm_widgets = ARRAY_SIZE(ak4104_dapm_widgets),
213 .dapm_routes = ak4104_dapm_routes,
214 .num_dapm_routes = ARRAY_SIZE(ak4104_dapm_routes),
217}; 215};
218 216
219static const struct regmap_config ak4104_regmap = { 217static const struct regmap_config ak4104_regmap = {
diff --git a/sound/soc/codecs/ak4554.c b/sound/soc/codecs/ak4554.c
new file mode 100644
index 000000000000..79e9555766c0
--- /dev/null
+++ b/sound/soc/codecs/ak4554.c
@@ -0,0 +1,106 @@
1/*
2 * ak4554.c
3 *
4 * Copyright (C) 2013 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <sound/soc.h>
14
15/*
16 * ak4554 is very simple DA/AD converter which has no setting register.
17 *
18 * CAUTION
19 *
20 * ak4554 playback format is SND_SOC_DAIFMT_RIGHT_J,
21 * and, capture format is SND_SOC_DAIFMT_LEFT_J
22 * on same bit clock, LR clock.
23 * But, this driver doesn't have snd_soc_dai_ops :: set_fmt
24 *
25 * CPU/Codec DAI image
26 *
27 * CPU-DAI1 (plaback only fmt = RIGHT_J) --+-- ak4554
28 * |
29 * CPU-DAI2 (capture only fmt = LEFT_J) ---+
30 */
31
32static const struct snd_soc_dapm_widget ak4554_dapm_widgets[] = {
33SND_SOC_DAPM_INPUT("AINL"),
34SND_SOC_DAPM_INPUT("AINR"),
35
36SND_SOC_DAPM_OUTPUT("AOUTL"),
37SND_SOC_DAPM_OUTPUT("AOUTR"),
38};
39
40static const struct snd_soc_dapm_route ak4554_dapm_routes[] = {
41 { "Capture", NULL, "AINL" },
42 { "Capture", NULL, "AINR" },
43
44 { "AOUTL", NULL, "Playback" },
45 { "AOUTR", NULL, "Playback" },
46};
47
48static struct snd_soc_dai_driver ak4554_dai = {
49 .name = "ak4554-hifi",
50 .playback = {
51 .stream_name = "Playback",
52 .channels_min = 2,
53 .channels_max = 2,
54 .rates = SNDRV_PCM_RATE_8000_48000,
55 .formats = SNDRV_PCM_FMTBIT_S16_LE,
56 },
57 .capture = {
58 .stream_name = "Capture",
59 .channels_min = 2,
60 .channels_max = 2,
61 .rates = SNDRV_PCM_RATE_8000_48000,
62 .formats = SNDRV_PCM_FMTBIT_S16_LE,
63 },
64 .symmetric_rates = 1,
65};
66
67static struct snd_soc_codec_driver soc_codec_dev_ak4554 = {
68 .dapm_widgets = ak4554_dapm_widgets,
69 .num_dapm_widgets = ARRAY_SIZE(ak4554_dapm_widgets),
70 .dapm_routes = ak4554_dapm_routes,
71 .num_dapm_routes = ARRAY_SIZE(ak4554_dapm_routes),
72};
73
74static int ak4554_soc_probe(struct platform_device *pdev)
75{
76 return snd_soc_register_codec(&pdev->dev,
77 &soc_codec_dev_ak4554,
78 &ak4554_dai, 1);
79}
80
81static int ak4554_soc_remove(struct platform_device *pdev)
82{
83 snd_soc_unregister_codec(&pdev->dev);
84 return 0;
85}
86
87static struct of_device_id ak4554_of_match[] = {
88 { .compatible = "asahi-kasei,ak4554" },
89 {},
90};
91MODULE_DEVICE_TABLE(of, ak4554_of_match);
92
93static struct platform_driver ak4554_driver = {
94 .driver = {
95 .name = "ak4554-adc-dac",
96 .owner = THIS_MODULE,
97 .of_match_table = ak4554_of_match,
98 },
99 .probe = ak4554_soc_probe,
100 .remove = ak4554_soc_remove,
101};
102module_platform_driver(ak4554_driver);
103
104MODULE_LICENSE("GPL");
105MODULE_DESCRIPTION("SoC AK4554 driver");
106MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/sound/soc/codecs/ak5386.c b/sound/soc/codecs/ak5386.c
index 1f303983ae02..72e953b2cb41 100644
--- a/sound/soc/codecs/ak5386.c
+++ b/sound/soc/codecs/ak5386.c
@@ -22,7 +22,22 @@ struct ak5386_priv {
22 int reset_gpio; 22 int reset_gpio;
23}; 23};
24 24
25static struct snd_soc_codec_driver soc_codec_ak5386; 25static const struct snd_soc_dapm_widget ak5386_dapm_widgets[] = {
26SND_SOC_DAPM_INPUT("AINL"),
27SND_SOC_DAPM_INPUT("AINR"),
28};
29
30static const struct snd_soc_dapm_route ak5386_dapm_routes[] = {
31 { "Capture", NULL, "AINL" },
32 { "Capture", NULL, "AINR" },
33};
34
35static struct snd_soc_codec_driver soc_codec_ak5386 = {
36 .dapm_widgets = ak5386_dapm_widgets,
37 .num_dapm_widgets = ARRAY_SIZE(ak5386_dapm_widgets),
38 .dapm_routes = ak5386_dapm_routes,
39 .num_dapm_routes = ARRAY_SIZE(ak5386_dapm_routes),
40};
26 41
27static int ak5386_set_dai_fmt(struct snd_soc_dai *codec_dai, 42static int ak5386_set_dai_fmt(struct snd_soc_dai *codec_dai,
28 unsigned int format) 43 unsigned int format)
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index de625813c0e6..657808ba1418 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -19,6 +19,7 @@
19#include <sound/tlv.h> 19#include <sound/tlv.h>
20 20
21#include <linux/mfd/arizona/core.h> 21#include <linux/mfd/arizona/core.h>
22#include <linux/mfd/arizona/gpio.h>
22#include <linux/mfd/arizona/registers.h> 23#include <linux/mfd/arizona/registers.h>
23 24
24#include "arizona.h" 25#include "arizona.h"
@@ -199,9 +200,16 @@ int arizona_init_spk(struct snd_soc_codec *codec)
199 if (ret != 0) 200 if (ret != 0)
200 return ret; 201 return ret;
201 202
202 ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkr, 1); 203 switch (arizona->type) {
203 if (ret != 0) 204 case WM8997:
204 return ret; 205 break;
206 default:
207 ret = snd_soc_dapm_new_controls(&codec->dapm,
208 &arizona_spkr, 1);
209 if (ret != 0)
210 return ret;
211 break;
212 }
205 213
206 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN_WARN, 214 ret = arizona_request_irq(arizona, ARIZONA_IRQ_SPK_SHUTDOWN_WARN,
207 "Thermal warning", arizona_thermal_warn, 215 "Thermal warning", arizona_thermal_warn,
@@ -223,6 +231,41 @@ int arizona_init_spk(struct snd_soc_codec *codec)
223} 231}
224EXPORT_SYMBOL_GPL(arizona_init_spk); 232EXPORT_SYMBOL_GPL(arizona_init_spk);
225 233
234int arizona_init_gpio(struct snd_soc_codec *codec)
235{
236 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
237 struct arizona *arizona = priv->arizona;
238 int i;
239
240 switch (arizona->type) {
241 case WM5110:
242 snd_soc_dapm_disable_pin(&codec->dapm, "DRC2 Signal Activity");
243 break;
244 default:
245 break;
246 }
247
248 snd_soc_dapm_disable_pin(&codec->dapm, "DRC1 Signal Activity");
249
250 for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
251 switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) {
252 case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT:
253 snd_soc_dapm_enable_pin(&codec->dapm,
254 "DRC1 Signal Activity");
255 break;
256 case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT:
257 snd_soc_dapm_enable_pin(&codec->dapm,
258 "DRC2 Signal Activity");
259 break;
260 default:
261 break;
262 }
263 }
264
265 return 0;
266}
267EXPORT_SYMBOL_GPL(arizona_init_gpio);
268
226const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = { 269const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
227 "None", 270 "None",
228 "Tone Generator 1", 271 "Tone Generator 1",
@@ -517,6 +560,26 @@ const struct soc_enum arizona_ng_hold =
517 4, arizona_ng_hold_text); 560 4, arizona_ng_hold_text);
518EXPORT_SYMBOL_GPL(arizona_ng_hold); 561EXPORT_SYMBOL_GPL(arizona_ng_hold);
519 562
563static const char * const arizona_in_dmic_osr_text[] = {
564 "1.536MHz", "3.072MHz", "6.144MHz",
565};
566
567const struct soc_enum arizona_in_dmic_osr[] = {
568 SOC_ENUM_SINGLE(ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT,
569 ARRAY_SIZE(arizona_in_dmic_osr_text),
570 arizona_in_dmic_osr_text),
571 SOC_ENUM_SINGLE(ARIZONA_IN2L_CONTROL, ARIZONA_IN2_OSR_SHIFT,
572 ARRAY_SIZE(arizona_in_dmic_osr_text),
573 arizona_in_dmic_osr_text),
574 SOC_ENUM_SINGLE(ARIZONA_IN3L_CONTROL, ARIZONA_IN3_OSR_SHIFT,
575 ARRAY_SIZE(arizona_in_dmic_osr_text),
576 arizona_in_dmic_osr_text),
577 SOC_ENUM_SINGLE(ARIZONA_IN4L_CONTROL, ARIZONA_IN4_OSR_SHIFT,
578 ARRAY_SIZE(arizona_in_dmic_osr_text),
579 arizona_in_dmic_osr_text),
580};
581EXPORT_SYMBOL_GPL(arizona_in_dmic_osr);
582
520static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena) 583static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
521{ 584{
522 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); 585 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index b60b08ccc1d0..9e81b6392692 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -150,7 +150,8 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
150 ARIZONA_MUX(name_str " Aux 5", &name##_aux5_mux), \ 150 ARIZONA_MUX(name_str " Aux 5", &name##_aux5_mux), \
151 ARIZONA_MUX(name_str " Aux 6", &name##_aux6_mux) 151 ARIZONA_MUX(name_str " Aux 6", &name##_aux6_mux)
152 152
153#define ARIZONA_MUX_ROUTES(name) \ 153#define ARIZONA_MUX_ROUTES(widget, name) \
154 { widget, NULL, name " Input" }, \
154 ARIZONA_MIXER_INPUT_ROUTES(name " Input") 155 ARIZONA_MIXER_INPUT_ROUTES(name " Input")
155 156
156#define ARIZONA_MIXER_ROUTES(widget, name) \ 157#define ARIZONA_MIXER_ROUTES(widget, name) \
@@ -198,6 +199,7 @@ extern const struct soc_enum arizona_lhpf3_mode;
198extern const struct soc_enum arizona_lhpf4_mode; 199extern const struct soc_enum arizona_lhpf4_mode;
199 200
200extern const struct soc_enum arizona_ng_hold; 201extern const struct soc_enum arizona_ng_hold;
202extern const struct soc_enum arizona_in_dmic_osr[];
201 203
202extern int arizona_in_ev(struct snd_soc_dapm_widget *w, 204extern int arizona_in_ev(struct snd_soc_dapm_widget *w,
203 struct snd_kcontrol *kcontrol, 205 struct snd_kcontrol *kcontrol,
@@ -242,6 +244,7 @@ extern int arizona_set_fll(struct arizona_fll *fll, int source,
242 unsigned int Fref, unsigned int Fout); 244 unsigned int Fref, unsigned int Fout);
243 245
244extern int arizona_init_spk(struct snd_soc_codec *codec); 246extern int arizona_init_spk(struct snd_soc_codec *codec);
247extern int arizona_init_gpio(struct snd_soc_codec *codec);
245 248
246extern int arizona_init_dai(struct arizona_priv *priv, int dai); 249extern int arizona_init_dai(struct arizona_priv *priv, int dai);
247 250
diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c
index a081d9fcb166..c4cf0699e77f 100644
--- a/sound/soc/codecs/bt-sco.c
+++ b/sound/soc/codecs/bt-sco.c
@@ -15,15 +15,27 @@
15 15
16#include <sound/soc.h> 16#include <sound/soc.h>
17 17
18static const struct snd_soc_dapm_widget bt_sco_widgets[] = {
19 SND_SOC_DAPM_INPUT("RX"),
20 SND_SOC_DAPM_OUTPUT("TX"),
21};
22
23static const struct snd_soc_dapm_route bt_sco_routes[] = {
24 { "Capture", NULL, "RX" },
25 { "TX", NULL, "Playback" },
26};
27
18static struct snd_soc_dai_driver bt_sco_dai = { 28static struct snd_soc_dai_driver bt_sco_dai = {
19 .name = "bt-sco-pcm", 29 .name = "bt-sco-pcm",
20 .playback = { 30 .playback = {
31 .stream_name = "Playback",
21 .channels_min = 1, 32 .channels_min = 1,
22 .channels_max = 1, 33 .channels_max = 1,
23 .rates = SNDRV_PCM_RATE_8000, 34 .rates = SNDRV_PCM_RATE_8000,
24 .formats = SNDRV_PCM_FMTBIT_S16_LE, 35 .formats = SNDRV_PCM_FMTBIT_S16_LE,
25 }, 36 },
26 .capture = { 37 .capture = {
38 .stream_name = "Capture",
27 .channels_min = 1, 39 .channels_min = 1,
28 .channels_max = 1, 40 .channels_max = 1,
29 .rates = SNDRV_PCM_RATE_8000, 41 .rates = SNDRV_PCM_RATE_8000,
@@ -31,7 +43,12 @@ static struct snd_soc_dai_driver bt_sco_dai = {
31 }, 43 },
32}; 44};
33 45
34static struct snd_soc_codec_driver soc_codec_dev_bt_sco; 46static struct snd_soc_codec_driver soc_codec_dev_bt_sco = {
47 .dapm_widgets = bt_sco_widgets,
48 .num_dapm_widgets = ARRAY_SIZE(bt_sco_widgets),
49 .dapm_routes = bt_sco_routes,
50 .num_dapm_routes = ARRAY_SIZE(bt_sco_routes),
51};
35 52
36static int bt_sco_probe(struct platform_device *pdev) 53static int bt_sco_probe(struct platform_device *pdev)
37{ 54{
@@ -50,6 +67,9 @@ static struct platform_device_id bt_sco_driver_ids[] = {
50 { 67 {
51 .name = "dfbmcs320", 68 .name = "dfbmcs320",
52 }, 69 },
70 {
71 .name = "bt-sco",
72 },
53 {}, 73 {},
54}; 74};
55MODULE_DEVICE_TABLE(platform, bt_sco_driver_ids); 75MODULE_DEVICE_TABLE(platform, bt_sco_driver_ids);
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 8e4779812b96..83c835d9fd88 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -139,6 +139,22 @@ struct cs4270_private {
139 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; 139 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
140}; 140};
141 141
142static const struct snd_soc_dapm_widget cs4270_dapm_widgets[] = {
143SND_SOC_DAPM_INPUT("AINL"),
144SND_SOC_DAPM_INPUT("AINR"),
145
146SND_SOC_DAPM_OUTPUT("AOUTL"),
147SND_SOC_DAPM_OUTPUT("AOUTR"),
148};
149
150static const struct snd_soc_dapm_route cs4270_dapm_routes[] = {
151 { "Capture", NULL, "AINA" },
152 { "Capture", NULL, "AINB" },
153
154 { "AOUTA", NULL, "Playback" },
155 { "AOUTB", NULL, "Playback" },
156};
157
142/** 158/**
143 * struct cs4270_mode_ratios - clock ratio tables 159 * struct cs4270_mode_ratios - clock ratio tables
144 * @ratio: the ratio of MCLK to the sample rate 160 * @ratio: the ratio of MCLK to the sample rate
@@ -612,6 +628,10 @@ static const struct snd_soc_codec_driver soc_codec_device_cs4270 = {
612 628
613 .controls = cs4270_snd_controls, 629 .controls = cs4270_snd_controls,
614 .num_controls = ARRAY_SIZE(cs4270_snd_controls), 630 .num_controls = ARRAY_SIZE(cs4270_snd_controls),
631 .dapm_widgets = cs4270_dapm_widgets,
632 .num_dapm_widgets = ARRAY_SIZE(cs4270_dapm_widgets),
633 .dapm_routes = cs4270_dapm_routes,
634 .num_dapm_routes = ARRAY_SIZE(cs4270_dapm_routes),
615}; 635};
616 636
617/* 637/*
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index 03036b326732..a20f1bb8f071 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -173,6 +173,26 @@ struct cs4271_private {
173 bool enable_soft_reset; 173 bool enable_soft_reset;
174}; 174};
175 175
176static const struct snd_soc_dapm_widget cs4271_dapm_widgets[] = {
177SND_SOC_DAPM_INPUT("AINA"),
178SND_SOC_DAPM_INPUT("AINB"),
179
180SND_SOC_DAPM_OUTPUT("AOUTA+"),
181SND_SOC_DAPM_OUTPUT("AOUTA-"),
182SND_SOC_DAPM_OUTPUT("AOUTB+"),
183SND_SOC_DAPM_OUTPUT("AOUTB-"),
184};
185
186static const struct snd_soc_dapm_route cs4271_dapm_routes[] = {
187 { "Capture", NULL, "AINA" },
188 { "Capture", NULL, "AINB" },
189
190 { "AOUTA+", NULL, "Playback" },
191 { "AOUTA-", NULL, "Playback" },
192 { "AOUTB+", NULL, "Playback" },
193 { "AOUTB-", NULL, "Playback" },
194};
195
176/* 196/*
177 * @freq is the desired MCLK rate 197 * @freq is the desired MCLK rate
178 * MCLK rate should (c) be the sample rate, multiplied by one of the 198 * MCLK rate should (c) be the sample rate, multiplied by one of the
@@ -576,8 +596,7 @@ static int cs4271_probe(struct snd_soc_codec *codec)
576 CS4271_MODE2_MUTECAEQUB, 596 CS4271_MODE2_MUTECAEQUB,
577 CS4271_MODE2_MUTECAEQUB); 597 CS4271_MODE2_MUTECAEQUB);
578 598
579 return snd_soc_add_codec_controls(codec, cs4271_snd_controls, 599 return 0;
580 ARRAY_SIZE(cs4271_snd_controls));
581} 600}
582 601
583static int cs4271_remove(struct snd_soc_codec *codec) 602static int cs4271_remove(struct snd_soc_codec *codec)
@@ -596,6 +615,13 @@ static struct snd_soc_codec_driver soc_codec_dev_cs4271 = {
596 .remove = cs4271_remove, 615 .remove = cs4271_remove,
597 .suspend = cs4271_soc_suspend, 616 .suspend = cs4271_soc_suspend,
598 .resume = cs4271_soc_resume, 617 .resume = cs4271_soc_resume,
618
619 .controls = cs4271_snd_controls,
620 .num_controls = ARRAY_SIZE(cs4271_snd_controls),
621 .dapm_widgets = cs4271_dapm_widgets,
622 .num_dapm_widgets = ARRAY_SIZE(cs4271_dapm_widgets),
623 .dapm_routes = cs4271_dapm_routes,
624 .num_dapm_routes = ARRAY_SIZE(cs4271_dapm_routes),
599}; 625};
600 626
601#if defined(CONFIG_SPI_MASTER) 627#if defined(CONFIG_SPI_MASTER)
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
index 66967ba6f757..b2090b2a5e2d 100644
--- a/sound/soc/codecs/dmic.c
+++ b/sound/soc/codecs/dmic.c
@@ -50,20 +50,11 @@ static const struct snd_soc_dapm_route intercon[] = {
50 {"DMIC AIF", NULL, "DMic"}, 50 {"DMIC AIF", NULL, "DMic"},
51}; 51};
52 52
53static int dmic_probe(struct snd_soc_codec *codec)
54{
55 struct snd_soc_dapm_context *dapm = &codec->dapm;
56
57 snd_soc_dapm_new_controls(dapm, dmic_dapm_widgets,
58 ARRAY_SIZE(dmic_dapm_widgets));
59 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
60 snd_soc_dapm_new_widgets(dapm);
61
62 return 0;
63}
64
65static struct snd_soc_codec_driver soc_dmic = { 53static struct snd_soc_codec_driver soc_dmic = {
66 .probe = dmic_probe, 54 .dapm_widgets = dmic_dapm_widgets,
55 .num_dapm_widgets = ARRAY_SIZE(dmic_dapm_widgets),
56 .dapm_routes = intercon,
57 .num_dapm_routes = ARRAY_SIZE(intercon),
67}; 58};
68 59
69static int dmic_dev_probe(struct platform_device *pdev) 60static int dmic_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/hdmi.c b/sound/soc/codecs/hdmi.c
index 2bcae2b40c92..68342b121c96 100644
--- a/sound/soc/codecs/hdmi.c
+++ b/sound/soc/codecs/hdmi.c
@@ -23,11 +23,20 @@
23 23
24#define DRV_NAME "hdmi-audio-codec" 24#define DRV_NAME "hdmi-audio-codec"
25 25
26static struct snd_soc_codec_driver hdmi_codec; 26static const struct snd_soc_dapm_widget hdmi_widgets[] = {
27 SND_SOC_DAPM_INPUT("RX"),
28 SND_SOC_DAPM_OUTPUT("TX"),
29};
30
31static const struct snd_soc_dapm_route hdmi_routes[] = {
32 { "Capture", NULL, "RX" },
33 { "TX", NULL, "Playback" },
34};
27 35
28static struct snd_soc_dai_driver hdmi_codec_dai = { 36static struct snd_soc_dai_driver hdmi_codec_dai = {
29 .name = "hdmi-hifi", 37 .name = "hdmi-hifi",
30 .playback = { 38 .playback = {
39 .stream_name = "Playback",
31 .channels_min = 2, 40 .channels_min = 2,
32 .channels_max = 8, 41 .channels_max = 8,
33 .rates = SNDRV_PCM_RATE_32000 | 42 .rates = SNDRV_PCM_RATE_32000 |
@@ -37,6 +46,25 @@ static struct snd_soc_dai_driver hdmi_codec_dai = {
37 .formats = SNDRV_PCM_FMTBIT_S16_LE | 46 .formats = SNDRV_PCM_FMTBIT_S16_LE |
38 SNDRV_PCM_FMTBIT_S24_LE, 47 SNDRV_PCM_FMTBIT_S24_LE,
39 }, 48 },
49 .capture = {
50 .stream_name = "Capture",
51 .channels_min = 2,
52 .channels_max = 2,
53 .rates = SNDRV_PCM_RATE_32000 |
54 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
55 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
56 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
57 .formats = SNDRV_PCM_FMTBIT_S16_LE |
58 SNDRV_PCM_FMTBIT_S24_LE,
59 },
60
61};
62
63static struct snd_soc_codec_driver hdmi_codec = {
64 .dapm_widgets = hdmi_widgets,
65 .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
66 .dapm_routes = hdmi_routes,
67 .num_dapm_routes = ARRAY_SIZE(hdmi_routes),
40}; 68};
41 69
42static int hdmi_codec_probe(struct platform_device *pdev) 70static int hdmi_codec_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
index 9f9f59573f72..0e5743ea79df 100644
--- a/sound/soc/codecs/lm4857.c
+++ b/sound/soc/codecs/lm4857.c
@@ -16,6 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/regmap.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
20 21
21#include <sound/core.h> 22#include <sound/core.h>
@@ -23,12 +24,15 @@
23#include <sound/tlv.h> 24#include <sound/tlv.h>
24 25
25struct lm4857 { 26struct lm4857 {
26 struct i2c_client *i2c; 27 struct regmap *regmap;
27 uint8_t mode; 28 uint8_t mode;
28}; 29};
29 30
30static const uint8_t lm4857_default_regs[] = { 31static const struct reg_default lm4857_default_regs[] = {
31 0x00, 0x00, 0x00, 0x00, 32 { 0x0, 0x00 },
33 { 0x1, 0x00 },
34 { 0x2, 0x00 },
35 { 0x3, 0x00 },
32}; 36};
33 37
34/* The register offsets in the cache array */ 38/* The register offsets in the cache array */
@@ -42,39 +46,6 @@ static const uint8_t lm4857_default_regs[] = {
42#define LM4857_WAKEUP 5 46#define LM4857_WAKEUP 5
43#define LM4857_EPGAIN 4 47#define LM4857_EPGAIN 4
44 48
45static int lm4857_write(struct snd_soc_codec *codec, unsigned int reg,
46 unsigned int value)
47{
48 uint8_t data;
49 int ret;
50
51 ret = snd_soc_cache_write(codec, reg, value);
52 if (ret < 0)
53 return ret;
54
55 data = (reg << 6) | value;
56 ret = i2c_master_send(codec->control_data, &data, 1);
57 if (ret != 1) {
58 dev_err(codec->dev, "Failed to write register: %d\n", ret);
59 return ret;
60 }
61
62 return 0;
63}
64
65static unsigned int lm4857_read(struct snd_soc_codec *codec,
66 unsigned int reg)
67{
68 unsigned int val;
69 int ret;
70
71 ret = snd_soc_cache_read(codec, reg, &val);
72 if (ret)
73 return -1;
74
75 return val;
76}
77
78static int lm4857_get_mode(struct snd_kcontrol *kcontrol, 49static int lm4857_get_mode(struct snd_kcontrol *kcontrol,
79 struct snd_ctl_elem_value *ucontrol) 50 struct snd_ctl_elem_value *ucontrol)
80{ 51{
@@ -96,7 +67,7 @@ static int lm4857_set_mode(struct snd_kcontrol *kcontrol,
96 lm4857->mode = value; 67 lm4857->mode = value;
97 68
98 if (codec->dapm.bias_level == SND_SOC_BIAS_ON) 69 if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
99 snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, value + 6); 70 regmap_update_bits(lm4857->regmap, LM4857_CTRL, 0x0F, value + 6);
100 71
101 return 1; 72 return 1;
102} 73}
@@ -108,10 +79,11 @@ static int lm4857_set_bias_level(struct snd_soc_codec *codec,
108 79
109 switch (level) { 80 switch (level) {
110 case SND_SOC_BIAS_ON: 81 case SND_SOC_BIAS_ON:
111 snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, lm4857->mode + 6); 82 regmap_update_bits(lm4857->regmap, LM4857_CTRL, 0x0F,
83 lm4857->mode + 6);
112 break; 84 break;
113 case SND_SOC_BIAS_STANDBY: 85 case SND_SOC_BIAS_STANDBY:
114 snd_soc_update_bits(codec, LM4857_CTRL, 0x0F, 0); 86 regmap_update_bits(lm4857->regmap, LM4857_CTRL, 0x0F, 0);
115 break; 87 break;
116 default: 88 default:
117 break; 89 break;
@@ -171,49 +143,32 @@ static const struct snd_soc_dapm_route lm4857_routes[] = {
171 {"EP", NULL, "IN"}, 143 {"EP", NULL, "IN"},
172}; 144};
173 145
174static int lm4857_probe(struct snd_soc_codec *codec) 146static struct snd_soc_codec_driver soc_codec_dev_lm4857 = {
175{ 147 .set_bias_level = lm4857_set_bias_level,
176 struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
177 struct snd_soc_dapm_context *dapm = &codec->dapm;
178 int ret;
179
180 codec->control_data = lm4857->i2c;
181
182 ret = snd_soc_add_codec_controls(codec, lm4857_controls,
183 ARRAY_SIZE(lm4857_controls));
184 if (ret)
185 return ret;
186
187 ret = snd_soc_dapm_new_controls(dapm, lm4857_dapm_widgets,
188 ARRAY_SIZE(lm4857_dapm_widgets));
189 if (ret)
190 return ret;
191 148
192 ret = snd_soc_dapm_add_routes(dapm, lm4857_routes, 149 .controls = lm4857_controls,
193 ARRAY_SIZE(lm4857_routes)); 150 .num_controls = ARRAY_SIZE(lm4857_controls),
194 if (ret) 151 .dapm_widgets = lm4857_dapm_widgets,
195 return ret; 152 .num_dapm_widgets = ARRAY_SIZE(lm4857_dapm_widgets),
153 .dapm_routes = lm4857_routes,
154 .num_dapm_routes = ARRAY_SIZE(lm4857_routes),
155};
196 156
197 snd_soc_dapm_new_widgets(dapm); 157static const struct regmap_config lm4857_regmap_config = {
158 .val_bits = 6,
159 .reg_bits = 2,
198 160
199 return 0; 161 .max_register = LM4857_CTRL,
200}
201 162
202static struct snd_soc_codec_driver soc_codec_dev_lm4857 = { 163 .cache_type = REGCACHE_FLAT,
203 .write = lm4857_write, 164 .reg_defaults = lm4857_default_regs,
204 .read = lm4857_read, 165 .num_reg_defaults = ARRAY_SIZE(lm4857_default_regs),
205 .probe = lm4857_probe,
206 .reg_cache_size = ARRAY_SIZE(lm4857_default_regs),
207 .reg_word_size = sizeof(uint8_t),
208 .reg_cache_default = lm4857_default_regs,
209 .set_bias_level = lm4857_set_bias_level,
210}; 166};
211 167
212static int lm4857_i2c_probe(struct i2c_client *i2c, 168static int lm4857_i2c_probe(struct i2c_client *i2c,
213 const struct i2c_device_id *id) 169 const struct i2c_device_id *id)
214{ 170{
215 struct lm4857 *lm4857; 171 struct lm4857 *lm4857;
216 int ret;
217 172
218 lm4857 = devm_kzalloc(&i2c->dev, sizeof(*lm4857), GFP_KERNEL); 173 lm4857 = devm_kzalloc(&i2c->dev, sizeof(*lm4857), GFP_KERNEL);
219 if (!lm4857) 174 if (!lm4857)
@@ -221,11 +176,11 @@ static int lm4857_i2c_probe(struct i2c_client *i2c,
221 176
222 i2c_set_clientdata(i2c, lm4857); 177 i2c_set_clientdata(i2c, lm4857);
223 178
224 lm4857->i2c = i2c; 179 lm4857->regmap = devm_regmap_init_i2c(i2c, &lm4857_regmap_config);
225 180 if (IS_ERR(lm4857->regmap))
226 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_lm4857, NULL, 0); 181 return PTR_ERR(lm4857->regmap);
227 182
228 return ret; 183 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_lm4857, NULL, 0);
229} 184}
230 185
231static int lm4857_i2c_remove(struct i2c_client *i2c) 186static int lm4857_i2c_remove(struct i2c_client *i2c)
diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c
index a6ac2313047d..31f91560e9f6 100644
--- a/sound/soc/codecs/max9768.c
+++ b/sound/soc/codecs/max9768.c
@@ -118,6 +118,18 @@ static const struct snd_kcontrol_new max9768_mute[] = {
118 SOC_SINGLE_BOOL_EXT("Playback Switch", 0, max9768_get_gpio, max9768_set_gpio), 118 SOC_SINGLE_BOOL_EXT("Playback Switch", 0, max9768_get_gpio, max9768_set_gpio),
119}; 119};
120 120
121static const struct snd_soc_dapm_widget max9768_dapm_widgets[] = {
122SND_SOC_DAPM_INPUT("IN"),
123
124SND_SOC_DAPM_OUTPUT("OUT+"),
125SND_SOC_DAPM_OUTPUT("OUT-"),
126};
127
128static const struct snd_soc_dapm_route max9768_dapm_routes[] = {
129 { "OUT+", NULL, "IN" },
130 { "OUT-", NULL, "IN" },
131};
132
121static int max9768_probe(struct snd_soc_codec *codec) 133static int max9768_probe(struct snd_soc_codec *codec)
122{ 134{
123 struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); 135 struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec);
@@ -148,6 +160,10 @@ static struct snd_soc_codec_driver max9768_codec_driver = {
148 .probe = max9768_probe, 160 .probe = max9768_probe,
149 .controls = max9768_volume, 161 .controls = max9768_volume,
150 .num_controls = ARRAY_SIZE(max9768_volume), 162 .num_controls = ARRAY_SIZE(max9768_volume),
163 .dapm_widgets = max9768_dapm_widgets,
164 .num_dapm_widgets = ARRAY_SIZE(max9768_dapm_widgets),
165 .dapm_routes = max9768_dapm_routes,
166 .num_dapm_routes = ARRAY_SIZE(max9768_dapm_routes),
151}; 167};
152 168
153static const struct regmap_config max9768_i2c_regmap_config = { 169static const struct regmap_config max9768_i2c_regmap_config = {
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index ad5313f98f28..0569a4c3ae00 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -2084,8 +2084,9 @@ static irqreturn_t max98090_interrupt(int irq, void *data)
2084 2084
2085 pm_wakeup_event(codec->dev, 100); 2085 pm_wakeup_event(codec->dev, 100);
2086 2086
2087 schedule_delayed_work(&max98090->jack_work, 2087 queue_delayed_work(system_power_efficient_wq,
2088 msecs_to_jiffies(100)); 2088 &max98090->jack_work,
2089 msecs_to_jiffies(100));
2089 } 2090 }
2090 2091
2091 if (active & M98090_DRCACT_MASK) 2092 if (active & M98090_DRCACT_MASK)
@@ -2132,8 +2133,9 @@ int max98090_mic_detect(struct snd_soc_codec *codec,
2132 snd_soc_jack_report(max98090->jack, 0, 2133 snd_soc_jack_report(max98090->jack, 0,
2133 SND_JACK_HEADSET | SND_JACK_BTN_0); 2134 SND_JACK_HEADSET | SND_JACK_BTN_0);
2134 2135
2135 schedule_delayed_work(&max98090->jack_work, 2136 queue_delayed_work(system_power_efficient_wq,
2136 msecs_to_jiffies(100)); 2137 &max98090->jack_work,
2138 msecs_to_jiffies(100));
2137 2139
2138 return 0; 2140 return 0;
2139} 2141}
diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c
index 6b6c74cd83e2..29549cdbf4c1 100644
--- a/sound/soc/codecs/max9877.c
+++ b/sound/soc/codecs/max9877.c
@@ -14,170 +14,21 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/i2c.h> 16#include <linux/i2c.h>
17#include <linux/regmap.h>
17#include <sound/soc.h> 18#include <sound/soc.h>
18#include <sound/tlv.h> 19#include <sound/tlv.h>
19 20
20#include "max9877.h" 21#include "max9877.h"
21 22
22static struct i2c_client *i2c; 23static struct regmap *regmap;
23 24
24static u8 max9877_regs[5] = { 0x40, 0x00, 0x00, 0x00, 0x49 }; 25static struct reg_default max9877_regs[] = {
25 26 { 0, 0x40 },
26static void max9877_write_regs(void) 27 { 1, 0x00 },
27{ 28 { 2, 0x00 },
28 unsigned int i; 29 { 3, 0x00 },
29 u8 data[6]; 30 { 4, 0x49 },
30 31};
31 data[0] = MAX9877_INPUT_MODE;
32 for (i = 0; i < ARRAY_SIZE(max9877_regs); i++)
33 data[i + 1] = max9877_regs[i];
34
35 if (i2c_master_send(i2c, data, 6) != 6)
36 dev_err(&i2c->dev, "i2c write failed\n");
37}
38
39static int max9877_get_reg(struct snd_kcontrol *kcontrol,
40 struct snd_ctl_elem_value *ucontrol)
41{
42 struct soc_mixer_control *mc =
43 (struct soc_mixer_control *)kcontrol->private_value;
44 unsigned int reg = mc->reg;
45 unsigned int shift = mc->shift;
46 unsigned int mask = mc->max;
47 unsigned int invert = mc->invert;
48
49 ucontrol->value.integer.value[0] = (max9877_regs[reg] >> shift) & mask;
50
51 if (invert)
52 ucontrol->value.integer.value[0] =
53 mask - ucontrol->value.integer.value[0];
54
55 return 0;
56}
57
58static int max9877_set_reg(struct snd_kcontrol *kcontrol,
59 struct snd_ctl_elem_value *ucontrol)
60{
61 struct soc_mixer_control *mc =
62 (struct soc_mixer_control *)kcontrol->private_value;
63 unsigned int reg = mc->reg;
64 unsigned int shift = mc->shift;
65 unsigned int mask = mc->max;
66 unsigned int invert = mc->invert;
67 unsigned int val = (ucontrol->value.integer.value[0] & mask);
68
69 if (invert)
70 val = mask - val;
71
72 if (((max9877_regs[reg] >> shift) & mask) == val)
73 return 0;
74
75 max9877_regs[reg] &= ~(mask << shift);
76 max9877_regs[reg] |= val << shift;
77 max9877_write_regs();
78
79 return 1;
80}
81
82static int max9877_get_2reg(struct snd_kcontrol *kcontrol,
83 struct snd_ctl_elem_value *ucontrol)
84{
85 struct soc_mixer_control *mc =
86 (struct soc_mixer_control *)kcontrol->private_value;
87 unsigned int reg = mc->reg;
88 unsigned int reg2 = mc->rreg;
89 unsigned int shift = mc->shift;
90 unsigned int mask = mc->max;
91
92 ucontrol->value.integer.value[0] = (max9877_regs[reg] >> shift) & mask;
93 ucontrol->value.integer.value[1] = (max9877_regs[reg2] >> shift) & mask;
94
95 return 0;
96}
97
98static int max9877_set_2reg(struct snd_kcontrol *kcontrol,
99 struct snd_ctl_elem_value *ucontrol)
100{
101 struct soc_mixer_control *mc =
102 (struct soc_mixer_control *)kcontrol->private_value;
103 unsigned int reg = mc->reg;
104 unsigned int reg2 = mc->rreg;
105 unsigned int shift = mc->shift;
106 unsigned int mask = mc->max;
107 unsigned int val = (ucontrol->value.integer.value[0] & mask);
108 unsigned int val2 = (ucontrol->value.integer.value[1] & mask);
109 unsigned int change = 0;
110
111 if (((max9877_regs[reg] >> shift) & mask) != val)
112 change = 1;
113
114 if (((max9877_regs[reg2] >> shift) & mask) != val2)
115 change = 1;
116
117 if (change) {
118 max9877_regs[reg] &= ~(mask << shift);
119 max9877_regs[reg] |= val << shift;
120 max9877_regs[reg2] &= ~(mask << shift);
121 max9877_regs[reg2] |= val2 << shift;
122 max9877_write_regs();
123 }
124
125 return change;
126}
127
128static int max9877_get_out_mode(struct snd_kcontrol *kcontrol,
129 struct snd_ctl_elem_value *ucontrol)
130{
131 u8 value = max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OUTMODE_MASK;
132
133 if (value)
134 value -= 1;
135
136 ucontrol->value.integer.value[0] = value;
137 return 0;
138}
139
140static int max9877_set_out_mode(struct snd_kcontrol *kcontrol,
141 struct snd_ctl_elem_value *ucontrol)
142{
143 u8 value = ucontrol->value.integer.value[0];
144
145 value += 1;
146
147 if ((max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OUTMODE_MASK) == value)
148 return 0;
149
150 max9877_regs[MAX9877_OUTPUT_MODE] &= ~MAX9877_OUTMODE_MASK;
151 max9877_regs[MAX9877_OUTPUT_MODE] |= value;
152 max9877_write_regs();
153 return 1;
154}
155
156static int max9877_get_osc_mode(struct snd_kcontrol *kcontrol,
157 struct snd_ctl_elem_value *ucontrol)
158{
159 u8 value = (max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OSC_MASK);
160
161 value = value >> MAX9877_OSC_OFFSET;
162
163 ucontrol->value.integer.value[0] = value;
164 return 0;
165}
166
167static int max9877_set_osc_mode(struct snd_kcontrol *kcontrol,
168 struct snd_ctl_elem_value *ucontrol)
169{
170 u8 value = ucontrol->value.integer.value[0];
171
172 value = value << MAX9877_OSC_OFFSET;
173 if ((max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OSC_MASK) == value)
174 return 0;
175
176 max9877_regs[MAX9877_OUTPUT_MODE] &= ~MAX9877_OSC_MASK;
177 max9877_regs[MAX9877_OUTPUT_MODE] |= value;
178 max9877_write_regs();
179 return 1;
180}
181 32
182static const unsigned int max9877_pgain_tlv[] = { 33static const unsigned int max9877_pgain_tlv[] = {
183 TLV_DB_RANGE_HEAD(2), 34 TLV_DB_RANGE_HEAD(2),
@@ -212,65 +63,104 @@ static const char *max9877_osc_mode[] = {
212}; 63};
213 64
214static const struct soc_enum max9877_enum[] = { 65static const struct soc_enum max9877_enum[] = {
215 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max9877_out_mode), max9877_out_mode), 66 SOC_ENUM_SINGLE(MAX9877_OUTPUT_MODE, 0, ARRAY_SIZE(max9877_out_mode),
216 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max9877_osc_mode), max9877_osc_mode), 67 max9877_out_mode),
68 SOC_ENUM_SINGLE(MAX9877_OUTPUT_MODE, MAX9877_OSC_OFFSET,
69 ARRAY_SIZE(max9877_osc_mode), max9877_osc_mode),
217}; 70};
218 71
219static const struct snd_kcontrol_new max9877_controls[] = { 72static const struct snd_kcontrol_new max9877_controls[] = {
220 SOC_SINGLE_EXT_TLV("MAX9877 PGAINA Playback Volume", 73 SOC_SINGLE_TLV("MAX9877 PGAINA Playback Volume",
221 MAX9877_INPUT_MODE, 0, 2, 0, 74 MAX9877_INPUT_MODE, 0, 2, 0, max9877_pgain_tlv),
222 max9877_get_reg, max9877_set_reg, max9877_pgain_tlv), 75 SOC_SINGLE_TLV("MAX9877 PGAINB Playback Volume",
223 SOC_SINGLE_EXT_TLV("MAX9877 PGAINB Playback Volume", 76 MAX9877_INPUT_MODE, 2, 2, 0, max9877_pgain_tlv),
224 MAX9877_INPUT_MODE, 2, 2, 0, 77 SOC_SINGLE_TLV("MAX9877 Amp Speaker Playback Volume",
225 max9877_get_reg, max9877_set_reg, max9877_pgain_tlv), 78 MAX9877_SPK_VOLUME, 0, 31, 0, max9877_output_tlv),
226 SOC_SINGLE_EXT_TLV("MAX9877 Amp Speaker Playback Volume", 79 SOC_DOUBLE_R_TLV("MAX9877 Amp HP Playback Volume",
227 MAX9877_SPK_VOLUME, 0, 31, 0, 80 MAX9877_HPL_VOLUME, MAX9877_HPR_VOLUME, 0, 31, 0,
228 max9877_get_reg, max9877_set_reg, max9877_output_tlv), 81 max9877_output_tlv),
229 SOC_DOUBLE_R_EXT_TLV("MAX9877 Amp HP Playback Volume", 82 SOC_SINGLE("MAX9877 INB Stereo Switch",
230 MAX9877_HPL_VOLUME, MAX9877_HPR_VOLUME, 0, 31, 0, 83 MAX9877_INPUT_MODE, 4, 1, 1),
231 max9877_get_2reg, max9877_set_2reg, max9877_output_tlv), 84 SOC_SINGLE("MAX9877 INA Stereo Switch",
232 SOC_SINGLE_EXT("MAX9877 INB Stereo Switch", 85 MAX9877_INPUT_MODE, 5, 1, 1),
233 MAX9877_INPUT_MODE, 4, 1, 1, 86 SOC_SINGLE("MAX9877 Zero-crossing detection Switch",
234 max9877_get_reg, max9877_set_reg), 87 MAX9877_INPUT_MODE, 6, 1, 0),
235 SOC_SINGLE_EXT("MAX9877 INA Stereo Switch", 88 SOC_SINGLE("MAX9877 Bypass Mode Switch",
236 MAX9877_INPUT_MODE, 5, 1, 1, 89 MAX9877_OUTPUT_MODE, 6, 1, 0),
237 max9877_get_reg, max9877_set_reg), 90 SOC_ENUM("MAX9877 Output Mode", max9877_enum[0]),
238 SOC_SINGLE_EXT("MAX9877 Zero-crossing detection Switch", 91 SOC_ENUM("MAX9877 Oscillator Mode", max9877_enum[1]),
239 MAX9877_INPUT_MODE, 6, 1, 0,
240 max9877_get_reg, max9877_set_reg),
241 SOC_SINGLE_EXT("MAX9877 Bypass Mode Switch",
242 MAX9877_OUTPUT_MODE, 6, 1, 0,
243 max9877_get_reg, max9877_set_reg),
244 SOC_SINGLE_EXT("MAX9877 Shutdown Mode Switch",
245 MAX9877_OUTPUT_MODE, 7, 1, 1,
246 max9877_get_reg, max9877_set_reg),
247 SOC_ENUM_EXT("MAX9877 Output Mode", max9877_enum[0],
248 max9877_get_out_mode, max9877_set_out_mode),
249 SOC_ENUM_EXT("MAX9877 Oscillator Mode", max9877_enum[1],
250 max9877_get_osc_mode, max9877_set_osc_mode),
251}; 92};
252 93
253/* This function is called from ASoC machine driver */ 94static const struct snd_soc_dapm_widget max9877_dapm_widgets[] = {
254int max9877_add_controls(struct snd_soc_codec *codec) 95SND_SOC_DAPM_INPUT("INA1"),
255{ 96SND_SOC_DAPM_INPUT("INA2"),
256 return snd_soc_add_codec_controls(codec, max9877_controls, 97SND_SOC_DAPM_INPUT("INB1"),
257 ARRAY_SIZE(max9877_controls)); 98SND_SOC_DAPM_INPUT("INB2"),
258} 99SND_SOC_DAPM_INPUT("RXIN+"),
259EXPORT_SYMBOL_GPL(max9877_add_controls); 100SND_SOC_DAPM_INPUT("RXIN-"),
101
102SND_SOC_DAPM_PGA("SHDN", MAX9877_OUTPUT_MODE, 7, 1, NULL, 0),
103
104SND_SOC_DAPM_OUTPUT("OUT+"),
105SND_SOC_DAPM_OUTPUT("OUT-"),
106SND_SOC_DAPM_OUTPUT("HPL"),
107SND_SOC_DAPM_OUTPUT("HPR"),
108};
109
110static const struct snd_soc_dapm_route max9877_dapm_routes[] = {
111 { "SHDN", NULL, "INA1" },
112 { "SHDN", NULL, "INA2" },
113 { "SHDN", NULL, "INB1" },
114 { "SHDN", NULL, "INB2" },
115
116 { "OUT+", NULL, "RXIN+" },
117 { "OUT+", NULL, "SHDN" },
118
119 { "OUT-", NULL, "SHDN" },
120 { "OUT-", NULL, "RXIN-" },
121
122 { "HPL", NULL, "SHDN" },
123 { "HPR", NULL, "SHDN" },
124};
125
126static const struct snd_soc_codec_driver max9877_codec = {
127 .controls = max9877_controls,
128 .num_controls = ARRAY_SIZE(max9877_controls),
129
130 .dapm_widgets = max9877_dapm_widgets,
131 .num_dapm_widgets = ARRAY_SIZE(max9877_dapm_widgets),
132 .dapm_routes = max9877_dapm_routes,
133 .num_dapm_routes = ARRAY_SIZE(max9877_dapm_routes),
134};
135
136static const struct regmap_config max9877_regmap = {
137 .reg_bits = 8,
138 .val_bits = 8,
139
140 .reg_defaults = max9877_regs,
141 .num_reg_defaults = ARRAY_SIZE(max9877_regs),
142 .cache_type = REGCACHE_RBTREE,
143};
260 144
261static int max9877_i2c_probe(struct i2c_client *client, 145static int max9877_i2c_probe(struct i2c_client *client,
262 const struct i2c_device_id *id) 146 const struct i2c_device_id *id)
263{ 147{
264 i2c = client; 148 int i;
265 149
266 max9877_write_regs(); 150 regmap = devm_regmap_init_i2c(client, &max9877_regmap);
151 if (IS_ERR(regmap))
152 return PTR_ERR(regmap);
267 153
268 return 0; 154 /* Ensure the device is in reset state */
155 for (i = 0; i < ARRAY_SIZE(max9877_regs); i++)
156 regmap_write(regmap, max9877_regs[i].reg, max9877_regs[i].def);
157
158 return snd_soc_register_codec(&client->dev, &max9877_codec, NULL, 0);
269} 159}
270 160
271static int max9877_i2c_remove(struct i2c_client *client) 161static int max9877_i2c_remove(struct i2c_client *client)
272{ 162{
273 i2c = NULL; 163 snd_soc_unregister_codec(&client->dev);
274 164
275 return 0; 165 return 0;
276} 166}
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index 5402dfbbb716..4d3c8fd8c5db 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -94,7 +94,6 @@
94#define AUDIO_DAC_CFS_DLY_B (1 << 10) 94#define AUDIO_DAC_CFS_DLY_B (1 << 10)
95 95
96struct mc13783_priv { 96struct mc13783_priv {
97 struct snd_soc_codec codec;
98 struct mc13xxx *mc13xxx; 97 struct mc13xxx *mc13xxx;
99 98
100 enum mc13783_ssi_port adc_ssi_port; 99 enum mc13783_ssi_port adc_ssi_port;
diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c
new file mode 100644
index 000000000000..651ce0923675
--- /dev/null
+++ b/sound/soc/codecs/pcm1681.c
@@ -0,0 +1,339 @@
1/*
2 * PCM1681 ASoC codec driver
3 *
4 * Copyright (c) StreamUnlimited GmbH 2013
5 * Marek Belisko <marek.belisko@streamunlimited.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (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
18#include <linux/module.h>
19#include <linux/slab.h>
20#include <linux/delay.h>
21#include <linux/gpio.h>
22#include <linux/i2c.h>
23#include <linux/regmap.h>
24#include <linux/of_device.h>
25#include <linux/of_gpio.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/tlv.h>
30
31#define PCM1681_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
32 SNDRV_PCM_FMTBIT_S24_LE)
33
34#define PCM1681_PCM_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | \
35 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
36 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \
37 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
38
39#define PCM1681_SOFT_MUTE_ALL 0xff
40#define PCM1681_DEEMPH_RATE_MASK 0x18
41#define PCM1681_DEEMPH_MASK 0x01
42
43#define PCM1681_ATT_CONTROL(X) (X <= 6 ? X : X + 9) /* Attenuation level */
44#define PCM1681_SOFT_MUTE 0x07 /* Soft mute control register */
45#define PCM1681_DAC_CONTROL 0x08 /* DAC operation control */
46#define PCM1681_FMT_CONTROL 0x09 /* Audio interface data format */
47#define PCM1681_DEEMPH_CONTROL 0x0a /* De-emphasis control */
48#define PCM1681_ZERO_DETECT_STATUS 0x0e /* Zero detect status reg */
49
50static const struct reg_default pcm1681_reg_defaults[] = {
51 { 0x01, 0xff },
52 { 0x02, 0xff },
53 { 0x03, 0xff },
54 { 0x04, 0xff },
55 { 0x05, 0xff },
56 { 0x06, 0xff },
57 { 0x07, 0x00 },
58 { 0x08, 0x00 },
59 { 0x09, 0x06 },
60 { 0x0A, 0x00 },
61 { 0x0B, 0xff },
62 { 0x0C, 0x0f },
63 { 0x0D, 0x00 },
64 { 0x10, 0xff },
65 { 0x11, 0xff },
66 { 0x12, 0x00 },
67 { 0x13, 0x00 },
68};
69
70static bool pcm1681_accessible_reg(struct device *dev, unsigned int reg)
71{
72 return !((reg == 0x00) || (reg == 0x0f));
73}
74
75static bool pcm1681_writeable_reg(struct device *dev, unsigned register reg)
76{
77 return pcm1681_accessible_reg(dev, reg) &&
78 (reg != PCM1681_ZERO_DETECT_STATUS);
79}
80
81struct pcm1681_private {
82 struct regmap *regmap;
83 unsigned int format;
84 /* Current deemphasis status */
85 unsigned int deemph;
86 /* Current rate for deemphasis control */
87 unsigned int rate;
88};
89
90static const int pcm1681_deemph[] = { 44100, 48000, 32000 };
91
92static int pcm1681_set_deemph(struct snd_soc_codec *codec)
93{
94 struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
95 int i = 0, val = -1, enable = 0;
96
97 if (priv->deemph)
98 for (i = 0; i < ARRAY_SIZE(pcm1681_deemph); i++)
99 if (pcm1681_deemph[i] == priv->rate)
100 val = i;
101
102 if (val != -1) {
103 regmap_update_bits(priv->regmap, PCM1681_DEEMPH_CONTROL,
104 PCM1681_DEEMPH_RATE_MASK, val);
105 enable = 1;
106 } else
107 enable = 0;
108
109 /* enable/disable deemphasis functionality */
110 return regmap_update_bits(priv->regmap, PCM1681_DEEMPH_CONTROL,
111 PCM1681_DEEMPH_MASK, enable);
112}
113
114static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol,
115 struct snd_ctl_elem_value *ucontrol)
116{
117 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
118 struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
119
120 ucontrol->value.enumerated.item[0] = priv->deemph;
121
122 return 0;
123}
124
125static int pcm1681_put_deemph(struct snd_kcontrol *kcontrol,
126 struct snd_ctl_elem_value *ucontrol)
127{
128 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
129 struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
130
131 priv->deemph = ucontrol->value.enumerated.item[0];
132
133 return pcm1681_set_deemph(codec);
134}
135
136static int pcm1681_set_dai_fmt(struct snd_soc_dai *codec_dai,
137 unsigned int format)
138{
139 struct snd_soc_codec *codec = codec_dai->codec;
140 struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
141
142 /* The PCM1681 can only be slave to all clocks */
143 if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
144 dev_err(codec->dev, "Invalid clocking mode\n");
145 return -EINVAL;
146 }
147
148 priv->format = format;
149
150 return 0;
151}
152
153static int pcm1681_digital_mute(struct snd_soc_dai *dai, int mute)
154{
155 struct snd_soc_codec *codec = dai->codec;
156 struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
157 int val;
158
159 if (mute)
160 val = PCM1681_SOFT_MUTE_ALL;
161 else
162 val = 0;
163
164 return regmap_write(priv->regmap, PCM1681_SOFT_MUTE, val);
165}
166
167static int pcm1681_hw_params(struct snd_pcm_substream *substream,
168 struct snd_pcm_hw_params *params,
169 struct snd_soc_dai *dai)
170{
171 struct snd_soc_codec *codec = dai->codec;
172 struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec);
173 int val = 0, ret;
174 int pcm_format = params_format(params);
175
176 priv->rate = params_rate(params);
177
178 switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
179 case SND_SOC_DAIFMT_RIGHT_J:
180 if (pcm_format == SNDRV_PCM_FORMAT_S24_LE)
181 val = 0x00;
182 else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE)
183 val = 0x03;
184 break;
185 case SND_SOC_DAIFMT_I2S:
186 val = 0x04;
187 break;
188 case SND_SOC_DAIFMT_LEFT_J:
189 val = 0x05;
190 break;
191 default:
192 dev_err(codec->dev, "Invalid DAI format\n");
193 return -EINVAL;
194 }
195
196 ret = regmap_update_bits(priv->regmap, PCM1681_FMT_CONTROL, 0x0f, val);
197 if (ret < 0)
198 return ret;
199
200 return pcm1681_set_deemph(codec);
201}
202
203static const struct snd_soc_dai_ops pcm1681_dai_ops = {
204 .set_fmt = pcm1681_set_dai_fmt,
205 .hw_params = pcm1681_hw_params,
206 .digital_mute = pcm1681_digital_mute,
207};
208
209static const struct snd_soc_dapm_widget pcm1681_dapm_widgets[] = {
210SND_SOC_DAPM_OUTPUT("VOUT1"),
211SND_SOC_DAPM_OUTPUT("VOUT2"),
212SND_SOC_DAPM_OUTPUT("VOUT3"),
213SND_SOC_DAPM_OUTPUT("VOUT4"),
214SND_SOC_DAPM_OUTPUT("VOUT5"),
215SND_SOC_DAPM_OUTPUT("VOUT6"),
216SND_SOC_DAPM_OUTPUT("VOUT7"),
217SND_SOC_DAPM_OUTPUT("VOUT8"),
218};
219
220static const struct snd_soc_dapm_route pcm1681_dapm_routes[] = {
221 { "VOUT1", NULL, "Playback" },
222 { "VOUT2", NULL, "Playback" },
223 { "VOUT3", NULL, "Playback" },
224 { "VOUT4", NULL, "Playback" },
225 { "VOUT5", NULL, "Playback" },
226 { "VOUT6", NULL, "Playback" },
227 { "VOUT7", NULL, "Playback" },
228 { "VOUT8", NULL, "Playback" },
229};
230
231static const DECLARE_TLV_DB_SCALE(pcm1681_dac_tlv, -6350, 50, 1);
232
233static const struct snd_kcontrol_new pcm1681_controls[] = {
234 SOC_DOUBLE_R_TLV("Channel 1/2 Playback Volume",
235 PCM1681_ATT_CONTROL(1), PCM1681_ATT_CONTROL(2), 0,
236 0x7f, 0, pcm1681_dac_tlv),
237 SOC_DOUBLE_R_TLV("Channel 3/4 Playback Volume",
238 PCM1681_ATT_CONTROL(3), PCM1681_ATT_CONTROL(4), 0,
239 0x7f, 0, pcm1681_dac_tlv),
240 SOC_DOUBLE_R_TLV("Channel 5/6 Playback Volume",
241 PCM1681_ATT_CONTROL(5), PCM1681_ATT_CONTROL(6), 0,
242 0x7f, 0, pcm1681_dac_tlv),
243 SOC_DOUBLE_R_TLV("Channel 7/8 Playback Volume",
244 PCM1681_ATT_CONTROL(7), PCM1681_ATT_CONTROL(8), 0,
245 0x7f, 0, pcm1681_dac_tlv),
246 SOC_SINGLE_BOOL_EXT("De-emphasis Switch", 0,
247 pcm1681_get_deemph, pcm1681_put_deemph),
248};
249
250static struct snd_soc_dai_driver pcm1681_dai = {
251 .name = "pcm1681-hifi",
252 .playback = {
253 .stream_name = "Playback",
254 .channels_min = 2,
255 .channels_max = 8,
256 .rates = PCM1681_PCM_RATES,
257 .formats = PCM1681_PCM_FORMATS,
258 },
259 .ops = &pcm1681_dai_ops,
260};
261
262#ifdef CONFIG_OF
263static const struct of_device_id pcm1681_dt_ids[] = {
264 { .compatible = "ti,pcm1681", },
265 { }
266};
267MODULE_DEVICE_TABLE(of, pcm1681_dt_ids);
268#endif
269
270static const struct regmap_config pcm1681_regmap = {
271 .reg_bits = 8,
272 .val_bits = 8,
273 .max_register = ARRAY_SIZE(pcm1681_reg_defaults) + 1,
274 .reg_defaults = pcm1681_reg_defaults,
275 .num_reg_defaults = ARRAY_SIZE(pcm1681_reg_defaults),
276 .writeable_reg = pcm1681_writeable_reg,
277 .readable_reg = pcm1681_accessible_reg,
278};
279
280static struct snd_soc_codec_driver soc_codec_dev_pcm1681 = {
281 .controls = pcm1681_controls,
282 .num_controls = ARRAY_SIZE(pcm1681_controls),
283 .dapm_widgets = pcm1681_dapm_widgets,
284 .num_dapm_widgets = ARRAY_SIZE(pcm1681_dapm_widgets),
285 .dapm_routes = pcm1681_dapm_routes,
286 .num_dapm_routes = ARRAY_SIZE(pcm1681_dapm_routes),
287};
288
289static const struct i2c_device_id pcm1681_i2c_id[] = {
290 {"pcm1681", 0},
291 {}
292};
293MODULE_DEVICE_TABLE(i2c, pcm1681_i2c_id);
294
295static int pcm1681_i2c_probe(struct i2c_client *client,
296 const struct i2c_device_id *id)
297{
298 int ret;
299 struct pcm1681_private *priv;
300
301 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
302 if (!priv)
303 return -ENOMEM;
304
305 priv->regmap = devm_regmap_init_i2c(client, &pcm1681_regmap);
306 if (IS_ERR(priv->regmap)) {
307 ret = PTR_ERR(priv->regmap);
308 dev_err(&client->dev, "Failed to create regmap: %d\n", ret);
309 return ret;
310 }
311
312 i2c_set_clientdata(client, priv);
313
314 return snd_soc_register_codec(&client->dev, &soc_codec_dev_pcm1681,
315 &pcm1681_dai, 1);
316}
317
318static int pcm1681_i2c_remove(struct i2c_client *client)
319{
320 snd_soc_unregister_codec(&client->dev);
321 return 0;
322}
323
324static struct i2c_driver pcm1681_i2c_driver = {
325 .driver = {
326 .name = "pcm1681",
327 .owner = THIS_MODULE,
328 .of_match_table = of_match_ptr(pcm1681_dt_ids),
329 },
330 .id_table = pcm1681_i2c_id,
331 .probe = pcm1681_i2c_probe,
332 .remove = pcm1681_i2c_remove,
333};
334
335module_i2c_driver(pcm1681_i2c_driver);
336
337MODULE_DESCRIPTION("Texas Instruments PCM1681 ALSA SoC Codec Driver");
338MODULE_AUTHOR("Marek Belisko <marek.belisko@streamunlimited.com>");
339MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm1792a.c b/sound/soc/codecs/pcm1792a.c
new file mode 100644
index 000000000000..2a8eccf64c76
--- /dev/null
+++ b/sound/soc/codecs/pcm1792a.c
@@ -0,0 +1,257 @@
1/*
2 * PCM1792A ASoC codec driver
3 *
4 * Copyright (c) Amarula Solutions B.V. 2013
5 *
6 * Michael Trimarchi <michael@amarulasolutions.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/module.h>
20#include <linux/slab.h>
21#include <linux/kernel.h>
22#include <linux/device.h>
23#include <linux/spi/spi.h>
24
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/initval.h>
29#include <sound/soc.h>
30#include <sound/tlv.h>
31#include <linux/of_device.h>
32
33#include "pcm1792a.h"
34
35#define PCM1792A_DAC_VOL_LEFT 0x10
36#define PCM1792A_DAC_VOL_RIGHT 0x11
37#define PCM1792A_FMT_CONTROL 0x12
38#define PCM1792A_SOFT_MUTE PCM1792A_FMT_CONTROL
39
40#define PCM1792A_FMT_MASK 0x70
41#define PCM1792A_FMT_SHIFT 4
42#define PCM1792A_MUTE_MASK 0x01
43#define PCM1792A_MUTE_SHIFT 0
44#define PCM1792A_ATLD_ENABLE (1 << 7)
45
46static const struct reg_default pcm1792a_reg_defaults[] = {
47 { 0x10, 0xff },
48 { 0x11, 0xff },
49 { 0x12, 0x50 },
50 { 0x13, 0x00 },
51 { 0x14, 0x00 },
52 { 0x15, 0x01 },
53 { 0x16, 0x00 },
54 { 0x17, 0x00 },
55};
56
57static bool pcm1792a_accessible_reg(struct device *dev, unsigned int reg)
58{
59 return reg >= 0x10 && reg <= 0x17;
60}
61
62static bool pcm1792a_writeable_reg(struct device *dev, unsigned register reg)
63{
64 bool accessible;
65
66 accessible = pcm1792a_accessible_reg(dev, reg);
67
68 return accessible && reg != 0x16 && reg != 0x17;
69}
70
71struct pcm1792a_private {
72 struct regmap *regmap;
73 unsigned int format;
74 unsigned int rate;
75};
76
77static int pcm1792a_set_dai_fmt(struct snd_soc_dai *codec_dai,
78 unsigned int format)
79{
80 struct snd_soc_codec *codec = codec_dai->codec;
81 struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec);
82
83 priv->format = format;
84
85 return 0;
86}
87
88static int pcm1792a_digital_mute(struct snd_soc_dai *dai, int mute)
89{
90 struct snd_soc_codec *codec = dai->codec;
91 struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec);
92 int ret;
93
94 ret = regmap_update_bits(priv->regmap, PCM1792A_SOFT_MUTE,
95 PCM1792A_MUTE_MASK, !!mute);
96 if (ret < 0)
97 return ret;
98
99 return 0;
100}
101
102static int pcm1792a_hw_params(struct snd_pcm_substream *substream,
103 struct snd_pcm_hw_params *params,
104 struct snd_soc_dai *dai)
105{
106 struct snd_soc_codec *codec = dai->codec;
107 struct pcm1792a_private *priv = snd_soc_codec_get_drvdata(codec);
108 int val = 0, ret;
109 int pcm_format = params_format(params);
110
111 priv->rate = params_rate(params);
112
113 switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) {
114 case SND_SOC_DAIFMT_RIGHT_J:
115 if (pcm_format == SNDRV_PCM_FORMAT_S24_LE ||
116 pcm_format == SNDRV_PCM_FORMAT_S32_LE)
117 val = 0x02;
118 else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE)
119 val = 0x00;
120 break;
121 case SND_SOC_DAIFMT_I2S:
122 if (pcm_format == SNDRV_PCM_FORMAT_S24_LE ||
123 pcm_format == SNDRV_PCM_FORMAT_S32_LE)
124 val = 0x05;
125 else if (pcm_format == SNDRV_PCM_FORMAT_S16_LE)
126 val = 0x04;
127 break;
128 default:
129 dev_err(codec->dev, "Invalid DAI format\n");
130 return -EINVAL;
131 }
132
133 val = val << PCM1792A_FMT_SHIFT | PCM1792A_ATLD_ENABLE;
134
135 ret = regmap_update_bits(priv->regmap, PCM1792A_FMT_CONTROL,
136 PCM1792A_FMT_MASK | PCM1792A_ATLD_ENABLE, val);
137 if (ret < 0)
138 return ret;
139
140 return 0;
141}
142
143static const struct snd_soc_dai_ops pcm1792a_dai_ops = {
144 .set_fmt = pcm1792a_set_dai_fmt,
145 .hw_params = pcm1792a_hw_params,
146 .digital_mute = pcm1792a_digital_mute,
147};
148
149static const DECLARE_TLV_DB_SCALE(pcm1792a_dac_tlv, -12000, 50, 1);
150
151static const struct snd_kcontrol_new pcm1792a_controls[] = {
152 SOC_DOUBLE_R_RANGE_TLV("DAC Playback Volume", PCM1792A_DAC_VOL_LEFT,
153 PCM1792A_DAC_VOL_RIGHT, 0, 0xf, 0xff, 0,
154 pcm1792a_dac_tlv),
155};
156
157static const struct snd_soc_dapm_widget pcm1792a_dapm_widgets[] = {
158SND_SOC_DAPM_OUTPUT("IOUTL+"),
159SND_SOC_DAPM_OUTPUT("IOUTL-"),
160SND_SOC_DAPM_OUTPUT("IOUTR+"),
161SND_SOC_DAPM_OUTPUT("IOUTR-"),
162};
163
164static const struct snd_soc_dapm_route pcm1792a_dapm_routes[] = {
165 { "IOUTL+", NULL, "Playback" },
166 { "IOUTL-", NULL, "Playback" },
167 { "IOUTR+", NULL, "Playback" },
168 { "IOUTR-", NULL, "Playback" },
169};
170
171static struct snd_soc_dai_driver pcm1792a_dai = {
172 .name = "pcm1792a-hifi",
173 .playback = {
174 .stream_name = "Playback",
175 .channels_min = 2,
176 .channels_max = 2,
177 .rates = PCM1792A_RATES,
178 .formats = PCM1792A_FORMATS, },
179 .ops = &pcm1792a_dai_ops,
180};
181
182static const struct of_device_id pcm1792a_of_match[] = {
183 { .compatible = "ti,pcm1792a", },
184 { }
185};
186MODULE_DEVICE_TABLE(of, pcm1792a_of_match);
187
188static const struct regmap_config pcm1792a_regmap = {
189 .reg_bits = 8,
190 .val_bits = 8,
191 .max_register = 24,
192 .reg_defaults = pcm1792a_reg_defaults,
193 .num_reg_defaults = ARRAY_SIZE(pcm1792a_reg_defaults),
194 .writeable_reg = pcm1792a_writeable_reg,
195 .readable_reg = pcm1792a_accessible_reg,
196};
197
198static struct snd_soc_codec_driver soc_codec_dev_pcm1792a = {
199 .controls = pcm1792a_controls,
200 .num_controls = ARRAY_SIZE(pcm1792a_controls),
201 .dapm_widgets = pcm1792a_dapm_widgets,
202 .num_dapm_widgets = ARRAY_SIZE(pcm1792a_dapm_widgets),
203 .dapm_routes = pcm1792a_dapm_routes,
204 .num_dapm_routes = ARRAY_SIZE(pcm1792a_dapm_routes),
205};
206
207static int pcm1792a_spi_probe(struct spi_device *spi)
208{
209 struct pcm1792a_private *pcm1792a;
210 int ret;
211
212 pcm1792a = devm_kzalloc(&spi->dev, sizeof(struct pcm1792a_private),
213 GFP_KERNEL);
214 if (!pcm1792a)
215 return -ENOMEM;
216
217 spi_set_drvdata(spi, pcm1792a);
218
219 pcm1792a->regmap = devm_regmap_init_spi(spi, &pcm1792a_regmap);
220 if (IS_ERR(pcm1792a->regmap)) {
221 ret = PTR_ERR(pcm1792a->regmap);
222 dev_err(&spi->dev, "Failed to register regmap: %d\n", ret);
223 return ret;
224 }
225
226 return snd_soc_register_codec(&spi->dev,
227 &soc_codec_dev_pcm1792a, &pcm1792a_dai, 1);
228}
229
230static int pcm1792a_spi_remove(struct spi_device *spi)
231{
232 snd_soc_unregister_codec(&spi->dev);
233 return 0;
234}
235
236static const struct spi_device_id pcm1792a_spi_ids[] = {
237 { "pcm1792a", 0 },
238 { },
239};
240MODULE_DEVICE_TABLE(spi, pcm1792a_spi_ids);
241
242static struct spi_driver pcm1792a_codec_driver = {
243 .driver = {
244 .name = "pcm1792a",
245 .owner = THIS_MODULE,
246 .of_match_table = of_match_ptr(pcm1792a_of_match),
247 },
248 .id_table = pcm1792a_spi_ids,
249 .probe = pcm1792a_spi_probe,
250 .remove = pcm1792a_spi_remove,
251};
252
253module_spi_driver(pcm1792a_codec_driver);
254
255MODULE_DESCRIPTION("ASoC PCM1792A driver");
256MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>");
257MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm1792a.h b/sound/soc/codecs/pcm1792a.h
new file mode 100644
index 000000000000..7a83d1fc102a
--- /dev/null
+++ b/sound/soc/codecs/pcm1792a.h
@@ -0,0 +1,26 @@
1/*
2 * definitions for PCM1792A
3 *
4 * Copyright 2013 Amarula Solutions
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (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
17#ifndef __PCM1792A_H__
18#define __PCM1792A_H__
19
20#define PCM1792A_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_8000_48000 | \
21 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
22
23#define PCM1792A_FORMATS (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \
24 SNDRV_PCM_FMTBIT_S16_LE)
25
26#endif
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
index f2a6282b41f4..b6618c4a7597 100644
--- a/sound/soc/codecs/pcm3008.c
+++ b/sound/soc/codecs/pcm3008.c
@@ -28,7 +28,54 @@
28 28
29#include "pcm3008.h" 29#include "pcm3008.h"
30 30
31#define PCM3008_VERSION "0.2" 31static int pcm3008_dac_ev(struct snd_soc_dapm_widget *w,
32 struct snd_kcontrol *kcontrol,
33 int event)
34{
35 struct snd_soc_codec *codec = w->codec;
36 struct pcm3008_setup_data *setup = codec->dev->platform_data;
37
38 gpio_set_value_cansleep(setup->pdda_pin,
39 SND_SOC_DAPM_EVENT_ON(event));
40
41 return 0;
42}
43
44static int pcm3008_adc_ev(struct snd_soc_dapm_widget *w,
45 struct snd_kcontrol *kcontrol,
46 int event)
47{
48 struct snd_soc_codec *codec = w->codec;
49 struct pcm3008_setup_data *setup = codec->dev->platform_data;
50
51 gpio_set_value_cansleep(setup->pdad_pin,
52 SND_SOC_DAPM_EVENT_ON(event));
53
54 return 0;
55}
56
57static const struct snd_soc_dapm_widget pcm3008_dapm_widgets[] = {
58SND_SOC_DAPM_INPUT("VINL"),
59SND_SOC_DAPM_INPUT("VINR"),
60
61SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, pcm3008_dac_ev,
62 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
63SND_SOC_DAPM_ADC_E("ADC", NULL, SND_SOC_NOPM, 0, 0, pcm3008_adc_ev,
64 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
65
66SND_SOC_DAPM_OUTPUT("VOUTL"),
67SND_SOC_DAPM_OUTPUT("VOUTR"),
68};
69
70static const struct snd_soc_dapm_route pcm3008_dapm_routes[] = {
71 { "PCM3008 Capture", NULL, "ADC" },
72 { "ADC", NULL, "VINL" },
73 { "ADC", NULL, "VINR" },
74
75 { "DAC", NULL, "PCM3008 Playback" },
76 { "VOUTL", NULL, "DAC" },
77 { "VOUTR", NULL, "DAC" },
78};
32 79
33#define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ 80#define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
34 SNDRV_PCM_RATE_48000) 81 SNDRV_PCM_RATE_48000)
@@ -51,20 +98,20 @@ static struct snd_soc_dai_driver pcm3008_dai = {
51 }, 98 },
52}; 99};
53 100
54static void pcm3008_gpio_free(struct pcm3008_setup_data *setup) 101static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = {
55{ 102 .dapm_widgets = pcm3008_dapm_widgets,
56 gpio_free(setup->dem0_pin); 103 .num_dapm_widgets = ARRAY_SIZE(pcm3008_dapm_widgets),
57 gpio_free(setup->dem1_pin); 104 .dapm_routes = pcm3008_dapm_routes,
58 gpio_free(setup->pdad_pin); 105 .num_dapm_routes = ARRAY_SIZE(pcm3008_dapm_routes),
59 gpio_free(setup->pdda_pin); 106};
60}
61 107
62static int pcm3008_soc_probe(struct snd_soc_codec *codec) 108static int pcm3008_codec_probe(struct platform_device *pdev)
63{ 109{
64 struct pcm3008_setup_data *setup = codec->dev->platform_data; 110 struct pcm3008_setup_data *setup = pdev->dev.platform_data;
65 int ret = 0; 111 int ret;
66 112
67 printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION); 113 if (!setup)
114 return -EINVAL;
68 115
69 /* DEM1 DEM0 DE-EMPHASIS_MODE 116 /* DEM1 DEM0 DE-EMPHASIS_MODE
70 * Low Low De-emphasis 44.1 kHz ON 117 * Low Low De-emphasis 44.1 kHz ON
@@ -74,83 +121,29 @@ static int pcm3008_soc_probe(struct snd_soc_codec *codec)
74 */ 121 */
75 122
76 /* Configure DEM0 GPIO (turning OFF DAC De-emphasis). */ 123 /* Configure DEM0 GPIO (turning OFF DAC De-emphasis). */
77 ret = gpio_request(setup->dem0_pin, "codec_dem0"); 124 ret = devm_gpio_request_one(&pdev->dev, setup->dem0_pin,
78 if (ret == 0) 125 GPIOF_OUT_INIT_HIGH, "codec_dem0");
79 ret = gpio_direction_output(setup->dem0_pin, 1);
80 if (ret != 0) 126 if (ret != 0)
81 goto gpio_err; 127 return ret;
82 128
83 /* Configure DEM1 GPIO (turning OFF DAC De-emphasis). */ 129 /* Configure DEM1 GPIO (turning OFF DAC De-emphasis). */
84 ret = gpio_request(setup->dem1_pin, "codec_dem1"); 130 ret = devm_gpio_request_one(&pdev->dev, setup->dem1_pin,
85 if (ret == 0) 131 GPIOF_OUT_INIT_LOW, "codec_dem1");
86 ret = gpio_direction_output(setup->dem1_pin, 0);
87 if (ret != 0) 132 if (ret != 0)
88 goto gpio_err; 133 return ret;
89 134
90 /* Configure PDAD GPIO. */ 135 /* Configure PDAD GPIO. */
91 ret = gpio_request(setup->pdad_pin, "codec_pdad"); 136 ret = devm_gpio_request_one(&pdev->dev, setup->pdad_pin,
92 if (ret == 0) 137 GPIOF_OUT_INIT_LOW, "codec_pdad");
93 ret = gpio_direction_output(setup->pdad_pin, 1);
94 if (ret != 0) 138 if (ret != 0)
95 goto gpio_err; 139 return ret;
96 140
97 /* Configure PDDA GPIO. */ 141 /* Configure PDDA GPIO. */
98 ret = gpio_request(setup->pdda_pin, "codec_pdda"); 142 ret = devm_gpio_request_one(&pdev->dev, setup->pdda_pin,
99 if (ret == 0) 143 GPIOF_OUT_INIT_LOW, "codec_pdda");
100 ret = gpio_direction_output(setup->pdda_pin, 1);
101 if (ret != 0) 144 if (ret != 0)
102 goto gpio_err; 145 return ret;
103
104 return ret;
105
106gpio_err:
107 pcm3008_gpio_free(setup);
108 146
109 return ret;
110}
111
112static int pcm3008_soc_remove(struct snd_soc_codec *codec)
113{
114 struct pcm3008_setup_data *setup = codec->dev->platform_data;
115
116 pcm3008_gpio_free(setup);
117 return 0;
118}
119
120#ifdef CONFIG_PM
121static int pcm3008_soc_suspend(struct snd_soc_codec *codec)
122{
123 struct pcm3008_setup_data *setup = codec->dev->platform_data;
124
125 gpio_set_value(setup->pdad_pin, 0);
126 gpio_set_value(setup->pdda_pin, 0);
127
128 return 0;
129}
130
131static int pcm3008_soc_resume(struct snd_soc_codec *codec)
132{
133 struct pcm3008_setup_data *setup = codec->dev->platform_data;
134
135 gpio_set_value(setup->pdad_pin, 1);
136 gpio_set_value(setup->pdda_pin, 1);
137
138 return 0;
139}
140#else
141#define pcm3008_soc_suspend NULL
142#define pcm3008_soc_resume NULL
143#endif
144
145static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = {
146 .probe = pcm3008_soc_probe,
147 .remove = pcm3008_soc_remove,
148 .suspend = pcm3008_soc_suspend,
149 .resume = pcm3008_soc_resume,
150};
151
152static int pcm3008_codec_probe(struct platform_device *pdev)
153{
154 return snd_soc_register_codec(&pdev->dev, 147 return snd_soc_register_codec(&pdev->dev,
155 &soc_codec_dev_pcm3008, &pcm3008_dai, 1); 148 &soc_codec_dev_pcm3008, &pcm3008_dai, 1);
156} 149}
@@ -158,6 +151,7 @@ static int pcm3008_codec_probe(struct platform_device *pdev)
158static int pcm3008_codec_remove(struct platform_device *pdev) 151static int pcm3008_codec_remove(struct platform_device *pdev)
159{ 152{
160 snd_soc_unregister_codec(&pdev->dev); 153 snd_soc_unregister_codec(&pdev->dev);
154
161 return 0; 155 return 0;
162} 156}
163 157
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index ce585e37e38a..c26a8f814b18 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -50,8 +50,6 @@ static const struct regmap_range_cfg rt5640_ranges[] = {
50 50
51static struct reg_default init_list[] = { 51static struct reg_default init_list[] = {
52 {RT5640_PR_BASE + 0x3d, 0x3600}, 52 {RT5640_PR_BASE + 0x3d, 0x3600},
53 {RT5640_PR_BASE + 0x1c, 0x0D21},
54 {RT5640_PR_BASE + 0x1b, 0x0000},
55 {RT5640_PR_BASE + 0x12, 0x0aa8}, 53 {RT5640_PR_BASE + 0x12, 0x0aa8},
56 {RT5640_PR_BASE + 0x14, 0x0aaa}, 54 {RT5640_PR_BASE + 0x14, 0x0aaa},
57 {RT5640_PR_BASE + 0x20, 0x6110}, 55 {RT5640_PR_BASE + 0x20, 0x6110},
@@ -384,15 +382,11 @@ static const SOC_ENUM_SINGLE_DECL(
384 382
385static const struct snd_kcontrol_new rt5640_snd_controls[] = { 383static const struct snd_kcontrol_new rt5640_snd_controls[] = {
386 /* Speaker Output Volume */ 384 /* Speaker Output Volume */
387 SOC_DOUBLE("Speaker Playback Switch", RT5640_SPK_VOL,
388 RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1),
389 SOC_DOUBLE("Speaker Channel Switch", RT5640_SPK_VOL, 385 SOC_DOUBLE("Speaker Channel Switch", RT5640_SPK_VOL,
390 RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1), 386 RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1),
391 SOC_DOUBLE_TLV("Speaker Playback Volume", RT5640_SPK_VOL, 387 SOC_DOUBLE_TLV("Speaker Playback Volume", RT5640_SPK_VOL,
392 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv), 388 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv),
393 /* Headphone Output Volume */ 389 /* Headphone Output Volume */
394 SOC_DOUBLE("HP Playback Switch", RT5640_HP_VOL,
395 RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1),
396 SOC_DOUBLE("HP Channel Switch", RT5640_HP_VOL, 390 SOC_DOUBLE("HP Channel Switch", RT5640_HP_VOL,
397 RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1), 391 RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1),
398 SOC_DOUBLE_TLV("HP Playback Volume", RT5640_HP_VOL, 392 SOC_DOUBLE_TLV("HP Playback Volume", RT5640_HP_VOL,
@@ -737,28 +731,21 @@ static const struct snd_kcontrol_new rt5640_mono_mix[] = {
737 RT5640_M_BST1_MM_SFT, 1, 1), 731 RT5640_M_BST1_MM_SFT, 1, 1),
738}; 732};
739 733
740/* INL/R source */ 734static const struct snd_kcontrol_new spk_l_enable_control =
741static const char * const rt5640_inl_src[] = { 735 SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_SPK_VOL,
742 "IN2P", "MONOP" 736 RT5640_L_MUTE_SFT, 1, 1);
743};
744 737
745static const SOC_ENUM_SINGLE_DECL( 738static const struct snd_kcontrol_new spk_r_enable_control =
746 rt5640_inl_enum, RT5640_INL_INR_VOL, 739 SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_SPK_VOL,
747 RT5640_INL_SEL_SFT, rt5640_inl_src); 740 RT5640_R_MUTE_SFT, 1, 1);
748 741
749static const struct snd_kcontrol_new rt5640_inl_mux = 742static const struct snd_kcontrol_new hp_l_enable_control =
750 SOC_DAPM_ENUM("INL source", rt5640_inl_enum); 743 SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_HP_VOL,
744 RT5640_L_MUTE_SFT, 1, 1);
751 745
752static const char * const rt5640_inr_src[] = { 746static const struct snd_kcontrol_new hp_r_enable_control =
753 "IN2N", "MONON" 747 SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_HP_VOL,
754}; 748 RT5640_R_MUTE_SFT, 1, 1);
755
756static const SOC_ENUM_SINGLE_DECL(
757 rt5640_inr_enum, RT5640_INL_INR_VOL,
758 RT5640_INR_SEL_SFT, rt5640_inr_src);
759
760static const struct snd_kcontrol_new rt5640_inr_mux =
761 SOC_DAPM_ENUM("INR source", rt5640_inr_enum);
762 749
763/* Stereo ADC source */ 750/* Stereo ADC source */
764static const char * const rt5640_stereo_adc1_src[] = { 751static const char * const rt5640_stereo_adc1_src[] = {
@@ -891,33 +878,6 @@ static const SOC_ENUM_SINGLE_DECL(
891static const struct snd_kcontrol_new rt5640_sdi_mux = 878static const struct snd_kcontrol_new rt5640_sdi_mux =
892 SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum); 879 SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum);
893 880
894static int spk_event(struct snd_soc_dapm_widget *w,
895 struct snd_kcontrol *kcontrol, int event)
896{
897 struct snd_soc_codec *codec = w->codec;
898 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
899
900 switch (event) {
901 case SND_SOC_DAPM_POST_PMU:
902 regmap_update_bits(rt5640->regmap, RT5640_PWR_DIG1,
903 0x0001, 0x0001);
904 regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + 0x1c,
905 0xf000, 0xf000);
906 break;
907
908 case SND_SOC_DAPM_PRE_PMD:
909 regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + 0x1c,
910 0xf000, 0x0000);
911 regmap_update_bits(rt5640->regmap, RT5640_PWR_DIG1,
912 0x0001, 0x0000);
913 break;
914
915 default:
916 return 0;
917 }
918 return 0;
919}
920
921static int rt5640_set_dmic1_event(struct snd_soc_dapm_widget *w, 881static int rt5640_set_dmic1_event(struct snd_soc_dapm_widget *w,
922 struct snd_kcontrol *kcontrol, int event) 882 struct snd_kcontrol *kcontrol, int event)
923{ 883{
@@ -966,6 +926,117 @@ static int rt5640_set_dmic2_event(struct snd_soc_dapm_widget *w,
966 return 0; 926 return 0;
967} 927}
968 928
929void hp_amp_power_on(struct snd_soc_codec *codec)
930{
931 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
932
933 /* depop parameters */
934 regmap_update_bits(rt5640->regmap, RT5640_PR_BASE +
935 RT5640_CHPUMP_INT_REG1, 0x0700, 0x0200);
936 regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M2,
937 RT5640_DEPOP_MASK, RT5640_DEPOP_MAN);
938 regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M1,
939 RT5640_HP_CP_MASK | RT5640_HP_SG_MASK | RT5640_HP_CB_MASK,
940 RT5640_HP_CP_PU | RT5640_HP_SG_DIS | RT5640_HP_CB_PU);
941 regmap_write(rt5640->regmap, RT5640_PR_BASE + RT5640_HP_DCC_INT1,
942 0x9f00);
943 /* headphone amp power on */
944 regmap_update_bits(rt5640->regmap, RT5640_PWR_ANLG1,
945 RT5640_PWR_FV1 | RT5640_PWR_FV2, 0);
946 regmap_update_bits(rt5640->regmap, RT5640_PWR_ANLG1,
947 RT5640_PWR_HA,
948 RT5640_PWR_HA);
949 usleep_range(10000, 15000);
950 regmap_update_bits(rt5640->regmap, RT5640_PWR_ANLG1,
951 RT5640_PWR_FV1 | RT5640_PWR_FV2 ,
952 RT5640_PWR_FV1 | RT5640_PWR_FV2);
953}
954
955static void rt5640_pmu_depop(struct snd_soc_codec *codec)
956{
957 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
958
959 regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M2,
960 RT5640_DEPOP_MASK | RT5640_DIG_DP_MASK,
961 RT5640_DEPOP_AUTO | RT5640_DIG_DP_EN);
962 regmap_update_bits(rt5640->regmap, RT5640_CHARGE_PUMP,
963 RT5640_PM_HP_MASK, RT5640_PM_HP_HV);
964
965 regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M3,
966 RT5640_CP_FQ1_MASK | RT5640_CP_FQ2_MASK | RT5640_CP_FQ3_MASK,
967 (RT5640_CP_FQ_192_KHZ << RT5640_CP_FQ1_SFT) |
968 (RT5640_CP_FQ_12_KHZ << RT5640_CP_FQ2_SFT) |
969 (RT5640_CP_FQ_192_KHZ << RT5640_CP_FQ3_SFT));
970
971 regmap_write(rt5640->regmap, RT5640_PR_BASE +
972 RT5640_MAMP_INT_REG2, 0x1c00);
973 regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M1,
974 RT5640_HP_CP_MASK | RT5640_HP_SG_MASK,
975 RT5640_HP_CP_PD | RT5640_HP_SG_EN);
976 regmap_update_bits(rt5640->regmap, RT5640_PR_BASE +
977 RT5640_CHPUMP_INT_REG1, 0x0700, 0x0400);
978}
979
980static int rt5640_hp_event(struct snd_soc_dapm_widget *w,
981 struct snd_kcontrol *kcontrol, int event)
982{
983 struct snd_soc_codec *codec = w->codec;
984 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
985
986 switch (event) {
987 case SND_SOC_DAPM_POST_PMU:
988 rt5640_pmu_depop(codec);
989 rt5640->hp_mute = 0;
990 break;
991
992 case SND_SOC_DAPM_PRE_PMD:
993 rt5640->hp_mute = 1;
994 usleep_range(70000, 75000);
995 break;
996
997 default:
998 return 0;
999 }
1000
1001 return 0;
1002}
1003
1004static int rt5640_hp_power_event(struct snd_soc_dapm_widget *w,
1005 struct snd_kcontrol *kcontrol, int event)
1006{
1007 struct snd_soc_codec *codec = w->codec;
1008
1009 switch (event) {
1010 case SND_SOC_DAPM_POST_PMU:
1011 hp_amp_power_on(codec);
1012 break;
1013 default:
1014 return 0;
1015 }
1016
1017 return 0;
1018}
1019
1020static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w,
1021 struct snd_kcontrol *kcontrol, int event)
1022{
1023 struct snd_soc_codec *codec = w->codec;
1024 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
1025
1026 switch (event) {
1027 case SND_SOC_DAPM_POST_PMU:
1028 if (!rt5640->hp_mute)
1029 usleep_range(80000, 85000);
1030
1031 break;
1032
1033 default:
1034 return 0;
1035 }
1036
1037 return 0;
1038}
1039
969static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { 1040static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
970 SND_SOC_DAPM_SUPPLY("PLL1", RT5640_PWR_ANLG2, 1041 SND_SOC_DAPM_SUPPLY("PLL1", RT5640_PWR_ANLG2,
971 RT5640_PWR_PLL_BIT, 0, NULL, 0), 1042 RT5640_PWR_PLL_BIT, 0, NULL, 0),
@@ -1005,9 +1076,6 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
1005 RT5640_PWR_IN_L_BIT, 0, NULL, 0), 1076 RT5640_PWR_IN_L_BIT, 0, NULL, 0),
1006 SND_SOC_DAPM_PGA("INR VOL", RT5640_PWR_VOL, 1077 SND_SOC_DAPM_PGA("INR VOL", RT5640_PWR_VOL,
1007 RT5640_PWR_IN_R_BIT, 0, NULL, 0), 1078 RT5640_PWR_IN_R_BIT, 0, NULL, 0),
1008 /* IN Mux */
1009 SND_SOC_DAPM_MUX("INL Mux", SND_SOC_NOPM, 0, 0, &rt5640_inl_mux),
1010 SND_SOC_DAPM_MUX("INR Mux", SND_SOC_NOPM, 0, 0, &rt5640_inr_mux),
1011 /* REC Mixer */ 1079 /* REC Mixer */
1012 SND_SOC_DAPM_MIXER("RECMIXL", RT5640_PWR_MIXER, RT5640_PWR_RM_L_BIT, 0, 1080 SND_SOC_DAPM_MIXER("RECMIXL", RT5640_PWR_MIXER, RT5640_PWR_RM_L_BIT, 0,
1013 rt5640_rec_l_mix, ARRAY_SIZE(rt5640_rec_l_mix)), 1081 rt5640_rec_l_mix, ARRAY_SIZE(rt5640_rec_l_mix)),
@@ -1158,15 +1226,28 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
1158 rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)), 1226 rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)),
1159 SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1, 1227 SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1,
1160 RT5640_PWR_MA_BIT, 0, NULL, 0), 1228 RT5640_PWR_MA_BIT, 0, NULL, 0),
1161 SND_SOC_DAPM_SUPPLY("Improve HP Amp Drv", RT5640_PWR_ANLG1, 1229 SND_SOC_DAPM_SUPPLY_S("Improve HP Amp Drv", 1, SND_SOC_NOPM,
1162 SND_SOC_NOPM, 0, NULL, 0), 1230 0, 0, rt5640_hp_power_event, SND_SOC_DAPM_POST_PMU),
1163 SND_SOC_DAPM_PGA("HP L Amp", RT5640_PWR_ANLG1, 1231 SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0,
1232 rt5640_hp_event,
1233 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1234 SND_SOC_DAPM_SUPPLY("HP L Amp", RT5640_PWR_ANLG1,
1164 RT5640_PWR_HP_L_BIT, 0, NULL, 0), 1235 RT5640_PWR_HP_L_BIT, 0, NULL, 0),
1165 SND_SOC_DAPM_PGA("HP R Amp", RT5640_PWR_ANLG1, 1236 SND_SOC_DAPM_SUPPLY("HP R Amp", RT5640_PWR_ANLG1,
1166 RT5640_PWR_HP_R_BIT, 0, NULL, 0), 1237 RT5640_PWR_HP_R_BIT, 0, NULL, 0),
1167 SND_SOC_DAPM_SUPPLY("Improve SPK Amp Drv", RT5640_PWR_DIG1, 1238 SND_SOC_DAPM_SUPPLY("Improve SPK Amp Drv", RT5640_PWR_DIG1,
1168 SND_SOC_NOPM, 0, spk_event, 1239 RT5640_PWR_CLS_D_BIT, 0, NULL, 0),
1169 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 1240
1241 /* Output Switch */
1242 SND_SOC_DAPM_SWITCH("Speaker L Playback", SND_SOC_NOPM, 0, 0,
1243 &spk_l_enable_control),
1244 SND_SOC_DAPM_SWITCH("Speaker R Playback", SND_SOC_NOPM, 0, 0,
1245 &spk_r_enable_control),
1246 SND_SOC_DAPM_SWITCH("HP L Playback", SND_SOC_NOPM, 0, 0,
1247 &hp_l_enable_control),
1248 SND_SOC_DAPM_SWITCH("HP R Playback", SND_SOC_NOPM, 0, 0,
1249 &hp_r_enable_control),
1250 SND_SOC_DAPM_POST("HP Post", rt5640_hp_post_event),
1170 /* Output Lines */ 1251 /* Output Lines */
1171 SND_SOC_DAPM_OUTPUT("SPOLP"), 1252 SND_SOC_DAPM_OUTPUT("SPOLP"),
1172 SND_SOC_DAPM_OUTPUT("SPOLN"), 1253 SND_SOC_DAPM_OUTPUT("SPOLN"),
@@ -1407,9 +1488,11 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
1407 {"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"}, 1488 {"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"},
1408 {"HPO MIX L", "HPO MIX DAC1 Switch", "DAC L1"}, 1489 {"HPO MIX L", "HPO MIX DAC1 Switch", "DAC L1"},
1409 {"HPO MIX L", "HPO MIX HPVOL Switch", "HPOVOL L"}, 1490 {"HPO MIX L", "HPO MIX HPVOL Switch", "HPOVOL L"},
1491 {"HPO MIX L", NULL, "HP L Amp"},
1410 {"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"}, 1492 {"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"},
1411 {"HPO MIX R", "HPO MIX DAC1 Switch", "DAC R1"}, 1493 {"HPO MIX R", "HPO MIX DAC1 Switch", "DAC R1"},
1412 {"HPO MIX R", "HPO MIX HPVOL Switch", "HPOVOL R"}, 1494 {"HPO MIX R", "HPO MIX HPVOL Switch", "HPOVOL R"},
1495 {"HPO MIX R", NULL, "HP R Amp"},
1413 1496
1414 {"LOUT MIX", "DAC L1 Switch", "DAC L1"}, 1497 {"LOUT MIX", "DAC L1 Switch", "DAC L1"},
1415 {"LOUT MIX", "DAC R1 Switch", "DAC R1"}, 1498 {"LOUT MIX", "DAC R1 Switch", "DAC R1"},
@@ -1422,13 +1505,15 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
1422 {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"}, 1505 {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"},
1423 {"Mono MIX", "BST1 Switch", "BST1"}, 1506 {"Mono MIX", "BST1 Switch", "BST1"},
1424 1507
1425 {"HP L Amp", NULL, "HPO MIX L"}, 1508 {"HP Amp", NULL, "HPO MIX L"},
1426 {"HP R Amp", NULL, "HPO MIX R"}, 1509 {"HP Amp", NULL, "HPO MIX R"},
1427 1510
1428 {"SPOLP", NULL, "SPOL MIX"}, 1511 {"Speaker L Playback", "Switch", "SPOL MIX"},
1429 {"SPOLN", NULL, "SPOL MIX"}, 1512 {"Speaker R Playback", "Switch", "SPOR MIX"},
1430 {"SPORP", NULL, "SPOR MIX"}, 1513 {"SPOLP", NULL, "Speaker L Playback"},
1431 {"SPORN", NULL, "SPOR MIX"}, 1514 {"SPOLN", NULL, "Speaker L Playback"},
1515 {"SPORP", NULL, "Speaker R Playback"},
1516 {"SPORN", NULL, "Speaker R Playback"},
1432 1517
1433 {"SPOLP", NULL, "Improve SPK Amp Drv"}, 1518 {"SPOLP", NULL, "Improve SPK Amp Drv"},
1434 {"SPOLN", NULL, "Improve SPK Amp Drv"}, 1519 {"SPOLN", NULL, "Improve SPK Amp Drv"},
@@ -1438,8 +1523,10 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
1438 {"HPOL", NULL, "Improve HP Amp Drv"}, 1523 {"HPOL", NULL, "Improve HP Amp Drv"},
1439 {"HPOR", NULL, "Improve HP Amp Drv"}, 1524 {"HPOR", NULL, "Improve HP Amp Drv"},
1440 1525
1441 {"HPOL", NULL, "HP L Amp"}, 1526 {"HP L Playback", "Switch", "HP Amp"},
1442 {"HPOR", NULL, "HP R Amp"}, 1527 {"HP R Playback", "Switch", "HP Amp"},
1528 {"HPOL", NULL, "HP L Playback"},
1529 {"HPOR", NULL, "HP R Playback"},
1443 {"LOUTL", NULL, "LOUT MIX"}, 1530 {"LOUTL", NULL, "LOUT MIX"},
1444 {"LOUTR", NULL, "LOUT MIX"}, 1531 {"LOUTR", NULL, "LOUT MIX"},
1445 {"MONOP", NULL, "Mono MIX"}, 1532 {"MONOP", NULL, "Mono MIX"},
@@ -1818,17 +1905,13 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
1818 RT5640_PWR_BG | RT5640_PWR_VREF2, 1905 RT5640_PWR_BG | RT5640_PWR_VREF2,
1819 RT5640_PWR_VREF1 | RT5640_PWR_MB | 1906 RT5640_PWR_VREF1 | RT5640_PWR_MB |
1820 RT5640_PWR_BG | RT5640_PWR_VREF2); 1907 RT5640_PWR_BG | RT5640_PWR_VREF2);
1821 mdelay(10); 1908 usleep_range(10000, 15000);
1822 snd_soc_update_bits(codec, RT5640_PWR_ANLG1, 1909 snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
1823 RT5640_PWR_FV1 | RT5640_PWR_FV2, 1910 RT5640_PWR_FV1 | RT5640_PWR_FV2,
1824 RT5640_PWR_FV1 | RT5640_PWR_FV2); 1911 RT5640_PWR_FV1 | RT5640_PWR_FV2);
1825 regcache_sync(rt5640->regmap); 1912 regcache_sync(rt5640->regmap);
1826 snd_soc_update_bits(codec, RT5640_DUMMY1, 1913 snd_soc_update_bits(codec, RT5640_DUMMY1,
1827 0x0301, 0x0301); 1914 0x0301, 0x0301);
1828 snd_soc_update_bits(codec, RT5640_DEPOP_M1,
1829 0x001d, 0x0019);
1830 snd_soc_update_bits(codec, RT5640_DEPOP_M2,
1831 0x2000, 0x2000);
1832 snd_soc_update_bits(codec, RT5640_MICBIAS, 1915 snd_soc_update_bits(codec, RT5640_MICBIAS,
1833 0x0030, 0x0030); 1916 0x0030, 0x0030);
1834 } 1917 }
@@ -1872,8 +1955,6 @@ static int rt5640_probe(struct snd_soc_codec *codec)
1872 rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF); 1955 rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF);
1873 1956
1874 snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301); 1957 snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301);
1875 snd_soc_update_bits(codec, RT5640_DEPOP_M1, 0x001d, 0x0019);
1876 snd_soc_update_bits(codec, RT5640_DEPOP_M2, 0x2000, 0x2000);
1877 snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030); 1958 snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030);
1878 snd_soc_update_bits(codec, RT5640_DSP_PATH2, 0xfc00, 0x0c00); 1959 snd_soc_update_bits(codec, RT5640_DSP_PATH2, 0xfc00, 0x0c00);
1879 1960
@@ -2095,6 +2176,8 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
2095 regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4, 2176 regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4,
2096 RT5640_IN_DF2, RT5640_IN_DF2); 2177 RT5640_IN_DF2, RT5640_IN_DF2);
2097 2178
2179 rt5640->hp_mute = 1;
2180
2098 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640, 2181 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640,
2099 rt5640_dai, ARRAY_SIZE(rt5640_dai)); 2182 rt5640_dai, ARRAY_SIZE(rt5640_dai));
2100 if (ret < 0) 2183 if (ret < 0)
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index c48286d7118f..5e8df25a13f3 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -145,6 +145,8 @@
145 145
146 146
147/* Index of Codec Private Register definition */ 147/* Index of Codec Private Register definition */
148#define RT5640_CHPUMP_INT_REG1 0x24
149#define RT5640_MAMP_INT_REG2 0x37
148#define RT5640_3D_SPK 0x63 150#define RT5640_3D_SPK 0x63
149#define RT5640_WND_1 0x6c 151#define RT5640_WND_1 0x6c
150#define RT5640_WND_2 0x6d 152#define RT5640_WND_2 0x6d
@@ -153,6 +155,7 @@
153#define RT5640_WND_5 0x70 155#define RT5640_WND_5 0x70
154#define RT5640_WND_8 0x73 156#define RT5640_WND_8 0x73
155#define RT5640_DIP_SPK_INF 0x75 157#define RT5640_DIP_SPK_INF 0x75
158#define RT5640_HP_DCC_INT1 0x77
156#define RT5640_EQ_BW_LOP 0xa0 159#define RT5640_EQ_BW_LOP 0xa0
157#define RT5640_EQ_GN_LOP 0xa1 160#define RT5640_EQ_GN_LOP 0xa1
158#define RT5640_EQ_FC_BP1 0xa2 161#define RT5640_EQ_FC_BP1 0xa2
@@ -1201,6 +1204,14 @@
1201#define RT5640_CP_FQ2_SFT 4 1204#define RT5640_CP_FQ2_SFT 4
1202#define RT5640_CP_FQ3_MASK (0x7) 1205#define RT5640_CP_FQ3_MASK (0x7)
1203#define RT5640_CP_FQ3_SFT 0 1206#define RT5640_CP_FQ3_SFT 0
1207#define RT5640_CP_FQ_1_5_KHZ 0
1208#define RT5640_CP_FQ_3_KHZ 1
1209#define RT5640_CP_FQ_6_KHZ 2
1210#define RT5640_CP_FQ_12_KHZ 3
1211#define RT5640_CP_FQ_24_KHZ 4
1212#define RT5640_CP_FQ_48_KHZ 5
1213#define RT5640_CP_FQ_96_KHZ 6
1214#define RT5640_CP_FQ_192_KHZ 7
1204 1215
1205/* HPOUT charge pump (0x91) */ 1216/* HPOUT charge pump (0x91) */
1206#define RT5640_OSW_L_MASK (0x1 << 11) 1217#define RT5640_OSW_L_MASK (0x1 << 11)
@@ -2087,6 +2098,7 @@ struct rt5640_priv {
2087 int pll_out; 2098 int pll_out;
2088 2099
2089 int dmic_en; 2100 int dmic_en;
2101 bool hp_mute;
2090}; 2102};
2091 2103
2092#endif 2104#endif
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 760e8bfeacaa..1f4093f3f3a1 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -654,16 +654,19 @@ static int sgtl5000_set_clock(struct snd_soc_codec *codec, int frame_rate)
654 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, 654 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
655 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP, 655 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
656 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP); 656 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP);
657
658 /* if using pll, clk_ctrl must be set after pll power up */
659 snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
657 } else { 660 } else {
661 /* otherwise, clk_ctrl must be set before pll power down */
662 snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
663
658 /* power down pll */ 664 /* power down pll */
659 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, 665 snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
660 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP, 666 SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP,
661 0); 667 0);
662 } 668 }
663 669
664 /* if using pll, clk_ctrl must be set after pll power up */
665 snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, clk_ctl);
666
667 return 0; 670 return 0;
668} 671}
669 672
@@ -1480,6 +1483,7 @@ static struct snd_soc_codec_driver sgtl5000_driver = {
1480static const struct regmap_config sgtl5000_regmap = { 1483static const struct regmap_config sgtl5000_regmap = {
1481 .reg_bits = 16, 1484 .reg_bits = 16,
1482 .val_bits = 16, 1485 .val_bits = 16,
1486 .reg_stride = 2,
1483 1487
1484 .max_register = SGTL5000_MAX_REG_OFFSET, 1488 .max_register = SGTL5000_MAX_REG_OFFSET,
1485 .volatile_reg = sgtl5000_volatile, 1489 .volatile_reg = sgtl5000_volatile,
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c
index 73e205c892a0..38f3b105c17d 100644
--- a/sound/soc/codecs/si476x.c
+++ b/sound/soc/codecs/si476x.c
@@ -102,6 +102,16 @@ static int si476x_codec_write(struct snd_soc_codec *codec,
102 return err; 102 return err;
103} 103}
104 104
105static const struct snd_soc_dapm_widget si476x_dapm_widgets[] = {
106SND_SOC_DAPM_OUTPUT("LOUT"),
107SND_SOC_DAPM_OUTPUT("ROUT"),
108};
109
110static const struct snd_soc_dapm_route si476x_dapm_routes[] = {
111 { "Capture", NULL, "LOUT" },
112 { "Capture", NULL, "ROUT" },
113};
114
105static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, 115static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
106 unsigned int fmt) 116 unsigned int fmt)
107{ 117{
@@ -260,6 +270,10 @@ static struct snd_soc_codec_driver soc_codec_dev_si476x = {
260 .probe = si476x_codec_probe, 270 .probe = si476x_codec_probe,
261 .read = si476x_codec_read, 271 .read = si476x_codec_read,
262 .write = si476x_codec_write, 272 .write = si476x_codec_write,
273 .dapm_widgets = si476x_dapm_widgets,
274 .num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets),
275 .dapm_routes = si476x_dapm_routes,
276 .num_dapm_routes = ARRAY_SIZE(si476x_dapm_routes),
263}; 277};
264 278
265static int si476x_platform_probe(struct platform_device *pdev) 279static int si476x_platform_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/spdif_receiver.c b/sound/soc/codecs/spdif_receiver.c
index e9d7881ed2c8..e3501f40c7b3 100644
--- a/sound/soc/codecs/spdif_receiver.c
+++ b/sound/soc/codecs/spdif_receiver.c
@@ -23,11 +23,26 @@
23#include <sound/initval.h> 23#include <sound/initval.h>
24#include <linux/of.h> 24#include <linux/of.h>
25 25
26static const struct snd_soc_dapm_widget dir_widgets[] = {
27 SND_SOC_DAPM_INPUT("spdif-in"),
28};
29
30static const struct snd_soc_dapm_route dir_routes[] = {
31 { "Capture", NULL, "spdif-in" },
32};
33
26#define STUB_RATES SNDRV_PCM_RATE_8000_192000 34#define STUB_RATES SNDRV_PCM_RATE_8000_192000
27#define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 35#define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
36 SNDRV_PCM_FMTBIT_S20_3LE | \
37 SNDRV_PCM_FMTBIT_S24_LE | \
28 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) 38 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
29 39
30static struct snd_soc_codec_driver soc_codec_spdif_dir; 40static struct snd_soc_codec_driver soc_codec_spdif_dir = {
41 .dapm_widgets = dir_widgets,
42 .num_dapm_widgets = ARRAY_SIZE(dir_widgets),
43 .dapm_routes = dir_routes,
44 .num_dapm_routes = ARRAY_SIZE(dir_routes),
45};
31 46
32static struct snd_soc_dai_driver dir_stub_dai = { 47static struct snd_soc_dai_driver dir_stub_dai = {
33 .name = "dir-hifi", 48 .name = "dir-hifi",
diff --git a/sound/soc/codecs/spdif_transmitter.c b/sound/soc/codecs/spdif_transmitter.c
index 18280499fd55..a078aa31052a 100644
--- a/sound/soc/codecs/spdif_transmitter.c
+++ b/sound/soc/codecs/spdif_transmitter.c
@@ -25,10 +25,24 @@
25#define DRV_NAME "spdif-dit" 25#define DRV_NAME "spdif-dit"
26 26
27#define STUB_RATES SNDRV_PCM_RATE_8000_96000 27#define STUB_RATES SNDRV_PCM_RATE_8000_96000
28#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE 28#define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
29 SNDRV_PCM_FMTBIT_S20_3LE | \
30 SNDRV_PCM_FMTBIT_S24_LE)
29 31
32static const struct snd_soc_dapm_widget dit_widgets[] = {
33 SND_SOC_DAPM_OUTPUT("spdif-out"),
34};
35
36static const struct snd_soc_dapm_route dit_routes[] = {
37 { "spdif-out", NULL, "Playback" },
38};
30 39
31static struct snd_soc_codec_driver soc_codec_spdif_dit; 40static struct snd_soc_codec_driver soc_codec_spdif_dit = {
41 .dapm_widgets = dit_widgets,
42 .num_dapm_widgets = ARRAY_SIZE(dit_widgets),
43 .dapm_routes = dit_routes,
44 .num_dapm_routes = ARRAY_SIZE(dit_routes),
45};
32 46
33static struct snd_soc_dai_driver dit_stub_dai = { 47static struct snd_soc_dai_driver dit_stub_dai = {
34 .name = "dit-hifi", 48 .name = "dit-hifi",
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index f8d30e5f6371..492644e67ace 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -561,8 +561,9 @@ static int ssm2602_suspend(struct snd_soc_codec *codec)
561 561
562static int ssm2602_resume(struct snd_soc_codec *codec) 562static int ssm2602_resume(struct snd_soc_codec *codec)
563{ 563{
564 snd_soc_cache_sync(codec); 564 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
565 565
566 regcache_sync(ssm2602->regmap);
566 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 567 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
567 568
568 return 0; 569 return 0;
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index cfb55fe35e98..06edb396e733 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -363,16 +363,18 @@ static void sta32x_watchdog(struct work_struct *work)
363 } 363 }
364 364
365 if (!sta32x->shutdown) 365 if (!sta32x->shutdown)
366 schedule_delayed_work(&sta32x->watchdog_work, 366 queue_delayed_work(system_power_efficient_wq,
367 round_jiffies_relative(HZ)); 367 &sta32x->watchdog_work,
368 round_jiffies_relative(HZ));
368} 369}
369 370
370static void sta32x_watchdog_start(struct sta32x_priv *sta32x) 371static void sta32x_watchdog_start(struct sta32x_priv *sta32x)
371{ 372{
372 if (sta32x->pdata->needs_esd_watchdog) { 373 if (sta32x->pdata->needs_esd_watchdog) {
373 sta32x->shutdown = 0; 374 sta32x->shutdown = 0;
374 schedule_delayed_work(&sta32x->watchdog_work, 375 queue_delayed_work(system_power_efficient_wq,
375 round_jiffies_relative(HZ)); 376 &sta32x->watchdog_work,
377 round_jiffies_relative(HZ));
376 } 378 }
377} 379}
378 380
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index b1f6982c7c9c..7b8f3d965f43 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -29,7 +29,7 @@ MODULE_LICENSE("GPL");
29/* AIC26 driver private data */ 29/* AIC26 driver private data */
30struct aic26 { 30struct aic26 {
31 struct spi_device *spi; 31 struct spi_device *spi;
32 struct snd_soc_codec codec; 32 struct snd_soc_codec *codec;
33 int master; 33 int master;
34 int datfm; 34 int datfm;
35 int mclk; 35 int mclk;
@@ -119,6 +119,22 @@ static int aic26_reg_write(struct snd_soc_codec *codec, unsigned int reg,
119 return 0; 119 return 0;
120} 120}
121 121
122static const struct snd_soc_dapm_widget tlv320aic26_dapm_widgets[] = {
123SND_SOC_DAPM_INPUT("MICIN"),
124SND_SOC_DAPM_INPUT("AUX"),
125
126SND_SOC_DAPM_OUTPUT("HPL"),
127SND_SOC_DAPM_OUTPUT("HPR"),
128};
129
130static const struct snd_soc_dapm_route tlv320aic26_dapm_routes[] = {
131 { "Capture", NULL, "MICIN" },
132 { "Capture", NULL, "AUX" },
133
134 { "HPL", NULL, "Playback" },
135 { "HPR", NULL, "Playback" },
136};
137
122/* --------------------------------------------------------------------- 138/* ---------------------------------------------------------------------
123 * Digital Audio Interface Operations 139 * Digital Audio Interface Operations
124 */ 140 */
@@ -174,9 +190,9 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
174 dev_dbg(&aic26->spi->dev, "Setting PLLM to %d.%04d\n", jval, dval); 190 dev_dbg(&aic26->spi->dev, "Setting PLLM to %d.%04d\n", jval, dval);
175 qval = 0; 191 qval = 0;
176 reg = 0x8000 | qval << 11 | pval << 8 | jval << 2; 192 reg = 0x8000 | qval << 11 | pval << 8 | jval << 2;
177 aic26_reg_write(codec, AIC26_REG_PLL_PROG1, reg); 193 snd_soc_write(codec, AIC26_REG_PLL_PROG1, reg);
178 reg = dval << 2; 194 reg = dval << 2;
179 aic26_reg_write(codec, AIC26_REG_PLL_PROG2, reg); 195 snd_soc_write(codec, AIC26_REG_PLL_PROG2, reg);
180 196
181 /* Audio Control 3 (master mode, fsref rate) */ 197 /* Audio Control 3 (master mode, fsref rate) */
182 reg = aic26_reg_read_cache(codec, AIC26_REG_AUDIO_CTRL3); 198 reg = aic26_reg_read_cache(codec, AIC26_REG_AUDIO_CTRL3);
@@ -185,13 +201,13 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
185 reg |= 0x0800; 201 reg |= 0x0800;
186 if (fsref == 48000) 202 if (fsref == 48000)
187 reg |= 0x2000; 203 reg |= 0x2000;
188 aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL3, reg); 204 snd_soc_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
189 205
190 /* Audio Control 1 (FSref divisor) */ 206 /* Audio Control 1 (FSref divisor) */
191 reg = aic26_reg_read_cache(codec, AIC26_REG_AUDIO_CTRL1); 207 reg = aic26_reg_read_cache(codec, AIC26_REG_AUDIO_CTRL1);
192 reg &= ~0x0fff; 208 reg &= ~0x0fff;
193 reg |= wlen | aic26->datfm | (divisor << 3) | divisor; 209 reg |= wlen | aic26->datfm | (divisor << 3) | divisor;
194 aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL1, reg); 210 snd_soc_write(codec, AIC26_REG_AUDIO_CTRL1, reg);
195 211
196 return 0; 212 return 0;
197} 213}
@@ -212,7 +228,7 @@ static int aic26_mute(struct snd_soc_dai *dai, int mute)
212 reg |= 0x8080; 228 reg |= 0x8080;
213 else 229 else
214 reg &= ~0x8080; 230 reg &= ~0x8080;
215 aic26_reg_write(codec, AIC26_REG_DAC_GAIN, reg); 231 snd_soc_write(codec, AIC26_REG_DAC_GAIN, reg);
216 232
217 return 0; 233 return 0;
218} 234}
@@ -330,7 +346,7 @@ static ssize_t aic26_keyclick_show(struct device *dev,
330 struct aic26 *aic26 = dev_get_drvdata(dev); 346 struct aic26 *aic26 = dev_get_drvdata(dev);
331 int val, amp, freq, len; 347 int val, amp, freq, len;
332 348
333 val = aic26_reg_read_cache(&aic26->codec, AIC26_REG_AUDIO_CTRL2); 349 val = aic26_reg_read_cache(aic26->codec, AIC26_REG_AUDIO_CTRL2);
334 amp = (val >> 12) & 0x7; 350 amp = (val >> 12) & 0x7;
335 freq = (125 << ((val >> 8) & 0x7)) >> 1; 351 freq = (125 << ((val >> 8) & 0x7)) >> 1;
336 len = 2 * (1 + ((val >> 4) & 0xf)); 352 len = 2 * (1 + ((val >> 4) & 0xf));
@@ -346,9 +362,9 @@ static ssize_t aic26_keyclick_set(struct device *dev,
346 struct aic26 *aic26 = dev_get_drvdata(dev); 362 struct aic26 *aic26 = dev_get_drvdata(dev);
347 int val; 363 int val;
348 364
349 val = aic26_reg_read_cache(&aic26->codec, AIC26_REG_AUDIO_CTRL2); 365 val = aic26_reg_read_cache(aic26->codec, AIC26_REG_AUDIO_CTRL2);
350 val |= 0x8000; 366 val |= 0x8000;
351 aic26_reg_write(&aic26->codec, AIC26_REG_AUDIO_CTRL2, val); 367 snd_soc_write(aic26->codec, AIC26_REG_AUDIO_CTRL2, val);
352 368
353 return count; 369 return count;
354} 370}
@@ -360,25 +376,26 @@ static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
360 */ 376 */
361static int aic26_probe(struct snd_soc_codec *codec) 377static int aic26_probe(struct snd_soc_codec *codec)
362{ 378{
379 struct aic26 *aic26 = dev_get_drvdata(codec->dev);
363 int ret, err, i, reg; 380 int ret, err, i, reg;
364 381
365 dev_info(codec->dev, "Probing AIC26 SoC CODEC driver\n"); 382 aic26->codec = codec;
366 383
367 /* Reset the codec to power on defaults */ 384 /* Reset the codec to power on defaults */
368 aic26_reg_write(codec, AIC26_REG_RESET, 0xBB00); 385 snd_soc_write(codec, AIC26_REG_RESET, 0xBB00);
369 386
370 /* Power up CODEC */ 387 /* Power up CODEC */
371 aic26_reg_write(codec, AIC26_REG_POWER_CTRL, 0); 388 snd_soc_write(codec, AIC26_REG_POWER_CTRL, 0);
372 389
373 /* Audio Control 3 (master mode, fsref rate) */ 390 /* Audio Control 3 (master mode, fsref rate) */
374 reg = aic26_reg_read(codec, AIC26_REG_AUDIO_CTRL3); 391 reg = snd_soc_read(codec, AIC26_REG_AUDIO_CTRL3);
375 reg &= ~0xf800; 392 reg &= ~0xf800;
376 reg |= 0x0800; /* set master mode */ 393 reg |= 0x0800; /* set master mode */
377 aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL3, reg); 394 snd_soc_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
378 395
379 /* Fill register cache */ 396 /* Fill register cache */
380 for (i = 0; i < codec->driver->reg_cache_size; i++) 397 for (i = 0; i < codec->driver->reg_cache_size; i++)
381 aic26_reg_read(codec, i); 398 snd_soc_read(codec, i);
382 399
383 /* Register the sysfs files for debugging */ 400 /* Register the sysfs files for debugging */
384 /* Create SysFS files */ 401 /* Create SysFS files */
@@ -401,6 +418,10 @@ static struct snd_soc_codec_driver aic26_soc_codec_dev = {
401 .write = aic26_reg_write, 418 .write = aic26_reg_write,
402 .reg_cache_size = AIC26_NUM_REGS, 419 .reg_cache_size = AIC26_NUM_REGS,
403 .reg_word_size = sizeof(u16), 420 .reg_word_size = sizeof(u16),
421 .dapm_widgets = tlv320aic26_dapm_widgets,
422 .num_dapm_widgets = ARRAY_SIZE(tlv320aic26_dapm_widgets),
423 .dapm_routes = tlv320aic26_dapm_routes,
424 .num_dapm_routes = ARRAY_SIZE(tlv320aic26_dapm_routes),
404}; 425};
405 426
406/* --------------------------------------------------------------------- 427/* ---------------------------------------------------------------------
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index 17df4e32feac..2ed57d4aa445 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -338,18 +338,6 @@ static inline int aic32x4_get_divs(int mclk, int rate)
338 return -EINVAL; 338 return -EINVAL;
339} 339}
340 340
341static int aic32x4_add_widgets(struct snd_soc_codec *codec)
342{
343 snd_soc_dapm_new_controls(&codec->dapm, aic32x4_dapm_widgets,
344 ARRAY_SIZE(aic32x4_dapm_widgets));
345
346 snd_soc_dapm_add_routes(&codec->dapm, aic32x4_dapm_routes,
347 ARRAY_SIZE(aic32x4_dapm_routes));
348
349 snd_soc_dapm_new_widgets(&codec->dapm);
350 return 0;
351}
352
353static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai, 341static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
354 int clk_id, unsigned int freq, int dir) 342 int clk_id, unsigned int freq, int dir)
355{ 343{
@@ -683,9 +671,6 @@ static int aic32x4_probe(struct snd_soc_codec *codec)
683 } 671 }
684 672
685 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 673 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
686 snd_soc_add_codec_controls(codec, aic32x4_snd_controls,
687 ARRAY_SIZE(aic32x4_snd_controls));
688 aic32x4_add_widgets(codec);
689 674
690 /* 675 /*
691 * Workaround: for an unknown reason, the ADC needs to be powered up 676 * Workaround: for an unknown reason, the ADC needs to be powered up
@@ -714,6 +699,13 @@ static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = {
714 .suspend = aic32x4_suspend, 699 .suspend = aic32x4_suspend,
715 .resume = aic32x4_resume, 700 .resume = aic32x4_resume,
716 .set_bias_level = aic32x4_set_bias_level, 701 .set_bias_level = aic32x4_set_bias_level,
702
703 .controls = aic32x4_snd_controls,
704 .num_controls = ARRAY_SIZE(aic32x4_snd_controls),
705 .dapm_widgets = aic32x4_dapm_widgets,
706 .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets),
707 .dapm_routes = aic32x4_dapm_routes,
708 .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes),
717}; 709};
718 710
719static int aic32x4_i2c_probe(struct i2c_client *i2c, 711static int aic32x4_i2c_probe(struct i2c_client *i2c,
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index e5b926883131..6e3f269243e0 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -138,8 +138,7 @@ static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = {
138static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, 138static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
139 struct snd_ctl_elem_value *ucontrol) 139 struct snd_ctl_elem_value *ucontrol)
140{ 140{
141 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 141 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
142 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
143 struct soc_mixer_control *mc = 142 struct soc_mixer_control *mc =
144 (struct soc_mixer_control *)kcontrol->private_value; 143 (struct soc_mixer_control *)kcontrol->private_value;
145 unsigned int reg = mc->reg; 144 unsigned int reg = mc->reg;
@@ -147,10 +146,9 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
147 int max = mc->max; 146 int max = mc->max;
148 unsigned int mask = (1 << fls(max)) - 1; 147 unsigned int mask = (1 << fls(max)) - 1;
149 unsigned int invert = mc->invert; 148 unsigned int invert = mc->invert;
150 unsigned short val, val_mask; 149 unsigned short val;
151 int ret; 150 struct snd_soc_dapm_update update;
152 struct snd_soc_dapm_path *path; 151 int connect, change;
153 int found = 0;
154 152
155 val = (ucontrol->value.integer.value[0] & mask); 153 val = (ucontrol->value.integer.value[0] & mask);
156 154
@@ -158,42 +156,26 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
158 if (val) 156 if (val)
159 val = mask; 157 val = mask;
160 158
159 connect = !!val;
160
161 if (invert) 161 if (invert)
162 val = mask - val; 162 val = mask - val;
163 val_mask = mask << shift;
164 val = val << shift;
165
166 mutex_lock(&widget->codec->mutex);
167 163
168 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) { 164 mask <<= shift;
169 /* find dapm widget path assoc with kcontrol */ 165 val <<= shift;
170 list_for_each_entry(path, &widget->dapm->card->paths, list) {
171 if (path->kcontrol != kcontrol)
172 continue;
173 166
174 /* found, now check type */ 167 change = snd_soc_test_bits(codec, val, mask, reg);
175 found = 1; 168 if (change) {
176 if (val) 169 update.kcontrol = kcontrol;
177 /* new connection */ 170 update.reg = reg;
178 path->connect = invert ? 0 : 1; 171 update.mask = mask;
179 else 172 update.val = val;
180 /* old connection must be powered down */
181 path->connect = invert ? 1 : 0;
182 173
183 dapm_mark_dirty(path->source, "tlv320aic3x source"); 174 snd_soc_dapm_mixer_update_power(&codec->dapm, kcontrol, connect,
184 dapm_mark_dirty(path->sink, "tlv320aic3x sink"); 175 &update);
185
186 break;
187 }
188 } 176 }
189 177
190 mutex_unlock(&widget->codec->mutex); 178 return change;
191
192 if (found)
193 snd_soc_dapm_sync(widget->dapm);
194
195 ret = snd_soc_update_bits_locked(widget->codec, reg, val_mask, val);
196 return ret;
197} 179}
198 180
199/* 181/*
@@ -1492,6 +1474,7 @@ static const struct i2c_device_id aic3x_i2c_id[] = {
1492 { "tlv320aic3x", AIC3X_MODEL_3X }, 1474 { "tlv320aic3x", AIC3X_MODEL_3X },
1493 { "tlv320aic33", AIC3X_MODEL_33 }, 1475 { "tlv320aic33", AIC3X_MODEL_33 },
1494 { "tlv320aic3007", AIC3X_MODEL_3007 }, 1476 { "tlv320aic3007", AIC3X_MODEL_3007 },
1477 { "tlv320aic3106", AIC3X_MODEL_3X },
1495 { } 1478 { }
1496}; 1479};
1497MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); 1480MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
@@ -1582,6 +1565,9 @@ static int aic3x_i2c_remove(struct i2c_client *client)
1582#if defined(CONFIG_OF) 1565#if defined(CONFIG_OF)
1583static const struct of_device_id tlv320aic3x_of_match[] = { 1566static const struct of_device_id tlv320aic3x_of_match[] = {
1584 { .compatible = "ti,tlv320aic3x", }, 1567 { .compatible = "ti,tlv320aic3x", },
1568 { .compatible = "ti,tlv320aic33" },
1569 { .compatible = "ti,tlv320aic3007" },
1570 { .compatible = "ti,tlv320aic3106" },
1585 {}, 1571 {},
1586}; 1572};
1587MODULE_DEVICE_TABLE(of, tlv320aic3x_of_match); 1573MODULE_DEVICE_TABLE(of, tlv320aic3x_of_match);
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 8e6e5b016021..1e3884d6b3fb 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -137,8 +137,6 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
137 137
138/* codec private data */ 138/* codec private data */
139struct twl4030_priv { 139struct twl4030_priv {
140 struct snd_soc_codec codec;
141
142 unsigned int codec_powered; 140 unsigned int codec_powered;
143 141
144 /* reference counts of AIF/APLL users */ 142 /* reference counts of AIF/APLL users */
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 44621ddc332d..3c79dbb6c323 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -429,7 +429,8 @@ static irqreturn_t twl6040_audio_handler(int irq, void *data)
429 struct snd_soc_codec *codec = data; 429 struct snd_soc_codec *codec = data;
430 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 430 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
431 431
432 schedule_delayed_work(&priv->hs_jack.work, msecs_to_jiffies(200)); 432 queue_delayed_work(system_power_efficient_wq,
433 &priv->hs_jack.work, msecs_to_jiffies(200));
433 434
434 return IRQ_HANDLED; 435 return IRQ_HANDLED;
435} 436}
@@ -437,9 +438,7 @@ static irqreturn_t twl6040_audio_handler(int irq, void *data)
437static int twl6040_soc_dapm_put_vibra_enum(struct snd_kcontrol *kcontrol, 438static int twl6040_soc_dapm_put_vibra_enum(struct snd_kcontrol *kcontrol,
438 struct snd_ctl_elem_value *ucontrol) 439 struct snd_ctl_elem_value *ucontrol)
439{ 440{
440 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 441 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
441 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
442 struct snd_soc_codec *codec = widget->codec;
443 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 442 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
444 unsigned int val; 443 unsigned int val;
445 444
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 6d0aa44c3757..c94d4c1e3dac 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -325,7 +325,6 @@ static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
325static int uda134x_set_bias_level(struct snd_soc_codec *codec, 325static int uda134x_set_bias_level(struct snd_soc_codec *codec,
326 enum snd_soc_bias_level level) 326 enum snd_soc_bias_level level)
327{ 327{
328 u8 reg;
329 struct uda134x_platform_data *pd = codec->control_data; 328 struct uda134x_platform_data *pd = codec->control_data;
330 int i; 329 int i;
331 u8 *cache = codec->reg_cache; 330 u8 *cache = codec->reg_cache;
@@ -334,23 +333,6 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec,
334 333
335 switch (level) { 334 switch (level) {
336 case SND_SOC_BIAS_ON: 335 case SND_SOC_BIAS_ON:
337 /* ADC, DAC on */
338 switch (pd->model) {
339 case UDA134X_UDA1340:
340 case UDA134X_UDA1344:
341 case UDA134X_UDA1345:
342 reg = uda134x_read_reg_cache(codec, UDA134X_DATA011);
343 uda134x_write(codec, UDA134X_DATA011, reg | 0x03);
344 break;
345 case UDA134X_UDA1341:
346 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
347 uda134x_write(codec, UDA134X_STATUS1, reg | 0x03);
348 break;
349 default:
350 printk(KERN_ERR "UDA134X SoC codec: "
351 "unsupported model %d\n", pd->model);
352 return -EINVAL;
353 }
354 break; 336 break;
355 case SND_SOC_BIAS_PREPARE: 337 case SND_SOC_BIAS_PREPARE:
356 /* power on */ 338 /* power on */
@@ -362,23 +344,6 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec,
362 } 344 }
363 break; 345 break;
364 case SND_SOC_BIAS_STANDBY: 346 case SND_SOC_BIAS_STANDBY:
365 /* ADC, DAC power off */
366 switch (pd->model) {
367 case UDA134X_UDA1340:
368 case UDA134X_UDA1344:
369 case UDA134X_UDA1345:
370 reg = uda134x_read_reg_cache(codec, UDA134X_DATA011);
371 uda134x_write(codec, UDA134X_DATA011, reg & ~(0x03));
372 break;
373 case UDA134X_UDA1341:
374 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
375 uda134x_write(codec, UDA134X_STATUS1, reg & ~(0x03));
376 break;
377 default:
378 printk(KERN_ERR "UDA134X SoC codec: "
379 "unsupported model %d\n", pd->model);
380 return -EINVAL;
381 }
382 break; 347 break;
383 case SND_SOC_BIAS_OFF: 348 case SND_SOC_BIAS_OFF:
384 /* power off */ 349 /* power off */
@@ -450,6 +415,37 @@ SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
450SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0), 415SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
451}; 416};
452 417
418/* UDA1341 has the DAC/ADC power down in STATUS1 */
419static const struct snd_soc_dapm_widget uda1341_dapm_widgets[] = {
420 SND_SOC_DAPM_DAC("DAC", "Playback", UDA134X_STATUS1, 0, 0),
421 SND_SOC_DAPM_ADC("ADC", "Capture", UDA134X_STATUS1, 1, 0),
422};
423
424/* UDA1340/4/5 has the DAC/ADC pwoer down in DATA0 11 */
425static const struct snd_soc_dapm_widget uda1340_dapm_widgets[] = {
426 SND_SOC_DAPM_DAC("DAC", "Playback", UDA134X_DATA011, 0, 0),
427 SND_SOC_DAPM_ADC("ADC", "Capture", UDA134X_DATA011, 1, 0),
428};
429
430/* Common DAPM widgets */
431static const struct snd_soc_dapm_widget uda134x_dapm_widgets[] = {
432 SND_SOC_DAPM_INPUT("VINL1"),
433 SND_SOC_DAPM_INPUT("VINR1"),
434 SND_SOC_DAPM_INPUT("VINL2"),
435 SND_SOC_DAPM_INPUT("VINR2"),
436 SND_SOC_DAPM_OUTPUT("VOUTL"),
437 SND_SOC_DAPM_OUTPUT("VOUTR"),
438};
439
440static const struct snd_soc_dapm_route uda134x_dapm_routes[] = {
441 { "ADC", NULL, "VINL1" },
442 { "ADC", NULL, "VINR1" },
443 { "ADC", NULL, "VINL2" },
444 { "ADC", NULL, "VINR2" },
445 { "VOUTL", NULL, "DAC" },
446 { "VOUTR", NULL, "DAC" },
447};
448
453static const struct snd_soc_dai_ops uda134x_dai_ops = { 449static const struct snd_soc_dai_ops uda134x_dai_ops = {
454 .startup = uda134x_startup, 450 .startup = uda134x_startup,
455 .shutdown = uda134x_shutdown, 451 .shutdown = uda134x_shutdown,
@@ -485,6 +481,8 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec)
485{ 481{
486 struct uda134x_priv *uda134x; 482 struct uda134x_priv *uda134x;
487 struct uda134x_platform_data *pd = codec->card->dev->platform_data; 483 struct uda134x_platform_data *pd = codec->card->dev->platform_data;
484 const struct snd_soc_dapm_widget *widgets;
485 unsigned num_widgets;
488 486
489 int ret; 487 int ret;
490 488
@@ -526,6 +524,22 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec)
526 else 524 else
527 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 525 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
528 526
527 if (pd->model == UDA134X_UDA1341) {
528 widgets = uda1341_dapm_widgets;
529 num_widgets = ARRAY_SIZE(uda1341_dapm_widgets);
530 } else {
531 widgets = uda1340_dapm_widgets;
532 num_widgets = ARRAY_SIZE(uda1340_dapm_widgets);
533 }
534
535 ret = snd_soc_dapm_new_controls(&codec->dapm, widgets, num_widgets);
536 if (ret) {
537 printk(KERN_ERR "%s failed to register dapm controls: %d",
538 __func__, ret);
539 kfree(uda134x);
540 return ret;
541 }
542
529 switch (pd->model) { 543 switch (pd->model) {
530 case UDA134X_UDA1340: 544 case UDA134X_UDA1340:
531 case UDA134X_UDA1344: 545 case UDA134X_UDA1344:
@@ -599,6 +613,10 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = {
599 .read = uda134x_read_reg_cache, 613 .read = uda134x_read_reg_cache,
600 .write = uda134x_write, 614 .write = uda134x_write,
601 .set_bias_level = uda134x_set_bias_level, 615 .set_bias_level = uda134x_set_bias_level,
616 .dapm_widgets = uda134x_dapm_widgets,
617 .num_dapm_widgets = ARRAY_SIZE(uda134x_dapm_widgets),
618 .dapm_routes = uda134x_dapm_routes,
619 .num_dapm_routes = ARRAY_SIZE(uda134x_dapm_routes),
602}; 620};
603 621
604static int uda134x_codec_probe(struct platform_device *pdev) 622static int uda134x_codec_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 54cd3da09abd..b7ab2ef567c8 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -290,6 +290,18 @@ static const struct snd_kcontrol_new wl1273_controls[] = {
290 snd_wl1273_fm_volume_get, snd_wl1273_fm_volume_put), 290 snd_wl1273_fm_volume_get, snd_wl1273_fm_volume_put),
291}; 291};
292 292
293static const struct snd_soc_dapm_widget wl1273_dapm_widgets[] = {
294 SND_SOC_DAPM_INPUT("RX"),
295
296 SND_SOC_DAPM_OUTPUT("TX"),
297};
298
299static const struct snd_soc_dapm_route wl1273_dapm_routes[] = {
300 { "Capture", NULL, "RX" },
301
302 { "TX", NULL, "Playback" },
303};
304
293static int wl1273_startup(struct snd_pcm_substream *substream, 305static int wl1273_startup(struct snd_pcm_substream *substream,
294 struct snd_soc_dai *dai) 306 struct snd_soc_dai *dai)
295{ 307{
@@ -483,6 +495,11 @@ static int wl1273_remove(struct snd_soc_codec *codec)
483static struct snd_soc_codec_driver soc_codec_dev_wl1273 = { 495static struct snd_soc_codec_driver soc_codec_dev_wl1273 = {
484 .probe = wl1273_probe, 496 .probe = wl1273_probe,
485 .remove = wl1273_remove, 497 .remove = wl1273_remove,
498
499 .dapm_widgets = wl1273_dapm_widgets,
500 .num_dapm_widgets = ARRAY_SIZE(wl1273_dapm_widgets),
501 .dapm_routes = wl1273_dapm_routes,
502 .num_dapm_routes = ARRAY_SIZE(wl1273_dapm_routes),
486}; 503};
487 504
488static int wl1273_platform_probe(struct platform_device *pdev) 505static int wl1273_platform_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c
index 10adc4145d46..d5ebcb00019b 100644
--- a/sound/soc/codecs/wm0010.c
+++ b/sound/soc/codecs/wm0010.c
@@ -420,7 +420,7 @@ static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec)
420 xfer->codec = codec; 420 xfer->codec = codec;
421 list_add_tail(&xfer->list, &xfer_list); 421 list_add_tail(&xfer->list, &xfer_list);
422 422
423 out = kzalloc(len, GFP_KERNEL); 423 out = kzalloc(len, GFP_KERNEL | GFP_DMA);
424 if (!out) { 424 if (!out) {
425 dev_err(codec->dev, 425 dev_err(codec->dev,
426 "Failed to allocate RX buffer\n"); 426 "Failed to allocate RX buffer\n");
@@ -429,7 +429,7 @@ static int wm0010_firmware_load(const char *name, struct snd_soc_codec *codec)
429 } 429 }
430 xfer->t.rx_buf = out; 430 xfer->t.rx_buf = out;
431 431
432 img = kzalloc(len, GFP_KERNEL); 432 img = kzalloc(len, GFP_KERNEL | GFP_DMA);
433 if (!img) { 433 if (!img) {
434 dev_err(codec->dev, 434 dev_err(codec->dev,
435 "Failed to allocate image buffer\n"); 435 "Failed to allocate image buffer\n");
@@ -523,14 +523,14 @@ static int wm0010_stage2_load(struct snd_soc_codec *codec)
523 dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size); 523 dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size);
524 524
525 /* Copy to local buffer first as vmalloc causes problems for dma */ 525 /* Copy to local buffer first as vmalloc causes problems for dma */
526 img = kzalloc(fw->size, GFP_KERNEL); 526 img = kzalloc(fw->size, GFP_KERNEL | GFP_DMA);
527 if (!img) { 527 if (!img) {
528 dev_err(codec->dev, "Failed to allocate image buffer\n"); 528 dev_err(codec->dev, "Failed to allocate image buffer\n");
529 ret = -ENOMEM; 529 ret = -ENOMEM;
530 goto abort2; 530 goto abort2;
531 } 531 }
532 532
533 out = kzalloc(fw->size, GFP_KERNEL); 533 out = kzalloc(fw->size, GFP_KERNEL | GFP_DMA);
534 if (!out) { 534 if (!out) {
535 dev_err(codec->dev, "Failed to allocate output buffer\n"); 535 dev_err(codec->dev, "Failed to allocate output buffer\n");
536 ret = -ENOMEM; 536 ret = -ENOMEM;
@@ -670,14 +670,14 @@ static int wm0010_boot(struct snd_soc_codec *codec)
670 670
671 ret = -ENOMEM; 671 ret = -ENOMEM;
672 len = pll_rec.length + 8; 672 len = pll_rec.length + 8;
673 out = kzalloc(len, GFP_KERNEL); 673 out = kzalloc(len, GFP_KERNEL | GFP_DMA);
674 if (!out) { 674 if (!out) {
675 dev_err(codec->dev, 675 dev_err(codec->dev,
676 "Failed to allocate RX buffer\n"); 676 "Failed to allocate RX buffer\n");
677 goto abort; 677 goto abort;
678 } 678 }
679 679
680 img_swap = kzalloc(len, GFP_KERNEL); 680 img_swap = kzalloc(len, GFP_KERNEL | GFP_DMA);
681 if (!img_swap) { 681 if (!img_swap) {
682 dev_err(codec->dev, 682 dev_err(codec->dev,
683 "Failed to allocate image buffer\n"); 683 "Failed to allocate image buffer\n");
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index 282fd232cdf7..8bbddc151aa8 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -998,6 +998,8 @@ SND_SOC_DAPM_INPUT("IN2R"),
998SND_SOC_DAPM_INPUT("IN3L"), 998SND_SOC_DAPM_INPUT("IN3L"),
999SND_SOC_DAPM_INPUT("IN3R"), 999SND_SOC_DAPM_INPUT("IN3R"),
1000 1000
1001SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
1002
1001SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, 1003SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
1002 0, NULL, 0, arizona_in_ev, 1004 0, NULL, 0, arizona_in_ev,
1003 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 1005 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
@@ -1421,9 +1423,6 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1421 { "Tone Generator 1", NULL, "TONE" }, 1423 { "Tone Generator 1", NULL, "TONE" },
1422 { "Tone Generator 2", NULL, "TONE" }, 1424 { "Tone Generator 2", NULL, "TONE" },
1423 1425
1424 { "Mic Mute Mixer", NULL, "Noise Mixer" },
1425 { "Mic Mute Mixer", NULL, "Mic Mixer" },
1426
1427 { "AIF1 Capture", NULL, "AIF1TX1" }, 1426 { "AIF1 Capture", NULL, "AIF1TX1" },
1428 { "AIF1 Capture", NULL, "AIF1TX2" }, 1427 { "AIF1 Capture", NULL, "AIF1TX2" },
1429 { "AIF1 Capture", NULL, "AIF1TX3" }, 1428 { "AIF1 Capture", NULL, "AIF1TX3" },
@@ -1499,23 +1498,6 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1499 { "IN3L PGA", NULL, "IN3L" }, 1498 { "IN3L PGA", NULL, "IN3L" },
1500 { "IN3R PGA", NULL, "IN3R" }, 1499 { "IN3R PGA", NULL, "IN3R" },
1501 1500
1502 { "ASRC1L", NULL, "ASRC1L Input" },
1503 { "ASRC1R", NULL, "ASRC1R Input" },
1504 { "ASRC2L", NULL, "ASRC2L Input" },
1505 { "ASRC2R", NULL, "ASRC2R Input" },
1506
1507 { "ISRC1DEC1", NULL, "ISRC1DEC1 Input" },
1508 { "ISRC1DEC2", NULL, "ISRC1DEC2 Input" },
1509
1510 { "ISRC1INT1", NULL, "ISRC1INT1 Input" },
1511 { "ISRC1INT2", NULL, "ISRC1INT2 Input" },
1512
1513 { "ISRC2DEC1", NULL, "ISRC2DEC1 Input" },
1514 { "ISRC2DEC2", NULL, "ISRC2DEC2 Input" },
1515
1516 { "ISRC2INT1", NULL, "ISRC2INT1 Input" },
1517 { "ISRC2INT2", NULL, "ISRC2INT2 Input" },
1518
1519 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), 1501 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
1520 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), 1502 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
1521 ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), 1503 ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
@@ -1567,22 +1549,25 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1567 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), 1549 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
1568 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), 1550 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
1569 1551
1570 ARIZONA_MUX_ROUTES("ASRC1L"), 1552 ARIZONA_MIXER_ROUTES("Mic Mute Mixer", "Noise"),
1571 ARIZONA_MUX_ROUTES("ASRC1R"), 1553 ARIZONA_MIXER_ROUTES("Mic Mute Mixer", "Mic"),
1572 ARIZONA_MUX_ROUTES("ASRC2L"),
1573 ARIZONA_MUX_ROUTES("ASRC2R"),
1574 1554
1575 ARIZONA_MUX_ROUTES("ISRC1INT1"), 1555 ARIZONA_MUX_ROUTES("ASRC1L", "ASRC1L"),
1576 ARIZONA_MUX_ROUTES("ISRC1INT2"), 1556 ARIZONA_MUX_ROUTES("ASRC1R", "ASRC1R"),
1557 ARIZONA_MUX_ROUTES("ASRC2L", "ASRC2L"),
1558 ARIZONA_MUX_ROUTES("ASRC2R", "ASRC2R"),
1577 1559
1578 ARIZONA_MUX_ROUTES("ISRC1DEC1"), 1560 ARIZONA_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
1579 ARIZONA_MUX_ROUTES("ISRC1DEC2"), 1561 ARIZONA_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),
1580 1562
1581 ARIZONA_MUX_ROUTES("ISRC2INT1"), 1563 ARIZONA_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
1582 ARIZONA_MUX_ROUTES("ISRC2INT2"), 1564 ARIZONA_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
1583 1565
1584 ARIZONA_MUX_ROUTES("ISRC2DEC1"), 1566 ARIZONA_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
1585 ARIZONA_MUX_ROUTES("ISRC2DEC2"), 1567 ARIZONA_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
1568
1569 ARIZONA_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
1570 ARIZONA_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
1586 1571
1587 ARIZONA_DSP_ROUTES("DSP1"), 1572 ARIZONA_DSP_ROUTES("DSP1"),
1588 1573
@@ -1614,6 +1599,9 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
1614 { "SPKDAT1R", NULL, "OUT5R" }, 1599 { "SPKDAT1R", NULL, "OUT5R" },
1615 1600
1616 { "MICSUPP", NULL, "SYSCLK" }, 1601 { "MICSUPP", NULL, "SYSCLK" },
1602
1603 { "DRC1 Signal Activity", NULL, "DRC1L" },
1604 { "DRC1 Signal Activity", NULL, "DRC1R" },
1617}; 1605};
1618 1606
1619static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source, 1607static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
@@ -1781,6 +1769,7 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec)
1781 return ret; 1769 return ret;
1782 1770
1783 arizona_init_spk(codec); 1771 arizona_init_spk(codec);
1772 arizona_init_gpio(codec);
1784 1773
1785 snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); 1774 snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");
1786 1775
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 2e7cb4ba161a..bbd64384ca1c 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -58,14 +58,10 @@ static DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
58 SOC_SINGLE(name " NG SPKDAT2R Switch", base, 11, 1, 0) 58 SOC_SINGLE(name " NG SPKDAT2R Switch", base, 11, 1, 0)
59 59
60static const struct snd_kcontrol_new wm5110_snd_controls[] = { 60static const struct snd_kcontrol_new wm5110_snd_controls[] = {
61SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL, 61SOC_ENUM("IN1 OSR", arizona_in_dmic_osr[0]),
62 ARIZONA_IN1_OSR_SHIFT, 1, 0), 62SOC_ENUM("IN2 OSR", arizona_in_dmic_osr[1]),
63SOC_SINGLE("IN2 High Performance Switch", ARIZONA_IN2L_CONTROL, 63SOC_ENUM("IN3 OSR", arizona_in_dmic_osr[2]),
64 ARIZONA_IN2_OSR_SHIFT, 1, 0), 64SOC_ENUM("IN4 OSR", arizona_in_dmic_osr[3]),
65SOC_SINGLE("IN3 High Performance Switch", ARIZONA_IN3L_CONTROL,
66 ARIZONA_IN3_OSR_SHIFT, 1, 0),
67SOC_SINGLE("IN4 High Performance Switch", ARIZONA_IN4L_CONTROL,
68 ARIZONA_IN4_OSR_SHIFT, 1, 0),
69 65
70SOC_SINGLE_RANGE_TLV("IN1L Volume", ARIZONA_IN1L_CONTROL, 66SOC_SINGLE_RANGE_TLV("IN1L Volume", ARIZONA_IN1L_CONTROL,
71 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 67 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
@@ -432,6 +428,9 @@ SND_SOC_DAPM_INPUT("IN3R"),
432SND_SOC_DAPM_INPUT("IN4L"), 428SND_SOC_DAPM_INPUT("IN4L"),
433SND_SOC_DAPM_INPUT("IN4R"), 429SND_SOC_DAPM_INPUT("IN4R"),
434 430
431SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
432SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
433
435SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, 434SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
436 0, NULL, 0, arizona_in_ev, 435 0, NULL, 0, arizona_in_ev,
437 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 436 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
@@ -842,9 +841,6 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
842 { "Tone Generator 1", NULL, "TONE" }, 841 { "Tone Generator 1", NULL, "TONE" },
843 { "Tone Generator 2", NULL, "TONE" }, 842 { "Tone Generator 2", NULL, "TONE" },
844 843
845 { "Mic Mute Mixer", NULL, "Noise Mixer" },
846 { "Mic Mute Mixer", NULL, "Mic Mixer" },
847
848 { "AIF1 Capture", NULL, "AIF1TX1" }, 844 { "AIF1 Capture", NULL, "AIF1TX1" },
849 { "AIF1 Capture", NULL, "AIF1TX2" }, 845 { "AIF1 Capture", NULL, "AIF1TX2" },
850 { "AIF1 Capture", NULL, "AIF1TX3" }, 846 { "AIF1 Capture", NULL, "AIF1TX3" },
@@ -979,10 +975,13 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
979 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"), 975 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
980 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"), 976 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
981 977
982 ARIZONA_MUX_ROUTES("ASRC1L"), 978 ARIZONA_MIXER_ROUTES("Mic Mute Mixer", "Noise"),
983 ARIZONA_MUX_ROUTES("ASRC1R"), 979 ARIZONA_MIXER_ROUTES("Mic Mute Mixer", "Mic"),
984 ARIZONA_MUX_ROUTES("ASRC2L"), 980
985 ARIZONA_MUX_ROUTES("ASRC2R"), 981 ARIZONA_MUX_ROUTES("ASRC1L", "ASRC1L"),
982 ARIZONA_MUX_ROUTES("ASRC1R", "ASRC1R"),
983 ARIZONA_MUX_ROUTES("ASRC2L", "ASRC2L"),
984 ARIZONA_MUX_ROUTES("ASRC2R", "ASRC2R"),
986 985
987 { "HPOUT1L", NULL, "OUT1L" }, 986 { "HPOUT1L", NULL, "OUT1L" },
988 { "HPOUT1R", NULL, "OUT1R" }, 987 { "HPOUT1R", NULL, "OUT1R" },
@@ -1006,6 +1005,11 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
1006 { "SPKDAT2R", NULL, "OUT6R" }, 1005 { "SPKDAT2R", NULL, "OUT6R" },
1007 1006
1008 { "MICSUPP", NULL, "SYSCLK" }, 1007 { "MICSUPP", NULL, "SYSCLK" },
1008
1009 { "DRC1 Signal Activity", NULL, "DRC1L" },
1010 { "DRC1 Signal Activity", NULL, "DRC1R" },
1011 { "DRC2 Signal Activity", NULL, "DRC2L" },
1012 { "DRC2 Signal Activity", NULL, "DRC2R" },
1009}; 1013};
1010 1014
1011static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source, 1015static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
@@ -1170,6 +1174,7 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)
1170 return ret; 1174 return ret;
1171 1175
1172 arizona_init_spk(codec); 1176 arizona_init_spk(codec);
1177 arizona_init_gpio(codec);
1173 1178
1174 snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS"); 1179 snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");
1175 1180
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 0e8b3aaf6c8d..af1318ddb062 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -1301,7 +1301,8 @@ static irqreturn_t wm8350_hpl_jack_handler(int irq, void *data)
1301 if (device_may_wakeup(wm8350->dev)) 1301 if (device_may_wakeup(wm8350->dev))
1302 pm_wakeup_event(wm8350->dev, 250); 1302 pm_wakeup_event(wm8350->dev, 250);
1303 1303
1304 schedule_delayed_work(&priv->hpl.work, msecs_to_jiffies(200)); 1304 queue_delayed_work(system_power_efficient_wq,
1305 &priv->hpl.work, msecs_to_jiffies(200));
1305 1306
1306 return IRQ_HANDLED; 1307 return IRQ_HANDLED;
1307} 1308}
@@ -1318,7 +1319,8 @@ static irqreturn_t wm8350_hpr_jack_handler(int irq, void *data)
1318 if (device_may_wakeup(wm8350->dev)) 1319 if (device_may_wakeup(wm8350->dev))
1319 pm_wakeup_event(wm8350->dev, 250); 1320 pm_wakeup_event(wm8350->dev, 250);
1320 1321
1321 schedule_delayed_work(&priv->hpr.work, msecs_to_jiffies(200)); 1322 queue_delayed_work(system_power_efficient_wq,
1323 &priv->hpr.work, msecs_to_jiffies(200));
1322 1324
1323 return IRQ_HANDLED; 1325 return IRQ_HANDLED;
1324} 1326}
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
index 462f5e4d5c05..7b1a6d5c11c6 100644
--- a/sound/soc/codecs/wm8727.c
+++ b/sound/soc/codecs/wm8727.c
@@ -23,6 +23,16 @@
23#include <sound/initval.h> 23#include <sound/initval.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25 25
26static const struct snd_soc_dapm_widget wm8727_dapm_widgets[] = {
27SND_SOC_DAPM_OUTPUT("VOUTL"),
28SND_SOC_DAPM_OUTPUT("VOUTR"),
29};
30
31static const struct snd_soc_dapm_route wm8727_dapm_routes[] = {
32 { "VOUTL", NULL, "Playback" },
33 { "VOUTR", NULL, "Playback" },
34};
35
26/* 36/*
27 * Note this is a simple chip with no configuration interface, sample rate is 37 * Note this is a simple chip with no configuration interface, sample rate is
28 * determined automatically by examining the Master clock and Bit clock ratios 38 * determined automatically by examining the Master clock and Bit clock ratios
@@ -43,7 +53,12 @@ static struct snd_soc_dai_driver wm8727_dai = {
43 }, 53 },
44}; 54};
45 55
46static struct snd_soc_codec_driver soc_codec_dev_wm8727; 56static struct snd_soc_codec_driver soc_codec_dev_wm8727 = {
57 .dapm_widgets = wm8727_dapm_widgets,
58 .num_dapm_widgets = ARRAY_SIZE(wm8727_dapm_widgets),
59 .dapm_routes = wm8727_dapm_routes,
60 .num_dapm_routes = ARRAY_SIZE(wm8727_dapm_routes),
61};
47 62
48static int wm8727_probe(struct platform_device *pdev) 63static int wm8727_probe(struct platform_device *pdev)
49{ 64{
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 5276062d6c79..456bb8c6d759 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -45,6 +45,7 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
45struct wm8731_priv { 45struct wm8731_priv {
46 struct regmap *regmap; 46 struct regmap *regmap;
47 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; 47 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
48 const struct snd_pcm_hw_constraint_list *constraints;
48 unsigned int sysclk; 49 unsigned int sysclk;
49 int sysclk_type; 50 int sysclk_type;
50 int playback_fs; 51 int playback_fs;
@@ -290,6 +291,36 @@ static const struct _coeff_div coeff_div[] = {
290 {12000000, 88200, 136, 0xf, 0x1, 0x1}, 291 {12000000, 88200, 136, 0xf, 0x1, 0x1},
291}; 292};
292 293
294/* rates constraints */
295static const unsigned int wm8731_rates_12000000[] = {
296 8000, 32000, 44100, 48000, 96000, 88200,
297};
298
299static const unsigned int wm8731_rates_12288000_18432000[] = {
300 8000, 32000, 48000, 96000,
301};
302
303static const unsigned int wm8731_rates_11289600_16934400[] = {
304 8000, 44100, 88200,
305};
306
307static const struct snd_pcm_hw_constraint_list wm8731_constraints_12000000 = {
308 .list = wm8731_rates_12000000,
309 .count = ARRAY_SIZE(wm8731_rates_12000000),
310};
311
312static const
313struct snd_pcm_hw_constraint_list wm8731_constraints_12288000_18432000 = {
314 .list = wm8731_rates_12288000_18432000,
315 .count = ARRAY_SIZE(wm8731_rates_12288000_18432000),
316};
317
318static const
319struct snd_pcm_hw_constraint_list wm8731_constraints_11289600_16934400 = {
320 .list = wm8731_rates_11289600_16934400,
321 .count = ARRAY_SIZE(wm8731_rates_11289600_16934400),
322};
323
293static inline int get_coeff(int mclk, int rate) 324static inline int get_coeff(int mclk, int rate)
294{ 325{
295 int i; 326 int i;
@@ -362,17 +393,26 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
362 } 393 }
363 394
364 switch (freq) { 395 switch (freq) {
365 case 11289600: 396 case 0:
397 wm8731->constraints = NULL;
398 break;
366 case 12000000: 399 case 12000000:
400 wm8731->constraints = &wm8731_constraints_12000000;
401 break;
367 case 12288000: 402 case 12288000:
368 case 16934400:
369 case 18432000: 403 case 18432000:
370 wm8731->sysclk = freq; 404 wm8731->constraints = &wm8731_constraints_12288000_18432000;
405 break;
406 case 16934400:
407 case 11289600:
408 wm8731->constraints = &wm8731_constraints_11289600_16934400;
371 break; 409 break;
372 default: 410 default:
373 return -EINVAL; 411 return -EINVAL;
374 } 412 }
375 413
414 wm8731->sysclk = freq;
415
376 snd_soc_dapm_sync(&codec->dapm); 416 snd_soc_dapm_sync(&codec->dapm);
377 417
378 return 0; 418 return 0;
@@ -475,12 +515,26 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
475 return 0; 515 return 0;
476} 516}
477 517
518static int wm8731_startup(struct snd_pcm_substream *substream,
519 struct snd_soc_dai *dai)
520{
521 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(dai->codec);
522
523 if (wm8731->constraints)
524 snd_pcm_hw_constraint_list(substream->runtime, 0,
525 SNDRV_PCM_HW_PARAM_RATE,
526 wm8731->constraints);
527
528 return 0;
529}
530
478#define WM8731_RATES SNDRV_PCM_RATE_8000_96000 531#define WM8731_RATES SNDRV_PCM_RATE_8000_96000
479 532
480#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 533#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
481 SNDRV_PCM_FMTBIT_S24_LE) 534 SNDRV_PCM_FMTBIT_S24_LE)
482 535
483static const struct snd_soc_dai_ops wm8731_dai_ops = { 536static const struct snd_soc_dai_ops wm8731_dai_ops = {
537 .startup = wm8731_startup,
484 .hw_params = wm8731_hw_params, 538 .hw_params = wm8731_hw_params,
485 .digital_mute = wm8731_mute, 539 .digital_mute = wm8731_mute,
486 .set_sysclk = wm8731_set_dai_sysclk, 540 .set_sysclk = wm8731_set_dai_sysclk,
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 0a4ab4c423d1..d96ebf52d953 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -1456,8 +1456,9 @@ static int wm8753_resume(struct snd_soc_codec *codec)
1456 if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) { 1456 if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
1457 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 1457 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1458 codec->dapm.bias_level = SND_SOC_BIAS_ON; 1458 codec->dapm.bias_level = SND_SOC_BIAS_ON;
1459 schedule_delayed_work(&codec->dapm.delayed_work, 1459 queue_delayed_work(system_power_efficient_wq,
1460 msecs_to_jiffies(caps_charge)); 1460 &codec->dapm.delayed_work,
1461 msecs_to_jiffies(caps_charge));
1461 } 1462 }
1462 1463
1463 return 0; 1464 return 0;
diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c
index f1fdbf63abb4..8092495605ce 100644
--- a/sound/soc/codecs/wm8782.c
+++ b/sound/soc/codecs/wm8782.c
@@ -26,6 +26,16 @@
26#include <sound/initval.h> 26#include <sound/initval.h>
27#include <sound/soc.h> 27#include <sound/soc.h>
28 28
29static const struct snd_soc_dapm_widget wm8782_dapm_widgets[] = {
30SND_SOC_DAPM_INPUT("AINL"),
31SND_SOC_DAPM_INPUT("AINR"),
32};
33
34static const struct snd_soc_dapm_route wm8782_dapm_routes[] = {
35 { "Capture", NULL, "AINL" },
36 { "Capture", NULL, "AINR" },
37};
38
29static struct snd_soc_dai_driver wm8782_dai = { 39static struct snd_soc_dai_driver wm8782_dai = {
30 .name = "wm8782", 40 .name = "wm8782",
31 .capture = { 41 .capture = {
@@ -40,7 +50,12 @@ static struct snd_soc_dai_driver wm8782_dai = {
40 }, 50 },
41}; 51};
42 52
43static struct snd_soc_codec_driver soc_codec_dev_wm8782; 53static struct snd_soc_codec_driver soc_codec_dev_wm8782 = {
54 .dapm_widgets = wm8782_dapm_widgets,
55 .num_dapm_widgets = ARRAY_SIZE(wm8782_dapm_widgets),
56 .dapm_routes = wm8782_dapm_routes,
57 .num_dapm_routes = ARRAY_SIZE(wm8782_dapm_routes),
58};
44 59
45static int wm8782_probe(struct platform_device *pdev) 60static int wm8782_probe(struct platform_device *pdev)
46{ 61{
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index fa24cedee687..eebcb1da3b7b 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -364,9 +364,7 @@ static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm,
364static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, 364static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
365 struct snd_ctl_elem_value *ucontrol) 365 struct snd_ctl_elem_value *ucontrol)
366{ 366{
367 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 367 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
368 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
369 struct snd_soc_codec *codec = widget->codec;
370 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 368 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
371 u16 reg; 369 u16 reg;
372 int ret; 370 int ret;
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 4c9fb142cb2d..4dfa8dceeabf 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -1012,7 +1012,7 @@ static const struct soc_enum liner_enum =
1012 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 0, 2, out_mux_text); 1012 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 0, 2, out_mux_text);
1013 1013
1014static const struct snd_kcontrol_new liner_mux = 1014static const struct snd_kcontrol_new liner_mux =
1015 SOC_DAPM_ENUM("LINEL Mux", liner_enum); 1015 SOC_DAPM_ENUM("LINER Mux", liner_enum);
1016 1016
1017static const char *sidetone_text[] = { 1017static const char *sidetone_text[] = {
1018 "None", "Left", "Right" 1018 "None", "Left", "Right"
@@ -1202,7 +1202,6 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
1202 break; 1202 break;
1203 } 1203 }
1204 1204
1205 snd_soc_dapm_new_widgets(dapm);
1206 return 0; 1205 return 0;
1207} 1206}
1208 1207
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 0a4ffdd1d2a7..f156010e52bc 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -263,8 +263,8 @@ SOC_SINGLE("ALC Attack", WM8960_ALC3, 0, 15, 0),
263SOC_SINGLE("Noise Gate Threshold", WM8960_NOISEG, 3, 31, 0), 263SOC_SINGLE("Noise Gate Threshold", WM8960_NOISEG, 3, 31, 0),
264SOC_SINGLE("Noise Gate Switch", WM8960_NOISEG, 0, 1, 0), 264SOC_SINGLE("Noise Gate Switch", WM8960_NOISEG, 0, 1, 0),
265 265
266SOC_DOUBLE_R("ADC PCM Capture Volume", WM8960_LINPATH, WM8960_RINPATH, 266SOC_DOUBLE_R_TLV("ADC PCM Capture Volume", WM8960_LADC, WM8960_RADC,
267 0, 127, 0), 267 0, 255, 0, adc_tlv),
268 268
269SOC_SINGLE_TLV("Left Output Mixer Boost Bypass Volume", 269SOC_SINGLE_TLV("Left Output Mixer Boost Bypass Volume",
270 WM8960_BYPASS1, 4, 7, 1, bypass_tlv), 270 WM8960_BYPASS1, 4, 7, 1, bypass_tlv),
@@ -857,9 +857,9 @@ static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
857 if (pll_div.k) { 857 if (pll_div.k) {
858 reg |= 0x20; 858 reg |= 0x20;
859 859
860 snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 18) & 0x3f); 860 snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 16) & 0xff);
861 snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 9) & 0x1ff); 861 snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 8) & 0xff);
862 snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0x1ff); 862 snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0xff);
863 } 863 }
864 snd_soc_write(codec, WM8960_PLL1, reg); 864 snd_soc_write(codec, WM8960_PLL1, reg);
865 865
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index e2de9ecfd641..11d80f3b6137 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -2621,8 +2621,6 @@ static int wm8962_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
2621 2621
2622 wm8962->sysclk_rate = freq; 2622 wm8962->sysclk_rate = freq;
2623 2623
2624 wm8962_configure_bclk(codec);
2625
2626 return 0; 2624 return 0;
2627} 2625}
2628 2626
@@ -3046,8 +3044,9 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3046 3044
3047 pm_wakeup_event(dev, 300); 3045 pm_wakeup_event(dev, 300);
3048 3046
3049 schedule_delayed_work(&wm8962->mic_work, 3047 queue_delayed_work(system_power_efficient_wq,
3050 msecs_to_jiffies(250)); 3048 &wm8962->mic_work,
3049 msecs_to_jiffies(250));
3051 } 3050 }
3052 3051
3053 return IRQ_HANDLED; 3052 return IRQ_HANDLED;
@@ -3175,7 +3174,7 @@ static ssize_t wm8962_beep_set(struct device *dev,
3175 long int time; 3174 long int time;
3176 int ret; 3175 int ret;
3177 3176
3178 ret = strict_strtol(buf, 10, &time); 3177 ret = kstrtol(buf, 10, &time);
3179 if (ret != 0) 3178 if (ret != 0)
3180 return ret; 3179 return ret;
3181 3180
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index ba832b77c543..86426a117b07 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -819,8 +819,9 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
819 * don't want false reports. 819 * don't want false reports.
820 */ 820 */
821 if (wm8994->jackdet && !wm8994->clk_has_run) { 821 if (wm8994->jackdet && !wm8994->clk_has_run) {
822 schedule_delayed_work(&wm8994->jackdet_bootstrap, 822 queue_delayed_work(system_power_efficient_wq,
823 msecs_to_jiffies(1000)); 823 &wm8994->jackdet_bootstrap,
824 msecs_to_jiffies(1000));
824 wm8994->clk_has_run = true; 825 wm8994->clk_has_run = true;
825 } 826 }
826 break; 827 break;
@@ -1432,14 +1433,12 @@ SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
1432 1433
1433#define WM8994_CLASS_W_SWITCH(xname, reg, shift, max, invert) \ 1434#define WM8994_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
1434 SOC_SINGLE_EXT(xname, reg, shift, max, invert, \ 1435 SOC_SINGLE_EXT(xname, reg, shift, max, invert, \
1435 snd_soc_get_volsw, wm8994_put_class_w) 1436 snd_soc_dapm_get_volsw, wm8994_put_class_w)
1436 1437
1437static int wm8994_put_class_w(struct snd_kcontrol *kcontrol, 1438static int wm8994_put_class_w(struct snd_kcontrol *kcontrol,
1438 struct snd_ctl_elem_value *ucontrol) 1439 struct snd_ctl_elem_value *ucontrol)
1439{ 1440{
1440 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 1441 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
1441 struct snd_soc_dapm_widget *w = wlist->widgets[0];
1442 struct snd_soc_codec *codec = w->codec;
1443 int ret; 1442 int ret;
1444 1443
1445 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); 1444 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
@@ -3487,7 +3486,8 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
3487 3486
3488 pm_wakeup_event(codec->dev, 300); 3487 pm_wakeup_event(codec->dev, 300);
3489 3488
3490 schedule_delayed_work(&priv->mic_work, msecs_to_jiffies(250)); 3489 queue_delayed_work(system_power_efficient_wq,
3490 &priv->mic_work, msecs_to_jiffies(250));
3491 3491
3492 return IRQ_HANDLED; 3492 return IRQ_HANDLED;
3493} 3493}
@@ -3575,8 +3575,9 @@ static void wm8958_mic_id(void *data, u16 status)
3575 /* If nothing present then clear our statuses */ 3575 /* If nothing present then clear our statuses */
3576 dev_dbg(codec->dev, "Detected open circuit\n"); 3576 dev_dbg(codec->dev, "Detected open circuit\n");
3577 3577
3578 schedule_delayed_work(&wm8994->open_circuit_work, 3578 queue_delayed_work(system_power_efficient_wq,
3579 msecs_to_jiffies(2500)); 3579 &wm8994->open_circuit_work,
3580 msecs_to_jiffies(2500));
3580 return; 3581 return;
3581 } 3582 }
3582 3583
@@ -3690,8 +3691,9 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3690 WM1811_JACKDET_DB, 0); 3691 WM1811_JACKDET_DB, 0);
3691 3692
3692 delay = control->pdata.micdet_delay; 3693 delay = control->pdata.micdet_delay;
3693 schedule_delayed_work(&wm8994->mic_work, 3694 queue_delayed_work(system_power_efficient_wq,
3694 msecs_to_jiffies(delay)); 3695 &wm8994->mic_work,
3696 msecs_to_jiffies(delay));
3695 } else { 3697 } else {
3696 dev_dbg(codec->dev, "Jack not detected\n"); 3698 dev_dbg(codec->dev, "Jack not detected\n");
3697 3699
@@ -3936,8 +3938,9 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data)
3936 id_delay = wm8994->wm8994->pdata.mic_id_delay; 3938 id_delay = wm8994->wm8994->pdata.mic_id_delay;
3937 3939
3938 if (wm8994->mic_detecting) 3940 if (wm8994->mic_detecting)
3939 schedule_delayed_work(&wm8994->mic_complete_work, 3941 queue_delayed_work(system_power_efficient_wq,
3940 msecs_to_jiffies(id_delay)); 3942 &wm8994->mic_complete_work,
3943 msecs_to_jiffies(id_delay));
3941 else 3944 else
3942 wm8958_button_det(codec, reg); 3945 wm8958_button_det(codec, reg);
3943 3946
@@ -4010,9 +4013,6 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
4010 4013
4011 wm8994->micdet_irq = control->pdata.micdet_irq; 4014 wm8994->micdet_irq = control->pdata.micdet_irq;
4012 4015
4013 pm_runtime_enable(codec->dev);
4014 pm_runtime_idle(codec->dev);
4015
4016 /* By default use idle_bias_off, will override for WM8994 */ 4016 /* By default use idle_bias_off, will override for WM8994 */
4017 codec->dapm.idle_bias_off = 1; 4017 codec->dapm.idle_bias_off = 1;
4018 4018
@@ -4385,8 +4385,6 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
4385 4385
4386 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); 4386 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
4387 4387
4388 pm_runtime_disable(codec->dev);
4389
4390 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) 4388 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
4391 wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FLL1_LOCK + i, 4389 wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FLL1_LOCK + i,
4392 &wm8994->fll_locked[i]); 4390 &wm8994->fll_locked[i]);
@@ -4445,6 +4443,9 @@ static int wm8994_probe(struct platform_device *pdev)
4445 4443
4446 wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent); 4444 wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent);
4447 4445
4446 pm_runtime_enable(&pdev->dev);
4447 pm_runtime_idle(&pdev->dev);
4448
4448 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994, 4449 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994,
4449 wm8994_dai, ARRAY_SIZE(wm8994_dai)); 4450 wm8994_dai, ARRAY_SIZE(wm8994_dai));
4450} 4451}
@@ -4452,6 +4453,8 @@ static int wm8994_probe(struct platform_device *pdev)
4452static int wm8994_remove(struct platform_device *pdev) 4453static int wm8994_remove(struct platform_device *pdev)
4453{ 4454{
4454 snd_soc_unregister_codec(&pdev->dev); 4455 snd_soc_unregister_codec(&pdev->dev);
4456 pm_runtime_disable(&pdev->dev);
4457
4455 return 0; 4458 return 0;
4456} 4459}
4457 4460
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index 90a65c427541..da2899e6c401 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -549,12 +549,9 @@ static int check_clk_sys(struct snd_soc_dapm_widget *source,
549static int wm8995_put_class_w(struct snd_kcontrol *kcontrol, 549static int wm8995_put_class_w(struct snd_kcontrol *kcontrol,
550 struct snd_ctl_elem_value *ucontrol) 550 struct snd_ctl_elem_value *ucontrol)
551{ 551{
552 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 552 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
553 struct snd_soc_dapm_widget *w = wlist->widgets[0];
554 struct snd_soc_codec *codec;
555 int ret; 553 int ret;
556 554
557 codec = w->codec;
558 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); 555 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
559 wm8995_update_class_w(codec); 556 wm8995_update_class_w(codec);
560 return ret; 557 return ret;
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c
new file mode 100644
index 000000000000..6ec3de3efa4f
--- /dev/null
+++ b/sound/soc/codecs/wm8997.c
@@ -0,0 +1,1175 @@
1/*
2 * wm8997.c -- WM8997 ALSA SoC Audio driver
3 *
4 * Copyright 2012 Wolfson Microelectronics plc
5 *
6 * Author: Charles Keepax <ckeepax@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 "wm8997.h"
34
35struct wm8997_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);
44static DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
45
46static const struct reg_default wm8997_sysclk_reva_patch[] = {
47 { 0x301D, 0x7B15 },
48 { 0x301B, 0x0050 },
49 { 0x305D, 0x7B17 },
50 { 0x305B, 0x0050 },
51 { 0x3001, 0x08FE },
52 { 0x3003, 0x00F4 },
53 { 0x3041, 0x08FF },
54 { 0x3043, 0x0005 },
55 { 0x3020, 0x0225 },
56 { 0x3021, 0x0A00 },
57 { 0x3022, 0xE24D },
58 { 0x3023, 0x0800 },
59 { 0x3024, 0xE24D },
60 { 0x3025, 0xF000 },
61 { 0x3060, 0x0226 },
62 { 0x3061, 0x0A00 },
63 { 0x3062, 0xE252 },
64 { 0x3063, 0x0800 },
65 { 0x3064, 0xE252 },
66 { 0x3065, 0xF000 },
67 { 0x3116, 0x022B },
68 { 0x3117, 0xFA00 },
69 { 0x3110, 0x246C },
70 { 0x3111, 0x0A03 },
71 { 0x3112, 0x246E },
72 { 0x3113, 0x0A03 },
73 { 0x3114, 0x2470 },
74 { 0x3115, 0x0A03 },
75 { 0x3126, 0x246C },
76 { 0x3127, 0x0A02 },
77 { 0x3128, 0x246E },
78 { 0x3129, 0x0A02 },
79 { 0x312A, 0x2470 },
80 { 0x312B, 0xFA02 },
81 { 0x3125, 0x0800 },
82};
83
84static int wm8997_sysclk_ev(struct snd_soc_dapm_widget *w,
85 struct snd_kcontrol *kcontrol, int event)
86{
87 struct snd_soc_codec *codec = w->codec;
88 struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
89 struct regmap *regmap = codec->control_data;
90 const struct reg_default *patch = NULL;
91 int i, patch_size;
92
93 switch (arizona->rev) {
94 case 0:
95 patch = wm8997_sysclk_reva_patch;
96 patch_size = ARRAY_SIZE(wm8997_sysclk_reva_patch);
97 break;
98 default:
99 break;
100 }
101
102 switch (event) {
103 case SND_SOC_DAPM_POST_PMU:
104 if (patch)
105 for (i = 0; i < patch_size; i++)
106 regmap_write(regmap, patch[i].reg,
107 patch[i].def);
108 break;
109 default:
110 break;
111 }
112
113 return 0;
114}
115
116static const char *wm8997_osr_text[] = {
117 "Low power", "Normal", "High performance",
118};
119
120static const unsigned int wm8997_osr_val[] = {
121 0x0, 0x3, 0x5,
122};
123
124static const struct soc_enum wm8997_hpout_osr[] = {
125 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_1L,
126 ARIZONA_OUT1_OSR_SHIFT, 0x7, 3,
127 wm8997_osr_text, wm8997_osr_val),
128 SOC_VALUE_ENUM_SINGLE(ARIZONA_OUTPUT_PATH_CONFIG_3L,
129 ARIZONA_OUT3_OSR_SHIFT, 0x7, 3,
130 wm8997_osr_text, wm8997_osr_val),
131};
132
133#define WM8997_NG_SRC(name, base) \
134 SOC_SINGLE(name " NG HPOUT1L Switch", base, 0, 1, 0), \
135 SOC_SINGLE(name " NG HPOUT1R Switch", base, 1, 1, 0), \
136 SOC_SINGLE(name " NG EPOUT Switch", base, 4, 1, 0), \
137 SOC_SINGLE(name " NG SPKOUT Switch", base, 6, 1, 0), \
138 SOC_SINGLE(name " NG SPKDAT1L Switch", base, 8, 1, 0), \
139 SOC_SINGLE(name " NG SPKDAT1R Switch", base, 9, 1, 0)
140
141static const struct snd_kcontrol_new wm8997_snd_controls[] = {
142SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL,
143 ARIZONA_IN1_OSR_SHIFT, 1, 0),
144SOC_SINGLE("IN2 High Performance Switch", ARIZONA_IN2L_CONTROL,
145 ARIZONA_IN2_OSR_SHIFT, 1, 0),
146
147SOC_SINGLE_RANGE_TLV("IN1L Volume", ARIZONA_IN1L_CONTROL,
148 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
149SOC_SINGLE_RANGE_TLV("IN1R Volume", ARIZONA_IN1R_CONTROL,
150 ARIZONA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
151SOC_SINGLE_RANGE_TLV("IN2L Volume", ARIZONA_IN2L_CONTROL,
152 ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
153SOC_SINGLE_RANGE_TLV("IN2R Volume", ARIZONA_IN2R_CONTROL,
154 ARIZONA_IN2R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
155
156SOC_SINGLE_TLV("IN1L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L,
157 ARIZONA_IN1L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
158SOC_SINGLE_TLV("IN1R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1R,
159 ARIZONA_IN1R_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
160SOC_SINGLE_TLV("IN2L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2L,
161 ARIZONA_IN2L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
162SOC_SINGLE_TLV("IN2R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2R,
163 ARIZONA_IN2R_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
164
165SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp),
166SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp),
167
168ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE),
169ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
170ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
171ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
172
173SND_SOC_BYTES_MASK("EQ1 Coefficeints", ARIZONA_EQ1_1, 21,
174 ARIZONA_EQ1_ENA_MASK),
175SND_SOC_BYTES_MASK("EQ2 Coefficeints", ARIZONA_EQ2_1, 21,
176 ARIZONA_EQ2_ENA_MASK),
177SND_SOC_BYTES_MASK("EQ3 Coefficeints", ARIZONA_EQ3_1, 21,
178 ARIZONA_EQ3_ENA_MASK),
179SND_SOC_BYTES_MASK("EQ4 Coefficeints", ARIZONA_EQ4_1, 21,
180 ARIZONA_EQ4_ENA_MASK),
181
182SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
183 24, 0, eq_tlv),
184SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
185 24, 0, eq_tlv),
186SOC_SINGLE_TLV("EQ1 B3 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B3_GAIN_SHIFT,
187 24, 0, eq_tlv),
188SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT,
189 24, 0, eq_tlv),
190SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT,
191 24, 0, eq_tlv),
192
193SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT,
194 24, 0, eq_tlv),
195SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT,
196 24, 0, eq_tlv),
197SOC_SINGLE_TLV("EQ2 B3 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B3_GAIN_SHIFT,
198 24, 0, eq_tlv),
199SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT,
200 24, 0, eq_tlv),
201SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT,
202 24, 0, eq_tlv),
203
204SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT,
205 24, 0, eq_tlv),
206SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT,
207 24, 0, eq_tlv),
208SOC_SINGLE_TLV("EQ3 B3 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B3_GAIN_SHIFT,
209 24, 0, eq_tlv),
210SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT,
211 24, 0, eq_tlv),
212SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT,
213 24, 0, eq_tlv),
214
215SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT,
216 24, 0, eq_tlv),
217SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT,
218 24, 0, eq_tlv),
219SOC_SINGLE_TLV("EQ4 B3 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B3_GAIN_SHIFT,
220 24, 0, eq_tlv),
221SOC_SINGLE_TLV("EQ4 B4 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B4_GAIN_SHIFT,
222 24, 0, eq_tlv),
223SOC_SINGLE_TLV("EQ4 B5 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B5_GAIN_SHIFT,
224 24, 0, eq_tlv),
225
226ARIZONA_MIXER_CONTROLS("DRC1L", ARIZONA_DRC1LMIX_INPUT_1_SOURCE),
227ARIZONA_MIXER_CONTROLS("DRC1R", ARIZONA_DRC1RMIX_INPUT_1_SOURCE),
228
229SND_SOC_BYTES_MASK("DRC1", ARIZONA_DRC1_CTRL1, 5,
230 ARIZONA_DRC1R_ENA | ARIZONA_DRC1L_ENA),
231
232ARIZONA_MIXER_CONTROLS("LHPF1", ARIZONA_HPLP1MIX_INPUT_1_SOURCE),
233ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE),
234ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE),
235ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE),
236
237SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode),
238SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
239SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
240SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
241
242SND_SOC_BYTES("LHPF1 Coefficients", ARIZONA_HPLPF1_2, 1),
243SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1),
244SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1),
245SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1),
246
247SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]),
248SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]),
249
250ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE),
251ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE),
252
253SOC_SINGLE_TLV("Noise Generator Volume", ARIZONA_COMFORT_NOISE_GENERATOR,
254 ARIZONA_NOISE_GEN_GAIN_SHIFT, 0x16, 0, noise_tlv),
255
256ARIZONA_MIXER_CONTROLS("HPOUT1L", ARIZONA_OUT1LMIX_INPUT_1_SOURCE),
257ARIZONA_MIXER_CONTROLS("HPOUT1R", ARIZONA_OUT1RMIX_INPUT_1_SOURCE),
258ARIZONA_MIXER_CONTROLS("EPOUT", ARIZONA_OUT3LMIX_INPUT_1_SOURCE),
259ARIZONA_MIXER_CONTROLS("SPKOUT", ARIZONA_OUT4LMIX_INPUT_1_SOURCE),
260ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE),
261ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE),
262
263SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
264 ARIZONA_OUT4_OSR_SHIFT, 1, 0),
265SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
266 ARIZONA_OUT5_OSR_SHIFT, 1, 0),
267
268SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
269 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
270SOC_SINGLE("EPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
271 ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
272SOC_SINGLE("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
273 ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
274SOC_DOUBLE_R("SPKDAT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L,
275 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_MUTE_SHIFT, 1, 1),
276
277SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
278 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_VOL_SHIFT,
279 0xbf, 0, digital_tlv),
280SOC_SINGLE_TLV("EPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
281 ARIZONA_OUT3L_VOL_SHIFT, 0xbf, 0, digital_tlv),
282SOC_SINGLE_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
283 ARIZONA_OUT4L_VOL_SHIFT, 0xbf, 0, digital_tlv),
284SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L,
285 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT,
286 0xbf, 0, digital_tlv),
287
288SOC_VALUE_ENUM("HPOUT1 OSR", wm8997_hpout_osr[0]),
289SOC_VALUE_ENUM("EPOUT OSR", wm8997_hpout_osr[1]),
290
291SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
292SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
293
294SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
295 ARIZONA_SPK1R_MUTE_SHIFT, 1, 1),
296
297SOC_SINGLE("Noise Gate Switch", ARIZONA_NOISE_GATE_CONTROL,
298 ARIZONA_NGATE_ENA_SHIFT, 1, 0),
299SOC_SINGLE_TLV("Noise Gate Threshold Volume", ARIZONA_NOISE_GATE_CONTROL,
300 ARIZONA_NGATE_THR_SHIFT, 7, 1, ng_tlv),
301SOC_ENUM("Noise Gate Hold", arizona_ng_hold),
302
303WM8997_NG_SRC("HPOUT1L", ARIZONA_NOISE_GATE_SELECT_1L),
304WM8997_NG_SRC("HPOUT1R", ARIZONA_NOISE_GATE_SELECT_1R),
305WM8997_NG_SRC("EPOUT", ARIZONA_NOISE_GATE_SELECT_3L),
306WM8997_NG_SRC("SPKOUT", ARIZONA_NOISE_GATE_SELECT_4L),
307WM8997_NG_SRC("SPKDAT1L", ARIZONA_NOISE_GATE_SELECT_5L),
308WM8997_NG_SRC("SPKDAT1R", ARIZONA_NOISE_GATE_SELECT_5R),
309
310ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE),
311ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE),
312ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE),
313ARIZONA_MIXER_CONTROLS("AIF1TX4", ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE),
314ARIZONA_MIXER_CONTROLS("AIF1TX5", ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE),
315ARIZONA_MIXER_CONTROLS("AIF1TX6", ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE),
316ARIZONA_MIXER_CONTROLS("AIF1TX7", ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE),
317ARIZONA_MIXER_CONTROLS("AIF1TX8", ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE),
318
319ARIZONA_MIXER_CONTROLS("AIF2TX1", ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE),
320ARIZONA_MIXER_CONTROLS("AIF2TX2", ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE),
321
322ARIZONA_MIXER_CONTROLS("SLIMTX1", ARIZONA_SLIMTX1MIX_INPUT_1_SOURCE),
323ARIZONA_MIXER_CONTROLS("SLIMTX2", ARIZONA_SLIMTX2MIX_INPUT_1_SOURCE),
324ARIZONA_MIXER_CONTROLS("SLIMTX3", ARIZONA_SLIMTX3MIX_INPUT_1_SOURCE),
325ARIZONA_MIXER_CONTROLS("SLIMTX4", ARIZONA_SLIMTX4MIX_INPUT_1_SOURCE),
326ARIZONA_MIXER_CONTROLS("SLIMTX5", ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE),
327ARIZONA_MIXER_CONTROLS("SLIMTX6", ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE),
328ARIZONA_MIXER_CONTROLS("SLIMTX7", ARIZONA_SLIMTX7MIX_INPUT_1_SOURCE),
329ARIZONA_MIXER_CONTROLS("SLIMTX8", ARIZONA_SLIMTX8MIX_INPUT_1_SOURCE),
330};
331
332ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
333ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE);
334ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE);
335ARIZONA_MIXER_ENUMS(EQ4, ARIZONA_EQ4MIX_INPUT_1_SOURCE);
336
337ARIZONA_MIXER_ENUMS(DRC1L, ARIZONA_DRC1LMIX_INPUT_1_SOURCE);
338ARIZONA_MIXER_ENUMS(DRC1R, ARIZONA_DRC1RMIX_INPUT_1_SOURCE);
339
340ARIZONA_MIXER_ENUMS(LHPF1, ARIZONA_HPLP1MIX_INPUT_1_SOURCE);
341ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE);
342ARIZONA_MIXER_ENUMS(LHPF3, ARIZONA_HPLP3MIX_INPUT_1_SOURCE);
343ARIZONA_MIXER_ENUMS(LHPF4, ARIZONA_HPLP4MIX_INPUT_1_SOURCE);
344
345ARIZONA_MIXER_ENUMS(Mic, ARIZONA_MICMIX_INPUT_1_SOURCE);
346ARIZONA_MIXER_ENUMS(Noise, ARIZONA_NOISEMIX_INPUT_1_SOURCE);
347
348ARIZONA_MIXER_ENUMS(PWM1, ARIZONA_PWM1MIX_INPUT_1_SOURCE);
349ARIZONA_MIXER_ENUMS(PWM2, ARIZONA_PWM2MIX_INPUT_1_SOURCE);
350
351ARIZONA_MIXER_ENUMS(OUT1L, ARIZONA_OUT1LMIX_INPUT_1_SOURCE);
352ARIZONA_MIXER_ENUMS(OUT1R, ARIZONA_OUT1RMIX_INPUT_1_SOURCE);
353ARIZONA_MIXER_ENUMS(OUT3, ARIZONA_OUT3LMIX_INPUT_1_SOURCE);
354ARIZONA_MIXER_ENUMS(SPKOUT, ARIZONA_OUT4LMIX_INPUT_1_SOURCE);
355ARIZONA_MIXER_ENUMS(SPKDAT1L, ARIZONA_OUT5LMIX_INPUT_1_SOURCE);
356ARIZONA_MIXER_ENUMS(SPKDAT1R, ARIZONA_OUT5RMIX_INPUT_1_SOURCE);
357
358ARIZONA_MIXER_ENUMS(AIF1TX1, ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE);
359ARIZONA_MIXER_ENUMS(AIF1TX2, ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE);
360ARIZONA_MIXER_ENUMS(AIF1TX3, ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE);
361ARIZONA_MIXER_ENUMS(AIF1TX4, ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE);
362ARIZONA_MIXER_ENUMS(AIF1TX5, ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE);
363ARIZONA_MIXER_ENUMS(AIF1TX6, ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE);
364ARIZONA_MIXER_ENUMS(AIF1TX7, ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE);
365ARIZONA_MIXER_ENUMS(AIF1TX8, ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE);
366
367ARIZONA_MIXER_ENUMS(AIF2TX1, ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE);
368ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
369
370ARIZONA_MIXER_ENUMS(SLIMTX1, ARIZONA_SLIMTX1MIX_INPUT_1_SOURCE);
371ARIZONA_MIXER_ENUMS(SLIMTX2, ARIZONA_SLIMTX2MIX_INPUT_1_SOURCE);
372ARIZONA_MIXER_ENUMS(SLIMTX3, ARIZONA_SLIMTX3MIX_INPUT_1_SOURCE);
373ARIZONA_MIXER_ENUMS(SLIMTX4, ARIZONA_SLIMTX4MIX_INPUT_1_SOURCE);
374ARIZONA_MIXER_ENUMS(SLIMTX5, ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE);
375ARIZONA_MIXER_ENUMS(SLIMTX6, ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE);
376ARIZONA_MIXER_ENUMS(SLIMTX7, ARIZONA_SLIMTX7MIX_INPUT_1_SOURCE);
377ARIZONA_MIXER_ENUMS(SLIMTX8, ARIZONA_SLIMTX8MIX_INPUT_1_SOURCE);
378
379ARIZONA_MUX_ENUMS(ISRC1INT1, ARIZONA_ISRC1INT1MIX_INPUT_1_SOURCE);
380ARIZONA_MUX_ENUMS(ISRC1INT2, ARIZONA_ISRC1INT2MIX_INPUT_1_SOURCE);
381
382ARIZONA_MUX_ENUMS(ISRC1DEC1, ARIZONA_ISRC1DEC1MIX_INPUT_1_SOURCE);
383ARIZONA_MUX_ENUMS(ISRC1DEC2, ARIZONA_ISRC1DEC2MIX_INPUT_1_SOURCE);
384
385ARIZONA_MUX_ENUMS(ISRC2INT1, ARIZONA_ISRC2INT1MIX_INPUT_1_SOURCE);
386ARIZONA_MUX_ENUMS(ISRC2INT2, ARIZONA_ISRC2INT2MIX_INPUT_1_SOURCE);
387
388ARIZONA_MUX_ENUMS(ISRC2DEC1, ARIZONA_ISRC2DEC1MIX_INPUT_1_SOURCE);
389ARIZONA_MUX_ENUMS(ISRC2DEC2, ARIZONA_ISRC2DEC2MIX_INPUT_1_SOURCE);
390
391static const char *wm8997_aec_loopback_texts[] = {
392 "HPOUT1L", "HPOUT1R", "EPOUT", "SPKOUT", "SPKDAT1L", "SPKDAT1R",
393};
394
395static const unsigned int wm8997_aec_loopback_values[] = {
396 0, 1, 4, 6, 8, 9,
397};
398
399static const struct soc_enum wm8997_aec_loopback =
400 SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1,
401 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf,
402 ARRAY_SIZE(wm8997_aec_loopback_texts),
403 wm8997_aec_loopback_texts,
404 wm8997_aec_loopback_values);
405
406static const struct snd_kcontrol_new wm8997_aec_loopback_mux =
407 SOC_DAPM_VALUE_ENUM("AEC Loopback", wm8997_aec_loopback);
408
409static const struct snd_soc_dapm_widget wm8997_dapm_widgets[] = {
410SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
411 0, wm8997_sysclk_ev, SND_SOC_DAPM_POST_PMU),
412SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
413 ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
414SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK,
415 ARIZONA_OPCLK_ENA_SHIFT, 0, NULL, 0),
416SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK,
417 ARIZONA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0),
418
419SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0),
420SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
421SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS),
422SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDD", 0, 0),
423
424SND_SOC_DAPM_SIGGEN("TONE"),
425SND_SOC_DAPM_SIGGEN("NOISE"),
426SND_SOC_DAPM_SIGGEN("HAPTICS"),
427
428SND_SOC_DAPM_INPUT("IN1L"),
429SND_SOC_DAPM_INPUT("IN1R"),
430SND_SOC_DAPM_INPUT("IN2L"),
431SND_SOC_DAPM_INPUT("IN2R"),
432
433SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
434 0, NULL, 0, arizona_in_ev,
435 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
436 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
437SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
438 0, NULL, 0, arizona_in_ev,
439 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
440 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
441SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
442 0, NULL, 0, arizona_in_ev,
443 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
444 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
445SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
446 0, NULL, 0, arizona_in_ev,
447 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
448 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
449
450SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
451 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
452SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2,
453 ARIZONA_MICB2_ENA_SHIFT, 0, NULL, 0),
454SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3,
455 ARIZONA_MICB3_ENA_SHIFT, 0, NULL, 0),
456
457SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR,
458 ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0),
459
460SND_SOC_DAPM_PGA("Tone Generator 1", ARIZONA_TONE_GENERATOR_1,
461 ARIZONA_TONE1_ENA_SHIFT, 0, NULL, 0),
462SND_SOC_DAPM_PGA("Tone Generator 2", ARIZONA_TONE_GENERATOR_1,
463 ARIZONA_TONE2_ENA_SHIFT, 0, NULL, 0),
464
465SND_SOC_DAPM_PGA("Mic Mute Mixer", ARIZONA_MIC_NOISE_MIX_CONTROL_1,
466 ARIZONA_MICMUTE_MIX_ENA_SHIFT, 0, NULL, 0),
467
468SND_SOC_DAPM_PGA("EQ1", ARIZONA_EQ1_1, ARIZONA_EQ1_ENA_SHIFT, 0, NULL, 0),
469SND_SOC_DAPM_PGA("EQ2", ARIZONA_EQ2_1, ARIZONA_EQ2_ENA_SHIFT, 0, NULL, 0),
470SND_SOC_DAPM_PGA("EQ3", ARIZONA_EQ3_1, ARIZONA_EQ3_ENA_SHIFT, 0, NULL, 0),
471SND_SOC_DAPM_PGA("EQ4", ARIZONA_EQ4_1, ARIZONA_EQ4_ENA_SHIFT, 0, NULL, 0),
472
473SND_SOC_DAPM_PGA("DRC1L", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1L_ENA_SHIFT, 0,
474 NULL, 0),
475SND_SOC_DAPM_PGA("DRC1R", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1R_ENA_SHIFT, 0,
476 NULL, 0),
477
478SND_SOC_DAPM_PGA("LHPF1", ARIZONA_HPLPF1_1, ARIZONA_LHPF1_ENA_SHIFT, 0,
479 NULL, 0),
480SND_SOC_DAPM_PGA("LHPF2", ARIZONA_HPLPF2_1, ARIZONA_LHPF2_ENA_SHIFT, 0,
481 NULL, 0),
482SND_SOC_DAPM_PGA("LHPF3", ARIZONA_HPLPF3_1, ARIZONA_LHPF3_ENA_SHIFT, 0,
483 NULL, 0),
484SND_SOC_DAPM_PGA("LHPF4", ARIZONA_HPLPF4_1, ARIZONA_LHPF4_ENA_SHIFT, 0,
485 NULL, 0),
486
487SND_SOC_DAPM_PGA("PWM1 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM1_ENA_SHIFT,
488 0, NULL, 0),
489SND_SOC_DAPM_PGA("PWM2 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM2_ENA_SHIFT,
490 0, NULL, 0),
491
492SND_SOC_DAPM_PGA("ISRC1INT1", ARIZONA_ISRC_1_CTRL_3,
493 ARIZONA_ISRC1_INT0_ENA_SHIFT, 0, NULL, 0),
494SND_SOC_DAPM_PGA("ISRC1INT2", ARIZONA_ISRC_1_CTRL_3,
495 ARIZONA_ISRC1_INT1_ENA_SHIFT, 0, NULL, 0),
496
497SND_SOC_DAPM_PGA("ISRC1DEC1", ARIZONA_ISRC_1_CTRL_3,
498 ARIZONA_ISRC1_DEC0_ENA_SHIFT, 0, NULL, 0),
499SND_SOC_DAPM_PGA("ISRC1DEC2", ARIZONA_ISRC_1_CTRL_3,
500 ARIZONA_ISRC1_DEC1_ENA_SHIFT, 0, NULL, 0),
501
502SND_SOC_DAPM_PGA("ISRC2INT1", ARIZONA_ISRC_2_CTRL_3,
503 ARIZONA_ISRC2_INT0_ENA_SHIFT, 0, NULL, 0),
504SND_SOC_DAPM_PGA("ISRC2INT2", ARIZONA_ISRC_2_CTRL_3,
505 ARIZONA_ISRC2_INT1_ENA_SHIFT, 0, NULL, 0),
506
507SND_SOC_DAPM_PGA("ISRC2DEC1", ARIZONA_ISRC_2_CTRL_3,
508 ARIZONA_ISRC2_DEC0_ENA_SHIFT, 0, NULL, 0),
509SND_SOC_DAPM_PGA("ISRC2DEC2", ARIZONA_ISRC_2_CTRL_3,
510 ARIZONA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0),
511
512SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
513 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
514SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
515 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX2_ENA_SHIFT, 0),
516SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0,
517 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX3_ENA_SHIFT, 0),
518SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0,
519 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX4_ENA_SHIFT, 0),
520SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0,
521 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX5_ENA_SHIFT, 0),
522SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0,
523 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX6_ENA_SHIFT, 0),
524SND_SOC_DAPM_AIF_OUT("AIF1TX7", NULL, 0,
525 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX7_ENA_SHIFT, 0),
526SND_SOC_DAPM_AIF_OUT("AIF1TX8", NULL, 0,
527 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX8_ENA_SHIFT, 0),
528
529SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0,
530 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX1_ENA_SHIFT, 0),
531SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0,
532 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX2_ENA_SHIFT, 0),
533SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0,
534 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX3_ENA_SHIFT, 0),
535SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0,
536 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX4_ENA_SHIFT, 0),
537SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0,
538 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX5_ENA_SHIFT, 0),
539SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0,
540 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX6_ENA_SHIFT, 0),
541SND_SOC_DAPM_AIF_IN("AIF1RX7", NULL, 0,
542 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX7_ENA_SHIFT, 0),
543SND_SOC_DAPM_AIF_IN("AIF1RX8", NULL, 0,
544 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX8_ENA_SHIFT, 0),
545
546SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
547 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX1_ENA_SHIFT, 0),
548SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
549 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX2_ENA_SHIFT, 0),
550
551SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
552 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX1_ENA_SHIFT, 0),
553SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
554 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX2_ENA_SHIFT, 0),
555
556SND_SOC_DAPM_AIF_OUT("SLIMTX1", NULL, 0,
557 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
558 ARIZONA_SLIMTX1_ENA_SHIFT, 0),
559SND_SOC_DAPM_AIF_OUT("SLIMTX2", NULL, 0,
560 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
561 ARIZONA_SLIMTX2_ENA_SHIFT, 0),
562SND_SOC_DAPM_AIF_OUT("SLIMTX3", NULL, 0,
563 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
564 ARIZONA_SLIMTX3_ENA_SHIFT, 0),
565SND_SOC_DAPM_AIF_OUT("SLIMTX4", NULL, 0,
566 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
567 ARIZONA_SLIMTX4_ENA_SHIFT, 0),
568SND_SOC_DAPM_AIF_OUT("SLIMTX5", NULL, 0,
569 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
570 ARIZONA_SLIMTX5_ENA_SHIFT, 0),
571SND_SOC_DAPM_AIF_OUT("SLIMTX6", NULL, 0,
572 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
573 ARIZONA_SLIMTX6_ENA_SHIFT, 0),
574SND_SOC_DAPM_AIF_OUT("SLIMTX7", NULL, 0,
575 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
576 ARIZONA_SLIMTX7_ENA_SHIFT, 0),
577SND_SOC_DAPM_AIF_OUT("SLIMTX8", NULL, 0,
578 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
579 ARIZONA_SLIMTX8_ENA_SHIFT, 0),
580
581SND_SOC_DAPM_AIF_IN("SLIMRX1", NULL, 0,
582 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
583 ARIZONA_SLIMRX1_ENA_SHIFT, 0),
584SND_SOC_DAPM_AIF_IN("SLIMRX2", NULL, 0,
585 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
586 ARIZONA_SLIMRX2_ENA_SHIFT, 0),
587SND_SOC_DAPM_AIF_IN("SLIMRX3", NULL, 0,
588 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
589 ARIZONA_SLIMRX3_ENA_SHIFT, 0),
590SND_SOC_DAPM_AIF_IN("SLIMRX4", NULL, 0,
591 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
592 ARIZONA_SLIMRX4_ENA_SHIFT, 0),
593SND_SOC_DAPM_AIF_IN("SLIMRX5", NULL, 0,
594 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
595 ARIZONA_SLIMRX5_ENA_SHIFT, 0),
596SND_SOC_DAPM_AIF_IN("SLIMRX6", NULL, 0,
597 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
598 ARIZONA_SLIMRX6_ENA_SHIFT, 0),
599SND_SOC_DAPM_AIF_IN("SLIMRX7", NULL, 0,
600 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
601 ARIZONA_SLIMRX7_ENA_SHIFT, 0),
602SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0,
603 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
604 ARIZONA_SLIMRX8_ENA_SHIFT, 0),
605
606SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
607 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
608 &wm8997_aec_loopback_mux),
609
610SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
611 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
612 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
613SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
614 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
615 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
616SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
617 ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
618 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
619SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
620 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
621 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
622SND_SOC_DAPM_PGA_E("OUT5R", ARIZONA_OUTPUT_ENABLES_1,
623 ARIZONA_OUT5R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
624 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
625
626ARIZONA_MIXER_WIDGETS(EQ1, "EQ1"),
627ARIZONA_MIXER_WIDGETS(EQ2, "EQ2"),
628ARIZONA_MIXER_WIDGETS(EQ3, "EQ3"),
629ARIZONA_MIXER_WIDGETS(EQ4, "EQ4"),
630
631ARIZONA_MIXER_WIDGETS(DRC1L, "DRC1L"),
632ARIZONA_MIXER_WIDGETS(DRC1R, "DRC1R"),
633
634ARIZONA_MIXER_WIDGETS(LHPF1, "LHPF1"),
635ARIZONA_MIXER_WIDGETS(LHPF2, "LHPF2"),
636ARIZONA_MIXER_WIDGETS(LHPF3, "LHPF3"),
637ARIZONA_MIXER_WIDGETS(LHPF4, "LHPF4"),
638
639ARIZONA_MIXER_WIDGETS(Mic, "Mic"),
640ARIZONA_MIXER_WIDGETS(Noise, "Noise"),
641
642ARIZONA_MIXER_WIDGETS(PWM1, "PWM1"),
643ARIZONA_MIXER_WIDGETS(PWM2, "PWM2"),
644
645ARIZONA_MIXER_WIDGETS(OUT1L, "HPOUT1L"),
646ARIZONA_MIXER_WIDGETS(OUT1R, "HPOUT1R"),
647ARIZONA_MIXER_WIDGETS(OUT3, "EPOUT"),
648ARIZONA_MIXER_WIDGETS(SPKOUT, "SPKOUT"),
649ARIZONA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
650ARIZONA_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"),
651
652ARIZONA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
653ARIZONA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
654ARIZONA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
655ARIZONA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
656ARIZONA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
657ARIZONA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
658ARIZONA_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"),
659ARIZONA_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
660
661ARIZONA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
662ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
663
664ARIZONA_MIXER_WIDGETS(SLIMTX1, "SLIMTX1"),
665ARIZONA_MIXER_WIDGETS(SLIMTX2, "SLIMTX2"),
666ARIZONA_MIXER_WIDGETS(SLIMTX3, "SLIMTX3"),
667ARIZONA_MIXER_WIDGETS(SLIMTX4, "SLIMTX4"),
668ARIZONA_MIXER_WIDGETS(SLIMTX5, "SLIMTX5"),
669ARIZONA_MIXER_WIDGETS(SLIMTX6, "SLIMTX6"),
670ARIZONA_MIXER_WIDGETS(SLIMTX7, "SLIMTX7"),
671ARIZONA_MIXER_WIDGETS(SLIMTX8, "SLIMTX8"),
672
673ARIZONA_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"),
674ARIZONA_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"),
675
676ARIZONA_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"),
677ARIZONA_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"),
678
679ARIZONA_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"),
680ARIZONA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
681
682ARIZONA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
683ARIZONA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
684
685SND_SOC_DAPM_OUTPUT("HPOUT1L"),
686SND_SOC_DAPM_OUTPUT("HPOUT1R"),
687SND_SOC_DAPM_OUTPUT("EPOUTN"),
688SND_SOC_DAPM_OUTPUT("EPOUTP"),
689SND_SOC_DAPM_OUTPUT("SPKOUTN"),
690SND_SOC_DAPM_OUTPUT("SPKOUTP"),
691SND_SOC_DAPM_OUTPUT("SPKDAT1L"),
692SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
693
694SND_SOC_DAPM_OUTPUT("MICSUPP"),
695};
696
697#define ARIZONA_MIXER_INPUT_ROUTES(name) \
698 { name, "Noise Generator", "Noise Generator" }, \
699 { name, "Tone Generator 1", "Tone Generator 1" }, \
700 { name, "Tone Generator 2", "Tone Generator 2" }, \
701 { name, "Haptics", "HAPTICS" }, \
702 { name, "AEC", "AEC Loopback" }, \
703 { name, "IN1L", "IN1L PGA" }, \
704 { name, "IN1R", "IN1R PGA" }, \
705 { name, "IN2L", "IN2L PGA" }, \
706 { name, "IN2R", "IN2R PGA" }, \
707 { name, "Mic Mute Mixer", "Mic Mute Mixer" }, \
708 { name, "AIF1RX1", "AIF1RX1" }, \
709 { name, "AIF1RX2", "AIF1RX2" }, \
710 { name, "AIF1RX3", "AIF1RX3" }, \
711 { name, "AIF1RX4", "AIF1RX4" }, \
712 { name, "AIF1RX5", "AIF1RX5" }, \
713 { name, "AIF1RX6", "AIF1RX6" }, \
714 { name, "AIF1RX7", "AIF1RX7" }, \
715 { name, "AIF1RX8", "AIF1RX8" }, \
716 { name, "AIF2RX1", "AIF2RX1" }, \
717 { name, "AIF2RX2", "AIF2RX2" }, \
718 { name, "SLIMRX1", "SLIMRX1" }, \
719 { name, "SLIMRX2", "SLIMRX2" }, \
720 { name, "SLIMRX3", "SLIMRX3" }, \
721 { name, "SLIMRX4", "SLIMRX4" }, \
722 { name, "SLIMRX5", "SLIMRX5" }, \
723 { name, "SLIMRX6", "SLIMRX6" }, \
724 { name, "SLIMRX7", "SLIMRX7" }, \
725 { name, "SLIMRX8", "SLIMRX8" }, \
726 { name, "EQ1", "EQ1" }, \
727 { name, "EQ2", "EQ2" }, \
728 { name, "EQ3", "EQ3" }, \
729 { name, "EQ4", "EQ4" }, \
730 { name, "DRC1L", "DRC1L" }, \
731 { name, "DRC1R", "DRC1R" }, \
732 { name, "LHPF1", "LHPF1" }, \
733 { name, "LHPF2", "LHPF2" }, \
734 { name, "LHPF3", "LHPF3" }, \
735 { name, "LHPF4", "LHPF4" }, \
736 { name, "ISRC1DEC1", "ISRC1DEC1" }, \
737 { name, "ISRC1DEC2", "ISRC1DEC2" }, \
738 { name, "ISRC1INT1", "ISRC1INT1" }, \
739 { name, "ISRC1INT2", "ISRC1INT2" }, \
740 { name, "ISRC2DEC1", "ISRC2DEC1" }, \
741 { name, "ISRC2DEC2", "ISRC2DEC2" }, \
742 { name, "ISRC2INT1", "ISRC2INT1" }, \
743 { name, "ISRC2INT2", "ISRC2INT2" }
744
745static const struct snd_soc_dapm_route wm8997_dapm_routes[] = {
746 { "AIF2 Capture", NULL, "DBVDD2" },
747 { "AIF2 Playback", NULL, "DBVDD2" },
748
749 { "OUT1L", NULL, "CPVDD" },
750 { "OUT1R", NULL, "CPVDD" },
751 { "OUT3L", NULL, "CPVDD" },
752
753 { "OUT4L", NULL, "SPKVDD" },
754
755 { "OUT1L", NULL, "SYSCLK" },
756 { "OUT1R", NULL, "SYSCLK" },
757 { "OUT3L", NULL, "SYSCLK" },
758 { "OUT4L", NULL, "SYSCLK" },
759
760 { "IN1L", NULL, "SYSCLK" },
761 { "IN1R", NULL, "SYSCLK" },
762 { "IN2L", NULL, "SYSCLK" },
763 { "IN2R", NULL, "SYSCLK" },
764
765 { "MICBIAS1", NULL, "MICVDD" },
766 { "MICBIAS2", NULL, "MICVDD" },
767 { "MICBIAS3", NULL, "MICVDD" },
768
769 { "Noise Generator", NULL, "SYSCLK" },
770 { "Tone Generator 1", NULL, "SYSCLK" },
771 { "Tone Generator 2", NULL, "SYSCLK" },
772
773 { "Noise Generator", NULL, "NOISE" },
774 { "Tone Generator 1", NULL, "TONE" },
775 { "Tone Generator 2", NULL, "TONE" },
776
777 { "AIF1 Capture", NULL, "AIF1TX1" },
778 { "AIF1 Capture", NULL, "AIF1TX2" },
779 { "AIF1 Capture", NULL, "AIF1TX3" },
780 { "AIF1 Capture", NULL, "AIF1TX4" },
781 { "AIF1 Capture", NULL, "AIF1TX5" },
782 { "AIF1 Capture", NULL, "AIF1TX6" },
783 { "AIF1 Capture", NULL, "AIF1TX7" },
784 { "AIF1 Capture", NULL, "AIF1TX8" },
785
786 { "AIF1RX1", NULL, "AIF1 Playback" },
787 { "AIF1RX2", NULL, "AIF1 Playback" },
788 { "AIF1RX3", NULL, "AIF1 Playback" },
789 { "AIF1RX4", NULL, "AIF1 Playback" },
790 { "AIF1RX5", NULL, "AIF1 Playback" },
791 { "AIF1RX6", NULL, "AIF1 Playback" },
792 { "AIF1RX7", NULL, "AIF1 Playback" },
793 { "AIF1RX8", NULL, "AIF1 Playback" },
794
795 { "AIF2 Capture", NULL, "AIF2TX1" },
796 { "AIF2 Capture", NULL, "AIF2TX2" },
797
798 { "AIF2RX1", NULL, "AIF2 Playback" },
799 { "AIF2RX2", NULL, "AIF2 Playback" },
800
801 { "Slim1 Capture", NULL, "SLIMTX1" },
802 { "Slim1 Capture", NULL, "SLIMTX2" },
803 { "Slim1 Capture", NULL, "SLIMTX3" },
804 { "Slim1 Capture", NULL, "SLIMTX4" },
805
806 { "SLIMRX1", NULL, "Slim1 Playback" },
807 { "SLIMRX2", NULL, "Slim1 Playback" },
808 { "SLIMRX3", NULL, "Slim1 Playback" },
809 { "SLIMRX4", NULL, "Slim1 Playback" },
810
811 { "Slim2 Capture", NULL, "SLIMTX5" },
812 { "Slim2 Capture", NULL, "SLIMTX6" },
813
814 { "SLIMRX5", NULL, "Slim2 Playback" },
815 { "SLIMRX6", NULL, "Slim2 Playback" },
816
817 { "Slim3 Capture", NULL, "SLIMTX7" },
818 { "Slim3 Capture", NULL, "SLIMTX8" },
819
820 { "SLIMRX7", NULL, "Slim3 Playback" },
821 { "SLIMRX8", NULL, "Slim3 Playback" },
822
823 { "AIF1 Playback", NULL, "SYSCLK" },
824 { "AIF2 Playback", NULL, "SYSCLK" },
825 { "Slim1 Playback", NULL, "SYSCLK" },
826 { "Slim2 Playback", NULL, "SYSCLK" },
827 { "Slim3 Playback", NULL, "SYSCLK" },
828
829 { "AIF1 Capture", NULL, "SYSCLK" },
830 { "AIF2 Capture", NULL, "SYSCLK" },
831 { "Slim1 Capture", NULL, "SYSCLK" },
832 { "Slim2 Capture", NULL, "SYSCLK" },
833 { "Slim3 Capture", NULL, "SYSCLK" },
834
835 { "IN1L PGA", NULL, "IN1L" },
836 { "IN1R PGA", NULL, "IN1R" },
837
838 { "IN2L PGA", NULL, "IN2L" },
839 { "IN2R PGA", NULL, "IN2R" },
840
841 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
842 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
843 ARIZONA_MIXER_ROUTES("OUT3L", "EPOUT"),
844
845 ARIZONA_MIXER_ROUTES("OUT4L", "SPKOUT"),
846 ARIZONA_MIXER_ROUTES("OUT5L", "SPKDAT1L"),
847 ARIZONA_MIXER_ROUTES("OUT5R", "SPKDAT1R"),
848
849 ARIZONA_MIXER_ROUTES("PWM1 Driver", "PWM1"),
850 ARIZONA_MIXER_ROUTES("PWM2 Driver", "PWM2"),
851
852 ARIZONA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
853 ARIZONA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
854 ARIZONA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
855 ARIZONA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
856 ARIZONA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
857 ARIZONA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
858 ARIZONA_MIXER_ROUTES("AIF1TX7", "AIF1TX7"),
859 ARIZONA_MIXER_ROUTES("AIF1TX8", "AIF1TX8"),
860
861 ARIZONA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
862 ARIZONA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
863
864 ARIZONA_MIXER_ROUTES("SLIMTX1", "SLIMTX1"),
865 ARIZONA_MIXER_ROUTES("SLIMTX2", "SLIMTX2"),
866 ARIZONA_MIXER_ROUTES("SLIMTX3", "SLIMTX3"),
867 ARIZONA_MIXER_ROUTES("SLIMTX4", "SLIMTX4"),
868 ARIZONA_MIXER_ROUTES("SLIMTX5", "SLIMTX5"),
869 ARIZONA_MIXER_ROUTES("SLIMTX6", "SLIMTX6"),
870 ARIZONA_MIXER_ROUTES("SLIMTX7", "SLIMTX7"),
871 ARIZONA_MIXER_ROUTES("SLIMTX8", "SLIMTX8"),
872
873 ARIZONA_MIXER_ROUTES("EQ1", "EQ1"),
874 ARIZONA_MIXER_ROUTES("EQ2", "EQ2"),
875 ARIZONA_MIXER_ROUTES("EQ3", "EQ3"),
876 ARIZONA_MIXER_ROUTES("EQ4", "EQ4"),
877
878 ARIZONA_MIXER_ROUTES("DRC1L", "DRC1L"),
879 ARIZONA_MIXER_ROUTES("DRC1R", "DRC1R"),
880
881 ARIZONA_MIXER_ROUTES("LHPF1", "LHPF1"),
882 ARIZONA_MIXER_ROUTES("LHPF2", "LHPF2"),
883 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
884 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
885
886 ARIZONA_MIXER_ROUTES("Mic Mute Mixer", "Noise"),
887 ARIZONA_MIXER_ROUTES("Mic Mute Mixer", "Mic"),
888
889 ARIZONA_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
890 ARIZONA_MUX_ROUTES("ISRC1INT2", "ISRC2INT2"),
891
892 ARIZONA_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
893 ARIZONA_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
894
895 ARIZONA_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
896 ARIZONA_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
897
898 ARIZONA_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
899 ARIZONA_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
900
901 { "AEC Loopback", "HPOUT1L", "OUT1L" },
902 { "AEC Loopback", "HPOUT1R", "OUT1R" },
903 { "HPOUT1L", NULL, "OUT1L" },
904 { "HPOUT1R", NULL, "OUT1R" },
905
906 { "AEC Loopback", "EPOUT", "OUT3L" },
907 { "EPOUTN", NULL, "OUT3L" },
908 { "EPOUTP", NULL, "OUT3L" },
909
910 { "AEC Loopback", "SPKOUT", "OUT4L" },
911 { "SPKOUTN", NULL, "OUT4L" },
912 { "SPKOUTP", NULL, "OUT4L" },
913
914 { "AEC Loopback", "SPKDAT1L", "OUT5L" },
915 { "AEC Loopback", "SPKDAT1R", "OUT5R" },
916 { "SPKDAT1L", NULL, "OUT5L" },
917 { "SPKDAT1R", NULL, "OUT5R" },
918
919 { "MICSUPP", NULL, "SYSCLK" },
920};
921
922static int wm8997_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
923 unsigned int Fref, unsigned int Fout)
924{
925 struct wm8997_priv *wm8997 = snd_soc_codec_get_drvdata(codec);
926
927 switch (fll_id) {
928 case WM8997_FLL1:
929 return arizona_set_fll(&wm8997->fll[0], source, Fref, Fout);
930 case WM8997_FLL2:
931 return arizona_set_fll(&wm8997->fll[1], source, Fref, Fout);
932 case WM8997_FLL1_REFCLK:
933 return arizona_set_fll_refclk(&wm8997->fll[0], source, Fref,
934 Fout);
935 case WM8997_FLL2_REFCLK:
936 return arizona_set_fll_refclk(&wm8997->fll[1], source, Fref,
937 Fout);
938 default:
939 return -EINVAL;
940 }
941}
942
943#define WM8997_RATES SNDRV_PCM_RATE_8000_192000
944
945#define WM8997_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
946 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
947
948static struct snd_soc_dai_driver wm8997_dai[] = {
949 {
950 .name = "wm8997-aif1",
951 .id = 1,
952 .base = ARIZONA_AIF1_BCLK_CTRL,
953 .playback = {
954 .stream_name = "AIF1 Playback",
955 .channels_min = 1,
956 .channels_max = 8,
957 .rates = WM8997_RATES,
958 .formats = WM8997_FORMATS,
959 },
960 .capture = {
961 .stream_name = "AIF1 Capture",
962 .channels_min = 1,
963 .channels_max = 8,
964 .rates = WM8997_RATES,
965 .formats = WM8997_FORMATS,
966 },
967 .ops = &arizona_dai_ops,
968 .symmetric_rates = 1,
969 },
970 {
971 .name = "wm8997-aif2",
972 .id = 2,
973 .base = ARIZONA_AIF2_BCLK_CTRL,
974 .playback = {
975 .stream_name = "AIF2 Playback",
976 .channels_min = 1,
977 .channels_max = 2,
978 .rates = WM8997_RATES,
979 .formats = WM8997_FORMATS,
980 },
981 .capture = {
982 .stream_name = "AIF2 Capture",
983 .channels_min = 1,
984 .channels_max = 2,
985 .rates = WM8997_RATES,
986 .formats = WM8997_FORMATS,
987 },
988 .ops = &arizona_dai_ops,
989 .symmetric_rates = 1,
990 },
991 {
992 .name = "wm8997-slim1",
993 .id = 3,
994 .playback = {
995 .stream_name = "Slim1 Playback",
996 .channels_min = 1,
997 .channels_max = 4,
998 .rates = WM8997_RATES,
999 .formats = WM8997_FORMATS,
1000 },
1001 .capture = {
1002 .stream_name = "Slim1 Capture",
1003 .channels_min = 1,
1004 .channels_max = 4,
1005 .rates = WM8997_RATES,
1006 .formats = WM8997_FORMATS,
1007 },
1008 .ops = &arizona_simple_dai_ops,
1009 },
1010 {
1011 .name = "wm8997-slim2",
1012 .id = 4,
1013 .playback = {
1014 .stream_name = "Slim2 Playback",
1015 .channels_min = 1,
1016 .channels_max = 2,
1017 .rates = WM8997_RATES,
1018 .formats = WM8997_FORMATS,
1019 },
1020 .capture = {
1021 .stream_name = "Slim2 Capture",
1022 .channels_min = 1,
1023 .channels_max = 2,
1024 .rates = WM8997_RATES,
1025 .formats = WM8997_FORMATS,
1026 },
1027 .ops = &arizona_simple_dai_ops,
1028 },
1029 {
1030 .name = "wm8997-slim3",
1031 .id = 5,
1032 .playback = {
1033 .stream_name = "Slim3 Playback",
1034 .channels_min = 1,
1035 .channels_max = 2,
1036 .rates = WM8997_RATES,
1037 .formats = WM8997_FORMATS,
1038 },
1039 .capture = {
1040 .stream_name = "Slim3 Capture",
1041 .channels_min = 1,
1042 .channels_max = 2,
1043 .rates = WM8997_RATES,
1044 .formats = WM8997_FORMATS,
1045 },
1046 .ops = &arizona_simple_dai_ops,
1047 },
1048};
1049
1050static int wm8997_codec_probe(struct snd_soc_codec *codec)
1051{
1052 struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec);
1053 int ret;
1054
1055 codec->control_data = priv->core.arizona->regmap;
1056
1057 ret = snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
1058 if (ret != 0)
1059 return ret;
1060
1061 arizona_init_spk(codec);
1062
1063 snd_soc_dapm_disable_pin(&codec->dapm, "HAPTICS");
1064
1065 priv->core.arizona->dapm = &codec->dapm;
1066
1067 return 0;
1068}
1069
1070static int wm8997_codec_remove(struct snd_soc_codec *codec)
1071{
1072 struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec);
1073
1074 priv->core.arizona->dapm = NULL;
1075
1076 return 0;
1077}
1078
1079#define WM8997_DIG_VU 0x0200
1080
1081static unsigned int wm8997_digital_vu[] = {
1082 ARIZONA_DAC_DIGITAL_VOLUME_1L,
1083 ARIZONA_DAC_DIGITAL_VOLUME_1R,
1084 ARIZONA_DAC_DIGITAL_VOLUME_3L,
1085 ARIZONA_DAC_DIGITAL_VOLUME_4L,
1086 ARIZONA_DAC_DIGITAL_VOLUME_5L,
1087 ARIZONA_DAC_DIGITAL_VOLUME_5R,
1088};
1089
1090static struct snd_soc_codec_driver soc_codec_dev_wm8997 = {
1091 .probe = wm8997_codec_probe,
1092 .remove = wm8997_codec_remove,
1093
1094 .idle_bias_off = true,
1095
1096 .set_sysclk = arizona_set_sysclk,
1097 .set_pll = wm8997_set_fll,
1098
1099 .controls = wm8997_snd_controls,
1100 .num_controls = ARRAY_SIZE(wm8997_snd_controls),
1101 .dapm_widgets = wm8997_dapm_widgets,
1102 .num_dapm_widgets = ARRAY_SIZE(wm8997_dapm_widgets),
1103 .dapm_routes = wm8997_dapm_routes,
1104 .num_dapm_routes = ARRAY_SIZE(wm8997_dapm_routes),
1105};
1106
1107static int wm8997_probe(struct platform_device *pdev)
1108{
1109 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
1110 struct wm8997_priv *wm8997;
1111 int i;
1112
1113 wm8997 = devm_kzalloc(&pdev->dev, sizeof(struct wm8997_priv),
1114 GFP_KERNEL);
1115 if (wm8997 == NULL)
1116 return -ENOMEM;
1117 platform_set_drvdata(pdev, wm8997);
1118
1119 wm8997->core.arizona = arizona;
1120 wm8997->core.num_inputs = 4;
1121
1122 for (i = 0; i < ARRAY_SIZE(wm8997->fll); i++)
1123 wm8997->fll[i].vco_mult = 1;
1124
1125 arizona_init_fll(arizona, 1, ARIZONA_FLL1_CONTROL_1 - 1,
1126 ARIZONA_IRQ_FLL1_LOCK, ARIZONA_IRQ_FLL1_CLOCK_OK,
1127 &wm8997->fll[0]);
1128 arizona_init_fll(arizona, 2, ARIZONA_FLL2_CONTROL_1 - 1,
1129 ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK,
1130 &wm8997->fll[1]);
1131
1132 /* SR2 fixed at 8kHz, SR3 fixed at 16kHz */
1133 regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_2,
1134 ARIZONA_SAMPLE_RATE_2_MASK, 0x11);
1135 regmap_update_bits(arizona->regmap, ARIZONA_SAMPLE_RATE_3,
1136 ARIZONA_SAMPLE_RATE_3_MASK, 0x12);
1137
1138 for (i = 0; i < ARRAY_SIZE(wm8997_dai); i++)
1139 arizona_init_dai(&wm8997->core, i);
1140
1141 /* Latch volume update bits */
1142 for (i = 0; i < ARRAY_SIZE(wm8997_digital_vu); i++)
1143 regmap_update_bits(arizona->regmap, wm8997_digital_vu[i],
1144 WM8997_DIG_VU, WM8997_DIG_VU);
1145
1146 pm_runtime_enable(&pdev->dev);
1147 pm_runtime_idle(&pdev->dev);
1148
1149 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8997,
1150 wm8997_dai, ARRAY_SIZE(wm8997_dai));
1151}
1152
1153static int wm8997_remove(struct platform_device *pdev)
1154{
1155 snd_soc_unregister_codec(&pdev->dev);
1156 pm_runtime_disable(&pdev->dev);
1157
1158 return 0;
1159}
1160
1161static struct platform_driver wm8997_codec_driver = {
1162 .driver = {
1163 .name = "wm8997-codec",
1164 .owner = THIS_MODULE,
1165 },
1166 .probe = wm8997_probe,
1167 .remove = wm8997_remove,
1168};
1169
1170module_platform_driver(wm8997_codec_driver);
1171
1172MODULE_DESCRIPTION("ASoC WM8997 driver");
1173MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.wolfsonmicro.com>");
1174MODULE_LICENSE("GPL");
1175MODULE_ALIAS("platform:wm8997-codec");
diff --git a/sound/soc/codecs/wm8997.h b/sound/soc/codecs/wm8997.h
new file mode 100644
index 000000000000..5e91c6a7d567
--- /dev/null
+++ b/sound/soc/codecs/wm8997.h
@@ -0,0 +1,23 @@
1/*
2 * wm8997.h -- WM8997 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 _WM8997_H
14#define _WM8997_H
15
16#include "arizona.h"
17
18#define WM8997_FLL1 1
19#define WM8997_FLL2 2
20#define WM8997_FLL1_REFCLK 3
21#define WM8997_FLL2_REFCLK 4
22
23#endif
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 05252ac936a3..b38f3506418f 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -225,15 +225,8 @@ struct wm_coeff_ctl_ops {
225 struct snd_ctl_elem_info *uinfo); 225 struct snd_ctl_elem_info *uinfo);
226}; 226};
227 227
228struct wm_coeff {
229 struct device *dev;
230 struct list_head ctl_list;
231 struct regmap *regmap;
232};
233
234struct wm_coeff_ctl { 228struct wm_coeff_ctl {
235 const char *name; 229 const char *name;
236 struct snd_card *card;
237 struct wm_adsp_alg_region region; 230 struct wm_adsp_alg_region region;
238 struct wm_coeff_ctl_ops ops; 231 struct wm_coeff_ctl_ops ops;
239 struct wm_adsp *adsp; 232 struct wm_adsp *adsp;
@@ -378,7 +371,6 @@ static int wm_coeff_info(struct snd_kcontrol *kcontrol,
378static int wm_coeff_write_control(struct snd_kcontrol *kcontrol, 371static int wm_coeff_write_control(struct snd_kcontrol *kcontrol,
379 const void *buf, size_t len) 372 const void *buf, size_t len)
380{ 373{
381 struct wm_coeff *wm_coeff= snd_kcontrol_chip(kcontrol);
382 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 374 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
383 struct wm_adsp_alg_region *region = &ctl->region; 375 struct wm_adsp_alg_region *region = &ctl->region;
384 const struct wm_adsp_region *mem; 376 const struct wm_adsp_region *mem;
@@ -401,7 +393,7 @@ static int wm_coeff_write_control(struct snd_kcontrol *kcontrol,
401 if (!scratch) 393 if (!scratch)
402 return -ENOMEM; 394 return -ENOMEM;
403 395
404 ret = regmap_raw_write(wm_coeff->regmap, reg, scratch, 396 ret = regmap_raw_write(adsp->regmap, reg, scratch,
405 ctl->len); 397 ctl->len);
406 if (ret) { 398 if (ret) {
407 adsp_err(adsp, "Failed to write %zu bytes to %x\n", 399 adsp_err(adsp, "Failed to write %zu bytes to %x\n",
@@ -434,7 +426,6 @@ static int wm_coeff_put(struct snd_kcontrol *kcontrol,
434static int wm_coeff_read_control(struct snd_kcontrol *kcontrol, 426static int wm_coeff_read_control(struct snd_kcontrol *kcontrol,
435 void *buf, size_t len) 427 void *buf, size_t len)
436{ 428{
437 struct wm_coeff *wm_coeff= snd_kcontrol_chip(kcontrol);
438 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 429 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
439 struct wm_adsp_alg_region *region = &ctl->region; 430 struct wm_adsp_alg_region *region = &ctl->region;
440 const struct wm_adsp_region *mem; 431 const struct wm_adsp_region *mem;
@@ -457,7 +448,7 @@ static int wm_coeff_read_control(struct snd_kcontrol *kcontrol,
457 if (!scratch) 448 if (!scratch)
458 return -ENOMEM; 449 return -ENOMEM;
459 450
460 ret = regmap_raw_read(wm_coeff->regmap, reg, scratch, ctl->len); 451 ret = regmap_raw_read(adsp->regmap, reg, scratch, ctl->len);
461 if (ret) { 452 if (ret) {
462 adsp_err(adsp, "Failed to read %zu bytes from %x\n", 453 adsp_err(adsp, "Failed to read %zu bytes from %x\n",
463 ctl->len, reg); 454 ctl->len, reg);
@@ -481,37 +472,18 @@ static int wm_coeff_get(struct snd_kcontrol *kcontrol,
481 return 0; 472 return 0;
482} 473}
483 474
484static int wm_coeff_add_kcontrol(struct wm_coeff *wm_coeff,
485 struct wm_coeff_ctl *ctl,
486 const struct snd_kcontrol_new *kctl)
487{
488 int ret;
489 struct snd_kcontrol *kcontrol;
490
491 kcontrol = snd_ctl_new1(kctl, wm_coeff);
492 ret = snd_ctl_add(ctl->card, kcontrol);
493 if (ret < 0) {
494 dev_err(wm_coeff->dev, "Failed to add %s: %d\n",
495 kctl->name, ret);
496 return ret;
497 }
498 ctl->kcontrol = kcontrol;
499 return 0;
500}
501
502struct wmfw_ctl_work { 475struct wmfw_ctl_work {
503 struct wm_coeff *wm_coeff; 476 struct wm_adsp *adsp;
504 struct wm_coeff_ctl *ctl; 477 struct wm_coeff_ctl *ctl;
505 struct work_struct work; 478 struct work_struct work;
506}; 479};
507 480
508static int wmfw_add_ctl(struct wm_coeff *wm_coeff, 481static int wmfw_add_ctl(struct wm_adsp *adsp, struct wm_coeff_ctl *ctl)
509 struct wm_coeff_ctl *ctl)
510{ 482{
511 struct snd_kcontrol_new *kcontrol; 483 struct snd_kcontrol_new *kcontrol;
512 int ret; 484 int ret;
513 485
514 if (!wm_coeff || !ctl || !ctl->name || !ctl->card) 486 if (!ctl || !ctl->name)
515 return -EINVAL; 487 return -EINVAL;
516 488
517 kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL); 489 kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL);
@@ -525,14 +497,17 @@ static int wmfw_add_ctl(struct wm_coeff *wm_coeff,
525 kcontrol->put = wm_coeff_put; 497 kcontrol->put = wm_coeff_put;
526 kcontrol->private_value = (unsigned long)ctl; 498 kcontrol->private_value = (unsigned long)ctl;
527 499
528 ret = wm_coeff_add_kcontrol(wm_coeff, 500 ret = snd_soc_add_card_controls(adsp->card,
529 ctl, kcontrol); 501 kcontrol, 1);
530 if (ret < 0) 502 if (ret < 0)
531 goto err_kcontrol; 503 goto err_kcontrol;
532 504
533 kfree(kcontrol); 505 kfree(kcontrol);
534 506
535 list_add(&ctl->list, &wm_coeff->ctl_list); 507 ctl->kcontrol = snd_soc_card_get_kcontrol(adsp->card,
508 ctl->name);
509
510 list_add(&ctl->list, &adsp->ctl_list);
536 return 0; 511 return 0;
537 512
538err_kcontrol: 513err_kcontrol:
@@ -753,13 +728,12 @@ out:
753 return ret; 728 return ret;
754} 729}
755 730
756static int wm_coeff_init_control_caches(struct wm_coeff *wm_coeff) 731static int wm_coeff_init_control_caches(struct wm_adsp *adsp)
757{ 732{
758 struct wm_coeff_ctl *ctl; 733 struct wm_coeff_ctl *ctl;
759 int ret; 734 int ret;
760 735
761 list_for_each_entry(ctl, &wm_coeff->ctl_list, 736 list_for_each_entry(ctl, &adsp->ctl_list, list) {
762 list) {
763 if (!ctl->enabled || ctl->set) 737 if (!ctl->enabled || ctl->set)
764 continue; 738 continue;
765 ret = wm_coeff_read_control(ctl->kcontrol, 739 ret = wm_coeff_read_control(ctl->kcontrol,
@@ -772,13 +746,12 @@ static int wm_coeff_init_control_caches(struct wm_coeff *wm_coeff)
772 return 0; 746 return 0;
773} 747}
774 748
775static int wm_coeff_sync_controls(struct wm_coeff *wm_coeff) 749static int wm_coeff_sync_controls(struct wm_adsp *adsp)
776{ 750{
777 struct wm_coeff_ctl *ctl; 751 struct wm_coeff_ctl *ctl;
778 int ret; 752 int ret;
779 753
780 list_for_each_entry(ctl, &wm_coeff->ctl_list, 754 list_for_each_entry(ctl, &adsp->ctl_list, list) {
781 list) {
782 if (!ctl->enabled) 755 if (!ctl->enabled)
783 continue; 756 continue;
784 if (ctl->set) { 757 if (ctl->set) {
@@ -799,15 +772,14 @@ static void wm_adsp_ctl_work(struct work_struct *work)
799 struct wmfw_ctl_work, 772 struct wmfw_ctl_work,
800 work); 773 work);
801 774
802 wmfw_add_ctl(ctl_work->wm_coeff, ctl_work->ctl); 775 wmfw_add_ctl(ctl_work->adsp, ctl_work->ctl);
803 kfree(ctl_work); 776 kfree(ctl_work);
804} 777}
805 778
806static int wm_adsp_create_control(struct snd_soc_codec *codec, 779static int wm_adsp_create_control(struct wm_adsp *dsp,
807 const struct wm_adsp_alg_region *region) 780 const struct wm_adsp_alg_region *region)
808 781
809{ 782{
810 struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
811 struct wm_coeff_ctl *ctl; 783 struct wm_coeff_ctl *ctl;
812 struct wmfw_ctl_work *ctl_work; 784 struct wmfw_ctl_work *ctl_work;
813 char *name; 785 char *name;
@@ -842,7 +814,7 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec,
842 snprintf(name, PAGE_SIZE, "DSP%d %s %x", 814 snprintf(name, PAGE_SIZE, "DSP%d %s %x",
843 dsp->num, region_name, region->alg); 815 dsp->num, region_name, region->alg);
844 816
845 list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list, 817 list_for_each_entry(ctl, &dsp->ctl_list,
846 list) { 818 list) {
847 if (!strcmp(ctl->name, name)) { 819 if (!strcmp(ctl->name, name)) {
848 if (!ctl->enabled) 820 if (!ctl->enabled)
@@ -866,7 +838,6 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec,
866 ctl->set = 0; 838 ctl->set = 0;
867 ctl->ops.xget = wm_coeff_get; 839 ctl->ops.xget = wm_coeff_get;
868 ctl->ops.xput = wm_coeff_put; 840 ctl->ops.xput = wm_coeff_put;
869 ctl->card = codec->card->snd_card;
870 ctl->adsp = dsp; 841 ctl->adsp = dsp;
871 842
872 ctl->len = region->len; 843 ctl->len = region->len;
@@ -882,7 +853,7 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec,
882 goto err_ctl_cache; 853 goto err_ctl_cache;
883 } 854 }
884 855
885 ctl_work->wm_coeff = dsp->wm_coeff; 856 ctl_work->adsp = dsp;
886 ctl_work->ctl = ctl; 857 ctl_work->ctl = ctl;
887 INIT_WORK(&ctl_work->work, wm_adsp_ctl_work); 858 INIT_WORK(&ctl_work->work, wm_adsp_ctl_work);
888 schedule_work(&ctl_work->work); 859 schedule_work(&ctl_work->work);
@@ -903,7 +874,7 @@ err_name:
903 return ret; 874 return ret;
904} 875}
905 876
906static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec) 877static int wm_adsp_setup_algs(struct wm_adsp *dsp)
907{ 878{
908 struct regmap *regmap = dsp->regmap; 879 struct regmap *regmap = dsp->regmap;
909 struct wmfw_adsp1_id_hdr adsp1_id; 880 struct wmfw_adsp1_id_hdr adsp1_id;
@@ -1091,7 +1062,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec)
1091 if (i + 1 < algs) { 1062 if (i + 1 < algs) {
1092 region->len = be32_to_cpu(adsp1_alg[i + 1].dm); 1063 region->len = be32_to_cpu(adsp1_alg[i + 1].dm);
1093 region->len -= be32_to_cpu(adsp1_alg[i].dm); 1064 region->len -= be32_to_cpu(adsp1_alg[i].dm);
1094 wm_adsp_create_control(codec, region); 1065 wm_adsp_create_control(dsp, region);
1095 } else { 1066 } else {
1096 adsp_warn(dsp, "Missing length info for region DM with ID %x\n", 1067 adsp_warn(dsp, "Missing length info for region DM with ID %x\n",
1097 be32_to_cpu(adsp1_alg[i].alg.id)); 1068 be32_to_cpu(adsp1_alg[i].alg.id));
@@ -1108,7 +1079,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec)
1108 if (i + 1 < algs) { 1079 if (i + 1 < algs) {
1109 region->len = be32_to_cpu(adsp1_alg[i + 1].zm); 1080 region->len = be32_to_cpu(adsp1_alg[i + 1].zm);
1110 region->len -= be32_to_cpu(adsp1_alg[i].zm); 1081 region->len -= be32_to_cpu(adsp1_alg[i].zm);
1111 wm_adsp_create_control(codec, region); 1082 wm_adsp_create_control(dsp, region);
1112 } else { 1083 } else {
1113 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", 1084 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n",
1114 be32_to_cpu(adsp1_alg[i].alg.id)); 1085 be32_to_cpu(adsp1_alg[i].alg.id));
@@ -1137,7 +1108,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec)
1137 if (i + 1 < algs) { 1108 if (i + 1 < algs) {
1138 region->len = be32_to_cpu(adsp2_alg[i + 1].xm); 1109 region->len = be32_to_cpu(adsp2_alg[i + 1].xm);
1139 region->len -= be32_to_cpu(adsp2_alg[i].xm); 1110 region->len -= be32_to_cpu(adsp2_alg[i].xm);
1140 wm_adsp_create_control(codec, region); 1111 wm_adsp_create_control(dsp, region);
1141 } else { 1112 } else {
1142 adsp_warn(dsp, "Missing length info for region XM with ID %x\n", 1113 adsp_warn(dsp, "Missing length info for region XM with ID %x\n",
1143 be32_to_cpu(adsp2_alg[i].alg.id)); 1114 be32_to_cpu(adsp2_alg[i].alg.id));
@@ -1154,7 +1125,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec)
1154 if (i + 1 < algs) { 1125 if (i + 1 < algs) {
1155 region->len = be32_to_cpu(adsp2_alg[i + 1].ym); 1126 region->len = be32_to_cpu(adsp2_alg[i + 1].ym);
1156 region->len -= be32_to_cpu(adsp2_alg[i].ym); 1127 region->len -= be32_to_cpu(adsp2_alg[i].ym);
1157 wm_adsp_create_control(codec, region); 1128 wm_adsp_create_control(dsp, region);
1158 } else { 1129 } else {
1159 adsp_warn(dsp, "Missing length info for region YM with ID %x\n", 1130 adsp_warn(dsp, "Missing length info for region YM with ID %x\n",
1160 be32_to_cpu(adsp2_alg[i].alg.id)); 1131 be32_to_cpu(adsp2_alg[i].alg.id));
@@ -1171,7 +1142,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec)
1171 if (i + 1 < algs) { 1142 if (i + 1 < algs) {
1172 region->len = be32_to_cpu(adsp2_alg[i + 1].zm); 1143 region->len = be32_to_cpu(adsp2_alg[i + 1].zm);
1173 region->len -= be32_to_cpu(adsp2_alg[i].zm); 1144 region->len -= be32_to_cpu(adsp2_alg[i].zm);
1174 wm_adsp_create_control(codec, region); 1145 wm_adsp_create_control(dsp, region);
1175 } else { 1146 } else {
1176 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", 1147 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n",
1177 be32_to_cpu(adsp2_alg[i].alg.id)); 1148 be32_to_cpu(adsp2_alg[i].alg.id));
@@ -1391,6 +1362,8 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1391 int ret; 1362 int ret;
1392 int val; 1363 int val;
1393 1364
1365 dsp->card = codec->card;
1366
1394 switch (event) { 1367 switch (event) {
1395 case SND_SOC_DAPM_POST_PMU: 1368 case SND_SOC_DAPM_POST_PMU:
1396 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 1369 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
@@ -1425,7 +1398,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1425 if (ret != 0) 1398 if (ret != 0)
1426 goto err; 1399 goto err;
1427 1400
1428 ret = wm_adsp_setup_algs(dsp, codec); 1401 ret = wm_adsp_setup_algs(dsp);
1429 if (ret != 0) 1402 if (ret != 0)
1430 goto err; 1403 goto err;
1431 1404
@@ -1434,12 +1407,12 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1434 goto err; 1407 goto err;
1435 1408
1436 /* Initialize caches for enabled and unset controls */ 1409 /* Initialize caches for enabled and unset controls */
1437 ret = wm_coeff_init_control_caches(dsp->wm_coeff); 1410 ret = wm_coeff_init_control_caches(dsp);
1438 if (ret != 0) 1411 if (ret != 0)
1439 goto err; 1412 goto err;
1440 1413
1441 /* Sync set controls */ 1414 /* Sync set controls */
1442 ret = wm_coeff_sync_controls(dsp->wm_coeff); 1415 ret = wm_coeff_sync_controls(dsp);
1443 if (ret != 0) 1416 if (ret != 0)
1444 goto err; 1417 goto err;
1445 1418
@@ -1460,10 +1433,8 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1460 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 1433 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
1461 ADSP1_SYS_ENA, 0); 1434 ADSP1_SYS_ENA, 0);
1462 1435
1463 list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list, 1436 list_for_each_entry(ctl, &dsp->ctl_list, list)
1464 list) {
1465 ctl->enabled = 0; 1437 ctl->enabled = 0;
1466 }
1467 break; 1438 break;
1468 1439
1469 default: 1440 default:
@@ -1520,6 +1491,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1520 unsigned int val; 1491 unsigned int val;
1521 int ret; 1492 int ret;
1522 1493
1494 dsp->card = codec->card;
1495
1523 switch (event) { 1496 switch (event) {
1524 case SND_SOC_DAPM_POST_PMU: 1497 case SND_SOC_DAPM_POST_PMU:
1525 /* 1498 /*
@@ -1582,7 +1555,7 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1582 if (ret != 0) 1555 if (ret != 0)
1583 goto err; 1556 goto err;
1584 1557
1585 ret = wm_adsp_setup_algs(dsp, codec); 1558 ret = wm_adsp_setup_algs(dsp);
1586 if (ret != 0) 1559 if (ret != 0)
1587 goto err; 1560 goto err;
1588 1561
@@ -1591,12 +1564,12 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1591 goto err; 1564 goto err;
1592 1565
1593 /* Initialize caches for enabled and unset controls */ 1566 /* Initialize caches for enabled and unset controls */
1594 ret = wm_coeff_init_control_caches(dsp->wm_coeff); 1567 ret = wm_coeff_init_control_caches(dsp);
1595 if (ret != 0) 1568 if (ret != 0)
1596 goto err; 1569 goto err;
1597 1570
1598 /* Sync set controls */ 1571 /* Sync set controls */
1599 ret = wm_coeff_sync_controls(dsp->wm_coeff); 1572 ret = wm_coeff_sync_controls(dsp);
1600 if (ret != 0) 1573 if (ret != 0)
1601 goto err; 1574 goto err;
1602 1575
@@ -1637,10 +1610,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1637 ret); 1610 ret);
1638 } 1611 }
1639 1612
1640 list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list, 1613 list_for_each_entry(ctl, &dsp->ctl_list, list)
1641 list) {
1642 ctl->enabled = 0; 1614 ctl->enabled = 0;
1643 }
1644 1615
1645 while (!list_empty(&dsp->alg_regions)) { 1616 while (!list_empty(&dsp->alg_regions)) {
1646 alg_region = list_first_entry(&dsp->alg_regions, 1617 alg_region = list_first_entry(&dsp->alg_regions,
@@ -1679,49 +1650,38 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
1679 } 1650 }
1680 1651
1681 INIT_LIST_HEAD(&adsp->alg_regions); 1652 INIT_LIST_HEAD(&adsp->alg_regions);
1682 1653 INIT_LIST_HEAD(&adsp->ctl_list);
1683 adsp->wm_coeff = kzalloc(sizeof(*adsp->wm_coeff),
1684 GFP_KERNEL);
1685 if (!adsp->wm_coeff)
1686 return -ENOMEM;
1687 adsp->wm_coeff->regmap = adsp->regmap;
1688 adsp->wm_coeff->dev = adsp->dev;
1689 INIT_LIST_HEAD(&adsp->wm_coeff->ctl_list);
1690 1654
1691 if (dvfs) { 1655 if (dvfs) {
1692 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); 1656 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD");
1693 if (IS_ERR(adsp->dvfs)) { 1657 if (IS_ERR(adsp->dvfs)) {
1694 ret = PTR_ERR(adsp->dvfs); 1658 ret = PTR_ERR(adsp->dvfs);
1695 dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret); 1659 dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret);
1696 goto out_coeff; 1660 return ret;
1697 } 1661 }
1698 1662
1699 ret = regulator_enable(adsp->dvfs); 1663 ret = regulator_enable(adsp->dvfs);
1700 if (ret != 0) { 1664 if (ret != 0) {
1701 dev_err(adsp->dev, "Failed to enable DCVDD: %d\n", 1665 dev_err(adsp->dev, "Failed to enable DCVDD: %d\n",
1702 ret); 1666 ret);
1703 goto out_coeff; 1667 return ret;
1704 } 1668 }
1705 1669
1706 ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000); 1670 ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000);
1707 if (ret != 0) { 1671 if (ret != 0) {
1708 dev_err(adsp->dev, "Failed to initialise DVFS: %d\n", 1672 dev_err(adsp->dev, "Failed to initialise DVFS: %d\n",
1709 ret); 1673 ret);
1710 goto out_coeff; 1674 return ret;
1711 } 1675 }
1712 1676
1713 ret = regulator_disable(adsp->dvfs); 1677 ret = regulator_disable(adsp->dvfs);
1714 if (ret != 0) { 1678 if (ret != 0) {
1715 dev_err(adsp->dev, "Failed to disable DCVDD: %d\n", 1679 dev_err(adsp->dev, "Failed to disable DCVDD: %d\n",
1716 ret); 1680 ret);
1717 goto out_coeff; 1681 return ret;
1718 } 1682 }
1719 } 1683 }
1720 1684
1721 return 0; 1685 return 0;
1722
1723out_coeff:
1724 kfree(adsp->wm_coeff);
1725 return ret;
1726} 1686}
1727EXPORT_SYMBOL_GPL(wm_adsp2_init); 1687EXPORT_SYMBOL_GPL(wm_adsp2_init);
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 9f922c82536c..d018dea6254d 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -39,6 +39,7 @@ struct wm_adsp {
39 int type; 39 int type;
40 struct device *dev; 40 struct device *dev;
41 struct regmap *regmap; 41 struct regmap *regmap;
42 struct snd_soc_card *card;
42 43
43 int base; 44 int base;
44 int sysclk_reg; 45 int sysclk_reg;
@@ -57,7 +58,7 @@ struct wm_adsp {
57 58
58 struct regulator *dvfs; 59 struct regulator *dvfs;
59 60
60 struct wm_coeff *wm_coeff; 61 struct list_head ctl_list;
61}; 62};
62 63
63#define WM_ADSP1(wname, num) \ 64#define WM_ADSP1(wname, num) \
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 2d9e099415a5..8b50e5958de5 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -699,9 +699,7 @@ EXPORT_SYMBOL_GPL(wm_hubs_update_class_w);
699static int class_w_put_volsw(struct snd_kcontrol *kcontrol, 699static int class_w_put_volsw(struct snd_kcontrol *kcontrol,
700 struct snd_ctl_elem_value *ucontrol) 700 struct snd_ctl_elem_value *ucontrol)
701{ 701{
702 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 702 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
703 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
704 struct snd_soc_codec *codec = widget->codec;
705 int ret; 703 int ret;
706 704
707 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); 705 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
@@ -721,9 +719,7 @@ static int class_w_put_volsw(struct snd_kcontrol *kcontrol,
721static int class_w_put_double(struct snd_kcontrol *kcontrol, 719static int class_w_put_double(struct snd_kcontrol *kcontrol,
722 struct snd_ctl_elem_value *ucontrol) 720 struct snd_ctl_elem_value *ucontrol)
723{ 721{
724 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 722 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
725 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
726 struct snd_soc_codec *codec = widget->codec;
727 int ret; 723 int ret;
728 724
729 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol); 725 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index 70eb37a5dd16..25c31f1655f6 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -421,13 +421,11 @@ static int dw_i2s_probe(struct platform_device *pdev)
421 dw_i2s_dai, 1); 421 dw_i2s_dai, 1);
422 if (ret != 0) { 422 if (ret != 0) {
423 dev_err(&pdev->dev, "not able to register dai\n"); 423 dev_err(&pdev->dev, "not able to register dai\n");
424 goto err_set_drvdata; 424 goto err_clk_disable;
425 } 425 }
426 426
427 return 0; 427 return 0;
428 428
429err_set_drvdata:
430 dev_set_drvdata(&pdev->dev, NULL);
431err_clk_disable: 429err_clk_disable:
432 clk_disable(dev->clk); 430 clk_disable(dev->clk);
433err_clk_put: 431err_clk_put:
@@ -440,7 +438,6 @@ static int dw_i2s_remove(struct platform_device *pdev)
440 struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); 438 struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
441 439
442 snd_soc_unregister_component(&pdev->dev); 440 snd_soc_unregister_component(&pdev->dev);
443 dev_set_drvdata(&pdev->dev, NULL);
444 441
445 clk_put(dev->clk); 442 clk_put(dev->clk);
446 443
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index aa438546c912..704e246f5b1e 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -1,6 +1,9 @@
1config SND_SOC_FSL_SSI 1config SND_SOC_FSL_SSI
2 tristate 2 tristate
3 3
4config SND_SOC_FSL_SPDIF
5 tristate
6
4config SND_SOC_FSL_UTILS 7config SND_SOC_FSL_UTILS
5 tristate 8 tristate
6 9
@@ -98,7 +101,7 @@ endif # SND_POWERPC_SOC
98 101
99menuconfig SND_IMX_SOC 102menuconfig SND_IMX_SOC
100 tristate "SoC Audio for Freescale i.MX CPUs" 103 tristate "SoC Audio for Freescale i.MX CPUs"
101 depends on ARCH_MXC 104 depends on ARCH_MXC || COMPILE_TEST
102 help 105 help
103 Say Y or M if you want to add support for codecs attached to 106 Say Y or M if you want to add support for codecs attached to
104 the i.MX CPUs. 107 the i.MX CPUs.
@@ -109,11 +112,11 @@ config SND_SOC_IMX_SSI
109 tristate 112 tristate
110 113
111config SND_SOC_IMX_PCM_FIQ 114config SND_SOC_IMX_PCM_FIQ
112 bool 115 tristate
113 select FIQ 116 select FIQ
114 117
115config SND_SOC_IMX_PCM_DMA 118config SND_SOC_IMX_PCM_DMA
116 bool 119 tristate
117 select SND_SOC_GENERIC_DMAENGINE_PCM 120 select SND_SOC_GENERIC_DMAENGINE_PCM
118 121
119config SND_SOC_IMX_AUDMUX 122config SND_SOC_IMX_AUDMUX
@@ -175,7 +178,6 @@ config SND_SOC_IMX_WM8962
175 select SND_SOC_IMX_PCM_DMA 178 select SND_SOC_IMX_PCM_DMA
176 select SND_SOC_IMX_AUDMUX 179 select SND_SOC_IMX_AUDMUX
177 select SND_SOC_FSL_SSI 180 select SND_SOC_FSL_SSI
178 select SND_SOC_FSL_UTILS
179 help 181 help
180 Say Y if you want to add support for SoC audio on an i.MX board with 182 Say Y if you want to add support for SoC audio on an i.MX board with
181 a wm8962 codec. 183 a wm8962 codec.
@@ -187,14 +189,23 @@ config SND_SOC_IMX_SGTL5000
187 select SND_SOC_IMX_PCM_DMA 189 select SND_SOC_IMX_PCM_DMA
188 select SND_SOC_IMX_AUDMUX 190 select SND_SOC_IMX_AUDMUX
189 select SND_SOC_FSL_SSI 191 select SND_SOC_FSL_SSI
190 select SND_SOC_FSL_UTILS
191 help 192 help
192 Say Y if you want to add support for SoC audio on an i.MX board with 193 Say Y if you want to add support for SoC audio on an i.MX board with
193 a sgtl5000 codec. 194 a sgtl5000 codec.
194 195
196config SND_SOC_IMX_SPDIF
197 tristate "SoC Audio support for i.MX boards with S/PDIF"
198 select SND_SOC_IMX_PCM_DMA
199 select SND_SOC_FSL_SPDIF
200 select SND_SOC_SPDIF
201 help
202 SoC Audio support for i.MX boards with S/PDIF
203 Say Y if you want to add support for SoC audio on an i.MX board with
204 a S/DPDIF.
205
195config SND_SOC_IMX_MC13783 206config SND_SOC_IMX_MC13783
196 tristate "SoC Audio support for I.MX boards with mc13783" 207 tristate "SoC Audio support for I.MX boards with mc13783"
197 depends on MFD_MC13783 208 depends on MFD_MC13783 && ARM
198 select SND_SOC_IMX_SSI 209 select SND_SOC_IMX_SSI
199 select SND_SOC_IMX_AUDMUX 210 select SND_SOC_IMX_AUDMUX
200 select SND_SOC_MC13783 211 select SND_SOC_MC13783
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index d4b4aa8b5649..8db705b0fdf9 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -12,9 +12,11 @@ obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
12 12
13# Freescale PowerPC SSI/DMA Platform Support 13# Freescale PowerPC SSI/DMA Platform Support
14snd-soc-fsl-ssi-objs := fsl_ssi.o 14snd-soc-fsl-ssi-objs := fsl_ssi.o
15snd-soc-fsl-spdif-objs := fsl_spdif.o
15snd-soc-fsl-utils-objs := fsl_utils.o 16snd-soc-fsl-utils-objs := fsl_utils.o
16snd-soc-fsl-dma-objs := fsl_dma.o 17snd-soc-fsl-dma-objs := fsl_dma.o
17obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o 18obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o
19obj-$(CONFIG_SND_SOC_FSL_SPDIF) += snd-soc-fsl-spdif.o
18obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o 20obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o
19obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o 21obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
20 22
@@ -43,6 +45,7 @@ snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
43snd-soc-wm1133-ev1-objs := wm1133-ev1.o 45snd-soc-wm1133-ev1-objs := wm1133-ev1.o
44snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o 46snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
45snd-soc-imx-wm8962-objs := imx-wm8962.o 47snd-soc-imx-wm8962-objs := imx-wm8962.o
48snd-soc-imx-spdif-objs := imx-spdif.o
46snd-soc-imx-mc13783-objs := imx-mc13783.o 49snd-soc-imx-mc13783-objs := imx-mc13783.o
47 50
48obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o 51obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
@@ -51,4 +54,5 @@ obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
51obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o 54obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
52obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o 55obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
53obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o 56obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o
57obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
54obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o 58obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
new file mode 100644
index 000000000000..3920c3e849ce
--- /dev/null
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -0,0 +1,1225 @@
1/*
2 * Freescale S/PDIF ALSA SoC Digital Audio Interface (DAI) driver
3 *
4 * Copyright (C) 2013 Freescale Semiconductor, Inc.
5 *
6 * Based on stmp3xxx_spdif_dai.c
7 * Vladimir Barinov <vbarinov@embeddedalley.com>
8 * Copyright 2008 SigmaTel, Inc
9 * Copyright 2008 Embedded Alley Solutions, Inc
10 *
11 * This file is licensed under the terms of the GNU General Public License
12 * version 2. This program is licensed "as is" without any warranty of any
13 * kind, whether express or implied.
14 */
15
16#include <linux/module.h>
17#include <linux/clk.h>
18#include <linux/clk-private.h>
19#include <linux/bitrev.h>
20#include <linux/regmap.h>
21#include <linux/of_address.h>
22#include <linux/of_device.h>
23#include <linux/of_irq.h>
24
25#include <sound/asoundef.h>
26#include <sound/soc.h>
27#include <sound/dmaengine_pcm.h>
28
29#include "fsl_spdif.h"
30#include "imx-pcm.h"
31
32#define FSL_SPDIF_TXFIFO_WML 0x8
33#define FSL_SPDIF_RXFIFO_WML 0x8
34
35#define INTR_FOR_PLAYBACK (INT_TXFIFO_RESYNC)
36#define INTR_FOR_CAPTURE (INT_SYM_ERR | INT_BIT_ERR | INT_URX_FUL | INT_URX_OV|\
37 INT_QRX_FUL | INT_QRX_OV | INT_UQ_SYNC | INT_UQ_ERR |\
38 INT_RXFIFO_RESYNC | INT_LOSS_LOCK | INT_DPLL_LOCKED)
39
40/* Index list for the values that has if (DPLL Locked) condition */
41static u8 srpc_dpll_locked[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0xa, 0xb };
42#define SRPC_NODPLL_START1 0x5
43#define SRPC_NODPLL_START2 0xc
44
45#define DEFAULT_RXCLK_SRC 1
46
47/*
48 * SPDIF control structure
49 * Defines channel status, subcode and Q sub
50 */
51struct spdif_mixer_control {
52 /* spinlock to access control data */
53 spinlock_t ctl_lock;
54
55 /* IEC958 channel tx status bit */
56 unsigned char ch_status[4];
57
58 /* User bits */
59 unsigned char subcode[2 * SPDIF_UBITS_SIZE];
60
61 /* Q subcode part of user bits */
62 unsigned char qsub[2 * SPDIF_QSUB_SIZE];
63
64 /* Buffer offset for U/Q */
65 u32 upos;
66 u32 qpos;
67
68 /* Ready buffer index of the two buffers */
69 u32 ready_buf;
70};
71
72struct fsl_spdif_priv {
73 struct spdif_mixer_control fsl_spdif_control;
74 struct snd_soc_dai_driver cpu_dai_drv;
75 struct platform_device *pdev;
76 struct regmap *regmap;
77 bool dpll_locked;
78 u8 txclk_div[SPDIF_TXRATE_MAX];
79 u8 txclk_src[SPDIF_TXRATE_MAX];
80 u8 rxclk_src;
81 struct clk *txclk[SPDIF_TXRATE_MAX];
82 struct clk *rxclk;
83 struct snd_dmaengine_dai_dma_data dma_params_tx;
84 struct snd_dmaengine_dai_dma_data dma_params_rx;
85
86 /* The name space will be allocated dynamically */
87 char name[0];
88};
89
90
91/* DPLL locked and lock loss interrupt handler */
92static void spdif_irq_dpll_lock(struct fsl_spdif_priv *spdif_priv)
93{
94 struct regmap *regmap = spdif_priv->regmap;
95 struct platform_device *pdev = spdif_priv->pdev;
96 u32 locked;
97
98 regmap_read(regmap, REG_SPDIF_SRPC, &locked);
99 locked &= SRPC_DPLL_LOCKED;
100
101 dev_dbg(&pdev->dev, "isr: Rx dpll %s \n",
102 locked ? "locked" : "loss lock");
103
104 spdif_priv->dpll_locked = locked ? true : false;
105}
106
107/* Receiver found illegal symbol interrupt handler */
108static void spdif_irq_sym_error(struct fsl_spdif_priv *spdif_priv)
109{
110 struct regmap *regmap = spdif_priv->regmap;
111 struct platform_device *pdev = spdif_priv->pdev;
112
113 dev_dbg(&pdev->dev, "isr: receiver found illegal symbol\n");
114
115 if (!spdif_priv->dpll_locked) {
116 /* DPLL unlocked seems no audio stream */
117 regmap_update_bits(regmap, REG_SPDIF_SIE, INT_SYM_ERR, 0);
118 }
119}
120
121/* U/Q Channel receive register full */
122static void spdif_irq_uqrx_full(struct fsl_spdif_priv *spdif_priv, char name)
123{
124 struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
125 struct regmap *regmap = spdif_priv->regmap;
126 struct platform_device *pdev = spdif_priv->pdev;
127 u32 *pos, size, val, reg;
128
129 switch (name) {
130 case 'U':
131 pos = &ctrl->upos;
132 size = SPDIF_UBITS_SIZE;
133 reg = REG_SPDIF_SRU;
134 break;
135 case 'Q':
136 pos = &ctrl->qpos;
137 size = SPDIF_QSUB_SIZE;
138 reg = REG_SPDIF_SRQ;
139 break;
140 default:
141 dev_err(&pdev->dev, "unsupported channel name\n");
142 return;
143 }
144
145 dev_dbg(&pdev->dev, "isr: %c Channel receive register full\n", name);
146
147 if (*pos >= size * 2) {
148 *pos = 0;
149 } else if (unlikely((*pos % size) + 3 > size)) {
150 dev_err(&pdev->dev, "User bit receivce buffer overflow\n");
151 return;
152 }
153
154 regmap_read(regmap, reg, &val);
155 ctrl->subcode[*pos++] = val >> 16;
156 ctrl->subcode[*pos++] = val >> 8;
157 ctrl->subcode[*pos++] = val;
158}
159
160/* U/Q Channel sync found */
161static void spdif_irq_uq_sync(struct fsl_spdif_priv *spdif_priv)
162{
163 struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
164 struct platform_device *pdev = spdif_priv->pdev;
165
166 dev_dbg(&pdev->dev, "isr: U/Q Channel sync found\n");
167
168 /* U/Q buffer reset */
169 if (ctrl->qpos == 0)
170 return;
171
172 /* Set ready to this buffer */
173 ctrl->ready_buf = (ctrl->qpos - 1) / SPDIF_QSUB_SIZE + 1;
174}
175
176/* U/Q Channel framing error */
177static void spdif_irq_uq_err(struct fsl_spdif_priv *spdif_priv)
178{
179 struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
180 struct regmap *regmap = spdif_priv->regmap;
181 struct platform_device *pdev = spdif_priv->pdev;
182 u32 val;
183
184 dev_dbg(&pdev->dev, "isr: U/Q Channel framing error\n");
185
186 /* Read U/Q data to clear the irq and do buffer reset */
187 regmap_read(regmap, REG_SPDIF_SRU, &val);
188 regmap_read(regmap, REG_SPDIF_SRQ, &val);
189
190 /* Drop this U/Q buffer */
191 ctrl->ready_buf = 0;
192 ctrl->upos = 0;
193 ctrl->qpos = 0;
194}
195
196/* Get spdif interrupt status and clear the interrupt */
197static u32 spdif_intr_status_clear(struct fsl_spdif_priv *spdif_priv)
198{
199 struct regmap *regmap = spdif_priv->regmap;
200 u32 val, val2;
201
202 regmap_read(regmap, REG_SPDIF_SIS, &val);
203 regmap_read(regmap, REG_SPDIF_SIE, &val2);
204
205 regmap_write(regmap, REG_SPDIF_SIC, val & val2);
206
207 return val;
208}
209
210static irqreturn_t spdif_isr(int irq, void *devid)
211{
212 struct fsl_spdif_priv *spdif_priv = (struct fsl_spdif_priv *)devid;
213 struct platform_device *pdev = spdif_priv->pdev;
214 u32 sis;
215
216 sis = spdif_intr_status_clear(spdif_priv);
217
218 if (sis & INT_DPLL_LOCKED)
219 spdif_irq_dpll_lock(spdif_priv);
220
221 if (sis & INT_TXFIFO_UNOV)
222 dev_dbg(&pdev->dev, "isr: Tx FIFO under/overrun\n");
223
224 if (sis & INT_TXFIFO_RESYNC)
225 dev_dbg(&pdev->dev, "isr: Tx FIFO resync\n");
226
227 if (sis & INT_CNEW)
228 dev_dbg(&pdev->dev, "isr: cstatus new\n");
229
230 if (sis & INT_VAL_NOGOOD)
231 dev_dbg(&pdev->dev, "isr: validity flag no good\n");
232
233 if (sis & INT_SYM_ERR)
234 spdif_irq_sym_error(spdif_priv);
235
236 if (sis & INT_BIT_ERR)
237 dev_dbg(&pdev->dev, "isr: receiver found parity bit error\n");
238
239 if (sis & INT_URX_FUL)
240 spdif_irq_uqrx_full(spdif_priv, 'U');
241
242 if (sis & INT_URX_OV)
243 dev_dbg(&pdev->dev, "isr: U Channel receive register overrun\n");
244
245 if (sis & INT_QRX_FUL)
246 spdif_irq_uqrx_full(spdif_priv, 'Q');
247
248 if (sis & INT_QRX_OV)
249 dev_dbg(&pdev->dev, "isr: Q Channel receive register overrun\n");
250
251 if (sis & INT_UQ_SYNC)
252 spdif_irq_uq_sync(spdif_priv);
253
254 if (sis & INT_UQ_ERR)
255 spdif_irq_uq_err(spdif_priv);
256
257 if (sis & INT_RXFIFO_UNOV)
258 dev_dbg(&pdev->dev, "isr: Rx FIFO under/overrun\n");
259
260 if (sis & INT_RXFIFO_RESYNC)
261 dev_dbg(&pdev->dev, "isr: Rx FIFO resync\n");
262
263 if (sis & INT_LOSS_LOCK)
264 spdif_irq_dpll_lock(spdif_priv);
265
266 /* FIXME: Write Tx FIFO to clear TxEm */
267 if (sis & INT_TX_EM)
268 dev_dbg(&pdev->dev, "isr: Tx FIFO empty\n");
269
270 /* FIXME: Read Rx FIFO to clear RxFIFOFul */
271 if (sis & INT_RXFIFO_FUL)
272 dev_dbg(&pdev->dev, "isr: Rx FIFO full\n");
273
274 return IRQ_HANDLED;
275}
276
277static int spdif_softreset(struct fsl_spdif_priv *spdif_priv)
278{
279 struct regmap *regmap = spdif_priv->regmap;
280 u32 val, cycle = 1000;
281
282 regmap_write(regmap, REG_SPDIF_SCR, SCR_SOFT_RESET);
283
284 /*
285 * RESET bit would be cleared after finishing its reset procedure,
286 * which typically lasts 8 cycles. 1000 cycles will keep it safe.
287 */
288 do {
289 regmap_read(regmap, REG_SPDIF_SCR, &val);
290 } while ((val & SCR_SOFT_RESET) && cycle--);
291
292 if (cycle)
293 return 0;
294 else
295 return -EBUSY;
296}
297
298static void spdif_set_cstatus(struct spdif_mixer_control *ctrl,
299 u8 mask, u8 cstatus)
300{
301 ctrl->ch_status[3] &= ~mask;
302 ctrl->ch_status[3] |= cstatus & mask;
303}
304
305static void spdif_write_channel_status(struct fsl_spdif_priv *spdif_priv)
306{
307 struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
308 struct regmap *regmap = spdif_priv->regmap;
309 struct platform_device *pdev = spdif_priv->pdev;
310 u32 ch_status;
311
312 ch_status = (bitrev8(ctrl->ch_status[0]) << 16) |
313 (bitrev8(ctrl->ch_status[1]) << 8) |
314 bitrev8(ctrl->ch_status[2]);
315 regmap_write(regmap, REG_SPDIF_STCSCH, ch_status);
316
317 dev_dbg(&pdev->dev, "STCSCH: 0x%06x\n", ch_status);
318
319 ch_status = bitrev8(ctrl->ch_status[3]) << 16;
320 regmap_write(regmap, REG_SPDIF_STCSCL, ch_status);
321
322 dev_dbg(&pdev->dev, "STCSCL: 0x%06x\n", ch_status);
323}
324
325/* Set SPDIF PhaseConfig register for rx clock */
326static int spdif_set_rx_clksrc(struct fsl_spdif_priv *spdif_priv,
327 enum spdif_gainsel gainsel, int dpll_locked)
328{
329 struct regmap *regmap = spdif_priv->regmap;
330 u8 clksrc = spdif_priv->rxclk_src;
331
332 if (clksrc >= SRPC_CLKSRC_MAX || gainsel >= GAINSEL_MULTI_MAX)
333 return -EINVAL;
334
335 regmap_update_bits(regmap, REG_SPDIF_SRPC,
336 SRPC_CLKSRC_SEL_MASK | SRPC_GAINSEL_MASK,
337 SRPC_CLKSRC_SEL_SET(clksrc) | SRPC_GAINSEL_SET(gainsel));
338
339 return 0;
340}
341
342static int spdif_set_sample_rate(struct snd_pcm_substream *substream,
343 int sample_rate)
344{
345 struct snd_soc_pcm_runtime *rtd = substream->private_data;
346 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai);
347 struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
348 struct regmap *regmap = spdif_priv->regmap;
349 struct platform_device *pdev = spdif_priv->pdev;
350 unsigned long csfs = 0;
351 u32 stc, mask, rate;
352 u8 clk, div;
353 int ret;
354
355 switch (sample_rate) {
356 case 32000:
357 rate = SPDIF_TXRATE_32000;
358 csfs = IEC958_AES3_CON_FS_32000;
359 break;
360 case 44100:
361 rate = SPDIF_TXRATE_44100;
362 csfs = IEC958_AES3_CON_FS_44100;
363 break;
364 case 48000:
365 rate = SPDIF_TXRATE_48000;
366 csfs = IEC958_AES3_CON_FS_48000;
367 break;
368 default:
369 dev_err(&pdev->dev, "unsupported sample rate %d\n", sample_rate);
370 return -EINVAL;
371 }
372
373 clk = spdif_priv->txclk_src[rate];
374 if (clk >= STC_TXCLK_SRC_MAX) {
375 dev_err(&pdev->dev, "tx clock source is out of range\n");
376 return -EINVAL;
377 }
378
379 div = spdif_priv->txclk_div[rate];
380 if (div == 0) {
381 dev_err(&pdev->dev, "the divisor can't be zero\n");
382 return -EINVAL;
383 }
384
385 /*
386 * The S/PDIF block needs a clock of 64 * fs * div. The S/PDIF block
387 * will divide by (div). So request 64 * fs * (div+1) which will
388 * get rounded.
389 */
390 ret = clk_set_rate(spdif_priv->txclk[rate], 64 * sample_rate * (div + 1));
391 if (ret) {
392 dev_err(&pdev->dev, "failed to set tx clock rate\n");
393 return ret;
394 }
395
396 dev_dbg(&pdev->dev, "expected clock rate = %d\n",
397 (64 * sample_rate * div));
398 dev_dbg(&pdev->dev, "actual clock rate = %ld\n",
399 clk_get_rate(spdif_priv->txclk[rate]));
400
401 /* set fs field in consumer channel status */
402 spdif_set_cstatus(ctrl, IEC958_AES3_CON_FS, csfs);
403
404 /* select clock source and divisor */
405 stc = STC_TXCLK_ALL_EN | STC_TXCLK_SRC_SET(clk) | STC_TXCLK_DIV(div);
406 mask = STC_TXCLK_ALL_EN_MASK | STC_TXCLK_SRC_MASK | STC_TXCLK_DIV_MASK;
407 regmap_update_bits(regmap, REG_SPDIF_STC, mask, stc);
408
409 dev_dbg(&pdev->dev, "set sample rate to %d\n", sample_rate);
410
411 return 0;
412}
413
414static int fsl_spdif_startup(struct snd_pcm_substream *substream,
415 struct snd_soc_dai *cpu_dai)
416{
417 struct snd_soc_pcm_runtime *rtd = substream->private_data;
418 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai);
419 struct platform_device *pdev = spdif_priv->pdev;
420 struct regmap *regmap = spdif_priv->regmap;
421 u32 scr, mask, i;
422 int ret;
423
424 /* Reset module and interrupts only for first initialization */
425 if (!cpu_dai->active) {
426 ret = spdif_softreset(spdif_priv);
427 if (ret) {
428 dev_err(&pdev->dev, "failed to soft reset\n");
429 return ret;
430 }
431
432 /* Disable all the interrupts */
433 regmap_update_bits(regmap, REG_SPDIF_SIE, 0xffffff, 0);
434 }
435
436 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
437 scr = SCR_TXFIFO_AUTOSYNC | SCR_TXFIFO_CTRL_NORMAL |
438 SCR_TXSEL_NORMAL | SCR_USRC_SEL_CHIP |
439 SCR_TXFIFO_FSEL_IF8;
440 mask = SCR_TXFIFO_AUTOSYNC_MASK | SCR_TXFIFO_CTRL_MASK |
441 SCR_TXSEL_MASK | SCR_USRC_SEL_MASK |
442 SCR_TXFIFO_FSEL_MASK;
443 for (i = 0; i < SPDIF_TXRATE_MAX; i++)
444 clk_prepare_enable(spdif_priv->txclk[i]);
445 } else {
446 scr = SCR_RXFIFO_FSEL_IF8 | SCR_RXFIFO_AUTOSYNC;
447 mask = SCR_RXFIFO_FSEL_MASK | SCR_RXFIFO_AUTOSYNC_MASK|
448 SCR_RXFIFO_CTL_MASK | SCR_RXFIFO_OFF_MASK;
449 clk_prepare_enable(spdif_priv->rxclk);
450 }
451 regmap_update_bits(regmap, REG_SPDIF_SCR, mask, scr);
452
453 /* Power up SPDIF module */
454 regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_LOW_POWER, 0);
455
456 return 0;
457}
458
459static void fsl_spdif_shutdown(struct snd_pcm_substream *substream,
460 struct snd_soc_dai *cpu_dai)
461{
462 struct snd_soc_pcm_runtime *rtd = substream->private_data;
463 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai);
464 struct regmap *regmap = spdif_priv->regmap;
465 u32 scr, mask, i;
466
467 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
468 scr = 0;
469 mask = SCR_TXFIFO_AUTOSYNC_MASK | SCR_TXFIFO_CTRL_MASK |
470 SCR_TXSEL_MASK | SCR_USRC_SEL_MASK |
471 SCR_TXFIFO_FSEL_MASK;
472 for (i = 0; i < SPDIF_TXRATE_MAX; i++)
473 clk_disable_unprepare(spdif_priv->txclk[i]);
474 } else {
475 scr = SCR_RXFIFO_OFF | SCR_RXFIFO_CTL_ZERO;
476 mask = SCR_RXFIFO_FSEL_MASK | SCR_RXFIFO_AUTOSYNC_MASK|
477 SCR_RXFIFO_CTL_MASK | SCR_RXFIFO_OFF_MASK;
478 clk_disable_unprepare(spdif_priv->rxclk);
479 }
480 regmap_update_bits(regmap, REG_SPDIF_SCR, mask, scr);
481
482 /* Power down SPDIF module only if tx&rx are both inactive */
483 if (!cpu_dai->active) {
484 spdif_intr_status_clear(spdif_priv);
485 regmap_update_bits(regmap, REG_SPDIF_SCR,
486 SCR_LOW_POWER, SCR_LOW_POWER);
487 }
488}
489
490static int fsl_spdif_hw_params(struct snd_pcm_substream *substream,
491 struct snd_pcm_hw_params *params,
492 struct snd_soc_dai *dai)
493{
494 struct snd_soc_pcm_runtime *rtd = substream->private_data;
495 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai);
496 struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
497 struct platform_device *pdev = spdif_priv->pdev;
498 u32 sample_rate = params_rate(params);
499 int ret = 0;
500
501 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
502 ret = spdif_set_sample_rate(substream, sample_rate);
503 if (ret) {
504 dev_err(&pdev->dev, "%s: set sample rate failed: %d\n",
505 __func__, sample_rate);
506 return ret;
507 }
508 spdif_set_cstatus(ctrl, IEC958_AES3_CON_CLOCK,
509 IEC958_AES3_CON_CLOCK_1000PPM);
510 spdif_write_channel_status(spdif_priv);
511 } else {
512 /* Setup rx clock source */
513 ret = spdif_set_rx_clksrc(spdif_priv, SPDIF_DEFAULT_GAINSEL, 1);
514 }
515
516 return ret;
517}
518
519static int fsl_spdif_trigger(struct snd_pcm_substream *substream,
520 int cmd, struct snd_soc_dai *dai)
521{
522 struct snd_soc_pcm_runtime *rtd = substream->private_data;
523 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai);
524 struct regmap *regmap = spdif_priv->regmap;
525 int is_playack = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
526 u32 intr = is_playack ? INTR_FOR_PLAYBACK : INTR_FOR_CAPTURE;
527 u32 dmaen = is_playack ? SCR_DMA_TX_EN : SCR_DMA_RX_EN;;
528
529 switch (cmd) {
530 case SNDRV_PCM_TRIGGER_START:
531 case SNDRV_PCM_TRIGGER_RESUME:
532 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
533 regmap_update_bits(regmap, REG_SPDIF_SIE, intr, intr);
534 regmap_update_bits(regmap, REG_SPDIF_SCR, dmaen, dmaen);
535 break;
536 case SNDRV_PCM_TRIGGER_STOP:
537 case SNDRV_PCM_TRIGGER_SUSPEND:
538 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
539 regmap_update_bits(regmap, REG_SPDIF_SCR, dmaen, 0);
540 regmap_update_bits(regmap, REG_SPDIF_SIE, intr, 0);
541 break;
542 default:
543 return -EINVAL;
544 }
545
546 return 0;
547}
548
549static struct snd_soc_dai_ops fsl_spdif_dai_ops = {
550 .startup = fsl_spdif_startup,
551 .hw_params = fsl_spdif_hw_params,
552 .trigger = fsl_spdif_trigger,
553 .shutdown = fsl_spdif_shutdown,
554};
555
556
557/*
558 * FSL SPDIF IEC958 controller(mixer) functions
559 *
560 * Channel status get/put control
561 * User bit value get/put control
562 * Valid bit value get control
563 * DPLL lock status get control
564 * User bit sync mode selection control
565 */
566
567static int fsl_spdif_info(struct snd_kcontrol *kcontrol,
568 struct snd_ctl_elem_info *uinfo)
569{
570 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
571 uinfo->count = 1;
572
573 return 0;
574}
575
576static int fsl_spdif_pb_get(struct snd_kcontrol *kcontrol,
577 struct snd_ctl_elem_value *uvalue)
578{
579 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
580 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
581 struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
582
583 uvalue->value.iec958.status[0] = ctrl->ch_status[0];
584 uvalue->value.iec958.status[1] = ctrl->ch_status[1];
585 uvalue->value.iec958.status[2] = ctrl->ch_status[2];
586 uvalue->value.iec958.status[3] = ctrl->ch_status[3];
587
588 return 0;
589}
590
591static int fsl_spdif_pb_put(struct snd_kcontrol *kcontrol,
592 struct snd_ctl_elem_value *uvalue)
593{
594 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
595 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
596 struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
597
598 ctrl->ch_status[0] = uvalue->value.iec958.status[0];
599 ctrl->ch_status[1] = uvalue->value.iec958.status[1];
600 ctrl->ch_status[2] = uvalue->value.iec958.status[2];
601 ctrl->ch_status[3] = uvalue->value.iec958.status[3];
602
603 spdif_write_channel_status(spdif_priv);
604
605 return 0;
606}
607
608/* Get channel status from SPDIF_RX_CCHAN register */
609static int fsl_spdif_capture_get(struct snd_kcontrol *kcontrol,
610 struct snd_ctl_elem_value *ucontrol)
611{
612 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
613 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
614 struct regmap *regmap = spdif_priv->regmap;
615 u32 cstatus, val;
616
617 regmap_read(regmap, REG_SPDIF_SIS, &val);
618 if (!(val & INT_CNEW)) {
619 return -EAGAIN;
620 }
621
622 regmap_read(regmap, REG_SPDIF_SRCSH, &cstatus);
623 ucontrol->value.iec958.status[0] = (cstatus >> 16) & 0xFF;
624 ucontrol->value.iec958.status[1] = (cstatus >> 8) & 0xFF;
625 ucontrol->value.iec958.status[2] = cstatus & 0xFF;
626
627 regmap_read(regmap, REG_SPDIF_SRCSL, &cstatus);
628 ucontrol->value.iec958.status[3] = (cstatus >> 16) & 0xFF;
629 ucontrol->value.iec958.status[4] = (cstatus >> 8) & 0xFF;
630 ucontrol->value.iec958.status[5] = cstatus & 0xFF;
631
632 /* Clear intr */
633 regmap_write(regmap, REG_SPDIF_SIC, INT_CNEW);
634
635 return 0;
636}
637
638/*
639 * Get User bits (subcode) from chip value which readed out
640 * in UChannel register.
641 */
642static int fsl_spdif_subcode_get(struct snd_kcontrol *kcontrol,
643 struct snd_ctl_elem_value *ucontrol)
644{
645 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
646 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
647 struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
648 unsigned long flags;
649 int ret = 0;
650
651 spin_lock_irqsave(&ctrl->ctl_lock, flags);
652 if (ctrl->ready_buf) {
653 int idx = (ctrl->ready_buf - 1) * SPDIF_UBITS_SIZE;
654 memcpy(&ucontrol->value.iec958.subcode[0],
655 &ctrl->subcode[idx], SPDIF_UBITS_SIZE);
656 } else {
657 ret = -EAGAIN;
658 }
659 spin_unlock_irqrestore(&ctrl->ctl_lock, flags);
660
661 return ret;
662}
663
664/* Q-subcode infomation. The byte size is SPDIF_UBITS_SIZE/8 */
665static int fsl_spdif_qinfo(struct snd_kcontrol *kcontrol,
666 struct snd_ctl_elem_info *uinfo)
667{
668 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
669 uinfo->count = SPDIF_QSUB_SIZE;
670
671 return 0;
672}
673
674/* Get Q subcode from chip value which readed out in QChannel register */
675static int fsl_spdif_qget(struct snd_kcontrol *kcontrol,
676 struct snd_ctl_elem_value *ucontrol)
677{
678 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
679 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
680 struct spdif_mixer_control *ctrl = &spdif_priv->fsl_spdif_control;
681 unsigned long flags;
682 int ret = 0;
683
684 spin_lock_irqsave(&ctrl->ctl_lock, flags);
685 if (ctrl->ready_buf) {
686 int idx = (ctrl->ready_buf - 1) * SPDIF_QSUB_SIZE;
687 memcpy(&ucontrol->value.bytes.data[0],
688 &ctrl->qsub[idx], SPDIF_QSUB_SIZE);
689 } else {
690 ret = -EAGAIN;
691 }
692 spin_unlock_irqrestore(&ctrl->ctl_lock, flags);
693
694 return ret;
695}
696
697/* Valid bit infomation */
698static int fsl_spdif_vbit_info(struct snd_kcontrol *kcontrol,
699 struct snd_ctl_elem_info *uinfo)
700{
701 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
702 uinfo->count = 1;
703 uinfo->value.integer.min = 0;
704 uinfo->value.integer.max = 1;
705
706 return 0;
707}
708
709/* Get valid good bit from interrupt status register */
710static int fsl_spdif_vbit_get(struct snd_kcontrol *kcontrol,
711 struct snd_ctl_elem_value *ucontrol)
712{
713 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
714 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
715 struct regmap *regmap = spdif_priv->regmap;
716 u32 val;
717
718 val = regmap_read(regmap, REG_SPDIF_SIS, &val);
719 ucontrol->value.integer.value[0] = (val & INT_VAL_NOGOOD) != 0;
720 regmap_write(regmap, REG_SPDIF_SIC, INT_VAL_NOGOOD);
721
722 return 0;
723}
724
725/* DPLL lock infomation */
726static int fsl_spdif_rxrate_info(struct snd_kcontrol *kcontrol,
727 struct snd_ctl_elem_info *uinfo)
728{
729 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
730 uinfo->count = 1;
731 uinfo->value.integer.min = 16000;
732 uinfo->value.integer.max = 96000;
733
734 return 0;
735}
736
737static u32 gainsel_multi[GAINSEL_MULTI_MAX] = {
738 24, 16, 12, 8, 6, 4, 3,
739};
740
741/* Get RX data clock rate given the SPDIF bus_clk */
742static int spdif_get_rxclk_rate(struct fsl_spdif_priv *spdif_priv,
743 enum spdif_gainsel gainsel)
744{
745 struct regmap *regmap = spdif_priv->regmap;
746 struct platform_device *pdev = spdif_priv->pdev;
747 u64 tmpval64, busclk_freq = 0;
748 u32 freqmeas, phaseconf;
749 u8 clksrc;
750
751 regmap_read(regmap, REG_SPDIF_SRFM, &freqmeas);
752 regmap_read(regmap, REG_SPDIF_SRPC, &phaseconf);
753
754 clksrc = (phaseconf >> SRPC_CLKSRC_SEL_OFFSET) & 0xf;
755 if (srpc_dpll_locked[clksrc] && (phaseconf & SRPC_DPLL_LOCKED)) {
756 /* Get bus clock from system */
757 busclk_freq = clk_get_rate(spdif_priv->rxclk);
758 }
759
760 /* FreqMeas_CLK = (BUS_CLK * FreqMeas) / 2 ^ 10 / GAINSEL / 128 */
761 tmpval64 = (u64) busclk_freq * freqmeas;
762 do_div(tmpval64, gainsel_multi[gainsel] * 1024);
763 do_div(tmpval64, 128 * 1024);
764
765 dev_dbg(&pdev->dev, "FreqMeas: %d\n", freqmeas);
766 dev_dbg(&pdev->dev, "BusclkFreq: %lld\n", busclk_freq);
767 dev_dbg(&pdev->dev, "RxRate: %lld\n", tmpval64);
768
769 return (int)tmpval64;
770}
771
772/*
773 * Get DPLL lock or not info from stable interrupt status register.
774 * User application must use this control to get locked,
775 * then can do next PCM operation
776 */
777static int fsl_spdif_rxrate_get(struct snd_kcontrol *kcontrol,
778 struct snd_ctl_elem_value *ucontrol)
779{
780 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
781 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
782 int rate = spdif_get_rxclk_rate(spdif_priv, SPDIF_DEFAULT_GAINSEL);
783
784 if (spdif_priv->dpll_locked)
785 ucontrol->value.integer.value[0] = rate;
786 else
787 ucontrol->value.integer.value[0] = 0;
788
789 return 0;
790}
791
792/* User bit sync mode info */
793static int fsl_spdif_usync_info(struct snd_kcontrol *kcontrol,
794 struct snd_ctl_elem_info *uinfo)
795{
796 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
797 uinfo->count = 1;
798 uinfo->value.integer.min = 0;
799 uinfo->value.integer.max = 1;
800
801 return 0;
802}
803
804/*
805 * User bit sync mode:
806 * 1 CD User channel subcode
807 * 0 Non-CD data
808 */
809static int fsl_spdif_usync_get(struct snd_kcontrol *kcontrol,
810 struct snd_ctl_elem_value *ucontrol)
811{
812 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
813 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
814 struct regmap *regmap = spdif_priv->regmap;
815 u32 val;
816
817 regmap_read(regmap, REG_SPDIF_SRCD, &val);
818 ucontrol->value.integer.value[0] = (val & SRCD_CD_USER) != 0;
819
820 return 0;
821}
822
823/*
824 * User bit sync mode:
825 * 1 CD User channel subcode
826 * 0 Non-CD data
827 */
828static int fsl_spdif_usync_put(struct snd_kcontrol *kcontrol,
829 struct snd_ctl_elem_value *ucontrol)
830{
831 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
832 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
833 struct regmap *regmap = spdif_priv->regmap;
834 u32 val = ucontrol->value.integer.value[0] << SRCD_CD_USER_OFFSET;
835
836 regmap_update_bits(regmap, REG_SPDIF_SRCD, SRCD_CD_USER, val);
837
838 return 0;
839}
840
841/* FSL SPDIF IEC958 controller defines */
842static struct snd_kcontrol_new fsl_spdif_ctrls[] = {
843 /* Status cchanel controller */
844 {
845 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
846 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
847 .access = SNDRV_CTL_ELEM_ACCESS_READ |
848 SNDRV_CTL_ELEM_ACCESS_WRITE |
849 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
850 .info = fsl_spdif_info,
851 .get = fsl_spdif_pb_get,
852 .put = fsl_spdif_pb_put,
853 },
854 {
855 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
856 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
857 .access = SNDRV_CTL_ELEM_ACCESS_READ |
858 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
859 .info = fsl_spdif_info,
860 .get = fsl_spdif_capture_get,
861 },
862 /* User bits controller */
863 {
864 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
865 .name = "IEC958 Subcode Capture Default",
866 .access = SNDRV_CTL_ELEM_ACCESS_READ |
867 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
868 .info = fsl_spdif_info,
869 .get = fsl_spdif_subcode_get,
870 },
871 {
872 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
873 .name = "IEC958 Q-subcode Capture Default",
874 .access = SNDRV_CTL_ELEM_ACCESS_READ |
875 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
876 .info = fsl_spdif_qinfo,
877 .get = fsl_spdif_qget,
878 },
879 /* Valid bit error controller */
880 {
881 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
882 .name = "IEC958 V-Bit Errors",
883 .access = SNDRV_CTL_ELEM_ACCESS_READ |
884 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
885 .info = fsl_spdif_vbit_info,
886 .get = fsl_spdif_vbit_get,
887 },
888 /* DPLL lock info get controller */
889 {
890 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
891 .name = "RX Sample Rate",
892 .access = SNDRV_CTL_ELEM_ACCESS_READ |
893 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
894 .info = fsl_spdif_rxrate_info,
895 .get = fsl_spdif_rxrate_get,
896 },
897 /* User bit sync mode set/get controller */
898 {
899 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
900 .name = "IEC958 USyncMode CDText",
901 .access = SNDRV_CTL_ELEM_ACCESS_READ |
902 SNDRV_CTL_ELEM_ACCESS_WRITE |
903 SNDRV_CTL_ELEM_ACCESS_VOLATILE,
904 .info = fsl_spdif_usync_info,
905 .get = fsl_spdif_usync_get,
906 .put = fsl_spdif_usync_put,
907 },
908};
909
910static int fsl_spdif_dai_probe(struct snd_soc_dai *dai)
911{
912 struct fsl_spdif_priv *spdif_private = snd_soc_dai_get_drvdata(dai);
913
914 dai->playback_dma_data = &spdif_private->dma_params_tx;
915 dai->capture_dma_data = &spdif_private->dma_params_rx;
916
917 snd_soc_add_dai_controls(dai, fsl_spdif_ctrls, ARRAY_SIZE(fsl_spdif_ctrls));
918
919 return 0;
920}
921
922static struct snd_soc_dai_driver fsl_spdif_dai = {
923 .probe = &fsl_spdif_dai_probe,
924 .playback = {
925 .channels_min = 2,
926 .channels_max = 2,
927 .rates = FSL_SPDIF_RATES_PLAYBACK,
928 .formats = FSL_SPDIF_FORMATS_PLAYBACK,
929 },
930 .capture = {
931 .channels_min = 2,
932 .channels_max = 2,
933 .rates = FSL_SPDIF_RATES_CAPTURE,
934 .formats = FSL_SPDIF_FORMATS_CAPTURE,
935 },
936 .ops = &fsl_spdif_dai_ops,
937};
938
939static const struct snd_soc_component_driver fsl_spdif_component = {
940 .name = "fsl-spdif",
941};
942
943/* FSL SPDIF REGMAP */
944
945static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg)
946{
947 switch (reg) {
948 case REG_SPDIF_SCR:
949 case REG_SPDIF_SRCD:
950 case REG_SPDIF_SRPC:
951 case REG_SPDIF_SIE:
952 case REG_SPDIF_SIS:
953 case REG_SPDIF_SRL:
954 case REG_SPDIF_SRR:
955 case REG_SPDIF_SRCSH:
956 case REG_SPDIF_SRCSL:
957 case REG_SPDIF_SRU:
958 case REG_SPDIF_SRQ:
959 case REG_SPDIF_STCSCH:
960 case REG_SPDIF_STCSCL:
961 case REG_SPDIF_SRFM:
962 case REG_SPDIF_STC:
963 return true;
964 default:
965 return false;
966 };
967}
968
969static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg)
970{
971 switch (reg) {
972 case REG_SPDIF_SCR:
973 case REG_SPDIF_SRCD:
974 case REG_SPDIF_SRPC:
975 case REG_SPDIF_SIE:
976 case REG_SPDIF_SIC:
977 case REG_SPDIF_STL:
978 case REG_SPDIF_STR:
979 case REG_SPDIF_STCSCH:
980 case REG_SPDIF_STCSCL:
981 case REG_SPDIF_STC:
982 return true;
983 default:
984 return false;
985 };
986}
987
988static const struct regmap_config fsl_spdif_regmap_config = {
989 .reg_bits = 32,
990 .reg_stride = 4,
991 .val_bits = 32,
992
993 .max_register = REG_SPDIF_STC,
994 .readable_reg = fsl_spdif_readable_reg,
995 .writeable_reg = fsl_spdif_writeable_reg,
996};
997
998static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
999 struct clk *clk, u64 savesub,
1000 enum spdif_txrate index)
1001{
1002 const u32 rate[] = { 32000, 44100, 48000 };
1003 u64 rate_ideal, rate_actual, sub;
1004 u32 div, arate;
1005
1006 for (div = 1; div <= 128; div++) {
1007 rate_ideal = rate[index] * (div + 1) * 64;
1008 rate_actual = clk_round_rate(clk, rate_ideal);
1009
1010 arate = rate_actual / 64;
1011 arate /= div;
1012
1013 if (arate == rate[index]) {
1014 /* We are lucky */
1015 savesub = 0;
1016 spdif_priv->txclk_div[index] = div;
1017 break;
1018 } else if (arate / rate[index] == 1) {
1019 /* A little bigger than expect */
1020 sub = (arate - rate[index]) * 100000;
1021 do_div(sub, rate[index]);
1022 if (sub < savesub) {
1023 savesub = sub;
1024 spdif_priv->txclk_div[index] = div;
1025 }
1026 } else if (rate[index] / arate == 1) {
1027 /* A little smaller than expect */
1028 sub = (rate[index] - arate) * 100000;
1029 do_div(sub, rate[index]);
1030 if (sub < savesub) {
1031 savesub = sub;
1032 spdif_priv->txclk_div[index] = div;
1033 }
1034 }
1035 }
1036
1037 return savesub;
1038}
1039
1040static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv,
1041 enum spdif_txrate index)
1042{
1043 const u32 rate[] = { 32000, 44100, 48000 };
1044 struct platform_device *pdev = spdif_priv->pdev;
1045 struct device *dev = &pdev->dev;
1046 u64 savesub = 100000, ret;
1047 struct clk *clk;
1048 char tmp[16];
1049 int i;
1050
1051 for (i = 0; i < STC_TXCLK_SRC_MAX; i++) {
1052 sprintf(tmp, "rxtx%d", i);
1053 clk = devm_clk_get(&pdev->dev, tmp);
1054 if (IS_ERR(clk)) {
1055 dev_err(dev, "no rxtx%d clock in devicetree\n", i);
1056 return PTR_ERR(clk);
1057 }
1058 if (!clk_get_rate(clk))
1059 continue;
1060
1061 ret = fsl_spdif_txclk_caldiv(spdif_priv, clk, savesub, index);
1062 if (savesub == ret)
1063 continue;
1064
1065 savesub = ret;
1066 spdif_priv->txclk[index] = clk;
1067 spdif_priv->txclk_src[index] = i;
1068
1069 /* To quick catch a divisor, we allow a 0.1% deviation */
1070 if (savesub < 100)
1071 break;
1072 }
1073
1074 dev_dbg(&pdev->dev, "use rxtx%d as tx clock source for %dHz sample rate\n",
1075 spdif_priv->txclk_src[index], rate[index]);
1076 dev_dbg(&pdev->dev, "use divisor %d for %dHz sample rate\n",
1077 spdif_priv->txclk_div[index], rate[index]);
1078
1079 return 0;
1080}
1081
1082static int fsl_spdif_probe(struct platform_device *pdev)
1083{
1084 struct device_node *np = pdev->dev.of_node;
1085 struct fsl_spdif_priv *spdif_priv;
1086 struct spdif_mixer_control *ctrl;
1087 struct resource *res;
1088 void __iomem *regs;
1089 int irq, ret, i;
1090
1091 if (!np)
1092 return -ENODEV;
1093
1094 spdif_priv = devm_kzalloc(&pdev->dev,
1095 sizeof(struct fsl_spdif_priv) + strlen(np->name) + 1,
1096 GFP_KERNEL);
1097 if (!spdif_priv)
1098 return -ENOMEM;
1099
1100 strcpy(spdif_priv->name, np->name);
1101
1102 spdif_priv->pdev = pdev;
1103
1104 /* Initialize this copy of the CPU DAI driver structure */
1105 memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai));
1106 spdif_priv->cpu_dai_drv.name = spdif_priv->name;
1107
1108 /* Get the addresses and IRQ */
1109 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1110 if (IS_ERR(res)) {
1111 dev_err(&pdev->dev, "could not determine device resources\n");
1112 return PTR_ERR(res);
1113 }
1114
1115 regs = devm_ioremap_resource(&pdev->dev, res);
1116 if (IS_ERR(regs))
1117 return PTR_ERR(regs);
1118
1119 spdif_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
1120 "core", regs, &fsl_spdif_regmap_config);
1121 if (IS_ERR(spdif_priv->regmap)) {
1122 dev_err(&pdev->dev, "regmap init failed\n");
1123 return PTR_ERR(spdif_priv->regmap);
1124 }
1125
1126 irq = platform_get_irq(pdev, 0);
1127 if (irq < 0) {
1128 dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
1129 return irq;
1130 }
1131
1132 ret = devm_request_irq(&pdev->dev, irq, spdif_isr, 0,
1133 spdif_priv->name, spdif_priv);
1134 if (ret) {
1135 dev_err(&pdev->dev, "could not claim irq %u\n", irq);
1136 return ret;
1137 }
1138
1139 /* Select clock source for rx/tx clock */
1140 spdif_priv->rxclk = devm_clk_get(&pdev->dev, "rxtx1");
1141 if (IS_ERR(spdif_priv->rxclk)) {
1142 dev_err(&pdev->dev, "no rxtx1 clock in devicetree\n");
1143 return PTR_ERR(spdif_priv->rxclk);
1144 }
1145 spdif_priv->rxclk_src = DEFAULT_RXCLK_SRC;
1146
1147 for (i = 0; i < SPDIF_TXRATE_MAX; i++) {
1148 ret = fsl_spdif_probe_txclk(spdif_priv, i);
1149 if (ret)
1150 return ret;
1151 }
1152
1153 /* Initial spinlock for control data */
1154 ctrl = &spdif_priv->fsl_spdif_control;
1155 spin_lock_init(&ctrl->ctl_lock);
1156
1157 /* Init tx channel status default value */
1158 ctrl->ch_status[0] =
1159 IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_5015;
1160 ctrl->ch_status[1] = IEC958_AES1_CON_DIGDIGCONV_ID;
1161 ctrl->ch_status[2] = 0x00;
1162 ctrl->ch_status[3] =
1163 IEC958_AES3_CON_FS_44100 | IEC958_AES3_CON_CLOCK_1000PPM;
1164
1165 spdif_priv->dpll_locked = false;
1166
1167 spdif_priv->dma_params_tx.maxburst = FSL_SPDIF_TXFIFO_WML;
1168 spdif_priv->dma_params_rx.maxburst = FSL_SPDIF_RXFIFO_WML;
1169 spdif_priv->dma_params_tx.addr = res->start + REG_SPDIF_STL;
1170 spdif_priv->dma_params_rx.addr = res->start + REG_SPDIF_SRL;
1171
1172 /* Register with ASoC */
1173 dev_set_drvdata(&pdev->dev, spdif_priv);
1174
1175 ret = snd_soc_register_component(&pdev->dev, &fsl_spdif_component,
1176 &spdif_priv->cpu_dai_drv, 1);
1177 if (ret) {
1178 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
1179 return ret;
1180 }
1181
1182 ret = imx_pcm_dma_init(pdev);
1183 if (ret) {
1184 dev_err(&pdev->dev, "imx_pcm_dma_init failed: %d\n", ret);
1185 goto error_component;
1186 }
1187
1188 return ret;
1189
1190error_component:
1191 snd_soc_unregister_component(&pdev->dev);
1192
1193 return ret;
1194}
1195
1196static int fsl_spdif_remove(struct platform_device *pdev)
1197{
1198 imx_pcm_dma_exit(pdev);
1199 snd_soc_unregister_component(&pdev->dev);
1200
1201 return 0;
1202}
1203
1204static const struct of_device_id fsl_spdif_dt_ids[] = {
1205 { .compatible = "fsl,imx35-spdif", },
1206 {}
1207};
1208MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids);
1209
1210static struct platform_driver fsl_spdif_driver = {
1211 .driver = {
1212 .name = "fsl-spdif-dai",
1213 .owner = THIS_MODULE,
1214 .of_match_table = fsl_spdif_dt_ids,
1215 },
1216 .probe = fsl_spdif_probe,
1217 .remove = fsl_spdif_remove,
1218};
1219
1220module_platform_driver(fsl_spdif_driver);
1221
1222MODULE_AUTHOR("Freescale Semiconductor, Inc.");
1223MODULE_DESCRIPTION("Freescale S/PDIF CPU DAI Driver");
1224MODULE_LICENSE("GPL v2");
1225MODULE_ALIAS("platform:fsl-spdif-dai");
diff --git a/sound/soc/fsl/fsl_spdif.h b/sound/soc/fsl/fsl_spdif.h
new file mode 100644
index 000000000000..b1266790d117
--- /dev/null
+++ b/sound/soc/fsl/fsl_spdif.h
@@ -0,0 +1,191 @@
1/*
2 * fsl_spdif.h - ALSA S/PDIF interface for the Freescale i.MX SoC
3 *
4 * Copyright (C) 2013 Freescale Semiconductor, Inc.
5 *
6 * Author: Nicolin Chen <b42378@freescale.com>
7 *
8 * Based on fsl_ssi.h
9 * Author: Timur Tabi <timur@freescale.com>
10 * Copyright 2007-2008 Freescale Semiconductor, Inc.
11 *
12 * This file is licensed under the terms of the GNU General Public License
13 * version 2. This program is licensed "as is" without any warranty of any
14 * kind, whether express or implied.
15 */
16
17#ifndef _FSL_SPDIF_DAI_H
18#define _FSL_SPDIF_DAI_H
19
20/* S/PDIF Register Map */
21#define REG_SPDIF_SCR 0x0 /* SPDIF Configuration Register */
22#define REG_SPDIF_SRCD 0x4 /* CDText Control Register */
23#define REG_SPDIF_SRPC 0x8 /* PhaseConfig Register */
24#define REG_SPDIF_SIE 0xc /* InterruptEn Register */
25#define REG_SPDIF_SIS 0x10 /* InterruptStat Register */
26#define REG_SPDIF_SIC 0x10 /* InterruptClear Register */
27#define REG_SPDIF_SRL 0x14 /* SPDIFRxLeft Register */
28#define REG_SPDIF_SRR 0x18 /* SPDIFRxRight Register */
29#define REG_SPDIF_SRCSH 0x1c /* SPDIFRxCChannel_h Register */
30#define REG_SPDIF_SRCSL 0x20 /* SPDIFRxCChannel_l Register */
31#define REG_SPDIF_SRU 0x24 /* UchannelRx Register */
32#define REG_SPDIF_SRQ 0x28 /* QchannelRx Register */
33#define REG_SPDIF_STL 0x2C /* SPDIFTxLeft Register */
34#define REG_SPDIF_STR 0x30 /* SPDIFTxRight Register */
35#define REG_SPDIF_STCSCH 0x34 /* SPDIFTxCChannelCons_h Register */
36#define REG_SPDIF_STCSCL 0x38 /* SPDIFTxCChannelCons_l Register */
37#define REG_SPDIF_SRFM 0x44 /* FreqMeas Register */
38#define REG_SPDIF_STC 0x50 /* SPDIFTxClk Register */
39
40
41/* SPDIF Configuration register */
42#define SCR_RXFIFO_CTL_OFFSET 23
43#define SCR_RXFIFO_CTL_MASK (1 << SCR_RXFIFO_CTL_OFFSET)
44#define SCR_RXFIFO_CTL_ZERO (1 << SCR_RXFIFO_CTL_OFFSET)
45#define SCR_RXFIFO_OFF_OFFSET 22
46#define SCR_RXFIFO_OFF_MASK (1 << SCR_RXFIFO_OFF_OFFSET)
47#define SCR_RXFIFO_OFF (1 << SCR_RXFIFO_OFF_OFFSET)
48#define SCR_RXFIFO_RST_OFFSET 21
49#define SCR_RXFIFO_RST_MASK (1 << SCR_RXFIFO_RST_OFFSET)
50#define SCR_RXFIFO_RST (1 << SCR_RXFIFO_RST_OFFSET)
51#define SCR_RXFIFO_FSEL_OFFSET 19
52#define SCR_RXFIFO_FSEL_MASK (0x3 << SCR_RXFIFO_FSEL_OFFSET)
53#define SCR_RXFIFO_FSEL_IF0 (0x0 << SCR_RXFIFO_FSEL_OFFSET)
54#define SCR_RXFIFO_FSEL_IF4 (0x1 << SCR_RXFIFO_FSEL_OFFSET)
55#define SCR_RXFIFO_FSEL_IF8 (0x2 << SCR_RXFIFO_FSEL_OFFSET)
56#define SCR_RXFIFO_FSEL_IF12 (0x3 << SCR_RXFIFO_FSEL_OFFSET)
57#define SCR_RXFIFO_AUTOSYNC_OFFSET 18
58#define SCR_RXFIFO_AUTOSYNC_MASK (1 << SCR_RXFIFO_AUTOSYNC_OFFSET)
59#define SCR_RXFIFO_AUTOSYNC (1 << SCR_RXFIFO_AUTOSYNC_OFFSET)
60#define SCR_TXFIFO_AUTOSYNC_OFFSET 17
61#define SCR_TXFIFO_AUTOSYNC_MASK (1 << SCR_TXFIFO_AUTOSYNC_OFFSET)
62#define SCR_TXFIFO_AUTOSYNC (1 << SCR_TXFIFO_AUTOSYNC_OFFSET)
63#define SCR_TXFIFO_FSEL_OFFSET 15
64#define SCR_TXFIFO_FSEL_MASK (0x3 << SCR_TXFIFO_FSEL_OFFSET)
65#define SCR_TXFIFO_FSEL_IF0 (0x0 << SCR_TXFIFO_FSEL_OFFSET)
66#define SCR_TXFIFO_FSEL_IF4 (0x1 << SCR_TXFIFO_FSEL_OFFSET)
67#define SCR_TXFIFO_FSEL_IF8 (0x2 << SCR_TXFIFO_FSEL_OFFSET)
68#define SCR_TXFIFO_FSEL_IF12 (0x3 << SCR_TXFIFO_FSEL_OFFSET)
69#define SCR_LOW_POWER (1 << 13)
70#define SCR_SOFT_RESET (1 << 12)
71#define SCR_TXFIFO_CTRL_OFFSET 10
72#define SCR_TXFIFO_CTRL_MASK (0x3 << SCR_TXFIFO_CTRL_OFFSET)
73#define SCR_TXFIFO_CTRL_ZERO (0x0 << SCR_TXFIFO_CTRL_OFFSET)
74#define SCR_TXFIFO_CTRL_NORMAL (0x1 << SCR_TXFIFO_CTRL_OFFSET)
75#define SCR_TXFIFO_CTRL_ONESAMPLE (0x2 << SCR_TXFIFO_CTRL_OFFSET)
76#define SCR_DMA_RX_EN_OFFSET 9
77#define SCR_DMA_RX_EN_MASK (1 << SCR_DMA_RX_EN_OFFSET)
78#define SCR_DMA_RX_EN (1 << SCR_DMA_RX_EN_OFFSET)
79#define SCR_DMA_TX_EN_OFFSET 8
80#define SCR_DMA_TX_EN_MASK (1 << SCR_DMA_TX_EN_OFFSET)
81#define SCR_DMA_TX_EN (1 << SCR_DMA_TX_EN_OFFSET)
82#define SCR_VAL_OFFSET 5
83#define SCR_VAL_MASK (1 << SCR_VAL_OFFSET)
84#define SCR_VAL_CLEAR (1 << SCR_VAL_OFFSET)
85#define SCR_TXSEL_OFFSET 2
86#define SCR_TXSEL_MASK (0x7 << SCR_TXSEL_OFFSET)
87#define SCR_TXSEL_OFF (0 << SCR_TXSEL_OFFSET)
88#define SCR_TXSEL_RX (1 << SCR_TXSEL_OFFSET)
89#define SCR_TXSEL_NORMAL (0x5 << SCR_TXSEL_OFFSET)
90#define SCR_USRC_SEL_OFFSET 0x0
91#define SCR_USRC_SEL_MASK (0x3 << SCR_USRC_SEL_OFFSET)
92#define SCR_USRC_SEL_NONE (0x0 << SCR_USRC_SEL_OFFSET)
93#define SCR_USRC_SEL_RECV (0x1 << SCR_USRC_SEL_OFFSET)
94#define SCR_USRC_SEL_CHIP (0x3 << SCR_USRC_SEL_OFFSET)
95
96/* SPDIF CDText control */
97#define SRCD_CD_USER_OFFSET 1
98#define SRCD_CD_USER (1 << SRCD_CD_USER_OFFSET)
99
100/* SPDIF Phase Configuration register */
101#define SRPC_DPLL_LOCKED (1 << 6)
102#define SRPC_CLKSRC_SEL_OFFSET 7
103#define SRPC_CLKSRC_SEL_MASK (0xf << SRPC_CLKSRC_SEL_OFFSET)
104#define SRPC_CLKSRC_SEL_SET(x) ((x << SRPC_CLKSRC_SEL_OFFSET) & SRPC_CLKSRC_SEL_MASK)
105#define SRPC_CLKSRC_SEL_LOCKED_OFFSET1 5
106#define SRPC_CLKSRC_SEL_LOCKED_OFFSET2 2
107#define SRPC_GAINSEL_OFFSET 3
108#define SRPC_GAINSEL_MASK (0x7 << SRPC_GAINSEL_OFFSET)
109#define SRPC_GAINSEL_SET(x) ((x << SRPC_GAINSEL_OFFSET) & SRPC_GAINSEL_MASK)
110
111#define SRPC_CLKSRC_MAX 16
112
113enum spdif_gainsel {
114 GAINSEL_MULTI_24 = 0,
115 GAINSEL_MULTI_16,
116 GAINSEL_MULTI_12,
117 GAINSEL_MULTI_8,
118 GAINSEL_MULTI_6,
119 GAINSEL_MULTI_4,
120 GAINSEL_MULTI_3,
121};
122#define GAINSEL_MULTI_MAX (GAINSEL_MULTI_3 + 1)
123#define SPDIF_DEFAULT_GAINSEL GAINSEL_MULTI_8
124
125/* SPDIF interrupt mask define */
126#define INT_DPLL_LOCKED (1 << 20)
127#define INT_TXFIFO_UNOV (1 << 19)
128#define INT_TXFIFO_RESYNC (1 << 18)
129#define INT_CNEW (1 << 17)
130#define INT_VAL_NOGOOD (1 << 16)
131#define INT_SYM_ERR (1 << 15)
132#define INT_BIT_ERR (1 << 14)
133#define INT_URX_FUL (1 << 10)
134#define INT_URX_OV (1 << 9)
135#define INT_QRX_FUL (1 << 8)
136#define INT_QRX_OV (1 << 7)
137#define INT_UQ_SYNC (1 << 6)
138#define INT_UQ_ERR (1 << 5)
139#define INT_RXFIFO_UNOV (1 << 4)
140#define INT_RXFIFO_RESYNC (1 << 3)
141#define INT_LOSS_LOCK (1 << 2)
142#define INT_TX_EM (1 << 1)
143#define INT_RXFIFO_FUL (1 << 0)
144
145/* SPDIF Clock register */
146#define STC_SYSCLK_DIV_OFFSET 11
147#define STC_SYSCLK_DIV_MASK (0x1ff << STC_TXCLK_SRC_OFFSET)
148#define STC_SYSCLK_DIV(x) ((((x) - 1) << STC_TXCLK_DIV_OFFSET) & STC_SYSCLK_DIV_MASK)
149#define STC_TXCLK_SRC_OFFSET 8
150#define STC_TXCLK_SRC_MASK (0x7 << STC_TXCLK_SRC_OFFSET)
151#define STC_TXCLK_SRC_SET(x) ((x << STC_TXCLK_SRC_OFFSET) & STC_TXCLK_SRC_MASK)
152#define STC_TXCLK_ALL_EN_OFFSET 7
153#define STC_TXCLK_ALL_EN_MASK (1 << STC_TXCLK_ALL_EN_OFFSET)
154#define STC_TXCLK_ALL_EN (1 << STC_TXCLK_ALL_EN_OFFSET)
155#define STC_TXCLK_DIV_OFFSET 0
156#define STC_TXCLK_DIV_MASK (0x7ff << STC_TXCLK_DIV_OFFSET)
157#define STC_TXCLK_DIV(x) ((((x) - 1) << STC_TXCLK_DIV_OFFSET) & STC_TXCLK_DIV_MASK)
158#define STC_TXCLK_SRC_MAX 8
159
160/* SPDIF tx rate */
161enum spdif_txrate {
162 SPDIF_TXRATE_32000 = 0,
163 SPDIF_TXRATE_44100,
164 SPDIF_TXRATE_48000,
165};
166#define SPDIF_TXRATE_MAX (SPDIF_TXRATE_48000 + 1)
167
168
169#define SPDIF_CSTATUS_BYTE 6
170#define SPDIF_UBITS_SIZE 96
171#define SPDIF_QSUB_SIZE (SPDIF_UBITS_SIZE / 8)
172
173
174#define FSL_SPDIF_RATES_PLAYBACK (SNDRV_PCM_RATE_32000 | \
175 SNDRV_PCM_RATE_44100 | \
176 SNDRV_PCM_RATE_48000)
177
178#define FSL_SPDIF_RATES_CAPTURE (SNDRV_PCM_RATE_16000 | \
179 SNDRV_PCM_RATE_32000 | \
180 SNDRV_PCM_RATE_44100 | \
181 SNDRV_PCM_RATE_48000 | \
182 SNDRV_PCM_RATE_64000 | \
183 SNDRV_PCM_RATE_96000)
184
185#define FSL_SPDIF_FORMATS_PLAYBACK (SNDRV_PCM_FMTBIT_S16_LE | \
186 SNDRV_PCM_FMTBIT_S20_3LE | \
187 SNDRV_PCM_FMTBIT_S24_LE)
188
189#define FSL_SPDIF_FORMATS_CAPTURE (SNDRV_PCM_FMTBIT_S24_LE)
190
191#endif /* _FSL_SPDIF_DAI_H */
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 2f2d837df07f..c6b743978d5e 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -8,6 +8,26 @@
8 * This file is licensed under the terms of the GNU General Public License 8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any 9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied. 10 * kind, whether express or implied.
11 *
12 *
13 * Some notes why imx-pcm-fiq is used instead of DMA on some boards:
14 *
15 * The i.MX SSI core has some nasty limitations in AC97 mode. While most
16 * sane processor vendors have a FIFO per AC97 slot, the i.MX has only
17 * one FIFO which combines all valid receive slots. We cannot even select
18 * which slots we want to receive. The WM9712 with which this driver
19 * was developed with always sends GPIO status data in slot 12 which
20 * we receive in our (PCM-) data stream. The only chance we have is to
21 * manually skip this data in the FIQ handler. With sampling rates different
22 * from 48000Hz not every frame has valid receive data, so the ratio
23 * between pcm data and GPIO status data changes. Our FIQ handler is not
24 * able to handle this, hence this driver only works with 48000Hz sampling
25 * rate.
26 * Reading and writing AC97 registers is another challenge. The core
27 * provides us status bits when the read register is updated with *another*
28 * value. When we read the same register two times (and the register still
29 * contains the same value) these status bits are not set. We work
30 * around this by not polling these bits but only wait a fixed delay.
11 */ 31 */
12 32
13#include <linux/init.h> 33#include <linux/init.h>
@@ -36,7 +56,7 @@
36#define read_ssi(addr) in_be32(addr) 56#define read_ssi(addr) in_be32(addr)
37#define write_ssi(val, addr) out_be32(addr, val) 57#define write_ssi(val, addr) out_be32(addr, val)
38#define write_ssi_mask(addr, clear, set) clrsetbits_be32(addr, clear, set) 58#define write_ssi_mask(addr, clear, set) clrsetbits_be32(addr, clear, set)
39#elif defined ARM 59#else
40#define read_ssi(addr) readl(addr) 60#define read_ssi(addr) readl(addr)
41#define write_ssi(val, addr) writel(val, addr) 61#define write_ssi(val, addr) writel(val, addr)
42/* 62/*
@@ -121,11 +141,14 @@ struct fsl_ssi_private {
121 141
122 bool new_binding; 142 bool new_binding;
123 bool ssi_on_imx; 143 bool ssi_on_imx;
144 bool imx_ac97;
145 bool use_dma;
124 struct clk *clk; 146 struct clk *clk;
125 struct snd_dmaengine_dai_dma_data dma_params_tx; 147 struct snd_dmaengine_dai_dma_data dma_params_tx;
126 struct snd_dmaengine_dai_dma_data dma_params_rx; 148 struct snd_dmaengine_dai_dma_data dma_params_rx;
127 struct imx_dma_data filter_data_tx; 149 struct imx_dma_data filter_data_tx;
128 struct imx_dma_data filter_data_rx; 150 struct imx_dma_data filter_data_rx;
151 struct imx_pcm_fiq_params fiq_params;
129 152
130 struct { 153 struct {
131 unsigned int rfrc; 154 unsigned int rfrc;
@@ -298,6 +321,102 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
298 return ret; 321 return ret;
299} 322}
300 323
324static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
325{
326 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
327 u8 i2s_mode;
328 u8 wm;
329 int synchronous = ssi_private->cpu_dai_drv.symmetric_rates;
330
331 if (ssi_private->imx_ac97)
332 i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET;
333 else
334 i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE;
335
336 /*
337 * Section 16.5 of the MPC8610 reference manual says that the SSI needs
338 * to be disabled before updating the registers we set here.
339 */
340 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
341
342 /*
343 * Program the SSI into I2S Slave Non-Network Synchronous mode. Also
344 * enable the transmit and receive FIFO.
345 *
346 * FIXME: Little-endian samples require a different shift dir
347 */
348 write_ssi_mask(&ssi->scr,
349 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
350 CCSR_SSI_SCR_TFR_CLK_DIS |
351 i2s_mode |
352 (synchronous ? CCSR_SSI_SCR_SYN : 0));
353
354 write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
355 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
356 CCSR_SSI_STCR_TSCKP, &ssi->stcr);
357
358 write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
359 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
360 CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
361 /*
362 * The DC and PM bits are only used if the SSI is the clock master.
363 */
364
365 /*
366 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We don't
367 * use FIFO 1. We program the transmit water to signal a DMA transfer
368 * if there are only two (or fewer) elements left in the FIFO. Two
369 * elements equals one frame (left channel, right channel). This value,
370 * however, depends on the depth of the transmit buffer.
371 *
372 * We set the watermark on the same level as the DMA burstsize. For
373 * fiq it is probably better to use the biggest possible watermark
374 * size.
375 */
376 if (ssi_private->use_dma)
377 wm = ssi_private->fifo_depth - 2;
378 else
379 wm = ssi_private->fifo_depth;
380
381 write_ssi(CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) |
382 CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm),
383 &ssi->sfcsr);
384
385 /*
386 * For ac97 interrupts are enabled with the startup of the substream
387 * because it is also running without an active substream. Normally SSI
388 * is only enabled when there is a substream.
389 */
390 if (ssi_private->imx_ac97) {
391 /*
392 * Setup the clock control register
393 */
394 write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13),
395 &ssi->stccr);
396 write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13),
397 &ssi->srccr);
398
399 /*
400 * Enable AC97 mode and startup the SSI
401 */
402 write_ssi(CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV,
403 &ssi->sacnt);
404 write_ssi(0xff, &ssi->saccdis);
405 write_ssi(0x300, &ssi->saccen);
406
407 /*
408 * Enable SSI, Transmit and Receive
409 */
410 write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN |
411 CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE);
412
413 write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor);
414 }
415
416 return 0;
417}
418
419
301/** 420/**
302 * fsl_ssi_startup: create a new substream 421 * fsl_ssi_startup: create a new substream
303 * 422 *
@@ -319,70 +438,14 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
319 * and initialize the SSI registers. 438 * and initialize the SSI registers.
320 */ 439 */
321 if (!ssi_private->first_stream) { 440 if (!ssi_private->first_stream) {
322 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
323
324 ssi_private->first_stream = substream; 441 ssi_private->first_stream = substream;
325 442
326 /* 443 /*
327 * Section 16.5 of the MPC8610 reference manual says that the 444 * fsl_ssi_setup was already called by ac97_init earlier if
328 * SSI needs to be disabled before updating the registers we set 445 * the driver is in ac97 mode.
329 * here.
330 */
331 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
332
333 /*
334 * Program the SSI into I2S Slave Non-Network Synchronous mode.
335 * Also enable the transmit and receive FIFO.
336 *
337 * FIXME: Little-endian samples require a different shift dir
338 */
339 write_ssi_mask(&ssi->scr,
340 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
341 CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE
342 | (synchronous ? CCSR_SSI_SCR_SYN : 0));
343
344 write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
345 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
346 CCSR_SSI_STCR_TSCKP, &ssi->stcr);
347
348 write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
349 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
350 CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
351
352 /*
353 * The DC and PM bits are only used if the SSI is the clock
354 * master.
355 */
356
357 /* Enable the interrupts and DMA requests */
358 write_ssi(SIER_FLAGS, &ssi->sier);
359
360 /*
361 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
362 * don't use FIFO 1. We program the transmit water to signal a
363 * DMA transfer if there are only two (or fewer) elements left
364 * in the FIFO. Two elements equals one frame (left channel,
365 * right channel). This value, however, depends on the depth of
366 * the transmit buffer.
367 *
368 * We program the receive FIFO to notify us if at least two
369 * elements (one frame) have been written to the FIFO. We could
370 * make this value larger (and maybe we should), but this way
371 * data will be written to memory as soon as it's available.
372 */
373 write_ssi(CCSR_SSI_SFCSR_TFWM0(ssi_private->fifo_depth - 2) |
374 CCSR_SSI_SFCSR_RFWM0(ssi_private->fifo_depth - 2),
375 &ssi->sfcsr);
376
377 /*
378 * We keep the SSI disabled because if we enable it, then the
379 * DMA controller will start. It's not supposed to start until
380 * the SCR.TE (or SCR.RE) bit is set, but it does anyway. The
381 * DMA controller will transfer one "BWC" of data (i.e. the
382 * amount of data that the MR.BWC bits are set to). The reason
383 * this is bad is because at this point, the PCM driver has not
384 * finished initializing the DMA controller.
385 */ 446 */
447 if (!ssi_private->imx_ac97)
448 fsl_ssi_setup(ssi_private);
386 } else { 449 } else {
387 if (synchronous) { 450 if (synchronous) {
388 struct snd_pcm_runtime *first_runtime = 451 struct snd_pcm_runtime *first_runtime =
@@ -492,6 +555,27 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
492 struct snd_soc_pcm_runtime *rtd = substream->private_data; 555 struct snd_soc_pcm_runtime *rtd = substream->private_data;
493 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); 556 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
494 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 557 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
558 unsigned int sier_bits;
559
560 /*
561 * Enable only the interrupts and DMA requests
562 * that are needed for the channel. As the fiq
563 * is polling for this bits, we have to ensure
564 * that this are aligned with the preallocated
565 * buffers
566 */
567
568 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
569 if (ssi_private->use_dma)
570 sier_bits = SIER_FLAGS;
571 else
572 sier_bits = CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN;
573 } else {
574 if (ssi_private->use_dma)
575 sier_bits = SIER_FLAGS;
576 else
577 sier_bits = CCSR_SSI_SIER_RIE | CCSR_SSI_SIER_RFF0_EN;
578 }
495 579
496 switch (cmd) { 580 switch (cmd) {
497 case SNDRV_PCM_TRIGGER_START: 581 case SNDRV_PCM_TRIGGER_START:
@@ -510,12 +594,18 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
510 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TE, 0); 594 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TE, 0);
511 else 595 else
512 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_RE, 0); 596 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_RE, 0);
597
598 if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) &
599 (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0)
600 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
513 break; 601 break;
514 602
515 default: 603 default:
516 return -EINVAL; 604 return -EINVAL;
517 } 605 }
518 606
607 write_ssi(sier_bits, &ssi->sier);
608
519 return 0; 609 return 0;
520} 610}
521 611
@@ -534,22 +624,13 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
534 ssi_private->first_stream = ssi_private->second_stream; 624 ssi_private->first_stream = ssi_private->second_stream;
535 625
536 ssi_private->second_stream = NULL; 626 ssi_private->second_stream = NULL;
537
538 /*
539 * If this is the last active substream, disable the SSI.
540 */
541 if (!ssi_private->first_stream) {
542 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
543
544 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
545 }
546} 627}
547 628
548static int fsl_ssi_dai_probe(struct snd_soc_dai *dai) 629static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
549{ 630{
550 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai); 631 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai);
551 632
552 if (ssi_private->ssi_on_imx) { 633 if (ssi_private->ssi_on_imx && ssi_private->use_dma) {
553 dai->playback_dma_data = &ssi_private->dma_params_tx; 634 dai->playback_dma_data = &ssi_private->dma_params_tx;
554 dai->capture_dma_data = &ssi_private->dma_params_rx; 635 dai->capture_dma_data = &ssi_private->dma_params_rx;
555 } 636 }
@@ -587,6 +668,133 @@ static const struct snd_soc_component_driver fsl_ssi_component = {
587 .name = "fsl-ssi", 668 .name = "fsl-ssi",
588}; 669};
589 670
671/**
672 * fsl_ssi_ac97_trigger: start and stop the AC97 receive/transmit.
673 *
674 * This function is called by ALSA to start, stop, pause, and resume the
675 * transfer of data.
676 */
677static int fsl_ssi_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
678 struct snd_soc_dai *dai)
679{
680 struct snd_soc_pcm_runtime *rtd = substream->private_data;
681 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(
682 rtd->cpu_dai);
683 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
684
685 switch (cmd) {
686 case SNDRV_PCM_TRIGGER_START:
687 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
688 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
689 write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_TIE |
690 CCSR_SSI_SIER_TFE0_EN);
691 else
692 write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_RIE |
693 CCSR_SSI_SIER_RFF0_EN);
694 break;
695
696 case SNDRV_PCM_TRIGGER_STOP:
697 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
698 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
699 write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_TIE |
700 CCSR_SSI_SIER_TFE0_EN, 0);
701 else
702 write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_RIE |
703 CCSR_SSI_SIER_RFF0_EN, 0);
704 break;
705
706 default:
707 return -EINVAL;
708 }
709
710 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
711 write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor);
712 else
713 write_ssi(CCSR_SSI_SOR_RX_CLR, &ssi->sor);
714
715 return 0;
716}
717
718static const struct snd_soc_dai_ops fsl_ssi_ac97_dai_ops = {
719 .startup = fsl_ssi_startup,
720 .shutdown = fsl_ssi_shutdown,
721 .trigger = fsl_ssi_ac97_trigger,
722};
723
724static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
725 .ac97_control = 1,
726 .playback = {
727 .stream_name = "AC97 Playback",
728 .channels_min = 2,
729 .channels_max = 2,
730 .rates = SNDRV_PCM_RATE_8000_48000,
731 .formats = SNDRV_PCM_FMTBIT_S16_LE,
732 },
733 .capture = {
734 .stream_name = "AC97 Capture",
735 .channels_min = 2,
736 .channels_max = 2,
737 .rates = SNDRV_PCM_RATE_48000,
738 .formats = SNDRV_PCM_FMTBIT_S16_LE,
739 },
740 .ops = &fsl_ssi_ac97_dai_ops,
741};
742
743
744static struct fsl_ssi_private *fsl_ac97_data;
745
746static void fsl_ssi_ac97_init(void)
747{
748 fsl_ssi_setup(fsl_ac97_data);
749}
750
751void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
752 unsigned short val)
753{
754 struct ccsr_ssi *ssi = fsl_ac97_data->ssi;
755 unsigned int lreg;
756 unsigned int lval;
757
758 if (reg > 0x7f)
759 return;
760
761
762 lreg = reg << 12;
763 write_ssi(lreg, &ssi->sacadd);
764
765 lval = val << 4;
766 write_ssi(lval , &ssi->sacdat);
767
768 write_ssi_mask(&ssi->sacnt, CCSR_SSI_SACNT_RDWR_MASK,
769 CCSR_SSI_SACNT_WR);
770 udelay(100);
771}
772
773unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97,
774 unsigned short reg)
775{
776 struct ccsr_ssi *ssi = fsl_ac97_data->ssi;
777
778 unsigned short val = -1;
779 unsigned int lreg;
780
781 lreg = (reg & 0x7f) << 12;
782 write_ssi(lreg, &ssi->sacadd);
783 write_ssi_mask(&ssi->sacnt, CCSR_SSI_SACNT_RDWR_MASK,
784 CCSR_SSI_SACNT_RD);
785
786 udelay(100);
787
788 val = (read_ssi(&ssi->sacdat) >> 4) & 0xffff;
789
790 return val;
791}
792
793static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = {
794 .read = fsl_ssi_ac97_read,
795 .write = fsl_ssi_ac97_write,
796};
797
590/* Show the statistics of a flag only if its interrupt is enabled. The 798/* Show the statistics of a flag only if its interrupt is enabled. The
591 * compiler will optimze this code to a no-op if the interrupt is not 799 * compiler will optimze this code to a no-op if the interrupt is not
592 * enabled. 800 * enabled.
@@ -663,6 +871,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
663 struct resource res; 871 struct resource res;
664 char name[64]; 872 char name[64];
665 bool shared; 873 bool shared;
874 bool ac97 = false;
666 875
667 /* SSIs that are not connected on the board should have a 876 /* SSIs that are not connected on the board should have a
668 * status = "disabled" 877 * status = "disabled"
@@ -673,14 +882,20 @@ static int fsl_ssi_probe(struct platform_device *pdev)
673 882
674 /* We only support the SSI in "I2S Slave" mode */ 883 /* We only support the SSI in "I2S Slave" mode */
675 sprop = of_get_property(np, "fsl,mode", NULL); 884 sprop = of_get_property(np, "fsl,mode", NULL);
676 if (!sprop || strcmp(sprop, "i2s-slave")) { 885 if (!sprop) {
886 dev_err(&pdev->dev, "fsl,mode property is necessary\n");
887 return -EINVAL;
888 }
889 if (!strcmp(sprop, "ac97-slave")) {
890 ac97 = true;
891 } else if (strcmp(sprop, "i2s-slave")) {
677 dev_notice(&pdev->dev, "mode %s is unsupported\n", sprop); 892 dev_notice(&pdev->dev, "mode %s is unsupported\n", sprop);
678 return -ENODEV; 893 return -ENODEV;
679 } 894 }
680 895
681 /* The DAI name is the last part of the full name of the node. */ 896 /* The DAI name is the last part of the full name of the node. */
682 p = strrchr(np->full_name, '/') + 1; 897 p = strrchr(np->full_name, '/') + 1;
683 ssi_private = kzalloc(sizeof(struct fsl_ssi_private) + strlen(p), 898 ssi_private = devm_kzalloc(&pdev->dev, sizeof(*ssi_private) + strlen(p),
684 GFP_KERNEL); 899 GFP_KERNEL);
685 if (!ssi_private) { 900 if (!ssi_private) {
686 dev_err(&pdev->dev, "could not allocate DAI object\n"); 901 dev_err(&pdev->dev, "could not allocate DAI object\n");
@@ -689,38 +904,41 @@ static int fsl_ssi_probe(struct platform_device *pdev)
689 904
690 strcpy(ssi_private->name, p); 905 strcpy(ssi_private->name, p);
691 906
692 /* Initialize this copy of the CPU DAI driver structure */ 907 ssi_private->use_dma = !of_property_read_bool(np,
693 memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template, 908 "fsl,fiq-stream-filter");
694 sizeof(fsl_ssi_dai_template)); 909
910 if (ac97) {
911 memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai,
912 sizeof(fsl_ssi_ac97_dai));
913
914 fsl_ac97_data = ssi_private;
915 ssi_private->imx_ac97 = true;
916
917 snd_soc_set_ac97_ops_of_reset(&fsl_ssi_ac97_ops, pdev);
918 } else {
919 /* Initialize this copy of the CPU DAI driver structure */
920 memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template,
921 sizeof(fsl_ssi_dai_template));
922 }
695 ssi_private->cpu_dai_drv.name = ssi_private->name; 923 ssi_private->cpu_dai_drv.name = ssi_private->name;
696 924
697 /* Get the addresses and IRQ */ 925 /* Get the addresses and IRQ */
698 ret = of_address_to_resource(np, 0, &res); 926 ret = of_address_to_resource(np, 0, &res);
699 if (ret) { 927 if (ret) {
700 dev_err(&pdev->dev, "could not determine device resources\n"); 928 dev_err(&pdev->dev, "could not determine device resources\n");
701 goto error_kmalloc; 929 return ret;
702 } 930 }
703 ssi_private->ssi = of_iomap(np, 0); 931 ssi_private->ssi = of_iomap(np, 0);
704 if (!ssi_private->ssi) { 932 if (!ssi_private->ssi) {
705 dev_err(&pdev->dev, "could not map device resources\n"); 933 dev_err(&pdev->dev, "could not map device resources\n");
706 ret = -ENOMEM; 934 return -ENOMEM;
707 goto error_kmalloc;
708 } 935 }
709 ssi_private->ssi_phys = res.start; 936 ssi_private->ssi_phys = res.start;
710 937
711 ssi_private->irq = irq_of_parse_and_map(np, 0); 938 ssi_private->irq = irq_of_parse_and_map(np, 0);
712 if (ssi_private->irq == NO_IRQ) { 939 if (ssi_private->irq == NO_IRQ) {
713 dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); 940 dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
714 ret = -ENXIO; 941 return -ENXIO;
715 goto error_iomap;
716 }
717
718 /* The 'name' should not have any slashes in it. */
719 ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0, ssi_private->name,
720 ssi_private);
721 if (ret < 0) {
722 dev_err(&pdev->dev, "could not claim irq %u\n", ssi_private->irq);
723 goto error_irqmap;
724 } 942 }
725 943
726 /* Are the RX and the TX clocks locked? */ 944 /* Are the RX and the TX clocks locked? */
@@ -739,13 +957,18 @@ static int fsl_ssi_probe(struct platform_device *pdev)
739 u32 dma_events[2]; 957 u32 dma_events[2];
740 ssi_private->ssi_on_imx = true; 958 ssi_private->ssi_on_imx = true;
741 959
742 ssi_private->clk = clk_get(&pdev->dev, NULL); 960 ssi_private->clk = devm_clk_get(&pdev->dev, NULL);
743 if (IS_ERR(ssi_private->clk)) { 961 if (IS_ERR(ssi_private->clk)) {
744 ret = PTR_ERR(ssi_private->clk); 962 ret = PTR_ERR(ssi_private->clk);
745 dev_err(&pdev->dev, "could not get clock: %d\n", ret); 963 dev_err(&pdev->dev, "could not get clock: %d\n", ret);
746 goto error_irq; 964 goto error_irqmap;
965 }
966 ret = clk_prepare_enable(ssi_private->clk);
967 if (ret) {
968 dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n",
969 ret);
970 goto error_irqmap;
747 } 971 }
748 clk_prepare_enable(ssi_private->clk);
749 972
750 /* 973 /*
751 * We have burstsize be "fifo_depth - 2" to match the SSI 974 * We have burstsize be "fifo_depth - 2" to match the SSI
@@ -763,24 +986,38 @@ static int fsl_ssi_probe(struct platform_device *pdev)
763 &ssi_private->filter_data_tx; 986 &ssi_private->filter_data_tx;
764 ssi_private->dma_params_rx.filter_data = 987 ssi_private->dma_params_rx.filter_data =
765 &ssi_private->filter_data_rx; 988 &ssi_private->filter_data_rx;
766 /* 989 if (!of_property_read_bool(pdev->dev.of_node, "dmas") &&
767 * TODO: This is a temporary solution and should be changed 990 ssi_private->use_dma) {
768 * to use generic DMA binding later when the helplers get in. 991 /*
769 */ 992 * FIXME: This is a temporary solution until all
770 ret = of_property_read_u32_array(pdev->dev.of_node, 993 * necessary dma drivers support the generic dma
994 * bindings.
995 */
996 ret = of_property_read_u32_array(pdev->dev.of_node,
771 "fsl,ssi-dma-events", dma_events, 2); 997 "fsl,ssi-dma-events", dma_events, 2);
772 if (ret) { 998 if (ret && ssi_private->use_dma) {
773 dev_err(&pdev->dev, "could not get dma events\n"); 999 dev_err(&pdev->dev, "could not get dma events but fsl-ssi is configured to use DMA\n");
774 goto error_clk; 1000 goto error_clk;
1001 }
775 } 1002 }
776 1003
777 shared = of_device_is_compatible(of_get_parent(np), 1004 shared = of_device_is_compatible(of_get_parent(np),
778 "fsl,spba-bus"); 1005 "fsl,spba-bus");
779 1006
780 imx_pcm_dma_params_init_data(&ssi_private->filter_data_tx, 1007 imx_pcm_dma_params_init_data(&ssi_private->filter_data_tx,
781 dma_events[0], shared); 1008 dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
782 imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx, 1009 imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
783 dma_events[1], shared); 1010 dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
1011 } else if (ssi_private->use_dma) {
1012 /* The 'name' should not have any slashes in it. */
1013 ret = devm_request_irq(&pdev->dev, ssi_private->irq,
1014 fsl_ssi_isr, 0, ssi_private->name,
1015 ssi_private);
1016 if (ret < 0) {
1017 dev_err(&pdev->dev, "could not claim irq %u\n",
1018 ssi_private->irq);
1019 goto error_irqmap;
1020 }
784 } 1021 }
785 1022
786 /* Initialize the the device_attribute structure */ 1023 /* Initialize the the device_attribute structure */
@@ -794,7 +1031,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
794 if (ret) { 1031 if (ret) {
795 dev_err(&pdev->dev, "could not create sysfs %s file\n", 1032 dev_err(&pdev->dev, "could not create sysfs %s file\n",
796 ssi_private->dev_attr.attr.name); 1033 ssi_private->dev_attr.attr.name);
797 goto error_irq; 1034 goto error_clk;
798 } 1035 }
799 1036
800 /* Register with ASoC */ 1037 /* Register with ASoC */
@@ -808,9 +1045,30 @@ static int fsl_ssi_probe(struct platform_device *pdev)
808 } 1045 }
809 1046
810 if (ssi_private->ssi_on_imx) { 1047 if (ssi_private->ssi_on_imx) {
811 ret = imx_pcm_dma_init(pdev); 1048 if (!ssi_private->use_dma) {
812 if (ret) 1049
813 goto error_dev; 1050 /*
1051 * Some boards use an incompatible codec. To get it
1052 * working, we are using imx-fiq-pcm-audio, that
1053 * can handle those codecs. DMA is not possible in this
1054 * situation.
1055 */
1056
1057 ssi_private->fiq_params.irq = ssi_private->irq;
1058 ssi_private->fiq_params.base = ssi_private->ssi;
1059 ssi_private->fiq_params.dma_params_rx =
1060 &ssi_private->dma_params_rx;
1061 ssi_private->fiq_params.dma_params_tx =
1062 &ssi_private->dma_params_tx;
1063
1064 ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params);
1065 if (ret)
1066 goto error_dev;
1067 } else {
1068 ret = imx_pcm_dma_init(pdev);
1069 if (ret)
1070 goto error_dev;
1071 }
814 } 1072 }
815 1073
816 /* 1074 /*
@@ -845,6 +1103,9 @@ static int fsl_ssi_probe(struct platform_device *pdev)
845 } 1103 }
846 1104
847done: 1105done:
1106 if (ssi_private->imx_ac97)
1107 fsl_ssi_ac97_init();
1108
848 return 0; 1109 return 0;
849 1110
850error_dai: 1111error_dai:
@@ -853,27 +1114,15 @@ error_dai:
853 snd_soc_unregister_component(&pdev->dev); 1114 snd_soc_unregister_component(&pdev->dev);
854 1115
855error_dev: 1116error_dev:
856 dev_set_drvdata(&pdev->dev, NULL);
857 device_remove_file(&pdev->dev, dev_attr); 1117 device_remove_file(&pdev->dev, dev_attr);
858 1118
859error_clk: 1119error_clk:
860 if (ssi_private->ssi_on_imx) { 1120 if (ssi_private->ssi_on_imx)
861 clk_disable_unprepare(ssi_private->clk); 1121 clk_disable_unprepare(ssi_private->clk);
862 clk_put(ssi_private->clk);
863 }
864
865error_irq:
866 free_irq(ssi_private->irq, ssi_private);
867 1122
868error_irqmap: 1123error_irqmap:
869 irq_dispose_mapping(ssi_private->irq); 1124 irq_dispose_mapping(ssi_private->irq);
870 1125
871error_iomap:
872 iounmap(ssi_private->ssi);
873
874error_kmalloc:
875 kfree(ssi_private);
876
877 return ret; 1126 return ret;
878} 1127}
879 1128
@@ -883,20 +1132,15 @@ static int fsl_ssi_remove(struct platform_device *pdev)
883 1132
884 if (!ssi_private->new_binding) 1133 if (!ssi_private->new_binding)
885 platform_device_unregister(ssi_private->pdev); 1134 platform_device_unregister(ssi_private->pdev);
886 if (ssi_private->ssi_on_imx) { 1135 if (ssi_private->ssi_on_imx)
887 imx_pcm_dma_exit(pdev); 1136 imx_pcm_dma_exit(pdev);
888 clk_disable_unprepare(ssi_private->clk);
889 clk_put(ssi_private->clk);
890 }
891 snd_soc_unregister_component(&pdev->dev); 1137 snd_soc_unregister_component(&pdev->dev);
1138 dev_set_drvdata(&pdev->dev, NULL);
892 device_remove_file(&pdev->dev, &ssi_private->dev_attr); 1139 device_remove_file(&pdev->dev, &ssi_private->dev_attr);
893 1140 if (ssi_private->ssi_on_imx)
894 free_irq(ssi_private->irq, ssi_private); 1141 clk_disable_unprepare(ssi_private->clk);
895 irq_dispose_mapping(ssi_private->irq); 1142 irq_dispose_mapping(ssi_private->irq);
896 1143
897 kfree(ssi_private);
898 dev_set_drvdata(&pdev->dev, NULL);
899
900 return 0; 1144 return 0;
901} 1145}
902 1146
@@ -919,6 +1163,7 @@ static struct platform_driver fsl_ssi_driver = {
919 1163
920module_platform_driver(fsl_ssi_driver); 1164module_platform_driver(fsl_ssi_driver);
921 1165
1166MODULE_ALIAS("platform:fsl-ssi-dai");
922MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); 1167MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
923MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver"); 1168MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver");
924MODULE_LICENSE("GPL v2"); 1169MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index e260f1f899db..ab17381cc981 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -73,8 +73,11 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
73 if (!buf) 73 if (!buf)
74 return -ENOMEM; 74 return -ENOMEM;
75 75
76 if (audmux_clk) 76 if (audmux_clk) {
77 clk_prepare_enable(audmux_clk); 77 ret = clk_prepare_enable(audmux_clk);
78 if (ret)
79 return ret;
80 }
78 81
79 ptcr = readl(audmux_base + IMX_AUDMUX_V2_PTCR(port)); 82 ptcr = readl(audmux_base + IMX_AUDMUX_V2_PTCR(port));
80 pdcr = readl(audmux_base + IMX_AUDMUX_V2_PDCR(port)); 83 pdcr = readl(audmux_base + IMX_AUDMUX_V2_PDCR(port));
@@ -224,14 +227,19 @@ EXPORT_SYMBOL_GPL(imx_audmux_v1_configure_port);
224int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr, 227int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
225 unsigned int pdcr) 228 unsigned int pdcr)
226{ 229{
230 int ret;
231
227 if (audmux_type != IMX31_AUDMUX) 232 if (audmux_type != IMX31_AUDMUX)
228 return -EINVAL; 233 return -EINVAL;
229 234
230 if (!audmux_base) 235 if (!audmux_base)
231 return -ENOSYS; 236 return -ENOSYS;
232 237
233 if (audmux_clk) 238 if (audmux_clk) {
234 clk_prepare_enable(audmux_clk); 239 ret = clk_prepare_enable(audmux_clk);
240 if (ret)
241 return ret;
242 }
235 243
236 writel(ptcr, audmux_base + IMX_AUDMUX_V2_PTCR(port)); 244 writel(ptcr, audmux_base + IMX_AUDMUX_V2_PTCR(port));
237 writel(pdcr, audmux_base + IMX_AUDMUX_V2_PDCR(port)); 245 writel(pdcr, audmux_base + IMX_AUDMUX_V2_PDCR(port));
@@ -243,6 +251,66 @@ int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
243} 251}
244EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port); 252EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
245 253
254static int imx_audmux_parse_dt_defaults(struct platform_device *pdev,
255 struct device_node *of_node)
256{
257 struct device_node *child;
258
259 for_each_available_child_of_node(of_node, child) {
260 unsigned int port;
261 unsigned int ptcr = 0;
262 unsigned int pdcr = 0;
263 unsigned int pcr = 0;
264 unsigned int val;
265 int ret;
266 int i = 0;
267
268 ret = of_property_read_u32(child, "fsl,audmux-port", &port);
269 if (ret) {
270 dev_warn(&pdev->dev, "Failed to get fsl,audmux-port of child node \"%s\"\n",
271 child->full_name);
272 continue;
273 }
274 if (!of_property_read_bool(child, "fsl,port-config")) {
275 dev_warn(&pdev->dev, "child node \"%s\" does not have property fsl,port-config\n",
276 child->full_name);
277 continue;
278 }
279
280 for (i = 0; (ret = of_property_read_u32_index(child,
281 "fsl,port-config", i, &val)) == 0;
282 ++i) {
283 if (audmux_type == IMX31_AUDMUX) {
284 if (i % 2)
285 pdcr |= val;
286 else
287 ptcr |= val;
288 } else {
289 pcr |= val;
290 }
291 }
292
293 if (ret != -EOVERFLOW) {
294 dev_err(&pdev->dev, "Failed to read u32 at index %d of child %s\n",
295 i, child->full_name);
296 continue;
297 }
298
299 if (audmux_type == IMX31_AUDMUX) {
300 if (i % 2) {
301 dev_err(&pdev->dev, "One pdcr value is missing in child node %s\n",
302 child->full_name);
303 continue;
304 }
305 imx_audmux_v2_configure_port(port, ptcr, pdcr);
306 } else {
307 imx_audmux_v1_configure_port(port, pcr);
308 }
309 }
310
311 return 0;
312}
313
246static int imx_audmux_probe(struct platform_device *pdev) 314static int imx_audmux_probe(struct platform_device *pdev)
247{ 315{
248 struct resource *res; 316 struct resource *res;
@@ -267,6 +335,8 @@ static int imx_audmux_probe(struct platform_device *pdev)
267 if (audmux_type == IMX31_AUDMUX) 335 if (audmux_type == IMX31_AUDMUX)
268 audmux_debugfs_init(); 336 audmux_debugfs_init();
269 337
338 imx_audmux_parse_dt_defaults(pdev, pdev->dev.of_node);
339
270 return 0; 340 return 0;
271} 341}
272 342
diff --git a/sound/soc/fsl/imx-audmux.h b/sound/soc/fsl/imx-audmux.h
index b8ff44b9dafa..38a4209af7c6 100644
--- a/sound/soc/fsl/imx-audmux.h
+++ b/sound/soc/fsl/imx-audmux.h
@@ -1,57 +1,7 @@
1#ifndef __IMX_AUDMUX_H 1#ifndef __IMX_AUDMUX_H
2#define __IMX_AUDMUX_H 2#define __IMX_AUDMUX_H
3 3
4#define MX27_AUDMUX_HPCR1_SSI0 0 4#include <dt-bindings/sound/fsl-imx-audmux.h>
5#define MX27_AUDMUX_HPCR2_SSI1 1
6#define MX27_AUDMUX_HPCR3_SSI_PINS_4 2
7#define MX27_AUDMUX_PPCR1_SSI_PINS_1 3
8#define MX27_AUDMUX_PPCR2_SSI_PINS_2 4
9#define MX27_AUDMUX_PPCR3_SSI_PINS_3 5
10
11#define MX31_AUDMUX_PORT1_SSI0 0
12#define MX31_AUDMUX_PORT2_SSI1 1
13#define MX31_AUDMUX_PORT3_SSI_PINS_3 2
14#define MX31_AUDMUX_PORT4_SSI_PINS_4 3
15#define MX31_AUDMUX_PORT5_SSI_PINS_5 4
16#define MX31_AUDMUX_PORT6_SSI_PINS_6 5
17#define MX31_AUDMUX_PORT7_SSI_PINS_7 6
18
19#define MX51_AUDMUX_PORT1_SSI0 0
20#define MX51_AUDMUX_PORT2_SSI1 1
21#define MX51_AUDMUX_PORT3 2
22#define MX51_AUDMUX_PORT4 3
23#define MX51_AUDMUX_PORT5 4
24#define MX51_AUDMUX_PORT6 5
25#define MX51_AUDMUX_PORT7 6
26
27/* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
28#define IMX_AUDMUX_V1_PCR_INMMASK(x) ((x) & 0xff)
29#define IMX_AUDMUX_V1_PCR_INMEN (1 << 8)
30#define IMX_AUDMUX_V1_PCR_TXRXEN (1 << 10)
31#define IMX_AUDMUX_V1_PCR_SYN (1 << 12)
32#define IMX_AUDMUX_V1_PCR_RXDSEL(x) (((x) & 0x7) << 13)
33#define IMX_AUDMUX_V1_PCR_RFCSEL(x) (((x) & 0xf) << 20)
34#define IMX_AUDMUX_V1_PCR_RCLKDIR (1 << 24)
35#define IMX_AUDMUX_V1_PCR_RFSDIR (1 << 25)
36#define IMX_AUDMUX_V1_PCR_TFCSEL(x) (((x) & 0xf) << 26)
37#define IMX_AUDMUX_V1_PCR_TCLKDIR (1 << 30)
38#define IMX_AUDMUX_V1_PCR_TFSDIR (1 << 31)
39
40/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */
41#define IMX_AUDMUX_V2_PTCR_TFSDIR (1 << 31)
42#define IMX_AUDMUX_V2_PTCR_TFSEL(x) (((x) & 0xf) << 27)
43#define IMX_AUDMUX_V2_PTCR_TCLKDIR (1 << 26)
44#define IMX_AUDMUX_V2_PTCR_TCSEL(x) (((x) & 0xf) << 22)
45#define IMX_AUDMUX_V2_PTCR_RFSDIR (1 << 21)
46#define IMX_AUDMUX_V2_PTCR_RFSEL(x) (((x) & 0xf) << 17)
47#define IMX_AUDMUX_V2_PTCR_RCLKDIR (1 << 16)
48#define IMX_AUDMUX_V2_PTCR_RCSEL(x) (((x) & 0xf) << 12)
49#define IMX_AUDMUX_V2_PTCR_SYN (1 << 11)
50
51#define IMX_AUDMUX_V2_PDCR_RXDSEL(x) (((x) & 0x7) << 13)
52#define IMX_AUDMUX_V2_PDCR_TXRXEN (1 << 12)
53#define IMX_AUDMUX_V2_PDCR_MODE(x) (((x) & 0x3) << 8)
54#define IMX_AUDMUX_V2_PDCR_INMMASK(x) ((x) & 0xff)
55 5
56int imx_audmux_v1_configure_port(unsigned int port, unsigned int pcr); 6int imx_audmux_v1_configure_port(unsigned int port, unsigned int pcr);
57 7
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c
index 9df173c091a6..a3d60d4bea4c 100644
--- a/sound/soc/fsl/imx-mc13783.c
+++ b/sound/soc/fsl/imx-mc13783.c
@@ -90,6 +90,7 @@ static const struct snd_soc_dapm_route imx_mc13783_routes[] = {
90 90
91static struct snd_soc_card imx_mc13783 = { 91static struct snd_soc_card imx_mc13783 = {
92 .name = "imx_mc13783", 92 .name = "imx_mc13783",
93 .owner = THIS_MODULE,
93 .dai_link = imx_mc13783_dai_mc13783, 94 .dai_link = imx_mc13783_dai_mc13783,
94 .num_links = ARRAY_SIZE(imx_mc13783_dai_mc13783), 95 .num_links = ARRAY_SIZE(imx_mc13783_dai_mc13783),
95 .dapm_widgets = imx_mc13783_widget, 96 .dapm_widgets = imx_mc13783_widget,
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index fde4d2ea68c8..4dc1296688e9 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -14,6 +14,7 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/dmaengine.h> 15#include <linux/dmaengine.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/module.h>
17 18
18#include <sound/core.h> 19#include <sound/core.h>
19#include <sound/pcm.h> 20#include <sound/pcm.h>
@@ -64,7 +65,6 @@ int imx_pcm_dma_init(struct platform_device *pdev)
64{ 65{
65 return snd_dmaengine_pcm_register(&pdev->dev, &imx_dmaengine_pcm_config, 66 return snd_dmaengine_pcm_register(&pdev->dev, &imx_dmaengine_pcm_config,
66 SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | 67 SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
67 SND_DMAENGINE_PCM_FLAG_NO_DT |
68 SND_DMAENGINE_PCM_FLAG_COMPAT); 68 SND_DMAENGINE_PCM_FLAG_COMPAT);
69} 69}
70EXPORT_SYMBOL_GPL(imx_pcm_dma_init); 70EXPORT_SYMBOL_GPL(imx_pcm_dma_init);
@@ -74,3 +74,5 @@ void imx_pcm_dma_exit(struct platform_device *pdev)
74 snd_dmaengine_pcm_unregister(&pdev->dev); 74 snd_dmaengine_pcm_unregister(&pdev->dev);
75} 75}
76EXPORT_SYMBOL_GPL(imx_pcm_dma_exit); 76EXPORT_SYMBOL_GPL(imx_pcm_dma_exit);
77
78MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index 310d90290320..34043c55f2a6 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -22,6 +22,7 @@
22#include <linux/slab.h> 22#include <linux/slab.h>
23 23
24#include <sound/core.h> 24#include <sound/core.h>
25#include <sound/dmaengine_pcm.h>
25#include <sound/initval.h> 26#include <sound/initval.h>
26#include <sound/pcm.h> 27#include <sound/pcm.h>
27#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
@@ -32,6 +33,7 @@
32#include <linux/platform_data/asoc-imx-ssi.h> 33#include <linux/platform_data/asoc-imx-ssi.h>
33 34
34#include "imx-ssi.h" 35#include "imx-ssi.h"
36#include "imx-pcm.h"
35 37
36struct imx_pcm_runtime_data { 38struct imx_pcm_runtime_data {
37 unsigned int period; 39 unsigned int period;
@@ -366,9 +368,9 @@ static struct snd_soc_platform_driver imx_soc_platform_fiq = {
366 .pcm_free = imx_pcm_fiq_free, 368 .pcm_free = imx_pcm_fiq_free,
367}; 369};
368 370
369int imx_pcm_fiq_init(struct platform_device *pdev) 371int imx_pcm_fiq_init(struct platform_device *pdev,
372 struct imx_pcm_fiq_params *params)
370{ 373{
371 struct imx_ssi *ssi = platform_get_drvdata(pdev);
372 int ret; 374 int ret;
373 375
374 ret = claim_fiq(&fh); 376 ret = claim_fiq(&fh);
@@ -377,15 +379,15 @@ int imx_pcm_fiq_init(struct platform_device *pdev)
377 return ret; 379 return ret;
378 } 380 }
379 381
380 mxc_set_irq_fiq(ssi->irq, 1); 382 mxc_set_irq_fiq(params->irq, 1);
381 ssi_irq = ssi->irq; 383 ssi_irq = params->irq;
382 384
383 imx_pcm_fiq = ssi->irq; 385 imx_pcm_fiq = params->irq;
384 386
385 imx_ssi_fiq_base = (unsigned long)ssi->base; 387 imx_ssi_fiq_base = (unsigned long)params->base;
386 388
387 ssi->dma_params_tx.maxburst = 4; 389 params->dma_params_tx->maxburst = 4;
388 ssi->dma_params_rx.maxburst = 6; 390 params->dma_params_rx->maxburst = 6;
389 391
390 ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq); 392 ret = snd_soc_register_platform(&pdev->dev, &imx_soc_platform_fiq);
391 if (ret) 393 if (ret)
@@ -406,3 +408,5 @@ void imx_pcm_fiq_exit(struct platform_device *pdev)
406 snd_soc_unregister_platform(&pdev->dev); 408 snd_soc_unregister_platform(&pdev->dev);
407} 409}
408EXPORT_SYMBOL_GPL(imx_pcm_fiq_exit); 410EXPORT_SYMBOL_GPL(imx_pcm_fiq_exit);
411
412MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/imx-pcm.h b/sound/soc/fsl/imx-pcm.h
index 67f656c7c320..5d5b73303e11 100644
--- a/sound/soc/fsl/imx-pcm.h
+++ b/sound/soc/fsl/imx-pcm.h
@@ -22,17 +22,23 @@
22 22
23static inline void 23static inline void
24imx_pcm_dma_params_init_data(struct imx_dma_data *dma_data, 24imx_pcm_dma_params_init_data(struct imx_dma_data *dma_data,
25 int dma, bool shared) 25 int dma, enum sdma_peripheral_type peripheral_type)
26{ 26{
27 dma_data->dma_request = dma; 27 dma_data->dma_request = dma;
28 dma_data->priority = DMA_PRIO_HIGH; 28 dma_data->priority = DMA_PRIO_HIGH;
29 if (shared) 29 dma_data->peripheral_type = peripheral_type;
30 dma_data->peripheral_type = IMX_DMATYPE_SSI_SP;
31 else
32 dma_data->peripheral_type = IMX_DMATYPE_SSI;
33} 30}
34 31
35#ifdef CONFIG_SND_SOC_IMX_PCM_DMA 32struct imx_pcm_fiq_params {
33 int irq;
34 void __iomem *base;
35
36 /* Pointer to original ssi driver to setup tx rx sizes */
37 struct snd_dmaengine_dai_dma_data *dma_params_rx;
38 struct snd_dmaengine_dai_dma_data *dma_params_tx;
39};
40
41#if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_DMA)
36int imx_pcm_dma_init(struct platform_device *pdev); 42int imx_pcm_dma_init(struct platform_device *pdev);
37void imx_pcm_dma_exit(struct platform_device *pdev); 43void imx_pcm_dma_exit(struct platform_device *pdev);
38#else 44#else
@@ -46,11 +52,13 @@ static inline void imx_pcm_dma_exit(struct platform_device *pdev)
46} 52}
47#endif 53#endif
48 54
49#ifdef CONFIG_SND_SOC_IMX_PCM_FIQ 55#if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_FIQ)
50int imx_pcm_fiq_init(struct platform_device *pdev); 56int imx_pcm_fiq_init(struct platform_device *pdev,
57 struct imx_pcm_fiq_params *params);
51void imx_pcm_fiq_exit(struct platform_device *pdev); 58void imx_pcm_fiq_exit(struct platform_device *pdev);
52#else 59#else
53static inline int imx_pcm_fiq_init(struct platform_device *pdev) 60static inline int imx_pcm_fiq_init(struct platform_device *pdev,
61 struct imx_pcm_fiq_params *params)
54{ 62{
55 return -ENODEV; 63 return -ENODEV;
56} 64}
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c
index 3f726e4f88db..389cbfa6dca7 100644
--- a/sound/soc/fsl/imx-sgtl5000.c
+++ b/sound/soc/fsl/imx-sgtl5000.c
@@ -129,8 +129,10 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
129 } 129 }
130 130
131 data->codec_clk = devm_clk_get(&codec_dev->dev, NULL); 131 data->codec_clk = devm_clk_get(&codec_dev->dev, NULL);
132 if (IS_ERR(data->codec_clk)) 132 if (IS_ERR(data->codec_clk)) {
133 ret = PTR_ERR(data->codec_clk);
133 goto fail; 134 goto fail;
135 }
134 136
135 data->clk_frequency = clk_get_rate(data->codec_clk); 137 data->clk_frequency = clk_get_rate(data->codec_clk);
136 138
diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c
new file mode 100644
index 000000000000..816013b0ebba
--- /dev/null
+++ b/sound/soc/fsl/imx-spdif.c
@@ -0,0 +1,148 @@
1/*
2 * Copyright (C) 2013 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/module.h>
13#include <linux/of_platform.h>
14#include <sound/soc.h>
15
16struct imx_spdif_data {
17 struct snd_soc_dai_link dai[2];
18 struct snd_soc_card card;
19 struct platform_device *txdev;
20 struct platform_device *rxdev;
21};
22
23static int imx_spdif_audio_probe(struct platform_device *pdev)
24{
25 struct device_node *spdif_np, *np = pdev->dev.of_node;
26 struct imx_spdif_data *data;
27 int ret = 0, num_links = 0;
28
29 spdif_np = of_parse_phandle(np, "spdif-controller", 0);
30 if (!spdif_np) {
31 dev_err(&pdev->dev, "failed to find spdif-controller\n");
32 ret = -EINVAL;
33 goto end;
34 }
35
36 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
37 if (!data) {
38 dev_err(&pdev->dev, "failed to allocate memory\n");
39 ret = -ENOMEM;
40 goto end;
41 }
42
43 if (of_property_read_bool(np, "spdif-out")) {
44 data->dai[num_links].name = "S/PDIF TX";
45 data->dai[num_links].stream_name = "S/PDIF PCM Playback";
46 data->dai[num_links].codec_dai_name = "dit-hifi";
47 data->dai[num_links].codec_name = "spdif-dit";
48 data->dai[num_links].cpu_of_node = spdif_np;
49 data->dai[num_links].platform_of_node = spdif_np;
50 num_links++;
51
52 data->txdev = platform_device_register_simple("spdif-dit", -1, NULL, 0);
53 if (IS_ERR(data->txdev)) {
54 ret = PTR_ERR(data->txdev);
55 dev_err(&pdev->dev, "register dit failed: %d\n", ret);
56 goto end;
57 }
58 }
59
60 if (of_property_read_bool(np, "spdif-in")) {
61 data->dai[num_links].name = "S/PDIF RX";
62 data->dai[num_links].stream_name = "S/PDIF PCM Capture";
63 data->dai[num_links].codec_dai_name = "dir-hifi";
64 data->dai[num_links].codec_name = "spdif-dir";
65 data->dai[num_links].cpu_of_node = spdif_np;
66 data->dai[num_links].platform_of_node = spdif_np;
67 num_links++;
68
69 data->rxdev = platform_device_register_simple("spdif-dir", -1, NULL, 0);
70 if (IS_ERR(data->rxdev)) {
71 ret = PTR_ERR(data->rxdev);
72 dev_err(&pdev->dev, "register dir failed: %d\n", ret);
73 goto error_dit;
74 }
75 }
76
77 if (!num_links) {
78 dev_err(&pdev->dev, "no enabled S/PDIF DAI link\n");
79 goto error_dir;
80 }
81
82 data->card.dev = &pdev->dev;
83 data->card.num_links = num_links;
84 data->card.dai_link = data->dai;
85
86 ret = snd_soc_of_parse_card_name(&data->card, "model");
87 if (ret)
88 goto error_dir;
89
90 ret = snd_soc_register_card(&data->card);
91 if (ret) {
92 dev_err(&pdev->dev, "snd_soc_register_card failed: %d\n", ret);
93 goto error_dir;
94 }
95
96 platform_set_drvdata(pdev, data);
97
98 goto end;
99
100error_dir:
101 if (data->rxdev)
102 platform_device_unregister(data->rxdev);
103error_dit:
104 if (data->txdev)
105 platform_device_unregister(data->txdev);
106end:
107 if (spdif_np)
108 of_node_put(spdif_np);
109
110 return ret;
111}
112
113static int imx_spdif_audio_remove(struct platform_device *pdev)
114{
115 struct imx_spdif_data *data = platform_get_drvdata(pdev);
116
117 if (data->rxdev)
118 platform_device_unregister(data->rxdev);
119 if (data->txdev)
120 platform_device_unregister(data->txdev);
121
122 snd_soc_unregister_card(&data->card);
123
124 return 0;
125}
126
127static const struct of_device_id imx_spdif_dt_ids[] = {
128 { .compatible = "fsl,imx-audio-spdif", },
129 { /* sentinel */ }
130};
131MODULE_DEVICE_TABLE(of, imx_spdif_dt_ids);
132
133static struct platform_driver imx_spdif_driver = {
134 .driver = {
135 .name = "imx-spdif",
136 .owner = THIS_MODULE,
137 .of_match_table = imx_spdif_dt_ids,
138 },
139 .probe = imx_spdif_audio_probe,
140 .remove = imx_spdif_audio_remove,
141};
142
143module_platform_driver(imx_spdif_driver);
144
145MODULE_AUTHOR("Freescale Semiconductor, Inc.");
146MODULE_DESCRIPTION("Freescale i.MX S/PDIF machine driver");
147MODULE_LICENSE("GPL v2");
148MODULE_ALIAS("platform:imx-spdif");
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index 51be3772cba9..f58bcd85c07f 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -571,13 +571,13 @@ static int imx_ssi_probe(struct platform_device *pdev)
571 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0"); 571 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
572 if (res) { 572 if (res) {
573 imx_pcm_dma_params_init_data(&ssi->filter_data_tx, res->start, 573 imx_pcm_dma_params_init_data(&ssi->filter_data_tx, res->start,
574 false); 574 IMX_DMATYPE_SSI);
575 } 575 }
576 576
577 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0"); 577 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0");
578 if (res) { 578 if (res) {
579 imx_pcm_dma_params_init_data(&ssi->filter_data_rx, res->start, 579 imx_pcm_dma_params_init_data(&ssi->filter_data_rx, res->start,
580 false); 580 IMX_DMATYPE_SSI);
581 } 581 }
582 582
583 platform_set_drvdata(pdev, ssi); 583 platform_set_drvdata(pdev, ssi);
@@ -595,7 +595,12 @@ static int imx_ssi_probe(struct platform_device *pdev)
595 goto failed_register; 595 goto failed_register;
596 } 596 }
597 597
598 ret = imx_pcm_fiq_init(pdev); 598 ssi->fiq_params.irq = ssi->irq;
599 ssi->fiq_params.base = ssi->base;
600 ssi->fiq_params.dma_params_rx = &ssi->dma_params_rx;
601 ssi->fiq_params.dma_params_tx = &ssi->dma_params_tx;
602
603 ret = imx_pcm_fiq_init(pdev, &ssi->fiq_params);
599 if (ret) 604 if (ret)
600 goto failed_pcm_fiq; 605 goto failed_pcm_fiq;
601 606
diff --git a/sound/soc/fsl/imx-ssi.h b/sound/soc/fsl/imx-ssi.h
index d5003cefca8d..fb1616ba8c59 100644
--- a/sound/soc/fsl/imx-ssi.h
+++ b/sound/soc/fsl/imx-ssi.h
@@ -209,6 +209,7 @@ struct imx_ssi {
209 struct snd_dmaengine_dai_dma_data dma_params_tx; 209 struct snd_dmaengine_dai_dma_data dma_params_tx;
210 struct imx_dma_data filter_data_tx; 210 struct imx_dma_data filter_data_tx;
211 struct imx_dma_data filter_data_rx; 211 struct imx_dma_data filter_data_rx;
212 struct imx_pcm_fiq_params fiq_params;
212 213
213 int enabled; 214 int enabled;
214}; 215};
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
index 52a36a90f4f4..1d70e278e915 100644
--- a/sound/soc/fsl/imx-wm8962.c
+++ b/sound/soc/fsl/imx-wm8962.c
@@ -217,7 +217,8 @@ static int imx_wm8962_probe(struct platform_device *pdev)
217 codec_dev = of_find_i2c_device_by_node(codec_np); 217 codec_dev = of_find_i2c_device_by_node(codec_np);
218 if (!codec_dev || !codec_dev->driver) { 218 if (!codec_dev || !codec_dev->driver) {
219 dev_err(&pdev->dev, "failed to find codec platform device\n"); 219 dev_err(&pdev->dev, "failed to find codec platform device\n");
220 return -EINVAL; 220 ret = -EINVAL;
221 goto fail;
221 } 222 }
222 223
223 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 224 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 6cf8355a8542..8c49147db84c 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -105,6 +105,7 @@ static int asoc_simple_card_remove(struct platform_device *pdev)
105static struct platform_driver asoc_simple_card = { 105static struct platform_driver asoc_simple_card = {
106 .driver = { 106 .driver = {
107 .name = "asoc-simple-card", 107 .name = "asoc-simple-card",
108 .owner = THIS_MODULE,
108 }, 109 },
109 .probe = asoc_simple_card_probe, 110 .probe = asoc_simple_card_probe,
110 .remove = asoc_simple_card_remove, 111 .remove = asoc_simple_card_remove,
@@ -112,6 +113,7 @@ static struct platform_driver asoc_simple_card = {
112 113
113module_platform_driver(asoc_simple_card); 114module_platform_driver(asoc_simple_card);
114 115
116MODULE_ALIAS("platform:asoc-simple-card");
115MODULE_LICENSE("GPL"); 117MODULE_LICENSE("GPL");
116MODULE_DESCRIPTION("ASoC Simple Sound Card"); 118MODULE_DESCRIPTION("ASoC Simple Sound Card");
117MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); 119MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig
index c62d715235e2..78ed4a42ad21 100644
--- a/sound/soc/kirkwood/Kconfig
+++ b/sound/soc/kirkwood/Kconfig
@@ -1,19 +1,15 @@
1config SND_KIRKWOOD_SOC 1config SND_KIRKWOOD_SOC
2 tristate "SoC Audio for the Marvell Kirkwood chip" 2 tristate "SoC Audio for the Marvell Kirkwood and Dove chips"
3 depends on ARCH_KIRKWOOD 3 depends on ARCH_KIRKWOOD || ARCH_DOVE || COMPILE_TEST
4 help 4 help
5 Say Y or M if you want to add support for codecs attached to 5 Say Y or M if you want to add support for codecs attached to
6 the Kirkwood I2S interface. You will also need to select the 6 the Kirkwood I2S interface. You will also need to select the
7 audio interfaces to support below. 7 audio interfaces to support below.
8 8
9config SND_KIRKWOOD_SOC_I2S
10 tristate
11
12config SND_KIRKWOOD_SOC_OPENRD 9config SND_KIRKWOOD_SOC_OPENRD
13 tristate "SoC Audio support for Kirkwood Openrd Client" 10 tristate "SoC Audio support for Kirkwood Openrd Client"
14 depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE) 11 depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE || COMPILE_TEST)
15 depends on I2C 12 depends on I2C
16 select SND_KIRKWOOD_SOC_I2S
17 select SND_SOC_CS42L51 13 select SND_SOC_CS42L51
18 help 14 help
19 Say Y if you want to add support for SoC audio on 15 Say Y if you want to add support for SoC audio on
@@ -21,8 +17,7 @@ config SND_KIRKWOOD_SOC_OPENRD
21 17
22config SND_KIRKWOOD_SOC_T5325 18config SND_KIRKWOOD_SOC_T5325
23 tristate "SoC Audio support for HP t5325" 19 tristate "SoC Audio support for HP t5325"
24 depends on SND_KIRKWOOD_SOC && MACH_T5325 && I2C 20 depends on SND_KIRKWOOD_SOC && (MACH_T5325 || COMPILE_TEST) && I2C
25 select SND_KIRKWOOD_SOC_I2S
26 select SND_SOC_ALC5623 21 select SND_SOC_ALC5623
27 help 22 help
28 Say Y if you want to add support for SoC audio on 23 Say Y if you want to add support for SoC audio on
diff --git a/sound/soc/kirkwood/Makefile b/sound/soc/kirkwood/Makefile
index 3e62ae9e7bbe..9e781385cb88 100644
--- a/sound/soc/kirkwood/Makefile
+++ b/sound/soc/kirkwood/Makefile
@@ -1,8 +1,6 @@
1snd-soc-kirkwood-objs := kirkwood-dma.o 1snd-soc-kirkwood-objs := kirkwood-dma.o kirkwood-i2s.o
2snd-soc-kirkwood-i2s-objs := kirkwood-i2s.o
3 2
4obj-$(CONFIG_SND_KIRKWOOD_SOC) += snd-soc-kirkwood.o 3obj-$(CONFIG_SND_KIRKWOOD_SOC) += snd-soc-kirkwood.o
5obj-$(CONFIG_SND_KIRKWOOD_SOC_I2S) += snd-soc-kirkwood-i2s.o
6 4
7snd-soc-openrd-objs := kirkwood-openrd.o 5snd-soc-openrd-objs := kirkwood-openrd.o
8snd-soc-t5325-objs := kirkwood-t5325.o 6snd-soc-t5325-objs := kirkwood-t5325.o
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c
index a9f14530c3db..b238434f92b0 100644
--- a/sound/soc/kirkwood/kirkwood-dma.c
+++ b/sound/soc/kirkwood/kirkwood-dma.c
@@ -33,11 +33,11 @@
33 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | \ 33 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | \
34 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE) 34 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE)
35 35
36struct kirkwood_dma_priv { 36static struct kirkwood_dma_data *kirkwood_priv(struct snd_pcm_substream *subs)
37 struct snd_pcm_substream *play_stream; 37{
38 struct snd_pcm_substream *rec_stream; 38 struct snd_soc_pcm_runtime *soc_runtime = subs->private_data;
39 struct kirkwood_dma_data *data; 39 return snd_soc_dai_get_drvdata(soc_runtime->cpu_dai);
40}; 40}
41 41
42static struct snd_pcm_hardware kirkwood_dma_snd_hw = { 42static struct snd_pcm_hardware kirkwood_dma_snd_hw = {
43 .info = (SNDRV_PCM_INFO_INTERLEAVED | 43 .info = (SNDRV_PCM_INFO_INTERLEAVED |
@@ -51,7 +51,7 @@ static struct snd_pcm_hardware kirkwood_dma_snd_hw = {
51 .rate_max = 384000, 51 .rate_max = 384000,
52 .channels_min = 1, 52 .channels_min = 1,
53 .channels_max = 8, 53 .channels_max = 8,
54 .buffer_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES * KIRKWOOD_SND_MAX_PERIODS, 54 .buffer_bytes_max = KIRKWOOD_SND_MAX_BUFFER_BYTES,
55 .period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES, 55 .period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES,
56 .period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES, 56 .period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES,
57 .periods_min = KIRKWOOD_SND_MIN_PERIODS, 57 .periods_min = KIRKWOOD_SND_MIN_PERIODS,
@@ -63,8 +63,7 @@ static u64 kirkwood_dma_dmamask = DMA_BIT_MASK(32);
63 63
64static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id) 64static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id)
65{ 65{
66 struct kirkwood_dma_priv *prdata = dev_id; 66 struct kirkwood_dma_data *priv = dev_id;
67 struct kirkwood_dma_data *priv = prdata->data;
68 unsigned long mask, status, cause; 67 unsigned long mask, status, cause;
69 68
70 mask = readl(priv->io + KIRKWOOD_INT_MASK); 69 mask = readl(priv->io + KIRKWOOD_INT_MASK);
@@ -89,10 +88,10 @@ static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id)
89 writel(status, priv->io + KIRKWOOD_INT_CAUSE); 88 writel(status, priv->io + KIRKWOOD_INT_CAUSE);
90 89
91 if (status & KIRKWOOD_INT_CAUSE_PLAY_BYTES) 90 if (status & KIRKWOOD_INT_CAUSE_PLAY_BYTES)
92 snd_pcm_period_elapsed(prdata->play_stream); 91 snd_pcm_period_elapsed(priv->substream_play);
93 92
94 if (status & KIRKWOOD_INT_CAUSE_REC_BYTES) 93 if (status & KIRKWOOD_INT_CAUSE_REC_BYTES)
95 snd_pcm_period_elapsed(prdata->rec_stream); 94 snd_pcm_period_elapsed(priv->substream_rec);
96 95
97 return IRQ_HANDLED; 96 return IRQ_HANDLED;
98} 97}
@@ -126,15 +125,10 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream)
126{ 125{
127 int err; 126 int err;
128 struct snd_pcm_runtime *runtime = substream->runtime; 127 struct snd_pcm_runtime *runtime = substream->runtime;
129 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 128 struct kirkwood_dma_data *priv = kirkwood_priv(substream);
130 struct snd_soc_platform *platform = soc_runtime->platform;
131 struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
132 struct kirkwood_dma_data *priv;
133 struct kirkwood_dma_priv *prdata = snd_soc_platform_get_drvdata(platform);
134 const struct mbus_dram_target_info *dram; 129 const struct mbus_dram_target_info *dram;
135 unsigned long addr; 130 unsigned long addr;
136 131
137 priv = snd_soc_dai_get_dma_data(cpu_dai, substream);
138 snd_soc_set_runtime_hwparams(substream, &kirkwood_dma_snd_hw); 132 snd_soc_set_runtime_hwparams(substream, &kirkwood_dma_snd_hw);
139 133
140 /* Ensure that all constraints linked to dma burst are fulfilled */ 134 /* Ensure that all constraints linked to dma burst are fulfilled */
@@ -157,21 +151,11 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream)
157 if (err < 0) 151 if (err < 0)
158 return err; 152 return err;
159 153
160 if (prdata == NULL) { 154 if (!priv->substream_play && !priv->substream_rec) {
161 prdata = kzalloc(sizeof(struct kirkwood_dma_priv), GFP_KERNEL);
162 if (prdata == NULL)
163 return -ENOMEM;
164
165 prdata->data = priv;
166
167 err = request_irq(priv->irq, kirkwood_dma_irq, IRQF_SHARED, 155 err = request_irq(priv->irq, kirkwood_dma_irq, IRQF_SHARED,
168 "kirkwood-i2s", prdata); 156 "kirkwood-i2s", priv);
169 if (err) { 157 if (err)
170 kfree(prdata);
171 return -EBUSY; 158 return -EBUSY;
172 }
173
174 snd_soc_platform_set_drvdata(platform, prdata);
175 159
176 /* 160 /*
177 * Enable Error interrupts. We're only ack'ing them but 161 * Enable Error interrupts. We're only ack'ing them but
@@ -183,11 +167,11 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream)
183 dram = mv_mbus_dram_info(); 167 dram = mv_mbus_dram_info();
184 addr = substream->dma_buffer.addr; 168 addr = substream->dma_buffer.addr;
185 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 169 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
186 prdata->play_stream = substream; 170 priv->substream_play = substream;
187 kirkwood_dma_conf_mbus_windows(priv->io, 171 kirkwood_dma_conf_mbus_windows(priv->io,
188 KIRKWOOD_PLAYBACK_WIN, addr, dram); 172 KIRKWOOD_PLAYBACK_WIN, addr, dram);
189 } else { 173 } else {
190 prdata->rec_stream = substream; 174 priv->substream_rec = substream;
191 kirkwood_dma_conf_mbus_windows(priv->io, 175 kirkwood_dma_conf_mbus_windows(priv->io,
192 KIRKWOOD_RECORD_WIN, addr, dram); 176 KIRKWOOD_RECORD_WIN, addr, dram);
193 } 177 }
@@ -197,27 +181,19 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream)
197 181
198static int kirkwood_dma_close(struct snd_pcm_substream *substream) 182static int kirkwood_dma_close(struct snd_pcm_substream *substream)
199{ 183{
200 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 184 struct kirkwood_dma_data *priv = kirkwood_priv(substream);
201 struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
202 struct snd_soc_platform *platform = soc_runtime->platform;
203 struct kirkwood_dma_priv *prdata = snd_soc_platform_get_drvdata(platform);
204 struct kirkwood_dma_data *priv;
205
206 priv = snd_soc_dai_get_dma_data(cpu_dai, substream);
207 185
208 if (!prdata || !priv) 186 if (!priv)
209 return 0; 187 return 0;
210 188
211 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 189 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
212 prdata->play_stream = NULL; 190 priv->substream_play = NULL;
213 else 191 else
214 prdata->rec_stream = NULL; 192 priv->substream_rec = NULL;
215 193
216 if (!prdata->play_stream && !prdata->rec_stream) { 194 if (!priv->substream_play && !priv->substream_rec) {
217 writel(0, priv->io + KIRKWOOD_ERR_MASK); 195 writel(0, priv->io + KIRKWOOD_ERR_MASK);
218 free_irq(priv->irq, prdata); 196 free_irq(priv->irq, priv);
219 kfree(prdata);
220 snd_soc_platform_set_drvdata(platform, NULL);
221 } 197 }
222 198
223 return 0; 199 return 0;
@@ -243,13 +219,9 @@ static int kirkwood_dma_hw_free(struct snd_pcm_substream *substream)
243static int kirkwood_dma_prepare(struct snd_pcm_substream *substream) 219static int kirkwood_dma_prepare(struct snd_pcm_substream *substream)
244{ 220{
245 struct snd_pcm_runtime *runtime = substream->runtime; 221 struct snd_pcm_runtime *runtime = substream->runtime;
246 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 222 struct kirkwood_dma_data *priv = kirkwood_priv(substream);
247 struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
248 struct kirkwood_dma_data *priv;
249 unsigned long size, count; 223 unsigned long size, count;
250 224
251 priv = snd_soc_dai_get_dma_data(cpu_dai, substream);
252
253 /* compute buffer size in term of "words" as requested in specs */ 225 /* compute buffer size in term of "words" as requested in specs */
254 size = frames_to_bytes(runtime, runtime->buffer_size); 226 size = frames_to_bytes(runtime, runtime->buffer_size);
255 size = (size>>2)-1; 227 size = (size>>2)-1;
@@ -272,13 +244,9 @@ static int kirkwood_dma_prepare(struct snd_pcm_substream *substream)
272static snd_pcm_uframes_t kirkwood_dma_pointer(struct snd_pcm_substream 244static snd_pcm_uframes_t kirkwood_dma_pointer(struct snd_pcm_substream
273 *substream) 245 *substream)
274{ 246{
275 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 247 struct kirkwood_dma_data *priv = kirkwood_priv(substream);
276 struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai;
277 struct kirkwood_dma_data *priv;
278 snd_pcm_uframes_t count; 248 snd_pcm_uframes_t count;
279 249
280 priv = snd_soc_dai_get_dma_data(cpu_dai, substream);
281
282 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 250 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
283 count = bytes_to_frames(substream->runtime, 251 count = bytes_to_frames(substream->runtime,
284 readl(priv->io + KIRKWOOD_PLAY_BYTE_COUNT)); 252 readl(priv->io + KIRKWOOD_PLAY_BYTE_COUNT));
@@ -366,36 +334,8 @@ static void kirkwood_dma_free_dma_buffers(struct snd_pcm *pcm)
366 } 334 }
367} 335}
368 336
369static struct snd_soc_platform_driver kirkwood_soc_platform = { 337struct snd_soc_platform_driver kirkwood_soc_platform = {
370 .ops = &kirkwood_dma_ops, 338 .ops = &kirkwood_dma_ops,
371 .pcm_new = kirkwood_dma_new, 339 .pcm_new = kirkwood_dma_new,
372 .pcm_free = kirkwood_dma_free_dma_buffers, 340 .pcm_free = kirkwood_dma_free_dma_buffers,
373}; 341};
374
375static int kirkwood_soc_platform_probe(struct platform_device *pdev)
376{
377 return snd_soc_register_platform(&pdev->dev, &kirkwood_soc_platform);
378}
379
380static int kirkwood_soc_platform_remove(struct platform_device *pdev)
381{
382 snd_soc_unregister_platform(&pdev->dev);
383 return 0;
384}
385
386static struct platform_driver kirkwood_pcm_driver = {
387 .driver = {
388 .name = "kirkwood-pcm-audio",
389 .owner = THIS_MODULE,
390 },
391
392 .probe = kirkwood_soc_platform_probe,
393 .remove = kirkwood_soc_platform_remove,
394};
395
396module_platform_driver(kirkwood_pcm_driver);
397
398MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
399MODULE_DESCRIPTION("Marvell Kirkwood Audio DMA module");
400MODULE_LICENSE("GPL");
401MODULE_ALIAS("platform:kirkwood-pcm-audio");
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index 4c9dad3263c5..7fce340ab3ef 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -22,13 +22,12 @@
22#include <sound/pcm_params.h> 22#include <sound/pcm_params.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <linux/platform_data/asoc-kirkwood.h> 24#include <linux/platform_data/asoc-kirkwood.h>
25#include <linux/of.h>
26
25#include "kirkwood.h" 27#include "kirkwood.h"
26 28
27#define DRV_NAME "kirkwood-i2s" 29#define DRV_NAME "mvebu-audio"
28 30
29#define KIRKWOOD_I2S_RATES \
30 (SNDRV_PCM_RATE_44100 | \
31 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
32#define KIRKWOOD_I2S_FORMATS \ 31#define KIRKWOOD_I2S_FORMATS \
33 (SNDRV_PCM_FMTBIT_S16_LE | \ 32 (SNDRV_PCM_FMTBIT_S16_LE | \
34 SNDRV_PCM_FMTBIT_S24_LE | \ 33 SNDRV_PCM_FMTBIT_S24_LE | \
@@ -105,14 +104,16 @@ static void kirkwood_set_rate(struct snd_soc_dai *dai,
105 uint32_t clks_ctrl; 104 uint32_t clks_ctrl;
106 105
107 if (rate == 44100 || rate == 48000 || rate == 96000) { 106 if (rate == 44100 || rate == 48000 || rate == 96000) {
108 /* use internal dco for supported rates */ 107 /* use internal dco for the supported rates
108 * defined in kirkwood_i2s_dai */
109 dev_dbg(dai->dev, "%s: dco set rate = %lu\n", 109 dev_dbg(dai->dev, "%s: dco set rate = %lu\n",
110 __func__, rate); 110 __func__, rate);
111 kirkwood_set_dco(priv->io, rate); 111 kirkwood_set_dco(priv->io, rate);
112 112
113 clks_ctrl = KIRKWOOD_MCLK_SOURCE_DCO; 113 clks_ctrl = KIRKWOOD_MCLK_SOURCE_DCO;
114 } else if (!IS_ERR(priv->extclk)) { 114 } else {
115 /* use optional external clk for other rates */ 115 /* use the external clock for the other rates
116 * defined in kirkwood_i2s_dai_extclk */
116 dev_dbg(dai->dev, "%s: extclk set rate = %lu -> %lu\n", 117 dev_dbg(dai->dev, "%s: extclk set rate = %lu -> %lu\n",
117 __func__, rate, 256 * rate); 118 __func__, rate, 256 * rate);
118 clk_set_rate(priv->extclk, 256 * rate); 119 clk_set_rate(priv->extclk, 256 * rate);
@@ -199,8 +200,7 @@ static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream,
199 ctl_play |= KIRKWOOD_PLAYCTL_MONO_OFF; 200 ctl_play |= KIRKWOOD_PLAYCTL_MONO_OFF;
200 201
201 priv->ctl_play &= ~(KIRKWOOD_PLAYCTL_MONO_MASK | 202 priv->ctl_play &= ~(KIRKWOOD_PLAYCTL_MONO_MASK |
202 KIRKWOOD_PLAYCTL_I2S_EN | 203 KIRKWOOD_PLAYCTL_ENABLE_MASK |
203 KIRKWOOD_PLAYCTL_SPDIF_EN |
204 KIRKWOOD_PLAYCTL_SIZE_MASK); 204 KIRKWOOD_PLAYCTL_SIZE_MASK);
205 priv->ctl_play |= ctl_play; 205 priv->ctl_play |= ctl_play;
206 } else { 206 } else {
@@ -244,8 +244,7 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
244 case SNDRV_PCM_TRIGGER_START: 244 case SNDRV_PCM_TRIGGER_START:
245 /* configure */ 245 /* configure */
246 ctl = priv->ctl_play; 246 ctl = priv->ctl_play;
247 value = ctl & ~(KIRKWOOD_PLAYCTL_I2S_EN | 247 value = ctl & ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
248 KIRKWOOD_PLAYCTL_SPDIF_EN);
249 writel(value, priv->io + KIRKWOOD_PLAYCTL); 248 writel(value, priv->io + KIRKWOOD_PLAYCTL);
250 249
251 /* enable interrupts */ 250 /* enable interrupts */
@@ -267,7 +266,7 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
267 writel(value, priv->io + KIRKWOOD_INT_MASK); 266 writel(value, priv->io + KIRKWOOD_INT_MASK);
268 267
269 /* disable all playbacks */ 268 /* disable all playbacks */
270 ctl &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN); 269 ctl &= ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
271 writel(ctl, priv->io + KIRKWOOD_PLAYCTL); 270 writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
272 break; 271 break;
273 272
@@ -387,7 +386,7 @@ static int kirkwood_i2s_probe(struct snd_soc_dai *dai)
387 386
388 /* disable playback/record */ 387 /* disable playback/record */
389 value = readl(priv->io + KIRKWOOD_PLAYCTL); 388 value = readl(priv->io + KIRKWOOD_PLAYCTL);
390 value &= ~(KIRKWOOD_PLAYCTL_I2S_EN|KIRKWOOD_PLAYCTL_SPDIF_EN); 389 value &= ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
391 writel(value, priv->io + KIRKWOOD_PLAYCTL); 390 writel(value, priv->io + KIRKWOOD_PLAYCTL);
392 391
393 value = readl(priv->io + KIRKWOOD_RECCTL); 392 value = readl(priv->io + KIRKWOOD_RECCTL);
@@ -398,11 +397,6 @@ static int kirkwood_i2s_probe(struct snd_soc_dai *dai)
398 397
399} 398}
400 399
401static int kirkwood_i2s_remove(struct snd_soc_dai *dai)
402{
403 return 0;
404}
405
406static const struct snd_soc_dai_ops kirkwood_i2s_dai_ops = { 400static const struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {
407 .startup = kirkwood_i2s_startup, 401 .startup = kirkwood_i2s_startup,
408 .trigger = kirkwood_i2s_trigger, 402 .trigger = kirkwood_i2s_trigger,
@@ -413,17 +407,18 @@ static const struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {
413 407
414static struct snd_soc_dai_driver kirkwood_i2s_dai = { 408static struct snd_soc_dai_driver kirkwood_i2s_dai = {
415 .probe = kirkwood_i2s_probe, 409 .probe = kirkwood_i2s_probe,
416 .remove = kirkwood_i2s_remove,
417 .playback = { 410 .playback = {
418 .channels_min = 1, 411 .channels_min = 1,
419 .channels_max = 2, 412 .channels_max = 2,
420 .rates = KIRKWOOD_I2S_RATES, 413 .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
414 SNDRV_PCM_RATE_96000,
421 .formats = KIRKWOOD_I2S_FORMATS, 415 .formats = KIRKWOOD_I2S_FORMATS,
422 }, 416 },
423 .capture = { 417 .capture = {
424 .channels_min = 1, 418 .channels_min = 1,
425 .channels_max = 2, 419 .channels_max = 2,
426 .rates = KIRKWOOD_I2S_RATES, 420 .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
421 SNDRV_PCM_RATE_96000,
427 .formats = KIRKWOOD_I2S_FORMATS, 422 .formats = KIRKWOOD_I2S_FORMATS,
428 }, 423 },
429 .ops = &kirkwood_i2s_dai_ops, 424 .ops = &kirkwood_i2s_dai_ops,
@@ -431,7 +426,6 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai = {
431 426
432static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk = { 427static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk = {
433 .probe = kirkwood_i2s_probe, 428 .probe = kirkwood_i2s_probe,
434 .remove = kirkwood_i2s_remove,
435 .playback = { 429 .playback = {
436 .channels_min = 1, 430 .channels_min = 1,
437 .channels_max = 2, 431 .channels_max = 2,
@@ -461,6 +455,7 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
461 struct snd_soc_dai_driver *soc_dai = &kirkwood_i2s_dai; 455 struct snd_soc_dai_driver *soc_dai = &kirkwood_i2s_dai;
462 struct kirkwood_dma_data *priv; 456 struct kirkwood_dma_data *priv;
463 struct resource *mem; 457 struct resource *mem;
458 struct device_node *np = pdev->dev.of_node;
464 int err; 459 int err;
465 460
466 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 461 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
@@ -481,14 +476,16 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
481 return -ENXIO; 476 return -ENXIO;
482 } 477 }
483 478
484 if (!data) { 479 if (np) {
485 dev_err(&pdev->dev, "no platform data ?!\n"); 480 priv->burst = 128; /* might be 32 or 128 */
481 } else if (data) {
482 priv->burst = data->burst;
483 } else {
484 dev_err(&pdev->dev, "no DT nor platform data ?!\n");
486 return -EINVAL; 485 return -EINVAL;
487 } 486 }
488 487
489 priv->burst = data->burst; 488 priv->clk = devm_clk_get(&pdev->dev, np ? "internal" : NULL);
490
491 priv->clk = devm_clk_get(&pdev->dev, NULL);
492 if (IS_ERR(priv->clk)) { 489 if (IS_ERR(priv->clk)) {
493 dev_err(&pdev->dev, "no clock\n"); 490 dev_err(&pdev->dev, "no clock\n");
494 return PTR_ERR(priv->clk); 491 return PTR_ERR(priv->clk);
@@ -498,10 +495,10 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
498 if (err < 0) 495 if (err < 0)
499 return err; 496 return err;
500 497
501 priv->extclk = clk_get(&pdev->dev, "extclk"); 498 priv->extclk = devm_clk_get(&pdev->dev, "extclk");
502 if (!IS_ERR(priv->extclk)) { 499 if (!IS_ERR(priv->extclk)) {
503 if (priv->extclk == priv->clk) { 500 if (priv->extclk == priv->clk) {
504 clk_put(priv->extclk); 501 devm_clk_put(&pdev->dev, priv->extclk);
505 priv->extclk = ERR_PTR(-EINVAL); 502 priv->extclk = ERR_PTR(-EINVAL);
506 } else { 503 } else {
507 dev_info(&pdev->dev, "found external clock\n"); 504 dev_info(&pdev->dev, "found external clock\n");
@@ -515,7 +512,7 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
515 priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24; 512 priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24;
516 513
517 /* Select the burst size */ 514 /* Select the burst size */
518 if (data->burst == 32) { 515 if (priv->burst == 32) {
519 priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32; 516 priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32;
520 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32; 517 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32;
521 } else { 518 } else {
@@ -525,14 +522,22 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
525 522
526 err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component, 523 err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component,
527 soc_dai, 1); 524 soc_dai, 1);
528 if (!err) 525 if (err) {
529 return 0; 526 dev_err(&pdev->dev, "snd_soc_register_component failed\n");
530 dev_err(&pdev->dev, "snd_soc_register_component failed\n"); 527 goto err_component;
528 }
531 529
532 if (!IS_ERR(priv->extclk)) { 530 err = snd_soc_register_platform(&pdev->dev, &kirkwood_soc_platform);
533 clk_disable_unprepare(priv->extclk); 531 if (err) {
534 clk_put(priv->extclk); 532 dev_err(&pdev->dev, "snd_soc_register_platform failed\n");
533 goto err_platform;
535 } 534 }
535 return 0;
536 err_platform:
537 snd_soc_unregister_component(&pdev->dev);
538 err_component:
539 if (!IS_ERR(priv->extclk))
540 clk_disable_unprepare(priv->extclk);
536 clk_disable_unprepare(priv->clk); 541 clk_disable_unprepare(priv->clk);
537 542
538 return err; 543 return err;
@@ -542,23 +547,31 @@ static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
542{ 547{
543 struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev); 548 struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev);
544 549
550 snd_soc_unregister_platform(&pdev->dev);
545 snd_soc_unregister_component(&pdev->dev); 551 snd_soc_unregister_component(&pdev->dev);
546 552
547 if (!IS_ERR(priv->extclk)) { 553 if (!IS_ERR(priv->extclk))
548 clk_disable_unprepare(priv->extclk); 554 clk_disable_unprepare(priv->extclk);
549 clk_put(priv->extclk);
550 }
551 clk_disable_unprepare(priv->clk); 555 clk_disable_unprepare(priv->clk);
552 556
553 return 0; 557 return 0;
554} 558}
555 559
560#ifdef CONFIG_OF
561static struct of_device_id mvebu_audio_of_match[] = {
562 { .compatible = "marvell,mvebu-audio" },
563 { }
564};
565MODULE_DEVICE_TABLE(of, mvebu_audio_of_match);
566#endif
567
556static struct platform_driver kirkwood_i2s_driver = { 568static struct platform_driver kirkwood_i2s_driver = {
557 .probe = kirkwood_i2s_dev_probe, 569 .probe = kirkwood_i2s_dev_probe,
558 .remove = kirkwood_i2s_dev_remove, 570 .remove = kirkwood_i2s_dev_remove,
559 .driver = { 571 .driver = {
560 .name = DRV_NAME, 572 .name = DRV_NAME,
561 .owner = THIS_MODULE, 573 .owner = THIS_MODULE,
574 .of_match_table = of_match_ptr(mvebu_audio_of_match),
562 }, 575 },
563}; 576};
564 577
@@ -568,4 +581,4 @@ module_platform_driver(kirkwood_i2s_driver);
568MODULE_AUTHOR("Arnaud Patard, <arnaud.patard@rtp-net.org>"); 581MODULE_AUTHOR("Arnaud Patard, <arnaud.patard@rtp-net.org>");
569MODULE_DESCRIPTION("Kirkwood I2S SoC Interface"); 582MODULE_DESCRIPTION("Kirkwood I2S SoC Interface");
570MODULE_LICENSE("GPL"); 583MODULE_LICENSE("GPL");
571MODULE_ALIAS("platform:kirkwood-i2s"); 584MODULE_ALIAS("platform:mvebu-audio");
diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c
index b979c7154715..025be0e97164 100644
--- a/sound/soc/kirkwood/kirkwood-openrd.c
+++ b/sound/soc/kirkwood/kirkwood-openrd.c
@@ -16,9 +16,7 @@
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
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>
20#include <linux/platform_data/asoc-kirkwood.h> 19#include <linux/platform_data/asoc-kirkwood.h>
21#include <asm/mach-types.h>
22#include "../codecs/cs42l51.h" 20#include "../codecs/cs42l51.h"
23 21
24static int openrd_client_hw_params(struct snd_pcm_substream *substream, 22static int openrd_client_hw_params(struct snd_pcm_substream *substream,
@@ -54,8 +52,8 @@ static struct snd_soc_dai_link openrd_client_dai[] = {
54{ 52{
55 .name = "CS42L51", 53 .name = "CS42L51",
56 .stream_name = "CS42L51 HiFi", 54 .stream_name = "CS42L51 HiFi",
57 .cpu_dai_name = "kirkwood-i2s", 55 .cpu_dai_name = "mvebu-audio",
58 .platform_name = "kirkwood-pcm-audio", 56 .platform_name = "mvebu-audio",
59 .codec_dai_name = "cs42l51-hifi", 57 .codec_dai_name = "cs42l51-hifi",
60 .codec_name = "cs42l51-codec.0-004a", 58 .codec_name = "cs42l51-codec.0-004a",
61 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, 59 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS,
diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c
index 1d0ed6f8add7..27545b0c4856 100644
--- a/sound/soc/kirkwood/kirkwood-t5325.c
+++ b/sound/soc/kirkwood/kirkwood-t5325.c
@@ -15,9 +15,7 @@
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
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>
19#include <linux/platform_data/asoc-kirkwood.h> 18#include <linux/platform_data/asoc-kirkwood.h>
20#include <asm/mach-types.h>
21#include "../codecs/alc5623.h" 19#include "../codecs/alc5623.h"
22 20
23static int t5325_hw_params(struct snd_pcm_substream *substream, 21static int t5325_hw_params(struct snd_pcm_substream *substream,
@@ -70,8 +68,8 @@ static struct snd_soc_dai_link t5325_dai[] = {
70{ 68{
71 .name = "ALC5621", 69 .name = "ALC5621",
72 .stream_name = "ALC5621 HiFi", 70 .stream_name = "ALC5621 HiFi",
73 .cpu_dai_name = "kirkwood-i2s", 71 .cpu_dai_name = "mvebu-audio",
74 .platform_name = "kirkwood-pcm-audio", 72 .platform_name = "mvebu-audio",
75 .codec_dai_name = "alc5621-hifi", 73 .codec_dai_name = "alc5621-hifi",
76 .codec_name = "alc562x-codec.0-001a", 74 .codec_name = "alc562x-codec.0-001a",
77 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, 75 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS,
diff --git a/sound/soc/kirkwood/kirkwood.h b/sound/soc/kirkwood/kirkwood.h
index 4d92637ddb3f..f8e1ccc1c58c 100644
--- a/sound/soc/kirkwood/kirkwood.h
+++ b/sound/soc/kirkwood/kirkwood.h
@@ -54,7 +54,7 @@
54#define KIRKWOOD_PLAYCTL_MONO_OFF (0<<5) 54#define KIRKWOOD_PLAYCTL_MONO_OFF (0<<5)
55#define KIRKWOOD_PLAYCTL_I2S_MUTE (1<<7) 55#define KIRKWOOD_PLAYCTL_I2S_MUTE (1<<7)
56#define KIRKWOOD_PLAYCTL_SPDIF_EN (1<<4) 56#define KIRKWOOD_PLAYCTL_SPDIF_EN (1<<4)
57#define KIRKWOOD_PLAYCTL_I2S_EN (1<<3) 57#define KIRKWOOD_PLAYCTL_I2S_EN (1<<3)
58#define KIRKWOOD_PLAYCTL_SIZE_MASK (7<<0) 58#define KIRKWOOD_PLAYCTL_SIZE_MASK (7<<0)
59#define KIRKWOOD_PLAYCTL_SIZE_16 (7<<0) 59#define KIRKWOOD_PLAYCTL_SIZE_16 (7<<0)
60#define KIRKWOOD_PLAYCTL_SIZE_16_C (3<<0) 60#define KIRKWOOD_PLAYCTL_SIZE_16_C (3<<0)
@@ -62,6 +62,9 @@
62#define KIRKWOOD_PLAYCTL_SIZE_24 (1<<0) 62#define KIRKWOOD_PLAYCTL_SIZE_24 (1<<0)
63#define KIRKWOOD_PLAYCTL_SIZE_32 (0<<0) 63#define KIRKWOOD_PLAYCTL_SIZE_32 (0<<0)
64 64
65#define KIRKWOOD_PLAYCTL_ENABLE_MASK (KIRKWOOD_PLAYCTL_SPDIF_EN | \
66 KIRKWOOD_PLAYCTL_I2S_EN)
67
65#define KIRKWOOD_PLAY_BUF_ADDR 0x1104 68#define KIRKWOOD_PLAY_BUF_ADDR 0x1104
66#define KIRKWOOD_PLAY_BUF_SIZE 0x1108 69#define KIRKWOOD_PLAY_BUF_SIZE 0x1108
67#define KIRKWOOD_PLAY_BYTE_COUNT 0x110C 70#define KIRKWOOD_PLAY_BYTE_COUNT 0x110C
@@ -122,6 +125,8 @@
122#define KIRKWOOD_SND_MAX_PERIODS 16 125#define KIRKWOOD_SND_MAX_PERIODS 16
123#define KIRKWOOD_SND_MIN_PERIOD_BYTES 0x4000 126#define KIRKWOOD_SND_MIN_PERIOD_BYTES 0x4000
124#define KIRKWOOD_SND_MAX_PERIOD_BYTES 0x4000 127#define KIRKWOOD_SND_MAX_PERIOD_BYTES 0x4000
128#define KIRKWOOD_SND_MAX_BUFFER_BYTES (KIRKWOOD_SND_MAX_PERIOD_BYTES \
129 * KIRKWOOD_SND_MAX_PERIODS)
125 130
126struct kirkwood_dma_data { 131struct kirkwood_dma_data {
127 void __iomem *io; 132 void __iomem *io;
@@ -129,8 +134,12 @@ struct kirkwood_dma_data {
129 struct clk *extclk; 134 struct clk *extclk;
130 uint32_t ctl_play; 135 uint32_t ctl_play;
131 uint32_t ctl_rec; 136 uint32_t ctl_rec;
137 struct snd_pcm_substream *substream_play;
138 struct snd_pcm_substream *substream_rec;
132 int irq; 139 int irq;
133 int burst; 140 int burst;
134}; 141};
135 142
143extern struct snd_soc_platform_driver kirkwood_soc_platform;
144
136#endif 145#endif
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig
index 78d321cbe8b4..219235c02212 100644
--- a/sound/soc/mxs/Kconfig
+++ b/sound/soc/mxs/Kconfig
@@ -1,6 +1,7 @@
1menuconfig SND_MXS_SOC 1menuconfig SND_MXS_SOC
2 tristate "SoC Audio for Freescale MXS CPUs" 2 tristate "SoC Audio for Freescale MXS CPUs"
3 depends on ARCH_MXS 3 depends on ARCH_MXS || COMPILE_TEST
4 depends on COMMON_CLK
4 select SND_SOC_GENERIC_DMAENGINE_PCM 5 select SND_SOC_GENERIC_DMAENGINE_PCM
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
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index 54511c5e6a7c..b56b8a0e8deb 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -31,7 +31,6 @@
31#include <sound/pcm.h> 31#include <sound/pcm.h>
32#include <sound/pcm_params.h> 32#include <sound/pcm_params.h>
33#include <sound/soc.h> 33#include <sound/soc.h>
34#include <asm/mach-types.h>
35 34
36#include "mxs-saif.h" 35#include "mxs-saif.h"
37 36
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
index 1b134d72f120..4bb273786ff3 100644
--- a/sound/soc/mxs/mxs-sgtl5000.c
+++ b/sound/soc/mxs/mxs-sgtl5000.c
@@ -25,7 +25,6 @@
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/jack.h> 26#include <sound/jack.h>
27#include <sound/soc-dapm.h> 27#include <sound/soc-dapm.h>
28#include <asm/mach-types.h>
29 28
30#include "../codecs/sgtl5000.h" 29#include "../codecs/sgtl5000.h"
31#include "mxs-saif.h" 30#include "mxs-saif.h"
@@ -51,18 +50,27 @@ static int mxs_sgtl5000_hw_params(struct snd_pcm_substream *substream,
51 } 50 }
52 51
53 /* Sgtl5000 sysclk should be >= 8MHz and <= 27M */ 52 /* Sgtl5000 sysclk should be >= 8MHz and <= 27M */
54 if (mclk < 8000000 || mclk > 27000000) 53 if (mclk < 8000000 || mclk > 27000000) {
54 dev_err(codec_dai->dev, "Invalid mclk frequency: %u.%03uMHz\n",
55 mclk / 1000000, mclk / 1000 % 1000);
55 return -EINVAL; 56 return -EINVAL;
57 }
56 58
57 /* Set SGTL5000's SYSCLK (provided by SAIF MCLK) */ 59 /* Set SGTL5000's SYSCLK (provided by SAIF MCLK) */
58 ret = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, mclk, 0); 60 ret = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, mclk, 0);
59 if (ret) 61 if (ret) {
62 dev_err(codec_dai->dev, "Failed to set sysclk to %u.%03uMHz\n",
63 mclk / 1000000, mclk / 1000 % 1000);
60 return ret; 64 return ret;
65 }
61 66
62 /* The SAIF MCLK should be the same as SGTL5000_SYSCLK */ 67 /* The SAIF MCLK should be the same as SGTL5000_SYSCLK */
63 ret = snd_soc_dai_set_sysclk(cpu_dai, MXS_SAIF_MCLK, mclk, 0); 68 ret = snd_soc_dai_set_sysclk(cpu_dai, MXS_SAIF_MCLK, mclk, 0);
64 if (ret) 69 if (ret) {
70 dev_err(cpu_dai->dev, "Failed to set sysclk to %u.%03uMHz\n",
71 mclk / 1000000, mclk / 1000 % 1000);
65 return ret; 72 return ret;
73 }
66 74
67 /* set codec to slave mode */ 75 /* set codec to slave mode */
68 dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 76 dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
@@ -70,13 +78,19 @@ static int mxs_sgtl5000_hw_params(struct snd_pcm_substream *substream,
70 78
71 /* set codec DAI configuration */ 79 /* set codec DAI configuration */
72 ret = snd_soc_dai_set_fmt(codec_dai, dai_format); 80 ret = snd_soc_dai_set_fmt(codec_dai, dai_format);
73 if (ret) 81 if (ret) {
82 dev_err(codec_dai->dev, "Failed to set dai format to %08x\n",
83 dai_format);
74 return ret; 84 return ret;
85 }
75 86
76 /* set cpu DAI configuration */ 87 /* set cpu DAI configuration */
77 ret = snd_soc_dai_set_fmt(cpu_dai, dai_format); 88 ret = snd_soc_dai_set_fmt(cpu_dai, dai_format);
78 if (ret) 89 if (ret) {
90 dev_err(cpu_dai->dev, "Failed to set dai format to %08x\n",
91 dai_format);
79 return ret; 92 return ret;
93 }
80 94
81 return 0; 95 return 0;
82} 96}
@@ -91,11 +105,13 @@ static struct snd_soc_dai_link mxs_sgtl5000_dai[] = {
91 .stream_name = "HiFi Playback", 105 .stream_name = "HiFi Playback",
92 .codec_dai_name = "sgtl5000", 106 .codec_dai_name = "sgtl5000",
93 .ops = &mxs_sgtl5000_hifi_ops, 107 .ops = &mxs_sgtl5000_hifi_ops,
108 .playback_only = true,
94 }, { 109 }, {
95 .name = "HiFi Rx", 110 .name = "HiFi Rx",
96 .stream_name = "HiFi Capture", 111 .stream_name = "HiFi Capture",
97 .codec_dai_name = "sgtl5000", 112 .codec_dai_name = "sgtl5000",
98 .ops = &mxs_sgtl5000_hifi_ops, 113 .ops = &mxs_sgtl5000_hifi_ops,
114 .capture_only = true,
99 }, 115 },
100}; 116};
101 117
@@ -154,8 +170,10 @@ static int mxs_sgtl5000_probe(struct platform_device *pdev)
154 * should be >= 8MHz and <= 27M. 170 * should be >= 8MHz and <= 27M.
155 */ 171 */
156 ret = mxs_saif_get_mclk(0, 44100 * 256, 44100); 172 ret = mxs_saif_get_mclk(0, 44100 * 256, 44100);
157 if (ret) 173 if (ret) {
174 dev_err(&pdev->dev, "failed to get mclk\n");
158 return ret; 175 return ret;
176 }
159 177
160 card->dev = &pdev->dev; 178 card->dev = &pdev->dev;
161 platform_set_drvdata(pdev, card); 179 platform_set_drvdata(pdev, card);
diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c
index f4c2417a8730..8987bf987e58 100644
--- a/sound/soc/nuc900/nuc900-ac97.c
+++ b/sound/soc/nuc900/nuc900-ac97.c
@@ -333,9 +333,6 @@ static int nuc900_ac97_drvprobe(struct platform_device *pdev)
333 spin_lock_init(&nuc900_audio->lock); 333 spin_lock_init(&nuc900_audio->lock);
334 334
335 nuc900_audio->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 335 nuc900_audio->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
336 if (!nuc900_audio->res)
337 return ret;
338
339 nuc900_audio->mmio = devm_ioremap_resource(&pdev->dev, 336 nuc900_audio->mmio = devm_ioremap_resource(&pdev->dev,
340 nuc900_audio->res); 337 nuc900_audio->res);
341 if (IS_ERR(nuc900_audio->mmio)) 338 if (IS_ERR(nuc900_audio->mmio))
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 9f5d55e6b17a..daa78a0095fa 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -1,7 +1,7 @@
1config SND_OMAP_SOC 1config SND_OMAP_SOC
2 tristate "SoC Audio for the Texas Instruments OMAP chips" 2 tristate "SoC Audio for the Texas Instruments OMAP chips"
3 depends on ARCH_OMAP && DMA_OMAP 3 depends on (ARCH_OMAP && DMA_OMAP) || (ARCH_ARM && COMPILE_TEST)
4 select SND_SOC_DMAENGINE_PCM 4 select SND_DMAENGINE_PCM
5 5
6config SND_OMAP_SOC_DMIC 6config SND_OMAP_SOC_DMIC
7 tristate 7 tristate
@@ -26,7 +26,7 @@ config SND_OMAP_SOC_N810
26 26
27config SND_OMAP_SOC_RX51 27config SND_OMAP_SOC_RX51
28 tristate "SoC Audio support for Nokia RX-51" 28 tristate "SoC Audio support for Nokia RX-51"
29 depends on SND_OMAP_SOC && MACH_NOKIA_RX51 29 depends on SND_OMAP_SOC && ARCH_ARM && (MACH_NOKIA_RX51 || COMPILE_TEST)
30 select SND_OMAP_SOC_MCBSP 30 select SND_OMAP_SOC_MCBSP
31 select SND_SOC_TLV320AIC3X 31 select SND_SOC_TLV320AIC3X
32 select SND_SOC_TPA6130A2 32 select SND_SOC_TPA6130A2
@@ -87,7 +87,7 @@ config SND_OMAP_SOC_OMAP_TWL4030
87 87
88config SND_OMAP_SOC_OMAP_ABE_TWL6040 88config SND_OMAP_SOC_OMAP_ABE_TWL6040
89 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" 89 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
90 depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4 90 depends on TWL6040_CORE && SND_OMAP_SOC && (ARCH_OMAP4 || COMPILE_TEST)
91 select SND_OMAP_SOC_DMIC 91 select SND_OMAP_SOC_DMIC
92 select SND_OMAP_SOC_MCPDM 92 select SND_OMAP_SOC_MCPDM
93 select SND_SOC_TWL6040 93 select SND_SOC_TWL6040
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c
index 361e4c03646e..83433fdea32a 100644
--- a/sound/soc/omap/mcbsp.c
+++ b/sound/soc/omap/mcbsp.c
@@ -781,7 +781,7 @@ static ssize_t prop##_store(struct device *dev, \
781 unsigned long val; \ 781 unsigned long val; \
782 int status; \ 782 int status; \
783 \ 783 \
784 status = strict_strtoul(buf, 0, &val); \ 784 status = kstrtoul(buf, 0, &val); \
785 if (status) \ 785 if (status) \
786 return status; \ 786 return status; \
787 \ 787 \
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
index 70cd5c7b2e14..ebb13906b3a0 100644
--- a/sound/soc/omap/omap-abe-twl6040.c
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -23,7 +23,6 @@
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/mfd/twl6040.h> 25#include <linux/mfd/twl6040.h>
26#include <linux/platform_data/omap-abe-twl6040.h>
27#include <linux/module.h> 26#include <linux/module.h>
28#include <linux/of.h> 27#include <linux/of.h>
29 28
@@ -166,19 +165,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
166 {"AFMR", NULL, "Line In"}, 165 {"AFMR", NULL, "Line In"},
167}; 166};
168 167
169static inline void twl6040_disconnect_pin(struct snd_soc_dapm_context *dapm,
170 int connected, char *pin)
171{
172 if (!connected)
173 snd_soc_dapm_disable_pin(dapm, pin);
174}
175
176static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd) 168static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
177{ 169{
178 struct snd_soc_codec *codec = rtd->codec; 170 struct snd_soc_codec *codec = rtd->codec;
179 struct snd_soc_card *card = codec->card; 171 struct snd_soc_card *card = codec->card;
180 struct snd_soc_dapm_context *dapm = &codec->dapm;
181 struct omap_abe_twl6040_data *pdata = dev_get_platdata(card->dev);
182 struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card); 172 struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card);
183 int hs_trim; 173 int hs_trim;
184 int ret = 0; 174 int ret = 0;
@@ -203,24 +193,6 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
203 twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); 193 twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
204 } 194 }
205 195
206 /*
207 * NULL pdata means we booted with DT. In this case the routing is
208 * provided and the card is fully routed, no need to mark pins.
209 */
210 if (!pdata)
211 return ret;
212
213 /* Disable not connected paths if not used */
214 twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone");
215 twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk");
216 twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk");
217 twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out");
218 twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vibrator");
219 twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic");
220 twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic");
221 twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic");
222 twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In");
223
224 return ret; 196 return ret;
225} 197}
226 198
@@ -274,13 +246,18 @@ static struct snd_soc_card omap_abe_card = {
274 246
275static int omap_abe_probe(struct platform_device *pdev) 247static int omap_abe_probe(struct platform_device *pdev)
276{ 248{
277 struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev);
278 struct device_node *node = pdev->dev.of_node; 249 struct device_node *node = pdev->dev.of_node;
279 struct snd_soc_card *card = &omap_abe_card; 250 struct snd_soc_card *card = &omap_abe_card;
251 struct device_node *dai_node;
280 struct abe_twl6040 *priv; 252 struct abe_twl6040 *priv;
281 int num_links = 0; 253 int num_links = 0;
282 int ret = 0; 254 int ret = 0;
283 255
256 if (!node) {
257 dev_err(&pdev->dev, "of node is missing.\n");
258 return -ENODEV;
259 }
260
284 card->dev = &pdev->dev; 261 card->dev = &pdev->dev;
285 262
286 priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL); 263 priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL);
@@ -289,78 +266,50 @@ static int omap_abe_probe(struct platform_device *pdev)
289 266
290 priv->dmic_codec_dev = ERR_PTR(-EINVAL); 267 priv->dmic_codec_dev = ERR_PTR(-EINVAL);
291 268
292 if (node) { 269 if (snd_soc_of_parse_card_name(card, "ti,model")) {
293 struct device_node *dai_node; 270 dev_err(&pdev->dev, "Card name is not provided\n");
294 271 return -ENODEV;
295 if (snd_soc_of_parse_card_name(card, "ti,model")) { 272 }
296 dev_err(&pdev->dev, "Card name is not provided\n");
297 return -ENODEV;
298 }
299 273
300 ret = snd_soc_of_parse_audio_routing(card, 274 ret = snd_soc_of_parse_audio_routing(card, "ti,audio-routing");
301 "ti,audio-routing"); 275 if (ret) {
302 if (ret) { 276 dev_err(&pdev->dev, "Error while parsing DAPM routing\n");
303 dev_err(&pdev->dev, 277 return ret;
304 "Error while parsing DAPM routing\n"); 278 }
305 return ret;
306 }
307 279
308 dai_node = of_parse_phandle(node, "ti,mcpdm", 0); 280 dai_node = of_parse_phandle(node, "ti,mcpdm", 0);
309 if (!dai_node) { 281 if (!dai_node) {
310 dev_err(&pdev->dev, "McPDM node is not provided\n"); 282 dev_err(&pdev->dev, "McPDM node is not provided\n");
311 return -EINVAL; 283 return -EINVAL;
312 } 284 }
313 abe_twl6040_dai_links[0].cpu_dai_name = NULL; 285 abe_twl6040_dai_links[0].cpu_dai_name = NULL;
314 abe_twl6040_dai_links[0].cpu_of_node = dai_node; 286 abe_twl6040_dai_links[0].cpu_of_node = dai_node;
315 287
316 dai_node = of_parse_phandle(node, "ti,dmic", 0); 288 dai_node = of_parse_phandle(node, "ti,dmic", 0);
317 if (dai_node) { 289 if (dai_node) {
318 num_links = 2; 290 num_links = 2;
319 abe_twl6040_dai_links[1].cpu_dai_name = NULL; 291 abe_twl6040_dai_links[1].cpu_dai_name = NULL;
320 abe_twl6040_dai_links[1].cpu_of_node = dai_node; 292 abe_twl6040_dai_links[1].cpu_of_node = dai_node;
321 293
322 priv->dmic_codec_dev = platform_device_register_simple( 294 priv->dmic_codec_dev = platform_device_register_simple(
323 "dmic-codec", -1, NULL, 0); 295 "dmic-codec", -1, NULL, 0);
324 if (IS_ERR(priv->dmic_codec_dev)) { 296 if (IS_ERR(priv->dmic_codec_dev)) {
325 dev_err(&pdev->dev, 297 dev_err(&pdev->dev, "Can't instantiate dmic-codec\n");
326 "Can't instantiate dmic-codec\n"); 298 return PTR_ERR(priv->dmic_codec_dev);
327 return PTR_ERR(priv->dmic_codec_dev);
328 }
329 } else {
330 num_links = 1;
331 }
332
333 priv->jack_detection = of_property_read_bool(node,
334 "ti,jack-detection");
335 of_property_read_u32(node, "ti,mclk-freq",
336 &priv->mclk_freq);
337 if (!priv->mclk_freq) {
338 dev_err(&pdev->dev, "MCLK frequency not provided\n");
339 ret = -EINVAL;
340 goto err_unregister;
341 } 299 }
342
343 omap_abe_card.fully_routed = 1;
344 } else if (pdata) {
345 if (pdata->card_name) {
346 card->name = pdata->card_name;
347 } else {
348 dev_err(&pdev->dev, "Card name is not provided\n");
349 return -ENODEV;
350 }
351
352 if (pdata->has_dmic)
353 num_links = 2;
354 else
355 num_links = 1;
356
357 priv->jack_detection = pdata->jack_detection;
358 priv->mclk_freq = pdata->mclk_freq;
359 } else { 300 } else {
360 dev_err(&pdev->dev, "Missing pdata\n"); 301 num_links = 1;
361 return -ENODEV; 302 }
303
304 priv->jack_detection = of_property_read_bool(node, "ti,jack-detection");
305 of_property_read_u32(node, "ti,mclk-freq", &priv->mclk_freq);
306 if (!priv->mclk_freq) {
307 dev_err(&pdev->dev, "MCLK frequency not provided\n");
308 ret = -EINVAL;
309 goto err_unregister;
362 } 310 }
363 311
312 card->fully_routed = 1;
364 313
365 if (!priv->mclk_freq) { 314 if (!priv->mclk_freq) {
366 dev_err(&pdev->dev, "MCLK frequency missing\n"); 315 dev_err(&pdev->dev, "MCLK frequency missing\n");
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
index 4db1f8e6e172..12e566be3793 100644
--- a/sound/soc/omap/omap-dmic.c
+++ b/sound/soc/omap/omap-dmic.c
@@ -480,15 +480,12 @@ static int asoc_dmic_probe(struct platform_device *pdev)
480 dmic->dma_data.filter_data = "up_link"; 480 dmic->dma_data.filter_data = "up_link";
481 481
482 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); 482 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
483 if (!res) { 483 dmic->io_base = devm_ioremap_resource(&pdev->dev, res);
484 dev_err(dmic->dev, "invalid memory resource\n"); 484 if (IS_ERR(dmic->io_base)) {
485 ret = -ENODEV; 485 ret = PTR_ERR(dmic->io_base);
486 goto err_put_clk; 486 goto err_put_clk;
487 } 487 }
488 488
489 dmic->io_base = devm_ioremap_resource(&pdev->dev, res);
490 if (IS_ERR(dmic->io_base))
491 return PTR_ERR(dmic->io_base);
492 489
493 ret = snd_soc_register_component(&pdev->dev, &omap_dmic_component, 490 ret = snd_soc_register_component(&pdev->dev, &omap_dmic_component,
494 &omap_dmic_dai, 1); 491 &omap_dmic_dai, 1);
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 7483efb6dc67..6c19bba23570 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -433,6 +433,11 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
433 /* Sample rate generator drives the FS */ 433 /* Sample rate generator drives the FS */
434 regs->srgr2 |= FSGM; 434 regs->srgr2 |= FSGM;
435 break; 435 break;
436 case SND_SOC_DAIFMT_CBM_CFS:
437 /* McBSP slave. FS clock as output */
438 regs->srgr2 |= FSGM;
439 regs->pcr0 |= FSXM;
440 break;
436 case SND_SOC_DAIFMT_CBM_CFM: 441 case SND_SOC_DAIFMT_CBM_CFM:
437 /* McBSP slave */ 442 /* McBSP slave */
438 break; 443 break;
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index a49dc52f8abc..90d2a7cd2563 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -480,9 +480,6 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
480 mcpdm->dma_data[1].filter_data = "up_link"; 480 mcpdm->dma_data[1].filter_data = "up_link";
481 481
482 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); 482 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
483 if (res == NULL)
484 return -ENOMEM;
485
486 mcpdm->io_base = devm_ioremap_resource(&pdev->dev, res); 483 mcpdm->io_base = devm_ioremap_resource(&pdev->dev, res);
487 if (IS_ERR(mcpdm->io_base)) 484 if (IS_ERR(mcpdm->io_base))
488 return PTR_ERR(mcpdm->io_base); 485 return PTR_ERR(mcpdm->io_base);
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index b35809467547..4db74a083db1 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -11,7 +11,7 @@ config SND_PXA2XX_SOC
11config SND_MMP_SOC 11config SND_MMP_SOC
12 bool "Soc Audio for Marvell MMP chips" 12 bool "Soc Audio for Marvell MMP chips"
13 depends on ARCH_MMP 13 depends on ARCH_MMP
14 select SND_SOC_DMAENGINE_PCM 14 select SND_DMAENGINE_PCM
15 select SND_ARM 15 select SND_ARM
16 help 16 help
17 Say Y if you want to add support for codecs attached to 17 Say Y if you want to add support for codecs attached to
diff --git a/sound/soc/pxa/brownstone.c b/sound/soc/pxa/brownstone.c
index 4ad76099dd43..5b7d969f89a9 100644
--- a/sound/soc/pxa/brownstone.c
+++ b/sound/soc/pxa/brownstone.c
@@ -129,6 +129,7 @@ static struct snd_soc_dai_link brownstone_wm8994_dai[] = {
129/* audio machine driver */ 129/* audio machine driver */
130static struct snd_soc_card brownstone = { 130static struct snd_soc_card brownstone = {
131 .name = "brownstone", 131 .name = "brownstone",
132 .owner = THIS_MODULE,
132 .dai_link = brownstone_wm8994_dai, 133 .dai_link = brownstone_wm8994_dai,
133 .num_links = ARRAY_SIZE(brownstone_wm8994_dai), 134 .num_links = ARRAY_SIZE(brownstone_wm8994_dai),
134 135
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 97b711e12821..bbea7780eac6 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -56,8 +56,6 @@
56#include "pxa2xx-ac97.h" 56#include "pxa2xx-ac97.h"
57#include "../codecs/wm9713.h" 57#include "../codecs/wm9713.h"
58 58
59#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
60
61#define AC97_GPIO_PULL 0x58 59#define AC97_GPIO_PULL 0x58
62 60
63/* Use GPIO8 for rear speaker amplifier */ 61/* Use GPIO8 for rear speaker amplifier */
@@ -133,10 +131,11 @@ static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
133 unsigned short reg; 131 unsigned short reg;
134 132
135 /* Add mioa701 specific widgets */ 133 /* Add mioa701 specific widgets */
136 snd_soc_dapm_new_controls(dapm, ARRAY_AND_SIZE(mioa701_dapm_widgets)); 134 snd_soc_dapm_new_controls(dapm, mioa701_dapm_widgets,
135 ARRAY_SIZE(mioa701_dapm_widgets));
137 136
138 /* Set up mioa701 specific audio path audio_mapnects */ 137 /* Set up mioa701 specific audio path audio_mapnects */
139 snd_soc_dapm_add_routes(dapm, ARRAY_AND_SIZE(audio_map)); 138 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
140 139
141 /* Prepare GPIO8 for rear speaker amplifier */ 140 /* Prepare GPIO8 for rear speaker amplifier */
142 reg = codec->driver->read(codec, AC97_GPIO_CFG); 141 reg = codec->driver->read(codec, AC97_GPIO_CFG);
diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c
index 5d57e071cdf5..8235e231d89c 100644
--- a/sound/soc/pxa/mmp-pcm.c
+++ b/sound/soc/pxa/mmp-pcm.c
@@ -17,6 +17,7 @@
17#include <linux/dmaengine.h> 17#include <linux/dmaengine.h>
18#include <linux/platform_data/dma-mmp_tdma.h> 18#include <linux/platform_data/dma-mmp_tdma.h>
19#include <linux/platform_data/mmp_audio.h> 19#include <linux/platform_data/mmp_audio.h>
20
20#include <sound/pxa2xx-lib.h> 21#include <sound/pxa2xx-lib.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
@@ -67,7 +68,7 @@ static int mmp_pcm_hw_params(struct snd_pcm_substream *substream,
67{ 68{
68 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); 69 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
69 struct snd_soc_pcm_runtime *rtd = substream->private_data; 70 struct snd_soc_pcm_runtime *rtd = substream->private_data;
70 struct pxa2xx_pcm_dma_params *dma_params; 71 struct snd_dmaengine_dai_dma_data *dma_params;
71 struct dma_slave_config slave_config; 72 struct dma_slave_config slave_config;
72 int ret; 73 int ret;
73 74
@@ -80,10 +81,10 @@ static int mmp_pcm_hw_params(struct snd_pcm_substream *substream,
80 return ret; 81 return ret;
81 82
82 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 83 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
83 slave_config.dst_addr = dma_params->dev_addr; 84 slave_config.dst_addr = dma_params->addr;
84 slave_config.dst_maxburst = 4; 85 slave_config.dst_maxburst = 4;
85 } else { 86 } else {
86 slave_config.src_addr = dma_params->dev_addr; 87 slave_config.src_addr = dma_params->addr;
87 slave_config.src_maxburst = 4; 88 slave_config.src_maxburst = 4;
88 } 89 }
89 90
diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c
index 62142ce367c7..41752a5fe3b0 100644
--- a/sound/soc/pxa/mmp-sspa.c
+++ b/sound/soc/pxa/mmp-sspa.c
@@ -27,12 +27,15 @@
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/pxa2xx_ssp.h> 28#include <linux/pxa2xx_ssp.h>
29#include <linux/io.h> 29#include <linux/io.h>
30#include <linux/dmaengine.h>
31
30#include <sound/core.h> 32#include <sound/core.h>
31#include <sound/pcm.h> 33#include <sound/pcm.h>
32#include <sound/initval.h> 34#include <sound/initval.h>
33#include <sound/pcm_params.h> 35#include <sound/pcm_params.h>
34#include <sound/soc.h> 36#include <sound/soc.h>
35#include <sound/pxa2xx-lib.h> 37#include <sound/pxa2xx-lib.h>
38#include <sound/dmaengine_pcm.h>
36#include "mmp-sspa.h" 39#include "mmp-sspa.h"
37 40
38/* 41/*
@@ -40,7 +43,7 @@
40 */ 43 */
41struct sspa_priv { 44struct sspa_priv {
42 struct ssp_device *sspa; 45 struct ssp_device *sspa;
43 struct pxa2xx_pcm_dma_params *dma_params; 46 struct snd_dmaengine_dai_dma_data *dma_params;
44 struct clk *audio_clk; 47 struct clk *audio_clk;
45 struct clk *sysclk; 48 struct clk *sysclk;
46 int dai_fmt; 49 int dai_fmt;
@@ -266,7 +269,7 @@ static int mmp_sspa_hw_params(struct snd_pcm_substream *substream,
266 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 269 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
267 struct sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(dai); 270 struct sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(dai);
268 struct ssp_device *sspa = sspa_priv->sspa; 271 struct ssp_device *sspa = sspa_priv->sspa;
269 struct pxa2xx_pcm_dma_params *dma_params; 272 struct snd_dmaengine_dai_dma_data *dma_params;
270 u32 sspa_ctrl; 273 u32 sspa_ctrl;
271 274
272 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 275 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -309,7 +312,7 @@ static int mmp_sspa_hw_params(struct snd_pcm_substream *substream,
309 } 312 }
310 313
311 dma_params = &sspa_priv->dma_params[substream->stream]; 314 dma_params = &sspa_priv->dma_params[substream->stream];
312 dma_params->dev_addr = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 315 dma_params->addr = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
313 (sspa->phys_base + SSPA_TXD) : 316 (sspa->phys_base + SSPA_TXD) :
314 (sspa->phys_base + SSPA_RXD); 317 (sspa->phys_base + SSPA_RXD);
315 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_params); 318 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_params);
@@ -425,14 +428,12 @@ static int asoc_mmp_sspa_probe(struct platform_device *pdev)
425 return -ENOMEM; 428 return -ENOMEM;
426 429
427 priv->dma_params = devm_kzalloc(&pdev->dev, 430 priv->dma_params = devm_kzalloc(&pdev->dev,
428 2 * sizeof(struct pxa2xx_pcm_dma_params), GFP_KERNEL); 431 2 * sizeof(struct snd_dmaengine_dai_dma_data),
432 GFP_KERNEL);
429 if (priv->dma_params == NULL) 433 if (priv->dma_params == NULL)
430 return -ENOMEM; 434 return -ENOMEM;
431 435
432 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 436 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
433 if (res == NULL)
434 return -ENOMEM;
435
436 priv->sspa->mmio_base = devm_ioremap_resource(&pdev->dev, res); 437 priv->sspa->mmio_base = devm_ioremap_resource(&pdev->dev, res);
437 if (IS_ERR(priv->sspa->mmio_base)) 438 if (IS_ERR(priv->sspa->mmio_base))
438 return PTR_ERR(priv->sspa->mmio_base); 439 return PTR_ERR(priv->sspa->mmio_base);
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 6f4dd7543e82..a3119a00d8fa 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -21,6 +21,8 @@
21#include <linux/clk.h> 21#include <linux/clk.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/pxa2xx_ssp.h> 23#include <linux/pxa2xx_ssp.h>
24#include <linux/of.h>
25#include <linux/dmaengine.h>
24 26
25#include <asm/irq.h> 27#include <asm/irq.h>
26 28
@@ -30,9 +32,9 @@
30#include <sound/pcm_params.h> 32#include <sound/pcm_params.h>
31#include <sound/soc.h> 33#include <sound/soc.h>
32#include <sound/pxa2xx-lib.h> 34#include <sound/pxa2xx-lib.h>
35#include <sound/dmaengine_pcm.h>
33 36
34#include <mach/hardware.h> 37#include <mach/hardware.h>
35#include <mach/dma.h>
36 38
37#include "../../arm/pxa2xx-pcm.h" 39#include "../../arm/pxa2xx-pcm.h"
38#include "pxa-ssp.h" 40#include "pxa-ssp.h"
@@ -79,27 +81,13 @@ static void pxa_ssp_disable(struct ssp_device *ssp)
79 __raw_writel(sscr0, ssp->mmio_base + SSCR0); 81 __raw_writel(sscr0, ssp->mmio_base + SSCR0);
80} 82}
81 83
82struct pxa2xx_pcm_dma_data {
83 struct pxa2xx_pcm_dma_params params;
84 char name[20];
85};
86
87static void pxa_ssp_set_dma_params(struct ssp_device *ssp, int width4, 84static void pxa_ssp_set_dma_params(struct ssp_device *ssp, int width4,
88 int out, struct pxa2xx_pcm_dma_params *dma_data) 85 int out, struct snd_dmaengine_dai_dma_data *dma)
89{ 86{
90 struct pxa2xx_pcm_dma_data *dma; 87 dma->addr_width = width4 ? DMA_SLAVE_BUSWIDTH_4_BYTES :
91 88 DMA_SLAVE_BUSWIDTH_2_BYTES;
92 dma = container_of(dma_data, struct pxa2xx_pcm_dma_data, params); 89 dma->maxburst = 16;
93 90 dma->addr = ssp->phys_base + SSDR;
94 snprintf(dma->name, 20, "SSP%d PCM %s %s", ssp->port_id,
95 width4 ? "32-bit" : "16-bit", out ? "out" : "in");
96
97 dma->params.name = dma->name;
98 dma->params.drcmr = &DRCMR(out ? ssp->drcmr_tx : ssp->drcmr_rx);
99 dma->params.dcmd = (out ? (DCMD_INCSRCADDR | DCMD_FLOWTRG) :
100 (DCMD_INCTRGADDR | DCMD_FLOWSRC)) |
101 (width4 ? DCMD_WIDTH4 : DCMD_WIDTH2) | DCMD_BURST16;
102 dma->params.dev_addr = ssp->phys_base + SSDR;
103} 91}
104 92
105static int pxa_ssp_startup(struct snd_pcm_substream *substream, 93static int pxa_ssp_startup(struct snd_pcm_substream *substream,
@@ -107,7 +95,7 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
107{ 95{
108 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai); 96 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
109 struct ssp_device *ssp = priv->ssp; 97 struct ssp_device *ssp = priv->ssp;
110 struct pxa2xx_pcm_dma_data *dma; 98 struct snd_dmaengine_dai_dma_data *dma;
111 int ret = 0; 99 int ret = 0;
112 100
113 if (!cpu_dai->active) { 101 if (!cpu_dai->active) {
@@ -115,10 +103,14 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
115 pxa_ssp_disable(ssp); 103 pxa_ssp_disable(ssp);
116 } 104 }
117 105
118 dma = kzalloc(sizeof(struct pxa2xx_pcm_dma_data), GFP_KERNEL); 106 dma = kzalloc(sizeof(struct snd_dmaengine_dai_dma_data), GFP_KERNEL);
119 if (!dma) 107 if (!dma)
120 return -ENOMEM; 108 return -ENOMEM;
121 snd_soc_dai_set_dma_data(cpu_dai, substream, &dma->params); 109
110 dma->filter_data = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
111 &ssp->drcmr_tx : &ssp->drcmr_rx;
112
113 snd_soc_dai_set_dma_data(cpu_dai, substream, dma);
122 114
123 return ret; 115 return ret;
124} 116}
@@ -559,7 +551,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
559 u32 sspsp; 551 u32 sspsp;
560 int width = snd_pcm_format_physical_width(params_format(params)); 552 int width = snd_pcm_format_physical_width(params_format(params));
561 int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf; 553 int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf;
562 struct pxa2xx_pcm_dma_params *dma_data; 554 struct snd_dmaengine_dai_dma_data *dma_data;
563 555
564 dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream); 556 dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
565 557
@@ -719,6 +711,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
719 711
720static int pxa_ssp_probe(struct snd_soc_dai *dai) 712static int pxa_ssp_probe(struct snd_soc_dai *dai)
721{ 713{
714 struct device *dev = dai->dev;
722 struct ssp_priv *priv; 715 struct ssp_priv *priv;
723 int ret; 716 int ret;
724 717
@@ -726,10 +719,26 @@ static int pxa_ssp_probe(struct snd_soc_dai *dai)
726 if (!priv) 719 if (!priv)
727 return -ENOMEM; 720 return -ENOMEM;
728 721
729 priv->ssp = pxa_ssp_request(dai->id + 1, "SoC audio"); 722 if (dev->of_node) {
730 if (priv->ssp == NULL) { 723 struct device_node *ssp_handle;
731 ret = -ENODEV; 724
732 goto err_priv; 725 ssp_handle = of_parse_phandle(dev->of_node, "port", 0);
726 if (!ssp_handle) {
727 dev_err(dev, "unable to get 'port' phandle\n");
728 return -ENODEV;
729 }
730
731 priv->ssp = pxa_ssp_request_of(ssp_handle, "SoC audio");
732 if (priv->ssp == NULL) {
733 ret = -ENODEV;
734 goto err_priv;
735 }
736 } else {
737 priv->ssp = pxa_ssp_request(dai->id + 1, "SoC audio");
738 if (priv->ssp == NULL) {
739 ret = -ENODEV;
740 goto err_priv;
741 }
733 } 742 }
734 743
735 priv->dai_fmt = (unsigned int) -1; 744 priv->dai_fmt = (unsigned int) -1;
@@ -798,6 +807,12 @@ static const struct snd_soc_component_driver pxa_ssp_component = {
798 .name = "pxa-ssp", 807 .name = "pxa-ssp",
799}; 808};
800 809
810#ifdef CONFIG_OF
811static const struct of_device_id pxa_ssp_of_ids[] = {
812 { .compatible = "mrvl,pxa-ssp-dai" },
813};
814#endif
815
801static int asoc_ssp_probe(struct platform_device *pdev) 816static int asoc_ssp_probe(struct platform_device *pdev)
802{ 817{
803 return snd_soc_register_component(&pdev->dev, &pxa_ssp_component, 818 return snd_soc_register_component(&pdev->dev, &pxa_ssp_component,
@@ -812,8 +827,9 @@ static int asoc_ssp_remove(struct platform_device *pdev)
812 827
813static struct platform_driver asoc_ssp_driver = { 828static struct platform_driver asoc_ssp_driver = {
814 .driver = { 829 .driver = {
815 .name = "pxa-ssp-dai", 830 .name = "pxa-ssp-dai",
816 .owner = THIS_MODULE, 831 .owner = THIS_MODULE,
832 .of_match_table = of_match_ptr(pxa_ssp_of_ids),
817 }, 833 },
818 834
819 .probe = asoc_ssp_probe, 835 .probe = asoc_ssp_probe,
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 1475515712e6..f1059d999de6 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -14,15 +14,16 @@
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/dmaengine.h>
17 18
18#include <sound/core.h> 19#include <sound/core.h>
19#include <sound/ac97_codec.h> 20#include <sound/ac97_codec.h>
20#include <sound/soc.h> 21#include <sound/soc.h>
21#include <sound/pxa2xx-lib.h> 22#include <sound/pxa2xx-lib.h>
23#include <sound/dmaengine_pcm.h>
22 24
23#include <mach/hardware.h> 25#include <mach/hardware.h>
24#include <mach/regs-ac97.h> 26#include <mach/regs-ac97.h>
25#include <mach/dma.h>
26#include <mach/audio.h> 27#include <mach/audio.h>
27 28
28#include "pxa2xx-ac97.h" 29#include "pxa2xx-ac97.h"
@@ -48,44 +49,44 @@ static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
48 .reset = pxa2xx_ac97_cold_reset, 49 .reset = pxa2xx_ac97_cold_reset,
49}; 50};
50 51
51static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = { 52static unsigned long pxa2xx_ac97_pcm_stereo_in_req = 12;
52 .name = "AC97 PCM Stereo out", 53static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_in = {
53 .dev_addr = __PREG(PCDR), 54 .addr = __PREG(PCDR),
54 .drcmr = &DRCMR(12), 55 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
55 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | 56 .maxburst = 32,
56 DCMD_BURST32 | DCMD_WIDTH4, 57 .filter_data = &pxa2xx_ac97_pcm_stereo_in_req,
57}; 58};
58 59
59static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = { 60static unsigned long pxa2xx_ac97_pcm_stereo_out_req = 11;
60 .name = "AC97 PCM Stereo in", 61static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_out = {
61 .dev_addr = __PREG(PCDR), 62 .addr = __PREG(PCDR),
62 .drcmr = &DRCMR(11), 63 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
63 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 64 .maxburst = 32,
64 DCMD_BURST32 | DCMD_WIDTH4, 65 .filter_data = &pxa2xx_ac97_pcm_stereo_out_req,
65}; 66};
66 67
67static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = { 68static unsigned long pxa2xx_ac97_pcm_aux_mono_out_req = 10;
68 .name = "AC97 Aux PCM (Slot 5) Mono out", 69static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_out = {
69 .dev_addr = __PREG(MODR), 70 .addr = __PREG(MODR),
70 .drcmr = &DRCMR(10), 71 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
71 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | 72 .maxburst = 16,
72 DCMD_BURST16 | DCMD_WIDTH2, 73 .filter_data = &pxa2xx_ac97_pcm_aux_mono_out_req,
73}; 74};
74 75
75static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = { 76static unsigned long pxa2xx_ac97_pcm_aux_mono_in_req = 9;
76 .name = "AC97 Aux PCM (Slot 5) Mono in", 77static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_in = {
77 .dev_addr = __PREG(MODR), 78 .addr = __PREG(MODR),
78 .drcmr = &DRCMR(9), 79 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
79 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 80 .maxburst = 16,
80 DCMD_BURST16 | DCMD_WIDTH2, 81 .filter_data = &pxa2xx_ac97_pcm_aux_mono_in_req,
81}; 82};
82 83
83static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = { 84static unsigned long pxa2xx_ac97_pcm_aux_mic_mono_req = 8;
84 .name = "AC97 Mic PCM (Slot 6) Mono in", 85static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_mic_mono_in = {
85 .dev_addr = __PREG(MCDR), 86 .addr = __PREG(MCDR),
86 .drcmr = &DRCMR(8), 87 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
87 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 88 .maxburst = 16,
88 DCMD_BURST16 | DCMD_WIDTH2, 89 .filter_data = &pxa2xx_ac97_pcm_aux_mic_mono_req,
89}; 90};
90 91
91#ifdef CONFIG_PM 92#ifdef CONFIG_PM
@@ -119,7 +120,7 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
119 struct snd_pcm_hw_params *params, 120 struct snd_pcm_hw_params *params,
120 struct snd_soc_dai *cpu_dai) 121 struct snd_soc_dai *cpu_dai)
121{ 122{
122 struct pxa2xx_pcm_dma_params *dma_data; 123 struct snd_dmaengine_dai_dma_data *dma_data;
123 124
124 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 125 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
125 dma_data = &pxa2xx_ac97_pcm_stereo_out; 126 dma_data = &pxa2xx_ac97_pcm_stereo_out;
@@ -135,7 +136,7 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
135 struct snd_pcm_hw_params *params, 136 struct snd_pcm_hw_params *params,
136 struct snd_soc_dai *cpu_dai) 137 struct snd_soc_dai *cpu_dai)
137{ 138{
138 struct pxa2xx_pcm_dma_params *dma_data; 139 struct snd_dmaengine_dai_dma_data *dma_data;
139 140
140 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 141 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
141 dma_data = &pxa2xx_ac97_pcm_aux_mono_out; 142 dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index f7ca71664112..d5340a088858 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -23,9 +23,9 @@
23#include <sound/initval.h> 23#include <sound/initval.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include <sound/pxa2xx-lib.h> 25#include <sound/pxa2xx-lib.h>
26#include <sound/dmaengine_pcm.h>
26 27
27#include <mach/hardware.h> 28#include <mach/hardware.h>
28#include <mach/dma.h>
29#include <mach/audio.h> 29#include <mach/audio.h>
30 30
31#include "pxa2xx-i2s.h" 31#include "pxa2xx-i2s.h"
@@ -82,20 +82,20 @@ static struct pxa_i2s_port pxa_i2s;
82static struct clk *clk_i2s; 82static struct clk *clk_i2s;
83static int clk_ena = 0; 83static int clk_ena = 0;
84 84
85static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = { 85static unsigned long pxa2xx_i2s_pcm_stereo_out_req = 3;
86 .name = "I2S PCM Stereo out", 86static struct snd_dmaengine_dai_dma_data pxa2xx_i2s_pcm_stereo_out = {
87 .dev_addr = __PREG(SADR), 87 .addr = __PREG(SADR),
88 .drcmr = &DRCMR(3), 88 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
89 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | 89 .maxburst = 32,
90 DCMD_BURST32 | DCMD_WIDTH4, 90 .filter_data = &pxa2xx_i2s_pcm_stereo_out_req,
91}; 91};
92 92
93static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = { 93static unsigned long pxa2xx_i2s_pcm_stereo_in_req = 2;
94 .name = "I2S PCM Stereo in", 94static struct snd_dmaengine_dai_dma_data pxa2xx_i2s_pcm_stereo_in = {
95 .dev_addr = __PREG(SADR), 95 .addr = __PREG(SADR),
96 .drcmr = &DRCMR(2), 96 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
97 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 97 .maxburst = 32,
98 DCMD_BURST32 | DCMD_WIDTH4, 98 .filter_data = &pxa2xx_i2s_pcm_stereo_in_req,
99}; 99};
100 100
101static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream, 101static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream,
@@ -163,7 +163,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
163 struct snd_pcm_hw_params *params, 163 struct snd_pcm_hw_params *params,
164 struct snd_soc_dai *dai) 164 struct snd_soc_dai *dai)
165{ 165{
166 struct pxa2xx_pcm_dma_params *dma_data; 166 struct snd_dmaengine_dai_dma_data *dma_data;
167 167
168 BUG_ON(IS_ERR(clk_i2s)); 168 BUG_ON(IS_ERR(clk_i2s));
169 clk_prepare_enable(clk_i2s); 169 clk_prepare_enable(clk_i2s);
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index ecff116cb7b0..806da27b8b67 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -12,10 +12,13 @@
12 12
13#include <linux/dma-mapping.h> 13#include <linux/dma-mapping.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/dmaengine.h>
16#include <linux/of.h>
15 17
16#include <sound/core.h> 18#include <sound/core.h>
17#include <sound/soc.h> 19#include <sound/soc.h>
18#include <sound/pxa2xx-lib.h> 20#include <sound/pxa2xx-lib.h>
21#include <sound/dmaengine_pcm.h>
19 22
20#include "../../arm/pxa2xx-pcm.h" 23#include "../../arm/pxa2xx-pcm.h"
21 24
@@ -25,7 +28,7 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
25 struct snd_pcm_runtime *runtime = substream->runtime; 28 struct snd_pcm_runtime *runtime = substream->runtime;
26 struct pxa2xx_runtime_data *prtd = runtime->private_data; 29 struct pxa2xx_runtime_data *prtd = runtime->private_data;
27 struct snd_soc_pcm_runtime *rtd = substream->private_data; 30 struct snd_soc_pcm_runtime *rtd = substream->private_data;
28 struct pxa2xx_pcm_dma_params *dma; 31 struct snd_dmaengine_dai_dma_data *dma;
29 int ret; 32 int ret;
30 33
31 dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 34 dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
@@ -39,7 +42,7 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
39 * with different params */ 42 * with different params */
40 if (prtd->params == NULL) { 43 if (prtd->params == NULL) {
41 prtd->params = dma; 44 prtd->params = dma;
42 ret = pxa_request_dma(prtd->params->name, DMA_PRIO_LOW, 45 ret = pxa_request_dma("name", DMA_PRIO_LOW,
43 pxa2xx_pcm_dma_irq, substream); 46 pxa2xx_pcm_dma_irq, substream);
44 if (ret < 0) 47 if (ret < 0)
45 return ret; 48 return ret;
@@ -47,7 +50,7 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
47 } else if (prtd->params != dma) { 50 } else if (prtd->params != dma) {
48 pxa_free_dma(prtd->dma_ch); 51 pxa_free_dma(prtd->dma_ch);
49 prtd->params = dma; 52 prtd->params = dma;
50 ret = pxa_request_dma(prtd->params->name, DMA_PRIO_LOW, 53 ret = pxa_request_dma("name", DMA_PRIO_LOW,
51 pxa2xx_pcm_dma_irq, substream); 54 pxa2xx_pcm_dma_irq, substream);
52 if (ret < 0) 55 if (ret < 0)
53 return ret; 56 return ret;
@@ -131,10 +134,18 @@ static int pxa2xx_soc_platform_remove(struct platform_device *pdev)
131 return 0; 134 return 0;
132} 135}
133 136
137#ifdef CONFIG_OF
138static const struct of_device_id snd_soc_pxa_audio_match[] = {
139 { .compatible = "mrvl,pxa-pcm-audio" },
140 { }
141};
142#endif
143
134static struct platform_driver pxa_pcm_driver = { 144static struct platform_driver pxa_pcm_driver = {
135 .driver = { 145 .driver = {
136 .name = "pxa-pcm-audio", 146 .name = "pxa-pcm-audio",
137 .owner = THIS_MODULE, 147 .owner = THIS_MODULE,
148 .of_match_table = of_match_ptr(snd_soc_pxa_audio_match),
138 }, 149 },
139 150
140 .probe = pxa2xx_soc_platform_probe, 151 .probe = pxa2xx_soc_platform_probe,
diff --git a/sound/soc/pxa/ttc-dkb.c b/sound/soc/pxa/ttc-dkb.c
index f4ea4f6663a2..13c9ee0cb83b 100644
--- a/sound/soc/pxa/ttc-dkb.c
+++ b/sound/soc/pxa/ttc-dkb.c
@@ -122,6 +122,7 @@ static struct snd_soc_dai_link ttc_pm860x_hifi_dai[] = {
122/* ttc/td audio machine driver */ 122/* ttc/td audio machine driver */
123static struct snd_soc_card ttc_dkb_card = { 123static struct snd_soc_card ttc_dkb_card = {
124 .name = "ttc-dkb-hifi", 124 .name = "ttc-dkb-hifi",
125 .owner = THIS_MODULE,
125 .dai_link = ttc_pm860x_hifi_dai, 126 .dai_link = ttc_pm860x_hifi_dai,
126 .num_links = ARRAY_SIZE(ttc_pm860x_hifi_dai), 127 .num_links = ARRAY_SIZE(ttc_pm860x_hifi_dai),
127 128
diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c
index 58cfb1eb7dd3..945e8abdc10f 100644
--- a/sound/soc/s6000/s6105-ipcam.c
+++ b/sound/soc/s6000/s6105-ipcam.c
@@ -192,7 +192,7 @@ static struct snd_soc_card snd_soc_card_s6105 = {
192 .num_links = 1, 192 .num_links = 1,
193}; 193};
194 194
195static struct s6000_snd_platform_data __initdata s6105_snd_data = { 195static struct s6000_snd_platform_data s6105_snd_data __initdata = {
196 .wide = 0, 196 .wide = 0,
197 .channel_in = 0, 197 .channel_in = 0,
198 .channel_out = 1, 198 .channel_out = 1,
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c
index 2dd623fa3882..2acf987844e8 100644
--- a/sound/soc/samsung/ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -404,18 +404,13 @@ static int s3c_ac97_probe(struct platform_device *pdev)
404 return -ENXIO; 404 return -ENXIO;
405 } 405 }
406 406
407 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
408 if (!mem_res) {
409 dev_err(&pdev->dev, "Unable to get register resource\n");
410 return -ENXIO;
411 }
412
413 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 407 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
414 if (!irq_res) { 408 if (!irq_res) {
415 dev_err(&pdev->dev, "AC97 IRQ not provided!\n"); 409 dev_err(&pdev->dev, "AC97 IRQ not provided!\n");
416 return -ENXIO; 410 return -ENXIO;
417 } 411 }
418 412
413 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
419 s3c_ac97.regs = devm_ioremap_resource(&pdev->dev, mem_res); 414 s3c_ac97.regs = devm_ioremap_resource(&pdev->dev, mem_res);
420 if (IS_ERR(s3c_ac97.regs)) 415 if (IS_ERR(s3c_ac97.regs))
421 return PTR_ERR(s3c_ac97.regs); 416 return PTR_ERR(s3c_ac97.regs);
@@ -462,7 +457,7 @@ static int s3c_ac97_probe(struct platform_device *pdev)
462 if (ret) 457 if (ret)
463 goto err5; 458 goto err5;
464 459
465 ret = asoc_dma_platform_register(&pdev->dev); 460 ret = samsung_asoc_dma_platform_register(&pdev->dev);
466 if (ret) { 461 if (ret) {
467 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); 462 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
468 goto err6; 463 goto err6;
@@ -485,7 +480,7 @@ static int s3c_ac97_remove(struct platform_device *pdev)
485{ 480{
486 struct resource *irq_res; 481 struct resource *irq_res;
487 482
488 asoc_dma_platform_unregister(&pdev->dev); 483 samsung_asoc_dma_platform_unregister(&pdev->dev);
489 snd_soc_unregister_component(&pdev->dev); 484 snd_soc_unregister_component(&pdev->dev);
490 485
491 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 486 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index 21b79262010e..9338d11e9216 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -90,6 +90,13 @@ static void dma_enqueue(struct snd_pcm_substream *substream)
90 dma_info.period = prtd->dma_period; 90 dma_info.period = prtd->dma_period;
91 dma_info.len = prtd->dma_period*limit; 91 dma_info.len = prtd->dma_period*limit;
92 92
93 if (dma_info.cap == DMA_CYCLIC) {
94 dma_info.buf = pos;
95 prtd->params->ops->prepare(prtd->params->ch, &dma_info);
96 prtd->dma_loaded += limit;
97 return;
98 }
99
93 while (prtd->dma_loaded < limit) { 100 while (prtd->dma_loaded < limit) {
94 pr_debug("dma_loaded: %d\n", prtd->dma_loaded); 101 pr_debug("dma_loaded: %d\n", prtd->dma_loaded);
95 102
@@ -176,6 +183,10 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
176 prtd->params->ch = prtd->params->ops->request( 183 prtd->params->ch = prtd->params->ops->request(
177 prtd->params->channel, &req, rtd->cpu_dai->dev, 184 prtd->params->channel, &req, rtd->cpu_dai->dev,
178 prtd->params->ch_name); 185 prtd->params->ch_name);
186 if (!prtd->params->ch) {
187 pr_err("Failed to allocate DMA channel\n");
188 return -ENXIO;
189 }
179 prtd->params->ops->config(prtd->params->ch, &config); 190 prtd->params->ops->config(prtd->params->ch, &config);
180 } 191 }
181 192
@@ -433,17 +444,17 @@ static struct snd_soc_platform_driver samsung_asoc_platform = {
433 .pcm_free = dma_free_dma_buffers, 444 .pcm_free = dma_free_dma_buffers,
434}; 445};
435 446
436int asoc_dma_platform_register(struct device *dev) 447int samsung_asoc_dma_platform_register(struct device *dev)
437{ 448{
438 return snd_soc_register_platform(dev, &samsung_asoc_platform); 449 return snd_soc_register_platform(dev, &samsung_asoc_platform);
439} 450}
440EXPORT_SYMBOL_GPL(asoc_dma_platform_register); 451EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register);
441 452
442void asoc_dma_platform_unregister(struct device *dev) 453void samsung_asoc_dma_platform_unregister(struct device *dev)
443{ 454{
444 snd_soc_unregister_platform(dev); 455 snd_soc_unregister_platform(dev);
445} 456}
446EXPORT_SYMBOL_GPL(asoc_dma_platform_unregister); 457EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_unregister);
447 458
448MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 459MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
449MODULE_DESCRIPTION("Samsung ASoC DMA Driver"); 460MODULE_DESCRIPTION("Samsung ASoC DMA Driver");
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h
index 189a7a6d5020..0e86315a3eaf 100644
--- a/sound/soc/samsung/dma.h
+++ b/sound/soc/samsung/dma.h
@@ -22,7 +22,7 @@ struct s3c_dma_params {
22 char *ch_name; 22 char *ch_name;
23}; 23};
24 24
25int asoc_dma_platform_register(struct device *dev); 25int samsung_asoc_dma_platform_register(struct device *dev);
26void asoc_dma_platform_unregister(struct device *dev); 26void samsung_asoc_dma_platform_unregister(struct device *dev);
27 27
28#endif 28#endif
diff --git a/sound/soc/samsung/i2s-regs.h b/sound/soc/samsung/i2s-regs.h
index c0e6d9a19efc..821a50231002 100644
--- a/sound/soc/samsung/i2s-regs.h
+++ b/sound/soc/samsung/i2s-regs.h
@@ -31,6 +31,10 @@
31#define I2SLVL1ADDR 0x34 31#define I2SLVL1ADDR 0x34
32#define I2SLVL2ADDR 0x38 32#define I2SLVL2ADDR 0x38
33#define I2SLVL3ADDR 0x3c 33#define I2SLVL3ADDR 0x3c
34#define I2SSTR1 0x40
35#define I2SVER 0x44
36#define I2SFIC2 0x48
37#define I2STDM 0x4c
34 38
35#define CON_RSTCLR (1 << 31) 39#define CON_RSTCLR (1 << 31)
36#define CON_FRXOFSTATUS (1 << 26) 40#define CON_FRXOFSTATUS (1 << 26)
@@ -95,24 +99,39 @@
95#define MOD_RXONLY (1 << 8) 99#define MOD_RXONLY (1 << 8)
96#define MOD_TXRX (2 << 8) 100#define MOD_TXRX (2 << 8)
97#define MOD_MASK (3 << 8) 101#define MOD_MASK (3 << 8)
98#define MOD_LR_LLOW (0 << 7) 102#define MOD_LRP_SHIFT 7
99#define MOD_LR_RLOW (1 << 7) 103#define MOD_LR_LLOW 0
100#define MOD_SDF_IIS (0 << 5) 104#define MOD_LR_RLOW 1
101#define MOD_SDF_MSB (1 << 5) 105#define MOD_SDF_SHIFT 5
102#define MOD_SDF_LSB (2 << 5) 106#define MOD_SDF_IIS 0
103#define MOD_SDF_MASK (3 << 5) 107#define MOD_SDF_MSB 1
104#define MOD_RCLK_256FS (0 << 3) 108#define MOD_SDF_LSB 2
105#define MOD_RCLK_512FS (1 << 3) 109#define MOD_SDF_MASK 3
106#define MOD_RCLK_384FS (2 << 3) 110#define MOD_RCLK_SHIFT 3
107#define MOD_RCLK_768FS (3 << 3) 111#define MOD_RCLK_256FS 0
108#define MOD_RCLK_MASK (3 << 3) 112#define MOD_RCLK_512FS 1
109#define MOD_BCLK_32FS (0 << 1) 113#define MOD_RCLK_384FS 2
110#define MOD_BCLK_48FS (1 << 1) 114#define MOD_RCLK_768FS 3
111#define MOD_BCLK_16FS (2 << 1) 115#define MOD_RCLK_MASK 3
112#define MOD_BCLK_24FS (3 << 1) 116#define MOD_BCLK_SHIFT 1
113#define MOD_BCLK_MASK (3 << 1) 117#define MOD_BCLK_32FS 0
118#define MOD_BCLK_48FS 1
119#define MOD_BCLK_16FS 2
120#define MOD_BCLK_24FS 3
121#define MOD_BCLK_MASK 3
114#define MOD_8BIT (1 << 0) 122#define MOD_8BIT (1 << 0)
115 123
124#define EXYNOS5420_MOD_LRP_SHIFT 15
125#define EXYNOS5420_MOD_SDF_SHIFT 6
126#define EXYNOS5420_MOD_RCLK_SHIFT 4
127#define EXYNOS5420_MOD_BCLK_SHIFT 0
128#define EXYNOS5420_MOD_BCLK_64FS 4
129#define EXYNOS5420_MOD_BCLK_96FS 5
130#define EXYNOS5420_MOD_BCLK_128FS 6
131#define EXYNOS5420_MOD_BCLK_192FS 7
132#define EXYNOS5420_MOD_BCLK_256FS 8
133#define EXYNOS5420_MOD_BCLK_MASK 0xf
134
116#define MOD_CDCLKCON (1 << 12) 135#define MOD_CDCLKCON (1 << 12)
117 136
118#define PSR_PSREN (1 << 15) 137#define PSR_PSREN (1 << 15)
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 959c702235c8..b302f3b7a587 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -40,6 +40,7 @@ enum samsung_dai_type {
40 40
41struct samsung_i2s_dai_data { 41struct samsung_i2s_dai_data {
42 int dai_type; 42 int dai_type;
43 u32 quirks;
43}; 44};
44 45
45struct i2s_dai { 46struct i2s_dai {
@@ -198,7 +199,13 @@ static inline bool is_manager(struct i2s_dai *i2s)
198/* Read RCLK of I2S (in multiples of LRCLK) */ 199/* Read RCLK of I2S (in multiples of LRCLK) */
199static inline unsigned get_rfs(struct i2s_dai *i2s) 200static inline unsigned get_rfs(struct i2s_dai *i2s)
200{ 201{
201 u32 rfs = (readl(i2s->addr + I2SMOD) >> 3) & 0x3; 202 u32 rfs;
203
204 if (i2s->quirks & QUIRK_SUPPORTS_TDM)
205 rfs = readl(i2s->addr + I2SMOD) >> EXYNOS5420_MOD_RCLK_SHIFT;
206 else
207 rfs = (readl(i2s->addr + I2SMOD) >> MOD_RCLK_SHIFT);
208 rfs &= MOD_RCLK_MASK;
202 209
203 switch (rfs) { 210 switch (rfs) {
204 case 3: return 768; 211 case 3: return 768;
@@ -212,21 +219,26 @@ static inline unsigned get_rfs(struct i2s_dai *i2s)
212static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs) 219static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
213{ 220{
214 u32 mod = readl(i2s->addr + I2SMOD); 221 u32 mod = readl(i2s->addr + I2SMOD);
222 int rfs_shift;
215 223
216 mod &= ~MOD_RCLK_MASK; 224 if (i2s->quirks & QUIRK_SUPPORTS_TDM)
225 rfs_shift = EXYNOS5420_MOD_RCLK_SHIFT;
226 else
227 rfs_shift = MOD_RCLK_SHIFT;
228 mod &= ~(MOD_RCLK_MASK << rfs_shift);
217 229
218 switch (rfs) { 230 switch (rfs) {
219 case 768: 231 case 768:
220 mod |= MOD_RCLK_768FS; 232 mod |= (MOD_RCLK_768FS << rfs_shift);
221 break; 233 break;
222 case 512: 234 case 512:
223 mod |= MOD_RCLK_512FS; 235 mod |= (MOD_RCLK_512FS << rfs_shift);
224 break; 236 break;
225 case 384: 237 case 384:
226 mod |= MOD_RCLK_384FS; 238 mod |= (MOD_RCLK_384FS << rfs_shift);
227 break; 239 break;
228 default: 240 default:
229 mod |= MOD_RCLK_256FS; 241 mod |= (MOD_RCLK_256FS << rfs_shift);
230 break; 242 break;
231 } 243 }
232 244
@@ -236,9 +248,22 @@ static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
236/* Read Bit-Clock of I2S (in multiples of LRCLK) */ 248/* Read Bit-Clock of I2S (in multiples of LRCLK) */
237static inline unsigned get_bfs(struct i2s_dai *i2s) 249static inline unsigned get_bfs(struct i2s_dai *i2s)
238{ 250{
239 u32 bfs = (readl(i2s->addr + I2SMOD) >> 1) & 0x3; 251 u32 bfs;
252
253 if (i2s->quirks & QUIRK_SUPPORTS_TDM) {
254 bfs = readl(i2s->addr + I2SMOD) >> EXYNOS5420_MOD_BCLK_SHIFT;
255 bfs &= EXYNOS5420_MOD_BCLK_MASK;
256 } else {
257 bfs = readl(i2s->addr + I2SMOD) >> MOD_BCLK_SHIFT;
258 bfs &= MOD_BCLK_MASK;
259 }
240 260
241 switch (bfs) { 261 switch (bfs) {
262 case 8: return 256;
263 case 7: return 192;
264 case 6: return 128;
265 case 5: return 96;
266 case 4: return 64;
242 case 3: return 24; 267 case 3: return 24;
243 case 2: return 16; 268 case 2: return 16;
244 case 1: return 48; 269 case 1: return 48;
@@ -250,21 +275,50 @@ static inline unsigned get_bfs(struct i2s_dai *i2s)
250static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs) 275static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
251{ 276{
252 u32 mod = readl(i2s->addr + I2SMOD); 277 u32 mod = readl(i2s->addr + I2SMOD);
278 int bfs_shift;
279 int tdm = i2s->quirks & QUIRK_SUPPORTS_TDM;
253 280
254 mod &= ~MOD_BCLK_MASK; 281 if (i2s->quirks & QUIRK_SUPPORTS_TDM) {
282 bfs_shift = EXYNOS5420_MOD_BCLK_SHIFT;
283 mod &= ~(EXYNOS5420_MOD_BCLK_MASK << bfs_shift);
284 } else {
285 bfs_shift = MOD_BCLK_SHIFT;
286 mod &= ~(MOD_BCLK_MASK << bfs_shift);
287 }
288
289 /* Non-TDM I2S controllers do not support BCLK > 48 * FS */
290 if (!tdm && bfs > 48) {
291 dev_err(&i2s->pdev->dev, "Unsupported BCLK divider\n");
292 return;
293 }
255 294
256 switch (bfs) { 295 switch (bfs) {
257 case 48: 296 case 48:
258 mod |= MOD_BCLK_48FS; 297 mod |= (MOD_BCLK_48FS << bfs_shift);
259 break; 298 break;
260 case 32: 299 case 32:
261 mod |= MOD_BCLK_32FS; 300 mod |= (MOD_BCLK_32FS << bfs_shift);
262 break; 301 break;
263 case 24: 302 case 24:
264 mod |= MOD_BCLK_24FS; 303 mod |= (MOD_BCLK_24FS << bfs_shift);
265 break; 304 break;
266 case 16: 305 case 16:
267 mod |= MOD_BCLK_16FS; 306 mod |= (MOD_BCLK_16FS << bfs_shift);
307 break;
308 case 64:
309 mod |= (EXYNOS5420_MOD_BCLK_64FS << bfs_shift);
310 break;
311 case 96:
312 mod |= (EXYNOS5420_MOD_BCLK_96FS << bfs_shift);
313 break;
314 case 128:
315 mod |= (EXYNOS5420_MOD_BCLK_128FS << bfs_shift);
316 break;
317 case 192:
318 mod |= (EXYNOS5420_MOD_BCLK_192FS << bfs_shift);
319 break;
320 case 256:
321 mod |= (EXYNOS5420_MOD_BCLK_256FS << bfs_shift);
268 break; 322 break;
269 default: 323 default:
270 dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n"); 324 dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n");
@@ -491,20 +545,32 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
491{ 545{
492 struct i2s_dai *i2s = to_info(dai); 546 struct i2s_dai *i2s = to_info(dai);
493 u32 mod = readl(i2s->addr + I2SMOD); 547 u32 mod = readl(i2s->addr + I2SMOD);
548 int lrp_shift, sdf_shift, sdf_mask, lrp_rlow;
494 u32 tmp = 0; 549 u32 tmp = 0;
495 550
551 if (i2s->quirks & QUIRK_SUPPORTS_TDM) {
552 lrp_shift = EXYNOS5420_MOD_LRP_SHIFT;
553 sdf_shift = EXYNOS5420_MOD_SDF_SHIFT;
554 } else {
555 lrp_shift = MOD_LRP_SHIFT;
556 sdf_shift = MOD_SDF_SHIFT;
557 }
558
559 sdf_mask = MOD_SDF_MASK << sdf_shift;
560 lrp_rlow = MOD_LR_RLOW << lrp_shift;
561
496 /* Format is priority */ 562 /* Format is priority */
497 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 563 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
498 case SND_SOC_DAIFMT_RIGHT_J: 564 case SND_SOC_DAIFMT_RIGHT_J:
499 tmp |= MOD_LR_RLOW; 565 tmp |= lrp_rlow;
500 tmp |= MOD_SDF_MSB; 566 tmp |= (MOD_SDF_MSB << sdf_shift);
501 break; 567 break;
502 case SND_SOC_DAIFMT_LEFT_J: 568 case SND_SOC_DAIFMT_LEFT_J:
503 tmp |= MOD_LR_RLOW; 569 tmp |= lrp_rlow;
504 tmp |= MOD_SDF_LSB; 570 tmp |= (MOD_SDF_LSB << sdf_shift);
505 break; 571 break;
506 case SND_SOC_DAIFMT_I2S: 572 case SND_SOC_DAIFMT_I2S:
507 tmp |= MOD_SDF_IIS; 573 tmp |= (MOD_SDF_IIS << sdf_shift);
508 break; 574 break;
509 default: 575 default:
510 dev_err(&i2s->pdev->dev, "Format not supported\n"); 576 dev_err(&i2s->pdev->dev, "Format not supported\n");
@@ -519,10 +585,10 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
519 case SND_SOC_DAIFMT_NB_NF: 585 case SND_SOC_DAIFMT_NB_NF:
520 break; 586 break;
521 case SND_SOC_DAIFMT_NB_IF: 587 case SND_SOC_DAIFMT_NB_IF:
522 if (tmp & MOD_LR_RLOW) 588 if (tmp & lrp_rlow)
523 tmp &= ~MOD_LR_RLOW; 589 tmp &= ~lrp_rlow;
524 else 590 else
525 tmp |= MOD_LR_RLOW; 591 tmp |= lrp_rlow;
526 break; 592 break;
527 default: 593 default:
528 dev_err(&i2s->pdev->dev, "Polarity not supported\n"); 594 dev_err(&i2s->pdev->dev, "Polarity not supported\n");
@@ -544,15 +610,18 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
544 return -EINVAL; 610 return -EINVAL;
545 } 611 }
546 612
613 /*
614 * Don't change the I2S mode if any controller is active on this
615 * channel.
616 */
547 if (any_active(i2s) && 617 if (any_active(i2s) &&
548 ((mod & (MOD_SDF_MASK | MOD_LR_RLOW 618 ((mod & (sdf_mask | lrp_rlow | MOD_SLAVE)) != tmp)) {
549 | MOD_SLAVE)) != tmp)) {
550 dev_err(&i2s->pdev->dev, 619 dev_err(&i2s->pdev->dev,
551 "%s:%d Other DAI busy\n", __func__, __LINE__); 620 "%s:%d Other DAI busy\n", __func__, __LINE__);
552 return -EAGAIN; 621 return -EAGAIN;
553 } 622 }
554 623
555 mod &= ~(MOD_SDF_MASK | MOD_LR_RLOW | MOD_SLAVE); 624 mod &= ~(sdf_mask | lrp_rlow | MOD_SLAVE);
556 mod |= tmp; 625 mod |= tmp;
557 writel(mod, i2s->addr + I2SMOD); 626 writel(mod, i2s->addr + I2SMOD);
558 627
@@ -1007,6 +1076,8 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
1007 if (IS_ERR(i2s->pdev)) 1076 if (IS_ERR(i2s->pdev))
1008 return NULL; 1077 return NULL;
1009 1078
1079 i2s->pdev->dev.parent = &pdev->dev;
1080
1010 platform_set_drvdata(i2s->pdev, i2s); 1081 platform_set_drvdata(i2s->pdev, i2s);
1011 ret = platform_device_add(i2s->pdev); 1082 ret = platform_device_add(i2s->pdev);
1012 if (ret < 0) 1083 if (ret < 0)
@@ -1018,18 +1089,18 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
1018 1089
1019static const struct of_device_id exynos_i2s_match[]; 1090static const struct of_device_id exynos_i2s_match[];
1020 1091
1021static inline int samsung_i2s_get_driver_data(struct platform_device *pdev) 1092static inline const struct samsung_i2s_dai_data *samsung_i2s_get_driver_data(
1093 struct platform_device *pdev)
1022{ 1094{
1023#ifdef CONFIG_OF 1095#ifdef CONFIG_OF
1024 struct samsung_i2s_dai_data *data;
1025 if (pdev->dev.of_node) { 1096 if (pdev->dev.of_node) {
1026 const struct of_device_id *match; 1097 const struct of_device_id *match;
1027 match = of_match_node(exynos_i2s_match, pdev->dev.of_node); 1098 match = of_match_node(exynos_i2s_match, pdev->dev.of_node);
1028 data = (struct samsung_i2s_dai_data *) match->data; 1099 return match->data;
1029 return data->dai_type;
1030 } else 1100 } else
1031#endif 1101#endif
1032 return platform_get_device_id(pdev)->driver_data; 1102 return (struct samsung_i2s_dai_data *)
1103 platform_get_device_id(pdev)->driver_data;
1033} 1104}
1034 1105
1035#ifdef CONFIG_PM_RUNTIME 1106#ifdef CONFIG_PM_RUNTIME
@@ -1060,13 +1131,13 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1060 struct resource *res; 1131 struct resource *res;
1061 u32 regs_base, quirks = 0, idma_addr = 0; 1132 u32 regs_base, quirks = 0, idma_addr = 0;
1062 struct device_node *np = pdev->dev.of_node; 1133 struct device_node *np = pdev->dev.of_node;
1063 enum samsung_dai_type samsung_dai_type; 1134 const struct samsung_i2s_dai_data *i2s_dai_data;
1064 int ret = 0; 1135 int ret = 0;
1065 1136
1066 /* Call during Seconday interface registration */ 1137 /* Call during Seconday interface registration */
1067 samsung_dai_type = samsung_i2s_get_driver_data(pdev); 1138 i2s_dai_data = samsung_i2s_get_driver_data(pdev);
1068 1139
1069 if (samsung_dai_type == TYPE_SEC) { 1140 if (i2s_dai_data->dai_type == TYPE_SEC) {
1070 sec_dai = dev_get_drvdata(&pdev->dev); 1141 sec_dai = dev_get_drvdata(&pdev->dev);
1071 if (!sec_dai) { 1142 if (!sec_dai) {
1072 dev_err(&pdev->dev, "Unable to get drvdata\n"); 1143 dev_err(&pdev->dev, "Unable to get drvdata\n");
@@ -1075,7 +1146,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1075 snd_soc_register_component(&sec_dai->pdev->dev, 1146 snd_soc_register_component(&sec_dai->pdev->dev,
1076 &samsung_i2s_component, 1147 &samsung_i2s_component,
1077 &sec_dai->i2s_dai_drv, 1); 1148 &sec_dai->i2s_dai_drv, 1);
1078 asoc_dma_platform_register(&pdev->dev); 1149 samsung_asoc_dma_platform_register(&pdev->dev);
1079 return 0; 1150 return 0;
1080 } 1151 }
1081 1152
@@ -1115,15 +1186,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1115 idma_addr = i2s_cfg->idma_addr; 1186 idma_addr = i2s_cfg->idma_addr;
1116 } 1187 }
1117 } else { 1188 } else {
1118 if (of_find_property(np, "samsung,supports-6ch", NULL)) 1189 quirks = i2s_dai_data->quirks;
1119 quirks |= QUIRK_PRI_6CHAN;
1120
1121 if (of_find_property(np, "samsung,supports-secdai", NULL))
1122 quirks |= QUIRK_SEC_DAI;
1123
1124 if (of_find_property(np, "samsung,supports-rstclr", NULL))
1125 quirks |= QUIRK_NEED_RSTCLR;
1126
1127 if (of_property_read_u32(np, "samsung,idma-addr", 1190 if (of_property_read_u32(np, "samsung,idma-addr",
1128 &idma_addr)) { 1191 &idma_addr)) {
1129 if (quirks & QUIRK_SEC_DAI) { 1192 if (quirks & QUIRK_SEC_DAI) {
@@ -1200,7 +1263,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1200 1263
1201 pm_runtime_enable(&pdev->dev); 1264 pm_runtime_enable(&pdev->dev);
1202 1265
1203 asoc_dma_platform_register(&pdev->dev); 1266 samsung_asoc_dma_platform_register(&pdev->dev);
1204 1267
1205 return 0; 1268 return 0;
1206err: 1269err:
@@ -1230,33 +1293,59 @@ static int samsung_i2s_remove(struct platform_device *pdev)
1230 i2s->pri_dai = NULL; 1293 i2s->pri_dai = NULL;
1231 i2s->sec_dai = NULL; 1294 i2s->sec_dai = NULL;
1232 1295
1233 asoc_dma_platform_unregister(&pdev->dev); 1296 samsung_asoc_dma_platform_unregister(&pdev->dev);
1234 snd_soc_unregister_component(&pdev->dev); 1297 snd_soc_unregister_component(&pdev->dev);
1235 1298
1236 return 0; 1299 return 0;
1237} 1300}
1238 1301
1302static const struct samsung_i2s_dai_data i2sv3_dai_type = {
1303 .dai_type = TYPE_PRI,
1304 .quirks = QUIRK_NO_MUXPSR,
1305};
1306
1307static const struct samsung_i2s_dai_data i2sv5_dai_type = {
1308 .dai_type = TYPE_PRI,
1309 .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR,
1310};
1311
1312static const struct samsung_i2s_dai_data i2sv6_dai_type = {
1313 .dai_type = TYPE_PRI,
1314 .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR |
1315 QUIRK_SUPPORTS_TDM,
1316};
1317
1318static const struct samsung_i2s_dai_data samsung_dai_type_pri = {
1319 .dai_type = TYPE_PRI,
1320};
1321
1322static const struct samsung_i2s_dai_data samsung_dai_type_sec = {
1323 .dai_type = TYPE_SEC,
1324};
1325
1239static struct platform_device_id samsung_i2s_driver_ids[] = { 1326static struct platform_device_id samsung_i2s_driver_ids[] = {
1240 { 1327 {
1241 .name = "samsung-i2s", 1328 .name = "samsung-i2s",
1242 .driver_data = TYPE_PRI, 1329 .driver_data = (kernel_ulong_t)&samsung_dai_type_pri,
1243 }, { 1330 }, {
1244 .name = "samsung-i2s-sec", 1331 .name = "samsung-i2s-sec",
1245 .driver_data = TYPE_SEC, 1332 .driver_data = (kernel_ulong_t)&samsung_dai_type_sec,
1246 }, 1333 },
1247 {}, 1334 {},
1248}; 1335};
1249MODULE_DEVICE_TABLE(platform, samsung_i2s_driver_ids); 1336MODULE_DEVICE_TABLE(platform, samsung_i2s_driver_ids);
1250 1337
1251#ifdef CONFIG_OF 1338#ifdef CONFIG_OF
1252static struct samsung_i2s_dai_data samsung_i2s_dai_data_array[] = {
1253 [TYPE_PRI] = { TYPE_PRI },
1254 [TYPE_SEC] = { TYPE_SEC },
1255};
1256
1257static const struct of_device_id exynos_i2s_match[] = { 1339static const struct of_device_id exynos_i2s_match[] = {
1258 { .compatible = "samsung,i2s-v5", 1340 {
1259 .data = &samsung_i2s_dai_data_array[TYPE_PRI], 1341 .compatible = "samsung,s3c6410-i2s",
1342 .data = &i2sv3_dai_type,
1343 }, {
1344 .compatible = "samsung,s5pv210-i2s",
1345 .data = &i2sv5_dai_type,
1346 }, {
1347 .compatible = "samsung,exynos5420-i2s",
1348 .data = &i2sv6_dai_type,
1260 }, 1349 },
1261 {}, 1350 {},
1262}; 1351};
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c
index 1566afe9ef52..e54256fc4b2c 100644
--- a/sound/soc/samsung/pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -594,7 +594,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
594 goto err5; 594 goto err5;
595 } 595 }
596 596
597 ret = asoc_dma_platform_register(&pdev->dev); 597 ret = samsung_asoc_dma_platform_register(&pdev->dev);
598 if (ret) { 598 if (ret) {
599 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); 599 dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
600 goto err6; 600 goto err6;
@@ -623,7 +623,7 @@ static int s3c_pcm_dev_remove(struct platform_device *pdev)
623 struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id]; 623 struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id];
624 struct resource *mem_res; 624 struct resource *mem_res;
625 625
626 asoc_dma_platform_unregister(&pdev->dev); 626 samsung_asoc_dma_platform_unregister(&pdev->dev);
627 snd_soc_unregister_component(&pdev->dev); 627 snd_soc_unregister_component(&pdev->dev);
628 628
629 pm_runtime_disable(&pdev->dev); 629 pm_runtime_disable(&pdev->dev);
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 47e23864ea72..ea885cb9f76c 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -176,7 +176,7 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
176 return ret; 176 return ret;
177 } 177 }
178 178
179 ret = asoc_dma_platform_register(&pdev->dev); 179 ret = samsung_asoc_dma_platform_register(&pdev->dev);
180 if (ret) { 180 if (ret) {
181 pr_err("failed to register the DMA: %d\n", ret); 181 pr_err("failed to register the DMA: %d\n", ret);
182 goto err; 182 goto err;
@@ -190,7 +190,7 @@ err:
190 190
191static int s3c2412_iis_dev_remove(struct platform_device *pdev) 191static int s3c2412_iis_dev_remove(struct platform_device *pdev)
192{ 192{
193 asoc_dma_platform_unregister(&pdev->dev); 193 samsung_asoc_dma_platform_unregister(&pdev->dev);
194 snd_soc_unregister_component(&pdev->dev); 194 snd_soc_unregister_component(&pdev->dev);
195 return 0; 195 return 0;
196} 196}
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index 8b3414551a62..9c8ebd872fac 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -480,7 +480,7 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
480 return ret; 480 return ret;
481 } 481 }
482 482
483 ret = asoc_dma_platform_register(&pdev->dev); 483 ret = samsung_asoc_dma_platform_register(&pdev->dev);
484 if (ret) { 484 if (ret) {
485 pr_err("failed to register the dma: %d\n", ret); 485 pr_err("failed to register the dma: %d\n", ret);
486 goto err; 486 goto err;
@@ -494,7 +494,7 @@ err:
494 494
495static int s3c24xx_iis_dev_remove(struct platform_device *pdev) 495static int s3c24xx_iis_dev_remove(struct platform_device *pdev)
496{ 496{
497 asoc_dma_platform_unregister(&pdev->dev); 497 samsung_asoc_dma_platform_unregister(&pdev->dev);
498 snd_soc_unregister_component(&pdev->dev); 498 snd_soc_unregister_component(&pdev->dev);
499 return 0; 499 return 0;
500} 500}
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c
index 581ea4a06fc6..5fd7a05a9b9e 100644
--- a/sound/soc/samsung/smdk_wm8994.c
+++ b/sound/soc/samsung/smdk_wm8994.c
@@ -11,6 +11,7 @@
11#include <sound/pcm_params.h> 11#include <sound/pcm_params.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/of.h> 13#include <linux/of.h>
14#include <linux/of_device.h>
14 15
15 /* 16 /*
16 * Default CFG switch settings to use this driver: 17 * Default CFG switch settings to use this driver:
@@ -37,11 +38,19 @@
37/* SMDK has a 16.934MHZ crystal attached to WM8994 */ 38/* SMDK has a 16.934MHZ crystal attached to WM8994 */
38#define SMDK_WM8994_FREQ 16934000 39#define SMDK_WM8994_FREQ 16934000
39 40
41struct smdk_wm8994_data {
42 int mclk1_rate;
43};
44
45/* Default SMDKs */
46static struct smdk_wm8994_data smdk_board_data = {
47 .mclk1_rate = SMDK_WM8994_FREQ,
48};
49
40static int smdk_hw_params(struct snd_pcm_substream *substream, 50static int smdk_hw_params(struct snd_pcm_substream *substream,
41 struct snd_pcm_hw_params *params) 51 struct snd_pcm_hw_params *params)
42{ 52{
43 struct snd_soc_pcm_runtime *rtd = substream->private_data; 53 struct snd_soc_pcm_runtime *rtd = substream->private_data;
44 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
45 struct snd_soc_dai *codec_dai = rtd->codec_dai; 54 struct snd_soc_dai *codec_dai = rtd->codec_dai;
46 unsigned int pll_out; 55 unsigned int pll_out;
47 int ret; 56 int ret;
@@ -54,18 +63,6 @@ static int smdk_hw_params(struct snd_pcm_substream *substream,
54 else 63 else
55 pll_out = params_rate(params) * 256; 64 pll_out = params_rate(params) * 256;
56 65
57 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
58 | SND_SOC_DAIFMT_NB_NF
59 | SND_SOC_DAIFMT_CBM_CFM);
60 if (ret < 0)
61 return ret;
62
63 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
64 | SND_SOC_DAIFMT_NB_NF
65 | SND_SOC_DAIFMT_CBM_CFM);
66 if (ret < 0)
67 return ret;
68
69 ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1, 66 ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1,
70 SMDK_WM8994_FREQ, pll_out); 67 SMDK_WM8994_FREQ, pll_out);
71 if (ret < 0) 68 if (ret < 0)
@@ -131,6 +128,8 @@ static struct snd_soc_dai_link smdk_dai[] = {
131 .platform_name = "samsung-i2s.0", 128 .platform_name = "samsung-i2s.0",
132 .codec_name = "wm8994-codec", 129 .codec_name = "wm8994-codec",
133 .init = smdk_wm8994_init_paiftx, 130 .init = smdk_wm8994_init_paiftx,
131 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
132 SND_SOC_DAIFMT_CBM_CFM,
134 .ops = &smdk_ops, 133 .ops = &smdk_ops,
135 }, { /* Sec_Fifo Playback i/f */ 134 }, { /* Sec_Fifo Playback i/f */
136 .name = "Sec_FIFO TX", 135 .name = "Sec_FIFO TX",
@@ -139,6 +138,8 @@ static struct snd_soc_dai_link smdk_dai[] = {
139 .codec_dai_name = "wm8994-aif1", 138 .codec_dai_name = "wm8994-aif1",
140 .platform_name = "samsung-i2s-sec", 139 .platform_name = "samsung-i2s-sec",
141 .codec_name = "wm8994-codec", 140 .codec_name = "wm8994-codec",
141 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
142 SND_SOC_DAIFMT_CBM_CFM,
142 .ops = &smdk_ops, 143 .ops = &smdk_ops,
143 }, 144 },
144}; 145};
@@ -150,15 +151,28 @@ static struct snd_soc_card smdk = {
150 .num_links = ARRAY_SIZE(smdk_dai), 151 .num_links = ARRAY_SIZE(smdk_dai),
151}; 152};
152 153
154#ifdef CONFIG_OF
155static const struct of_device_id samsung_wm8994_of_match[] = {
156 { .compatible = "samsung,smdk-wm8994", .data = &smdk_board_data },
157 {},
158};
159MODULE_DEVICE_TABLE(of, samsung_wm8994_of_match);
160#endif /* CONFIG_OF */
153 161
154static int smdk_audio_probe(struct platform_device *pdev) 162static int smdk_audio_probe(struct platform_device *pdev)
155{ 163{
156 int ret; 164 int ret;
157 struct device_node *np = pdev->dev.of_node; 165 struct device_node *np = pdev->dev.of_node;
158 struct snd_soc_card *card = &smdk; 166 struct snd_soc_card *card = &smdk;
167 struct smdk_wm8994_data *board;
168 const struct of_device_id *id;
159 169
160 card->dev = &pdev->dev; 170 card->dev = &pdev->dev;
161 171
172 board = devm_kzalloc(&pdev->dev, sizeof(*board), GFP_KERNEL);
173 if (!board)
174 return -ENOMEM;
175
162 if (np) { 176 if (np) {
163 smdk_dai[0].cpu_dai_name = NULL; 177 smdk_dai[0].cpu_dai_name = NULL;
164 smdk_dai[0].cpu_of_node = of_parse_phandle(np, 178 smdk_dai[0].cpu_of_node = of_parse_phandle(np,
@@ -173,6 +187,12 @@ static int smdk_audio_probe(struct platform_device *pdev)
173 smdk_dai[0].platform_of_node = smdk_dai[0].cpu_of_node; 187 smdk_dai[0].platform_of_node = smdk_dai[0].cpu_of_node;
174 } 188 }
175 189
190 id = of_match_device(samsung_wm8994_of_match, &pdev->dev);
191 if (id)
192 *board = *((struct smdk_wm8994_data *)id->data);
193
194 platform_set_drvdata(pdev, board);
195
176 ret = snd_soc_register_card(card); 196 ret = snd_soc_register_card(card);
177 197
178 if (ret) 198 if (ret)
@@ -190,17 +210,9 @@ static int smdk_audio_remove(struct platform_device *pdev)
190 return 0; 210 return 0;
191} 211}
192 212
193#ifdef CONFIG_OF
194static const struct of_device_id samsung_wm8994_of_match[] = {
195 { .compatible = "samsung,smdk-wm8994", },
196 {},
197};
198MODULE_DEVICE_TABLE(of, samsung_wm8994_of_match);
199#endif /* CONFIG_OF */
200
201static struct platform_driver smdk_audio_driver = { 213static struct platform_driver smdk_audio_driver = {
202 .driver = { 214 .driver = {
203 .name = "smdk-audio", 215 .name = "smdk-audio-wm8894",
204 .owner = THIS_MODULE, 216 .owner = THIS_MODULE,
205 .of_match_table = of_match_ptr(samsung_wm8994_of_match), 217 .of_match_table = of_match_ptr(samsung_wm8994_of_match),
206 }, 218 },
@@ -212,4 +224,4 @@ module_platform_driver(smdk_audio_driver);
212 224
213MODULE_DESCRIPTION("ALSA SoC SMDK WM8994"); 225MODULE_DESCRIPTION("ALSA SoC SMDK WM8994");
214MODULE_LICENSE("GPL"); 226MODULE_LICENSE("GPL");
215MODULE_ALIAS("platform:smdk-audio"); 227MODULE_ALIAS("platform:smdk-audio-wm8994");
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c
index 2e5ebb2f1982..28487dcc4538 100644
--- a/sound/soc/samsung/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -395,7 +395,7 @@ static int spdif_probe(struct platform_device *pdev)
395 395
396 spin_lock_init(&spdif->lock); 396 spin_lock_init(&spdif->lock);
397 397
398 spdif->pclk = clk_get(&pdev->dev, "spdif"); 398 spdif->pclk = devm_clk_get(&pdev->dev, "spdif");
399 if (IS_ERR(spdif->pclk)) { 399 if (IS_ERR(spdif->pclk)) {
400 dev_err(&pdev->dev, "failed to get peri-clock\n"); 400 dev_err(&pdev->dev, "failed to get peri-clock\n");
401 ret = -ENOENT; 401 ret = -ENOENT;
@@ -403,7 +403,7 @@ static int spdif_probe(struct platform_device *pdev)
403 } 403 }
404 clk_prepare_enable(spdif->pclk); 404 clk_prepare_enable(spdif->pclk);
405 405
406 spdif->sclk = clk_get(&pdev->dev, "sclk_spdif"); 406 spdif->sclk = devm_clk_get(&pdev->dev, "sclk_spdif");
407 if (IS_ERR(spdif->sclk)) { 407 if (IS_ERR(spdif->sclk)) {
408 dev_err(&pdev->dev, "failed to get internal source clock\n"); 408 dev_err(&pdev->dev, "failed to get internal source clock\n");
409 ret = -ENOENT; 409 ret = -ENOENT;
@@ -442,7 +442,7 @@ static int spdif_probe(struct platform_device *pdev)
442 442
443 spdif->dma_playback = &spdif_stereo_out; 443 spdif->dma_playback = &spdif_stereo_out;
444 444
445 ret = asoc_dma_platform_register(&pdev->dev); 445 ret = samsung_asoc_dma_platform_register(&pdev->dev);
446 if (ret) { 446 if (ret) {
447 dev_err(&pdev->dev, "failed to register DMA: %d\n", ret); 447 dev_err(&pdev->dev, "failed to register DMA: %d\n", ret);
448 goto err5; 448 goto err5;
@@ -457,10 +457,8 @@ err3:
457 release_mem_region(mem_res->start, resource_size(mem_res)); 457 release_mem_region(mem_res->start, resource_size(mem_res));
458err2: 458err2:
459 clk_disable_unprepare(spdif->sclk); 459 clk_disable_unprepare(spdif->sclk);
460 clk_put(spdif->sclk);
461err1: 460err1:
462 clk_disable_unprepare(spdif->pclk); 461 clk_disable_unprepare(spdif->pclk);
463 clk_put(spdif->pclk);
464err0: 462err0:
465 return ret; 463 return ret;
466} 464}
@@ -470,7 +468,7 @@ static int spdif_remove(struct platform_device *pdev)
470 struct samsung_spdif_info *spdif = &spdif_info; 468 struct samsung_spdif_info *spdif = &spdif_info;
471 struct resource *mem_res; 469 struct resource *mem_res;
472 470
473 asoc_dma_platform_unregister(&pdev->dev); 471 samsung_asoc_dma_platform_unregister(&pdev->dev);
474 snd_soc_unregister_component(&pdev->dev); 472 snd_soc_unregister_component(&pdev->dev);
475 473
476 iounmap(spdif->regs); 474 iounmap(spdif->regs);
@@ -480,9 +478,7 @@ static int spdif_remove(struct platform_device *pdev)
480 release_mem_region(mem_res->start, resource_size(mem_res)); 478 release_mem_region(mem_res->start, resource_size(mem_res));
481 479
482 clk_disable_unprepare(spdif->sclk); 480 clk_disable_unprepare(spdif->sclk);
483 clk_put(spdif->sclk);
484 clk_disable_unprepare(spdif->pclk); 481 clk_disable_unprepare(spdif->pclk);
485 clk_put(spdif->pclk);
486 482
487 return 0; 483 return 0;
488} 484}
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 6bcb1164d599..56d8ff6a402d 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -34,6 +34,13 @@ config SND_SOC_SH4_SIU
34 select SH_DMAE 34 select SH_DMAE
35 select FW_LOADER 35 select FW_LOADER
36 36
37config SND_SOC_RCAR
38 tristate "R-Car series SRU/SCU/SSIU/SSI support"
39 select SND_SIMPLE_CARD
40 select RCAR_CLK_ADG
41 help
42 This option enables R-Car SUR/SCU/SSIU/SSI sound support
43
37## 44##
38## Boards 45## Boards
39## 46##
diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile
index 849b387d17d9..aaf3dcd1ee2a 100644
--- a/sound/soc/sh/Makefile
+++ b/sound/soc/sh/Makefile
@@ -12,6 +12,9 @@ obj-$(CONFIG_SND_SOC_SH4_SSI) += snd-soc-ssi.o
12obj-$(CONFIG_SND_SOC_SH4_FSI) += snd-soc-fsi.o 12obj-$(CONFIG_SND_SOC_SH4_FSI) += snd-soc-fsi.o
13obj-$(CONFIG_SND_SOC_SH4_SIU) += snd-soc-siu.o 13obj-$(CONFIG_SND_SOC_SH4_SIU) += snd-soc-siu.o
14 14
15## audio units for R-Car
16obj-$(CONFIG_SND_SOC_RCAR) += rcar/
17
15## boards 18## boards
16snd-soc-sh7760-ac97-objs := sh7760-ac97.o 19snd-soc-sh7760-ac97-objs := sh7760-ac97.o
17snd-soc-migor-objs := migor.o 20snd-soc-migor-objs := migor.o
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 30390260bb67..b33ca7cd085b 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -235,6 +235,8 @@ struct fsi_stream {
235 struct sh_dmae_slave slave; /* see fsi_handler_init() */ 235 struct sh_dmae_slave slave; /* see fsi_handler_init() */
236 struct work_struct work; 236 struct work_struct work;
237 dma_addr_t dma; 237 dma_addr_t dma;
238 int loop_cnt;
239 int additional_pos;
238}; 240};
239 241
240struct fsi_clk { 242struct fsi_clk {
@@ -1289,6 +1291,8 @@ static int fsi_dma_init(struct fsi_priv *fsi, struct fsi_stream *io)
1289 io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | 1291 io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) |
1290 BUSOP_SET(16, PACKAGE_16BITBUS_STREAM); 1292 BUSOP_SET(16, PACKAGE_16BITBUS_STREAM);
1291 1293
1294 io->loop_cnt = 2; /* push 1st, 2nd period first, then 3rd, 4th... */
1295 io->additional_pos = 0;
1292 io->dma = dma_map_single(dai->dev, runtime->dma_area, 1296 io->dma = dma_map_single(dai->dev, runtime->dma_area,
1293 snd_pcm_lib_buffer_bytes(io->substream), dir); 1297 snd_pcm_lib_buffer_bytes(io->substream), dir);
1294 return 0; 1298 return 0;
@@ -1305,11 +1309,15 @@ static int fsi_dma_quit(struct fsi_priv *fsi, struct fsi_stream *io)
1305 return 0; 1309 return 0;
1306} 1310}
1307 1311
1308static dma_addr_t fsi_dma_get_area(struct fsi_stream *io) 1312static dma_addr_t fsi_dma_get_area(struct fsi_stream *io, int additional)
1309{ 1313{
1310 struct snd_pcm_runtime *runtime = io->substream->runtime; 1314 struct snd_pcm_runtime *runtime = io->substream->runtime;
1315 int period = io->period_pos + additional;
1311 1316
1312 return io->dma + samples_to_bytes(runtime, io->buff_sample_pos); 1317 if (period >= runtime->periods)
1318 period = 0;
1319
1320 return io->dma + samples_to_bytes(runtime, period * io->period_samples);
1313} 1321}
1314 1322
1315static void fsi_dma_complete(void *data) 1323static void fsi_dma_complete(void *data)
@@ -1321,7 +1329,7 @@ static void fsi_dma_complete(void *data)
1321 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ? 1329 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
1322 DMA_TO_DEVICE : DMA_FROM_DEVICE; 1330 DMA_TO_DEVICE : DMA_FROM_DEVICE;
1323 1331
1324 dma_sync_single_for_cpu(dai->dev, fsi_dma_get_area(io), 1332 dma_sync_single_for_cpu(dai->dev, fsi_dma_get_area(io, 0),
1325 samples_to_bytes(runtime, io->period_samples), dir); 1333 samples_to_bytes(runtime, io->period_samples), dir);
1326 1334
1327 io->buff_sample_pos += io->period_samples; 1335 io->buff_sample_pos += io->period_samples;
@@ -1347,7 +1355,7 @@ static void fsi_dma_do_work(struct work_struct *work)
1347 struct snd_pcm_runtime *runtime; 1355 struct snd_pcm_runtime *runtime;
1348 enum dma_data_direction dir; 1356 enum dma_data_direction dir;
1349 int is_play = fsi_stream_is_play(fsi, io); 1357 int is_play = fsi_stream_is_play(fsi, io);
1350 int len; 1358 int len, i;
1351 dma_addr_t buf; 1359 dma_addr_t buf;
1352 1360
1353 if (!fsi_stream_is_working(fsi, io)) 1361 if (!fsi_stream_is_working(fsi, io))
@@ -1357,26 +1365,33 @@ static void fsi_dma_do_work(struct work_struct *work)
1357 runtime = io->substream->runtime; 1365 runtime = io->substream->runtime;
1358 dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; 1366 dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
1359 len = samples_to_bytes(runtime, io->period_samples); 1367 len = samples_to_bytes(runtime, io->period_samples);
1360 buf = fsi_dma_get_area(io);
1361 1368
1362 dma_sync_single_for_device(dai->dev, buf, len, dir); 1369 for (i = 0; i < io->loop_cnt; i++) {
1370 buf = fsi_dma_get_area(io, io->additional_pos);
1363 1371
1364 desc = dmaengine_prep_slave_single(io->chan, buf, len, dir, 1372 dma_sync_single_for_device(dai->dev, buf, len, dir);
1365 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
1366 if (!desc) {
1367 dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n");
1368 return;
1369 }
1370 1373
1371 desc->callback = fsi_dma_complete; 1374 desc = dmaengine_prep_slave_single(io->chan, buf, len, dir,
1372 desc->callback_param = io; 1375 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
1376 if (!desc) {
1377 dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n");
1378 return;
1379 }
1373 1380
1374 if (dmaengine_submit(desc) < 0) { 1381 desc->callback = fsi_dma_complete;
1375 dev_err(dai->dev, "tx_submit() fail\n"); 1382 desc->callback_param = io;
1376 return; 1383
1384 if (dmaengine_submit(desc) < 0) {
1385 dev_err(dai->dev, "tx_submit() fail\n");
1386 return;
1387 }
1388
1389 dma_async_issue_pending(io->chan);
1390
1391 io->additional_pos = 1;
1377 } 1392 }
1378 1393
1379 dma_async_issue_pending(io->chan); 1394 io->loop_cnt = 1;
1380 1395
1381 /* 1396 /*
1382 * FIXME 1397 * FIXME
diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile
new file mode 100644
index 000000000000..0ff492df7929
--- /dev/null
+++ b/sound/soc/sh/rcar/Makefile
@@ -0,0 +1,2 @@
1snd-soc-rcar-objs := core.o gen.o scu.o adg.o ssi.o
2obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o \ No newline at end of file
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
new file mode 100644
index 000000000000..d80deb7ccf13
--- /dev/null
+++ b/sound/soc/sh/rcar/adg.c
@@ -0,0 +1,234 @@
1/*
2 * Helper routines for R-Car sound ADG.
3 *
4 * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/sh_clk.h>
11#include <mach/clock.h>
12#include "rsnd.h"
13
14#define CLKA 0
15#define CLKB 1
16#define CLKC 2
17#define CLKI 3
18#define CLKMAX 4
19
20struct rsnd_adg {
21 struct clk *clk[CLKMAX];
22
23 int rate_of_441khz_div_6;
24 int rate_of_48khz_div_6;
25};
26
27#define for_each_rsnd_clk(pos, adg, i) \
28 for (i = 0, (pos) = adg->clk[i]; \
29 i < CLKMAX; \
30 i++, (pos) = adg->clk[i])
31#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)
32
33static enum rsnd_reg rsnd_adg_ssi_reg_get(int id)
34{
35 enum rsnd_reg reg;
36
37 /*
38 * SSI 8 is not connected to ADG.
39 * it works with SSI 7
40 */
41 if (id == 8)
42 return RSND_REG_MAX;
43
44 if (0 <= id && id <= 3)
45 reg = RSND_REG_AUDIO_CLK_SEL0;
46 else if (4 <= id && id <= 7)
47 reg = RSND_REG_AUDIO_CLK_SEL1;
48 else
49 reg = RSND_REG_AUDIO_CLK_SEL2;
50
51 return reg;
52}
53
54int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod)
55{
56 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
57 enum rsnd_reg reg;
58 int id;
59
60 /*
61 * "mod" = "ssi" here.
62 * we can get "ssi id" from mod
63 */
64 id = rsnd_mod_id(mod);
65 reg = rsnd_adg_ssi_reg_get(id);
66
67 rsnd_write(priv, mod, reg, 0);
68
69 return 0;
70}
71
72int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate)
73{
74 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
75 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
76 struct device *dev = rsnd_priv_to_dev(priv);
77 struct clk *clk;
78 enum rsnd_reg reg;
79 int id, shift, i;
80 u32 data;
81 int sel_table[] = {
82 [CLKA] = 0x1,
83 [CLKB] = 0x2,
84 [CLKC] = 0x3,
85 [CLKI] = 0x0,
86 };
87
88 dev_dbg(dev, "request clock = %d\n", rate);
89
90 /*
91 * find suitable clock from
92 * AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC/AUDIO_CLKI.
93 */
94 data = 0;
95 for_each_rsnd_clk(clk, adg, i) {
96 if (rate == clk_get_rate(clk)) {
97 data = sel_table[i];
98 goto found_clock;
99 }
100 }
101
102 /*
103 * find 1/6 clock from BRGA/BRGB
104 */
105 if (rate == adg->rate_of_441khz_div_6) {
106 data = 0x10;
107 goto found_clock;
108 }
109
110 if (rate == adg->rate_of_48khz_div_6) {
111 data = 0x20;
112 goto found_clock;
113 }
114
115 return -EIO;
116
117found_clock:
118
119 /*
120 * This "mod" = "ssi" here.
121 * we can get "ssi id" from mod
122 */
123 id = rsnd_mod_id(mod);
124 reg = rsnd_adg_ssi_reg_get(id);
125
126 dev_dbg(dev, "ADG: ssi%d selects clk%d = %d", id, i, rate);
127
128 /*
129 * Enable SSIx clock
130 */
131 shift = (id % 4) * 8;
132
133 rsnd_bset(priv, mod, reg,
134 0xFF << shift,
135 data << shift);
136
137 return 0;
138}
139
140static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)
141{
142 struct clk *clk;
143 unsigned long rate;
144 u32 ckr;
145 int i;
146 int brg_table[] = {
147 [CLKA] = 0x0,
148 [CLKB] = 0x1,
149 [CLKC] = 0x4,
150 [CLKI] = 0x2,
151 };
152
153 /*
154 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC
155 * have 44.1kHz or 48kHz base clocks for now.
156 *
157 * SSI itself can divide parent clock by 1/1 - 1/16
158 * So, BRGA outputs 44.1kHz base parent clock 1/32,
159 * and, BRGB outputs 48.0kHz base parent clock 1/32 here.
160 * see
161 * rsnd_adg_ssi_clk_try_start()
162 */
163 ckr = 0;
164 adg->rate_of_441khz_div_6 = 0;
165 adg->rate_of_48khz_div_6 = 0;
166 for_each_rsnd_clk(clk, adg, i) {
167 rate = clk_get_rate(clk);
168
169 if (0 == rate) /* not used */
170 continue;
171
172 /* RBGA */
173 if (!adg->rate_of_441khz_div_6 && (0 == rate % 44100)) {
174 adg->rate_of_441khz_div_6 = rate / 6;
175 ckr |= brg_table[i] << 20;
176 }
177
178 /* RBGB */
179 if (!adg->rate_of_48khz_div_6 && (0 == rate % 48000)) {
180 adg->rate_of_48khz_div_6 = rate / 6;
181 ckr |= brg_table[i] << 16;
182 }
183 }
184
185 rsnd_priv_bset(priv, SSICKR, 0x00FF0000, ckr);
186 rsnd_priv_write(priv, BRRA, 0x00000002); /* 1/6 */
187 rsnd_priv_write(priv, BRRB, 0x00000002); /* 1/6 */
188}
189
190int rsnd_adg_probe(struct platform_device *pdev,
191 struct rcar_snd_info *info,
192 struct rsnd_priv *priv)
193{
194 struct rsnd_adg *adg;
195 struct device *dev = rsnd_priv_to_dev(priv);
196 struct clk *clk;
197 int i;
198
199 adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL);
200 if (!adg) {
201 dev_err(dev, "ADG allocate failed\n");
202 return -ENOMEM;
203 }
204
205 adg->clk[CLKA] = clk_get(NULL, "audio_clk_a");
206 adg->clk[CLKB] = clk_get(NULL, "audio_clk_b");
207 adg->clk[CLKC] = clk_get(NULL, "audio_clk_c");
208 adg->clk[CLKI] = clk_get(NULL, "audio_clk_internal");
209 for_each_rsnd_clk(clk, adg, i) {
210 if (IS_ERR(clk)) {
211 dev_err(dev, "Audio clock failed\n");
212 return -EIO;
213 }
214 }
215
216 rsnd_adg_ssi_clk_init(priv, adg);
217
218 priv->adg = adg;
219
220 dev_dbg(dev, "adg probed\n");
221
222 return 0;
223}
224
225void rsnd_adg_remove(struct platform_device *pdev,
226 struct rsnd_priv *priv)
227{
228 struct rsnd_adg *adg = priv->adg;
229 struct clk *clk;
230 int i;
231
232 for_each_rsnd_clk(clk, adg, i)
233 clk_put(clk);
234}
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
new file mode 100644
index 000000000000..a35706028514
--- /dev/null
+++ b/sound/soc/sh/rcar/core.c
@@ -0,0 +1,861 @@
1/*
2 * Renesas R-Car SRU/SCU/SSIU/SSI support
3 *
4 * Copyright (C) 2013 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * Based on fsi.c
8 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15/*
16 * Renesas R-Car sound device structure
17 *
18 * Gen1
19 *
20 * SRU : Sound Routing Unit
21 * - SRC : Sampling Rate Converter
22 * - CMD
23 * - CTU : Channel Count Conversion Unit
24 * - MIX : Mixer
25 * - DVC : Digital Volume and Mute Function
26 * - SSI : Serial Sound Interface
27 *
28 * Gen2
29 *
30 * SCU : Sampling Rate Converter Unit
31 * - SRC : Sampling Rate Converter
32 * - CMD
33 * - CTU : Channel Count Conversion Unit
34 * - MIX : Mixer
35 * - DVC : Digital Volume and Mute Function
36 * SSIU : Serial Sound Interface Unit
37 * - SSI : Serial Sound Interface
38 */
39
40/*
41 * driver data Image
42 *
43 * rsnd_priv
44 * |
45 * | ** this depends on Gen1/Gen2
46 * |
47 * +- gen
48 * |
49 * | ** these depend on data path
50 * | ** gen and platform data control it
51 * |
52 * +- rdai[0]
53 * | | sru ssiu ssi
54 * | +- playback -> [mod] -> [mod] -> [mod] -> ...
55 * | |
56 * | | sru ssiu ssi
57 * | +- capture -> [mod] -> [mod] -> [mod] -> ...
58 * |
59 * +- rdai[1]
60 * | | sru ssiu ssi
61 * | +- playback -> [mod] -> [mod] -> [mod] -> ...
62 * | |
63 * | | sru ssiu ssi
64 * | +- capture -> [mod] -> [mod] -> [mod] -> ...
65 * ...
66 * |
67 * | ** these control ssi
68 * |
69 * +- ssi
70 * | |
71 * | +- ssi[0]
72 * | +- ssi[1]
73 * | +- ssi[2]
74 * | ...
75 * |
76 * | ** these control scu
77 * |
78 * +- scu
79 * |
80 * +- scu[0]
81 * +- scu[1]
82 * +- scu[2]
83 * ...
84 *
85 *
86 * for_each_rsnd_dai(xx, priv, xx)
87 * rdai[0] => rdai[1] => rdai[2] => ...
88 *
89 * for_each_rsnd_mod(xx, rdai, xx)
90 * [mod] => [mod] => [mod] => ...
91 *
92 * rsnd_dai_call(xxx, fn )
93 * [mod]->fn() -> [mod]->fn() -> [mod]->fn()...
94 *
95 */
96#include <linux/pm_runtime.h>
97#include "rsnd.h"
98
99#define RSND_RATES SNDRV_PCM_RATE_8000_96000
100#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
101
102/*
103 * rsnd_platform functions
104 */
105#define rsnd_platform_call(priv, dai, func, param...) \
106 (!(priv->info->func) ? -ENODEV : \
107 priv->info->func(param))
108
109
110/*
111 * basic function
112 */
113u32 rsnd_read(struct rsnd_priv *priv,
114 struct rsnd_mod *mod, enum rsnd_reg reg)
115{
116 void __iomem *base = rsnd_gen_reg_get(priv, mod, reg);
117
118 BUG_ON(!base);
119
120 return ioread32(base);
121}
122
123void rsnd_write(struct rsnd_priv *priv,
124 struct rsnd_mod *mod,
125 enum rsnd_reg reg, u32 data)
126{
127 void __iomem *base = rsnd_gen_reg_get(priv, mod, reg);
128 struct device *dev = rsnd_priv_to_dev(priv);
129
130 BUG_ON(!base);
131
132 dev_dbg(dev, "w %p : %08x\n", base, data);
133
134 iowrite32(data, base);
135}
136
137void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
138 enum rsnd_reg reg, u32 mask, u32 data)
139{
140 void __iomem *base = rsnd_gen_reg_get(priv, mod, reg);
141 struct device *dev = rsnd_priv_to_dev(priv);
142 u32 val;
143
144 BUG_ON(!base);
145
146 val = ioread32(base);
147 val &= ~mask;
148 val |= data & mask;
149 iowrite32(val, base);
150
151 dev_dbg(dev, "s %p : %08x\n", base, val);
152}
153
154/*
155 * rsnd_mod functions
156 */
157char *rsnd_mod_name(struct rsnd_mod *mod)
158{
159 if (!mod || !mod->ops)
160 return "unknown";
161
162 return mod->ops->name;
163}
164
165void rsnd_mod_init(struct rsnd_priv *priv,
166 struct rsnd_mod *mod,
167 struct rsnd_mod_ops *ops,
168 int id)
169{
170 mod->priv = priv;
171 mod->id = id;
172 mod->ops = ops;
173 INIT_LIST_HEAD(&mod->list);
174}
175
176/*
177 * rsnd_dma functions
178 */
179static void rsnd_dma_continue(struct rsnd_dma *dma)
180{
181 /* push next A or B plane */
182 dma->submit_loop = 1;
183 schedule_work(&dma->work);
184}
185
186void rsnd_dma_start(struct rsnd_dma *dma)
187{
188 /* push both A and B plane*/
189 dma->submit_loop = 2;
190 schedule_work(&dma->work);
191}
192
193void rsnd_dma_stop(struct rsnd_dma *dma)
194{
195 dma->submit_loop = 0;
196 cancel_work_sync(&dma->work);
197 dmaengine_terminate_all(dma->chan);
198}
199
200static void rsnd_dma_complete(void *data)
201{
202 struct rsnd_dma *dma = (struct rsnd_dma *)data;
203 struct rsnd_priv *priv = dma->priv;
204 unsigned long flags;
205
206 rsnd_lock(priv, flags);
207
208 dma->complete(dma);
209
210 if (dma->submit_loop)
211 rsnd_dma_continue(dma);
212
213 rsnd_unlock(priv, flags);
214}
215
216static void rsnd_dma_do_work(struct work_struct *work)
217{
218 struct rsnd_dma *dma = container_of(work, struct rsnd_dma, work);
219 struct rsnd_priv *priv = dma->priv;
220 struct device *dev = rsnd_priv_to_dev(priv);
221 struct dma_async_tx_descriptor *desc;
222 dma_addr_t buf;
223 size_t len;
224 int i;
225
226 for (i = 0; i < dma->submit_loop; i++) {
227
228 if (dma->inquiry(dma, &buf, &len) < 0)
229 return;
230
231 desc = dmaengine_prep_slave_single(
232 dma->chan, buf, len, dma->dir,
233 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
234 if (!desc) {
235 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
236 return;
237 }
238
239 desc->callback = rsnd_dma_complete;
240 desc->callback_param = dma;
241
242 if (dmaengine_submit(desc) < 0) {
243 dev_err(dev, "dmaengine_submit() fail\n");
244 return;
245 }
246
247 }
248
249 dma_async_issue_pending(dma->chan);
250}
251
252int rsnd_dma_available(struct rsnd_dma *dma)
253{
254 return !!dma->chan;
255}
256
257static bool rsnd_dma_filter(struct dma_chan *chan, void *param)
258{
259 chan->private = param;
260
261 return true;
262}
263
264int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
265 int is_play, int id,
266 int (*inquiry)(struct rsnd_dma *dma,
267 dma_addr_t *buf, int *len),
268 int (*complete)(struct rsnd_dma *dma))
269{
270 struct device *dev = rsnd_priv_to_dev(priv);
271 dma_cap_mask_t mask;
272
273 if (dma->chan) {
274 dev_err(dev, "it already has dma channel\n");
275 return -EIO;
276 }
277
278 dma_cap_zero(mask);
279 dma_cap_set(DMA_SLAVE, mask);
280
281 dma->slave.shdma_slave.slave_id = id;
282
283 dma->chan = dma_request_channel(mask, rsnd_dma_filter,
284 &dma->slave.shdma_slave);
285 if (!dma->chan) {
286 dev_err(dev, "can't get dma channel\n");
287 return -EIO;
288 }
289
290 dma->dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
291 dma->priv = priv;
292 dma->inquiry = inquiry;
293 dma->complete = complete;
294 INIT_WORK(&dma->work, rsnd_dma_do_work);
295
296 return 0;
297}
298
299void rsnd_dma_quit(struct rsnd_priv *priv,
300 struct rsnd_dma *dma)
301{
302 if (dma->chan)
303 dma_release_channel(dma->chan);
304
305 dma->chan = NULL;
306}
307
308/*
309 * rsnd_dai functions
310 */
311#define rsnd_dai_call(rdai, io, fn) \
312({ \
313 struct rsnd_mod *mod, *n; \
314 int ret = 0; \
315 for_each_rsnd_mod(mod, n, io) { \
316 ret = rsnd_mod_call(mod, fn, rdai, io); \
317 if (ret < 0) \
318 break; \
319 } \
320 ret; \
321})
322
323int rsnd_dai_connect(struct rsnd_dai *rdai,
324 struct rsnd_mod *mod,
325 struct rsnd_dai_stream *io)
326{
327 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
328 struct device *dev = rsnd_priv_to_dev(priv);
329
330 if (!mod) {
331 dev_err(dev, "NULL mod\n");
332 return -EIO;
333 }
334
335 if (!list_empty(&mod->list)) {
336 dev_err(dev, "%s%d is not empty\n",
337 rsnd_mod_name(mod),
338 rsnd_mod_id(mod));
339 return -EIO;
340 }
341
342 list_add_tail(&mod->list, &io->head);
343
344 return 0;
345}
346
347int rsnd_dai_disconnect(struct rsnd_mod *mod)
348{
349 list_del_init(&mod->list);
350
351 return 0;
352}
353
354int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai)
355{
356 int id = rdai - priv->rdai;
357
358 if ((id < 0) || (id >= rsnd_dai_nr(priv)))
359 return -EINVAL;
360
361 return id;
362}
363
364struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id)
365{
366 return priv->rdai + id;
367}
368
369static struct rsnd_dai *rsnd_dai_to_rdai(struct snd_soc_dai *dai)
370{
371 struct rsnd_priv *priv = snd_soc_dai_get_drvdata(dai);
372
373 return rsnd_dai_get(priv, dai->id);
374}
375
376int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io)
377{
378 return &rdai->playback == io;
379}
380
381/*
382 * rsnd_soc_dai functions
383 */
384int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional)
385{
386 struct snd_pcm_substream *substream = io->substream;
387 struct snd_pcm_runtime *runtime = substream->runtime;
388 int pos = io->byte_pos + additional;
389
390 pos %= (runtime->periods * io->byte_per_period);
391
392 return pos;
393}
394
395void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int byte)
396{
397 io->byte_pos += byte;
398
399 if (io->byte_pos >= io->next_period_byte) {
400 struct snd_pcm_substream *substream = io->substream;
401 struct snd_pcm_runtime *runtime = substream->runtime;
402
403 io->period_pos++;
404 io->next_period_byte += io->byte_per_period;
405
406 if (io->period_pos >= runtime->periods) {
407 io->byte_pos = 0;
408 io->period_pos = 0;
409 io->next_period_byte = io->byte_per_period;
410 }
411
412 snd_pcm_period_elapsed(substream);
413 }
414}
415
416static int rsnd_dai_stream_init(struct rsnd_dai_stream *io,
417 struct snd_pcm_substream *substream)
418{
419 struct snd_pcm_runtime *runtime = substream->runtime;
420
421 if (!list_empty(&io->head))
422 return -EIO;
423
424 INIT_LIST_HEAD(&io->head);
425 io->substream = substream;
426 io->byte_pos = 0;
427 io->period_pos = 0;
428 io->byte_per_period = runtime->period_size *
429 runtime->channels *
430 samples_to_bytes(runtime, 1);
431 io->next_period_byte = io->byte_per_period;
432
433 return 0;
434}
435
436static
437struct snd_soc_dai *rsnd_substream_to_dai(struct snd_pcm_substream *substream)
438{
439 struct snd_soc_pcm_runtime *rtd = substream->private_data;
440
441 return rtd->cpu_dai;
442}
443
444static
445struct rsnd_dai_stream *rsnd_rdai_to_io(struct rsnd_dai *rdai,
446 struct snd_pcm_substream *substream)
447{
448 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
449 return &rdai->playback;
450 else
451 return &rdai->capture;
452}
453
454static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
455 struct snd_soc_dai *dai)
456{
457 struct rsnd_priv *priv = snd_soc_dai_get_drvdata(dai);
458 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
459 struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
460 struct rsnd_mod *mod = rsnd_ssi_mod_get_frm_dai(priv,
461 rsnd_dai_id(priv, rdai),
462 rsnd_dai_is_play(rdai, io));
463 int ssi_id = rsnd_mod_id(mod);
464 int ret;
465 unsigned long flags;
466
467 rsnd_lock(priv, flags);
468
469 switch (cmd) {
470 case SNDRV_PCM_TRIGGER_START:
471 ret = rsnd_dai_stream_init(io, substream);
472 if (ret < 0)
473 goto dai_trigger_end;
474
475 ret = rsnd_platform_call(priv, dai, start, ssi_id);
476 if (ret < 0)
477 goto dai_trigger_end;
478
479 ret = rsnd_gen_path_init(priv, rdai, io);
480 if (ret < 0)
481 goto dai_trigger_end;
482
483 ret = rsnd_dai_call(rdai, io, init);
484 if (ret < 0)
485 goto dai_trigger_end;
486
487 ret = rsnd_dai_call(rdai, io, start);
488 if (ret < 0)
489 goto dai_trigger_end;
490 break;
491 case SNDRV_PCM_TRIGGER_STOP:
492 ret = rsnd_dai_call(rdai, io, stop);
493 if (ret < 0)
494 goto dai_trigger_end;
495
496 ret = rsnd_dai_call(rdai, io, quit);
497 if (ret < 0)
498 goto dai_trigger_end;
499
500 ret = rsnd_gen_path_exit(priv, rdai, io);
501 if (ret < 0)
502 goto dai_trigger_end;
503
504 ret = rsnd_platform_call(priv, dai, stop, ssi_id);
505 if (ret < 0)
506 goto dai_trigger_end;
507 break;
508 default:
509 ret = -EINVAL;
510 }
511
512dai_trigger_end:
513 rsnd_unlock(priv, flags);
514
515 return ret;
516}
517
518static int rsnd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
519{
520 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
521
522 /* set master/slave audio interface */
523 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
524 case SND_SOC_DAIFMT_CBM_CFM:
525 rdai->clk_master = 1;
526 break;
527 case SND_SOC_DAIFMT_CBS_CFS:
528 rdai->clk_master = 0;
529 break;
530 default:
531 return -EINVAL;
532 }
533
534 /* set clock inversion */
535 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
536 case SND_SOC_DAIFMT_NB_IF:
537 rdai->bit_clk_inv = 0;
538 rdai->frm_clk_inv = 1;
539 break;
540 case SND_SOC_DAIFMT_IB_NF:
541 rdai->bit_clk_inv = 1;
542 rdai->frm_clk_inv = 0;
543 break;
544 case SND_SOC_DAIFMT_IB_IF:
545 rdai->bit_clk_inv = 1;
546 rdai->frm_clk_inv = 1;
547 break;
548 case SND_SOC_DAIFMT_NB_NF:
549 default:
550 rdai->bit_clk_inv = 0;
551 rdai->frm_clk_inv = 0;
552 break;
553 }
554
555 /* set format */
556 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
557 case SND_SOC_DAIFMT_I2S:
558 rdai->sys_delay = 0;
559 rdai->data_alignment = 0;
560 break;
561 case SND_SOC_DAIFMT_LEFT_J:
562 rdai->sys_delay = 1;
563 rdai->data_alignment = 0;
564 break;
565 case SND_SOC_DAIFMT_RIGHT_J:
566 rdai->sys_delay = 1;
567 rdai->data_alignment = 1;
568 break;
569 }
570
571 return 0;
572}
573
574static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
575 .trigger = rsnd_soc_dai_trigger,
576 .set_fmt = rsnd_soc_dai_set_fmt,
577};
578
579static int rsnd_dai_probe(struct platform_device *pdev,
580 struct rcar_snd_info *info,
581 struct rsnd_priv *priv)
582{
583 struct snd_soc_dai_driver *drv;
584 struct rsnd_dai *rdai;
585 struct rsnd_mod *pmod, *cmod;
586 struct device *dev = rsnd_priv_to_dev(priv);
587 int dai_nr;
588 int i;
589
590 /* get max dai nr */
591 for (dai_nr = 0; dai_nr < 32; dai_nr++) {
592 pmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 1);
593 cmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 0);
594
595 if (!pmod && !cmod)
596 break;
597 }
598
599 if (!dai_nr) {
600 dev_err(dev, "no dai\n");
601 return -EIO;
602 }
603
604 drv = devm_kzalloc(dev, sizeof(*drv) * dai_nr, GFP_KERNEL);
605 rdai = devm_kzalloc(dev, sizeof(*rdai) * dai_nr, GFP_KERNEL);
606 if (!drv || !rdai) {
607 dev_err(dev, "dai allocate failed\n");
608 return -ENOMEM;
609 }
610
611 for (i = 0; i < dai_nr; i++) {
612
613 pmod = rsnd_ssi_mod_get_frm_dai(priv, i, 1);
614 cmod = rsnd_ssi_mod_get_frm_dai(priv, i, 0);
615
616 /*
617 * init rsnd_dai
618 */
619 INIT_LIST_HEAD(&rdai[i].playback.head);
620 INIT_LIST_HEAD(&rdai[i].capture.head);
621
622 snprintf(rdai[i].name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", i);
623
624 /*
625 * init snd_soc_dai_driver
626 */
627 drv[i].name = rdai[i].name;
628 drv[i].ops = &rsnd_soc_dai_ops;
629 if (pmod) {
630 drv[i].playback.rates = RSND_RATES;
631 drv[i].playback.formats = RSND_FMTS;
632 drv[i].playback.channels_min = 2;
633 drv[i].playback.channels_max = 2;
634 }
635 if (cmod) {
636 drv[i].capture.rates = RSND_RATES;
637 drv[i].capture.formats = RSND_FMTS;
638 drv[i].capture.channels_min = 2;
639 drv[i].capture.channels_max = 2;
640 }
641
642 dev_dbg(dev, "%s (%s/%s)\n", rdai[i].name,
643 pmod ? "play" : " -- ",
644 cmod ? "capture" : " -- ");
645 }
646
647 priv->dai_nr = dai_nr;
648 priv->daidrv = drv;
649 priv->rdai = rdai;
650
651 return 0;
652}
653
654static void rsnd_dai_remove(struct platform_device *pdev,
655 struct rsnd_priv *priv)
656{
657}
658
659/*
660 * pcm ops
661 */
662static struct snd_pcm_hardware rsnd_pcm_hardware = {
663 .info = SNDRV_PCM_INFO_INTERLEAVED |
664 SNDRV_PCM_INFO_MMAP |
665 SNDRV_PCM_INFO_MMAP_VALID |
666 SNDRV_PCM_INFO_PAUSE,
667 .formats = RSND_FMTS,
668 .rates = RSND_RATES,
669 .rate_min = 8000,
670 .rate_max = 192000,
671 .channels_min = 2,
672 .channels_max = 2,
673 .buffer_bytes_max = 64 * 1024,
674 .period_bytes_min = 32,
675 .period_bytes_max = 8192,
676 .periods_min = 1,
677 .periods_max = 32,
678 .fifo_size = 256,
679};
680
681static int rsnd_pcm_open(struct snd_pcm_substream *substream)
682{
683 struct snd_pcm_runtime *runtime = substream->runtime;
684 int ret = 0;
685
686 snd_soc_set_runtime_hwparams(substream, &rsnd_pcm_hardware);
687
688 ret = snd_pcm_hw_constraint_integer(runtime,
689 SNDRV_PCM_HW_PARAM_PERIODS);
690
691 return ret;
692}
693
694static int rsnd_hw_params(struct snd_pcm_substream *substream,
695 struct snd_pcm_hw_params *hw_params)
696{
697 return snd_pcm_lib_malloc_pages(substream,
698 params_buffer_bytes(hw_params));
699}
700
701static snd_pcm_uframes_t rsnd_pointer(struct snd_pcm_substream *substream)
702{
703 struct snd_pcm_runtime *runtime = substream->runtime;
704 struct snd_soc_dai *dai = rsnd_substream_to_dai(substream);
705 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
706 struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
707
708 return bytes_to_frames(runtime, io->byte_pos);
709}
710
711static struct snd_pcm_ops rsnd_pcm_ops = {
712 .open = rsnd_pcm_open,
713 .ioctl = snd_pcm_lib_ioctl,
714 .hw_params = rsnd_hw_params,
715 .hw_free = snd_pcm_lib_free_pages,
716 .pointer = rsnd_pointer,
717};
718
719/*
720 * snd_soc_platform
721 */
722
723#define PREALLOC_BUFFER (32 * 1024)
724#define PREALLOC_BUFFER_MAX (32 * 1024)
725
726static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd)
727{
728 return snd_pcm_lib_preallocate_pages_for_all(
729 rtd->pcm,
730 SNDRV_DMA_TYPE_DEV,
731 rtd->card->snd_card->dev,
732 PREALLOC_BUFFER, PREALLOC_BUFFER_MAX);
733}
734
735static void rsnd_pcm_free(struct snd_pcm *pcm)
736{
737 snd_pcm_lib_preallocate_free_for_all(pcm);
738}
739
740static struct snd_soc_platform_driver rsnd_soc_platform = {
741 .ops = &rsnd_pcm_ops,
742 .pcm_new = rsnd_pcm_new,
743 .pcm_free = rsnd_pcm_free,
744};
745
746static const struct snd_soc_component_driver rsnd_soc_component = {
747 .name = "rsnd",
748};
749
750/*
751 * rsnd probe
752 */
753static int rsnd_probe(struct platform_device *pdev)
754{
755 struct rcar_snd_info *info;
756 struct rsnd_priv *priv;
757 struct device *dev = &pdev->dev;
758 int ret;
759
760 info = pdev->dev.platform_data;
761 if (!info) {
762 dev_err(dev, "driver needs R-Car sound information\n");
763 return -ENODEV;
764 }
765
766 /*
767 * init priv data
768 */
769 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
770 if (!priv) {
771 dev_err(dev, "priv allocate failed\n");
772 return -ENODEV;
773 }
774
775 priv->dev = dev;
776 priv->info = info;
777 spin_lock_init(&priv->lock);
778
779 /*
780 * init each module
781 */
782 ret = rsnd_gen_probe(pdev, info, priv);
783 if (ret < 0)
784 return ret;
785
786 ret = rsnd_scu_probe(pdev, info, priv);
787 if (ret < 0)
788 return ret;
789
790 ret = rsnd_adg_probe(pdev, info, priv);
791 if (ret < 0)
792 return ret;
793
794 ret = rsnd_ssi_probe(pdev, info, priv);
795 if (ret < 0)
796 return ret;
797
798 ret = rsnd_dai_probe(pdev, info, priv);
799 if (ret < 0)
800 return ret;
801
802 /*
803 * asoc register
804 */
805 ret = snd_soc_register_platform(dev, &rsnd_soc_platform);
806 if (ret < 0) {
807 dev_err(dev, "cannot snd soc register\n");
808 return ret;
809 }
810
811 ret = snd_soc_register_component(dev, &rsnd_soc_component,
812 priv->daidrv, rsnd_dai_nr(priv));
813 if (ret < 0) {
814 dev_err(dev, "cannot snd dai register\n");
815 goto exit_snd_soc;
816 }
817
818 dev_set_drvdata(dev, priv);
819
820 pm_runtime_enable(dev);
821
822 dev_info(dev, "probed\n");
823 return ret;
824
825exit_snd_soc:
826 snd_soc_unregister_platform(dev);
827
828 return ret;
829}
830
831static int rsnd_remove(struct platform_device *pdev)
832{
833 struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev);
834
835 pm_runtime_disable(&pdev->dev);
836
837 /*
838 * remove each module
839 */
840 rsnd_ssi_remove(pdev, priv);
841 rsnd_adg_remove(pdev, priv);
842 rsnd_scu_remove(pdev, priv);
843 rsnd_dai_remove(pdev, priv);
844 rsnd_gen_remove(pdev, priv);
845
846 return 0;
847}
848
849static struct platform_driver rsnd_driver = {
850 .driver = {
851 .name = "rcar_sound",
852 },
853 .probe = rsnd_probe,
854 .remove = rsnd_remove,
855};
856module_platform_driver(rsnd_driver);
857
858MODULE_LICENSE("GPL");
859MODULE_DESCRIPTION("Renesas R-Car audio driver");
860MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
861MODULE_ALIAS("platform:rcar-pcm-audio");
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
new file mode 100644
index 000000000000..babb203b43b7
--- /dev/null
+++ b/sound/soc/sh/rcar/gen.c
@@ -0,0 +1,280 @@
1/*
2 * Renesas R-Car Gen1 SRU/SSI support
3 *
4 * Copyright (C) 2013 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include "rsnd.h"
12
13struct rsnd_gen_ops {
14 int (*path_init)(struct rsnd_priv *priv,
15 struct rsnd_dai *rdai,
16 struct rsnd_dai_stream *io);
17 int (*path_exit)(struct rsnd_priv *priv,
18 struct rsnd_dai *rdai,
19 struct rsnd_dai_stream *io);
20};
21
22struct rsnd_gen_reg_map {
23 int index; /* -1 : not supported */
24 u32 offset_id; /* offset of ssi0, ssi1, ssi2... */
25 u32 offset_adr; /* offset of SSICR, SSISR, ... */
26};
27
28struct rsnd_gen {
29 void __iomem *base[RSND_BASE_MAX];
30
31 struct rsnd_gen_reg_map reg_map[RSND_REG_MAX];
32 struct rsnd_gen_ops *ops;
33};
34
35#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen)
36
37/*
38 * Gen2
39 * will be filled in the future
40 */
41
42/*
43 * Gen1
44 */
45static int rsnd_gen1_path_init(struct rsnd_priv *priv,
46 struct rsnd_dai *rdai,
47 struct rsnd_dai_stream *io)
48{
49 struct rsnd_mod *mod;
50 int ret;
51 int id;
52
53 /*
54 * Gen1 is created by SRU/SSI, and this SRU is base module of
55 * Gen2's SCU/SSIU/SSI. (Gen2 SCU/SSIU came from SRU)
56 *
57 * Easy image is..
58 * Gen1 SRU = Gen2 SCU + SSIU + etc
59 *
60 * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is
61 * using fixed path.
62 *
63 * Then, SSI id = SCU id here
64 */
65
66 /* get SSI's ID */
67 mod = rsnd_ssi_mod_get_frm_dai(priv,
68 rsnd_dai_id(priv, rdai),
69 rsnd_dai_is_play(rdai, io));
70 id = rsnd_mod_id(mod);
71
72 /* SSI */
73 mod = rsnd_ssi_mod_get(priv, id);
74 ret = rsnd_dai_connect(rdai, mod, io);
75 if (ret < 0)
76 return ret;
77
78 /* SCU */
79 mod = rsnd_scu_mod_get(priv, id);
80 ret = rsnd_dai_connect(rdai, mod, io);
81
82 return ret;
83}
84
85static int rsnd_gen1_path_exit(struct rsnd_priv *priv,
86 struct rsnd_dai *rdai,
87 struct rsnd_dai_stream *io)
88{
89 struct rsnd_mod *mod, *n;
90 int ret = 0;
91
92 /*
93 * remove all mod from rdai
94 */
95 for_each_rsnd_mod(mod, n, io)
96 ret |= rsnd_dai_disconnect(mod);
97
98 return ret;
99}
100
101static struct rsnd_gen_ops rsnd_gen1_ops = {
102 .path_init = rsnd_gen1_path_init,
103 .path_exit = rsnd_gen1_path_exit,
104};
105
106#define RSND_GEN1_REG_MAP(g, s, i, oi, oa) \
107 do { \
108 (g)->reg_map[RSND_REG_##i].index = RSND_GEN1_##s; \
109 (g)->reg_map[RSND_REG_##i].offset_id = oi; \
110 (g)->reg_map[RSND_REG_##i].offset_adr = oa; \
111 } while (0)
112
113static void rsnd_gen1_reg_map_init(struct rsnd_gen *gen)
114{
115 RSND_GEN1_REG_MAP(gen, SRU, SRC_ROUTE_SEL, 0x0, 0x00);
116 RSND_GEN1_REG_MAP(gen, SRU, SRC_TMG_SEL0, 0x0, 0x08);
117 RSND_GEN1_REG_MAP(gen, SRU, SRC_TMG_SEL1, 0x0, 0x0c);
118 RSND_GEN1_REG_MAP(gen, SRU, SRC_TMG_SEL2, 0x0, 0x10);
119 RSND_GEN1_REG_MAP(gen, SRU, SRC_CTRL, 0x0, 0xc0);
120 RSND_GEN1_REG_MAP(gen, SRU, SSI_MODE0, 0x0, 0xD0);
121 RSND_GEN1_REG_MAP(gen, SRU, SSI_MODE1, 0x0, 0xD4);
122 RSND_GEN1_REG_MAP(gen, SRU, BUSIF_MODE, 0x4, 0x20);
123 RSND_GEN1_REG_MAP(gen, SRU, BUSIF_ADINR, 0x40, 0x214);
124
125 RSND_GEN1_REG_MAP(gen, ADG, BRRA, 0x0, 0x00);
126 RSND_GEN1_REG_MAP(gen, ADG, BRRB, 0x0, 0x04);
127 RSND_GEN1_REG_MAP(gen, ADG, SSICKR, 0x0, 0x08);
128 RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL0, 0x0, 0x0c);
129 RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL1, 0x0, 0x10);
130 RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL3, 0x0, 0x18);
131 RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL4, 0x0, 0x1c);
132 RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL5, 0x0, 0x20);
133
134 RSND_GEN1_REG_MAP(gen, SSI, SSICR, 0x40, 0x00);
135 RSND_GEN1_REG_MAP(gen, SSI, SSISR, 0x40, 0x04);
136 RSND_GEN1_REG_MAP(gen, SSI, SSITDR, 0x40, 0x08);
137 RSND_GEN1_REG_MAP(gen, SSI, SSIRDR, 0x40, 0x0c);
138 RSND_GEN1_REG_MAP(gen, SSI, SSIWSR, 0x40, 0x20);
139}
140
141static int rsnd_gen1_probe(struct platform_device *pdev,
142 struct rcar_snd_info *info,
143 struct rsnd_priv *priv)
144{
145 struct device *dev = rsnd_priv_to_dev(priv);
146 struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
147 struct resource *sru_res;
148 struct resource *adg_res;
149 struct resource *ssi_res;
150
151 /*
152 * map address
153 */
154 sru_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SRU);
155 adg_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_ADG);
156 ssi_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SSI);
157
158 gen->base[RSND_GEN1_SRU] = devm_ioremap_resource(dev, sru_res);
159 gen->base[RSND_GEN1_ADG] = devm_ioremap_resource(dev, adg_res);
160 gen->base[RSND_GEN1_SSI] = devm_ioremap_resource(dev, ssi_res);
161 if (IS_ERR(gen->base[RSND_GEN1_SRU]) ||
162 IS_ERR(gen->base[RSND_GEN1_ADG]) ||
163 IS_ERR(gen->base[RSND_GEN1_SSI]))
164 return -ENODEV;
165
166 gen->ops = &rsnd_gen1_ops;
167 rsnd_gen1_reg_map_init(gen);
168
169 dev_dbg(dev, "Gen1 device probed\n");
170 dev_dbg(dev, "SRU : %08x => %p\n", sru_res->start,
171 gen->base[RSND_GEN1_SRU]);
172 dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start,
173 gen->base[RSND_GEN1_ADG]);
174 dev_dbg(dev, "SSI : %08x => %p\n", ssi_res->start,
175 gen->base[RSND_GEN1_SSI]);
176
177 return 0;
178
179}
180
181static void rsnd_gen1_remove(struct platform_device *pdev,
182 struct rsnd_priv *priv)
183{
184}
185
186/*
187 * Gen
188 */
189int rsnd_gen_path_init(struct rsnd_priv *priv,
190 struct rsnd_dai *rdai,
191 struct rsnd_dai_stream *io)
192{
193 struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
194
195 return gen->ops->path_init(priv, rdai, io);
196}
197
198int rsnd_gen_path_exit(struct rsnd_priv *priv,
199 struct rsnd_dai *rdai,
200 struct rsnd_dai_stream *io)
201{
202 struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
203
204 return gen->ops->path_exit(priv, rdai, io);
205}
206
207void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
208 struct rsnd_mod *mod,
209 enum rsnd_reg reg)
210{
211 struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
212 struct device *dev = rsnd_priv_to_dev(priv);
213 int index;
214 u32 offset_id, offset_adr;
215
216 if (reg >= RSND_REG_MAX) {
217 dev_err(dev, "rsnd_reg reg error\n");
218 return NULL;
219 }
220
221 index = gen->reg_map[reg].index;
222 offset_id = gen->reg_map[reg].offset_id;
223 offset_adr = gen->reg_map[reg].offset_adr;
224
225 if (index < 0) {
226 dev_err(dev, "unsupported reg access %d\n", reg);
227 return NULL;
228 }
229
230 if (offset_id && mod)
231 offset_id *= rsnd_mod_id(mod);
232
233 /*
234 * index/offset were set on gen1/gen2
235 */
236
237 return gen->base[index] + offset_id + offset_adr;
238}
239
240int rsnd_gen_probe(struct platform_device *pdev,
241 struct rcar_snd_info *info,
242 struct rsnd_priv *priv)
243{
244 struct device *dev = rsnd_priv_to_dev(priv);
245 struct rsnd_gen *gen;
246 int i;
247
248 gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
249 if (!gen) {
250 dev_err(dev, "GEN allocate failed\n");
251 return -ENOMEM;
252 }
253
254 priv->gen = gen;
255
256 /*
257 * see
258 * rsnd_reg_get()
259 * rsnd_gen_probe()
260 */
261 for (i = 0; i < RSND_REG_MAX; i++)
262 gen->reg_map[i].index = -1;
263
264 /*
265 * init each module
266 */
267 if (rsnd_is_gen1(priv))
268 return rsnd_gen1_probe(pdev, info, priv);
269
270 dev_err(dev, "unknown generation R-Car sound device\n");
271
272 return -ENODEV;
273}
274
275void rsnd_gen_remove(struct platform_device *pdev,
276 struct rsnd_priv *priv)
277{
278 if (rsnd_is_gen1(priv))
279 rsnd_gen1_remove(pdev, priv);
280}
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
new file mode 100644
index 000000000000..9cc6986a8cfb
--- /dev/null
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -0,0 +1,302 @@
1/*
2 * Renesas R-Car
3 *
4 * Copyright (C) 2013 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef RSND_H
12#define RSND_H
13
14#include <linux/clk.h>
15#include <linux/device.h>
16#include <linux/dma-mapping.h>
17#include <linux/io.h>
18#include <linux/list.h>
19#include <linux/module.h>
20#include <linux/sh_dma.h>
21#include <linux/workqueue.h>
22#include <sound/rcar_snd.h>
23#include <sound/soc.h>
24#include <sound/pcm_params.h>
25
26/*
27 * pseudo register
28 *
29 * The register address offsets SRU/SCU/SSIU on Gen1/Gen2 are very different.
30 * This driver uses pseudo register in order to hide it.
31 * see gen1/gen2 for detail
32 */
33enum rsnd_reg {
34 /* SRU/SCU */
35 RSND_REG_SRC_ROUTE_SEL,
36 RSND_REG_SRC_TMG_SEL0,
37 RSND_REG_SRC_TMG_SEL1,
38 RSND_REG_SRC_TMG_SEL2,
39 RSND_REG_SRC_CTRL,
40 RSND_REG_SSI_MODE0,
41 RSND_REG_SSI_MODE1,
42 RSND_REG_BUSIF_MODE,
43 RSND_REG_BUSIF_ADINR,
44
45 /* ADG */
46 RSND_REG_BRRA,
47 RSND_REG_BRRB,
48 RSND_REG_SSICKR,
49 RSND_REG_AUDIO_CLK_SEL0,
50 RSND_REG_AUDIO_CLK_SEL1,
51 RSND_REG_AUDIO_CLK_SEL2,
52 RSND_REG_AUDIO_CLK_SEL3,
53 RSND_REG_AUDIO_CLK_SEL4,
54 RSND_REG_AUDIO_CLK_SEL5,
55
56 /* SSI */
57 RSND_REG_SSICR,
58 RSND_REG_SSISR,
59 RSND_REG_SSITDR,
60 RSND_REG_SSIRDR,
61 RSND_REG_SSIWSR,
62
63 RSND_REG_MAX,
64};
65
66struct rsnd_priv;
67struct rsnd_mod;
68struct rsnd_dai;
69struct rsnd_dai_stream;
70
71/*
72 * R-Car basic functions
73 */
74#define rsnd_mod_read(m, r) \
75 rsnd_read(rsnd_mod_to_priv(m), m, RSND_REG_##r)
76#define rsnd_mod_write(m, r, d) \
77 rsnd_write(rsnd_mod_to_priv(m), m, RSND_REG_##r, d)
78#define rsnd_mod_bset(m, r, s, d) \
79 rsnd_bset(rsnd_mod_to_priv(m), m, RSND_REG_##r, s, d)
80
81#define rsnd_priv_read(p, r) rsnd_read(p, NULL, RSND_REG_##r)
82#define rsnd_priv_write(p, r, d) rsnd_write(p, NULL, RSND_REG_##r, d)
83#define rsnd_priv_bset(p, r, s, d) rsnd_bset(p, NULL, RSND_REG_##r, s, d)
84
85u32 rsnd_read(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg);
86void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
87 enum rsnd_reg reg, u32 data);
88void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
89 u32 mask, u32 data);
90
91/*
92 * R-Car DMA
93 */
94struct rsnd_dma {
95 struct rsnd_priv *priv;
96 struct sh_dmae_slave slave;
97 struct work_struct work;
98 struct dma_chan *chan;
99 enum dma_data_direction dir;
100 int (*inquiry)(struct rsnd_dma *dma, dma_addr_t *buf, int *len);
101 int (*complete)(struct rsnd_dma *dma);
102
103 int submit_loop;
104};
105
106void rsnd_dma_start(struct rsnd_dma *dma);
107void rsnd_dma_stop(struct rsnd_dma *dma);
108int rsnd_dma_available(struct rsnd_dma *dma);
109int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
110 int is_play, int id,
111 int (*inquiry)(struct rsnd_dma *dma, dma_addr_t *buf, int *len),
112 int (*complete)(struct rsnd_dma *dma));
113void rsnd_dma_quit(struct rsnd_priv *priv,
114 struct rsnd_dma *dma);
115
116
117/*
118 * R-Car sound mod
119 */
120
121struct rsnd_mod_ops {
122 char *name;
123 int (*init)(struct rsnd_mod *mod,
124 struct rsnd_dai *rdai,
125 struct rsnd_dai_stream *io);
126 int (*quit)(struct rsnd_mod *mod,
127 struct rsnd_dai *rdai,
128 struct rsnd_dai_stream *io);
129 int (*start)(struct rsnd_mod *mod,
130 struct rsnd_dai *rdai,
131 struct rsnd_dai_stream *io);
132 int (*stop)(struct rsnd_mod *mod,
133 struct rsnd_dai *rdai,
134 struct rsnd_dai_stream *io);
135};
136
137struct rsnd_mod {
138 int id;
139 struct rsnd_priv *priv;
140 struct rsnd_mod_ops *ops;
141 struct list_head list; /* connect to rsnd_dai playback/capture */
142 struct rsnd_dma dma;
143};
144
145#define rsnd_mod_to_priv(mod) ((mod)->priv)
146#define rsnd_mod_to_dma(mod) (&(mod)->dma)
147#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
148#define rsnd_mod_id(mod) ((mod)->id)
149#define for_each_rsnd_mod(pos, n, io) \
150 list_for_each_entry_safe(pos, n, &(io)->head, list)
151#define rsnd_mod_call(mod, func, rdai, io) \
152 (!(mod) ? -ENODEV : \
153 !((mod)->ops->func) ? 0 : \
154 (mod)->ops->func(mod, rdai, io))
155
156void rsnd_mod_init(struct rsnd_priv *priv,
157 struct rsnd_mod *mod,
158 struct rsnd_mod_ops *ops,
159 int id);
160char *rsnd_mod_name(struct rsnd_mod *mod);
161
162/*
163 * R-Car sound DAI
164 */
165#define RSND_DAI_NAME_SIZE 16
166struct rsnd_dai_stream {
167 struct list_head head; /* head of rsnd_mod list */
168 struct snd_pcm_substream *substream;
169 int byte_pos;
170 int period_pos;
171 int byte_per_period;
172 int next_period_byte;
173};
174
175struct rsnd_dai {
176 char name[RSND_DAI_NAME_SIZE];
177 struct rsnd_dai_platform_info *info; /* rcar_snd.h */
178 struct rsnd_dai_stream playback;
179 struct rsnd_dai_stream capture;
180
181 int clk_master:1;
182 int bit_clk_inv:1;
183 int frm_clk_inv:1;
184 int sys_delay:1;
185 int data_alignment:1;
186};
187
188#define rsnd_dai_nr(priv) ((priv)->dai_nr)
189#define for_each_rsnd_dai(rdai, priv, i) \
190 for (i = 0, (rdai) = rsnd_dai_get(priv, i); \
191 i < rsnd_dai_nr(priv); \
192 i++, (rdai) = rsnd_dai_get(priv, i))
193
194struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id);
195int rsnd_dai_disconnect(struct rsnd_mod *mod);
196int rsnd_dai_connect(struct rsnd_dai *rdai, struct rsnd_mod *mod,
197 struct rsnd_dai_stream *io);
198int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io);
199int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai);
200#define rsnd_dai_get_platform_info(rdai) ((rdai)->info)
201#define rsnd_io_to_runtime(io) ((io)->substream->runtime)
202
203void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt);
204int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional);
205
206/*
207 * R-Car Gen1/Gen2
208 */
209int rsnd_gen_probe(struct platform_device *pdev,
210 struct rcar_snd_info *info,
211 struct rsnd_priv *priv);
212void rsnd_gen_remove(struct platform_device *pdev,
213 struct rsnd_priv *priv);
214int rsnd_gen_path_init(struct rsnd_priv *priv,
215 struct rsnd_dai *rdai,
216 struct rsnd_dai_stream *io);
217int rsnd_gen_path_exit(struct rsnd_priv *priv,
218 struct rsnd_dai *rdai,
219 struct rsnd_dai_stream *io);
220void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
221 struct rsnd_mod *mod,
222 enum rsnd_reg reg);
223#define rsnd_is_gen1(s) ((s)->info->flags & RSND_GEN1)
224#define rsnd_is_gen2(s) ((s)->info->flags & RSND_GEN2)
225
226/*
227 * R-Car ADG
228 */
229int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod);
230int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate);
231int rsnd_adg_probe(struct platform_device *pdev,
232 struct rcar_snd_info *info,
233 struct rsnd_priv *priv);
234void rsnd_adg_remove(struct platform_device *pdev,
235 struct rsnd_priv *priv);
236
237/*
238 * R-Car sound priv
239 */
240struct rsnd_priv {
241
242 struct device *dev;
243 struct rcar_snd_info *info;
244 spinlock_t lock;
245
246 /*
247 * below value will be filled on rsnd_gen_probe()
248 */
249 void *gen;
250
251 /*
252 * below value will be filled on rsnd_scu_probe()
253 */
254 void *scu;
255 int scu_nr;
256
257 /*
258 * below value will be filled on rsnd_adg_probe()
259 */
260 void *adg;
261
262 /*
263 * below value will be filled on rsnd_ssi_probe()
264 */
265 void *ssiu;
266
267 /*
268 * below value will be filled on rsnd_dai_probe()
269 */
270 struct snd_soc_dai_driver *daidrv;
271 struct rsnd_dai *rdai;
272 int dai_nr;
273};
274
275#define rsnd_priv_to_dev(priv) ((priv)->dev)
276#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags)
277#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags)
278
279/*
280 * R-Car SCU
281 */
282int rsnd_scu_probe(struct platform_device *pdev,
283 struct rcar_snd_info *info,
284 struct rsnd_priv *priv);
285void rsnd_scu_remove(struct platform_device *pdev,
286 struct rsnd_priv *priv);
287struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id);
288#define rsnd_scu_nr(priv) ((priv)->scu_nr)
289
290/*
291 * R-Car SSI
292 */
293int rsnd_ssi_probe(struct platform_device *pdev,
294 struct rcar_snd_info *info,
295 struct rsnd_priv *priv);
296void rsnd_ssi_remove(struct platform_device *pdev,
297 struct rsnd_priv *priv);
298struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
299struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv,
300 int dai_id, int is_play);
301
302#endif
diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c
new file mode 100644
index 000000000000..184d9008cecd
--- /dev/null
+++ b/sound/soc/sh/rcar/scu.c
@@ -0,0 +1,236 @@
1/*
2 * Renesas R-Car SCU support
3 *
4 * Copyright (C) 2013 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include "rsnd.h"
12
13struct rsnd_scu {
14 struct rsnd_scu_platform_info *info; /* rcar_snd.h */
15 struct rsnd_mod mod;
16};
17
18#define rsnd_scu_mode_flags(p) ((p)->info->flags)
19
20/*
21 * ADINR
22 */
23#define OTBL_24 (0 << 16)
24#define OTBL_22 (2 << 16)
25#define OTBL_20 (4 << 16)
26#define OTBL_18 (6 << 16)
27#define OTBL_16 (8 << 16)
28
29
30#define rsnd_mod_to_scu(_mod) \
31 container_of((_mod), struct rsnd_scu, mod)
32
33#define for_each_rsnd_scu(pos, priv, i) \
34 for ((i) = 0; \
35 ((i) < rsnd_scu_nr(priv)) && \
36 ((pos) = (struct rsnd_scu *)(priv)->scu + i); \
37 i++)
38
39static int rsnd_scu_set_route(struct rsnd_priv *priv,
40 struct rsnd_mod *mod,
41 struct rsnd_dai *rdai,
42 struct rsnd_dai_stream *io)
43{
44 struct scu_route_config {
45 u32 mask;
46 int shift;
47 } routes[] = {
48 { 0xF, 0, }, /* 0 */
49 { 0xF, 4, }, /* 1 */
50 { 0xF, 8, }, /* 2 */
51 { 0x7, 12, }, /* 3 */
52 { 0x7, 16, }, /* 4 */
53 { 0x7, 20, }, /* 5 */
54 { 0x7, 24, }, /* 6 */
55 { 0x3, 28, }, /* 7 */
56 { 0x3, 30, }, /* 8 */
57 };
58
59 u32 mask;
60 u32 val;
61 int shift;
62 int id;
63
64 /*
65 * Gen1 only
66 */
67 if (!rsnd_is_gen1(priv))
68 return 0;
69
70 id = rsnd_mod_id(mod);
71 if (id < 0 || id > ARRAY_SIZE(routes))
72 return -EIO;
73
74 /*
75 * SRC_ROUTE_SELECT
76 */
77 val = rsnd_dai_is_play(rdai, io) ? 0x1 : 0x2;
78 val = val << routes[id].shift;
79 mask = routes[id].mask << routes[id].shift;
80
81 rsnd_mod_bset(mod, SRC_ROUTE_SEL, mask, val);
82
83 /*
84 * SRC_TIMING_SELECT
85 */
86 shift = (id % 4) * 8;
87 mask = 0x1F << shift;
88 if (8 == id) /* SRU8 is very special */
89 val = id << shift;
90 else
91 val = (id + 1) << shift;
92
93 switch (id / 4) {
94 case 0:
95 rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val);
96 break;
97 case 1:
98 rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val);
99 break;
100 case 2:
101 rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val);
102 break;
103 }
104
105 return 0;
106}
107
108static int rsnd_scu_set_mode(struct rsnd_priv *priv,
109 struct rsnd_mod *mod,
110 struct rsnd_dai *rdai,
111 struct rsnd_dai_stream *io)
112{
113 int id = rsnd_mod_id(mod);
114 u32 val;
115
116 if (rsnd_is_gen1(priv)) {
117 val = (1 << id);
118 rsnd_mod_bset(mod, SRC_CTRL, val, val);
119 }
120
121 return 0;
122}
123
124static int rsnd_scu_set_hpbif(struct rsnd_priv *priv,
125 struct rsnd_mod *mod,
126 struct rsnd_dai *rdai,
127 struct rsnd_dai_stream *io)
128{
129 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
130 u32 adinr = runtime->channels;
131
132 switch (runtime->sample_bits) {
133 case 16:
134 adinr |= OTBL_16;
135 break;
136 case 32:
137 adinr |= OTBL_24;
138 break;
139 default:
140 return -EIO;
141 }
142
143 rsnd_mod_write(mod, BUSIF_MODE, 1);
144 rsnd_mod_write(mod, BUSIF_ADINR, adinr);
145
146 return 0;
147}
148
149static int rsnd_scu_start(struct rsnd_mod *mod,
150 struct rsnd_dai *rdai,
151 struct rsnd_dai_stream *io)
152{
153 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
154 struct rsnd_scu *scu = rsnd_mod_to_scu(mod);
155 struct device *dev = rsnd_priv_to_dev(priv);
156 u32 flags = rsnd_scu_mode_flags(scu);
157 int ret;
158
159 /*
160 * SCU will be used if it has RSND_SCU_USB_HPBIF flags
161 */
162 if (!(flags & RSND_SCU_USB_HPBIF)) {
163 /* it use PIO transter */
164 dev_dbg(dev, "%s%d is not used\n",
165 rsnd_mod_name(mod), rsnd_mod_id(mod));
166
167 return 0;
168 }
169
170 /* it use DMA transter */
171 ret = rsnd_scu_set_route(priv, mod, rdai, io);
172 if (ret < 0)
173 return ret;
174
175 ret = rsnd_scu_set_mode(priv, mod, rdai, io);
176 if (ret < 0)
177 return ret;
178
179 ret = rsnd_scu_set_hpbif(priv, mod, rdai, io);
180 if (ret < 0)
181 return ret;
182
183 dev_dbg(dev, "%s%d start\n", rsnd_mod_name(mod), rsnd_mod_id(mod));
184
185 return 0;
186}
187
188static struct rsnd_mod_ops rsnd_scu_ops = {
189 .name = "scu",
190 .start = rsnd_scu_start,
191};
192
193struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id)
194{
195 BUG_ON(id < 0 || id >= rsnd_scu_nr(priv));
196
197 return &((struct rsnd_scu *)(priv->scu) + id)->mod;
198}
199
200int rsnd_scu_probe(struct platform_device *pdev,
201 struct rcar_snd_info *info,
202 struct rsnd_priv *priv)
203{
204 struct device *dev = rsnd_priv_to_dev(priv);
205 struct rsnd_scu *scu;
206 int i, nr;
207
208 /*
209 * init SCU
210 */
211 nr = info->scu_info_nr;
212 scu = devm_kzalloc(dev, sizeof(*scu) * nr, GFP_KERNEL);
213 if (!scu) {
214 dev_err(dev, "SCU allocate failed\n");
215 return -ENOMEM;
216 }
217
218 priv->scu_nr = nr;
219 priv->scu = scu;
220
221 for_each_rsnd_scu(scu, priv, i) {
222 rsnd_mod_init(priv, &scu->mod,
223 &rsnd_scu_ops, i);
224 scu->info = &info->scu_info[i];
225
226 dev_dbg(dev, "SCU%d probed\n", i);
227 }
228 dev_dbg(dev, "scu probed\n");
229
230 return 0;
231}
232
233void rsnd_scu_remove(struct platform_device *pdev,
234 struct rsnd_priv *priv)
235{
236}
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
new file mode 100644
index 000000000000..fae26d3f79d2
--- /dev/null
+++ b/sound/soc/sh/rcar/ssi.c
@@ -0,0 +1,728 @@
1/*
2 * Renesas R-Car SSIU/SSI support
3 *
4 * Copyright (C) 2013 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * Based on fsi.c
8 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14#include <linux/delay.h>
15#include "rsnd.h"
16#define RSND_SSI_NAME_SIZE 16
17
18/*
19 * SSICR
20 */
21#define FORCE (1 << 31) /* Fixed */
22#define DMEN (1 << 28) /* DMA Enable */
23#define UIEN (1 << 27) /* Underflow Interrupt Enable */
24#define OIEN (1 << 26) /* Overflow Interrupt Enable */
25#define IIEN (1 << 25) /* Idle Mode Interrupt Enable */
26#define DIEN (1 << 24) /* Data Interrupt Enable */
27
28#define DWL_8 (0 << 19) /* Data Word Length */
29#define DWL_16 (1 << 19) /* Data Word Length */
30#define DWL_18 (2 << 19) /* Data Word Length */
31#define DWL_20 (3 << 19) /* Data Word Length */
32#define DWL_22 (4 << 19) /* Data Word Length */
33#define DWL_24 (5 << 19) /* Data Word Length */
34#define DWL_32 (6 << 19) /* Data Word Length */
35
36#define SWL_32 (3 << 16) /* R/W System Word Length */
37#define SCKD (1 << 15) /* Serial Bit Clock Direction */
38#define SWSD (1 << 14) /* Serial WS Direction */
39#define SCKP (1 << 13) /* Serial Bit Clock Polarity */
40#define SWSP (1 << 12) /* Serial WS Polarity */
41#define SDTA (1 << 10) /* Serial Data Alignment */
42#define DEL (1 << 8) /* Serial Data Delay */
43#define CKDV(v) (v << 4) /* Serial Clock Division Ratio */
44#define TRMD (1 << 1) /* Transmit/Receive Mode Select */
45#define EN (1 << 0) /* SSI Module Enable */
46
47/*
48 * SSISR
49 */
50#define UIRQ (1 << 27) /* Underflow Error Interrupt Status */
51#define OIRQ (1 << 26) /* Overflow Error Interrupt Status */
52#define IIRQ (1 << 25) /* Idle Mode Interrupt Status */
53#define DIRQ (1 << 24) /* Data Interrupt Status Flag */
54
55/*
56 * SSIWSR
57 */
58#define CONT (1 << 8) /* WS Continue Function */
59
60struct rsnd_ssi {
61 struct clk *clk;
62 struct rsnd_ssi_platform_info *info; /* rcar_snd.h */
63 struct rsnd_ssi *parent;
64 struct rsnd_mod mod;
65
66 struct rsnd_dai *rdai;
67 struct rsnd_dai_stream *io;
68 u32 cr_own;
69 u32 cr_clk;
70 u32 cr_etc;
71 int err;
72 int dma_offset;
73 unsigned int usrcnt;
74 unsigned int rate;
75};
76
77struct rsnd_ssiu {
78 u32 ssi_mode0;
79 u32 ssi_mode1;
80
81 int ssi_nr;
82 struct rsnd_ssi *ssi;
83};
84
85#define for_each_rsnd_ssi(pos, priv, i) \
86 for (i = 0; \
87 (i < rsnd_ssi_nr(priv)) && \
88 ((pos) = ((struct rsnd_ssiu *)((priv)->ssiu))->ssi + i); \
89 i++)
90
91#define rsnd_ssi_nr(priv) (((struct rsnd_ssiu *)((priv)->ssiu))->ssi_nr)
92#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod)
93#define rsnd_dma_to_ssi(dma) rsnd_mod_to_ssi(rsnd_dma_to_mod(dma))
94#define rsnd_ssi_pio_available(ssi) ((ssi)->info->pio_irq > 0)
95#define rsnd_ssi_dma_available(ssi) \
96 rsnd_dma_available(rsnd_mod_to_dma(&(ssi)->mod))
97#define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent)
98#define rsnd_rdai_is_clk_master(rdai) ((rdai)->clk_master)
99#define rsnd_ssi_mode_flags(p) ((p)->info->flags)
100#define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id)
101#define rsnd_ssi_to_ssiu(ssi)\
102 (((struct rsnd_ssiu *)((ssi) - rsnd_mod_id(&(ssi)->mod))) - 1)
103
104static void rsnd_ssi_mode_init(struct rsnd_priv *priv,
105 struct rsnd_ssiu *ssiu)
106{
107 struct device *dev = rsnd_priv_to_dev(priv);
108 struct rsnd_ssi *ssi;
109 u32 flags;
110 u32 val;
111 int i;
112
113 /*
114 * SSI_MODE0
115 */
116 ssiu->ssi_mode0 = 0;
117 for_each_rsnd_ssi(ssi, priv, i) {
118 flags = rsnd_ssi_mode_flags(ssi);
119
120 /* see also BUSIF_MODE */
121 if (!(flags & RSND_SSI_DEPENDENT)) {
122 ssiu->ssi_mode0 |= (1 << i);
123 dev_dbg(dev, "SSI%d uses INDEPENDENT mode\n", i);
124 } else {
125 dev_dbg(dev, "SSI%d uses DEPENDENT mode\n", i);
126 }
127 }
128
129 /*
130 * SSI_MODE1
131 */
132#define ssi_parent_set(p, sync, adg, ext) \
133 do { \
134 ssi->parent = ssiu->ssi + p; \
135 if (flags & RSND_SSI_CLK_FROM_ADG) \
136 val = adg; \
137 else \
138 val = ext; \
139 if (flags & RSND_SSI_SYNC) \
140 val |= sync; \
141 } while (0)
142
143 ssiu->ssi_mode1 = 0;
144 for_each_rsnd_ssi(ssi, priv, i) {
145 flags = rsnd_ssi_mode_flags(ssi);
146
147 if (!(flags & RSND_SSI_CLK_PIN_SHARE))
148 continue;
149
150 val = 0;
151 switch (i) {
152 case 1:
153 ssi_parent_set(0, (1 << 4), (0x2 << 0), (0x1 << 0));
154 break;
155 case 2:
156 ssi_parent_set(0, (1 << 4), (0x2 << 2), (0x1 << 2));
157 break;
158 case 4:
159 ssi_parent_set(3, (1 << 20), (0x2 << 16), (0x1 << 16));
160 break;
161 case 8:
162 ssi_parent_set(7, 0, 0, 0);
163 break;
164 }
165
166 ssiu->ssi_mode1 |= val;
167 }
168}
169
170static void rsnd_ssi_mode_set(struct rsnd_ssi *ssi)
171{
172 struct rsnd_ssiu *ssiu = rsnd_ssi_to_ssiu(ssi);
173
174 rsnd_mod_write(&ssi->mod, SSI_MODE0, ssiu->ssi_mode0);
175 rsnd_mod_write(&ssi->mod, SSI_MODE1, ssiu->ssi_mode1);
176}
177
178static void rsnd_ssi_status_check(struct rsnd_mod *mod,
179 u32 bit)
180{
181 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
182 struct device *dev = rsnd_priv_to_dev(priv);
183 u32 status;
184 int i;
185
186 for (i = 0; i < 1024; i++) {
187 status = rsnd_mod_read(mod, SSISR);
188 if (status & bit)
189 return;
190
191 udelay(50);
192 }
193
194 dev_warn(dev, "status check failed\n");
195}
196
197static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
198 unsigned int rate)
199{
200 struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod);
201 struct device *dev = rsnd_priv_to_dev(priv);
202 int i, j, ret;
203 int adg_clk_div_table[] = {
204 1, 6, /* see adg.c */
205 };
206 int ssi_clk_mul_table[] = {
207 1, 2, 4, 8, 16, 6, 12,
208 };
209 unsigned int main_rate;
210
211 /*
212 * Find best clock, and try to start ADG
213 */
214 for (i = 0; i < ARRAY_SIZE(adg_clk_div_table); i++) {
215 for (j = 0; j < ARRAY_SIZE(ssi_clk_mul_table); j++) {
216
217 /*
218 * this driver is assuming that
219 * system word is 64fs (= 2 x 32bit)
220 * see rsnd_ssi_start()
221 */
222 main_rate = rate / adg_clk_div_table[i]
223 * 32 * 2 * ssi_clk_mul_table[j];
224
225 ret = rsnd_adg_ssi_clk_try_start(&ssi->mod, main_rate);
226 if (0 == ret) {
227 ssi->rate = rate;
228 ssi->cr_clk = FORCE | SWL_32 |
229 SCKD | SWSD | CKDV(j);
230
231 dev_dbg(dev, "ssi%d outputs %u Hz\n",
232 rsnd_mod_id(&ssi->mod), rate);
233
234 return 0;
235 }
236 }
237 }
238
239 dev_err(dev, "unsupported clock rate\n");
240 return -EIO;
241}
242
243static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi)
244{
245 ssi->rate = 0;
246 ssi->cr_clk = 0;
247 rsnd_adg_ssi_clk_stop(&ssi->mod);
248}
249
250static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
251 struct rsnd_dai *rdai,
252 struct rsnd_dai_stream *io)
253{
254 struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod);
255 struct device *dev = rsnd_priv_to_dev(priv);
256 u32 cr;
257
258 if (0 == ssi->usrcnt) {
259 clk_enable(ssi->clk);
260
261 if (rsnd_rdai_is_clk_master(rdai)) {
262 struct snd_pcm_runtime *runtime;
263
264 runtime = rsnd_io_to_runtime(io);
265
266 if (rsnd_ssi_clk_from_parent(ssi))
267 rsnd_ssi_hw_start(ssi->parent, rdai, io);
268 else
269 rsnd_ssi_master_clk_start(ssi, runtime->rate);
270 }
271 }
272
273 cr = ssi->cr_own |
274 ssi->cr_clk |
275 ssi->cr_etc |
276 EN;
277
278 rsnd_mod_write(&ssi->mod, SSICR, cr);
279
280 ssi->usrcnt++;
281
282 dev_dbg(dev, "ssi%d hw started\n", rsnd_mod_id(&ssi->mod));
283}
284
285static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi,
286 struct rsnd_dai *rdai)
287{
288 struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod);
289 struct device *dev = rsnd_priv_to_dev(priv);
290 u32 cr;
291
292 if (0 == ssi->usrcnt) /* stop might be called without start */
293 return;
294
295 ssi->usrcnt--;
296
297 if (0 == ssi->usrcnt) {
298 /*
299 * disable all IRQ,
300 * and, wait all data was sent
301 */
302 cr = ssi->cr_own |
303 ssi->cr_clk;
304
305 rsnd_mod_write(&ssi->mod, SSICR, cr | EN);
306 rsnd_ssi_status_check(&ssi->mod, DIRQ);
307
308 /*
309 * disable SSI,
310 * and, wait idle state
311 */
312 rsnd_mod_write(&ssi->mod, SSICR, cr); /* disabled all */
313 rsnd_ssi_status_check(&ssi->mod, IIRQ);
314
315 if (rsnd_rdai_is_clk_master(rdai)) {
316 if (rsnd_ssi_clk_from_parent(ssi))
317 rsnd_ssi_hw_stop(ssi->parent, rdai);
318 else
319 rsnd_ssi_master_clk_stop(ssi);
320 }
321
322 clk_disable(ssi->clk);
323 }
324
325 dev_dbg(dev, "ssi%d hw stopped\n", rsnd_mod_id(&ssi->mod));
326}
327
328/*
329 * SSI mod common functions
330 */
331static int rsnd_ssi_init(struct rsnd_mod *mod,
332 struct rsnd_dai *rdai,
333 struct rsnd_dai_stream *io)
334{
335 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
336 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
337 struct device *dev = rsnd_priv_to_dev(priv);
338 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
339 u32 cr;
340
341 cr = FORCE;
342
343 /*
344 * always use 32bit system word for easy clock calculation.
345 * see also rsnd_ssi_master_clk_enable()
346 */
347 cr |= SWL_32;
348
349 /*
350 * init clock settings for SSICR
351 */
352 switch (runtime->sample_bits) {
353 case 16:
354 cr |= DWL_16;
355 break;
356 case 32:
357 cr |= DWL_24;
358 break;
359 default:
360 return -EIO;
361 }
362
363 if (rdai->bit_clk_inv)
364 cr |= SCKP;
365 if (rdai->frm_clk_inv)
366 cr |= SWSP;
367 if (rdai->data_alignment)
368 cr |= SDTA;
369 if (rdai->sys_delay)
370 cr |= DEL;
371 if (rsnd_dai_is_play(rdai, io))
372 cr |= TRMD;
373
374 /*
375 * set ssi parameter
376 */
377 ssi->rdai = rdai;
378 ssi->io = io;
379 ssi->cr_own = cr;
380 ssi->err = -1; /* ignore 1st error */
381
382 rsnd_ssi_mode_set(ssi);
383
384 dev_dbg(dev, "%s.%d init\n", rsnd_mod_name(mod), rsnd_mod_id(mod));
385
386 return 0;
387}
388
389static int rsnd_ssi_quit(struct rsnd_mod *mod,
390 struct rsnd_dai *rdai,
391 struct rsnd_dai_stream *io)
392{
393 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
394 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
395 struct device *dev = rsnd_priv_to_dev(priv);
396
397 dev_dbg(dev, "%s.%d quit\n", rsnd_mod_name(mod), rsnd_mod_id(mod));
398
399 if (ssi->err > 0)
400 dev_warn(dev, "ssi under/over flow err = %d\n", ssi->err);
401
402 ssi->rdai = NULL;
403 ssi->io = NULL;
404 ssi->cr_own = 0;
405 ssi->err = 0;
406
407 return 0;
408}
409
410static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status)
411{
412 /* under/over flow error */
413 if (status & (UIRQ | OIRQ)) {
414 ssi->err++;
415
416 /* clear error status */
417 rsnd_mod_write(&ssi->mod, SSISR, 0);
418 }
419}
420
421/*
422 * SSI PIO
423 */
424static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data)
425{
426 struct rsnd_ssi *ssi = data;
427 struct rsnd_dai_stream *io = ssi->io;
428 u32 status = rsnd_mod_read(&ssi->mod, SSISR);
429 irqreturn_t ret = IRQ_NONE;
430
431 if (io && (status & DIRQ)) {
432 struct rsnd_dai *rdai = ssi->rdai;
433 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
434 u32 *buf = (u32 *)(runtime->dma_area +
435 rsnd_dai_pointer_offset(io, 0));
436
437 rsnd_ssi_record_error(ssi, status);
438
439 /*
440 * 8/16/32 data can be assesse to TDR/RDR register
441 * directly as 32bit data
442 * see rsnd_ssi_init()
443 */
444 if (rsnd_dai_is_play(rdai, io))
445 rsnd_mod_write(&ssi->mod, SSITDR, *buf);
446 else
447 *buf = rsnd_mod_read(&ssi->mod, SSIRDR);
448
449 rsnd_dai_pointer_update(io, sizeof(*buf));
450
451 ret = IRQ_HANDLED;
452 }
453
454 return ret;
455}
456
457static int rsnd_ssi_pio_start(struct rsnd_mod *mod,
458 struct rsnd_dai *rdai,
459 struct rsnd_dai_stream *io)
460{
461 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
462 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
463 struct device *dev = rsnd_priv_to_dev(priv);
464
465 /* enable PIO IRQ */
466 ssi->cr_etc = UIEN | OIEN | DIEN;
467
468 rsnd_ssi_hw_start(ssi, rdai, io);
469
470 dev_dbg(dev, "%s.%d start\n", rsnd_mod_name(mod), rsnd_mod_id(mod));
471
472 return 0;
473}
474
475static int rsnd_ssi_pio_stop(struct rsnd_mod *mod,
476 struct rsnd_dai *rdai,
477 struct rsnd_dai_stream *io)
478{
479 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
480 struct device *dev = rsnd_priv_to_dev(priv);
481 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
482
483 dev_dbg(dev, "%s.%d stop\n", rsnd_mod_name(mod), rsnd_mod_id(mod));
484
485 ssi->cr_etc = 0;
486
487 rsnd_ssi_hw_stop(ssi, rdai);
488
489 return 0;
490}
491
492static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
493 .name = "ssi (pio)",
494 .init = rsnd_ssi_init,
495 .quit = rsnd_ssi_quit,
496 .start = rsnd_ssi_pio_start,
497 .stop = rsnd_ssi_pio_stop,
498};
499
500static int rsnd_ssi_dma_inquiry(struct rsnd_dma *dma, dma_addr_t *buf, int *len)
501{
502 struct rsnd_ssi *ssi = rsnd_dma_to_ssi(dma);
503 struct rsnd_dai_stream *io = ssi->io;
504 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
505
506 *len = io->byte_per_period;
507 *buf = runtime->dma_addr +
508 rsnd_dai_pointer_offset(io, ssi->dma_offset + *len);
509 ssi->dma_offset = *len; /* it cares A/B plane */
510
511 return 0;
512}
513
514static int rsnd_ssi_dma_complete(struct rsnd_dma *dma)
515{
516 struct rsnd_ssi *ssi = rsnd_dma_to_ssi(dma);
517 struct rsnd_dai_stream *io = ssi->io;
518 u32 status = rsnd_mod_read(&ssi->mod, SSISR);
519
520 rsnd_ssi_record_error(ssi, status);
521
522 rsnd_dai_pointer_update(ssi->io, io->byte_per_period);
523
524 return 0;
525}
526
527static int rsnd_ssi_dma_start(struct rsnd_mod *mod,
528 struct rsnd_dai *rdai,
529 struct rsnd_dai_stream *io)
530{
531 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
532 struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod);
533
534 /* enable DMA transfer */
535 ssi->cr_etc = DMEN;
536 ssi->dma_offset = 0;
537
538 rsnd_dma_start(dma);
539
540 rsnd_ssi_hw_start(ssi, ssi->rdai, io);
541
542 /* enable WS continue */
543 if (rsnd_rdai_is_clk_master(rdai))
544 rsnd_mod_write(&ssi->mod, SSIWSR, CONT);
545
546 return 0;
547}
548
549static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,
550 struct rsnd_dai *rdai,
551 struct rsnd_dai_stream *io)
552{
553 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
554 struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod);
555
556 ssi->cr_etc = 0;
557
558 rsnd_ssi_hw_stop(ssi, rdai);
559
560 rsnd_dma_stop(dma);
561
562 return 0;
563}
564
565static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
566 .name = "ssi (dma)",
567 .init = rsnd_ssi_init,
568 .quit = rsnd_ssi_quit,
569 .start = rsnd_ssi_dma_start,
570 .stop = rsnd_ssi_dma_stop,
571};
572
573/*
574 * Non SSI
575 */
576static int rsnd_ssi_non(struct rsnd_mod *mod,
577 struct rsnd_dai *rdai,
578 struct rsnd_dai_stream *io)
579{
580 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
581 struct device *dev = rsnd_priv_to_dev(priv);
582
583 dev_dbg(dev, "%s\n", __func__);
584
585 return 0;
586}
587
588static struct rsnd_mod_ops rsnd_ssi_non_ops = {
589 .name = "ssi (non)",
590 .init = rsnd_ssi_non,
591 .quit = rsnd_ssi_non,
592 .start = rsnd_ssi_non,
593 .stop = rsnd_ssi_non,
594};
595
596/*
597 * ssi mod function
598 */
599struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv,
600 int dai_id, int is_play)
601{
602 struct rsnd_ssi *ssi;
603 int i, has_play;
604
605 is_play = !!is_play;
606
607 for_each_rsnd_ssi(ssi, priv, i) {
608 if (rsnd_ssi_dai_id(ssi) != dai_id)
609 continue;
610
611 has_play = !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY);
612
613 if (is_play == has_play)
614 return &ssi->mod;
615 }
616
617 return NULL;
618}
619
620struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id)
621{
622 BUG_ON(id < 0 || id >= rsnd_ssi_nr(priv));
623
624 return &(((struct rsnd_ssiu *)(priv->ssiu))->ssi + id)->mod;
625}
626
627int rsnd_ssi_probe(struct platform_device *pdev,
628 struct rcar_snd_info *info,
629 struct rsnd_priv *priv)
630{
631 struct rsnd_ssi_platform_info *pinfo;
632 struct device *dev = rsnd_priv_to_dev(priv);
633 struct rsnd_mod_ops *ops;
634 struct clk *clk;
635 struct rsnd_ssiu *ssiu;
636 struct rsnd_ssi *ssi;
637 char name[RSND_SSI_NAME_SIZE];
638 int i, nr, ret;
639
640 /*
641 * init SSI
642 */
643 nr = info->ssi_info_nr;
644 ssiu = devm_kzalloc(dev, sizeof(*ssiu) + (sizeof(*ssi) * nr),
645 GFP_KERNEL);
646 if (!ssiu) {
647 dev_err(dev, "SSI allocate failed\n");
648 return -ENOMEM;
649 }
650
651 priv->ssiu = ssiu;
652 ssiu->ssi = (struct rsnd_ssi *)(ssiu + 1);
653 ssiu->ssi_nr = nr;
654
655 for_each_rsnd_ssi(ssi, priv, i) {
656 pinfo = &info->ssi_info[i];
657
658 snprintf(name, RSND_SSI_NAME_SIZE, "ssi.%d", i);
659
660 clk = clk_get(dev, name);
661 if (IS_ERR(clk))
662 return PTR_ERR(clk);
663
664 ssi->info = pinfo;
665 ssi->clk = clk;
666
667 ops = &rsnd_ssi_non_ops;
668
669 /*
670 * SSI DMA case
671 */
672 if (pinfo->dma_id > 0) {
673 ret = rsnd_dma_init(
674 priv, rsnd_mod_to_dma(&ssi->mod),
675 (rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY),
676 pinfo->dma_id,
677 rsnd_ssi_dma_inquiry,
678 rsnd_ssi_dma_complete);
679 if (ret < 0)
680 dev_info(dev, "SSI DMA failed. try PIO transter\n");
681 else
682 ops = &rsnd_ssi_dma_ops;
683
684 dev_dbg(dev, "SSI%d use DMA transfer\n", i);
685 }
686
687 /*
688 * SSI PIO case
689 */
690 if (!rsnd_ssi_dma_available(ssi) &&
691 rsnd_ssi_pio_available(ssi)) {
692 ret = devm_request_irq(dev, pinfo->pio_irq,
693 &rsnd_ssi_pio_interrupt,
694 IRQF_SHARED,
695 dev_name(dev), ssi);
696 if (ret) {
697 dev_err(dev, "SSI request interrupt failed\n");
698 return ret;
699 }
700
701 ops = &rsnd_ssi_pio_ops;
702
703 dev_dbg(dev, "SSI%d use PIO transfer\n", i);
704 }
705
706 rsnd_mod_init(priv, &ssi->mod, ops, i);
707 }
708
709 rsnd_ssi_mode_init(priv, ssiu);
710
711 dev_dbg(dev, "ssi probed\n");
712
713 return 0;
714}
715
716void rsnd_ssi_remove(struct platform_device *pdev,
717 struct rsnd_priv *priv)
718{
719 struct rsnd_ssi *ssi;
720 int i;
721
722 for_each_rsnd_ssi(ssi, priv, i) {
723 clk_put(ssi->clk);
724 if (rsnd_ssi_dma_available(ssi))
725 rsnd_dma_quit(priv, rsnd_mod_to_dma(&ssi->mod));
726 }
727
728}
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 06a8000aa07b..53c9ecdd119f 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -149,8 +149,9 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
149 SND_SOC_DAPM_STREAM_STOP); 149 SND_SOC_DAPM_STREAM_STOP);
150 } else { 150 } else {
151 rtd->pop_wait = 1; 151 rtd->pop_wait = 1;
152 schedule_delayed_work(&rtd->delayed_work, 152 queue_delayed_work(system_power_efficient_wq,
153 msecs_to_jiffies(rtd->pmdown_time)); 153 &rtd->delayed_work,
154 msecs_to_jiffies(rtd->pmdown_time));
154 } 155 }
155 } else { 156 } else {
156 /* capture streams can be powered down now */ 157 /* capture streams can be powered down now */
@@ -334,7 +335,7 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
334 return ret; 335 return ret;
335} 336}
336 337
337static int sst_compr_set_metadata(struct snd_compr_stream *cstream, 338static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
338 struct snd_compr_metadata *metadata) 339 struct snd_compr_metadata *metadata)
339{ 340{
340 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 341 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
@@ -347,7 +348,7 @@ static int sst_compr_set_metadata(struct snd_compr_stream *cstream,
347 return ret; 348 return ret;
348} 349}
349 350
350static int sst_compr_get_metadata(struct snd_compr_stream *cstream, 351static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
351 struct snd_compr_metadata *metadata) 352 struct snd_compr_metadata *metadata)
352{ 353{
353 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 354 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
@@ -364,8 +365,8 @@ static struct snd_compr_ops soc_compr_ops = {
364 .open = soc_compr_open, 365 .open = soc_compr_open,
365 .free = soc_compr_free, 366 .free = soc_compr_free,
366 .set_params = soc_compr_set_params, 367 .set_params = soc_compr_set_params,
367 .set_metadata = sst_compr_set_metadata, 368 .set_metadata = soc_compr_set_metadata,
368 .get_metadata = sst_compr_get_metadata, 369 .get_metadata = soc_compr_get_metadata,
369 .get_params = soc_compr_get_params, 370 .get_params = soc_compr_get_params,
370 .trigger = soc_compr_trigger, 371 .trigger = soc_compr_trigger,
371 .pointer = soc_compr_pointer, 372 .pointer = soc_compr_pointer,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d82ee386eab5..4d0561312f3b 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -30,9 +30,12 @@
30#include <linux/bitops.h> 30#include <linux/bitops.h>
31#include <linux/debugfs.h> 31#include <linux/debugfs.h>
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/pinctrl/consumer.h>
33#include <linux/ctype.h> 34#include <linux/ctype.h>
34#include <linux/slab.h> 35#include <linux/slab.h>
35#include <linux/of.h> 36#include <linux/of.h>
37#include <linux/gpio.h>
38#include <linux/of_gpio.h>
36#include <sound/ac97_codec.h> 39#include <sound/ac97_codec.h>
37#include <sound/core.h> 40#include <sound/core.h>
38#include <sound/jack.h> 41#include <sound/jack.h>
@@ -47,8 +50,6 @@
47 50
48#define NAME_SIZE 32 51#define NAME_SIZE 32
49 52
50static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq);
51
52#ifdef CONFIG_DEBUG_FS 53#ifdef CONFIG_DEBUG_FS
53struct dentry *snd_soc_debugfs_root; 54struct dentry *snd_soc_debugfs_root;
54EXPORT_SYMBOL_GPL(snd_soc_debugfs_root); 55EXPORT_SYMBOL_GPL(snd_soc_debugfs_root);
@@ -69,6 +70,16 @@ static int pmdown_time = 5000;
69module_param(pmdown_time, int, 0); 70module_param(pmdown_time, int, 0);
70MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)"); 71MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
71 72
73struct snd_ac97_reset_cfg {
74 struct pinctrl *pctl;
75 struct pinctrl_state *pstate_reset;
76 struct pinctrl_state *pstate_warm_reset;
77 struct pinctrl_state *pstate_run;
78 int gpio_sdata;
79 int gpio_sync;
80 int gpio_reset;
81};
82
72/* returns the minimum number of bytes needed to represent 83/* returns the minimum number of bytes needed to represent
73 * a particular given value */ 84 * a particular given value */
74static int min_bytes_needed(unsigned long val) 85static int min_bytes_needed(unsigned long val)
@@ -192,7 +203,7 @@ static ssize_t pmdown_time_set(struct device *dev,
192 struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev); 203 struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
193 int ret; 204 int ret;
194 205
195 ret = strict_strtol(buf, 10, &rtd->pmdown_time); 206 ret = kstrtol(buf, 10, &rtd->pmdown_time);
196 if (ret) 207 if (ret)
197 return ret; 208 return ret;
198 209
@@ -237,6 +248,7 @@ static ssize_t codec_reg_write_file(struct file *file,
237 char *start = buf; 248 char *start = buf;
238 unsigned long reg, value; 249 unsigned long reg, value;
239 struct snd_soc_codec *codec = file->private_data; 250 struct snd_soc_codec *codec = file->private_data;
251 int ret;
240 252
241 buf_size = min(count, (sizeof(buf)-1)); 253 buf_size = min(count, (sizeof(buf)-1));
242 if (copy_from_user(buf, user_buf, buf_size)) 254 if (copy_from_user(buf, user_buf, buf_size))
@@ -248,8 +260,9 @@ static ssize_t codec_reg_write_file(struct file *file,
248 reg = simple_strtoul(start, &start, 16); 260 reg = simple_strtoul(start, &start, 16);
249 while (*start == ' ') 261 while (*start == ' ')
250 start++; 262 start++;
251 if (strict_strtoul(start, 16, &value)) 263 ret = kstrtoul(start, 16, &value);
252 return -EINVAL; 264 if (ret)
265 return ret;
253 266
254 /* Userspace has been fiddling around behind the kernel's back */ 267 /* Userspace has been fiddling around behind the kernel's back */
255 add_taint(TAINT_USER, LOCKDEP_NOW_UNRELIABLE); 268 add_taint(TAINT_USER, LOCKDEP_NOW_UNRELIABLE);
@@ -530,6 +543,15 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
530} 543}
531#endif 544#endif
532 545
546static void codec2codec_close_delayed_work(struct work_struct *work)
547{
548 /* Currently nothing to do for c2c links
549 * Since c2c links are internal nodes in the DAPM graph and
550 * don't interface with the outside world or application layer
551 * we don't have to do any special handling on close.
552 */
553}
554
533#ifdef CONFIG_PM_SLEEP 555#ifdef CONFIG_PM_SLEEP
534/* powers down audio subsystem for suspend */ 556/* powers down audio subsystem for suspend */
535int snd_soc_suspend(struct device *dev) 557int snd_soc_suspend(struct device *dev)
@@ -1223,9 +1245,6 @@ static int soc_post_component_init(struct snd_soc_card *card,
1223 } 1245 }
1224 rtd->card = card; 1246 rtd->card = card;
1225 1247
1226 /* Make sure all DAPM widgets are instantiated */
1227 snd_soc_dapm_new_widgets(&codec->dapm);
1228
1229 /* machine controls, routes and widgets are not prefixed */ 1248 /* machine controls, routes and widgets are not prefixed */
1230 temp = codec->name_prefix; 1249 temp = codec->name_prefix;
1231 codec->name_prefix = NULL; 1250 codec->name_prefix = NULL;
@@ -1428,6 +1447,9 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1428 return ret; 1447 return ret;
1429 } 1448 }
1430 } else { 1449 } else {
1450 INIT_DELAYED_WORK(&rtd->delayed_work,
1451 codec2codec_close_delayed_work);
1452
1431 /* link the DAI widgets */ 1453 /* link the DAI widgets */
1432 play_w = codec_dai->playback_widget; 1454 play_w = codec_dai->playback_widget;
1433 capture_w = cpu_dai->capture_widget; 1455 capture_w = cpu_dai->capture_widget;
@@ -1718,8 +1740,6 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1718 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, 1740 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
1719 card->num_dapm_routes); 1741 card->num_dapm_routes);
1720 1742
1721 snd_soc_dapm_new_widgets(&card->dapm);
1722
1723 for (i = 0; i < card->num_links; i++) { 1743 for (i = 0; i < card->num_links; i++) {
1724 dai_link = &card->dai_link[i]; 1744 dai_link = &card->dai_link[i];
1725 dai_fmt = dai_link->dai_fmt; 1745 dai_fmt = dai_link->dai_fmt;
@@ -1798,12 +1818,12 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1798 } 1818 }
1799 } 1819 }
1800 1820
1801 snd_soc_dapm_new_widgets(&card->dapm);
1802
1803 if (card->fully_routed) 1821 if (card->fully_routed)
1804 list_for_each_entry(codec, &card->codec_dev_list, card_list) 1822 list_for_each_entry(codec, &card->codec_dev_list, card_list)
1805 snd_soc_dapm_auto_nc_codec_pins(codec); 1823 snd_soc_dapm_auto_nc_codec_pins(codec);
1806 1824
1825 snd_soc_dapm_new_widgets(card);
1826
1807 ret = snd_card_register(card->snd_card); 1827 ret = snd_card_register(card->snd_card);
1808 if (ret < 0) { 1828 if (ret < 0) {
1809 dev_err(card->dev, "ASoC: failed to register soundcard %d\n", 1829 dev_err(card->dev, "ASoC: failed to register soundcard %d\n",
@@ -2080,6 +2100,117 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
2080} 2100}
2081EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); 2101EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
2082 2102
2103static struct snd_ac97_reset_cfg snd_ac97_rst_cfg;
2104
2105static void snd_soc_ac97_warm_reset(struct snd_ac97 *ac97)
2106{
2107 struct pinctrl *pctl = snd_ac97_rst_cfg.pctl;
2108
2109 pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_warm_reset);
2110
2111 gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 1);
2112
2113 udelay(10);
2114
2115 gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0);
2116
2117 pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run);
2118 msleep(2);
2119}
2120
2121static void snd_soc_ac97_reset(struct snd_ac97 *ac97)
2122{
2123 struct pinctrl *pctl = snd_ac97_rst_cfg.pctl;
2124
2125 pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_reset);
2126
2127 gpio_direction_output(snd_ac97_rst_cfg.gpio_sync, 0);
2128 gpio_direction_output(snd_ac97_rst_cfg.gpio_sdata, 0);
2129 gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 0);
2130
2131 udelay(10);
2132
2133 gpio_direction_output(snd_ac97_rst_cfg.gpio_reset, 1);
2134
2135 pinctrl_select_state(pctl, snd_ac97_rst_cfg.pstate_run);
2136 msleep(2);
2137}
2138
2139static int snd_soc_ac97_parse_pinctl(struct device *dev,
2140 struct snd_ac97_reset_cfg *cfg)
2141{
2142 struct pinctrl *p;
2143 struct pinctrl_state *state;
2144 int gpio;
2145 int ret;
2146
2147 p = devm_pinctrl_get(dev);
2148 if (IS_ERR(p)) {
2149 dev_err(dev, "Failed to get pinctrl\n");
2150 return PTR_RET(p);
2151 }
2152 cfg->pctl = p;
2153
2154 state = pinctrl_lookup_state(p, "ac97-reset");
2155 if (IS_ERR(state)) {
2156 dev_err(dev, "Can't find pinctrl state ac97-reset\n");
2157 return PTR_RET(state);
2158 }
2159 cfg->pstate_reset = state;
2160
2161 state = pinctrl_lookup_state(p, "ac97-warm-reset");
2162 if (IS_ERR(state)) {
2163 dev_err(dev, "Can't find pinctrl state ac97-warm-reset\n");
2164 return PTR_RET(state);
2165 }
2166 cfg->pstate_warm_reset = state;
2167
2168 state = pinctrl_lookup_state(p, "ac97-running");
2169 if (IS_ERR(state)) {
2170 dev_err(dev, "Can't find pinctrl state ac97-running\n");
2171 return PTR_RET(state);
2172 }
2173 cfg->pstate_run = state;
2174
2175 gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 0);
2176 if (gpio < 0) {
2177 dev_err(dev, "Can't find ac97-sync gpio\n");
2178 return gpio;
2179 }
2180 ret = devm_gpio_request(dev, gpio, "AC97 link sync");
2181 if (ret) {
2182 dev_err(dev, "Failed requesting ac97-sync gpio\n");
2183 return ret;
2184 }
2185 cfg->gpio_sync = gpio;
2186
2187 gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 1);
2188 if (gpio < 0) {
2189 dev_err(dev, "Can't find ac97-sdata gpio %d\n", gpio);
2190 return gpio;
2191 }
2192 ret = devm_gpio_request(dev, gpio, "AC97 link sdata");
2193 if (ret) {
2194 dev_err(dev, "Failed requesting ac97-sdata gpio\n");
2195 return ret;
2196 }
2197 cfg->gpio_sdata = gpio;
2198
2199 gpio = of_get_named_gpio(dev->of_node, "ac97-gpios", 2);
2200 if (gpio < 0) {
2201 dev_err(dev, "Can't find ac97-reset gpio\n");
2202 return gpio;
2203 }
2204 ret = devm_gpio_request(dev, gpio, "AC97 link reset");
2205 if (ret) {
2206 dev_err(dev, "Failed requesting ac97-reset gpio\n");
2207 return ret;
2208 }
2209 cfg->gpio_reset = gpio;
2210
2211 return 0;
2212}
2213
2083struct snd_ac97_bus_ops *soc_ac97_ops; 2214struct snd_ac97_bus_ops *soc_ac97_ops;
2084EXPORT_SYMBOL_GPL(soc_ac97_ops); 2215EXPORT_SYMBOL_GPL(soc_ac97_ops);
2085 2216
@@ -2098,6 +2229,35 @@ int snd_soc_set_ac97_ops(struct snd_ac97_bus_ops *ops)
2098EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops); 2229EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops);
2099 2230
2100/** 2231/**
2232 * snd_soc_set_ac97_ops_of_reset - Set ac97 ops with generic ac97 reset functions
2233 *
2234 * This function sets the reset and warm_reset properties of ops and parses
2235 * the device node of pdev to get pinctrl states and gpio numbers to use.
2236 */
2237int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops,
2238 struct platform_device *pdev)
2239{
2240 struct device *dev = &pdev->dev;
2241 struct snd_ac97_reset_cfg cfg;
2242 int ret;
2243
2244 ret = snd_soc_ac97_parse_pinctl(dev, &cfg);
2245 if (ret)
2246 return ret;
2247
2248 ret = snd_soc_set_ac97_ops(ops);
2249 if (ret)
2250 return ret;
2251
2252 ops->warm_reset = snd_soc_ac97_warm_reset;
2253 ops->reset = snd_soc_ac97_reset;
2254
2255 snd_ac97_rst_cfg = cfg;
2256 return 0;
2257}
2258EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops_of_reset);
2259
2260/**
2101 * snd_soc_free_ac97_codec - free AC97 codec device 2261 * snd_soc_free_ac97_codec - free AC97 codec device
2102 * @codec: audio codec 2262 * @codec: audio codec
2103 * 2263 *
@@ -2299,6 +2459,22 @@ static int snd_soc_add_controls(struct snd_card *card, struct device *dev,
2299 return 0; 2459 return 0;
2300} 2460}
2301 2461
2462struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
2463 const char *name)
2464{
2465 struct snd_card *card = soc_card->snd_card;
2466 struct snd_kcontrol *kctl;
2467
2468 if (unlikely(!name))
2469 return NULL;
2470
2471 list_for_each_entry(kctl, &card->controls, list)
2472 if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name)))
2473 return kctl;
2474 return NULL;
2475}
2476EXPORT_SYMBOL_GPL(snd_soc_card_get_kcontrol);
2477
2302/** 2478/**
2303 * snd_soc_add_codec_controls - add an array of controls to a codec. 2479 * snd_soc_add_codec_controls - add an array of controls to a codec.
2304 * Convenience function to add a list of controls. Many codecs were 2480 * Convenience function to add a list of controls. Many codecs were
@@ -2541,59 +2717,6 @@ int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
2541EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double); 2717EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double);
2542 2718
2543/** 2719/**
2544 * snd_soc_info_enum_ext - external enumerated single mixer info callback
2545 * @kcontrol: mixer control
2546 * @uinfo: control element information
2547 *
2548 * Callback to provide information about an external enumerated
2549 * single mixer.
2550 *
2551 * Returns 0 for success.
2552 */
2553int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol,
2554 struct snd_ctl_elem_info *uinfo)
2555{
2556 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2557
2558 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2559 uinfo->count = 1;
2560 uinfo->value.enumerated.items = e->max;
2561
2562 if (uinfo->value.enumerated.item > e->max - 1)
2563 uinfo->value.enumerated.item = e->max - 1;
2564 strcpy(uinfo->value.enumerated.name,
2565 e->texts[uinfo->value.enumerated.item]);
2566 return 0;
2567}
2568EXPORT_SYMBOL_GPL(snd_soc_info_enum_ext);
2569
2570/**
2571 * snd_soc_info_volsw_ext - external single mixer info callback
2572 * @kcontrol: mixer control
2573 * @uinfo: control element information
2574 *
2575 * Callback to provide information about a single external mixer control.
2576 *
2577 * Returns 0 for success.
2578 */
2579int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol,
2580 struct snd_ctl_elem_info *uinfo)
2581{
2582 int max = kcontrol->private_value;
2583
2584 if (max == 1 && !strstr(kcontrol->id.name, " Volume"))
2585 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2586 else
2587 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2588
2589 uinfo->count = 1;
2590 uinfo->value.integer.min = 0;
2591 uinfo->value.integer.max = max;
2592 return 0;
2593}
2594EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext);
2595
2596/**
2597 * snd_soc_info_volsw - single mixer info callback 2720 * snd_soc_info_volsw - single mixer info callback
2598 * @kcontrol: mixer control 2721 * @kcontrol: mixer control
2599 * @uinfo: control element information 2722 * @uinfo: control element information
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 4375c9f2b791..c17c14c394df 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -47,6 +47,15 @@
47 47
48#define DAPM_UPDATE_STAT(widget, val) widget->dapm->card->dapm_stats.val++; 48#define DAPM_UPDATE_STAT(widget, val) widget->dapm->card->dapm_stats.val++;
49 49
50static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm,
51 struct snd_soc_dapm_widget *wsource, struct snd_soc_dapm_widget *wsink,
52 const char *control,
53 int (*connected)(struct snd_soc_dapm_widget *source,
54 struct snd_soc_dapm_widget *sink));
55static struct snd_soc_dapm_widget *
56snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
57 const struct snd_soc_dapm_widget *widget);
58
50/* dapm power sequences - make this per codec in the future */ 59/* dapm power sequences - make this per codec in the future */
51static int dapm_up_seq[] = { 60static int dapm_up_seq[] = {
52 [snd_soc_dapm_pre] = 0, 61 [snd_soc_dapm_pre] = 0,
@@ -73,16 +82,18 @@ static int dapm_up_seq[] = {
73 [snd_soc_dapm_hp] = 10, 82 [snd_soc_dapm_hp] = 10,
74 [snd_soc_dapm_spk] = 10, 83 [snd_soc_dapm_spk] = 10,
75 [snd_soc_dapm_line] = 10, 84 [snd_soc_dapm_line] = 10,
76 [snd_soc_dapm_post] = 11, 85 [snd_soc_dapm_kcontrol] = 11,
86 [snd_soc_dapm_post] = 12,
77}; 87};
78 88
79static int dapm_down_seq[] = { 89static int dapm_down_seq[] = {
80 [snd_soc_dapm_pre] = 0, 90 [snd_soc_dapm_pre] = 0,
81 [snd_soc_dapm_adc] = 1, 91 [snd_soc_dapm_kcontrol] = 1,
82 [snd_soc_dapm_hp] = 2, 92 [snd_soc_dapm_adc] = 2,
83 [snd_soc_dapm_spk] = 2, 93 [snd_soc_dapm_hp] = 3,
84 [snd_soc_dapm_line] = 2, 94 [snd_soc_dapm_spk] = 3,
85 [snd_soc_dapm_out_drv] = 2, 95 [snd_soc_dapm_line] = 3,
96 [snd_soc_dapm_out_drv] = 3,
86 [snd_soc_dapm_pga] = 4, 97 [snd_soc_dapm_pga] = 4,
87 [snd_soc_dapm_switch] = 5, 98 [snd_soc_dapm_switch] = 5,
88 [snd_soc_dapm_mixer_named_ctl] = 5, 99 [snd_soc_dapm_mixer_named_ctl] = 5,
@@ -174,35 +185,177 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
174 return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL); 185 return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL);
175} 186}
176 187
177/* get snd_card from DAPM context */ 188struct dapm_kcontrol_data {
178static inline struct snd_card *dapm_get_snd_card( 189 unsigned int value;
179 struct snd_soc_dapm_context *dapm) 190 struct snd_soc_dapm_widget *widget;
191 struct list_head paths;
192 struct snd_soc_dapm_widget_list *wlist;
193};
194
195static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
196 struct snd_kcontrol *kcontrol)
180{ 197{
181 if (dapm->codec) 198 struct dapm_kcontrol_data *data;
182 return dapm->codec->card->snd_card; 199 struct soc_mixer_control *mc;
183 else if (dapm->platform)
184 return dapm->platform->card->snd_card;
185 else
186 BUG();
187 200
188 /* unreachable */ 201 data = kzalloc(sizeof(*data), GFP_KERNEL);
189 return NULL; 202 if (!data) {
203 dev_err(widget->dapm->dev,
204 "ASoC: can't allocate kcontrol data for %s\n",
205 widget->name);
206 return -ENOMEM;
207 }
208
209 INIT_LIST_HEAD(&data->paths);
210
211 switch (widget->id) {
212 case snd_soc_dapm_switch:
213 case snd_soc_dapm_mixer:
214 case snd_soc_dapm_mixer_named_ctl:
215 mc = (struct soc_mixer_control *)kcontrol->private_value;
216
217 if (mc->autodisable) {
218 struct snd_soc_dapm_widget template;
219
220 memset(&template, 0, sizeof(template));
221 template.reg = mc->reg;
222 template.mask = (1 << fls(mc->max)) - 1;
223 template.shift = mc->shift;
224 if (mc->invert)
225 template.off_val = mc->max;
226 else
227 template.off_val = 0;
228 template.on_val = template.off_val;
229 template.id = snd_soc_dapm_kcontrol;
230 template.name = kcontrol->id.name;
231
232 data->value = template.on_val;
233
234 data->widget = snd_soc_dapm_new_control(widget->dapm,
235 &template);
236 if (!data->widget) {
237 kfree(data);
238 return -ENOMEM;
239 }
240 }
241 break;
242 default:
243 break;
244 }
245
246 kcontrol->private_data = data;
247
248 return 0;
190} 249}
191 250
192/* get soc_card from DAPM context */ 251static void dapm_kcontrol_free(struct snd_kcontrol *kctl)
193static inline struct snd_soc_card *dapm_get_soc_card(
194 struct snd_soc_dapm_context *dapm)
195{ 252{
196 if (dapm->codec) 253 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kctl);
197 return dapm->codec->card; 254 kfree(data->widget);
198 else if (dapm->platform) 255 kfree(data->wlist);
199 return dapm->platform->card; 256 kfree(data);
257}
258
259static struct snd_soc_dapm_widget_list *dapm_kcontrol_get_wlist(
260 const struct snd_kcontrol *kcontrol)
261{
262 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
263
264 return data->wlist;
265}
266
267static int dapm_kcontrol_add_widget(struct snd_kcontrol *kcontrol,
268 struct snd_soc_dapm_widget *widget)
269{
270 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
271 struct snd_soc_dapm_widget_list *new_wlist;
272 unsigned int n;
273
274 if (data->wlist)
275 n = data->wlist->num_widgets + 1;
200 else 276 else
201 BUG(); 277 n = 1;
202 278
203 /* unreachable */ 279 new_wlist = krealloc(data->wlist,
204 return NULL; 280 sizeof(*new_wlist) + sizeof(widget) * n, GFP_KERNEL);
281 if (!new_wlist)
282 return -ENOMEM;
283
284 new_wlist->widgets[n - 1] = widget;
285 new_wlist->num_widgets = n;
286
287 data->wlist = new_wlist;
288
289 return 0;
290}
291
292static void dapm_kcontrol_add_path(const struct snd_kcontrol *kcontrol,
293 struct snd_soc_dapm_path *path)
294{
295 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
296
297 list_add_tail(&path->list_kcontrol, &data->paths);
298
299 if (data->widget) {
300 snd_soc_dapm_add_path(data->widget->dapm, data->widget,
301 path->source, NULL, NULL);
302 }
303}
304
305static bool dapm_kcontrol_is_powered(const struct snd_kcontrol *kcontrol)
306{
307 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
308
309 if (!data->widget)
310 return true;
311
312 return data->widget->power;
313}
314
315static struct list_head *dapm_kcontrol_get_path_list(
316 const struct snd_kcontrol *kcontrol)
317{
318 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
319
320 return &data->paths;
321}
322
323#define dapm_kcontrol_for_each_path(path, kcontrol) \
324 list_for_each_entry(path, dapm_kcontrol_get_path_list(kcontrol), \
325 list_kcontrol)
326
327static unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol)
328{
329 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
330
331 return data->value;
332}
333
334static bool dapm_kcontrol_set_value(const struct snd_kcontrol *kcontrol,
335 unsigned int value)
336{
337 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
338
339 if (data->value == value)
340 return false;
341
342 if (data->widget)
343 data->widget->on_val = value;
344
345 data->value = value;
346
347 return true;
348}
349
350/**
351 * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
352 * @kcontrol: The kcontrol
353 */
354struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(struct snd_kcontrol *kcontrol)
355{
356 return dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->codec;
205} 357}
358EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_codec);
206 359
207static void dapm_reset(struct snd_soc_card *card) 360static void dapm_reset(struct snd_soc_card *card)
208{ 361{
@@ -211,6 +364,7 @@ static void dapm_reset(struct snd_soc_card *card)
211 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); 364 memset(&card->dapm_stats, 0, sizeof(card->dapm_stats));
212 365
213 list_for_each_entry(w, &card->widgets, list) { 366 list_for_each_entry(w, &card->widgets, list) {
367 w->new_power = w->power;
214 w->power_checked = false; 368 w->power_checked = false;
215 w->inputs = -1; 369 w->inputs = -1;
216 w->outputs = -1; 370 w->outputs = -1;
@@ -428,6 +582,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
428 case snd_soc_dapm_spk: 582 case snd_soc_dapm_spk:
429 case snd_soc_dapm_line: 583 case snd_soc_dapm_line:
430 case snd_soc_dapm_dai_link: 584 case snd_soc_dapm_dai_link:
585 case snd_soc_dapm_kcontrol:
431 p->connect = 1; 586 p->connect = 1;
432 break; 587 break;
433 /* does affect routing - dynamically connected */ 588 /* does affect routing - dynamically connected */
@@ -507,17 +662,12 @@ static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm,
507 return 0; 662 return 0;
508} 663}
509 664
510static void dapm_kcontrol_free(struct snd_kcontrol *kctl)
511{
512 kfree(kctl->private_data);
513}
514
515/* 665/*
516 * Determine if a kcontrol is shared. If it is, look it up. If it isn't, 666 * Determine if a kcontrol is shared. If it is, look it up. If it isn't,
517 * create it. Either way, add the widget into the control's widget list 667 * create it. Either way, add the widget into the control's widget list
518 */ 668 */
519static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w, 669static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
520 int kci, struct snd_soc_dapm_path *path) 670 int kci)
521{ 671{
522 struct snd_soc_dapm_context *dapm = w->dapm; 672 struct snd_soc_dapm_context *dapm = w->dapm;
523 struct snd_card *card = dapm->card->snd_card; 673 struct snd_card *card = dapm->card->snd_card;
@@ -525,9 +675,6 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
525 size_t prefix_len; 675 size_t prefix_len;
526 int shared; 676 int shared;
527 struct snd_kcontrol *kcontrol; 677 struct snd_kcontrol *kcontrol;
528 struct snd_soc_dapm_widget_list *wlist;
529 int wlistentries;
530 size_t wlistsize;
531 bool wname_in_long_name, kcname_in_long_name; 678 bool wname_in_long_name, kcname_in_long_name;
532 char *long_name; 679 char *long_name;
533 const char *name; 680 const char *name;
@@ -546,25 +693,6 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
546 shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[kci], 693 shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[kci],
547 &kcontrol); 694 &kcontrol);
548 695
549 if (kcontrol) {
550 wlist = kcontrol->private_data;
551 wlistentries = wlist->num_widgets + 1;
552 } else {
553 wlist = NULL;
554 wlistentries = 1;
555 }
556
557 wlistsize = sizeof(struct snd_soc_dapm_widget_list) +
558 wlistentries * sizeof(struct snd_soc_dapm_widget *);
559 wlist = krealloc(wlist, wlistsize, GFP_KERNEL);
560 if (wlist == NULL) {
561 dev_err(dapm->dev, "ASoC: can't allocate widget list for %s\n",
562 w->name);
563 return -ENOMEM;
564 }
565 wlist->num_widgets = wlistentries;
566 wlist->widgets[wlistentries - 1] = w;
567
568 if (!kcontrol) { 696 if (!kcontrol) {
569 if (shared) { 697 if (shared) {
570 wname_in_long_name = false; 698 wname_in_long_name = false;
@@ -587,7 +715,6 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
587 kcname_in_long_name = false; 715 kcname_in_long_name = false;
588 break; 716 break;
589 default: 717 default:
590 kfree(wlist);
591 return -EINVAL; 718 return -EINVAL;
592 } 719 }
593 } 720 }
@@ -602,10 +729,8 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
602 long_name = kasprintf(GFP_KERNEL, "%s %s", 729 long_name = kasprintf(GFP_KERNEL, "%s %s",
603 w->name + prefix_len, 730 w->name + prefix_len,
604 w->kcontrol_news[kci].name); 731 w->kcontrol_news[kci].name);
605 if (long_name == NULL) { 732 if (long_name == NULL)
606 kfree(wlist);
607 return -ENOMEM; 733 return -ENOMEM;
608 }
609 734
610 name = long_name; 735 name = long_name;
611 } else if (wname_in_long_name) { 736 } else if (wname_in_long_name) {
@@ -616,23 +741,33 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
616 name = w->kcontrol_news[kci].name; 741 name = w->kcontrol_news[kci].name;
617 } 742 }
618 743
619 kcontrol = snd_soc_cnew(&w->kcontrol_news[kci], wlist, name, 744 kcontrol = snd_soc_cnew(&w->kcontrol_news[kci], NULL, name,
620 prefix); 745 prefix);
621 kcontrol->private_free = dapm_kcontrol_free;
622 kfree(long_name); 746 kfree(long_name);
747 if (!kcontrol)
748 return -ENOMEM;
749 kcontrol->private_free = dapm_kcontrol_free;
750
751 ret = dapm_kcontrol_data_alloc(w, kcontrol);
752 if (ret) {
753 snd_ctl_free_one(kcontrol);
754 return ret;
755 }
756
623 ret = snd_ctl_add(card, kcontrol); 757 ret = snd_ctl_add(card, kcontrol);
624 if (ret < 0) { 758 if (ret < 0) {
625 dev_err(dapm->dev, 759 dev_err(dapm->dev,
626 "ASoC: failed to add widget %s dapm kcontrol %s: %d\n", 760 "ASoC: failed to add widget %s dapm kcontrol %s: %d\n",
627 w->name, name, ret); 761 w->name, name, ret);
628 kfree(wlist);
629 return ret; 762 return ret;
630 } 763 }
631 } 764 }
632 765
633 kcontrol->private_data = wlist; 766 ret = dapm_kcontrol_add_widget(kcontrol, w);
767 if (ret)
768 return ret;
769
634 w->kcontrols[kci] = kcontrol; 770 w->kcontrols[kci] = kcontrol;
635 path->kcontrol = kcontrol;
636 771
637 return 0; 772 return 0;
638} 773}
@@ -652,13 +787,15 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
652 continue; 787 continue;
653 788
654 if (w->kcontrols[i]) { 789 if (w->kcontrols[i]) {
655 path->kcontrol = w->kcontrols[i]; 790 dapm_kcontrol_add_path(w->kcontrols[i], path);
656 continue; 791 continue;
657 } 792 }
658 793
659 ret = dapm_create_or_share_mixmux_kcontrol(w, i, path); 794 ret = dapm_create_or_share_mixmux_kcontrol(w, i);
660 if (ret < 0) 795 if (ret < 0)
661 return ret; 796 return ret;
797
798 dapm_kcontrol_add_path(w->kcontrols[i], path);
662 } 799 }
663 } 800 }
664 801
@@ -684,15 +821,12 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
684 return -EINVAL; 821 return -EINVAL;
685 } 822 }
686 823
687 path = list_first_entry(&w->sources, struct snd_soc_dapm_path, 824 ret = dapm_create_or_share_mixmux_kcontrol(w, 0);
688 list_sink);
689
690 ret = dapm_create_or_share_mixmux_kcontrol(w, 0, path);
691 if (ret < 0) 825 if (ret < 0)
692 return ret; 826 return ret;
693 827
694 list_for_each_entry(path, &w->sources, list_sink) 828 list_for_each_entry(path, &w->sources, list_sink)
695 path->kcontrol = w->kcontrols[0]; 829 dapm_kcontrol_add_path(w->kcontrols[0], path);
696 830
697 return 0; 831 return 0;
698} 832}
@@ -813,6 +947,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
813 case snd_soc_dapm_supply: 947 case snd_soc_dapm_supply:
814 case snd_soc_dapm_regulator_supply: 948 case snd_soc_dapm_regulator_supply:
815 case snd_soc_dapm_clock_supply: 949 case snd_soc_dapm_clock_supply:
950 case snd_soc_dapm_kcontrol:
816 return 0; 951 return 0;
817 default: 952 default:
818 break; 953 break;
@@ -908,6 +1043,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
908 case snd_soc_dapm_supply: 1043 case snd_soc_dapm_supply:
909 case snd_soc_dapm_regulator_supply: 1044 case snd_soc_dapm_regulator_supply:
910 case snd_soc_dapm_clock_supply: 1045 case snd_soc_dapm_clock_supply:
1046 case snd_soc_dapm_kcontrol:
911 return 0; 1047 return 0;
912 default: 1048 default:
913 break; 1049 break;
@@ -1062,7 +1198,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
1062 int ret; 1198 int ret;
1063 1199
1064 if (SND_SOC_DAPM_EVENT_ON(event)) { 1200 if (SND_SOC_DAPM_EVENT_ON(event)) {
1065 if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) { 1201 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) {
1066 ret = regulator_allow_bypass(w->regulator, false); 1202 ret = regulator_allow_bypass(w->regulator, false);
1067 if (ret != 0) 1203 if (ret != 0)
1068 dev_warn(w->dapm->dev, 1204 dev_warn(w->dapm->dev,
@@ -1072,7 +1208,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
1072 1208
1073 return regulator_enable(w->regulator); 1209 return regulator_enable(w->regulator);
1074 } else { 1210 } else {
1075 if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) { 1211 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) {
1076 ret = regulator_allow_bypass(w->regulator, true); 1212 ret = regulator_allow_bypass(w->regulator, true);
1077 if (ret != 0) 1213 if (ret != 0)
1078 dev_warn(w->dapm->dev, 1214 dev_warn(w->dapm->dev,
@@ -1244,10 +1380,9 @@ static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget,
1244 list_add_tail(&new_widget->power_list, list); 1380 list_add_tail(&new_widget->power_list, list);
1245} 1381}
1246 1382
1247static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm, 1383static void dapm_seq_check_event(struct snd_soc_card *card,
1248 struct snd_soc_dapm_widget *w, int event) 1384 struct snd_soc_dapm_widget *w, int event)
1249{ 1385{
1250 struct snd_soc_card *card = dapm->card;
1251 const char *ev_name; 1386 const char *ev_name;
1252 int power, ret; 1387 int power, ret;
1253 1388
@@ -1281,55 +1416,50 @@ static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm,
1281 return; 1416 return;
1282 } 1417 }
1283 1418
1284 if (w->power != power) 1419 if (w->new_power != power)
1285 return; 1420 return;
1286 1421
1287 if (w->event && (w->event_flags & event)) { 1422 if (w->event && (w->event_flags & event)) {
1288 pop_dbg(dapm->dev, card->pop_time, "pop test : %s %s\n", 1423 pop_dbg(w->dapm->dev, card->pop_time, "pop test : %s %s\n",
1289 w->name, ev_name); 1424 w->name, ev_name);
1290 trace_snd_soc_dapm_widget_event_start(w, event); 1425 trace_snd_soc_dapm_widget_event_start(w, event);
1291 ret = w->event(w, NULL, event); 1426 ret = w->event(w, NULL, event);
1292 trace_snd_soc_dapm_widget_event_done(w, event); 1427 trace_snd_soc_dapm_widget_event_done(w, event);
1293 if (ret < 0) 1428 if (ret < 0)
1294 dev_err(dapm->dev, "ASoC: %s: %s event failed: %d\n", 1429 dev_err(w->dapm->dev, "ASoC: %s: %s event failed: %d\n",
1295 ev_name, w->name, ret); 1430 ev_name, w->name, ret);
1296 } 1431 }
1297} 1432}
1298 1433
1299/* Apply the coalesced changes from a DAPM sequence */ 1434/* Apply the coalesced changes from a DAPM sequence */
1300static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, 1435static void dapm_seq_run_coalesced(struct snd_soc_card *card,
1301 struct list_head *pending) 1436 struct list_head *pending)
1302{ 1437{
1303 struct snd_soc_card *card = dapm->card;
1304 struct snd_soc_dapm_widget *w; 1438 struct snd_soc_dapm_widget *w;
1305 int reg, power; 1439 int reg;
1306 unsigned int value = 0; 1440 unsigned int value = 0;
1307 unsigned int mask = 0; 1441 unsigned int mask = 0;
1308 unsigned int cur_mask;
1309 1442
1310 reg = list_first_entry(pending, struct snd_soc_dapm_widget, 1443 reg = list_first_entry(pending, struct snd_soc_dapm_widget,
1311 power_list)->reg; 1444 power_list)->reg;
1312 1445
1313 list_for_each_entry(w, pending, power_list) { 1446 list_for_each_entry(w, pending, power_list) {
1314 cur_mask = 1 << w->shift;
1315 BUG_ON(reg != w->reg); 1447 BUG_ON(reg != w->reg);
1448 w->power = w->new_power;
1316 1449
1317 if (w->invert) 1450 mask |= w->mask << w->shift;
1318 power = !w->power; 1451 if (w->power)
1452 value |= w->on_val << w->shift;
1319 else 1453 else
1320 power = w->power; 1454 value |= w->off_val << w->shift;
1321 1455
1322 mask |= cur_mask; 1456 pop_dbg(w->dapm->dev, card->pop_time,
1323 if (power)
1324 value |= cur_mask;
1325
1326 pop_dbg(dapm->dev, card->pop_time,
1327 "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n", 1457 "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n",
1328 w->name, reg, value, mask); 1458 w->name, reg, value, mask);
1329 1459
1330 /* Check for events */ 1460 /* Check for events */
1331 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMU); 1461 dapm_seq_check_event(card, w, SND_SOC_DAPM_PRE_PMU);
1332 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMD); 1462 dapm_seq_check_event(card, w, SND_SOC_DAPM_PRE_PMD);
1333 } 1463 }
1334 1464
1335 if (reg >= 0) { 1465 if (reg >= 0) {
@@ -1339,7 +1469,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm,
1339 w = list_first_entry(pending, struct snd_soc_dapm_widget, 1469 w = list_first_entry(pending, struct snd_soc_dapm_widget,
1340 power_list); 1470 power_list);
1341 1471
1342 pop_dbg(dapm->dev, card->pop_time, 1472 pop_dbg(w->dapm->dev, card->pop_time,
1343 "pop test : Applying 0x%x/0x%x to %x in %dms\n", 1473 "pop test : Applying 0x%x/0x%x to %x in %dms\n",
1344 value, mask, reg, card->pop_time); 1474 value, mask, reg, card->pop_time);
1345 pop_wait(card->pop_time); 1475 pop_wait(card->pop_time);
@@ -1347,8 +1477,8 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm,
1347 } 1477 }
1348 1478
1349 list_for_each_entry(w, pending, power_list) { 1479 list_for_each_entry(w, pending, power_list) {
1350 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMU); 1480 dapm_seq_check_event(card, w, SND_SOC_DAPM_POST_PMU);
1351 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMD); 1481 dapm_seq_check_event(card, w, SND_SOC_DAPM_POST_PMD);
1352 } 1482 }
1353} 1483}
1354 1484
@@ -1360,8 +1490,8 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm,
1360 * Currently anything that requires more than a single write is not 1490 * Currently anything that requires more than a single write is not
1361 * handled. 1491 * handled.
1362 */ 1492 */
1363static void dapm_seq_run(struct snd_soc_dapm_context *dapm, 1493static void dapm_seq_run(struct snd_soc_card *card,
1364 struct list_head *list, int event, bool power_up) 1494 struct list_head *list, int event, bool power_up)
1365{ 1495{
1366 struct snd_soc_dapm_widget *w, *n; 1496 struct snd_soc_dapm_widget *w, *n;
1367 LIST_HEAD(pending); 1497 LIST_HEAD(pending);
@@ -1384,7 +1514,7 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
1384 if (sort[w->id] != cur_sort || w->reg != cur_reg || 1514 if (sort[w->id] != cur_sort || w->reg != cur_reg ||
1385 w->dapm != cur_dapm || w->subseq != cur_subseq) { 1515 w->dapm != cur_dapm || w->subseq != cur_subseq) {
1386 if (!list_empty(&pending)) 1516 if (!list_empty(&pending))
1387 dapm_seq_run_coalesced(cur_dapm, &pending); 1517 dapm_seq_run_coalesced(card, &pending);
1388 1518
1389 if (cur_dapm && cur_dapm->seq_notifier) { 1519 if (cur_dapm && cur_dapm->seq_notifier) {
1390 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++) 1520 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
@@ -1444,7 +1574,7 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
1444 } 1574 }
1445 1575
1446 if (!list_empty(&pending)) 1576 if (!list_empty(&pending))
1447 dapm_seq_run_coalesced(cur_dapm, &pending); 1577 dapm_seq_run_coalesced(card, &pending);
1448 1578
1449 if (cur_dapm && cur_dapm->seq_notifier) { 1579 if (cur_dapm && cur_dapm->seq_notifier) {
1450 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++) 1580 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++)
@@ -1454,37 +1584,48 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
1454 } 1584 }
1455} 1585}
1456 1586
1457static void dapm_widget_update(struct snd_soc_dapm_context *dapm) 1587static void dapm_widget_update(struct snd_soc_card *card)
1458{ 1588{
1459 struct snd_soc_dapm_update *update = dapm->update; 1589 struct snd_soc_dapm_update *update = card->update;
1460 struct snd_soc_dapm_widget *w; 1590 struct snd_soc_dapm_widget_list *wlist;
1591 struct snd_soc_dapm_widget *w = NULL;
1592 unsigned int wi;
1461 int ret; 1593 int ret;
1462 1594
1463 if (!update) 1595 if (!update || !dapm_kcontrol_is_powered(update->kcontrol))
1464 return; 1596 return;
1465 1597
1466 w = update->widget; 1598 wlist = dapm_kcontrol_get_wlist(update->kcontrol);
1467 1599
1468 if (w->event && 1600 for (wi = 0; wi < wlist->num_widgets; wi++) {
1469 (w->event_flags & SND_SOC_DAPM_PRE_REG)) { 1601 w = wlist->widgets[wi];
1470 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG); 1602
1471 if (ret != 0) 1603 if (w->event && (w->event_flags & SND_SOC_DAPM_PRE_REG)) {
1472 dev_err(dapm->dev, "ASoC: %s DAPM pre-event failed: %d\n", 1604 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG);
1473 w->name, ret); 1605 if (ret != 0)
1606 dev_err(w->dapm->dev, "ASoC: %s DAPM pre-event failed: %d\n",
1607 w->name, ret);
1608 }
1474 } 1609 }
1475 1610
1611 if (!w)
1612 return;
1613
1476 ret = soc_widget_update_bits_locked(w, update->reg, update->mask, 1614 ret = soc_widget_update_bits_locked(w, update->reg, update->mask,
1477 update->val); 1615 update->val);
1478 if (ret < 0) 1616 if (ret < 0)
1479 dev_err(dapm->dev, "ASoC: %s DAPM update failed: %d\n", 1617 dev_err(w->dapm->dev, "ASoC: %s DAPM update failed: %d\n",
1480 w->name, ret); 1618 w->name, ret);
1481 1619
1482 if (w->event && 1620 for (wi = 0; wi < wlist->num_widgets; wi++) {
1483 (w->event_flags & SND_SOC_DAPM_POST_REG)) { 1621 w = wlist->widgets[wi];
1484 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG); 1622
1485 if (ret != 0) 1623 if (w->event && (w->event_flags & SND_SOC_DAPM_POST_REG)) {
1486 dev_err(dapm->dev, "ASoC: %s DAPM post-event failed: %d\n", 1624 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG);
1487 w->name, ret); 1625 if (ret != 0)
1626 dev_err(w->dapm->dev, "ASoC: %s DAPM post-event failed: %d\n",
1627 w->name, ret);
1628 }
1488 } 1629 }
1489} 1630}
1490 1631
@@ -1596,6 +1737,7 @@ static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power,
1596 case snd_soc_dapm_supply: 1737 case snd_soc_dapm_supply:
1597 case snd_soc_dapm_regulator_supply: 1738 case snd_soc_dapm_regulator_supply:
1598 case snd_soc_dapm_clock_supply: 1739 case snd_soc_dapm_clock_supply:
1740 case snd_soc_dapm_kcontrol:
1599 /* Supplies can't affect their outputs, only their inputs */ 1741 /* Supplies can't affect their outputs, only their inputs */
1600 break; 1742 break;
1601 default: 1743 default:
@@ -1612,8 +1754,6 @@ static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power,
1612 dapm_seq_insert(w, up_list, true); 1754 dapm_seq_insert(w, up_list, true);
1613 else 1755 else
1614 dapm_seq_insert(w, down_list, false); 1756 dapm_seq_insert(w, down_list, false);
1615
1616 w->power = power;
1617} 1757}
1618 1758
1619static void dapm_power_one_widget(struct snd_soc_dapm_widget *w, 1759static void dapm_power_one_widget(struct snd_soc_dapm_widget *w,
@@ -1647,9 +1787,8 @@ static void dapm_power_one_widget(struct snd_soc_dapm_widget *w,
1647 * o Input pin to Output pin (bypass, sidetone) 1787 * o Input pin to Output pin (bypass, sidetone)
1648 * o DAC to ADC (loopback). 1788 * o DAC to ADC (loopback).
1649 */ 1789 */
1650static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) 1790static int dapm_power_widgets(struct snd_soc_card *card, int event)
1651{ 1791{
1652 struct snd_soc_card *card = dapm->card;
1653 struct snd_soc_dapm_widget *w; 1792 struct snd_soc_dapm_widget *w;
1654 struct snd_soc_dapm_context *d; 1793 struct snd_soc_dapm_context *d;
1655 LIST_HEAD(up_list); 1794 LIST_HEAD(up_list);
@@ -1689,7 +1828,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1689 break; 1828 break;
1690 } 1829 }
1691 1830
1692 if (w->power) { 1831 if (w->new_power) {
1693 d = w->dapm; 1832 d = w->dapm;
1694 1833
1695 /* Supplies and micbiases only bring the 1834 /* Supplies and micbiases only bring the
@@ -1731,29 +1870,29 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1731 trace_snd_soc_dapm_walk_done(card); 1870 trace_snd_soc_dapm_walk_done(card);
1732 1871
1733 /* Run all the bias changes in parallel */ 1872 /* Run all the bias changes in parallel */
1734 list_for_each_entry(d, &dapm->card->dapm_list, list) 1873 list_for_each_entry(d, &card->dapm_list, list)
1735 async_schedule_domain(dapm_pre_sequence_async, d, 1874 async_schedule_domain(dapm_pre_sequence_async, d,
1736 &async_domain); 1875 &async_domain);
1737 async_synchronize_full_domain(&async_domain); 1876 async_synchronize_full_domain(&async_domain);
1738 1877
1739 list_for_each_entry(w, &down_list, power_list) { 1878 list_for_each_entry(w, &down_list, power_list) {
1740 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_WILL_PMD); 1879 dapm_seq_check_event(card, w, SND_SOC_DAPM_WILL_PMD);
1741 } 1880 }
1742 1881
1743 list_for_each_entry(w, &up_list, power_list) { 1882 list_for_each_entry(w, &up_list, power_list) {
1744 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_WILL_PMU); 1883 dapm_seq_check_event(card, w, SND_SOC_DAPM_WILL_PMU);
1745 } 1884 }
1746 1885
1747 /* Power down widgets first; try to avoid amplifying pops. */ 1886 /* Power down widgets first; try to avoid amplifying pops. */
1748 dapm_seq_run(dapm, &down_list, event, false); 1887 dapm_seq_run(card, &down_list, event, false);
1749 1888
1750 dapm_widget_update(dapm); 1889 dapm_widget_update(card);
1751 1890
1752 /* Now power up. */ 1891 /* Now power up. */
1753 dapm_seq_run(dapm, &up_list, event, true); 1892 dapm_seq_run(card, &up_list, event, true);
1754 1893
1755 /* Run all the bias changes in parallel */ 1894 /* Run all the bias changes in parallel */
1756 list_for_each_entry(d, &dapm->card->dapm_list, list) 1895 list_for_each_entry(d, &card->dapm_list, list)
1757 async_schedule_domain(dapm_post_sequence_async, d, 1896 async_schedule_domain(dapm_post_sequence_async, d,
1758 &async_domain); 1897 &async_domain);
1759 async_synchronize_full_domain(&async_domain); 1898 async_synchronize_full_domain(&async_domain);
@@ -1764,7 +1903,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1764 d->stream_event(d, event); 1903 d->stream_event(d, event);
1765 } 1904 }
1766 1905
1767 pop_dbg(dapm->dev, card->pop_time, 1906 pop_dbg(card->dev, card->pop_time,
1768 "DAPM sequencing finished, waiting %dms\n", card->pop_time); 1907 "DAPM sequencing finished, waiting %dms\n", card->pop_time);
1769 pop_wait(card->pop_time); 1908 pop_wait(card->pop_time);
1770 1909
@@ -1799,8 +1938,8 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1799 1938
1800 if (w->reg >= 0) 1939 if (w->reg >= 0)
1801 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1940 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1802 " - R%d(0x%x) bit %d", 1941 " - R%d(0x%x) mask 0x%x",
1803 w->reg, w->reg, w->shift); 1942 w->reg, w->reg, w->mask << w->shift);
1804 1943
1805 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); 1944 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
1806 1945
@@ -1937,22 +2076,14 @@ static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
1937#endif 2076#endif
1938 2077
1939/* test and update the power status of a mux widget */ 2078/* test and update the power status of a mux widget */
1940static int soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 2079static int soc_dapm_mux_update_power(struct snd_soc_card *card,
1941 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e) 2080 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e)
1942{ 2081{
1943 struct snd_soc_dapm_path *path; 2082 struct snd_soc_dapm_path *path;
1944 int found = 0; 2083 int found = 0;
1945 2084
1946 if (widget->id != snd_soc_dapm_mux &&
1947 widget->id != snd_soc_dapm_virt_mux &&
1948 widget->id != snd_soc_dapm_value_mux)
1949 return -ENODEV;
1950
1951 /* find dapm widget path assoc with kcontrol */ 2085 /* find dapm widget path assoc with kcontrol */
1952 list_for_each_entry(path, &widget->dapm->card->paths, list) { 2086 dapm_kcontrol_for_each_path(path, kcontrol) {
1953 if (path->kcontrol != kcontrol)
1954 continue;
1955
1956 if (!path->name || !e->texts[mux]) 2087 if (!path->name || !e->texts[mux])
1957 continue; 2088 continue;
1958 2089
@@ -1967,73 +2098,68 @@ static int soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1967 "mux disconnection"); 2098 "mux disconnection");
1968 path->connect = 0; /* old connection must be powered down */ 2099 path->connect = 0; /* old connection must be powered down */
1969 } 2100 }
2101 dapm_mark_dirty(path->sink, "mux change");
1970 } 2102 }
1971 2103
1972 if (found) { 2104 if (found)
1973 dapm_mark_dirty(widget, "mux change"); 2105 dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP);
1974 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
1975 }
1976 2106
1977 return found; 2107 return found;
1978} 2108}
1979 2109
1980int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 2110int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_context *dapm,
1981 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e) 2111 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e,
2112 struct snd_soc_dapm_update *update)
1982{ 2113{
1983 struct snd_soc_card *card = widget->dapm->card; 2114 struct snd_soc_card *card = dapm->card;
1984 int ret; 2115 int ret;
1985 2116
1986 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2117 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
1987 ret = soc_dapm_mux_update_power(widget, kcontrol, mux, e); 2118 card->update = update;
2119 ret = soc_dapm_mux_update_power(card, kcontrol, mux, e);
2120 card->update = NULL;
1988 mutex_unlock(&card->dapm_mutex); 2121 mutex_unlock(&card->dapm_mutex);
1989 if (ret > 0) 2122 if (ret > 0)
1990 soc_dpcm_runtime_update(widget); 2123 soc_dpcm_runtime_update(card);
1991 return ret; 2124 return ret;
1992} 2125}
1993EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power); 2126EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power);
1994 2127
1995/* test and update the power status of a mixer or switch widget */ 2128/* test and update the power status of a mixer or switch widget */
1996static int soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, 2129static int soc_dapm_mixer_update_power(struct snd_soc_card *card,
1997 struct snd_kcontrol *kcontrol, int connect) 2130 struct snd_kcontrol *kcontrol, int connect)
1998{ 2131{
1999 struct snd_soc_dapm_path *path; 2132 struct snd_soc_dapm_path *path;
2000 int found = 0; 2133 int found = 0;
2001 2134
2002 if (widget->id != snd_soc_dapm_mixer &&
2003 widget->id != snd_soc_dapm_mixer_named_ctl &&
2004 widget->id != snd_soc_dapm_switch)
2005 return -ENODEV;
2006
2007 /* find dapm widget path assoc with kcontrol */ 2135 /* find dapm widget path assoc with kcontrol */
2008 list_for_each_entry(path, &widget->dapm->card->paths, list) { 2136 dapm_kcontrol_for_each_path(path, kcontrol) {
2009 if (path->kcontrol != kcontrol)
2010 continue;
2011
2012 /* found, now check type */
2013 found = 1; 2137 found = 1;
2014 path->connect = connect; 2138 path->connect = connect;
2015 dapm_mark_dirty(path->source, "mixer connection"); 2139 dapm_mark_dirty(path->source, "mixer connection");
2140 dapm_mark_dirty(path->sink, "mixer update");
2016 } 2141 }
2017 2142
2018 if (found) { 2143 if (found)
2019 dapm_mark_dirty(widget, "mixer update"); 2144 dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP);
2020 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
2021 }
2022 2145
2023 return found; 2146 return found;
2024} 2147}
2025 2148
2026int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, 2149int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_context *dapm,
2027 struct snd_kcontrol *kcontrol, int connect) 2150 struct snd_kcontrol *kcontrol, int connect,
2151 struct snd_soc_dapm_update *update)
2028{ 2152{
2029 struct snd_soc_card *card = widget->dapm->card; 2153 struct snd_soc_card *card = dapm->card;
2030 int ret; 2154 int ret;
2031 2155
2032 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2156 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2033 ret = soc_dapm_mixer_update_power(widget, kcontrol, connect); 2157 card->update = update;
2158 ret = soc_dapm_mixer_update_power(card, kcontrol, connect);
2159 card->update = NULL;
2034 mutex_unlock(&card->dapm_mutex); 2160 mutex_unlock(&card->dapm_mutex);
2035 if (ret > 0) 2161 if (ret > 0)
2036 soc_dpcm_runtime_update(widget); 2162 soc_dpcm_runtime_update(card);
2037 return ret; 2163 return ret;
2038} 2164}
2039EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power); 2165EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power);
@@ -2112,6 +2238,7 @@ static void dapm_free_path(struct snd_soc_dapm_path *path)
2112{ 2238{
2113 list_del(&path->list_sink); 2239 list_del(&path->list_sink);
2114 list_del(&path->list_source); 2240 list_del(&path->list_source);
2241 list_del(&path->list_kcontrol);
2115 list_del(&path->list); 2242 list_del(&path->list);
2116 kfree(path); 2243 kfree(path);
2117} 2244}
@@ -2206,70 +2333,20 @@ int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
2206 return 0; 2333 return 0;
2207 2334
2208 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2335 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2209 ret = dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); 2336 ret = dapm_power_widgets(dapm->card, SND_SOC_DAPM_STREAM_NOP);
2210 mutex_unlock(&dapm->card->dapm_mutex); 2337 mutex_unlock(&dapm->card->dapm_mutex);
2211 return ret; 2338 return ret;
2212} 2339}
2213EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 2340EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
2214 2341
2215static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, 2342static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm,
2216 const struct snd_soc_dapm_route *route) 2343 struct snd_soc_dapm_widget *wsource, struct snd_soc_dapm_widget *wsink,
2344 const char *control,
2345 int (*connected)(struct snd_soc_dapm_widget *source,
2346 struct snd_soc_dapm_widget *sink))
2217{ 2347{
2218 struct snd_soc_dapm_path *path; 2348 struct snd_soc_dapm_path *path;
2219 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; 2349 int ret;
2220 struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL;
2221 const char *sink;
2222 const char *control = route->control;
2223 const char *source;
2224 char prefixed_sink[80];
2225 char prefixed_source[80];
2226 int ret = 0;
2227
2228 if (dapm->codec && dapm->codec->name_prefix) {
2229 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
2230 dapm->codec->name_prefix, route->sink);
2231 sink = prefixed_sink;
2232 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
2233 dapm->codec->name_prefix, route->source);
2234 source = prefixed_source;
2235 } else {
2236 sink = route->sink;
2237 source = route->source;
2238 }
2239
2240 /*
2241 * find src and dest widgets over all widgets but favor a widget from
2242 * current DAPM context
2243 */
2244 list_for_each_entry(w, &dapm->card->widgets, list) {
2245 if (!wsink && !(strcmp(w->name, sink))) {
2246 wtsink = w;
2247 if (w->dapm == dapm)
2248 wsink = w;
2249 continue;
2250 }
2251 if (!wsource && !(strcmp(w->name, source))) {
2252 wtsource = w;
2253 if (w->dapm == dapm)
2254 wsource = w;
2255 }
2256 }
2257 /* use widget from another DAPM context if not found from this */
2258 if (!wsink)
2259 wsink = wtsink;
2260 if (!wsource)
2261 wsource = wtsource;
2262
2263 if (wsource == NULL) {
2264 dev_err(dapm->dev, "ASoC: no source widget found for %s\n",
2265 route->source);
2266 return -ENODEV;
2267 }
2268 if (wsink == NULL) {
2269 dev_err(dapm->dev, "ASoC: no sink widget found for %s\n",
2270 route->sink);
2271 return -ENODEV;
2272 }
2273 2350
2274 path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL); 2351 path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL);
2275 if (!path) 2352 if (!path)
@@ -2277,8 +2354,9 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
2277 2354
2278 path->source = wsource; 2355 path->source = wsource;
2279 path->sink = wsink; 2356 path->sink = wsink;
2280 path->connected = route->connected; 2357 path->connected = connected;
2281 INIT_LIST_HEAD(&path->list); 2358 INIT_LIST_HEAD(&path->list);
2359 INIT_LIST_HEAD(&path->list_kcontrol);
2282 INIT_LIST_HEAD(&path->list_source); 2360 INIT_LIST_HEAD(&path->list_source);
2283 INIT_LIST_HEAD(&path->list_sink); 2361 INIT_LIST_HEAD(&path->list_sink);
2284 2362
@@ -2298,6 +2376,9 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
2298 wsource->ext = 1; 2376 wsource->ext = 1;
2299 } 2377 }
2300 2378
2379 dapm_mark_dirty(wsource, "Route added");
2380 dapm_mark_dirty(wsink, "Route added");
2381
2301 /* connect static paths */ 2382 /* connect static paths */
2302 if (control == NULL) { 2383 if (control == NULL) {
2303 list_add(&path->list, &dapm->card->paths); 2384 list_add(&path->list, &dapm->card->paths);
@@ -2328,6 +2409,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
2328 case snd_soc_dapm_dai_in: 2409 case snd_soc_dapm_dai_in:
2329 case snd_soc_dapm_dai_out: 2410 case snd_soc_dapm_dai_out:
2330 case snd_soc_dapm_dai_link: 2411 case snd_soc_dapm_dai_link:
2412 case snd_soc_dapm_kcontrol:
2331 list_add(&path->list, &dapm->card->paths); 2413 list_add(&path->list, &dapm->card->paths);
2332 list_add(&path->list_sink, &wsink->sources); 2414 list_add(&path->list_sink, &wsink->sources);
2333 list_add(&path->list_source, &wsource->sinks); 2415 list_add(&path->list_source, &wsource->sinks);
@@ -2359,15 +2441,78 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
2359 return 0; 2441 return 0;
2360 } 2442 }
2361 2443
2362 dapm_mark_dirty(wsource, "Route added");
2363 dapm_mark_dirty(wsink, "Route added");
2364
2365 return 0; 2444 return 0;
2445err:
2446 kfree(path);
2447 return ret;
2448}
2449
2450static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
2451 const struct snd_soc_dapm_route *route)
2452{
2453 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
2454 struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL;
2455 const char *sink;
2456 const char *source;
2457 char prefixed_sink[80];
2458 char prefixed_source[80];
2459 int ret;
2460
2461 if (dapm->codec && dapm->codec->name_prefix) {
2462 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
2463 dapm->codec->name_prefix, route->sink);
2464 sink = prefixed_sink;
2465 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
2466 dapm->codec->name_prefix, route->source);
2467 source = prefixed_source;
2468 } else {
2469 sink = route->sink;
2470 source = route->source;
2471 }
2472
2473 /*
2474 * find src and dest widgets over all widgets but favor a widget from
2475 * current DAPM context
2476 */
2477 list_for_each_entry(w, &dapm->card->widgets, list) {
2478 if (!wsink && !(strcmp(w->name, sink))) {
2479 wtsink = w;
2480 if (w->dapm == dapm)
2481 wsink = w;
2482 continue;
2483 }
2484 if (!wsource && !(strcmp(w->name, source))) {
2485 wtsource = w;
2486 if (w->dapm == dapm)
2487 wsource = w;
2488 }
2489 }
2490 /* use widget from another DAPM context if not found from this */
2491 if (!wsink)
2492 wsink = wtsink;
2493 if (!wsource)
2494 wsource = wtsource;
2366 2495
2496 if (wsource == NULL) {
2497 dev_err(dapm->dev, "ASoC: no source widget found for %s\n",
2498 route->source);
2499 return -ENODEV;
2500 }
2501 if (wsink == NULL) {
2502 dev_err(dapm->dev, "ASoC: no sink widget found for %s\n",
2503 route->sink);
2504 return -ENODEV;
2505 }
2506
2507 ret = snd_soc_dapm_add_path(dapm, wsource, wsink, route->control,
2508 route->connected);
2509 if (ret)
2510 goto err;
2511
2512 return 0;
2367err: 2513err:
2368 dev_warn(dapm->dev, "ASoC: no dapm match for %s --> %s --> %s\n", 2514 dev_warn(dapm->dev, "ASoC: no dapm match for %s --> %s --> %s\n",
2369 source, control, sink); 2515 source, route->control, sink);
2370 kfree(path);
2371 return ret; 2516 return ret;
2372} 2517}
2373 2518
@@ -2569,14 +2714,14 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_weak_routes);
2569 * 2714 *
2570 * Returns 0 for success. 2715 * Returns 0 for success.
2571 */ 2716 */
2572int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) 2717int snd_soc_dapm_new_widgets(struct snd_soc_card *card)
2573{ 2718{
2574 struct snd_soc_dapm_widget *w; 2719 struct snd_soc_dapm_widget *w;
2575 unsigned int val; 2720 unsigned int val;
2576 2721
2577 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); 2722 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
2578 2723
2579 list_for_each_entry(w, &dapm->card->widgets, list) 2724 list_for_each_entry(w, &card->widgets, list)
2580 { 2725 {
2581 if (w->new) 2726 if (w->new)
2582 continue; 2727 continue;
@@ -2586,7 +2731,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
2586 sizeof(struct snd_kcontrol *), 2731 sizeof(struct snd_kcontrol *),
2587 GFP_KERNEL); 2732 GFP_KERNEL);
2588 if (!w->kcontrols) { 2733 if (!w->kcontrols) {
2589 mutex_unlock(&dapm->card->dapm_mutex); 2734 mutex_unlock(&card->dapm_mutex);
2590 return -ENOMEM; 2735 return -ENOMEM;
2591 } 2736 }
2592 } 2737 }
@@ -2612,12 +2757,9 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
2612 2757
2613 /* Read the initial power state from the device */ 2758 /* Read the initial power state from the device */
2614 if (w->reg >= 0) { 2759 if (w->reg >= 0) {
2615 val = soc_widget_read(w, w->reg); 2760 val = soc_widget_read(w, w->reg) >> w->shift;
2616 val &= 1 << w->shift; 2761 val &= w->mask;
2617 if (w->invert) 2762 if (val == w->on_val)
2618 val = !val;
2619
2620 if (val)
2621 w->power = 1; 2763 w->power = 1;
2622 } 2764 }
2623 2765
@@ -2627,8 +2769,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
2627 dapm_debugfs_add_widget(w); 2769 dapm_debugfs_add_widget(w);
2628 } 2770 }
2629 2771
2630 dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); 2772 dapm_power_widgets(card, SND_SOC_DAPM_STREAM_NOP);
2631 mutex_unlock(&dapm->card->dapm_mutex); 2773 mutex_unlock(&card->dapm_mutex);
2632 return 0; 2774 return 0;
2633} 2775}
2634EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets); 2776EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
@@ -2645,8 +2787,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
2645int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol, 2787int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
2646 struct snd_ctl_elem_value *ucontrol) 2788 struct snd_ctl_elem_value *ucontrol)
2647{ 2789{
2648 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2790 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
2649 struct snd_soc_dapm_widget *widget = wlist->widgets[0]; 2791 struct snd_soc_card *card = codec->card;
2650 struct soc_mixer_control *mc = 2792 struct soc_mixer_control *mc =
2651 (struct soc_mixer_control *)kcontrol->private_value; 2793 (struct soc_mixer_control *)kcontrol->private_value;
2652 unsigned int reg = mc->reg; 2794 unsigned int reg = mc->reg;
@@ -2654,17 +2796,24 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
2654 int max = mc->max; 2796 int max = mc->max;
2655 unsigned int mask = (1 << fls(max)) - 1; 2797 unsigned int mask = (1 << fls(max)) - 1;
2656 unsigned int invert = mc->invert; 2798 unsigned int invert = mc->invert;
2799 unsigned int val;
2657 2800
2658 if (snd_soc_volsw_is_stereo(mc)) 2801 if (snd_soc_volsw_is_stereo(mc))
2659 dev_warn(widget->dapm->dev, 2802 dev_warn(codec->dapm.dev,
2660 "ASoC: Control '%s' is stereo, which is not supported\n", 2803 "ASoC: Control '%s' is stereo, which is not supported\n",
2661 kcontrol->id.name); 2804 kcontrol->id.name);
2662 2805
2663 ucontrol->value.integer.value[0] = 2806 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2664 (snd_soc_read(widget->codec, reg) >> shift) & mask; 2807 if (dapm_kcontrol_is_powered(kcontrol))
2808 val = (snd_soc_read(codec, reg) >> shift) & mask;
2809 else
2810 val = dapm_kcontrol_get_value(kcontrol);
2811 mutex_unlock(&card->dapm_mutex);
2812
2665 if (invert) 2813 if (invert)
2666 ucontrol->value.integer.value[0] = 2814 ucontrol->value.integer.value[0] = max - val;
2667 max - ucontrol->value.integer.value[0]; 2815 else
2816 ucontrol->value.integer.value[0] = val;
2668 2817
2669 return 0; 2818 return 0;
2670} 2819}
@@ -2682,9 +2831,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw);
2682int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, 2831int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2683 struct snd_ctl_elem_value *ucontrol) 2832 struct snd_ctl_elem_value *ucontrol)
2684{ 2833{
2685 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2834 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
2686 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2687 struct snd_soc_codec *codec = widget->codec;
2688 struct snd_soc_card *card = codec->card; 2835 struct snd_soc_card *card = codec->card;
2689 struct soc_mixer_control *mc = 2836 struct soc_mixer_control *mc =
2690 (struct soc_mixer_control *)kcontrol->private_value; 2837 (struct soc_mixer_control *)kcontrol->private_value;
@@ -2696,10 +2843,9 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2696 unsigned int val; 2843 unsigned int val;
2697 int connect, change; 2844 int connect, change;
2698 struct snd_soc_dapm_update update; 2845 struct snd_soc_dapm_update update;
2699 int wi;
2700 2846
2701 if (snd_soc_volsw_is_stereo(mc)) 2847 if (snd_soc_volsw_is_stereo(mc))
2702 dev_warn(widget->dapm->dev, 2848 dev_warn(codec->dapm.dev,
2703 "ASoC: Control '%s' is stereo, which is not supported\n", 2849 "ASoC: Control '%s' is stereo, which is not supported\n",
2704 kcontrol->id.name); 2850 kcontrol->id.name);
2705 2851
@@ -2708,29 +2854,26 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2708 2854
2709 if (invert) 2855 if (invert)
2710 val = max - val; 2856 val = max - val;
2711 mask = mask << shift;
2712 val = val << shift;
2713 2857
2714 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2858 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2715 2859
2716 change = snd_soc_test_bits(widget->codec, reg, mask, val); 2860 dapm_kcontrol_set_value(kcontrol, val);
2717 if (change) {
2718 for (wi = 0; wi < wlist->num_widgets; wi++) {
2719 widget = wlist->widgets[wi];
2720 2861
2721 widget->value = val; 2862 mask = mask << shift;
2863 val = val << shift;
2722 2864
2723 update.kcontrol = kcontrol; 2865 change = snd_soc_test_bits(codec, reg, mask, val);
2724 update.widget = widget; 2866 if (change) {
2725 update.reg = reg; 2867 update.kcontrol = kcontrol;
2726 update.mask = mask; 2868 update.reg = reg;
2727 update.val = val; 2869 update.mask = mask;
2728 widget->dapm->update = &update; 2870 update.val = val;
2729 2871
2730 soc_dapm_mixer_update_power(widget, kcontrol, connect); 2872 card->update = &update;
2731 2873
2732 widget->dapm->update = NULL; 2874 soc_dapm_mixer_update_power(card, kcontrol, connect);
2733 } 2875
2876 card->update = NULL;
2734 } 2877 }
2735 2878
2736 mutex_unlock(&card->dapm_mutex); 2879 mutex_unlock(&card->dapm_mutex);
@@ -2750,12 +2893,11 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
2750int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol, 2893int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
2751 struct snd_ctl_elem_value *ucontrol) 2894 struct snd_ctl_elem_value *ucontrol)
2752{ 2895{
2753 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2896 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
2754 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2755 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2897 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2756 unsigned int val; 2898 unsigned int val;
2757 2899
2758 val = snd_soc_read(widget->codec, e->reg); 2900 val = snd_soc_read(codec, e->reg);
2759 ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & e->mask; 2901 ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & e->mask;
2760 if (e->shift_l != e->shift_r) 2902 if (e->shift_l != e->shift_r)
2761 ucontrol->value.enumerated.item[1] = 2903 ucontrol->value.enumerated.item[1] =
@@ -2777,15 +2919,12 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
2777int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, 2919int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
2778 struct snd_ctl_elem_value *ucontrol) 2920 struct snd_ctl_elem_value *ucontrol)
2779{ 2921{
2780 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2922 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
2781 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2782 struct snd_soc_codec *codec = widget->codec;
2783 struct snd_soc_card *card = codec->card; 2923 struct snd_soc_card *card = codec->card;
2784 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2924 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2785 unsigned int val, mux, change; 2925 unsigned int val, mux, change;
2786 unsigned int mask; 2926 unsigned int mask;
2787 struct snd_soc_dapm_update update; 2927 struct snd_soc_dapm_update update;
2788 int wi;
2789 2928
2790 if (ucontrol->value.enumerated.item[0] > e->max - 1) 2929 if (ucontrol->value.enumerated.item[0] > e->max - 1)
2791 return -EINVAL; 2930 return -EINVAL;
@@ -2801,24 +2940,17 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
2801 2940
2802 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2941 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2803 2942
2804 change = snd_soc_test_bits(widget->codec, e->reg, mask, val); 2943 change = snd_soc_test_bits(codec, e->reg, mask, val);
2805 if (change) { 2944 if (change) {
2806 for (wi = 0; wi < wlist->num_widgets; wi++) { 2945 update.kcontrol = kcontrol;
2807 widget = wlist->widgets[wi]; 2946 update.reg = e->reg;
2808 2947 update.mask = mask;
2809 widget->value = val; 2948 update.val = val;
2949 card->update = &update;
2810 2950
2811 update.kcontrol = kcontrol; 2951 soc_dapm_mux_update_power(card, kcontrol, mux, e);
2812 update.widget = widget;
2813 update.reg = e->reg;
2814 update.mask = mask;
2815 update.val = val;
2816 widget->dapm->update = &update;
2817 2952
2818 soc_dapm_mux_update_power(widget, kcontrol, mux, e); 2953 card->update = NULL;
2819
2820 widget->dapm->update = NULL;
2821 }
2822 } 2954 }
2823 2955
2824 mutex_unlock(&card->dapm_mutex); 2956 mutex_unlock(&card->dapm_mutex);
@@ -2836,11 +2968,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
2836int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol, 2968int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol,
2837 struct snd_ctl_elem_value *ucontrol) 2969 struct snd_ctl_elem_value *ucontrol)
2838{ 2970{
2839 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2971 ucontrol->value.enumerated.item[0] = dapm_kcontrol_get_value(kcontrol);
2840 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2841
2842 ucontrol->value.enumerated.item[0] = widget->value;
2843
2844 return 0; 2972 return 0;
2845} 2973}
2846EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_virt); 2974EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_virt);
@@ -2855,30 +2983,22 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_virt);
2855int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol, 2983int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
2856 struct snd_ctl_elem_value *ucontrol) 2984 struct snd_ctl_elem_value *ucontrol)
2857{ 2985{
2858 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2986 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
2859 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2860 struct snd_soc_codec *codec = widget->codec;
2861 struct snd_soc_card *card = codec->card; 2987 struct snd_soc_card *card = codec->card;
2988 unsigned int value;
2862 struct soc_enum *e = 2989 struct soc_enum *e =
2863 (struct soc_enum *)kcontrol->private_value; 2990 (struct soc_enum *)kcontrol->private_value;
2864 int change; 2991 int change;
2865 int wi;
2866 2992
2867 if (ucontrol->value.enumerated.item[0] >= e->max) 2993 if (ucontrol->value.enumerated.item[0] >= e->max)
2868 return -EINVAL; 2994 return -EINVAL;
2869 2995
2870 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2996 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2871 2997
2872 change = widget->value != ucontrol->value.enumerated.item[0]; 2998 value = ucontrol->value.enumerated.item[0];
2873 if (change) { 2999 change = dapm_kcontrol_set_value(kcontrol, value);
2874 for (wi = 0; wi < wlist->num_widgets; wi++) { 3000 if (change)
2875 widget = wlist->widgets[wi]; 3001 soc_dapm_mux_update_power(card, kcontrol, value, e);
2876
2877 widget->value = ucontrol->value.enumerated.item[0];
2878
2879 soc_dapm_mux_update_power(widget, kcontrol, widget->value, e);
2880 }
2881 }
2882 3002
2883 mutex_unlock(&card->dapm_mutex); 3003 mutex_unlock(&card->dapm_mutex);
2884 return change; 3004 return change;
@@ -2901,12 +3021,11 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
2901int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol, 3021int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
2902 struct snd_ctl_elem_value *ucontrol) 3022 struct snd_ctl_elem_value *ucontrol)
2903{ 3023{
2904 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 3024 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
2905 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2906 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 3025 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2907 unsigned int reg_val, val, mux; 3026 unsigned int reg_val, val, mux;
2908 3027
2909 reg_val = snd_soc_read(widget->codec, e->reg); 3028 reg_val = snd_soc_read(codec, e->reg);
2910 val = (reg_val >> e->shift_l) & e->mask; 3029 val = (reg_val >> e->shift_l) & e->mask;
2911 for (mux = 0; mux < e->max; mux++) { 3030 for (mux = 0; mux < e->max; mux++) {
2912 if (val == e->values[mux]) 3031 if (val == e->values[mux])
@@ -2942,15 +3061,12 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_value_enum_double);
2942int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, 3061int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
2943 struct snd_ctl_elem_value *ucontrol) 3062 struct snd_ctl_elem_value *ucontrol)
2944{ 3063{
2945 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 3064 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
2946 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2947 struct snd_soc_codec *codec = widget->codec;
2948 struct snd_soc_card *card = codec->card; 3065 struct snd_soc_card *card = codec->card;
2949 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 3066 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2950 unsigned int val, mux, change; 3067 unsigned int val, mux, change;
2951 unsigned int mask; 3068 unsigned int mask;
2952 struct snd_soc_dapm_update update; 3069 struct snd_soc_dapm_update update;
2953 int wi;
2954 3070
2955 if (ucontrol->value.enumerated.item[0] > e->max - 1) 3071 if (ucontrol->value.enumerated.item[0] > e->max - 1)
2956 return -EINVAL; 3072 return -EINVAL;
@@ -2966,24 +3082,17 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
2966 3082
2967 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 3083 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2968 3084
2969 change = snd_soc_test_bits(widget->codec, e->reg, mask, val); 3085 change = snd_soc_test_bits(codec, e->reg, mask, val);
2970 if (change) { 3086 if (change) {
2971 for (wi = 0; wi < wlist->num_widgets; wi++) { 3087 update.kcontrol = kcontrol;
2972 widget = wlist->widgets[wi]; 3088 update.reg = e->reg;
2973 3089 update.mask = mask;
2974 widget->value = val; 3090 update.val = val;
3091 card->update = &update;
2975 3092
2976 update.kcontrol = kcontrol; 3093 soc_dapm_mux_update_power(card, kcontrol, mux, e);
2977 update.widget = widget;
2978 update.reg = e->reg;
2979 update.mask = mask;
2980 update.val = val;
2981 widget->dapm->update = &update;
2982 3094
2983 soc_dapm_mux_update_power(widget, kcontrol, mux, e); 3095 card->update = NULL;
2984
2985 widget->dapm->update = NULL;
2986 }
2987 } 3096 }
2988 3097
2989 mutex_unlock(&card->dapm_mutex); 3098 mutex_unlock(&card->dapm_mutex);
@@ -3080,7 +3189,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3080 return NULL; 3189 return NULL;
3081 } 3190 }
3082 3191
3083 if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) { 3192 if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) {
3084 ret = regulator_allow_bypass(w->regulator, true); 3193 ret = regulator_allow_bypass(w->regulator, true);
3085 if (ret != 0) 3194 if (ret != 0)
3086 dev_warn(w->dapm->dev, 3195 dev_warn(w->dapm->dev,
@@ -3127,16 +3236,16 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3127 case snd_soc_dapm_value_mux: 3236 case snd_soc_dapm_value_mux:
3128 w->power_check = dapm_generic_check_power; 3237 w->power_check = dapm_generic_check_power;
3129 break; 3238 break;
3130 case snd_soc_dapm_adc:
3131 case snd_soc_dapm_aif_out:
3132 case snd_soc_dapm_dai_out: 3239 case snd_soc_dapm_dai_out:
3133 w->power_check = dapm_adc_check_power; 3240 w->power_check = dapm_adc_check_power;
3134 break; 3241 break;
3135 case snd_soc_dapm_dac:
3136 case snd_soc_dapm_aif_in:
3137 case snd_soc_dapm_dai_in: 3242 case snd_soc_dapm_dai_in:
3138 w->power_check = dapm_dac_check_power; 3243 w->power_check = dapm_dac_check_power;
3139 break; 3244 break;
3245 case snd_soc_dapm_adc:
3246 case snd_soc_dapm_aif_out:
3247 case snd_soc_dapm_dac:
3248 case snd_soc_dapm_aif_in:
3140 case snd_soc_dapm_pga: 3249 case snd_soc_dapm_pga:
3141 case snd_soc_dapm_out_drv: 3250 case snd_soc_dapm_out_drv:
3142 case snd_soc_dapm_input: 3251 case snd_soc_dapm_input:
@@ -3152,6 +3261,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3152 case snd_soc_dapm_supply: 3261 case snd_soc_dapm_supply:
3153 case snd_soc_dapm_regulator_supply: 3262 case snd_soc_dapm_regulator_supply:
3154 case snd_soc_dapm_clock_supply: 3263 case snd_soc_dapm_clock_supply:
3264 case snd_soc_dapm_kcontrol:
3155 w->power_check = dapm_supply_check_power; 3265 w->power_check = dapm_supply_check_power;
3156 break; 3266 break;
3157 default: 3267 default:
@@ -3416,9 +3526,6 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
3416{ 3526{
3417 struct snd_soc_dapm_widget *dai_w, *w; 3527 struct snd_soc_dapm_widget *dai_w, *w;
3418 struct snd_soc_dai *dai; 3528 struct snd_soc_dai *dai;
3419 struct snd_soc_dapm_route r;
3420
3421 memset(&r, 0, sizeof(r));
3422 3529
3423 /* For each DAI widget... */ 3530 /* For each DAI widget... */
3424 list_for_each_entry(dai_w, &card->widgets, list) { 3531 list_for_each_entry(dai_w, &card->widgets, list) {
@@ -3445,29 +3552,27 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
3445 break; 3552 break;
3446 } 3553 }
3447 3554
3448 if (!w->sname) 3555 if (!w->sname || !strstr(w->sname, dai_w->name))
3449 continue; 3556 continue;
3450 3557
3451 if (dai->driver->playback.stream_name && 3558 if (dai->driver->playback.stream_name &&
3452 strstr(w->sname, 3559 strstr(w->sname,
3453 dai->driver->playback.stream_name)) { 3560 dai->driver->playback.stream_name)) {
3454 r.source = dai->playback_widget->name;
3455 r.sink = w->name;
3456 dev_dbg(dai->dev, "%s -> %s\n", 3561 dev_dbg(dai->dev, "%s -> %s\n",
3457 r.source, r.sink); 3562 dai->playback_widget->name, w->name);
3458 3563
3459 snd_soc_dapm_add_route(w->dapm, &r); 3564 snd_soc_dapm_add_path(w->dapm,
3565 dai->playback_widget, w, NULL, NULL);
3460 } 3566 }
3461 3567
3462 if (dai->driver->capture.stream_name && 3568 if (dai->driver->capture.stream_name &&
3463 strstr(w->sname, 3569 strstr(w->sname,
3464 dai->driver->capture.stream_name)) { 3570 dai->driver->capture.stream_name)) {
3465 r.source = w->name;
3466 r.sink = dai->capture_widget->name;
3467 dev_dbg(dai->dev, "%s -> %s\n", 3571 dev_dbg(dai->dev, "%s -> %s\n",
3468 r.source, r.sink); 3572 w->name, dai->capture_widget->name);
3469 3573
3470 snd_soc_dapm_add_route(w->dapm, &r); 3574 snd_soc_dapm_add_path(w->dapm, w,
3575 dai->capture_widget, NULL, NULL);
3471 } 3576 }
3472 } 3577 }
3473 } 3578 }
@@ -3529,7 +3634,7 @@ static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
3529 } 3634 }
3530 } 3635 }
3531 3636
3532 dapm_power_widgets(&rtd->card->dapm, event); 3637 dapm_power_widgets(rtd->card, event);
3533} 3638}
3534 3639
3535/** 3640/**
@@ -3798,7 +3903,7 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
3798 if (dapm->bias_level == SND_SOC_BIAS_ON) 3903 if (dapm->bias_level == SND_SOC_BIAS_ON)
3799 snd_soc_dapm_set_bias_level(dapm, 3904 snd_soc_dapm_set_bias_level(dapm,
3800 SND_SOC_BIAS_PREPARE); 3905 SND_SOC_BIAS_PREPARE);
3801 dapm_seq_run(dapm, &down_list, 0, false); 3906 dapm_seq_run(card, &down_list, 0, false);
3802 if (dapm->bias_level == SND_SOC_BIAS_PREPARE) 3907 if (dapm->bias_level == SND_SOC_BIAS_PREPARE)
3803 snd_soc_dapm_set_bias_level(dapm, 3908 snd_soc_dapm_set_bias_level(dapm,
3804 SND_SOC_BIAS_STANDBY); 3909 SND_SOC_BIAS_STANDBY);
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 0bb5cccd7766..71358e3b54d9 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -183,8 +183,6 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
183 list_add(&(pins[i].list), &jack->pins); 183 list_add(&(pins[i].list), &jack->pins);
184 } 184 }
185 185
186 snd_soc_dapm_new_widgets(&jack->codec->card->dapm);
187
188 /* Update to reflect the last reported status; canned jack 186 /* Update to reflect the last reported status; canned jack
189 * implementations are likely to set their state before the 187 * implementations are likely to set their state before the
190 * card has an opportunity to associate pins. 188 * card has an opportunity to associate pins.
@@ -263,7 +261,7 @@ static irqreturn_t gpio_handler(int irq, void *data)
263 if (device_may_wakeup(dev)) 261 if (device_may_wakeup(dev))
264 pm_wakeup_event(dev, gpio->debounce_time + 50); 262 pm_wakeup_event(dev, gpio->debounce_time + 50);
265 263
266 schedule_delayed_work(&gpio->work, 264 queue_delayed_work(system_power_efficient_wq, &gpio->work,
267 msecs_to_jiffies(gpio->debounce_time)); 265 msecs_to_jiffies(gpio->debounce_time));
268 266
269 return IRQ_HANDLED; 267 return IRQ_HANDLED;
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index b6c640332a17..330c9a6b5cb5 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -411,8 +411,9 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
411 } else { 411 } else {
412 /* start delayed pop wq here for playback streams */ 412 /* start delayed pop wq here for playback streams */
413 rtd->pop_wait = 1; 413 rtd->pop_wait = 1;
414 schedule_delayed_work(&rtd->delayed_work, 414 queue_delayed_work(system_power_efficient_wq,
415 msecs_to_jiffies(rtd->pmdown_time)); 415 &rtd->delayed_work,
416 msecs_to_jiffies(rtd->pmdown_time));
416 } 417 }
417 } else { 418 } else {
418 /* capture streams can be powered down now */ 419 /* capture streams can be powered down now */
@@ -1832,18 +1833,10 @@ static int dpcm_run_old_update(struct snd_soc_pcm_runtime *fe, int stream)
1832/* Called by DAPM mixer/mux changes to update audio routing between PCMs and 1833/* Called by DAPM mixer/mux changes to update audio routing between PCMs and
1833 * any DAI links. 1834 * any DAI links.
1834 */ 1835 */
1835int soc_dpcm_runtime_update(struct snd_soc_dapm_widget *widget) 1836int soc_dpcm_runtime_update(struct snd_soc_card *card)
1836{ 1837{
1837 struct snd_soc_card *card;
1838 int i, old, new, paths; 1838 int i, old, new, paths;
1839 1839
1840 if (widget->codec)
1841 card = widget->codec->card;
1842 else if (widget->platform)
1843 card = widget->platform->card;
1844 else
1845 return -EINVAL;
1846
1847 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME); 1840 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1848 for (i = 0; i < card->num_rtd; i++) { 1841 for (i = 0; i < card->num_rtd; i++) {
1849 struct snd_soc_dapm_widget_list *list; 1842 struct snd_soc_dapm_widget_list *list;
@@ -2027,6 +2020,16 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2027 capture = 1; 2020 capture = 1;
2028 } 2021 }
2029 2022
2023 if (rtd->dai_link->playback_only) {
2024 playback = 1;
2025 capture = 0;
2026 }
2027
2028 if (rtd->dai_link->capture_only) {
2029 playback = 0;
2030 capture = 1;
2031 }
2032
2030 /* create the PCM */ 2033 /* create the PCM */
2031 if (rtd->dai_link->no_pcm) { 2034 if (rtd->dai_link->no_pcm) {
2032 snprintf(new_name, sizeof(new_name), "(%s)", 2035 snprintf(new_name, sizeof(new_name), "(%s)",
diff --git a/sound/soc/spear/Kconfig b/sound/soc/spear/Kconfig
index 3567d73b218e..0a53053495f3 100644
--- a/sound/soc/spear/Kconfig
+++ b/sound/soc/spear/Kconfig
@@ -1,6 +1,6 @@
1config SND_SPEAR_SOC 1config SND_SPEAR_SOC
2 tristate 2 tristate
3 select SND_SOC_DMAENGINE_PCM 3 select SND_DMAENGINE_PCM
4 4
5config SND_SPEAR_SPDIF_OUT 5config SND_SPEAR_SPDIF_OUT
6 tristate 6 tristate
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index 995b120c2cd0..8fc653ca3ab4 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -1,8 +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 && TEGRA20_APB_DMA 3 depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
4 select REGMAP_MMIO 4 select REGMAP_MMIO
5 select SND_SOC_GENERIC_DMAENGINE_PCM if TEGRA20_APB_DMA 5 select SND_SOC_GENERIC_DMAENGINE_PCM
6 help 6 help
7 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.
8 8
@@ -61,7 +61,7 @@ config SND_SOC_TEGRA30_I2S
61 61
62config SND_SOC_TEGRA_RT5640 62config SND_SOC_TEGRA_RT5640
63 tristate "SoC Audio support for Tegra boards using an RT5640 codec" 63 tristate "SoC Audio support for Tegra boards using an RT5640 codec"
64 depends on SND_SOC_TEGRA && I2C 64 depends on SND_SOC_TEGRA && I2C && GPIOLIB
65 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC 65 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
66 select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC 66 select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC
67 select SND_SOC_RT5640 67 select SND_SOC_RT5640
@@ -71,7 +71,7 @@ config SND_SOC_TEGRA_RT5640
71 71
72config SND_SOC_TEGRA_WM8753 72config SND_SOC_TEGRA_WM8753
73 tristate "SoC Audio support for Tegra boards using a WM8753 codec" 73 tristate "SoC Audio support for Tegra boards using a WM8753 codec"
74 depends on SND_SOC_TEGRA && I2C 74 depends on SND_SOC_TEGRA && I2C && GPIOLIB
75 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC 75 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
76 select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC 76 select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC
77 select SND_SOC_WM8753 77 select SND_SOC_WM8753
@@ -81,7 +81,7 @@ config SND_SOC_TEGRA_WM8753
81 81
82config SND_SOC_TEGRA_WM8903 82config SND_SOC_TEGRA_WM8903
83 tristate "SoC Audio support for Tegra boards using a WM8903 codec" 83 tristate "SoC Audio support for Tegra boards using a WM8903 codec"
84 depends on SND_SOC_TEGRA && I2C 84 depends on SND_SOC_TEGRA && I2C && GPIOLIB
85 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC 85 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
86 select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC 86 select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC
87 select SND_SOC_WM8903 87 select SND_SOC_WM8903
@@ -92,7 +92,7 @@ config SND_SOC_TEGRA_WM8903
92 92
93config SND_SOC_TEGRA_WM9712 93config SND_SOC_TEGRA_WM9712
94 tristate "SoC Audio support for Tegra boards using a WM9712 codec" 94 tristate "SoC Audio support for Tegra boards using a WM9712 codec"
95 depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC 95 depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC && GPIOLIB
96 select SND_SOC_TEGRA20_AC97 96 select SND_SOC_TEGRA20_AC97
97 select SND_SOC_WM9712 97 select SND_SOC_WM9712
98 help 98 help
@@ -110,7 +110,7 @@ config SND_SOC_TEGRA_TRIMSLICE
110 110
111config SND_SOC_TEGRA_ALC5632 111config SND_SOC_TEGRA_ALC5632
112 tristate "SoC Audio support for Tegra boards using an ALC5632 codec" 112 tristate "SoC Audio support for Tegra boards using an ALC5632 codec"
113 depends on SND_SOC_TEGRA && I2C 113 depends on SND_SOC_TEGRA && I2C && GPIOLIB
114 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC 114 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
115 select SND_SOC_ALC5632 115 select SND_SOC_ALC5632
116 help 116 help
diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c
index 6c486625321b..ae27bcd586d2 100644
--- a/sound/soc/tegra/tegra20_ac97.c
+++ b/sound/soc/tegra/tegra20_ac97.c
@@ -334,12 +334,6 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
334 } 334 }
335 335
336 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 336 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
337 if (!mem) {
338 dev_err(&pdev->dev, "No memory resource\n");
339 ret = -ENODEV;
340 goto err_clk_put;
341 }
342
343 regs = devm_ioremap_resource(&pdev->dev, mem); 337 regs = devm_ioremap_resource(&pdev->dev, mem);
344 if (IS_ERR(regs)) { 338 if (IS_ERR(regs)) {
345 ret = PTR_ERR(regs); 339 ret = PTR_ERR(regs);
@@ -432,8 +426,6 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
432 426
433 return 0; 427 return 0;
434 428
435err_unregister_pcm:
436 tegra_pcm_platform_unregister(&pdev->dev);
437err_unregister_component: 429err_unregister_component:
438 snd_soc_unregister_component(&pdev->dev); 430 snd_soc_unregister_component(&pdev->dev);
439err_asoc_utils_fini: 431err_asoc_utils_fini:
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index 48d05d9e1002..c61ea3a1030f 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -13,8 +13,6 @@
13 * published by the Free Software Foundation. 13 * published by the Free Software Foundation.
14 */ 14 */
15 15
16#include <asm/mach-types.h>
17
18#include <linux/module.h> 16#include <linux/module.h>
19#include <linux/platform_device.h> 17#include <linux/platform_device.h>
20#include <linux/slab.h> 18#include <linux/slab.h>
diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c
index 08794f915a94..4511c5a875ec 100644
--- a/sound/soc/tegra/tegra_rt5640.c
+++ b/sound/soc/tegra/tegra_rt5640.c
@@ -99,6 +99,7 @@ static struct snd_soc_jack_gpio tegra_rt5640_hp_jack_gpio = {
99static const struct snd_soc_dapm_widget tegra_rt5640_dapm_widgets[] = { 99static const struct snd_soc_dapm_widget tegra_rt5640_dapm_widgets[] = {
100 SND_SOC_DAPM_HP("Headphones", NULL), 100 SND_SOC_DAPM_HP("Headphones", NULL),
101 SND_SOC_DAPM_SPK("Speakers", NULL), 101 SND_SOC_DAPM_SPK("Speakers", NULL),
102 SND_SOC_DAPM_MIC("Mic Jack", NULL),
102}; 103};
103 104
104static const struct snd_kcontrol_new tegra_rt5640_controls[] = { 105static const struct snd_kcontrol_new tegra_rt5640_controls[] = {
diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c
index f87fc53e9b8c..8e774d1a243c 100644
--- a/sound/soc/tegra/tegra_wm8753.c
+++ b/sound/soc/tegra/tegra_wm8753.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>
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
index 05c68aab5cf0..734bfcd21148 100644
--- a/sound/soc/tegra/trimslice.c
+++ b/sound/soc/tegra/trimslice.c
@@ -24,8 +24,6 @@
24 * 24 *
25 */ 25 */
26 26
27#include <asm/mach-types.h>
28
29#include <linux/module.h> 27#include <linux/module.h>
30#include <linux/of.h> 28#include <linux/of.h>
31#include <linux/platform_device.h> 29#include <linux/platform_device.h>
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c
index 4bcce8a3cded..e0305a148568 100644
--- a/sound/soc/txx9/txx9aclc-ac97.c
+++ b/sound/soc/txx9/txx9aclc-ac97.c
@@ -184,9 +184,6 @@ static int txx9aclc_ac97_dev_probe(struct platform_device *pdev)
184 if (irq < 0) 184 if (irq < 0)
185 return irq; 185 return irq;
186 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 186 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
187 if (!r)
188 return -EBUSY;
189
190 drvdata->base = devm_ioremap_resource(&pdev->dev, r); 187 drvdata->base = devm_ioremap_resource(&pdev->dev, r);
191 if (IS_ERR(drvdata->base)) 188 if (IS_ERR(drvdata->base))
192 return PTR_ERR(drvdata->base); 189 return PTR_ERR(drvdata->base);
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
index 8f5cd00a6e46..178d1bad6259 100644
--- a/sound/soc/ux500/mop500.c
+++ b/sound/soc/ux500/mop500.c
@@ -52,6 +52,7 @@ static struct snd_soc_dai_link mop500_dai_links[] = {
52 52
53static struct snd_soc_card mop500_card = { 53static struct snd_soc_card mop500_card = {
54 .name = "MOP500-card", 54 .name = "MOP500-card",
55 .owner = THIS_MODULE,
55 .probe = NULL, 56 .probe = NULL,
56 .dai_link = mop500_dai_links, 57 .dai_link = mop500_dai_links,
57 .num_links = ARRAY_SIZE(mop500_dai_links), 58 .num_links = ARRAY_SIZE(mop500_dai_links),
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c
index b9defcdeb7ef..780bf3f62d28 100644
--- a/sound/usb/6fire/firmware.c
+++ b/sound/usb/6fire/firmware.c
@@ -346,10 +346,10 @@ static int usb6fire_fw_check(u8 *version)
346 if (!memcmp(version, known_fw_versions + i, 2)) 346 if (!memcmp(version, known_fw_versions + i, 2))
347 return 0; 347 return 0;
348 348
349 snd_printk(KERN_ERR PREFIX "invalid fimware version in device: %*ph. " 349 snd_printk(KERN_ERR PREFIX "invalid fimware version in device: %4ph. "
350 "please reconnect to power. if this failure " 350 "please reconnect to power. if this failure "
351 "still happens, check your firmware installation.", 351 "still happens, check your firmware installation.",
352 4, version); 352 version);
353 return -EINVAL; 353 return -EINVAL;
354} 354}
355 355
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 659950e5b94f..93e970f2b3c0 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -418,6 +418,9 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
418 struct snd_usb_endpoint *ep; 418 struct snd_usb_endpoint *ep;
419 int is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK; 419 int is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK;
420 420
421 if (WARN_ON(!alts))
422 return NULL;
423
421 mutex_lock(&chip->mutex); 424 mutex_lock(&chip->mutex);
422 425
423 list_for_each_entry(ep, &chip->ep_list, list) { 426 list_for_each_entry(ep, &chip->ep_list, list) {
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 15b151ed4899..b375d58871e7 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -327,6 +327,137 @@ static int search_roland_implicit_fb(struct usb_device *dev, int ifnum,
327 return 0; 327 return 0;
328} 328}
329 329
330static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs,
331 struct usb_device *dev,
332 struct usb_interface_descriptor *altsd,
333 unsigned int attr)
334{
335 struct usb_host_interface *alts;
336 struct usb_interface *iface;
337 unsigned int ep;
338
339 /* Implicit feedback sync EPs consumers are always playback EPs */
340 if (subs->direction != SNDRV_PCM_STREAM_PLAYBACK)
341 return 0;
342
343 switch (subs->stream->chip->usb_id) {
344 case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
345 case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */
346 ep = 0x81;
347 iface = usb_ifnum_to_if(dev, 3);
348
349 if (!iface || iface->num_altsetting == 0)
350 return -EINVAL;
351
352 alts = &iface->altsetting[1];
353 goto add_sync_ep;
354 break;
355 case USB_ID(0x0763, 0x2080): /* M-Audio FastTrack Ultra */
356 case USB_ID(0x0763, 0x2081):
357 ep = 0x81;
358 iface = usb_ifnum_to_if(dev, 2);
359
360 if (!iface || iface->num_altsetting == 0)
361 return -EINVAL;
362
363 alts = &iface->altsetting[1];
364 goto add_sync_ep;
365 }
366 if (attr == USB_ENDPOINT_SYNC_ASYNC &&
367 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
368 altsd->bInterfaceProtocol == 2 &&
369 altsd->bNumEndpoints == 1 &&
370 USB_ID_VENDOR(subs->stream->chip->usb_id) == 0x0582 /* Roland */ &&
371 search_roland_implicit_fb(dev, altsd->bInterfaceNumber + 1,
372 altsd->bAlternateSetting,
373 &alts, &ep) >= 0) {
374 goto add_sync_ep;
375 }
376
377 /* No quirk */
378 return 0;
379
380add_sync_ep:
381 subs->sync_endpoint = snd_usb_add_endpoint(subs->stream->chip,
382 alts, ep, !subs->direction,
383 SND_USB_ENDPOINT_TYPE_DATA);
384 if (!subs->sync_endpoint)
385 return -EINVAL;
386
387 subs->data_endpoint->sync_master = subs->sync_endpoint;
388
389 return 0;
390}
391
392static int set_sync_endpoint(struct snd_usb_substream *subs,
393 struct audioformat *fmt,
394 struct usb_device *dev,
395 struct usb_host_interface *alts,
396 struct usb_interface_descriptor *altsd)
397{
398 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
399 unsigned int ep, attr;
400 bool implicit_fb;
401 int err;
402
403 /* we need a sync pipe in async OUT or adaptive IN mode */
404 /* check the number of EP, since some devices have broken
405 * descriptors which fool us. if it has only one EP,
406 * assume it as adaptive-out or sync-in.
407 */
408 attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
409
410 err = set_sync_ep_implicit_fb_quirk(subs, dev, altsd, attr);
411 if (err < 0)
412 return err;
413
414 if (altsd->bNumEndpoints < 2)
415 return 0;
416
417 if ((is_playback && attr != USB_ENDPOINT_SYNC_ASYNC) ||
418 (!is_playback && attr != USB_ENDPOINT_SYNC_ADAPTIVE))
419 return 0;
420
421 /* check sync-pipe endpoint */
422 /* ... and check descriptor size before accessing bSynchAddress
423 because there is a version of the SB Audigy 2 NX firmware lacking
424 the audio fields in the endpoint descriptors */
425 if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC ||
426 (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
427 get_endpoint(alts, 1)->bSynchAddress != 0)) {
428 snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. bmAttributes %02x, bLength %d, bSynchAddress %02x\n",
429 dev->devnum, fmt->iface, fmt->altsetting,
430 get_endpoint(alts, 1)->bmAttributes,
431 get_endpoint(alts, 1)->bLength,
432 get_endpoint(alts, 1)->bSynchAddress);
433 return -EINVAL;
434 }
435 ep = get_endpoint(alts, 1)->bEndpointAddress;
436 if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
437 ((is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
438 (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) {
439 snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. is_playback %d, ep %02x, bSynchAddress %02x\n",
440 dev->devnum, fmt->iface, fmt->altsetting,
441 is_playback, ep, get_endpoint(alts, 0)->bSynchAddress);
442 return -EINVAL;
443 }
444
445 implicit_fb = (get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_USAGE_MASK)
446 == USB_ENDPOINT_USAGE_IMPLICIT_FB;
447
448 subs->sync_endpoint = snd_usb_add_endpoint(subs->stream->chip,
449 alts, ep, !subs->direction,
450 implicit_fb ?
451 SND_USB_ENDPOINT_TYPE_DATA :
452 SND_USB_ENDPOINT_TYPE_SYNC);
453 if (!subs->sync_endpoint)
454 return -EINVAL;
455
456 subs->data_endpoint->sync_master = subs->sync_endpoint;
457
458 return 0;
459}
460
330/* 461/*
331 * find a matching format and set up the interface 462 * find a matching format and set up the interface
332 */ 463 */
@@ -336,9 +467,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
336 struct usb_host_interface *alts; 467 struct usb_host_interface *alts;
337 struct usb_interface_descriptor *altsd; 468 struct usb_interface_descriptor *altsd;
338 struct usb_interface *iface; 469 struct usb_interface *iface;
339 unsigned int ep, attr; 470 int err;
340 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
341 int err, implicit_fb = 0;
342 471
343 iface = usb_ifnum_to_if(dev, fmt->iface); 472 iface = usb_ifnum_to_if(dev, fmt->iface);
344 if (WARN_ON(!iface)) 473 if (WARN_ON(!iface))
@@ -383,118 +512,22 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
383 subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip, 512 subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip,
384 alts, fmt->endpoint, subs->direction, 513 alts, fmt->endpoint, subs->direction,
385 SND_USB_ENDPOINT_TYPE_DATA); 514 SND_USB_ENDPOINT_TYPE_DATA);
515
386 if (!subs->data_endpoint) 516 if (!subs->data_endpoint)
387 return -EINVAL; 517 return -EINVAL;
388 518
389 /* we need a sync pipe in async OUT or adaptive IN mode */ 519 err = set_sync_endpoint(subs, fmt, dev, alts, altsd);
390 /* check the number of EP, since some devices have broken 520 if (err < 0)
391 * descriptors which fool us. if it has only one EP, 521 return err;
392 * assume it as adaptive-out or sync-in.
393 */
394 attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
395
396 switch (subs->stream->chip->usb_id) {
397 case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
398 case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */
399 if (is_playback) {
400 implicit_fb = 1;
401 ep = 0x81;
402 iface = usb_ifnum_to_if(dev, 3);
403
404 if (!iface || iface->num_altsetting == 0)
405 return -EINVAL;
406
407 alts = &iface->altsetting[1];
408 goto add_sync_ep;
409 }
410 break;
411 case USB_ID(0x0763, 0x2080): /* M-Audio FastTrack Ultra */
412 case USB_ID(0x0763, 0x2081):
413 if (is_playback) {
414 implicit_fb = 1;
415 ep = 0x81;
416 iface = usb_ifnum_to_if(dev, 2);
417
418 if (!iface || iface->num_altsetting == 0)
419 return -EINVAL;
420
421 alts = &iface->altsetting[1];
422 goto add_sync_ep;
423 }
424 }
425 if (is_playback &&
426 attr == USB_ENDPOINT_SYNC_ASYNC &&
427 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
428 altsd->bInterfaceProtocol == 2 &&
429 altsd->bNumEndpoints == 1 &&
430 USB_ID_VENDOR(subs->stream->chip->usb_id) == 0x0582 /* Roland */ &&
431 search_roland_implicit_fb(dev, altsd->bInterfaceNumber + 1,
432 altsd->bAlternateSetting,
433 &alts, &ep) >= 0) {
434 implicit_fb = 1;
435 goto add_sync_ep;
436 }
437
438 if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) ||
439 (!is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) &&
440 altsd->bNumEndpoints >= 2) {
441 /* check sync-pipe endpoint */
442 /* ... and check descriptor size before accessing bSynchAddress
443 because there is a version of the SB Audigy 2 NX firmware lacking
444 the audio fields in the endpoint descriptors */
445 if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC ||
446 (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
447 get_endpoint(alts, 1)->bSynchAddress != 0 &&
448 !implicit_fb)) {
449 snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. bmAttributes %02x, bLength %d, bSynchAddress %02x\n",
450 dev->devnum, fmt->iface, fmt->altsetting,
451 get_endpoint(alts, 1)->bmAttributes,
452 get_endpoint(alts, 1)->bLength,
453 get_endpoint(alts, 1)->bSynchAddress);
454 return -EINVAL;
455 }
456 ep = get_endpoint(alts, 1)->bEndpointAddress;
457 if (!implicit_fb &&
458 get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
459 (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
460 (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) {
461 snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. is_playback %d, ep %02x, bSynchAddress %02x\n",
462 dev->devnum, fmt->iface, fmt->altsetting,
463 is_playback, ep, get_endpoint(alts, 0)->bSynchAddress);
464 return -EINVAL;
465 }
466
467 implicit_fb = (get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_USAGE_MASK)
468 == USB_ENDPOINT_USAGE_IMPLICIT_FB;
469
470add_sync_ep:
471 subs->sync_endpoint = snd_usb_add_endpoint(subs->stream->chip,
472 alts, ep, !subs->direction,
473 implicit_fb ?
474 SND_USB_ENDPOINT_TYPE_DATA :
475 SND_USB_ENDPOINT_TYPE_SYNC);
476 if (!subs->sync_endpoint)
477 return -EINVAL;
478
479 subs->data_endpoint->sync_master = subs->sync_endpoint;
480 }
481 522
482 if ((err = snd_usb_init_pitch(subs->stream->chip, fmt->iface, alts, fmt)) < 0) 523 err = snd_usb_init_pitch(subs->stream->chip, fmt->iface, alts, fmt);
524 if (err < 0)
483 return err; 525 return err;
484 526
485 subs->cur_audiofmt = fmt; 527 subs->cur_audiofmt = fmt;
486 528
487 snd_usb_set_format_quirk(subs, fmt); 529 snd_usb_set_format_quirk(subs, fmt);
488 530
489#if 0
490 printk(KERN_DEBUG
491 "setting done: format = %d, rate = %d..%d, channels = %d\n",
492 fmt->format, fmt->rate_min, fmt->rate_max, fmt->channels);
493 printk(KERN_DEBUG
494 " datapipe = 0x%0x, syncpipe = 0x%0x\n",
495 subs->datapipe, subs->syncpipe);
496#endif
497
498 return 0; 531 return 0;
499} 532}
500 533
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index 1f9bbd55553f..5a51b18c50fe 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -305,11 +305,9 @@ static void usX2Y_unlinkSeq(struct snd_usX2Y_AsyncSeq *S)
305{ 305{
306 int i; 306 int i;
307 for (i = 0; i < URBS_AsyncSeq; ++i) { 307 for (i = 0; i < URBS_AsyncSeq; ++i) {
308 if (S[i].urb) { 308 usb_kill_urb(S->urb[i]);
309 usb_kill_urb(S->urb[i]); 309 usb_free_urb(S->urb[i]);
310 usb_free_urb(S->urb[i]); 310 S->urb[i] = NULL;
311 S->urb[i] = NULL;
312 }
313 } 311 }
314 kfree(S->buffer); 312 kfree(S->buffer);
315} 313}