aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-23 16:05:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-23 16:05:43 -0400
commit2e341ca686042aa464efa755447e7bcee91d1eb6 (patch)
treec6b16b6b6a6e871fa04396cb2c7eb759bcad5be3 /sound/soc
parent927ad551031798d4cba49766549600bbb33872d7 (diff)
parent85e184e4c3cd3e2285ceab91ff8f0cac094e8a85 (diff)
Merge tag 'sound-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "This is the first big chunk for 3.5 merges of sound stuff. There are a few big changes in different areas. First off, the streaming logic of USB-audio endpoints has been largely rewritten for the better support of "implicit feedback". If anything about USB got broken, this change has to be checked. For HD-audio, the resume procedure was changed; instead of delaying the resume of the hardware until the first use, now waking up immediately at resume. This is for buggy BIOS. For ASoC, dynamic PCM support and the improved support for digital links between off-SoC devices are major framework changes. Some highlights are below: * HD-audio - Avoid accesses of invalid pin-control bits that may stall the codec - V-ref setup cleanups - Fix the races in power-saving code - Fix the races in codec cache hashes and connection lists - Split some common codes for BIOS auto-parser to hda_auto_parser.c - Changed the PM resume code to wake up immediately for buggy BIOS - Creative SoundCore3D support - Add Conexant CX20751/2/3/4 codec support * ASoC - Dynamic PCM support, allowing support for SoCs with internal routing through components with tight sequencing and formatting constraints within their internal paths or where there are multiple components connected with CPU managed DMA controllers inside the SoC. - Greatly improved support for direct digital links between off-SoC devices, providing a much simpler way of connecting things like digital basebands to CODECs. - Much more fine grained and robust locking, cleaning up some of the confusion that crept in with multi-component. - CPU support for nVidia Tegra 30 I2S and audio hub controllers and ST-Ericsson MSP I2S controolers - New CODEC drivers for Cirrus CS42L52, LAPIS Semiconductor ML26124, Texas Instruments LM49453. - Some regmap changes needed by the Tegra I2S driver. - mc13783 audio support. * Misc - Rewrite with module_pci_driver() - Xonar DGX support for snd-oxygen - Improvement of packet handling in snd-firewire driver - New USB-endpoint streaming logic - Enhanced M-audio FTU quirks and relevant cleanups - Increment the support of OSS devices to 256 - snd-aloop accuracy improvement There are a few more pending changes for 3.5, but they will be sent slightly later as partly depending on the changes of DRM." Fix up conflicts in regmap (due to duplicate patches, with some further updates then having already come in from the regmap tree). Also some fairly trivial context conflicts in the imx and mcx soc drivers. * tag 'sound-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (280 commits) ALSA: snd-usb: fix stream info output in /proc ALSA: pcm - Add proper state checks to snd_pcm_drain() ALSA: sh: Fix up namespace collision in sh_dac_audio. ALSA: hda/realtek - Fix unused variable compile warning ASoC: sh: fsi: enable chip specific data transfer mode ASoC: sh: fsi: call fsi_hw_startup/shutdown from fsi_dai_trigger() ASoC: sh: fsi: use same format for IN/OUT ASoC: sh: fsi: add fsi_version() and removed meaningless version check ASoC: sh: fsi: use register field macro name on IN/OUT_DMAC ASoC: tegra: Add machine driver for WM8753 codec ALSA: hda - Fix possible races of accesses to connection list array ASoC: OMAP: HDMI: Introduce codec ARM: mx31_3ds: Add sound support ASoC: imx-mc13783 cleanup mx31moboard: Add sound support ASoC: mc13783 codec cleanups ASoC: add imx-mc13783 sound support ASoC: Add mc13783 codec mfd: mc13xxx: add codec platform data ASoC: don't flip master of DT-instantiated DAI links ...
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/Kconfig5
-rw-r--r--sound/soc/Makefile3
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c37
-rw-r--r--sound/soc/codecs/Kconfig20
-rw-r--r--sound/soc/codecs/Makefile12
-rw-r--r--sound/soc/codecs/ac97.c6
-rw-r--r--sound/soc/codecs/ad1836.c4
-rw-r--r--sound/soc/codecs/ad193x.c4
-rw-r--r--sound/soc/codecs/adau1701.c3
-rw-r--r--sound/soc/codecs/ak4104.c3
-rw-r--r--sound/soc/codecs/ak4535.c3
-rw-r--r--sound/soc/codecs/ak4641.c113
-rw-r--r--sound/soc/codecs/alc5623.c23
-rw-r--r--sound/soc/codecs/alc5632.c31
-rw-r--r--sound/soc/codecs/cs4270.c11
-rw-r--r--sound/soc/codecs/cs4271.c3
-rw-r--r--sound/soc/codecs/cs42l51.c9
-rw-r--r--sound/soc/codecs/cs42l52.c1295
-rw-r--r--sound/soc/codecs/cs42l52.h274
-rw-r--r--sound/soc/codecs/cs42l73.c93
-rw-r--r--sound/soc/codecs/da7210.c379
-rw-r--r--sound/soc/codecs/jz4740.c3
-rw-r--r--sound/soc/codecs/lm49453.c1550
-rw-r--r--sound/soc/codecs/lm49453.h380
-rw-r--r--sound/soc/codecs/max98095.c158
-rw-r--r--sound/soc/codecs/max98095.h22
-rw-r--r--sound/soc/codecs/mc13783.c786
-rw-r--r--sound/soc/codecs/mc13783.h28
-rw-r--r--sound/soc/codecs/ml26124.c681
-rw-r--r--sound/soc/codecs/ml26124.h184
-rw-r--r--sound/soc/codecs/omap-hdmi.c69
-rw-r--r--sound/soc/codecs/rt5631.c110
-rw-r--r--sound/soc/codecs/sgtl5000.c25
-rw-r--r--sound/soc/codecs/ssm2602.c138
-rw-r--r--sound/soc/codecs/sta32x.c3
-rw-r--r--sound/soc/codecs/tlv320aic23.c13
-rw-r--r--sound/soc/codecs/tlv320aic26.c3
-rw-r--r--sound/soc/codecs/tlv320aic3x.c21
-rw-r--r--sound/soc/codecs/tlv320dac33.c35
-rw-r--r--sound/soc/codecs/twl4030.c18
-rw-r--r--sound/soc/codecs/twl6040.c450
-rw-r--r--sound/soc/codecs/uda134x.c6
-rw-r--r--sound/soc/codecs/uda1380.c6
-rw-r--r--sound/soc/codecs/wl1273.c6
-rw-r--r--sound/soc/codecs/wm1250-ev1.c65
-rw-r--r--sound/soc/codecs/wm5100-tables.c125
-rw-r--r--sound/soc/codecs/wm5100.c47
-rw-r--r--sound/soc/codecs/wm5100.h159
-rw-r--r--sound/soc/codecs/wm8350.c187
-rw-r--r--sound/soc/codecs/wm8400.c135
-rw-r--r--sound/soc/codecs/wm8510.c3
-rw-r--r--sound/soc/codecs/wm8523.c3
-rw-r--r--sound/soc/codecs/wm8728.c3
-rw-r--r--sound/soc/codecs/wm8731.c37
-rw-r--r--sound/soc/codecs/wm8737.c3
-rw-r--r--sound/soc/codecs/wm8741.c3
-rw-r--r--sound/soc/codecs/wm8750.c3
-rw-r--r--sound/soc/codecs/wm8753.c6
-rw-r--r--sound/soc/codecs/wm8900.c3
-rw-r--r--sound/soc/codecs/wm8903.c3
-rw-r--r--sound/soc/codecs/wm8940.c3
-rw-r--r--sound/soc/codecs/wm8960.c3
-rw-r--r--sound/soc/codecs/wm8962.c18
-rw-r--r--sound/soc/codecs/wm8971.c3
-rw-r--r--sound/soc/codecs/wm8978.c3
-rw-r--r--sound/soc/codecs/wm8988.c3
-rw-r--r--sound/soc/codecs/wm8990.c3
-rw-r--r--sound/soc/codecs/wm8993.c86
-rw-r--r--sound/soc/codecs/wm8994.c290
-rw-r--r--sound/soc/codecs/wm8994.h3
-rw-r--r--sound/soc/codecs/wm8996.c12
-rw-r--r--sound/soc/codecs/wm9081.c5
-rw-r--r--sound/soc/codecs/wm9705.c6
-rw-r--r--sound/soc/codecs/wm9712.c10
-rw-r--r--sound/soc/codecs/wm_hubs.c220
-rw-r--r--sound/soc/codecs/wm_hubs.h12
-rw-r--r--sound/soc/ep93xx/ep93xx-ac97.c74
-rw-r--r--sound/soc/ep93xx/ep93xx-i2s.c49
-rw-r--r--sound/soc/fsl/Kconfig129
-rw-r--r--sound/soc/fsl/Makefile31
-rw-r--r--sound/soc/fsl/eukrea-tlv320.c (renamed from sound/soc/imx/eukrea-tlv320.c)2
-rw-r--r--sound/soc/fsl/fsl_ssi.c167
-rw-r--r--sound/soc/fsl/fsl_utils.c91
-rw-r--r--sound/soc/fsl/fsl_utils.h26
-rw-r--r--sound/soc/fsl/imx-audmux.c (renamed from sound/soc/imx/imx-audmux.c)0
-rw-r--r--sound/soc/fsl/imx-audmux.h (renamed from sound/soc/imx/imx-audmux.h)0
-rw-r--r--sound/soc/fsl/imx-mc13783.c156
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c (renamed from sound/soc/imx/imx-pcm-dma-mx2.c)3
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c (renamed from sound/soc/imx/imx-pcm-fiq.c)0
-rw-r--r--sound/soc/fsl/imx-pcm.c (renamed from sound/soc/imx/imx-pcm.c)0
-rw-r--r--sound/soc/fsl/imx-pcm.h (renamed from sound/soc/imx/imx-pcm.h)1
-rw-r--r--sound/soc/fsl/imx-sgtl5000.c221
-rw-r--r--sound/soc/fsl/imx-ssi.c (renamed from sound/soc/imx/imx-ssi.c)2
-rw-r--r--sound/soc/fsl/imx-ssi.h (renamed from sound/soc/imx/imx-ssi.h)0
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c166
-rw-r--r--sound/soc/fsl/mx27vis-aic32x4.c (renamed from sound/soc/imx/mx27vis-aic32x4.c)0
-rw-r--r--sound/soc/fsl/p1022_ds.c158
-rw-r--r--sound/soc/fsl/phycore-ac97.c (renamed from sound/soc/imx/phycore-ac97.c)0
-rw-r--r--sound/soc/fsl/wm1133-ev1.c (renamed from sound/soc/imx/wm1133-ev1.c)0
-rw-r--r--sound/soc/generic/Kconfig4
-rw-r--r--sound/soc/generic/Makefile3
-rw-r--r--sound/soc/generic/simple-card.c114
-rw-r--r--sound/soc/imx/Kconfig79
-rw-r--r--sound/soc/imx/Makefile22
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c4
-rw-r--r--sound/soc/mxs/mxs-pcm.c24
-rw-r--r--sound/soc/mxs/mxs-pcm.h3
-rw-r--r--sound/soc/mxs/mxs-saif.c92
-rw-r--r--sound/soc/mxs/mxs-saif.h1
-rw-r--r--sound/soc/mxs/mxs-sgtl5000.c50
-rw-r--r--sound/soc/omap/Kconfig1
-rw-r--r--sound/soc/pxa/pxa-ssp.c28
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c4
-rw-r--r--sound/soc/samsung/littlemill.c102
-rw-r--r--sound/soc/samsung/lowland.c75
-rw-r--r--sound/soc/samsung/speyside.c33
-rw-r--r--sound/soc/sh/Kconfig24
-rw-r--r--sound/soc/sh/Makefile6
-rw-r--r--sound/soc/sh/fsi-ak4642.c108
-rw-r--r--sound/soc/sh/fsi-da7210.c81
-rw-r--r--sound/soc/sh/fsi-hdmi.c118
-rw-r--r--sound/soc/sh/fsi.c224
-rw-r--r--sound/soc/soc-core.c690
-rw-r--r--sound/soc/soc-dapm.c562
-rw-r--r--sound/soc/soc-jack.c5
-rw-r--r--sound/soc/soc-pcm.c1718
-rw-r--r--sound/soc/tegra/Kconfig68
-rw-r--r--sound/soc/tegra/Makefile20
-rw-r--r--sound/soc/tegra/tegra20_das.c233
-rw-r--r--sound/soc/tegra/tegra20_das.h134
-rw-r--r--sound/soc/tegra/tegra20_i2s.c494
-rw-r--r--sound/soc/tegra/tegra20_i2s.h164
-rw-r--r--sound/soc/tegra/tegra20_spdif.c404
-rw-r--r--sound/soc/tegra/tegra20_spdif.h471
-rw-r--r--sound/soc/tegra/tegra30_ahub.c631
-rw-r--r--sound/soc/tegra/tegra30_ahub.h483
-rw-r--r--sound/soc/tegra/tegra30_i2s.c536
-rw-r--r--sound/soc/tegra/tegra30_i2s.h242
-rw-r--r--sound/soc/tegra/tegra_alc5632.c48
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.c37
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.h9
-rw-r--r--sound/soc/tegra/tegra_das.c261
-rw-r--r--sound/soc/tegra/tegra_das.h135
-rw-r--r--sound/soc/tegra/tegra_i2s.c459
-rw-r--r--sound/soc/tegra/tegra_i2s.h166
-rw-r--r--sound/soc/tegra/tegra_pcm.c28
-rw-r--r--sound/soc/tegra/tegra_pcm.h5
-rw-r--r--sound/soc/tegra/tegra_spdif.c364
-rw-r--r--sound/soc/tegra/tegra_spdif.h473
-rw-r--r--sound/soc/tegra/tegra_wm8753.c224
-rw-r--r--sound/soc/tegra/tegra_wm8903.c29
-rw-r--r--sound/soc/tegra/trimslice.c41
-rw-r--r--sound/soc/ux500/Kconfig14
-rw-r--r--sound/soc/ux500/Makefile4
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c843
-rw-r--r--sound/soc/ux500/ux500_msp_dai.h79
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.c742
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.h553
158 files changed, 17406 insertions, 4930 deletions
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 91c985599d32..40b2ad1bb1cd 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -35,7 +35,6 @@ source "sound/soc/blackfin/Kconfig"
35source "sound/soc/davinci/Kconfig" 35source "sound/soc/davinci/Kconfig"
36source "sound/soc/ep93xx/Kconfig" 36source "sound/soc/ep93xx/Kconfig"
37source "sound/soc/fsl/Kconfig" 37source "sound/soc/fsl/Kconfig"
38source "sound/soc/imx/Kconfig"
39source "sound/soc/jz4740/Kconfig" 38source "sound/soc/jz4740/Kconfig"
40source "sound/soc/nuc900/Kconfig" 39source "sound/soc/nuc900/Kconfig"
41source "sound/soc/omap/Kconfig" 40source "sound/soc/omap/Kconfig"
@@ -48,9 +47,13 @@ source "sound/soc/s6000/Kconfig"
48source "sound/soc/sh/Kconfig" 47source "sound/soc/sh/Kconfig"
49source "sound/soc/tegra/Kconfig" 48source "sound/soc/tegra/Kconfig"
50source "sound/soc/txx9/Kconfig" 49source "sound/soc/txx9/Kconfig"
50source "sound/soc/ux500/Kconfig"
51 51
52# Supported codecs 52# Supported codecs
53source "sound/soc/codecs/Kconfig" 53source "sound/soc/codecs/Kconfig"
54 54
55# generic frame-work
56source "sound/soc/generic/Kconfig"
57
55endif # SND_SOC 58endif # SND_SOC
56 59
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 2feaf376e94b..70990f4017f4 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -6,13 +6,13 @@ obj-$(CONFIG_SND_SOC_DMAENGINE_PCM) += snd-soc-dmaengine-pcm.o
6 6
7obj-$(CONFIG_SND_SOC) += snd-soc-core.o 7obj-$(CONFIG_SND_SOC) += snd-soc-core.o
8obj-$(CONFIG_SND_SOC) += codecs/ 8obj-$(CONFIG_SND_SOC) += codecs/
9obj-$(CONFIG_SND_SOC) += generic/
9obj-$(CONFIG_SND_SOC) += atmel/ 10obj-$(CONFIG_SND_SOC) += atmel/
10obj-$(CONFIG_SND_SOC) += au1x/ 11obj-$(CONFIG_SND_SOC) += au1x/
11obj-$(CONFIG_SND_SOC) += blackfin/ 12obj-$(CONFIG_SND_SOC) += blackfin/
12obj-$(CONFIG_SND_SOC) += davinci/ 13obj-$(CONFIG_SND_SOC) += davinci/
13obj-$(CONFIG_SND_SOC) += ep93xx/ 14obj-$(CONFIG_SND_SOC) += ep93xx/
14obj-$(CONFIG_SND_SOC) += fsl/ 15obj-$(CONFIG_SND_SOC) += fsl/
15obj-$(CONFIG_SND_SOC) += imx/
16obj-$(CONFIG_SND_SOC) += jz4740/ 16obj-$(CONFIG_SND_SOC) += jz4740/
17obj-$(CONFIG_SND_SOC) += mid-x86/ 17obj-$(CONFIG_SND_SOC) += mid-x86/
18obj-$(CONFIG_SND_SOC) += mxs/ 18obj-$(CONFIG_SND_SOC) += mxs/
@@ -25,3 +25,4 @@ obj-$(CONFIG_SND_SOC) += s6000/
25obj-$(CONFIG_SND_SOC) += sh/ 25obj-$(CONFIG_SND_SOC) += sh/
26obj-$(CONFIG_SND_SOC) += tegra/ 26obj-$(CONFIG_SND_SOC) += tegra/
27obj-$(CONFIG_SND_SOC) += txx9/ 27obj-$(CONFIG_SND_SOC) += txx9/
28obj-$(CONFIG_SND_SOC) += ux500/
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index b39ad356b92b..7dbeef1099b4 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -44,16 +44,8 @@
44 44
45static struct snd_soc_card bf5xx_ssm2602; 45static struct snd_soc_card bf5xx_ssm2602;
46 46
47static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream, 47static int bf5xx_ssm2602_dai_init(struct snd_soc_pcm_runtime *rtd)
48 struct snd_pcm_hw_params *params)
49{ 48{
50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
51 struct snd_soc_dai *codec_dai = rtd->codec_dai;
52 unsigned int clk = 0;
53 int ret = 0;
54
55 pr_debug("%s rate %d format %x\n", __func__, params_rate(params),
56 params_format(params));
57 /* 49 /*
58 * If you are using a crystal source which frequency is not 12MHz 50 * If you are using a crystal source which frequency is not 12MHz
59 * then modify the below case statement with frequency of the crystal. 51 * then modify the below case statement with frequency of the crystal.
@@ -61,31 +53,10 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
61 * If you are using the SPORT to generate clocking then this is 53 * If you are using the SPORT to generate clocking then this is
62 * where to do it. 54 * where to do it.
63 */ 55 */
64 56 return snd_soc_dai_set_sysclk(rtd->codec_dai, SSM2602_SYSCLK, 12000000,
65 switch (params_rate(params)) {
66 case 8000:
67 case 16000:
68 case 48000:
69 case 96000:
70 case 11025:
71 case 22050:
72 case 44100:
73 clk = 12000000;
74 break;
75 }
76
77 ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, clk,
78 SND_SOC_CLOCK_IN); 57 SND_SOC_CLOCK_IN);
79 if (ret < 0)
80 return ret;
81
82 return 0;
83} 58}
84 59
85static struct snd_soc_ops bf5xx_ssm2602_ops = {
86 .hw_params = bf5xx_ssm2602_hw_params,
87};
88
89/* CODEC is master for BCLK and LRC in this configuration. */ 60/* CODEC is master for BCLK and LRC in this configuration. */
90#define BF5XX_SSM2602_DAIFMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \ 61#define BF5XX_SSM2602_DAIFMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \
91 SND_SOC_DAIFMT_CBM_CFM) 62 SND_SOC_DAIFMT_CBM_CFM)
@@ -98,7 +69,7 @@ static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = {
98 .codec_dai_name = "ssm2602-hifi", 69 .codec_dai_name = "ssm2602-hifi",
99 .platform_name = "bfin-i2s-pcm-audio", 70 .platform_name = "bfin-i2s-pcm-audio",
100 .codec_name = "ssm2602.0-001b", 71 .codec_name = "ssm2602.0-001b",
101 .ops = &bf5xx_ssm2602_ops, 72 .init = bf5xx_ssm2602_dai_init,
102 .dai_fmt = BF5XX_SSM2602_DAIFMT, 73 .dai_fmt = BF5XX_SSM2602_DAIFMT,
103 }, 74 },
104 { 75 {
@@ -108,7 +79,7 @@ static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = {
108 .codec_dai_name = "ssm2602-hifi", 79 .codec_dai_name = "ssm2602-hifi",
109 .platform_name = "bfin-i2s-pcm-audio", 80 .platform_name = "bfin-i2s-pcm-audio",
110 .codec_name = "ssm2602.0-001b", 81 .codec_name = "ssm2602.0-001b",
111 .ops = &bf5xx_ssm2602_ops, 82 .init = bf5xx_ssm2602_dai_init,
112 .dai_fmt = BF5XX_SSM2602_DAIFMT, 83 .dai_fmt = BF5XX_SSM2602_DAIFMT,
113 }, 84 },
114}; 85};
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 59d8efaa17e9..1e1613a438dd 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -29,6 +29,7 @@ config SND_SOC_ALL_CODECS
29 select SND_SOC_ALC5632 if I2C 29 select SND_SOC_ALC5632 if I2C
30 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC 30 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
31 select SND_SOC_CS42L51 if I2C 31 select SND_SOC_CS42L51 if I2C
32 select SND_SOC_CS42L52 if I2C
32 select SND_SOC_CS42L73 if I2C 33 select SND_SOC_CS42L73 if I2C
33 select SND_SOC_CS4270 if I2C 34 select SND_SOC_CS4270 if I2C
34 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI 35 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
@@ -37,11 +38,15 @@ config SND_SOC_ALL_CODECS
37 select SND_SOC_DFBMCS320 38 select SND_SOC_DFBMCS320
38 select SND_SOC_JZ4740_CODEC 39 select SND_SOC_JZ4740_CODEC
39 select SND_SOC_LM4857 if I2C 40 select SND_SOC_LM4857 if I2C
41 select SND_SOC_LM49453 if I2C
40 select SND_SOC_MAX98088 if I2C 42 select SND_SOC_MAX98088 if I2C
41 select SND_SOC_MAX98095 if I2C 43 select SND_SOC_MAX98095 if I2C
42 select SND_SOC_MAX9850 if I2C 44 select SND_SOC_MAX9850 if I2C
43 select SND_SOC_MAX9768 if I2C 45 select SND_SOC_MAX9768 if I2C
44 select SND_SOC_MAX9877 if I2C 46 select SND_SOC_MAX9877 if I2C
47 select SND_SOC_MC13783 if MFD_MC13XXX
48 select SND_SOC_ML26124 if I2C
49 select SND_SOC_OMAP_HDMI_CODEC if OMAP4_DSS_HDMI
45 select SND_SOC_PCM3008 50 select SND_SOC_PCM3008
46 select SND_SOC_RT5631 if I2C 51 select SND_SOC_RT5631 if I2C
47 select SND_SOC_SGTL5000 if I2C 52 select SND_SOC_SGTL5000 if I2C
@@ -181,6 +186,9 @@ config SND_SOC_CQ0093VC
181config SND_SOC_CS42L51 186config SND_SOC_CS42L51
182 tristate 187 tristate
183 188
189config SND_SOC_CS42L52
190 tristate
191
184config SND_SOC_CS42L73 192config SND_SOC_CS42L73
185 tristate 193 tristate
186 194
@@ -217,6 +225,9 @@ config SND_SOC_DFBMCS320
217config SND_SOC_DMIC 225config SND_SOC_DMIC
218 tristate 226 tristate
219 227
228config SND_SOC_LM49453
229 tristate
230
220config SND_SOC_MAX98088 231config SND_SOC_MAX98088
221 tristate 232 tristate
222 233
@@ -226,6 +237,9 @@ config SND_SOC_MAX98095
226config SND_SOC_MAX9850 237config SND_SOC_MAX9850
227 tristate 238 tristate
228 239
240config SND_SOC_OMAP_HDMI_CODEC
241 tristate
242
229config SND_SOC_PCM3008 243config SND_SOC_PCM3008
230 tristate 244 tristate
231 245
@@ -435,5 +449,11 @@ config SND_SOC_MAX9768
435config SND_SOC_MAX9877 449config SND_SOC_MAX9877
436 tristate 450 tristate
437 451
452config SND_SOC_MC13783
453 tristate
454
455config SND_SOC_ML26124
456 tristate
457
438config SND_SOC_TPA6130A2 458config SND_SOC_TPA6130A2
439 tristate 459 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 6662eb0cdcc0..fc27fec39487 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -15,6 +15,7 @@ snd-soc-ak4642-objs := ak4642.o
15snd-soc-ak4671-objs := ak4671.o 15snd-soc-ak4671-objs := ak4671.o
16snd-soc-cq93vc-objs := cq93vc.o 16snd-soc-cq93vc-objs := cq93vc.o
17snd-soc-cs42l51-objs := cs42l51.o 17snd-soc-cs42l51-objs := cs42l51.o
18snd-soc-cs42l52-objs := cs42l52.o
18snd-soc-cs42l73-objs := cs42l73.o 19snd-soc-cs42l73-objs := cs42l73.o
19snd-soc-cs4270-objs := cs4270.o 20snd-soc-cs4270-objs := cs4270.o
20snd-soc-cs4271-objs := cs4271.o 21snd-soc-cs4271-objs := cs4271.o
@@ -25,10 +26,14 @@ snd-soc-dmic-objs := dmic.o
25snd-soc-jz4740-codec-objs := jz4740.o 26snd-soc-jz4740-codec-objs := jz4740.o
26snd-soc-l3-objs := l3.o 27snd-soc-l3-objs := l3.o
27snd-soc-lm4857-objs := lm4857.o 28snd-soc-lm4857-objs := lm4857.o
29snd-soc-lm49453-objs := lm49453.o
28snd-soc-max9768-objs := max9768.o 30snd-soc-max9768-objs := max9768.o
29snd-soc-max98088-objs := max98088.o 31snd-soc-max98088-objs := max98088.o
30snd-soc-max98095-objs := max98095.o 32snd-soc-max98095-objs := max98095.o
31snd-soc-max9850-objs := max9850.o 33snd-soc-max9850-objs := max9850.o
34snd-soc-mc13783-objs := mc13783.o
35snd-soc-ml26124-objs := ml26124.o
36snd-soc-omap-hdmi-codec-objs := omap-hdmi.o
32snd-soc-pcm3008-objs := pcm3008.o 37snd-soc-pcm3008-objs := pcm3008.o
33snd-soc-rt5631-objs := rt5631.o 38snd-soc-rt5631-objs := rt5631.o
34snd-soc-sgtl5000-objs := sgtl5000.o 39snd-soc-sgtl5000-objs := sgtl5000.o
@@ -121,6 +126,7 @@ obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
121obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o 126obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o
122obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o 127obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
123obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o 128obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
129obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o
124obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o 130obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o
125obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 131obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
126obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o 132obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
@@ -128,13 +134,17 @@ obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
128obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 134obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
129obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o 135obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o
130obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o 136obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
137obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
131obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 138obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
132obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o 139obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
133obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 140obj-$(CONFIG_SND_SOC_LM49453) += snd-soc-lm49453.o
134obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o 141obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o
135obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o 142obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
136obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o 143obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
137obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 144obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
145obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
146obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
147obj-$(CONFIG_SND_SOC_OMAP_HDMI_CODEC) += snd-soc-omap-hdmi-codec.o
138obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 148obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
139obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o 149obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
140obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o 150obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 1bbad4c16d28..2023c749f232 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -26,13 +26,11 @@
26static int ac97_prepare(struct snd_pcm_substream *substream, 26static int ac97_prepare(struct snd_pcm_substream *substream,
27 struct snd_soc_dai *dai) 27 struct snd_soc_dai *dai)
28{ 28{
29 struct snd_pcm_runtime *runtime = substream->runtime; 29 struct snd_soc_codec *codec = dai->codec;
30 struct snd_soc_pcm_runtime *rtd = substream->private_data;
31 struct snd_soc_codec *codec = rtd->codec;
32 30
33 int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 31 int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
34 AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE; 32 AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE;
35 return snd_ac97_set_rate(codec->ac97, reg, runtime->rate); 33 return snd_ac97_set_rate(codec->ac97, reg, substream->runtime->rate);
36} 34}
37 35
38#define STD_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 36#define STD_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 12e3b4118557..c67b50d8b317 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -162,9 +162,7 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
162 struct snd_soc_dai *dai) 162 struct snd_soc_dai *dai)
163{ 163{
164 int word_len = 0; 164 int word_len = 0;
165 165 struct snd_soc_codec *codec = dai->codec;
166 struct snd_soc_pcm_runtime *rtd = substream->private_data;
167 struct snd_soc_codec *codec = rtd->codec;
168 166
169 /* bit size */ 167 /* bit size */
170 switch (params_format(params)) { 168 switch (params_format(params)) {
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index a4a6bef2c0bb..13e62be4f990 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -245,9 +245,7 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
245 struct snd_soc_dai *dai) 245 struct snd_soc_dai *dai)
246{ 246{
247 int word_len = 0, master_rate = 0; 247 int word_len = 0, master_rate = 0;
248 248 struct snd_soc_codec *codec = dai->codec;
249 struct snd_soc_pcm_runtime *rtd = substream->private_data;
250 struct snd_soc_codec *codec = rtd->codec;
251 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); 249 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
252 250
253 /* bit size */ 251 /* bit size */
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 78e9ce48bb99..3d50fc8646b6 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -258,8 +258,7 @@ static int adau1701_set_playback_pcm_format(struct snd_soc_codec *codec,
258static int adau1701_hw_params(struct snd_pcm_substream *substream, 258static int adau1701_hw_params(struct snd_pcm_substream *substream,
259 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 259 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
260{ 260{
261 struct snd_soc_pcm_runtime *rtd = substream->private_data; 261 struct snd_soc_codec *codec = dai->codec;
262 struct snd_soc_codec *codec = rtd->codec;
263 snd_pcm_format_t format; 262 snd_pcm_format_t format;
264 unsigned int val; 263 unsigned int val;
265 264
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index ceb96ecf5588..31d4483245d0 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -88,8 +88,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream,
88 struct snd_pcm_hw_params *params, 88 struct snd_pcm_hw_params *params,
89 struct snd_soc_dai *dai) 89 struct snd_soc_dai *dai)
90{ 90{
91 struct snd_soc_pcm_runtime *rtd = substream->private_data; 91 struct snd_soc_codec *codec = dai->codec;
92 struct snd_soc_codec *codec = rtd->codec;
93 int val = 0; 92 int val = 0;
94 93
95 /* set the IEC958 bits: consumer mode, no copyright bit */ 94 /* set the IEC958 bits: consumer mode, no copyright bit */
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 838ae8b22b50..618fdc30f73e 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -262,8 +262,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream,
262 struct snd_pcm_hw_params *params, 262 struct snd_pcm_hw_params *params,
263 struct snd_soc_dai *dai) 263 struct snd_soc_dai *dai)
264{ 264{
265 struct snd_soc_pcm_runtime *rtd = substream->private_data; 265 struct snd_soc_codec *codec = dai->codec;
266 struct snd_soc_codec *codec = rtd->codec;
267 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); 266 struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec);
268 u8 mode2 = snd_soc_read(codec, AK4535_MODE2) & ~(0x3 << 5); 267 u8 mode2 = snd_soc_read(codec, AK4535_MODE2) & ~(0x3 << 5);
269 int rate = params_rate(params), fs = 256; 268 int rate = params_rate(params), fs = 256;
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c
index c4d165a4bddf..543a12f471be 100644
--- a/sound/soc/codecs/ak4641.c
+++ b/sound/soc/codecs/ak4641.c
@@ -296,8 +296,7 @@ static int ak4641_i2s_hw_params(struct snd_pcm_substream *substream,
296 struct snd_pcm_hw_params *params, 296 struct snd_pcm_hw_params *params,
297 struct snd_soc_dai *dai) 297 struct snd_soc_dai *dai)
298{ 298{
299 struct snd_soc_pcm_runtime *rtd = substream->private_data; 299 struct snd_soc_codec *codec = dai->codec;
300 struct snd_soc_codec *codec = rtd->codec;
301 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); 300 struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec);
302 int rate = params_rate(params), fs = 256; 301 int rate = params_rate(params), fs = 256;
303 u8 mode2; 302 u8 mode2;
@@ -517,67 +516,24 @@ static int ak4641_resume(struct snd_soc_codec *codec)
517 516
518static int ak4641_probe(struct snd_soc_codec *codec) 517static int ak4641_probe(struct snd_soc_codec *codec)
519{ 518{
520 struct ak4641_platform_data *pdata = codec->dev->platform_data;
521 int ret; 519 int ret;
522 520
523
524 if (pdata) {
525 if (gpio_is_valid(pdata->gpio_power)) {
526 ret = gpio_request_one(pdata->gpio_power,
527 GPIOF_OUT_INIT_LOW, "ak4641 power");
528 if (ret)
529 goto err_out;
530 }
531 if (gpio_is_valid(pdata->gpio_npdn)) {
532 ret = gpio_request_one(pdata->gpio_npdn,
533 GPIOF_OUT_INIT_LOW, "ak4641 npdn");
534 if (ret)
535 goto err_gpio;
536
537 udelay(1); /* > 150 ns */
538 gpio_set_value(pdata->gpio_npdn, 1);
539 }
540 }
541
542 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); 521 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
543 if (ret != 0) { 522 if (ret != 0) {
544 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 523 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
545 goto err_register; 524 return ret;
546 } 525 }
547 526
548 /* power on device */ 527 /* power on device */
549 ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 528 ak4641_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
550 529
551 return 0; 530 return 0;
552
553err_register:
554 if (pdata) {
555 if (gpio_is_valid(pdata->gpio_power))
556 gpio_set_value(pdata->gpio_power, 0);
557 if (gpio_is_valid(pdata->gpio_npdn))
558 gpio_free(pdata->gpio_npdn);
559 }
560err_gpio:
561 if (pdata && gpio_is_valid(pdata->gpio_power))
562 gpio_free(pdata->gpio_power);
563err_out:
564 return ret;
565} 531}
566 532
567static int ak4641_remove(struct snd_soc_codec *codec) 533static int ak4641_remove(struct snd_soc_codec *codec)
568{ 534{
569 struct ak4641_platform_data *pdata = codec->dev->platform_data;
570
571 ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF); 535 ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF);
572 536
573 if (pdata) {
574 if (gpio_is_valid(pdata->gpio_power)) {
575 gpio_set_value(pdata->gpio_power, 0);
576 gpio_free(pdata->gpio_power);
577 }
578 if (gpio_is_valid(pdata->gpio_npdn))
579 gpio_free(pdata->gpio_npdn);
580 }
581 return 0; 537 return 0;
582} 538}
583 539
@@ -604,6 +560,7 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4641 = {
604static int __devinit ak4641_i2c_probe(struct i2c_client *i2c, 560static int __devinit ak4641_i2c_probe(struct i2c_client *i2c,
605 const struct i2c_device_id *id) 561 const struct i2c_device_id *id)
606{ 562{
563 struct ak4641_platform_data *pdata = i2c->dev.platform_data;
607 struct ak4641_priv *ak4641; 564 struct ak4641_priv *ak4641;
608 int ret; 565 int ret;
609 566
@@ -612,16 +569,62 @@ static int __devinit ak4641_i2c_probe(struct i2c_client *i2c,
612 if (!ak4641) 569 if (!ak4641)
613 return -ENOMEM; 570 return -ENOMEM;
614 571
572 if (pdata) {
573 if (gpio_is_valid(pdata->gpio_power)) {
574 ret = gpio_request_one(pdata->gpio_power,
575 GPIOF_OUT_INIT_LOW, "ak4641 power");
576 if (ret)
577 goto err_out;
578 }
579 if (gpio_is_valid(pdata->gpio_npdn)) {
580 ret = gpio_request_one(pdata->gpio_npdn,
581 GPIOF_OUT_INIT_LOW, "ak4641 npdn");
582 if (ret)
583 goto err_gpio;
584
585 udelay(1); /* > 150 ns */
586 gpio_set_value(pdata->gpio_npdn, 1);
587 }
588 }
589
615 i2c_set_clientdata(i2c, ak4641); 590 i2c_set_clientdata(i2c, ak4641);
616 591
617 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4641, 592 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4641,
618 ak4641_dai, ARRAY_SIZE(ak4641_dai)); 593 ak4641_dai, ARRAY_SIZE(ak4641_dai));
594 if (ret != 0)
595 goto err_gpio2;
596
597 return 0;
598
599err_gpio2:
600 if (pdata) {
601 if (gpio_is_valid(pdata->gpio_power))
602 gpio_set_value(pdata->gpio_power, 0);
603 if (gpio_is_valid(pdata->gpio_npdn))
604 gpio_free(pdata->gpio_npdn);
605 }
606err_gpio:
607 if (pdata && gpio_is_valid(pdata->gpio_power))
608 gpio_free(pdata->gpio_power);
609err_out:
619 return ret; 610 return ret;
620} 611}
621 612
622static int __devexit ak4641_i2c_remove(struct i2c_client *i2c) 613static int __devexit ak4641_i2c_remove(struct i2c_client *i2c)
623{ 614{
615 struct ak4641_platform_data *pdata = i2c->dev.platform_data;
616
624 snd_soc_unregister_codec(&i2c->dev); 617 snd_soc_unregister_codec(&i2c->dev);
618
619 if (pdata) {
620 if (gpio_is_valid(pdata->gpio_power)) {
621 gpio_set_value(pdata->gpio_power, 0);
622 gpio_free(pdata->gpio_power);
623 }
624 if (gpio_is_valid(pdata->gpio_npdn))
625 gpio_free(pdata->gpio_npdn);
626 }
627
625 return 0; 628 return 0;
626} 629}
627 630
@@ -641,23 +644,7 @@ static struct i2c_driver ak4641_i2c_driver = {
641 .id_table = ak4641_i2c_id, 644 .id_table = ak4641_i2c_id,
642}; 645};
643 646
644static int __init ak4641_modinit(void) 647module_i2c_driver(ak4641_i2c_driver);
645{
646 int ret;
647
648 ret = i2c_add_driver(&ak4641_i2c_driver);
649 if (ret != 0)
650 pr_err("Failed to register AK4641 I2C driver: %d\n", ret);
651
652 return ret;
653}
654module_init(ak4641_modinit);
655
656static void __exit ak4641_exit(void)
657{
658 i2c_del_driver(&ak4641_i2c_driver);
659}
660module_exit(ak4641_exit);
661 648
662MODULE_DESCRIPTION("SoC AK4641 driver"); 649MODULE_DESCRIPTION("SoC AK4641 driver");
663MODULE_AUTHOR("Harald Welte <laforge@gnufiish.org>"); 650MODULE_AUTHOR("Harald Welte <laforge@gnufiish.org>");
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index d47b62ddb210..1960478ce6bb 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -705,8 +705,7 @@ static int alc5623_set_dai_fmt(struct snd_soc_dai *codec_dai,
705static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream, 705static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream,
706 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 706 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
707{ 707{
708 struct snd_soc_pcm_runtime *rtd = substream->private_data; 708 struct snd_soc_codec *codec = dai->codec;
709 struct snd_soc_codec *codec = rtd->codec;
710 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); 709 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
711 int coeff, rate; 710 int coeff, rate;
712 u16 iface; 711 u16 iface;
@@ -1084,25 +1083,7 @@ static struct i2c_driver alc5623_i2c_driver = {
1084 .id_table = alc5623_i2c_table, 1083 .id_table = alc5623_i2c_table,
1085}; 1084};
1086 1085
1087static int __init alc5623_modinit(void) 1086module_i2c_driver(alc5623_i2c_driver);
1088{
1089 int ret;
1090
1091 ret = i2c_add_driver(&alc5623_i2c_driver);
1092 if (ret != 0) {
1093 printk(KERN_ERR "%s: can't add i2c driver", __func__);
1094 return ret;
1095 }
1096
1097 return ret;
1098}
1099module_init(alc5623_modinit);
1100
1101static void __exit alc5623_modexit(void)
1102{
1103 i2c_del_driver(&alc5623_i2c_driver);
1104}
1105module_exit(alc5623_modexit);
1106 1087
1107MODULE_DESCRIPTION("ASoC alc5621/2/3 driver"); 1088MODULE_DESCRIPTION("ASoC alc5621/2/3 driver");
1108MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); 1089MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
index e2111e0ccad7..7dd02420b36d 100644
--- a/sound/soc/codecs/alc5632.c
+++ b/sound/soc/codecs/alc5632.c
@@ -861,8 +861,7 @@ static int alc5632_set_dai_fmt(struct snd_soc_dai *codec_dai,
861static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream, 861static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream,
862 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 862 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
863{ 863{
864 struct snd_soc_pcm_runtime *rtd = substream->private_data; 864 struct snd_soc_codec *codec = dai->codec;
865 struct snd_soc_codec *codec = rtd->codec;
866 int coeff, rate; 865 int coeff, rate;
867 u16 iface; 866 u16 iface;
868 867
@@ -1131,7 +1130,7 @@ static __devinit int alc5632_i2c_probe(struct i2c_client *client,
1131 1130
1132 i2c_set_clientdata(client, alc5632); 1131 i2c_set_clientdata(client, alc5632);
1133 1132
1134 alc5632->regmap = regmap_init_i2c(client, &alc5632_regmap); 1133 alc5632->regmap = devm_regmap_init_i2c(client, &alc5632_regmap);
1135 if (IS_ERR(alc5632->regmap)) { 1134 if (IS_ERR(alc5632->regmap)) {
1136 ret = PTR_ERR(alc5632->regmap); 1135 ret = PTR_ERR(alc5632->regmap);
1137 dev_err(&client->dev, "regmap_init() failed: %d\n", ret); 1136 dev_err(&client->dev, "regmap_init() failed: %d\n", ret);
@@ -1143,7 +1142,6 @@ static __devinit int alc5632_i2c_probe(struct i2c_client *client,
1143 if (ret1 != 0 || ret2 != 0) { 1142 if (ret1 != 0 || ret2 != 0) {
1144 dev_err(&client->dev, 1143 dev_err(&client->dev,
1145 "Failed to read chip ID: ret1=%d, ret2=%d\n", ret1, ret2); 1144 "Failed to read chip ID: ret1=%d, ret2=%d\n", ret1, ret2);
1146 regmap_exit(alc5632->regmap);
1147 return -EIO; 1145 return -EIO;
1148 } 1146 }
1149 1147
@@ -1152,14 +1150,12 @@ static __devinit int alc5632_i2c_probe(struct i2c_client *client,
1152 if ((vid1 != 0x10EC) || (vid2 != id->driver_data)) { 1150 if ((vid1 != 0x10EC) || (vid2 != id->driver_data)) {
1153 dev_err(&client->dev, 1151 dev_err(&client->dev,
1154 "Device is not a ALC5632: VID1=0x%x, VID2=0x%x\n", vid1, vid2); 1152 "Device is not a ALC5632: VID1=0x%x, VID2=0x%x\n", vid1, vid2);
1155 regmap_exit(alc5632->regmap);
1156 return -EINVAL; 1153 return -EINVAL;
1157 } 1154 }
1158 1155
1159 ret = alc5632_reset(alc5632->regmap); 1156 ret = alc5632_reset(alc5632->regmap);
1160 if (ret < 0) { 1157 if (ret < 0) {
1161 dev_err(&client->dev, "Failed to issue reset\n"); 1158 dev_err(&client->dev, "Failed to issue reset\n");
1162 regmap_exit(alc5632->regmap);
1163 return ret; 1159 return ret;
1164 } 1160 }
1165 1161
@@ -1177,7 +1173,6 @@ static __devinit int alc5632_i2c_probe(struct i2c_client *client,
1177 1173
1178 if (ret < 0) { 1174 if (ret < 0) {
1179 dev_err(&client->dev, "Failed to register codec: %d\n", ret); 1175 dev_err(&client->dev, "Failed to register codec: %d\n", ret);
1180 regmap_exit(alc5632->regmap);
1181 return ret; 1176 return ret;
1182 } 1177 }
1183 1178
@@ -1186,9 +1181,7 @@ static __devinit int alc5632_i2c_probe(struct i2c_client *client,
1186 1181
1187static __devexit int alc5632_i2c_remove(struct i2c_client *client) 1182static __devexit int alc5632_i2c_remove(struct i2c_client *client)
1188{ 1183{
1189 struct alc5632_priv *alc5632 = i2c_get_clientdata(client);
1190 snd_soc_unregister_codec(&client->dev); 1184 snd_soc_unregister_codec(&client->dev);
1191 regmap_exit(alc5632->regmap);
1192 return 0; 1185 return 0;
1193} 1186}
1194 1187
@@ -1209,25 +1202,7 @@ static struct i2c_driver alc5632_i2c_driver = {
1209 .id_table = alc5632_i2c_table, 1202 .id_table = alc5632_i2c_table,
1210}; 1203};
1211 1204
1212static int __init alc5632_modinit(void) 1205module_i2c_driver(alc5632_i2c_driver);
1213{
1214 int ret;
1215
1216 ret = i2c_add_driver(&alc5632_i2c_driver);
1217 if (ret != 0) {
1218 printk(KERN_ERR "%s: can't add i2c driver", __func__);
1219 return ret;
1220 }
1221
1222 return ret;
1223}
1224module_init(alc5632_modinit);
1225
1226static void __exit alc5632_modexit(void)
1227{
1228 i2c_del_driver(&alc5632_i2c_driver);
1229}
1230module_exit(alc5632_modexit);
1231 1206
1232MODULE_DESCRIPTION("ASoC ALC5632 driver"); 1207MODULE_DESCRIPTION("ASoC ALC5632 driver");
1233MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>"); 1208MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>");
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 1d672f528662..047917f0b8ae 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -307,8 +307,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
307 struct snd_pcm_hw_params *params, 307 struct snd_pcm_hw_params *params,
308 struct snd_soc_dai *dai) 308 struct snd_soc_dai *dai)
309{ 309{
310 struct snd_soc_pcm_runtime *rtd = substream->private_data; 310 struct snd_soc_codec *codec = dai->codec;
311 struct snd_soc_codec *codec = rtd->codec;
312 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 311 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
313 int ret; 312 int ret;
314 unsigned int i; 313 unsigned int i;
@@ -600,10 +599,12 @@ static int cs4270_soc_suspend(struct snd_soc_codec *codec)
600static int cs4270_soc_resume(struct snd_soc_codec *codec) 599static int cs4270_soc_resume(struct snd_soc_codec *codec)
601{ 600{
602 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 601 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
603 int reg; 602 int reg, ret;
604 603
605 regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), 604 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
606 cs4270->supplies); 605 cs4270->supplies);
606 if (ret != 0)
607 return ret;
607 608
608 /* In case the device was put to hard reset during sleep, we need to 609 /* In case the device was put to hard reset during sleep, we need to
609 * wait 500ns here before any I2C communication. */ 610 * wait 500ns here before any I2C communication. */
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index bf7141280a74..9eb01d7d58a3 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -318,8 +318,7 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
318 struct snd_pcm_hw_params *params, 318 struct snd_pcm_hw_params *params,
319 struct snd_soc_dai *dai) 319 struct snd_soc_dai *dai)
320{ 320{
321 struct snd_soc_pcm_runtime *rtd = substream->private_data; 321 struct snd_soc_codec *codec = dai->codec;
322 struct snd_soc_codec *codec = rtd->codec;
323 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); 322 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
324 int i, ret; 323 int i, ret;
325 unsigned int ratio, val; 324 unsigned int ratio, val;
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index a8bf588e8740..091d0193f507 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -141,15 +141,15 @@ static const struct soc_enum cs42l51_chan_mix =
141static const struct snd_kcontrol_new cs42l51_snd_controls[] = { 141static const struct snd_kcontrol_new cs42l51_snd_controls[] = {
142 SOC_DOUBLE_R_SX_TLV("PCM Playback Volume", 142 SOC_DOUBLE_R_SX_TLV("PCM Playback Volume",
143 CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 143 CS42L51_PCMA_VOL, CS42L51_PCMB_VOL,
144 7, 0xffffff99, 0x18, adc_pcm_tlv), 144 6, 0x19, 0x7F, adc_pcm_tlv),
145 SOC_DOUBLE_R("PCM Playback Switch", 145 SOC_DOUBLE_R("PCM Playback Switch",
146 CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1), 146 CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1),
147 SOC_DOUBLE_R_SX_TLV("Analog Playback Volume", 147 SOC_DOUBLE_R_SX_TLV("Analog Playback Volume",
148 CS42L51_AOUTA_VOL, CS42L51_AOUTB_VOL, 148 CS42L51_AOUTA_VOL, CS42L51_AOUTB_VOL,
149 8, 0xffffff19, 0x18, aout_tlv), 149 0, 0x34, 0xE4, aout_tlv),
150 SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume", 150 SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume",
151 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 151 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL,
152 7, 0xffffff99, 0x18, adc_pcm_tlv), 152 6, 0x19, 0x7F, adc_pcm_tlv),
153 SOC_DOUBLE_R("ADC Mixer Switch", 153 SOC_DOUBLE_R("ADC Mixer Switch",
154 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1), 154 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1),
155 SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0), 155 SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0),
@@ -356,8 +356,7 @@ static int cs42l51_hw_params(struct snd_pcm_substream *substream,
356 struct snd_pcm_hw_params *params, 356 struct snd_pcm_hw_params *params,
357 struct snd_soc_dai *dai) 357 struct snd_soc_dai *dai)
358{ 358{
359 struct snd_soc_pcm_runtime *rtd = substream->private_data; 359 struct snd_soc_codec *codec = dai->codec;
360 struct snd_soc_codec *codec = rtd->codec;
361 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); 360 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
362 int ret; 361 int ret;
363 unsigned int i; 362 unsigned int i;
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
new file mode 100644
index 000000000000..a7109413aef1
--- /dev/null
+++ b/sound/soc/codecs/cs42l52.c
@@ -0,0 +1,1295 @@
1/*
2 * cs42l52.c -- CS42L52 ALSA SoC audio driver
3 *
4 * Copyright 2012 CirrusLogic, Inc.
5 *
6 * Author: Georgi Vlaev <joe@nucleusys.com>
7 * Author: Brian Austin <brian.austin@cirrus.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/version.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/delay.h>
21#include <linux/pm.h>
22#include <linux/i2c.h>
23#include <linux/input.h>
24#include <linux/regmap.h>
25#include <linux/slab.h>
26#include <linux/workqueue.h>
27#include <linux/platform_device.h>
28#include <linux/slab.h>
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/pcm_params.h>
32#include <sound/soc.h>
33#include <sound/soc-dapm.h>
34#include <sound/initval.h>
35#include <sound/tlv.h>
36#include <sound/cs42l52.h>
37#include "cs42l52.h"
38
39struct sp_config {
40 u8 spc, format, spfs;
41 u32 srate;
42};
43
44struct cs42l52_private {
45 struct regmap *regmap;
46 struct snd_soc_codec *codec;
47 struct device *dev;
48 struct sp_config config;
49 struct cs42l52_platform_data pdata;
50 u32 sysclk;
51 u8 mclksel;
52 u32 mclk;
53 u8 flags;
54#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
55 struct input_dev *beep;
56 struct work_struct beep_work;
57 int beep_rate;
58#endif
59};
60
61static const struct reg_default cs42l52_reg_defaults[] = {
62 { CS42L52_PWRCTL1, 0x9F }, /* r02 PWRCTL 1 */
63 { CS42L52_PWRCTL2, 0x07 }, /* r03 PWRCTL 2 */
64 { CS42L52_PWRCTL3, 0xFF }, /* r04 PWRCTL 3 */
65 { CS42L52_CLK_CTL, 0xA0 }, /* r05 Clocking Ctl */
66 { CS42L52_IFACE_CTL1, 0x00 }, /* r06 Interface Ctl 1 */
67 { CS42L52_ADC_PGA_A, 0x80 }, /* r08 Input A Select */
68 { CS42L52_ADC_PGA_B, 0x80 }, /* r09 Input B Select */
69 { CS42L52_ANALOG_HPF_CTL, 0xA5 }, /* r0A Analog HPF Ctl */
70 { CS42L52_ADC_HPF_FREQ, 0x00 }, /* r0B ADC HPF Corner Freq */
71 { CS42L52_ADC_MISC_CTL, 0x00 }, /* r0C Misc. ADC Ctl */
72 { CS42L52_PB_CTL1, 0x60 }, /* r0D Playback Ctl 1 */
73 { CS42L52_MISC_CTL, 0x02 }, /* r0E Misc. Ctl */
74 { CS42L52_PB_CTL2, 0x00 }, /* r0F Playback Ctl 2 */
75 { CS42L52_MICA_CTL, 0x00 }, /* r10 MICA Amp Ctl */
76 { CS42L52_MICB_CTL, 0x00 }, /* r11 MICB Amp Ctl */
77 { CS42L52_PGAA_CTL, 0x00 }, /* r12 PGAA Vol, Misc. */
78 { CS42L52_PGAB_CTL, 0x00 }, /* r13 PGAB Vol, Misc. */
79 { CS42L52_PASSTHRUA_VOL, 0x00 }, /* r14 Bypass A Vol */
80 { CS42L52_PASSTHRUB_VOL, 0x00 }, /* r15 Bypass B Vol */
81 { CS42L52_ADCA_VOL, 0x00 }, /* r16 ADCA Volume */
82 { CS42L52_ADCB_VOL, 0x00 }, /* r17 ADCB Volume */
83 { CS42L52_ADCA_MIXER_VOL, 0x80 }, /* r18 ADCA Mixer Volume */
84 { CS42L52_ADCB_MIXER_VOL, 0x80 }, /* r19 ADCB Mixer Volume */
85 { CS42L52_PCMA_MIXER_VOL, 0x00 }, /* r1A PCMA Mixer Volume */
86 { CS42L52_PCMB_MIXER_VOL, 0x00 }, /* r1B PCMB Mixer Volume */
87 { CS42L52_BEEP_FREQ, 0x00 }, /* r1C Beep Freq on Time */
88 { CS42L52_BEEP_VOL, 0x00 }, /* r1D Beep Volume off Time */
89 { CS42L52_BEEP_TONE_CTL, 0x00 }, /* r1E Beep Tone Cfg. */
90 { CS42L52_TONE_CTL, 0x00 }, /* r1F Tone Ctl */
91 { CS42L52_MASTERA_VOL, 0x88 }, /* r20 Master A Volume */
92 { CS42L52_MASTERB_VOL, 0x00 }, /* r21 Master B Volume */
93 { CS42L52_HPA_VOL, 0x00 }, /* r22 Headphone A Volume */
94 { CS42L52_HPB_VOL, 0x00 }, /* r23 Headphone B Volume */
95 { CS42L52_SPKA_VOL, 0x00 }, /* r24 Speaker A Volume */
96 { CS42L52_SPKB_VOL, 0x00 }, /* r25 Speaker B Volume */
97 { CS42L52_ADC_PCM_MIXER, 0x00 }, /* r26 Channel Mixer and Swap */
98 { CS42L52_LIMITER_CTL1, 0x00 }, /* r27 Limit Ctl 1 Thresholds */
99 { CS42L52_LIMITER_CTL2, 0x7F }, /* r28 Limit Ctl 2 Release Rate */
100 { CS42L52_LIMITER_AT_RATE, 0xC0 }, /* r29 Limiter Attack Rate */
101 { CS42L52_ALC_CTL, 0x00 }, /* r2A ALC Ctl 1 Attack Rate */
102 { CS42L52_ALC_RATE, 0x3F }, /* r2B ALC Release Rate */
103 { CS42L52_ALC_THRESHOLD, 0x3f }, /* r2C ALC Thresholds */
104 { CS42L52_NOISE_GATE_CTL, 0x00 }, /* r2D Noise Gate Ctl */
105 { CS42L52_CLK_STATUS, 0x00 }, /* r2E Overflow and Clock Status */
106 { CS42L52_BATT_COMPEN, 0x00 }, /* r2F battery Compensation */
107 { CS42L52_BATT_LEVEL, 0x00 }, /* r30 VP Battery Level */
108 { CS42L52_SPK_STATUS, 0x00 }, /* r31 Speaker Status */
109 { CS42L52_TEM_CTL, 0x3B }, /* r32 Temp Ctl */
110 { CS42L52_THE_FOLDBACK, 0x00 }, /* r33 Foldback */
111};
112
113static bool cs42l52_readable_register(struct device *dev, unsigned int reg)
114{
115 switch (reg) {
116 case CS42L52_CHIP:
117 case CS42L52_PWRCTL1:
118 case CS42L52_PWRCTL2:
119 case CS42L52_PWRCTL3:
120 case CS42L52_CLK_CTL:
121 case CS42L52_IFACE_CTL1:
122 case CS42L52_IFACE_CTL2:
123 case CS42L52_ADC_PGA_A:
124 case CS42L52_ADC_PGA_B:
125 case CS42L52_ANALOG_HPF_CTL:
126 case CS42L52_ADC_HPF_FREQ:
127 case CS42L52_ADC_MISC_CTL:
128 case CS42L52_PB_CTL1:
129 case CS42L52_MISC_CTL:
130 case CS42L52_PB_CTL2:
131 case CS42L52_MICA_CTL:
132 case CS42L52_MICB_CTL:
133 case CS42L52_PGAA_CTL:
134 case CS42L52_PGAB_CTL:
135 case CS42L52_PASSTHRUA_VOL:
136 case CS42L52_PASSTHRUB_VOL:
137 case CS42L52_ADCA_VOL:
138 case CS42L52_ADCB_VOL:
139 case CS42L52_ADCA_MIXER_VOL:
140 case CS42L52_ADCB_MIXER_VOL:
141 case CS42L52_PCMA_MIXER_VOL:
142 case CS42L52_PCMB_MIXER_VOL:
143 case CS42L52_BEEP_FREQ:
144 case CS42L52_BEEP_VOL:
145 case CS42L52_BEEP_TONE_CTL:
146 case CS42L52_TONE_CTL:
147 case CS42L52_MASTERA_VOL:
148 case CS42L52_MASTERB_VOL:
149 case CS42L52_HPA_VOL:
150 case CS42L52_HPB_VOL:
151 case CS42L52_SPKA_VOL:
152 case CS42L52_SPKB_VOL:
153 case CS42L52_ADC_PCM_MIXER:
154 case CS42L52_LIMITER_CTL1:
155 case CS42L52_LIMITER_CTL2:
156 case CS42L52_LIMITER_AT_RATE:
157 case CS42L52_ALC_CTL:
158 case CS42L52_ALC_RATE:
159 case CS42L52_ALC_THRESHOLD:
160 case CS42L52_NOISE_GATE_CTL:
161 case CS42L52_CLK_STATUS:
162 case CS42L52_BATT_COMPEN:
163 case CS42L52_BATT_LEVEL:
164 case CS42L52_SPK_STATUS:
165 case CS42L52_TEM_CTL:
166 case CS42L52_THE_FOLDBACK:
167 case CS42L52_CHARGE_PUMP:
168 return true;
169 default:
170 return false;
171 }
172}
173
174static bool cs42l52_volatile_register(struct device *dev, unsigned int reg)
175{
176 switch (reg) {
177 case CS42L52_IFACE_CTL2:
178 case CS42L52_CLK_STATUS:
179 case CS42L52_BATT_LEVEL:
180 case CS42L52_SPK_STATUS:
181 case CS42L52_CHARGE_PUMP:
182 return 1;
183 default:
184 return 0;
185 }
186}
187
188static DECLARE_TLV_DB_SCALE(hl_tlv, -10200, 50, 0);
189
190static DECLARE_TLV_DB_SCALE(hpd_tlv, -9600, 50, 1);
191
192static DECLARE_TLV_DB_SCALE(ipd_tlv, -9600, 100, 0);
193
194static DECLARE_TLV_DB_SCALE(mic_tlv, 1600, 100, 0);
195
196static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0);
197
198static const unsigned int limiter_tlv[] = {
199 TLV_DB_RANGE_HEAD(2),
200 0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0),
201 3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0),
202};
203
204static const char * const cs42l52_adca_text[] = {
205 "Input1A", "Input2A", "Input3A", "Input4A", "PGA Input Left"};
206
207static const char * const cs42l52_adcb_text[] = {
208 "Input1B", "Input2B", "Input3B", "Input4B", "PGA Input Right"};
209
210static const struct soc_enum adca_enum =
211 SOC_ENUM_SINGLE(CS42L52_ADC_PGA_A, 5,
212 ARRAY_SIZE(cs42l52_adca_text), cs42l52_adca_text);
213
214static const struct soc_enum adcb_enum =
215 SOC_ENUM_SINGLE(CS42L52_ADC_PGA_B, 5,
216 ARRAY_SIZE(cs42l52_adcb_text), cs42l52_adcb_text);
217
218static const struct snd_kcontrol_new adca_mux =
219 SOC_DAPM_ENUM("Left ADC Input Capture Mux", adca_enum);
220
221static const struct snd_kcontrol_new adcb_mux =
222 SOC_DAPM_ENUM("Right ADC Input Capture Mux", adcb_enum);
223
224static const char * const mic_bias_level_text[] = {
225 "0.5 +VA", "0.6 +VA", "0.7 +VA",
226 "0.8 +VA", "0.83 +VA", "0.91 +VA"
227};
228
229static const struct soc_enum mic_bias_level_enum =
230 SOC_ENUM_SINGLE(CS42L52_IFACE_CTL1, 0,
231 ARRAY_SIZE(mic_bias_level_text), mic_bias_level_text);
232
233static const char * const cs42l52_mic_text[] = { "Single", "Differential" };
234
235static const struct soc_enum mica_enum =
236 SOC_ENUM_SINGLE(CS42L52_MICA_CTL, 5,
237 ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text);
238
239static const struct soc_enum micb_enum =
240 SOC_ENUM_SINGLE(CS42L52_MICB_CTL, 5,
241 ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text);
242
243static const struct snd_kcontrol_new mica_mux =
244 SOC_DAPM_ENUM("Left Mic Input Capture Mux", mica_enum);
245
246static const struct snd_kcontrol_new micb_mux =
247 SOC_DAPM_ENUM("Right Mic Input Capture Mux", micb_enum);
248
249static const char * const digital_output_mux_text[] = {"ADC", "DSP"};
250
251static const struct soc_enum digital_output_mux_enum =
252 SOC_ENUM_SINGLE(CS42L52_ADC_MISC_CTL, 6,
253 ARRAY_SIZE(digital_output_mux_text),
254 digital_output_mux_text);
255
256static const struct snd_kcontrol_new digital_output_mux =
257 SOC_DAPM_ENUM("Digital Output Mux", digital_output_mux_enum);
258
259static const char * const hp_gain_num_text[] = {
260 "0.3959", "0.4571", "0.5111", "0.6047",
261 "0.7099", "0.8399", "1.000", "1.1430"
262};
263
264static const struct soc_enum hp_gain_enum =
265 SOC_ENUM_SINGLE(CS42L52_PB_CTL1, 4,
266 ARRAY_SIZE(hp_gain_num_text), hp_gain_num_text);
267
268static const char * const beep_pitch_text[] = {
269 "C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5",
270 "C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7"
271};
272
273static const struct soc_enum beep_pitch_enum =
274 SOC_ENUM_SINGLE(CS42L52_BEEP_FREQ, 4,
275 ARRAY_SIZE(beep_pitch_text), beep_pitch_text);
276
277static const char * const beep_ontime_text[] = {
278 "86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s",
279 "1.80 s", "2.20 s", "2.50 s", "2.80 s", "3.20 s",
280 "3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s"
281};
282
283static const struct soc_enum beep_ontime_enum =
284 SOC_ENUM_SINGLE(CS42L52_BEEP_FREQ, 0,
285 ARRAY_SIZE(beep_ontime_text), beep_ontime_text);
286
287static const char * const beep_offtime_text[] = {
288 "1.23 s", "2.58 s", "3.90 s", "5.20 s",
289 "6.60 s", "8.05 s", "9.35 s", "10.80 s"
290};
291
292static const struct soc_enum beep_offtime_enum =
293 SOC_ENUM_SINGLE(CS42L52_BEEP_VOL, 5,
294 ARRAY_SIZE(beep_offtime_text), beep_offtime_text);
295
296static const char * const beep_config_text[] = {
297 "Off", "Single", "Multiple", "Continuous"
298};
299
300static const struct soc_enum beep_config_enum =
301 SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 6,
302 ARRAY_SIZE(beep_config_text), beep_config_text);
303
304static const char * const beep_bass_text[] = {
305 "50 Hz", "100 Hz", "200 Hz", "250 Hz"
306};
307
308static const struct soc_enum beep_bass_enum =
309 SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 1,
310 ARRAY_SIZE(beep_bass_text), beep_bass_text);
311
312static const char * const beep_treble_text[] = {
313 "5 kHz", "7 kHz", "10 kHz", " 15 kHz"
314};
315
316static const struct soc_enum beep_treble_enum =
317 SOC_ENUM_SINGLE(CS42L52_BEEP_TONE_CTL, 3,
318 ARRAY_SIZE(beep_treble_text), beep_treble_text);
319
320static const char * const ng_threshold_text[] = {
321 "-34dB", "-37dB", "-40dB", "-43dB",
322 "-46dB", "-52dB", "-58dB", "-64dB"
323};
324
325static const struct soc_enum ng_threshold_enum =
326 SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 2,
327 ARRAY_SIZE(ng_threshold_text), ng_threshold_text);
328
329static const char * const cs42l52_ng_delay_text[] = {
330 "50ms", "100ms", "150ms", "200ms"};
331
332static const struct soc_enum ng_delay_enum =
333 SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 0,
334 ARRAY_SIZE(cs42l52_ng_delay_text), cs42l52_ng_delay_text);
335
336static const char * const cs42l52_ng_type_text[] = {
337 "Apply Specific", "Apply All"
338};
339
340static const struct soc_enum ng_type_enum =
341 SOC_ENUM_SINGLE(CS42L52_NOISE_GATE_CTL, 6,
342 ARRAY_SIZE(cs42l52_ng_type_text), cs42l52_ng_type_text);
343
344static const char * const left_swap_text[] = {
345 "Left", "LR 2", "Right"};
346
347static const char * const right_swap_text[] = {
348 "Right", "LR 2", "Left"};
349
350static const unsigned int swap_values[] = { 0, 1, 3 };
351
352static const struct soc_enum adca_swap_enum =
353 SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 2, 1,
354 ARRAY_SIZE(left_swap_text),
355 left_swap_text,
356 swap_values);
357
358static const struct snd_kcontrol_new adca_mixer =
359 SOC_DAPM_ENUM("Route", adca_swap_enum);
360
361static const struct soc_enum pcma_swap_enum =
362 SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 6, 1,
363 ARRAY_SIZE(left_swap_text),
364 left_swap_text,
365 swap_values);
366
367static const struct snd_kcontrol_new pcma_mixer =
368 SOC_DAPM_ENUM("Route", pcma_swap_enum);
369
370static const struct soc_enum adcb_swap_enum =
371 SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 0, 1,
372 ARRAY_SIZE(right_swap_text),
373 right_swap_text,
374 swap_values);
375
376static const struct snd_kcontrol_new adcb_mixer =
377 SOC_DAPM_ENUM("Route", adcb_swap_enum);
378
379static const struct soc_enum pcmb_swap_enum =
380 SOC_VALUE_ENUM_SINGLE(CS42L52_ADC_PCM_MIXER, 4, 1,
381 ARRAY_SIZE(right_swap_text),
382 right_swap_text,
383 swap_values);
384
385static const struct snd_kcontrol_new pcmb_mixer =
386 SOC_DAPM_ENUM("Route", pcmb_swap_enum);
387
388
389static const struct snd_kcontrol_new passthrul_ctl =
390 SOC_DAPM_SINGLE("Switch", CS42L52_MISC_CTL, 6, 1, 0);
391
392static const struct snd_kcontrol_new passthrur_ctl =
393 SOC_DAPM_SINGLE("Switch", CS42L52_MISC_CTL, 7, 1, 0);
394
395static const struct snd_kcontrol_new spkl_ctl =
396 SOC_DAPM_SINGLE("Switch", CS42L52_PWRCTL3, 0, 1, 1);
397
398static const struct snd_kcontrol_new spkr_ctl =
399 SOC_DAPM_SINGLE("Switch", CS42L52_PWRCTL3, 2, 1, 1);
400
401static const struct snd_kcontrol_new hpl_ctl =
402 SOC_DAPM_SINGLE("Switch", CS42L52_PWRCTL3, 4, 1, 1);
403
404static const struct snd_kcontrol_new hpr_ctl =
405 SOC_DAPM_SINGLE("Switch", CS42L52_PWRCTL3, 6, 1, 1);
406
407static const struct snd_kcontrol_new cs42l52_snd_controls[] = {
408
409 SOC_DOUBLE_R_SX_TLV("Master Volume", CS42L52_MASTERA_VOL,
410 CS42L52_MASTERB_VOL, 0, 0x34, 0xE4, hl_tlv),
411
412 SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L52_HPA_VOL,
413 CS42L52_HPB_VOL, 0, 0x34, 0xCC, hpd_tlv),
414
415 SOC_ENUM("Headphone Analog Gain", hp_gain_enum),
416
417 SOC_DOUBLE_R_SX_TLV("Speaker Volume", CS42L52_SPKA_VOL,
418 CS42L52_SPKB_VOL, 7, 0x1, 0xff, hl_tlv),
419
420 SOC_DOUBLE_R_SX_TLV("Bypass Volume", CS42L52_PASSTHRUA_VOL,
421 CS42L52_PASSTHRUB_VOL, 6, 0x18, 0x90, pga_tlv),
422
423 SOC_DOUBLE("Bypass Mute", CS42L52_MISC_CTL, 4, 5, 1, 0),
424
425 SOC_DOUBLE_R_TLV("MIC Gain Volume", CS42L52_MICA_CTL,
426 CS42L52_MICB_CTL, 0, 0x10, 0, mic_tlv),
427
428 SOC_ENUM("MIC Bias Level", mic_bias_level_enum),
429
430 SOC_DOUBLE_R_SX_TLV("ADC Volume", CS42L52_ADCA_VOL,
431 CS42L52_ADCB_VOL, 7, 0x80, 0xA0, ipd_tlv),
432 SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume",
433 CS42L52_ADCA_MIXER_VOL, CS42L52_ADCB_MIXER_VOL,
434 6, 0x7f, 0x19, ipd_tlv),
435
436 SOC_DOUBLE("ADC Switch", CS42L52_ADC_MISC_CTL, 0, 1, 1, 0),
437
438 SOC_DOUBLE_R("ADC Mixer Switch", CS42L52_ADCA_MIXER_VOL,
439 CS42L52_ADCB_MIXER_VOL, 7, 1, 1),
440
441 SOC_DOUBLE_R_SX_TLV("PGA Volume", CS42L52_PGAA_CTL,
442 CS42L52_PGAB_CTL, 0, 0x28, 0x30, pga_tlv),
443
444 SOC_DOUBLE_R_SX_TLV("PCM Mixer Volume",
445 CS42L52_PCMA_MIXER_VOL, CS42L52_PCMB_MIXER_VOL,
446 6, 0x7f, 0x19, hl_tlv),
447 SOC_DOUBLE_R("PCM Mixer Switch",
448 CS42L52_PCMA_MIXER_VOL, CS42L52_PCMB_MIXER_VOL, 7, 1, 1),
449
450 SOC_ENUM("Beep Config", beep_config_enum),
451 SOC_ENUM("Beep Pitch", beep_pitch_enum),
452 SOC_ENUM("Beep on Time", beep_ontime_enum),
453 SOC_ENUM("Beep off Time", beep_offtime_enum),
454 SOC_SINGLE_TLV("Beep Volume", CS42L52_BEEP_VOL, 0, 0x1f, 0x07, hl_tlv),
455 SOC_SINGLE("Beep Mixer Switch", CS42L52_BEEP_TONE_CTL, 5, 1, 1),
456 SOC_ENUM("Beep Treble Corner Freq", beep_treble_enum),
457 SOC_ENUM("Beep Bass Corner Freq", beep_bass_enum),
458
459 SOC_SINGLE("Tone Control Switch", CS42L52_BEEP_TONE_CTL, 0, 1, 1),
460 SOC_SINGLE_TLV("Treble Gain Volume",
461 CS42L52_TONE_CTL, 4, 15, 1, hl_tlv),
462 SOC_SINGLE_TLV("Bass Gain Volume",
463 CS42L52_TONE_CTL, 0, 15, 1, hl_tlv),
464
465 /* Limiter */
466 SOC_SINGLE_TLV("Limiter Max Threshold Volume",
467 CS42L52_LIMITER_CTL1, 5, 7, 0, limiter_tlv),
468 SOC_SINGLE_TLV("Limiter Cushion Threshold Volume",
469 CS42L52_LIMITER_CTL1, 2, 7, 0, limiter_tlv),
470 SOC_SINGLE_TLV("Limiter Release Rate Volume",
471 CS42L52_LIMITER_CTL2, 0, 63, 0, limiter_tlv),
472 SOC_SINGLE_TLV("Limiter Attack Rate Volume",
473 CS42L52_LIMITER_AT_RATE, 0, 63, 0, limiter_tlv),
474
475 SOC_SINGLE("Limiter SR Switch", CS42L52_LIMITER_CTL1, 1, 1, 0),
476 SOC_SINGLE("Limiter ZC Switch", CS42L52_LIMITER_CTL1, 0, 1, 0),
477 SOC_SINGLE("Limiter Switch", CS42L52_LIMITER_CTL2, 7, 1, 0),
478
479 /* ALC */
480 SOC_SINGLE_TLV("ALC Attack Rate Volume", CS42L52_ALC_CTL,
481 0, 63, 0, limiter_tlv),
482 SOC_SINGLE_TLV("ALC Release Rate Volume", CS42L52_ALC_RATE,
483 0, 63, 0, limiter_tlv),
484 SOC_SINGLE_TLV("ALC Max Threshold Volume", CS42L52_ALC_THRESHOLD,
485 5, 7, 0, limiter_tlv),
486 SOC_SINGLE_TLV("ALC Min Threshold Volume", CS42L52_ALC_THRESHOLD,
487 2, 7, 0, limiter_tlv),
488
489 SOC_DOUBLE_R("ALC SR Capture Switch", CS42L52_PGAA_CTL,
490 CS42L52_PGAB_CTL, 7, 1, 1),
491 SOC_DOUBLE_R("ALC ZC Capture Switch", CS42L52_PGAA_CTL,
492 CS42L52_PGAB_CTL, 6, 1, 1),
493 SOC_DOUBLE("ALC Capture Switch", CS42L52_ALC_CTL, 6, 7, 1, 0),
494
495 /* Noise gate */
496 SOC_ENUM("NG Type Switch", ng_type_enum),
497 SOC_SINGLE("NG Enable Switch", CS42L52_NOISE_GATE_CTL, 6, 1, 0),
498 SOC_SINGLE("NG Boost Switch", CS42L52_NOISE_GATE_CTL, 5, 1, 1),
499 SOC_ENUM("NG Threshold", ng_threshold_enum),
500 SOC_ENUM("NG Delay", ng_delay_enum),
501
502 SOC_DOUBLE("HPF Switch", CS42L52_ANALOG_HPF_CTL, 5, 7, 1, 0),
503
504 SOC_DOUBLE("Analog SR Switch", CS42L52_ANALOG_HPF_CTL, 1, 3, 1, 1),
505 SOC_DOUBLE("Analog ZC Switch", CS42L52_ANALOG_HPF_CTL, 0, 2, 1, 1),
506 SOC_SINGLE("Digital SR Switch", CS42L52_MISC_CTL, 1, 1, 0),
507 SOC_SINGLE("Digital ZC Switch", CS42L52_MISC_CTL, 0, 1, 0),
508 SOC_SINGLE("Deemphasis Switch", CS42L52_MISC_CTL, 2, 1, 0),
509
510 SOC_SINGLE("Batt Compensation Switch", CS42L52_BATT_COMPEN, 7, 1, 0),
511 SOC_SINGLE("Batt VP Monitor Switch", CS42L52_BATT_COMPEN, 6, 1, 0),
512 SOC_SINGLE("Batt VP ref", CS42L52_BATT_COMPEN, 0, 0x0f, 0),
513
514 SOC_SINGLE("PGA AIN1L Switch", CS42L52_ADC_PGA_A, 0, 1, 0),
515 SOC_SINGLE("PGA AIN1R Switch", CS42L52_ADC_PGA_B, 0, 1, 0),
516 SOC_SINGLE("PGA AIN2L Switch", CS42L52_ADC_PGA_A, 1, 1, 0),
517 SOC_SINGLE("PGA AIN2R Switch", CS42L52_ADC_PGA_B, 1, 1, 0),
518
519 SOC_SINGLE("PGA AIN3L Switch", CS42L52_ADC_PGA_A, 2, 1, 0),
520 SOC_SINGLE("PGA AIN3R Switch", CS42L52_ADC_PGA_B, 2, 1, 0),
521
522 SOC_SINGLE("PGA AIN4L Switch", CS42L52_ADC_PGA_A, 3, 1, 0),
523 SOC_SINGLE("PGA AIN4R Switch", CS42L52_ADC_PGA_B, 3, 1, 0),
524
525 SOC_SINGLE("PGA MICA Switch", CS42L52_ADC_PGA_A, 4, 1, 0),
526 SOC_SINGLE("PGA MICB Switch", CS42L52_ADC_PGA_B, 4, 1, 0),
527
528};
529
530static const struct snd_soc_dapm_widget cs42l52_dapm_widgets[] = {
531
532 SND_SOC_DAPM_INPUT("AIN1L"),
533 SND_SOC_DAPM_INPUT("AIN1R"),
534 SND_SOC_DAPM_INPUT("AIN2L"),
535 SND_SOC_DAPM_INPUT("AIN2R"),
536 SND_SOC_DAPM_INPUT("AIN3L"),
537 SND_SOC_DAPM_INPUT("AIN3R"),
538 SND_SOC_DAPM_INPUT("AIN4L"),
539 SND_SOC_DAPM_INPUT("AIN4R"),
540 SND_SOC_DAPM_INPUT("MICA"),
541 SND_SOC_DAPM_INPUT("MICB"),
542 SND_SOC_DAPM_SIGGEN("Beep"),
543
544 SND_SOC_DAPM_AIF_OUT("AIFOUTL", NULL, 0,
545 SND_SOC_NOPM, 0, 0),
546 SND_SOC_DAPM_AIF_OUT("AIFOUTR", NULL, 0,
547 SND_SOC_NOPM, 0, 0),
548
549 SND_SOC_DAPM_MUX("MICA Mux", SND_SOC_NOPM, 0, 0, &mica_mux),
550 SND_SOC_DAPM_MUX("MICB Mux", SND_SOC_NOPM, 0, 0, &micb_mux),
551
552 SND_SOC_DAPM_ADC("ADC Left", NULL, CS42L52_PWRCTL1, 1, 1),
553 SND_SOC_DAPM_ADC("ADC Right", NULL, CS42L52_PWRCTL1, 2, 1),
554 SND_SOC_DAPM_PGA("PGA Left", CS42L52_PWRCTL1, 3, 1, NULL, 0),
555 SND_SOC_DAPM_PGA("PGA Right", CS42L52_PWRCTL1, 4, 1, NULL, 0),
556
557 SND_SOC_DAPM_MUX("ADC Left Mux", SND_SOC_NOPM, 0, 0, &adca_mux),
558 SND_SOC_DAPM_MUX("ADC Right Mux", SND_SOC_NOPM, 0, 0, &adcb_mux),
559
560 SND_SOC_DAPM_MUX("ADC Left Swap", SND_SOC_NOPM,
561 0, 0, &adca_mixer),
562 SND_SOC_DAPM_MUX("ADC Right Swap", SND_SOC_NOPM,
563 0, 0, &adcb_mixer),
564
565 SND_SOC_DAPM_MUX("Output Mux", SND_SOC_NOPM,
566 0, 0, &digital_output_mux),
567
568 SND_SOC_DAPM_PGA("PGA MICA", CS42L52_PWRCTL2, 1, 1, NULL, 0),
569 SND_SOC_DAPM_PGA("PGA MICB", CS42L52_PWRCTL2, 2, 1, NULL, 0),
570
571 SND_SOC_DAPM_SUPPLY("Mic Bias", CS42L52_PWRCTL2, 0, 1, NULL, 0),
572 SND_SOC_DAPM_SUPPLY("Charge Pump", CS42L52_PWRCTL1, 7, 1, NULL, 0),
573
574 SND_SOC_DAPM_AIF_IN("AIFINL", NULL, 0,
575 SND_SOC_NOPM, 0, 0),
576 SND_SOC_DAPM_AIF_IN("AIFINR", NULL, 0,
577 SND_SOC_NOPM, 0, 0),
578
579 SND_SOC_DAPM_DAC("DAC Left", NULL, SND_SOC_NOPM, 0, 0),
580 SND_SOC_DAPM_DAC("DAC Right", NULL, SND_SOC_NOPM, 0, 0),
581
582 SND_SOC_DAPM_SWITCH("Bypass Left", CS42L52_MISC_CTL,
583 6, 0, &passthrul_ctl),
584 SND_SOC_DAPM_SWITCH("Bypass Right", CS42L52_MISC_CTL,
585 7, 0, &passthrur_ctl),
586
587 SND_SOC_DAPM_MUX("PCM Left Swap", SND_SOC_NOPM,
588 0, 0, &pcma_mixer),
589 SND_SOC_DAPM_MUX("PCM Right Swap", SND_SOC_NOPM,
590 0, 0, &pcmb_mixer),
591
592 SND_SOC_DAPM_SWITCH("HP Left Amp", SND_SOC_NOPM, 0, 0, &hpl_ctl),
593 SND_SOC_DAPM_SWITCH("HP Right Amp", SND_SOC_NOPM, 0, 0, &hpr_ctl),
594
595 SND_SOC_DAPM_SWITCH("SPK Left Amp", SND_SOC_NOPM, 0, 0, &spkl_ctl),
596 SND_SOC_DAPM_SWITCH("SPK Right Amp", SND_SOC_NOPM, 0, 0, &spkr_ctl),
597
598 SND_SOC_DAPM_OUTPUT("HPOUTA"),
599 SND_SOC_DAPM_OUTPUT("HPOUTB"),
600 SND_SOC_DAPM_OUTPUT("SPKOUTA"),
601 SND_SOC_DAPM_OUTPUT("SPKOUTB"),
602
603};
604
605static const struct snd_soc_dapm_route cs42l52_audio_map[] = {
606
607 {"Capture", NULL, "AIFOUTL"},
608 {"Capture", NULL, "AIFOUTL"},
609
610 {"AIFOUTL", NULL, "Output Mux"},
611 {"AIFOUTR", NULL, "Output Mux"},
612
613 {"Output Mux", "ADC", "ADC Left"},
614 {"Output Mux", "ADC", "ADC Right"},
615
616 {"ADC Left", NULL, "Charge Pump"},
617 {"ADC Right", NULL, "Charge Pump"},
618
619 {"Charge Pump", NULL, "ADC Left Mux"},
620 {"Charge Pump", NULL, "ADC Right Mux"},
621
622 {"ADC Left Mux", "Input1A", "AIN1L"},
623 {"ADC Right Mux", "Input1B", "AIN1R"},
624 {"ADC Left Mux", "Input2A", "AIN2L"},
625 {"ADC Right Mux", "Input2B", "AIN2R"},
626 {"ADC Left Mux", "Input3A", "AIN3L"},
627 {"ADC Right Mux", "Input3B", "AIN3R"},
628 {"ADC Left Mux", "Input4A", "AIN4L"},
629 {"ADC Right Mux", "Input4B", "AIN4R"},
630 {"ADC Left Mux", "PGA Input Left", "PGA Left"},
631 {"ADC Right Mux", "PGA Input Right" , "PGA Right"},
632
633 {"PGA Left", "Switch", "AIN1L"},
634 {"PGA Right", "Switch", "AIN1R"},
635 {"PGA Left", "Switch", "AIN2L"},
636 {"PGA Right", "Switch", "AIN2R"},
637 {"PGA Left", "Switch", "AIN3L"},
638 {"PGA Right", "Switch", "AIN3R"},
639 {"PGA Left", "Switch", "AIN4L"},
640 {"PGA Right", "Switch", "AIN4R"},
641
642 {"PGA Left", "Switch", "PGA MICA"},
643 {"PGA MICA", NULL, "MICA"},
644
645 {"PGA Right", "Switch", "PGA MICB"},
646 {"PGA MICB", NULL, "MICB"},
647
648 {"HPOUTA", NULL, "HP Left Amp"},
649 {"HPOUTB", NULL, "HP Right Amp"},
650 {"HP Left Amp", NULL, "Bypass Left"},
651 {"HP Right Amp", NULL, "Bypass Right"},
652 {"Bypass Left", "Switch", "PGA Left"},
653 {"Bypass Right", "Switch", "PGA Right"},
654 {"HP Left Amp", "Switch", "DAC Left"},
655 {"HP Right Amp", "Switch", "DAC Right"},
656
657 {"SPKOUTA", NULL, "SPK Left Amp"},
658 {"SPKOUTB", NULL, "SPK Right Amp"},
659
660 {"SPK Left Amp", NULL, "Beep"},
661 {"SPK Right Amp", NULL, "Beep"},
662 {"SPK Left Amp", "Switch", "Playback"},
663 {"SPK Right Amp", "Switch", "Playback"},
664
665 {"DAC Left", NULL, "Beep"},
666 {"DAC Right", NULL, "Beep"},
667 {"DAC Left", NULL, "Playback"},
668 {"DAC Right", NULL, "Playback"},
669
670 {"Output Mux", "DSP", "Playback"},
671 {"Output Mux", "DSP", "Playback"},
672
673 {"AIFINL", NULL, "Playback"},
674 {"AIFINR", NULL, "Playback"},
675
676};
677
678struct cs42l52_clk_para {
679 u32 mclk;
680 u32 rate;
681 u8 speed;
682 u8 group;
683 u8 videoclk;
684 u8 ratio;
685 u8 mclkdiv2;
686};
687
688static const struct cs42l52_clk_para clk_map_table[] = {
689 /*8k*/
690 {12288000, 8000, CLK_QS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
691 {18432000, 8000, CLK_QS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
692 {12000000, 8000, CLK_QS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 0},
693 {24000000, 8000, CLK_QS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 1},
694 {27000000, 8000, CLK_QS_MODE, CLK_32K, CLK_27M_MCLK, CLK_R_125, 0},
695
696 /*11.025k*/
697 {11289600, 11025, CLK_QS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
698 {16934400, 11025, CLK_QS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
699
700 /*16k*/
701 {12288000, 16000, CLK_HS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
702 {18432000, 16000, CLK_HS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
703 {12000000, 16000, CLK_HS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 0},
704 {24000000, 16000, CLK_HS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 1},
705 {27000000, 16000, CLK_HS_MODE, CLK_32K, CLK_27M_MCLK, CLK_R_125, 1},
706
707 /*22.05k*/
708 {11289600, 22050, CLK_HS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
709 {16934400, 22050, CLK_HS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
710
711 /* 32k */
712 {12288000, 32000, CLK_SS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
713 {18432000, 32000, CLK_SS_MODE, CLK_32K, CLK_NO_27M, CLK_R_128, 0},
714 {12000000, 32000, CLK_SS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 0},
715 {24000000, 32000, CLK_SS_MODE, CLK_32K, CLK_NO_27M, CLK_R_125, 1},
716 {27000000, 32000, CLK_SS_MODE, CLK_32K, CLK_27M_MCLK, CLK_R_125, 0},
717
718 /* 44.1k */
719 {11289600, 44100, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
720 {16934400, 44100, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
721
722 /* 48k */
723 {12288000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
724 {18432000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
725 {12000000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_125, 0},
726 {24000000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_125, 1},
727 {27000000, 48000, CLK_SS_MODE, CLK_NO_32K, CLK_27M_MCLK, CLK_R_125, 1},
728
729 /* 88.2k */
730 {11289600, 88200, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
731 {16934400, 88200, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
732
733 /* 96k */
734 {12288000, 96000, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
735 {18432000, 96000, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_128, 0},
736 {12000000, 96000, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_125, 0},
737 {24000000, 96000, CLK_DS_MODE, CLK_NO_32K, CLK_NO_27M, CLK_R_125, 1},
738};
739
740static int cs42l52_get_clk(int mclk, int rate)
741{
742 int i, ret = 0;
743 u_int mclk1, mclk2 = 0;
744
745 for (i = 0; i < ARRAY_SIZE(clk_map_table); i++) {
746 if (clk_map_table[i].rate == rate) {
747 mclk1 = clk_map_table[i].mclk;
748 if (abs(mclk - mclk1) < abs(mclk - mclk2)) {
749 mclk2 = mclk1;
750 ret = i;
751 }
752 }
753 }
754 if (ret > ARRAY_SIZE(clk_map_table))
755 return -EINVAL;
756 return ret;
757}
758
759static int cs42l52_set_sysclk(struct snd_soc_dai *codec_dai,
760 int clk_id, unsigned int freq, int dir)
761{
762 struct snd_soc_codec *codec = codec_dai->codec;
763 struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
764
765 if ((freq >= CS42L52_MIN_CLK) && (freq <= CS42L52_MAX_CLK)) {
766 cs42l52->sysclk = freq;
767 } else {
768 dev_err(codec->dev, "Invalid freq paramter\n");
769 return -EINVAL;
770 }
771 return 0;
772}
773
774static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
775{
776 struct snd_soc_codec *codec = codec_dai->codec;
777 struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
778 int ret = 0;
779 u8 iface = 0;
780
781 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
782 case SND_SOC_DAIFMT_CBM_CFM:
783 iface = CS42L52_IFACE_CTL1_MASTER;
784 break;
785 case SND_SOC_DAIFMT_CBS_CFS:
786 iface = CS42L52_IFACE_CTL1_SLAVE;
787 break;
788 default:
789 return -EINVAL;
790 }
791
792 /* interface format */
793 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
794 case SND_SOC_DAIFMT_I2S:
795 iface |= CS42L52_IFACE_CTL1_ADC_FMT_I2S |
796 CS42L52_IFACE_CTL1_DAC_FMT_I2S;
797 break;
798 case SND_SOC_DAIFMT_RIGHT_J:
799 iface |= CS42L52_IFACE_CTL1_DAC_FMT_RIGHT_J;
800 break;
801 case SND_SOC_DAIFMT_LEFT_J:
802 iface |= CS42L52_IFACE_CTL1_ADC_FMT_LEFT_J |
803 CS42L52_IFACE_CTL1_DAC_FMT_LEFT_J;
804 break;
805 case SND_SOC_DAIFMT_DSP_A:
806 iface |= CS42L52_IFACE_CTL1_DSP_MODE_EN;
807 break;
808 case SND_SOC_DAIFMT_DSP_B:
809 break;
810 default:
811 return -EINVAL;
812 }
813
814 /* clock inversion */
815 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
816 case SND_SOC_DAIFMT_NB_NF:
817 break;
818 case SND_SOC_DAIFMT_IB_IF:
819 iface |= CS42L52_IFACE_CTL1_INV_SCLK;
820 break;
821 case SND_SOC_DAIFMT_IB_NF:
822 iface |= CS42L52_IFACE_CTL1_INV_SCLK;
823 break;
824 case SND_SOC_DAIFMT_NB_IF:
825 break;
826 default:
827 ret = -EINVAL;
828 }
829 cs42l52->config.format = iface;
830 snd_soc_write(codec, CS42L52_IFACE_CTL1, cs42l52->config.format);
831
832 return 0;
833}
834
835static int cs42l52_digital_mute(struct snd_soc_dai *dai, int mute)
836{
837 struct snd_soc_codec *codec = dai->codec;
838
839 if (mute)
840 snd_soc_update_bits(codec, CS42L52_PB_CTL1,
841 CS42L52_PB_CTL1_MUTE_MASK,
842 CS42L52_PB_CTL1_MUTE);
843 else
844 snd_soc_update_bits(codec, CS42L52_PB_CTL1,
845 CS42L52_PB_CTL1_MUTE_MASK,
846 CS42L52_PB_CTL1_UNMUTE);
847
848 return 0;
849}
850
851static int cs42l52_pcm_hw_params(struct snd_pcm_substream *substream,
852 struct snd_pcm_hw_params *params,
853 struct snd_soc_dai *dai)
854{
855 struct snd_soc_codec *codec = dai->codec;
856 struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
857 u32 clk = 0;
858 int index;
859
860 index = cs42l52_get_clk(cs42l52->sysclk, params_rate(params));
861 if (index >= 0) {
862 cs42l52->sysclk = clk_map_table[index].mclk;
863
864 clk |= (clk_map_table[index].speed << CLK_SPEED_SHIFT) |
865 (clk_map_table[index].group << CLK_32K_SR_SHIFT) |
866 (clk_map_table[index].videoclk << CLK_27M_MCLK_SHIFT) |
867 (clk_map_table[index].ratio << CLK_RATIO_SHIFT) |
868 clk_map_table[index].mclkdiv2;
869
870 snd_soc_write(codec, CS42L52_CLK_CTL, clk);
871 } else {
872 dev_err(codec->dev, "can't get correct mclk\n");
873 return -EINVAL;
874 }
875
876 return 0;
877}
878
879static int cs42l52_set_bias_level(struct snd_soc_codec *codec,
880 enum snd_soc_bias_level level)
881{
882 struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
883
884 switch (level) {
885 case SND_SOC_BIAS_ON:
886 break;
887 case SND_SOC_BIAS_PREPARE:
888 snd_soc_update_bits(codec, CS42L52_PWRCTL1,
889 CS42L52_PWRCTL1_PDN_CODEC, 0);
890 break;
891 case SND_SOC_BIAS_STANDBY:
892 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
893 regcache_cache_only(cs42l52->regmap, false);
894 regcache_sync(cs42l52->regmap);
895 }
896 snd_soc_write(codec, CS42L52_PWRCTL1, CS42L52_PWRCTL1_PDN_ALL);
897 break;
898 case SND_SOC_BIAS_OFF:
899 snd_soc_write(codec, CS42L52_PWRCTL1, CS42L52_PWRCTL1_PDN_ALL);
900 regcache_cache_only(cs42l52->regmap, true);
901 break;
902 }
903 codec->dapm.bias_level = level;
904
905 return 0;
906}
907
908#define CS42L52_RATES (SNDRV_PCM_RATE_8000_96000)
909
910#define CS42L52_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \
911 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_U18_3LE | \
912 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \
913 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE)
914
915static struct snd_soc_dai_ops cs42l52_ops = {
916 .hw_params = cs42l52_pcm_hw_params,
917 .digital_mute = cs42l52_digital_mute,
918 .set_fmt = cs42l52_set_fmt,
919 .set_sysclk = cs42l52_set_sysclk,
920};
921
922static struct snd_soc_dai_driver cs42l52_dai = {
923 .name = "cs42l52",
924 .playback = {
925 .stream_name = "Playback",
926 .channels_min = 1,
927 .channels_max = 2,
928 .rates = CS42L52_RATES,
929 .formats = CS42L52_FORMATS,
930 },
931 .capture = {
932 .stream_name = "Capture",
933 .channels_min = 1,
934 .channels_max = 2,
935 .rates = CS42L52_RATES,
936 .formats = CS42L52_FORMATS,
937 },
938 .ops = &cs42l52_ops,
939};
940
941static int cs42l52_suspend(struct snd_soc_codec *codec)
942{
943 cs42l52_set_bias_level(codec, SND_SOC_BIAS_OFF);
944
945 return 0;
946}
947
948static int cs42l52_resume(struct snd_soc_codec *codec)
949{
950 cs42l52_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
951
952 return 0;
953}
954
955#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
956static int beep_rates[] = {
957 261, 522, 585, 667, 706, 774, 889, 1000,
958 1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182
959};
960
961static void cs42l52_beep_work(struct work_struct *work)
962{
963 struct cs42l52_private *cs42l52 =
964 container_of(work, struct cs42l52_private, beep_work);
965 struct snd_soc_codec *codec = cs42l52->codec;
966 struct snd_soc_dapm_context *dapm = &codec->dapm;
967 int i;
968 int val = 0;
969 int best = 0;
970
971 if (cs42l52->beep_rate) {
972 for (i = 0; i < ARRAY_SIZE(beep_rates); i++) {
973 if (abs(cs42l52->beep_rate - beep_rates[i]) <
974 abs(cs42l52->beep_rate - beep_rates[best]))
975 best = i;
976 }
977
978 dev_dbg(codec->dev, "Set beep rate %dHz for requested %dHz\n",
979 beep_rates[best], cs42l52->beep_rate);
980
981 val = (best << CS42L52_BEEP_RATE_SHIFT);
982
983 snd_soc_dapm_enable_pin(dapm, "Beep");
984 } else {
985 dev_dbg(codec->dev, "Disabling beep\n");
986 snd_soc_dapm_disable_pin(dapm, "Beep");
987 }
988
989 snd_soc_update_bits(codec, CS42L52_BEEP_FREQ,
990 CS42L52_BEEP_RATE_MASK, val);
991
992 snd_soc_dapm_sync(dapm);
993}
994
995/* For usability define a way of injecting beep events for the device -
996 * many systems will not have a keyboard.
997 */
998static int cs42l52_beep_event(struct input_dev *dev, unsigned int type,
999 unsigned int code, int hz)
1000{
1001 struct snd_soc_codec *codec = input_get_drvdata(dev);
1002 struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
1003
1004 dev_dbg(codec->dev, "Beep event %x %x\n", code, hz);
1005
1006 switch (code) {
1007 case SND_BELL:
1008 if (hz)
1009 hz = 261;
1010 case SND_TONE:
1011 break;
1012 default:
1013 return -1;
1014 }
1015
1016 /* Kick the beep from a workqueue */
1017 cs42l52->beep_rate = hz;
1018 schedule_work(&cs42l52->beep_work);
1019 return 0;
1020}
1021
1022static ssize_t cs42l52_beep_set(struct device *dev,
1023 struct device_attribute *attr,
1024 const char *buf, size_t count)
1025{
1026 struct cs42l52_private *cs42l52 = dev_get_drvdata(dev);
1027 long int time;
1028 int ret;
1029
1030 ret = kstrtol(buf, 10, &time);
1031 if (ret != 0)
1032 return ret;
1033
1034 input_event(cs42l52->beep, EV_SND, SND_TONE, time);
1035
1036 return count;
1037}
1038
1039static DEVICE_ATTR(beep, 0200, NULL, cs42l52_beep_set);
1040
1041static void cs42l52_init_beep(struct snd_soc_codec *codec)
1042{
1043 struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
1044 int ret;
1045
1046 cs42l52->beep = input_allocate_device();
1047 if (!cs42l52->beep) {
1048 dev_err(codec->dev, "Failed to allocate beep device\n");
1049 return;
1050 }
1051
1052 INIT_WORK(&cs42l52->beep_work, cs42l52_beep_work);
1053 cs42l52->beep_rate = 0;
1054
1055 cs42l52->beep->name = "CS42L52 Beep Generator";
1056 cs42l52->beep->phys = dev_name(codec->dev);
1057 cs42l52->beep->id.bustype = BUS_I2C;
1058
1059 cs42l52->beep->evbit[0] = BIT_MASK(EV_SND);
1060 cs42l52->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
1061 cs42l52->beep->event = cs42l52_beep_event;
1062 cs42l52->beep->dev.parent = codec->dev;
1063 input_set_drvdata(cs42l52->beep, codec);
1064
1065 ret = input_register_device(cs42l52->beep);
1066 if (ret != 0) {
1067 input_free_device(cs42l52->beep);
1068 cs42l52->beep = NULL;
1069 dev_err(codec->dev, "Failed to register beep device\n");
1070 }
1071
1072 ret = device_create_file(codec->dev, &dev_attr_beep);
1073 if (ret != 0) {
1074 dev_err(codec->dev, "Failed to create keyclick file: %d\n",
1075 ret);
1076 }
1077}
1078
1079static void cs42l52_free_beep(struct snd_soc_codec *codec)
1080{
1081 struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
1082
1083 device_remove_file(codec->dev, &dev_attr_beep);
1084 input_unregister_device(cs42l52->beep);
1085 cancel_work_sync(&cs42l52->beep_work);
1086 cs42l52->beep = NULL;
1087
1088 snd_soc_update_bits(codec, CS42L52_BEEP_TONE_CTL,
1089 CS42L52_BEEP_EN_MASK, 0);
1090}
1091#else
1092static void cs42l52_init_beep(struct snd_soc_codec *codec)
1093{
1094}
1095
1096static void cs42l52_free_beep(struct snd_soc_codec *codec)
1097{
1098}
1099#endif
1100
1101static int cs42l52_probe(struct snd_soc_codec *codec)
1102{
1103 struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec);
1104 int ret;
1105
1106 codec->control_data = cs42l52->regmap;
1107 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
1108 if (ret < 0) {
1109 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1110 return ret;
1111 }
1112 regcache_cache_only(cs42l52->regmap, true);
1113
1114 cs42l52_init_beep(codec);
1115
1116 cs42l52_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1117
1118 cs42l52->sysclk = CS42L52_DEFAULT_CLK;
1119 cs42l52->config.format = CS42L52_DEFAULT_FORMAT;
1120
1121 /* Set Platform MICx CFG */
1122 snd_soc_update_bits(codec, CS42L52_MICA_CTL,
1123 CS42L52_MIC_CTL_TYPE_MASK,
1124 cs42l52->pdata.mica_cfg <<
1125 CS42L52_MIC_CTL_TYPE_SHIFT);
1126
1127 snd_soc_update_bits(codec, CS42L52_MICB_CTL,
1128 CS42L52_MIC_CTL_TYPE_MASK,
1129 cs42l52->pdata.micb_cfg <<
1130 CS42L52_MIC_CTL_TYPE_SHIFT);
1131
1132 /* if Single Ended, Get Mic_Select */
1133 if (cs42l52->pdata.mica_cfg)
1134 snd_soc_update_bits(codec, CS42L52_MICA_CTL,
1135 CS42L52_MIC_CTL_MIC_SEL_MASK,
1136 cs42l52->pdata.mica_sel <<
1137 CS42L52_MIC_CTL_MIC_SEL_SHIFT);
1138 if (cs42l52->pdata.micb_cfg)
1139 snd_soc_update_bits(codec, CS42L52_MICB_CTL,
1140 CS42L52_MIC_CTL_MIC_SEL_MASK,
1141 cs42l52->pdata.micb_sel <<
1142 CS42L52_MIC_CTL_MIC_SEL_SHIFT);
1143
1144 /* Set Platform Charge Pump Freq */
1145 snd_soc_update_bits(codec, CS42L52_CHARGE_PUMP,
1146 CS42L52_CHARGE_PUMP_MASK,
1147 cs42l52->pdata.chgfreq <<
1148 CS42L52_CHARGE_PUMP_SHIFT);
1149
1150 /* Set Platform Bias Level */
1151 snd_soc_update_bits(codec, CS42L52_IFACE_CTL2,
1152 CS42L52_IFACE_CTL2_BIAS_LVL,
1153 cs42l52->pdata.micbias_lvl);
1154
1155 return ret;
1156}
1157
1158static int cs42l52_remove(struct snd_soc_codec *codec)
1159{
1160 cs42l52_free_beep(codec);
1161 cs42l52_set_bias_level(codec, SND_SOC_BIAS_OFF);
1162
1163 return 0;
1164}
1165
1166static struct snd_soc_codec_driver soc_codec_dev_cs42l52 = {
1167 .probe = cs42l52_probe,
1168 .remove = cs42l52_remove,
1169 .suspend = cs42l52_suspend,
1170 .resume = cs42l52_resume,
1171 .set_bias_level = cs42l52_set_bias_level,
1172
1173 .dapm_widgets = cs42l52_dapm_widgets,
1174 .num_dapm_widgets = ARRAY_SIZE(cs42l52_dapm_widgets),
1175 .dapm_routes = cs42l52_audio_map,
1176 .num_dapm_routes = ARRAY_SIZE(cs42l52_audio_map),
1177
1178 .controls = cs42l52_snd_controls,
1179 .num_controls = ARRAY_SIZE(cs42l52_snd_controls),
1180};
1181
1182/* Current and threshold powerup sequence Pg37 */
1183static const struct reg_default cs42l52_threshold_patch[] = {
1184
1185 { 0x00, 0x99 },
1186 { 0x3E, 0xBA },
1187 { 0x47, 0x80 },
1188 { 0x32, 0xBB },
1189 { 0x32, 0x3B },
1190 { 0x00, 0x00 },
1191
1192};
1193
1194static struct regmap_config cs42l52_regmap = {
1195 .reg_bits = 8,
1196 .val_bits = 8,
1197
1198 .max_register = CS42L52_MAX_REGISTER,
1199 .reg_defaults = cs42l52_reg_defaults,
1200 .num_reg_defaults = ARRAY_SIZE(cs42l52_reg_defaults),
1201 .readable_reg = cs42l52_readable_register,
1202 .volatile_reg = cs42l52_volatile_register,
1203 .cache_type = REGCACHE_RBTREE,
1204};
1205
1206static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
1207 const struct i2c_device_id *id)
1208{
1209 struct cs42l52_private *cs42l52;
1210 int ret;
1211 unsigned int devid = 0;
1212 unsigned int reg;
1213
1214 cs42l52 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l52_private),
1215 GFP_KERNEL);
1216 if (cs42l52 == NULL)
1217 return -ENOMEM;
1218 cs42l52->dev = &i2c_client->dev;
1219
1220 cs42l52->regmap = regmap_init_i2c(i2c_client, &cs42l52_regmap);
1221 if (IS_ERR(cs42l52->regmap)) {
1222 ret = PTR_ERR(cs42l52->regmap);
1223 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
1224 goto err;
1225 }
1226
1227 i2c_set_clientdata(i2c_client, cs42l52);
1228
1229 if (dev_get_platdata(&i2c_client->dev))
1230 memcpy(&cs42l52->pdata, dev_get_platdata(&i2c_client->dev),
1231 sizeof(cs42l52->pdata));
1232
1233 ret = regmap_register_patch(cs42l52->regmap, cs42l52_threshold_patch,
1234 ARRAY_SIZE(cs42l52_threshold_patch));
1235 if (ret != 0)
1236 dev_warn(cs42l52->dev, "Failed to apply regmap patch: %d\n",
1237 ret);
1238
1239 ret = regmap_read(cs42l52->regmap, CS42L52_CHIP, &reg);
1240 devid = reg & CS42L52_CHIP_ID_MASK;
1241 if (devid != CS42L52_CHIP_ID) {
1242 ret = -ENODEV;
1243 dev_err(&i2c_client->dev,
1244 "CS42L52 Device ID (%X). Expected %X\n",
1245 devid, CS42L52_CHIP_ID);
1246 goto err_regmap;
1247 }
1248
1249 regcache_cache_only(cs42l52->regmap, true);
1250
1251 ret = snd_soc_register_codec(&i2c_client->dev,
1252 &soc_codec_dev_cs42l52, &cs42l52_dai, 1);
1253 if (ret < 0)
1254 goto err_regmap;
1255 return 0;
1256
1257err_regmap:
1258 regmap_exit(cs42l52->regmap);
1259
1260err:
1261 return ret;
1262}
1263
1264static int cs42l52_i2c_remove(struct i2c_client *client)
1265{
1266 struct cs42l52_private *cs42l52 = i2c_get_clientdata(client);
1267
1268 snd_soc_unregister_codec(&client->dev);
1269 regmap_exit(cs42l52->regmap);
1270
1271 return 0;
1272}
1273
1274static const struct i2c_device_id cs42l52_id[] = {
1275 { "cs42l52", 0 },
1276 { }
1277};
1278MODULE_DEVICE_TABLE(i2c, cs42l52_id);
1279
1280static struct i2c_driver cs42l52_i2c_driver = {
1281 .driver = {
1282 .name = "cs42l52",
1283 .owner = THIS_MODULE,
1284 },
1285 .id_table = cs42l52_id,
1286 .probe = cs42l52_i2c_probe,
1287 .remove = __devexit_p(cs42l52_i2c_remove),
1288};
1289
1290module_i2c_driver(cs42l52_i2c_driver);
1291
1292MODULE_DESCRIPTION("ASoC CS42L52 driver");
1293MODULE_AUTHOR("Georgi Vlaev, Nucleus Systems Ltd, <joe@nucleusys.com>");
1294MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
1295MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs42l52.h b/sound/soc/codecs/cs42l52.h
new file mode 100644
index 000000000000..60985c059071
--- /dev/null
+++ b/sound/soc/codecs/cs42l52.h
@@ -0,0 +1,274 @@
1/*
2 * cs42l52.h -- CS42L52 ALSA SoC audio driver
3 *
4 * Copyright 2012 CirrusLogic, Inc.
5 *
6 * Author: Georgi Vlaev <joe@nucleusys.com>
7 * Author: Brian Austin <brian.austin@cirrus.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#ifndef __CS42L52_H__
16#define __CS42L52_H__
17
18#define CS42L52_NAME "CS42L52"
19#define CS42L52_DEFAULT_CLK 12000000
20#define CS42L52_MIN_CLK 11000000
21#define CS42L52_MAX_CLK 27000000
22#define CS42L52_DEFAULT_FORMAT SNDRV_PCM_FMTBIT_S16_LE
23#define CS42L52_DEFAULT_MAX_CHANS 2
24#define CS42L52_SYSCLK 1
25
26#define CS42L52_CHIP_SWICTH (1 << 17)
27#define CS42L52_ALL_IN_ONE (1 << 16)
28#define CS42L52_CHIP_ONE 0x00
29#define CS42L52_CHIP_TWO 0x01
30#define CS42L52_CHIP_THR 0x02
31#define CS42L52_CHIP_MASK 0x0f
32
33#define CS42L52_FIX_BITS_CTL 0x00
34#define CS42L52_CHIP 0x01
35#define CS42L52_CHIP_ID 0xE0
36#define CS42L52_CHIP_ID_MASK 0xF8
37#define CS42L52_CHIP_REV_A0 0x00
38#define CS42L52_CHIP_REV_A1 0x01
39#define CS42L52_CHIP_REV_B0 0x02
40#define CS42L52_CHIP_REV_MASK 0x03
41
42#define CS42L52_PWRCTL1 0x02
43#define CS42L52_PWRCTL1_PDN_ALL 0x9F
44#define CS42L52_PWRCTL1_PDN_CHRG 0x80
45#define CS42L52_PWRCTL1_PDN_PGAB 0x10
46#define CS42L52_PWRCTL1_PDN_PGAA 0x08
47#define CS42L52_PWRCTL1_PDN_ADCB 0x04
48#define CS42L52_PWRCTL1_PDN_ADCA 0x02
49#define CS42L52_PWRCTL1_PDN_CODEC 0x01
50
51#define CS42L52_PWRCTL2 0x03
52#define CS42L52_PWRCTL2_OVRDB (1 << 4)
53#define CS42L52_PWRCTL2_OVRDA (1 << 3)
54#define CS42L52_PWRCTL2_PDN_MICB (1 << 2)
55#define CS42L52_PWRCTL2_PDN_MICB_SHIFT 2
56#define CS42L52_PWRCTL2_PDN_MICA (1 << 1)
57#define CS42L52_PWRCTL2_PDN_MICA_SHIFT 1
58#define CS42L52_PWRCTL2_PDN_MICBIAS (1 << 0)
59#define CS42L52_PWRCTL2_PDN_MICBIAS_SHIFT 0
60
61#define CS42L52_PWRCTL3 0x04
62#define CS42L52_PWRCTL3_HPB_PDN_SHIFT 6
63#define CS42L52_PWRCTL3_HPB_ON_LOW 0x00
64#define CS42L52_PWRCTL3_HPB_ON_HIGH 0x01
65#define CS42L52_PWRCTL3_HPB_ALWAYS_ON 0x02
66#define CS42L52_PWRCTL3_HPB_ALWAYS_OFF 0x03
67#define CS42L52_PWRCTL3_HPA_PDN_SHIFT 4
68#define CS42L52_PWRCTL3_HPA_ON_LOW 0x00
69#define CS42L52_PWRCTL3_HPA_ON_HIGH 0x01
70#define CS42L52_PWRCTL3_HPA_ALWAYS_ON 0x02
71#define CS42L52_PWRCTL3_HPA_ALWAYS_OFF 0x03
72#define CS42L52_PWRCTL3_SPKB_PDN_SHIFT 2
73#define CS42L52_PWRCTL3_SPKB_ON_LOW 0x00
74#define CS42L52_PWRCTL3_SPKB_ON_HIGH 0x01
75#define CS42L52_PWRCTL3_SPKB_ALWAYS_ON 0x02
76#define CS42L52_PWRCTL3_PDN_SPKB (1 << 2)
77#define CS42L52_PWRCTL3_PDN_SPKA (1 << 0)
78#define CS42L52_PWRCTL3_SPKA_PDN_SHIFT 0
79#define CS42L52_PWRCTL3_SPKA_ON_LOW 0x00
80#define CS42L52_PWRCTL3_SPKA_ON_HIGH 0x01
81#define CS42L52_PWRCTL3_SPKA_ALWAYS_ON 0x02
82
83#define CS42L52_DEFAULT_OUTPUT_STATE 0x05
84#define CS42L52_PWRCTL3_CONF_MASK 0x03
85
86#define CS42L52_CLK_CTL 0x05
87#define CLK_AUTODECT_ENABLE (1 << 7)
88#define CLK_SPEED_SHIFT 5
89#define CLK_DS_MODE 0x00
90#define CLK_SS_MODE 0x01
91#define CLK_HS_MODE 0x02
92#define CLK_QS_MODE 0x03
93#define CLK_32K_SR_SHIFT 4
94#define CLK_32K 0x01
95#define CLK_NO_32K 0x00
96#define CLK_27M_MCLK_SHIFT 3
97#define CLK_27M_MCLK 0x01
98#define CLK_NO_27M 0x00
99#define CLK_RATIO_SHIFT 1
100#define CLK_R_128 0x00
101#define CLK_R_125 0x01
102#define CLK_R_132 0x02
103#define CLK_R_136 0x03
104
105#define CS42L52_IFACE_CTL1 0x06
106#define CS42L52_IFACE_CTL1_MASTER (1 << 7)
107#define CS42L52_IFACE_CTL1_SLAVE (0 << 7)
108#define CS42L52_IFACE_CTL1_INV_SCLK (1 << 6)
109#define CS42L52_IFACE_CTL1_ADC_FMT_I2S (1 << 5)
110#define CS42L52_IFACE_CTL1_ADC_FMT_LEFT_J (0 << 5)
111#define CS42L52_IFACE_CTL1_DSP_MODE_EN (1 << 4)
112#define CS42L52_IFACE_CTL1_DAC_FMT_LEFT_J (0 << 2)
113#define CS42L52_IFACE_CTL1_DAC_FMT_I2S (1 << 2)
114#define CS42L52_IFACE_CTL1_DAC_FMT_RIGHT_J (2 << 2)
115#define CS42L52_IFACE_CTL1_WL_32BIT (0x00)
116#define CS42L52_IFACE_CTL1_WL_24BIT (0x01)
117#define CS42L52_IFACE_CTL1_WL_20BIT (0x02)
118#define CS42L52_IFACE_CTL1_WL_16BIT (0x03)
119#define CS42L52_IFACE_CTL1_WL_MASK 0xFFFF
120
121#define CS42L52_IFACE_CTL2 0x07
122#define CS42L52_IFACE_CTL2_SC_MC_EQ (1 << 6)
123#define CS42L52_IFACE_CTL2_LOOPBACK (1 << 5)
124#define CS42L52_IFACE_CTL2_S_MODE_OUTPUT_EN (0 << 4)
125#define CS42L52_IFACE_CTL2_S_MODE_OUTPUT_HIZ (1 << 4)
126#define CS42L52_IFACE_CTL2_HP_SW_INV (1 << 3)
127#define CS42L52_IFACE_CTL2_BIAS_LVL 0x07
128
129#define CS42L52_ADC_PGA_A 0x08
130#define CS42L52_ADC_PGA_B 0x09
131#define CS42L52_ADC_SEL_SHIFT 5
132#define CS42L52_ADC_SEL_AIN1 0x00
133#define CS42L52_ADC_SEL_AIN2 0x01
134#define CS42L52_ADC_SEL_AIN3 0x02
135#define CS42L52_ADC_SEL_AIN4 0x03
136#define CS42L52_ADC_SEL_PGA 0x04
137
138#define CS42L52_ANALOG_HPF_CTL 0x0A
139#define CS42L52_HPF_CTL_ANLGSFTB (1 << 3)
140#define CS42L52_HPF_CTL_ANLGSFTA (1 << 0)
141
142#define CS42L52_ADC_HPF_FREQ 0x0B
143#define CS42L52_ADC_MISC_CTL 0x0C
144#define CS42L52_ADC_MISC_CTL_SOURCE_DSP (1 << 6)
145
146#define CS42L52_PB_CTL1 0x0D
147#define CS42L52_PB_CTL1_HP_GAIN_SHIFT 5
148#define CS42L52_PB_CTL1_HP_GAIN_03959 0x00
149#define CS42L52_PB_CTL1_HP_GAIN_04571 0x01
150#define CS42L52_PB_CTL1_HP_GAIN_05111 0x02
151#define CS42L52_PB_CTL1_HP_GAIN_06047 0x03
152#define CS42L52_PB_CTL1_HP_GAIN_07099 0x04
153#define CS42L52_PB_CTL1_HP_GAIN_08399 0x05
154#define CS42L52_PB_CTL1_HP_GAIN_10000 0x06
155#define CS42L52_PB_CTL1_HP_GAIN_11430 0x07
156#define CS42L52_PB_CTL1_INV_PCMB (1 << 3)
157#define CS42L52_PB_CTL1_INV_PCMA (1 << 2)
158#define CS42L52_PB_CTL1_MSTB_MUTE (1 << 1)
159#define CS42L52_PB_CTL1_MSTA_MUTE (1 << 0)
160#define CS42L52_PB_CTL1_MUTE_MASK 0xFFFD
161#define CS42L52_PB_CTL1_MUTE 3
162#define CS42L52_PB_CTL1_UNMUTE 0
163
164#define CS42L52_MISC_CTL 0x0E
165#define CS42L52_MISC_CTL_DEEMPH (1 << 2)
166#define CS42L52_MISC_CTL_DIGSFT (1 << 1)
167#define CS42L52_MISC_CTL_DIGZC (1 << 0)
168
169#define CS42L52_PB_CTL2 0x0F
170#define CS42L52_PB_CTL2_HPB_MUTE (1 << 7)
171#define CS42L52_PB_CTL2_HPA_MUTE (1 << 6)
172#define CS42L52_PB_CTL2_SPKB_MUTE (1 << 5)
173#define CS42L52_PB_CTL2_SPKA_MUTE (1 << 4)
174#define CS42L52_PB_CTL2_SPK_SWAP (1 << 2)
175#define CS42L52_PB_CTL2_SPK_MONO (1 << 1)
176#define CS42L52_PB_CTL2_SPK_MUTE50 (1 << 0)
177
178#define CS42L52_MICA_CTL 0x10
179#define CS42L52_MICB_CTL 0x11
180#define CS42L52_MIC_CTL_MIC_SEL_MASK 0xBF
181#define CS42L52_MIC_CTL_MIC_SEL_SHIFT 6
182#define CS42L52_MIC_CTL_TYPE_MASK 0xDF
183#define CS42L52_MIC_CTL_TYPE_SHIFT 5
184
185
186#define CS42L52_PGAA_CTL 0x12
187#define CS42L52_PGAB_CTL 0x13
188#define CS42L52_PGAX_CTL_VOL_12DB 24
189#define CS42L52_PGAX_CTL_VOL_6DB 12 /*step size 0.5db*/
190
191#define CS42L52_PASSTHRUA_VOL 0x14
192#define CS42L52_PASSTHRUB_VOL 0x15
193
194#define CS42L52_ADCA_VOL 0x16
195#define CS42L52_ADCB_VOL 0x17
196#define CS42L52_ADCX_VOL_24DB 24 /*step size 1db*/
197#define CS42L52_ADCX_VOL_12DB 12
198#define CS42L52_ADCX_VOL_6DB 6
199
200#define CS42L52_ADCA_MIXER_VOL 0x18
201#define CS42L52_ADCB_MIXER_VOL 0x19
202#define CS42L52_ADC_MIXER_VOL_12DB 0x18
203
204#define CS42L52_PCMA_MIXER_VOL 0x1A
205#define CS42L52_PCMB_MIXER_VOL 0x1B
206
207#define CS42L52_BEEP_FREQ 0x1C
208#define CS42L52_BEEP_VOL 0x1D
209#define CS42L52_BEEP_TONE_CTL 0x1E
210#define CS42L52_BEEP_RATE_SHIFT 4
211#define CS42L52_BEEP_RATE_MASK 0x0F
212
213#define CS42L52_TONE_CTL 0x1F
214#define CS42L52_BEEP_EN_MASK 0x3F
215
216#define CS42L52_MASTERA_VOL 0x20
217#define CS42L52_MASTERB_VOL 0x21
218
219#define CS42L52_HPA_VOL 0x22
220#define CS42L52_HPB_VOL 0x23
221#define CS42L52_DEFAULT_HP_VOL 0xF0
222
223#define CS42L52_SPKA_VOL 0x24
224#define CS42L52_SPKB_VOL 0x25
225#define CS42L52_DEFAULT_SPK_VOL 0xF0
226
227#define CS42L52_ADC_PCM_MIXER 0x26
228
229#define CS42L52_LIMITER_CTL1 0x27
230#define CS42L52_LIMITER_CTL2 0x28
231#define CS42L52_LIMITER_AT_RATE 0x29
232
233#define CS42L52_ALC_CTL 0x2A
234#define CS42L52_ALC_CTL_ALCB_ENABLE_SHIFT 7
235#define CS42L52_ALC_CTL_ALCA_ENABLE_SHIFT 6
236#define CS42L52_ALC_CTL_FASTEST_ATTACK 0
237
238#define CS42L52_ALC_RATE 0x2B
239#define CS42L52_ALC_SLOWEST_RELEASE 0x3F
240
241#define CS42L52_ALC_THRESHOLD 0x2C
242#define CS42L52_ALC_MAX_RATE_SHIFT 5
243#define CS42L52_ALC_MIN_RATE_SHIFT 2
244#define CS42L52_ALC_RATE_0DB 0
245#define CS42L52_ALC_RATE_3DB 1
246#define CS42L52_ALC_RATE_6DB 2
247
248#define CS42L52_NOISE_GATE_CTL 0x2D
249#define CS42L52_NG_ENABLE_SHIFT 6
250#define CS42L52_NG_THRESHOLD_SHIFT 2
251#define CS42L52_NG_MIN_70DB 2
252#define CS42L52_NG_DELAY_SHIFT 0
253#define CS42L52_NG_DELAY_100MS 1
254
255#define CS42L52_CLK_STATUS 0x2E
256#define CS42L52_BATT_COMPEN 0x2F
257
258#define CS42L52_BATT_LEVEL 0x30
259#define CS42L52_SPK_STATUS 0x31
260#define CS42L52_SPK_STATUS_PIN_SHIFT 3
261#define CS42L52_SPK_STATUS_PIN_HIGH 1
262
263#define CS42L52_TEM_CTL 0x32
264#define CS42L52_TEM_CTL_SET 0x80
265#define CS42L52_THE_FOLDBACK 0x33
266#define CS42L52_CHARGE_PUMP 0x34
267#define CS42L52_CHARGE_PUMP_MASK 0xF0
268#define CS42L52_CHARGE_PUMP_SHIFT 4
269#define CS42L52_FIX_BITS1 0x3E
270#define CS42L52_FIX_BITS2 0x47
271
272#define CS42L52_MAX_REGISTER 0x34
273
274#endif
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
index 3686417f5ea5..e0d45fdaa750 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -43,9 +43,6 @@ struct cs42l73_private {
43}; 43};
44 44
45static const struct reg_default cs42l73_reg_defaults[] = { 45static const struct reg_default cs42l73_reg_defaults[] = {
46 { 1, 0x42 }, /* r01 - Device ID A&B */
47 { 2, 0xA7 }, /* r02 - Device ID C&D */
48 { 3, 0x30 }, /* r03 - Device ID E */
49 { 6, 0xF1 }, /* r06 - Power Ctl 1 */ 46 { 6, 0xF1 }, /* r06 - Power Ctl 1 */
50 { 7, 0xDF }, /* r07 - Power Ctl 2 */ 47 { 7, 0xDF }, /* r07 - Power Ctl 2 */
51 { 8, 0x3F }, /* r08 - Power Ctl 3 */ 48 { 8, 0x3F }, /* r08 - Power Ctl 3 */
@@ -402,37 +399,37 @@ static const struct snd_kcontrol_new ear_amp_ctl =
402 399
403static const struct snd_kcontrol_new cs42l73_snd_controls[] = { 400static const struct snd_kcontrol_new cs42l73_snd_controls[] = {
404 SOC_DOUBLE_R_SX_TLV("Headphone Analog Playback Volume", 401 SOC_DOUBLE_R_SX_TLV("Headphone Analog Playback Volume",
405 CS42L73_HPAAVOL, CS42L73_HPBAVOL, 7, 402 CS42L73_HPAAVOL, CS42L73_HPBAVOL, 0,
406 0xffffffC1, 0x0C, hpaloa_tlv), 403 0x41, 0x4B, hpaloa_tlv),
407 404
408 SOC_DOUBLE_R_SX_TLV("LineOut Analog Playback Volume", CS42L73_LOAAVOL, 405 SOC_DOUBLE_R_SX_TLV("LineOut Analog Playback Volume", CS42L73_LOAAVOL,
409 CS42L73_LOBAVOL, 7, 0xffffffC1, 0x0C, hpaloa_tlv), 406 CS42L73_LOBAVOL, 0, 0x41, 0x4B, hpaloa_tlv),
410 407
411 SOC_DOUBLE_R_SX_TLV("Input PGA Analog Volume", CS42L73_MICAPREPGAAVOL, 408 SOC_DOUBLE_R_SX_TLV("Input PGA Analog Volume", CS42L73_MICAPREPGAAVOL,
412 CS42L73_MICBPREPGABVOL, 5, 0xffffff35, 409 CS42L73_MICBPREPGABVOL, 5, 0x34,
413 0x34, micpga_tlv), 410 0x24, micpga_tlv),
414 411
415 SOC_DOUBLE_R("MIC Preamp Switch", CS42L73_MICAPREPGAAVOL, 412 SOC_DOUBLE_R("MIC Preamp Switch", CS42L73_MICAPREPGAAVOL,
416 CS42L73_MICBPREPGABVOL, 6, 1, 1), 413 CS42L73_MICBPREPGABVOL, 6, 1, 1),
417 414
418 SOC_DOUBLE_R_SX_TLV("Input Path Digital Volume", CS42L73_IPADVOL, 415 SOC_DOUBLE_R_SX_TLV("Input Path Digital Volume", CS42L73_IPADVOL,
419 CS42L73_IPBDVOL, 7, 0xffffffA0, 0xA0, ipd_tlv), 416 CS42L73_IPBDVOL, 0, 0xA0, 0x6C, ipd_tlv),
420 417
421 SOC_DOUBLE_R_SX_TLV("HL Digital Playback Volume", 418 SOC_DOUBLE_R_SX_TLV("HL Digital Playback Volume",
422 CS42L73_HLADVOL, CS42L73_HLBDVOL, 7, 0xffffffE5, 419 CS42L73_HLADVOL, CS42L73_HLBDVOL,
423 0xE4, hl_tlv), 420 0, 0x34, 0xE4, hl_tlv),
424 421
425 SOC_SINGLE_TLV("ADC A Boost Volume", 422 SOC_SINGLE_TLV("ADC A Boost Volume",
426 CS42L73_ADCIPC, 2, 0x01, 1, adc_boost_tlv), 423 CS42L73_ADCIPC, 2, 0x01, 1, adc_boost_tlv),
427 424
428 SOC_SINGLE_TLV("ADC B Boost Volume", 425 SOC_SINGLE_TLV("ADC B Boost Volume",
429 CS42L73_ADCIPC, 6, 0x01, 1, adc_boost_tlv), 426 CS42L73_ADCIPC, 6, 0x01, 1, adc_boost_tlv),
430 427
431 SOC_SINGLE_TLV("Speakerphone Digital Playback Volume", 428 SOC_SINGLE_SX_TLV("Speakerphone Digital Volume",
432 CS42L73_SPKDVOL, 0, 0xE4, 1, hl_tlv), 429 CS42L73_SPKDVOL, 0, 0x34, 0xE4, hl_tlv),
433 430
434 SOC_SINGLE_TLV("Ear Speaker Digital Playback Volume", 431 SOC_SINGLE_SX_TLV("Ear Speaker Digital Volume",
435 CS42L73_ESLDVOL, 0, 0xE4, 1, hl_tlv), 432 CS42L73_ESLDVOL, 0, 0x34, 0xE4, hl_tlv),
436 433
437 SOC_DOUBLE_R("Headphone Analog Playback Switch", CS42L73_HPAAVOL, 434 SOC_DOUBLE_R("Headphone Analog Playback Switch", CS42L73_HPAAVOL,
438 CS42L73_HPBAVOL, 7, 1, 1), 435 CS42L73_HPBAVOL, 7, 1, 1),
@@ -599,17 +596,17 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
599 SND_SOC_DAPM_INPUT("MIC2"), 596 SND_SOC_DAPM_INPUT("MIC2"),
600 SND_SOC_DAPM_SUPPLY("MIC2 Bias", CS42L73_PWRCTL2, 7, 1, NULL, 0), 597 SND_SOC_DAPM_SUPPLY("MIC2 Bias", CS42L73_PWRCTL2, 7, 1, NULL, 0),
601 598
602 SND_SOC_DAPM_AIF_OUT("XSPOUTL", "XSP Capture", 0, 599 SND_SOC_DAPM_AIF_OUT("XSPOUTL", NULL, 0,
603 CS42L73_PWRCTL2, 1, 1), 600 CS42L73_PWRCTL2, 1, 1),
604 SND_SOC_DAPM_AIF_OUT("XSPOUTR", "XSP Capture", 0, 601 SND_SOC_DAPM_AIF_OUT("XSPOUTR", NULL, 0,
605 CS42L73_PWRCTL2, 1, 1), 602 CS42L73_PWRCTL2, 1, 1),
606 SND_SOC_DAPM_AIF_OUT("ASPOUTL", "ASP Capture", 0, 603 SND_SOC_DAPM_AIF_OUT("ASPOUTL", NULL, 0,
607 CS42L73_PWRCTL2, 3, 1), 604 CS42L73_PWRCTL2, 3, 1),
608 SND_SOC_DAPM_AIF_OUT("ASPOUTR", "ASP Capture", 0, 605 SND_SOC_DAPM_AIF_OUT("ASPOUTR", NULL, 0,
609 CS42L73_PWRCTL2, 3, 1), 606 CS42L73_PWRCTL2, 3, 1),
610 SND_SOC_DAPM_AIF_OUT("VSPOUTL", "VSP Capture", 0, 607 SND_SOC_DAPM_AIF_OUT("VSPOUTL", NULL, 0,
611 CS42L73_PWRCTL2, 4, 1), 608 CS42L73_PWRCTL2, 4, 1),
612 SND_SOC_DAPM_AIF_OUT("VSPOUTR", "VSP Capture", 0, 609 SND_SOC_DAPM_AIF_OUT("VSPOUTR", NULL, 0,
613 CS42L73_PWRCTL2, 4, 1), 610 CS42L73_PWRCTL2, 4, 1),
614 611
615 SND_SOC_DAPM_PGA("PGA Left", SND_SOC_NOPM, 0, 0, NULL, 0), 612 SND_SOC_DAPM_PGA("PGA Left", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -638,21 +635,21 @@ static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = {
638 SND_SOC_DAPM_MIXER("VSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 635 SND_SOC_DAPM_MIXER("VSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
639 SND_SOC_DAPM_MIXER("VSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 636 SND_SOC_DAPM_MIXER("VSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
640 637
641 SND_SOC_DAPM_AIF_IN("XSPINL", "XSP Playback", 0, 638 SND_SOC_DAPM_AIF_IN("XSPINL", NULL, 0,
642 CS42L73_PWRCTL2, 0, 1), 639 CS42L73_PWRCTL2, 0, 1),
643 SND_SOC_DAPM_AIF_IN("XSPINR", "XSP Playback", 0, 640 SND_SOC_DAPM_AIF_IN("XSPINR", NULL, 0,
644 CS42L73_PWRCTL2, 0, 1), 641 CS42L73_PWRCTL2, 0, 1),
645 SND_SOC_DAPM_AIF_IN("XSPINM", "XSP Playback", 0, 642 SND_SOC_DAPM_AIF_IN("XSPINM", NULL, 0,
646 CS42L73_PWRCTL2, 0, 1), 643 CS42L73_PWRCTL2, 0, 1),
647 644
648 SND_SOC_DAPM_AIF_IN("ASPINL", "ASP Playback", 0, 645 SND_SOC_DAPM_AIF_IN("ASPINL", NULL, 0,
649 CS42L73_PWRCTL2, 2, 1), 646 CS42L73_PWRCTL2, 2, 1),
650 SND_SOC_DAPM_AIF_IN("ASPINR", "ASP Playback", 0, 647 SND_SOC_DAPM_AIF_IN("ASPINR", NULL, 0,
651 CS42L73_PWRCTL2, 2, 1), 648 CS42L73_PWRCTL2, 2, 1),
652 SND_SOC_DAPM_AIF_IN("ASPINM", "ASP Playback", 0, 649 SND_SOC_DAPM_AIF_IN("ASPINM", NULL, 0,
653 CS42L73_PWRCTL2, 2, 1), 650 CS42L73_PWRCTL2, 2, 1),
654 651
655 SND_SOC_DAPM_AIF_IN("VSPIN", "VSP Playback", 0, 652 SND_SOC_DAPM_AIF_IN("VSPIN", NULL, 0,
656 CS42L73_PWRCTL2, 4, 1), 653 CS42L73_PWRCTL2, 4, 1),
657 654
658 SND_SOC_DAPM_MIXER("HL Left Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 655 SND_SOC_DAPM_MIXER("HL Left Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -776,6 +773,14 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
776 {"HL Left Mixer", NULL, "VSPIN"}, 773 {"HL Left Mixer", NULL, "VSPIN"},
777 {"HL Right Mixer", NULL, "VSPIN"}, 774 {"HL Right Mixer", NULL, "VSPIN"},
778 775
776 {"ASPINL", NULL, "ASP Playback"},
777 {"ASPINM", NULL, "ASP Playback"},
778 {"ASPINR", NULL, "ASP Playback"},
779 {"XSPINL", NULL, "XSP Playback"},
780 {"XSPINM", NULL, "XSP Playback"},
781 {"XSPINR", NULL, "XSP Playback"},
782 {"VSPIN", NULL, "VSP Playback"},
783
779 /* Capture Paths */ 784 /* Capture Paths */
780 {"MIC1", NULL, "MIC1 Bias"}, 785 {"MIC1", NULL, "MIC1 Bias"},
781 {"PGA Left Mux", "Mic 1", "MIC1"}, 786 {"PGA Left Mux", "Mic 1", "MIC1"},
@@ -822,6 +827,13 @@ static const struct snd_soc_dapm_route cs42l73_audio_map[] = {
822 827
823 {"VSPOUTL", NULL, "VSPL Output Mixer"}, 828 {"VSPOUTL", NULL, "VSPL Output Mixer"},
824 {"VSPOUTR", NULL, "VSPR Output Mixer"}, 829 {"VSPOUTR", NULL, "VSPR Output Mixer"},
830
831 {"ASP Capture", NULL, "ASPOUTL"},
832 {"ASP Capture", NULL, "ASPOUTR"},
833 {"XSP Capture", NULL, "XSPOUTL"},
834 {"XSP Capture", NULL, "XSPOUTR"},
835 {"VSP Capture", NULL, "VSPOUTL"},
836 {"VSP Capture", NULL, "VSPOUTR"},
825}; 837};
826 838
827struct cs42l73_mclk_div { 839struct cs42l73_mclk_div {
@@ -1091,8 +1103,7 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream,
1091 struct snd_pcm_hw_params *params, 1103 struct snd_pcm_hw_params *params,
1092 struct snd_soc_dai *dai) 1104 struct snd_soc_dai *dai)
1093{ 1105{
1094 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1106 struct snd_soc_codec *codec = dai->codec;
1095 struct snd_soc_codec *codec = rtd->codec;
1096 struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec); 1107 struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec);
1097 int id = dai->id; 1108 int id = dai->id;
1098 int mclk_coeff; 1109 int mclk_coeff;
@@ -1429,25 +1440,7 @@ static struct i2c_driver cs42l73_i2c_driver = {
1429 1440
1430}; 1441};
1431 1442
1432static int __init cs42l73_modinit(void) 1443module_i2c_driver(cs42l73_i2c_driver);
1433{
1434 int ret;
1435 ret = i2c_add_driver(&cs42l73_i2c_driver);
1436 if (ret != 0) {
1437 pr_err("Failed to register CS42L73 I2C driver: %d\n", ret);
1438 return ret;
1439 }
1440 return 0;
1441}
1442
1443module_init(cs42l73_modinit);
1444
1445static void __exit cs42l73_exit(void)
1446{
1447 i2c_del_driver(&cs42l73_i2c_driver);
1448}
1449
1450module_exit(cs42l73_exit);
1451 1444
1452MODULE_DESCRIPTION("ASoC CS42L73 driver"); 1445MODULE_DESCRIPTION("ASoC CS42L73 driver");
1453MODULE_AUTHOR("Georgi Vlaev, Nucleus Systems Ltd, <joe@nucleusys.com>"); 1446MODULE_AUTHOR("Georgi Vlaev, Nucleus Systems Ltd, <joe@nucleusys.com>");
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 7843711729bc..af5db7080519 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -17,6 +17,7 @@
17 17
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/spi/spi.h>
20#include <linux/regmap.h> 21#include <linux/regmap.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <linux/module.h> 23#include <linux/module.h>
@@ -27,6 +28,7 @@
27#include <sound/tlv.h> 28#include <sound/tlv.h>
28 29
29/* DA7210 register space */ 30/* DA7210 register space */
31#define DA7210_PAGE_CONTROL 0x00
30#define DA7210_CONTROL 0x01 32#define DA7210_CONTROL 0x01
31#define DA7210_STATUS 0x02 33#define DA7210_STATUS 0x02
32#define DA7210_STARTUP1 0x03 34#define DA7210_STARTUP1 0x03
@@ -146,6 +148,7 @@
146#define DA7210_DAI_EN (1 << 7) 148#define DA7210_DAI_EN (1 << 7)
147 149
148/*PLL_DIV3 bit fields */ 150/*PLL_DIV3 bit fields */
151#define DA7210_PLL_DIV_L_MASK (0xF << 0)
149#define DA7210_MCLK_RANGE_10_20_MHZ (1 << 4) 152#define DA7210_MCLK_RANGE_10_20_MHZ (1 << 4)
150#define DA7210_PLL_BYP (1 << 6) 153#define DA7210_PLL_BYP (1 << 6)
151 154
@@ -162,12 +165,16 @@
162#define DA7210_PLL_FS_48000 (0xB << 0) 165#define DA7210_PLL_FS_48000 (0xB << 0)
163#define DA7210_PLL_FS_88200 (0xE << 0) 166#define DA7210_PLL_FS_88200 (0xE << 0)
164#define DA7210_PLL_FS_96000 (0xF << 0) 167#define DA7210_PLL_FS_96000 (0xF << 0)
168#define DA7210_MCLK_DET_EN (0x1 << 5)
169#define DA7210_MCLK_SRM_EN (0x1 << 6)
165#define DA7210_PLL_EN (0x1 << 7) 170#define DA7210_PLL_EN (0x1 << 7)
166 171
167/* SOFTMUTE bit fields */ 172/* SOFTMUTE bit fields */
168#define DA7210_RAMP_EN (1 << 6) 173#define DA7210_RAMP_EN (1 << 6)
169 174
170/* CONTROL bit fields */ 175/* CONTROL bit fields */
176#define DA7210_REG_EN (1 << 0)
177#define DA7210_BIAS_EN (1 << 2)
171#define DA7210_NOISE_SUP_EN (1 << 3) 178#define DA7210_NOISE_SUP_EN (1 << 3)
172 179
173/* IN_GAIN bit fields */ 180/* IN_GAIN bit fields */
@@ -206,6 +213,47 @@
206#define DA7210_OUT2_OUTMIX_L (1 << 6) 213#define DA7210_OUT2_OUTMIX_L (1 << 6)
207#define DA7210_OUT2_EN (1 << 7) 214#define DA7210_OUT2_EN (1 << 7)
208 215
216struct pll_div {
217 int fref;
218 int fout;
219 u8 div1;
220 u8 div2;
221 u8 div3;
222 u8 mode; /* 0 = slave, 1 = master */
223};
224
225/* PLL dividers table */
226static const struct pll_div da7210_pll_div[] = {
227 /* for MASTER mode, fs = 44.1Khz */
228 { 12000000, 2822400, 0xE8, 0x6C, 0x2, 1}, /* MCLK=12Mhz */
229 { 13000000, 2822400, 0xDF, 0x28, 0xC, 1}, /* MCLK=13Mhz */
230 { 13500000, 2822400, 0xDB, 0x0A, 0xD, 1}, /* MCLK=13.5Mhz */
231 { 14400000, 2822400, 0xD4, 0x5A, 0x2, 1}, /* MCLK=14.4Mhz */
232 { 19200000, 2822400, 0xBB, 0x43, 0x9, 1}, /* MCLK=19.2Mhz */
233 { 19680000, 2822400, 0xB9, 0x6D, 0xA, 1}, /* MCLK=19.68Mhz */
234 { 19800000, 2822400, 0xB8, 0xFB, 0xB, 1}, /* MCLK=19.8Mhz */
235 /* for MASTER mode, fs = 48Khz */
236 { 12000000, 3072000, 0xF3, 0x12, 0x7, 1}, /* MCLK=12Mhz */
237 { 13000000, 3072000, 0xE8, 0xFD, 0x5, 1}, /* MCLK=13Mhz */
238 { 13500000, 3072000, 0xE4, 0x82, 0x3, 1}, /* MCLK=13.5Mhz */
239 { 14400000, 3072000, 0xDD, 0x3A, 0x0, 1}, /* MCLK=14.4Mhz */
240 { 19200000, 3072000, 0xC1, 0xEB, 0x8, 1}, /* MCLK=19.2Mhz */
241 { 19680000, 3072000, 0xBF, 0xEC, 0x0, 1}, /* MCLK=19.68Mhz */
242 { 19800000, 3072000, 0xBF, 0x70, 0x0, 1}, /* MCLK=19.8Mhz */
243 /* for SLAVE mode with SRM */
244 { 12000000, 2822400, 0xED, 0xBF, 0x5, 0}, /* MCLK=12Mhz */
245 { 13000000, 2822400, 0xE4, 0x13, 0x0, 0}, /* MCLK=13Mhz */
246 { 13500000, 2822400, 0xDF, 0xC6, 0x8, 0}, /* MCLK=13.5Mhz */
247 { 14400000, 2822400, 0xD8, 0xCA, 0x1, 0}, /* MCLK=14.4Mhz */
248 { 19200000, 2822400, 0xBE, 0x97, 0x9, 0}, /* MCLK=19.2Mhz */
249 { 19680000, 2822400, 0xBC, 0xAC, 0xD, 0}, /* MCLK=19.68Mhz */
250 { 19800000, 2822400, 0xBC, 0x35, 0xE, 0}, /* MCLK=19.8Mhz */
251};
252
253enum clk_src {
254 DA7210_CLKSRC_MCLK
255};
256
209#define DA7210_VERSION "0.0.1" 257#define DA7210_VERSION "0.0.1"
210 258
211/* 259/*
@@ -628,9 +676,12 @@ static const struct snd_soc_dapm_route da7210_audio_map[] = {
628/* Codec private data */ 676/* Codec private data */
629struct da7210_priv { 677struct da7210_priv {
630 struct regmap *regmap; 678 struct regmap *regmap;
679 unsigned int mclk_rate;
680 int master;
631}; 681};
632 682
633static struct reg_default da7210_reg_defaults[] = { 683static struct reg_default da7210_reg_defaults[] = {
684 { 0x00, 0x00 },
634 { 0x01, 0x11 }, 685 { 0x01, 0x11 },
635 { 0x03, 0x00 }, 686 { 0x03, 0x00 },
636 { 0x04, 0x00 }, 687 { 0x04, 0x00 },
@@ -713,10 +764,10 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
713 struct snd_pcm_hw_params *params, 764 struct snd_pcm_hw_params *params,
714 struct snd_soc_dai *dai) 765 struct snd_soc_dai *dai)
715{ 766{
716 struct snd_soc_pcm_runtime *rtd = substream->private_data; 767 struct snd_soc_codec *codec = dai->codec;
717 struct snd_soc_codec *codec = rtd->codec; 768 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
718 u32 dai_cfg1; 769 u32 dai_cfg1;
719 u32 fs, bypass; 770 u32 fs, sysclk;
720 771
721 /* set DAI source to Left and Right ADC */ 772 /* set DAI source to Left and Right ADC */
722 snd_soc_write(codec, DA7210_DAI_SRC_SEL, 773 snd_soc_write(codec, DA7210_DAI_SRC_SEL,
@@ -749,43 +800,43 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
749 switch (params_rate(params)) { 800 switch (params_rate(params)) {
750 case 8000: 801 case 8000:
751 fs = DA7210_PLL_FS_8000; 802 fs = DA7210_PLL_FS_8000;
752 bypass = DA7210_PLL_BYP; 803 sysclk = 3072000;
753 break; 804 break;
754 case 11025: 805 case 11025:
755 fs = DA7210_PLL_FS_11025; 806 fs = DA7210_PLL_FS_11025;
756 bypass = 0; 807 sysclk = 2822400;
757 break; 808 break;
758 case 12000: 809 case 12000:
759 fs = DA7210_PLL_FS_12000; 810 fs = DA7210_PLL_FS_12000;
760 bypass = DA7210_PLL_BYP; 811 sysclk = 3072000;
761 break; 812 break;
762 case 16000: 813 case 16000:
763 fs = DA7210_PLL_FS_16000; 814 fs = DA7210_PLL_FS_16000;
764 bypass = DA7210_PLL_BYP; 815 sysclk = 3072000;
765 break; 816 break;
766 case 22050: 817 case 22050:
767 fs = DA7210_PLL_FS_22050; 818 fs = DA7210_PLL_FS_22050;
768 bypass = 0; 819 sysclk = 2822400;
769 break; 820 break;
770 case 32000: 821 case 32000:
771 fs = DA7210_PLL_FS_32000; 822 fs = DA7210_PLL_FS_32000;
772 bypass = DA7210_PLL_BYP; 823 sysclk = 3072000;
773 break; 824 break;
774 case 44100: 825 case 44100:
775 fs = DA7210_PLL_FS_44100; 826 fs = DA7210_PLL_FS_44100;
776 bypass = 0; 827 sysclk = 2822400;
777 break; 828 break;
778 case 48000: 829 case 48000:
779 fs = DA7210_PLL_FS_48000; 830 fs = DA7210_PLL_FS_48000;
780 bypass = DA7210_PLL_BYP; 831 sysclk = 3072000;
781 break; 832 break;
782 case 88200: 833 case 88200:
783 fs = DA7210_PLL_FS_88200; 834 fs = DA7210_PLL_FS_88200;
784 bypass = 0; 835 sysclk = 2822400;
785 break; 836 break;
786 case 96000: 837 case 96000:
787 fs = DA7210_PLL_FS_96000; 838 fs = DA7210_PLL_FS_96000;
788 bypass = DA7210_PLL_BYP; 839 sysclk = 3072000;
789 break; 840 break;
790 default: 841 default:
791 return -EINVAL; 842 return -EINVAL;
@@ -795,8 +846,26 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
795 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0); 846 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
796 847
797 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs); 848 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs);
798 snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, bypass);
799 849
850 if (da7210->mclk_rate && (da7210->mclk_rate != sysclk)) {
851 /* PLL mode, disable PLL bypass */
852 snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, 0);
853
854 if (!da7210->master) {
855 /* PLL slave mode, also enable SRM */
856 snd_soc_update_bits(codec, DA7210_PLL,
857 (DA7210_MCLK_SRM_EN |
858 DA7210_MCLK_DET_EN),
859 (DA7210_MCLK_SRM_EN |
860 DA7210_MCLK_DET_EN));
861 }
862 } else {
863 /* PLL bypass mode, enable PLL bypass and Auto Detection */
864 snd_soc_update_bits(codec, DA7210_PLL, DA7210_MCLK_DET_EN,
865 DA7210_MCLK_DET_EN);
866 snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP,
867 DA7210_PLL_BYP);
868 }
800 /* Enable active mode */ 869 /* Enable active mode */
801 snd_soc_update_bits(codec, DA7210_STARTUP1, 870 snd_soc_update_bits(codec, DA7210_STARTUP1,
802 DA7210_SC_MST_EN, DA7210_SC_MST_EN); 871 DA7210_SC_MST_EN, DA7210_SC_MST_EN);
@@ -810,17 +879,24 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
810static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt) 879static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
811{ 880{
812 struct snd_soc_codec *codec = codec_dai->codec; 881 struct snd_soc_codec *codec = codec_dai->codec;
882 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
813 u32 dai_cfg1; 883 u32 dai_cfg1;
814 u32 dai_cfg3; 884 u32 dai_cfg3;
815 885
816 dai_cfg1 = 0x7f & snd_soc_read(codec, DA7210_DAI_CFG1); 886 dai_cfg1 = 0x7f & snd_soc_read(codec, DA7210_DAI_CFG1);
817 dai_cfg3 = 0xfc & snd_soc_read(codec, DA7210_DAI_CFG3); 887 dai_cfg3 = 0xfc & snd_soc_read(codec, DA7210_DAI_CFG3);
818 888
889 if ((snd_soc_read(codec, DA7210_PLL) & DA7210_PLL_EN) &&
890 (!(snd_soc_read(codec, DA7210_PLL_DIV3) & DA7210_PLL_BYP)))
891 return -EINVAL;
892
819 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 893 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
820 case SND_SOC_DAIFMT_CBM_CFM: 894 case SND_SOC_DAIFMT_CBM_CFM:
895 da7210->master = 1;
821 dai_cfg1 |= DA7210_DAI_MODE_MASTER; 896 dai_cfg1 |= DA7210_DAI_MODE_MASTER;
822 break; 897 break;
823 case SND_SOC_DAIFMT_CBS_CFS: 898 case SND_SOC_DAIFMT_CBS_CFS:
899 da7210->master = 0;
824 dai_cfg1 |= DA7210_DAI_MODE_SLAVE; 900 dai_cfg1 |= DA7210_DAI_MODE_SLAVE;
825 break; 901 break;
826 default: 902 default:
@@ -872,10 +948,101 @@ static int da7210_mute(struct snd_soc_dai *dai, int mute)
872#define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 948#define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
873 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 949 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
874 950
951static int da7210_set_dai_sysclk(struct snd_soc_dai *codec_dai,
952 int clk_id, unsigned int freq, int dir)
953{
954 struct snd_soc_codec *codec = codec_dai->codec;
955 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
956
957 switch (clk_id) {
958 case DA7210_CLKSRC_MCLK:
959 switch (freq) {
960 case 12000000:
961 case 13000000:
962 case 13500000:
963 case 14400000:
964 case 19200000:
965 case 19680000:
966 case 19800000:
967 da7210->mclk_rate = freq;
968 return 0;
969 default:
970 dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
971 freq);
972 return -EINVAL;
973 }
974 break;
975 default:
976 dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
977 return -EINVAL;
978 }
979}
980
981/**
982 * da7210_set_dai_pll :Configure the codec PLL
983 * @param codec_dai : pointer to codec DAI
984 * @param pll_id : da7210 has only one pll, so pll_id is always zero
985 * @param fref : MCLK frequency, should be < 20MHz
986 * @param fout : FsDM value, Refer page 44 & 45 of datasheet
987 * @return int : Zero for success, negative error code for error
988 *
989 * Note: Supported PLL input frequencies are 12MHz, 13MHz, 13.5MHz, 14.4MHz,
990 * 19.2MHz, 19.6MHz and 19.8MHz
991 */
992static int da7210_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
993 int source, unsigned int fref, unsigned int fout)
994{
995 struct snd_soc_codec *codec = codec_dai->codec;
996 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
997
998 u8 pll_div1, pll_div2, pll_div3, cnt;
999
1000 /* In slave mode, there is only one set of divisors */
1001 if (!da7210->master)
1002 fout = 2822400;
1003
1004 /* Search pll div array for correct divisors */
1005 for (cnt = 0; cnt < ARRAY_SIZE(da7210_pll_div); cnt++) {
1006 /* check fref, mode and fout */
1007 if ((fref == da7210_pll_div[cnt].fref) &&
1008 (da7210->master == da7210_pll_div[cnt].mode) &&
1009 (fout == da7210_pll_div[cnt].fout)) {
1010 /* all match, pick up divisors */
1011 pll_div1 = da7210_pll_div[cnt].div1;
1012 pll_div2 = da7210_pll_div[cnt].div2;
1013 pll_div3 = da7210_pll_div[cnt].div3;
1014 break;
1015 }
1016 }
1017 if (cnt >= ARRAY_SIZE(da7210_pll_div))
1018 goto err;
1019
1020 /* Disable active mode */
1021 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0);
1022 /* Write PLL dividers */
1023 snd_soc_write(codec, DA7210_PLL_DIV1, pll_div1);
1024 snd_soc_write(codec, DA7210_PLL_DIV2, pll_div2);
1025 snd_soc_update_bits(codec, DA7210_PLL_DIV3,
1026 DA7210_PLL_DIV_L_MASK, pll_div3);
1027
1028 /* Enable PLL */
1029 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
1030
1031 /* Enable active mode */
1032 snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN,
1033 DA7210_SC_MST_EN);
1034 return 0;
1035err:
1036 dev_err(codec_dai->dev, "Unsupported PLL input frequency %d\n", fref);
1037 return -EINVAL;
1038}
1039
875/* DAI operations */ 1040/* DAI operations */
876static const struct snd_soc_dai_ops da7210_dai_ops = { 1041static const struct snd_soc_dai_ops da7210_dai_ops = {
877 .hw_params = da7210_hw_params, 1042 .hw_params = da7210_hw_params,
878 .set_fmt = da7210_set_dai_fmt, 1043 .set_fmt = da7210_set_dai_fmt,
1044 .set_sysclk = da7210_set_dai_sysclk,
1045 .set_pll = da7210_set_dai_pll,
879 .digital_mute = da7210_mute, 1046 .digital_mute = da7210_mute,
880}; 1047};
881 1048
@@ -915,24 +1082,11 @@ static int da7210_probe(struct snd_soc_codec *codec)
915 return ret; 1082 return ret;
916 } 1083 }
917 1084
918 /* FIXME 1085 da7210->mclk_rate = 0; /* This will be set from set_sysclk() */
919 * 1086 da7210->master = 0; /* This will be set from set_fmt() */
920 * This driver use fixed value here
921 * And below settings expects MCLK = 12.288MHz
922 *
923 * When you select different MCLK, please check...
924 * DA7210_PLL_DIV1 val
925 * DA7210_PLL_DIV2 val
926 * DA7210_PLL_DIV3 val
927 * DA7210_PLL_DIV3 :: DA7210_MCLK_RANGExxx
928 */
929 1087
930 /* 1088 /* Enable internal regulator & bias current */
931 * make sure that DA7210 use bypass mode before start up 1089 snd_soc_write(codec, DA7210_CONTROL, DA7210_REG_EN | DA7210_BIAS_EN);
932 */
933 snd_soc_write(codec, DA7210_STARTUP1, 0);
934 snd_soc_write(codec, DA7210_PLL_DIV3,
935 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
936 1090
937 /* 1091 /*
938 * ADC settings 1092 * ADC settings
@@ -1007,34 +1161,13 @@ static int da7210_probe(struct snd_soc_codec *codec)
1007 /* Enable Aux2 */ 1161 /* Enable Aux2 */
1008 snd_soc_write(codec, DA7210_AUX2, DA7210_AUX2_EN); 1162 snd_soc_write(codec, DA7210_AUX2, DA7210_AUX2_EN);
1009 1163
1164 /* Set PLL Master clock range 10-20 MHz, enable PLL bypass */
1165 snd_soc_write(codec, DA7210_PLL_DIV3, DA7210_MCLK_RANGE_10_20_MHZ |
1166 DA7210_PLL_BYP);
1167
1010 /* Diable PLL and bypass it */ 1168 /* Diable PLL and bypass it */
1011 snd_soc_write(codec, DA7210_PLL, DA7210_PLL_FS_48000); 1169 snd_soc_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
1012 1170
1013 /*
1014 * If 48kHz sound came, it use bypass mode,
1015 * and when it is 44.1kHz, it use PLL.
1016 *
1017 * This time, this driver sets PLL always ON
1018 * and controls bypass/PLL mode by switching
1019 * DA7210_PLL_DIV3 :: DA7210_PLL_BYP bit.
1020 * see da7210_hw_params
1021 */
1022 snd_soc_write(codec, DA7210_PLL_DIV1, 0xE5); /* MCLK = 12.288MHz */
1023 snd_soc_write(codec, DA7210_PLL_DIV2, 0x99);
1024 snd_soc_write(codec, DA7210_PLL_DIV3, 0x0A |
1025 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
1026 snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN);
1027
1028 /* As suggested by Dialog */
1029 /* unlock */
1030 regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x8B);
1031 regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0xB4);
1032 regmap_write(da7210->regmap, DA7210_A_PLL1, 0x01);
1033 regmap_write(da7210->regmap, DA7210_A_CP_MODE, 0x7C);
1034 /* re-lock */
1035 regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x00);
1036 regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0x00);
1037
1038 /* Activate all enabled subsystem */ 1171 /* Activate all enabled subsystem */
1039 snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); 1172 snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
1040 1173
@@ -1055,7 +1188,26 @@ static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
1055 .num_dapm_routes = ARRAY_SIZE(da7210_audio_map), 1188 .num_dapm_routes = ARRAY_SIZE(da7210_audio_map),
1056}; 1189};
1057 1190
1058static struct regmap_config da7210_regmap = { 1191#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1192
1193static struct reg_default da7210_regmap_i2c_patch[] = {
1194
1195 /* System controller master disable */
1196 { DA7210_STARTUP1, 0x00 },
1197 /* Set PLL Master clock range 10-20 MHz */
1198 { DA7210_PLL_DIV3, DA7210_MCLK_RANGE_10_20_MHZ },
1199
1200 /* to unlock */
1201 { DA7210_A_HID_UNLOCK, 0x8B},
1202 { DA7210_A_TEST_UNLOCK, 0xB4},
1203 { DA7210_A_PLL1, 0x01},
1204 { DA7210_A_CP_MODE, 0x7C},
1205 /* to re-lock */
1206 { DA7210_A_HID_UNLOCK, 0x00},
1207 { DA7210_A_TEST_UNLOCK, 0x00},
1208};
1209
1210static const struct regmap_config da7210_regmap_config_i2c = {
1059 .reg_bits = 8, 1211 .reg_bits = 8,
1060 .val_bits = 8, 1212 .val_bits = 8,
1061 1213
@@ -1066,7 +1218,6 @@ static struct regmap_config da7210_regmap = {
1066 .cache_type = REGCACHE_RBTREE, 1218 .cache_type = REGCACHE_RBTREE,
1067}; 1219};
1068 1220
1069#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1070static int __devinit da7210_i2c_probe(struct i2c_client *i2c, 1221static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
1071 const struct i2c_device_id *id) 1222 const struct i2c_device_id *id)
1072{ 1223{
@@ -1080,13 +1231,18 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
1080 1231
1081 i2c_set_clientdata(i2c, da7210); 1232 i2c_set_clientdata(i2c, da7210);
1082 1233
1083 da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap); 1234 da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap_config_i2c);
1084 if (IS_ERR(da7210->regmap)) { 1235 if (IS_ERR(da7210->regmap)) {
1085 ret = PTR_ERR(da7210->regmap); 1236 ret = PTR_ERR(da7210->regmap);
1086 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); 1237 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
1087 return ret; 1238 return ret;
1088 } 1239 }
1089 1240
1241 ret = regmap_register_patch(da7210->regmap, da7210_regmap_i2c_patch,
1242 ARRAY_SIZE(da7210_regmap_i2c_patch));
1243 if (ret != 0)
1244 dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
1245
1090 ret = snd_soc_register_codec(&i2c->dev, 1246 ret = snd_soc_register_codec(&i2c->dev,
1091 &soc_codec_dev_da7210, &da7210_dai, 1); 1247 &soc_codec_dev_da7210, &da7210_dai, 1);
1092 if (ret < 0) { 1248 if (ret < 0) {
@@ -1119,7 +1275,7 @@ MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
1119/* I2C codec control layer */ 1275/* I2C codec control layer */
1120static struct i2c_driver da7210_i2c_driver = { 1276static struct i2c_driver da7210_i2c_driver = {
1121 .driver = { 1277 .driver = {
1122 .name = "da7210-codec", 1278 .name = "da7210",
1123 .owner = THIS_MODULE, 1279 .owner = THIS_MODULE,
1124 }, 1280 },
1125 .probe = da7210_i2c_probe, 1281 .probe = da7210_i2c_probe,
@@ -1128,12 +1284,112 @@ static struct i2c_driver da7210_i2c_driver = {
1128}; 1284};
1129#endif 1285#endif
1130 1286
1287#if defined(CONFIG_SPI_MASTER)
1288
1289static struct reg_default da7210_regmap_spi_patch[] = {
1290 /* Dummy read to give two pulses over nCS for SPI */
1291 { DA7210_AUX2, 0x00 },
1292 { DA7210_AUX2, 0x00 },
1293
1294 /* System controller master disable */
1295 { DA7210_STARTUP1, 0x00 },
1296 /* Set PLL Master clock range 10-20 MHz */
1297 { DA7210_PLL_DIV3, DA7210_MCLK_RANGE_10_20_MHZ },
1298
1299 /* to set PAGE1 of SPI register space */
1300 { DA7210_PAGE_CONTROL, 0x80 },
1301 /* to unlock */
1302 { DA7210_A_HID_UNLOCK, 0x8B},
1303 { DA7210_A_TEST_UNLOCK, 0xB4},
1304 { DA7210_A_PLL1, 0x01},
1305 { DA7210_A_CP_MODE, 0x7C},
1306 /* to re-lock */
1307 { DA7210_A_HID_UNLOCK, 0x00},
1308 { DA7210_A_TEST_UNLOCK, 0x00},
1309 /* to set back PAGE0 of SPI register space */
1310 { DA7210_PAGE_CONTROL, 0x00 },
1311};
1312
1313static const struct regmap_config da7210_regmap_config_spi = {
1314 .reg_bits = 8,
1315 .val_bits = 8,
1316 .read_flag_mask = 0x01,
1317 .write_flag_mask = 0x00,
1318
1319 .reg_defaults = da7210_reg_defaults,
1320 .num_reg_defaults = ARRAY_SIZE(da7210_reg_defaults),
1321 .volatile_reg = da7210_volatile_register,
1322 .readable_reg = da7210_readable_register,
1323 .cache_type = REGCACHE_RBTREE,
1324};
1325
1326static int __devinit da7210_spi_probe(struct spi_device *spi)
1327{
1328 struct da7210_priv *da7210;
1329 int ret;
1330
1331 da7210 = devm_kzalloc(&spi->dev, sizeof(struct da7210_priv),
1332 GFP_KERNEL);
1333 if (!da7210)
1334 return -ENOMEM;
1335
1336 spi_set_drvdata(spi, da7210);
1337 da7210->regmap = devm_regmap_init_spi(spi, &da7210_regmap_config_spi);
1338 if (IS_ERR(da7210->regmap)) {
1339 ret = PTR_ERR(da7210->regmap);
1340 dev_err(&spi->dev, "Failed to register regmap: %d\n", ret);
1341 return ret;
1342 }
1343
1344 ret = regmap_register_patch(da7210->regmap, da7210_regmap_spi_patch,
1345 ARRAY_SIZE(da7210_regmap_spi_patch));
1346 if (ret != 0)
1347 dev_warn(&spi->dev, "Failed to apply regmap patch: %d\n", ret);
1348
1349 ret = snd_soc_register_codec(&spi->dev,
1350 &soc_codec_dev_da7210, &da7210_dai, 1);
1351 if (ret < 0)
1352 goto err_regmap;
1353
1354 return ret;
1355
1356err_regmap:
1357 regmap_exit(da7210->regmap);
1358
1359 return ret;
1360}
1361
1362static int __devexit da7210_spi_remove(struct spi_device *spi)
1363{
1364 struct da7210_priv *da7210 = spi_get_drvdata(spi);
1365 snd_soc_unregister_codec(&spi->dev);
1366 regmap_exit(da7210->regmap);
1367 return 0;
1368}
1369
1370static struct spi_driver da7210_spi_driver = {
1371 .driver = {
1372 .name = "da7210",
1373 .owner = THIS_MODULE,
1374 },
1375 .probe = da7210_spi_probe,
1376 .remove = __devexit_p(da7210_spi_remove)
1377};
1378#endif
1379
1131static int __init da7210_modinit(void) 1380static int __init da7210_modinit(void)
1132{ 1381{
1133 int ret = 0; 1382 int ret = 0;
1134#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1383#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1135 ret = i2c_add_driver(&da7210_i2c_driver); 1384 ret = i2c_add_driver(&da7210_i2c_driver);
1136#endif 1385#endif
1386#if defined(CONFIG_SPI_MASTER)
1387 ret = spi_register_driver(&da7210_spi_driver);
1388 if (ret) {
1389 printk(KERN_ERR "Failed to register da7210 SPI driver: %d\n",
1390 ret);
1391 }
1392#endif
1137 return ret; 1393 return ret;
1138} 1394}
1139module_init(da7210_modinit); 1395module_init(da7210_modinit);
@@ -1143,6 +1399,9 @@ static void __exit da7210_exit(void)
1143#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1399#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1144 i2c_del_driver(&da7210_i2c_driver); 1400 i2c_del_driver(&da7210_i2c_driver);
1145#endif 1401#endif
1402#if defined(CONFIG_SPI_MASTER)
1403 spi_unregister_driver(&da7210_spi_driver);
1404#endif
1146} 1405}
1147module_exit(da7210_exit); 1406module_exit(da7210_exit);
1148 1407
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index 4624e752a188..85d9cabe6d55 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -164,8 +164,7 @@ static int jz4740_codec_hw_params(struct snd_pcm_substream *substream,
164 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 164 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
165{ 165{
166 uint32_t val; 166 uint32_t val;
167 struct snd_soc_pcm_runtime *rtd = substream->private_data; 167 struct snd_soc_codec *codec = dai->codec;
168 struct snd_soc_codec *codec =rtd->codec;
169 168
170 switch (params_rate(params)) { 169 switch (params_rate(params)) {
171 case 8000: 170 case 8000:
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c
new file mode 100644
index 000000000000..802b9f176b16
--- /dev/null
+++ b/sound/soc/codecs/lm49453.c
@@ -0,0 +1,1550 @@
1/*
2 * lm49453.c - LM49453 ALSA Soc Audio driver
3 *
4 * Copyright (c) 2012 Texas Instruments, Inc
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * Initially based on sound/soc/codecs/wm8350.c
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/version.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/regmap.h>
22#include <linux/slab.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/tlv.h>
29#include <sound/jack.h>
30#include <sound/initval.h>
31#include <asm/div64.h>
32#include "lm49453.h"
33
34static struct reg_default lm49453_reg_defs[] = {
35 { 0, 0x00 },
36 { 1, 0x00 },
37 { 2, 0x00 },
38 { 3, 0x00 },
39 { 4, 0x00 },
40 { 5, 0x00 },
41 { 6, 0x00 },
42 { 7, 0x00 },
43 { 8, 0x00 },
44 { 9, 0x00 },
45 { 10, 0x00 },
46 { 11, 0x00 },
47 { 12, 0x00 },
48 { 13, 0x00 },
49 { 14, 0x00 },
50 { 15, 0x00 },
51 { 16, 0x00 },
52 { 17, 0x00 },
53 { 18, 0x00 },
54 { 19, 0x00 },
55 { 20, 0x00 },
56 { 21, 0x00 },
57 { 22, 0x00 },
58 { 23, 0x00 },
59 { 32, 0x00 },
60 { 33, 0x00 },
61 { 35, 0x00 },
62 { 36, 0x00 },
63 { 37, 0x00 },
64 { 46, 0x00 },
65 { 48, 0x00 },
66 { 49, 0x00 },
67 { 51, 0x00 },
68 { 56, 0x00 },
69 { 58, 0x00 },
70 { 59, 0x00 },
71 { 60, 0x00 },
72 { 61, 0x00 },
73 { 62, 0x00 },
74 { 63, 0x00 },
75 { 64, 0x00 },
76 { 65, 0x00 },
77 { 66, 0x00 },
78 { 67, 0x00 },
79 { 68, 0x00 },
80 { 69, 0x00 },
81 { 70, 0x00 },
82 { 71, 0x00 },
83 { 72, 0x00 },
84 { 73, 0x00 },
85 { 74, 0x00 },
86 { 75, 0x00 },
87 { 76, 0x00 },
88 { 77, 0x00 },
89 { 78, 0x00 },
90 { 79, 0x00 },
91 { 80, 0x00 },
92 { 81, 0x00 },
93 { 82, 0x00 },
94 { 83, 0x00 },
95 { 85, 0x00 },
96 { 85, 0x00 },
97 { 86, 0x00 },
98 { 87, 0x00 },
99 { 88, 0x00 },
100 { 89, 0x00 },
101 { 90, 0x00 },
102 { 91, 0x00 },
103 { 92, 0x00 },
104 { 93, 0x00 },
105 { 94, 0x00 },
106 { 95, 0x00 },
107 { 96, 0x01 },
108 { 97, 0x00 },
109 { 98, 0x00 },
110 { 99, 0x00 },
111 { 100, 0x00 },
112 { 101, 0x00 },
113 { 102, 0x00 },
114 { 103, 0x01 },
115 { 105, 0x01 },
116 { 106, 0x00 },
117 { 107, 0x01 },
118 { 107, 0x00 },
119 { 108, 0x00 },
120 { 109, 0x00 },
121 { 110, 0x00 },
122 { 111, 0x02 },
123 { 112, 0x02 },
124 { 113, 0x00 },
125 { 121, 0x80 },
126 { 122, 0xBB },
127 { 123, 0x80 },
128 { 124, 0xBB },
129 { 128, 0x00 },
130 { 130, 0x00 },
131 { 131, 0x00 },
132 { 132, 0x00 },
133 { 133, 0x0A },
134 { 134, 0x0A },
135 { 135, 0x0A },
136 { 136, 0x0F },
137 { 137, 0x00 },
138 { 138, 0x73 },
139 { 139, 0x33 },
140 { 140, 0x73 },
141 { 141, 0x33 },
142 { 142, 0x73 },
143 { 143, 0x33 },
144 { 144, 0x73 },
145 { 145, 0x33 },
146 { 146, 0x73 },
147 { 147, 0x33 },
148 { 148, 0x73 },
149 { 149, 0x33 },
150 { 150, 0x73 },
151 { 151, 0x33 },
152 { 152, 0x00 },
153 { 153, 0x00 },
154 { 154, 0x00 },
155 { 155, 0x00 },
156 { 176, 0x00 },
157 { 177, 0x00 },
158 { 178, 0x00 },
159 { 179, 0x00 },
160 { 180, 0x00 },
161 { 181, 0x00 },
162 { 182, 0x00 },
163 { 183, 0x00 },
164 { 184, 0x00 },
165 { 185, 0x00 },
166 { 186, 0x00 },
167 { 189, 0x00 },
168 { 188, 0x00 },
169 { 194, 0x00 },
170 { 195, 0x00 },
171 { 196, 0x00 },
172 { 197, 0x00 },
173 { 200, 0x00 },
174 { 201, 0x00 },
175 { 202, 0x00 },
176 { 203, 0x00 },
177 { 204, 0x00 },
178 { 205, 0x00 },
179 { 208, 0x00 },
180 { 209, 0x00 },
181 { 210, 0x00 },
182 { 211, 0x00 },
183 { 213, 0x00 },
184 { 214, 0x00 },
185 { 215, 0x00 },
186 { 216, 0x00 },
187 { 217, 0x00 },
188 { 218, 0x00 },
189 { 219, 0x00 },
190 { 221, 0x00 },
191 { 222, 0x00 },
192 { 224, 0x00 },
193 { 225, 0x00 },
194 { 226, 0x00 },
195 { 227, 0x00 },
196 { 228, 0x00 },
197 { 229, 0x00 },
198 { 230, 0x13 },
199 { 231, 0x00 },
200 { 232, 0x80 },
201 { 233, 0x0C },
202 { 234, 0xDD },
203 { 235, 0x00 },
204 { 236, 0x04 },
205 { 237, 0x00 },
206 { 238, 0x00 },
207 { 239, 0x00 },
208 { 240, 0x00 },
209 { 241, 0x00 },
210 { 242, 0x00 },
211 { 243, 0x00 },
212 { 244, 0x00 },
213 { 245, 0x00 },
214 { 248, 0x00 },
215 { 249, 0x00 },
216 { 254, 0x00 },
217 { 255, 0x00 },
218};
219
220/* codec private data */
221struct lm49453_priv {
222 struct regmap *regmap;
223 int fs_rate;
224};
225
226/* capture path controls */
227
228static const char *lm49453_mic2mode_text[] = {"Single Ended", "Differential"};
229
230static const SOC_ENUM_SINGLE_DECL(lm49453_mic2mode_enum, LM49453_P0_MICR_REG, 5,
231 lm49453_mic2mode_text);
232
233static const char *lm49453_dmic_cfg_text[] = {"DMICDAT1", "DMICDAT2"};
234
235static const SOC_ENUM_SINGLE_DECL(lm49453_dmic12_cfg_enum,
236 LM49453_P0_DIGITAL_MIC1_CONFIG_REG,
237 7, lm49453_dmic_cfg_text);
238
239static const SOC_ENUM_SINGLE_DECL(lm49453_dmic34_cfg_enum,
240 LM49453_P0_DIGITAL_MIC2_CONFIG_REG,
241 7, lm49453_dmic_cfg_text);
242
243/* MUX Controls */
244static const char *lm49453_adcl_mux_text[] = { "MIC1", "Aux_L" };
245
246static const char *lm49453_adcr_mux_text[] = { "MIC2", "Aux_R" };
247
248static const struct soc_enum lm49453_adcl_enum =
249 SOC_ENUM_SINGLE(LM49453_P0_ANALOG_MIXER_ADC_REG, 0,
250 ARRAY_SIZE(lm49453_adcl_mux_text),
251 lm49453_adcl_mux_text);
252
253static const struct soc_enum lm49453_adcr_enum =
254 SOC_ENUM_SINGLE(LM49453_P0_ANALOG_MIXER_ADC_REG, 1,
255 ARRAY_SIZE(lm49453_adcr_mux_text),
256 lm49453_adcr_mux_text);
257
258static const struct snd_kcontrol_new lm49453_adcl_mux_control =
259 SOC_DAPM_ENUM("ADC Left Mux", lm49453_adcl_enum);
260
261static const struct snd_kcontrol_new lm49453_adcr_mux_control =
262 SOC_DAPM_ENUM("ADC Right Mux", lm49453_adcr_enum);
263
264static const struct snd_kcontrol_new lm49453_headset_left_mixer[] = {
265SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_DACHPL1_REG, 0, 1, 0),
266SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_DACHPL1_REG, 1, 1, 0),
267SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_DACHPL1_REG, 2, 1, 0),
268SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_DACHPL1_REG, 3, 1, 0),
269SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_DACHPL1_REG, 4, 1, 0),
270SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_DACHPL1_REG, 5, 1, 0),
271SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_DACHPL1_REG, 6, 1, 0),
272SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_DACHPL1_REG, 7, 1, 0),
273SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_DACHPL2_REG, 0, 1, 0),
274SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_DACHPL2_REG, 1, 1, 0),
275SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_DACHPL2_REG, 2, 1, 0),
276SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_DACHPL2_REG, 3, 1, 0),
277SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_DACHPL2_REG, 4, 1, 0),
278SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_DACHPL2_REG, 5, 1, 0),
279SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_DACHPL2_REG, 6, 1, 0),
280SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_DACHPL2_REG, 7, 1, 0),
281SOC_DAPM_SINGLE("Sidetone Switch", LM49453_P0_STN_SEL_REG, 0, 0, 0),
282};
283
284static const struct snd_kcontrol_new lm49453_headset_right_mixer[] = {
285SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_DACHPR1_REG, 0, 1, 0),
286SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_DACHPR1_REG, 1, 1, 0),
287SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_DACHPR1_REG, 2, 1, 0),
288SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_DACHPR1_REG, 3, 1, 0),
289SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_DACHPR1_REG, 4, 1, 0),
290SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_DACHPR1_REG, 5, 1, 0),
291SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_DACHPR1_REG, 6, 1, 0),
292SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_DACHPR1_REG, 7, 1, 0),
293SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_DACHPR2_REG, 0, 1, 0),
294SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_DACHPR2_REG, 1, 1, 0),
295SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_DACHPR2_REG, 2, 1, 0),
296SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_DACHPR2_REG, 3, 1, 0),
297SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_DACHPR2_REG, 4, 1, 0),
298SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_DACHPR2_REG, 5, 1, 0),
299SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_DACHPR2_REG, 6, 1, 0),
300SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_DACHPR2_REG, 7, 1, 0),
301SOC_DAPM_SINGLE("Sidetone Switch", LM49453_P0_STN_SEL_REG, 1, 0, 0),
302};
303
304static const struct snd_kcontrol_new lm49453_speaker_left_mixer[] = {
305SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_DACLSL1_REG, 0, 1, 0),
306SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_DACLSL1_REG, 1, 1, 0),
307SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_DACLSL1_REG, 2, 1, 0),
308SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_DACLSL1_REG, 3, 1, 0),
309SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_DACLSL1_REG, 4, 1, 0),
310SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_DACLSL1_REG, 5, 1, 0),
311SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_DACLSL1_REG, 6, 1, 0),
312SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_DACLSL1_REG, 7, 1, 0),
313SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_DACLSL2_REG, 0, 1, 0),
314SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_DACLSL2_REG, 1, 1, 0),
315SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_DACLSL2_REG, 2, 1, 0),
316SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_DACLSL2_REG, 3, 1, 0),
317SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_DACLSL2_REG, 4, 1, 0),
318SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_DACLSL2_REG, 5, 1, 0),
319SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_DACLSL2_REG, 6, 1, 0),
320SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_DACLSL2_REG, 7, 1, 0),
321SOC_DAPM_SINGLE("Sidetone Switch", LM49453_P0_STN_SEL_REG, 2, 0, 0),
322};
323
324static const struct snd_kcontrol_new lm49453_speaker_right_mixer[] = {
325SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_DACLSR1_REG, 0, 1, 0),
326SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_DACLSR1_REG, 1, 1, 0),
327SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_DACLSR1_REG, 2, 1, 0),
328SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_DACLSR1_REG, 3, 1, 0),
329SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_DACLSR1_REG, 4, 1, 0),
330SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_DACLSR1_REG, 5, 1, 0),
331SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_DACLSR1_REG, 6, 1, 0),
332SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_DACLSR1_REG, 7, 1, 0),
333SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_DACLSR2_REG, 0, 1, 0),
334SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_DACLSR2_REG, 1, 1, 0),
335SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_DACLSR2_REG, 2, 1, 0),
336SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_DACLSR2_REG, 3, 1, 0),
337SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_DACLSR2_REG, 4, 1, 0),
338SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_DACLSR2_REG, 5, 1, 0),
339SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_DACLSR2_REG, 6, 1, 0),
340SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_DACLSR2_REG, 7, 1, 0),
341SOC_DAPM_SINGLE("Sidetone Switch", LM49453_P0_STN_SEL_REG, 3, 0, 0),
342};
343
344static const struct snd_kcontrol_new lm49453_haptic_left_mixer[] = {
345SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_DACHAL1_REG, 0, 1, 0),
346SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_DACHAL1_REG, 1, 1, 0),
347SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_DACHAL1_REG, 2, 1, 0),
348SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_DACHAL1_REG, 3, 1, 0),
349SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_DACHAL1_REG, 4, 1, 0),
350SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_DACHAL1_REG, 5, 1, 0),
351SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_DACHAL1_REG, 6, 1, 0),
352SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_DACHAL1_REG, 7, 1, 0),
353SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_DACHAL2_REG, 0, 1, 0),
354SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_DACHAL2_REG, 1, 1, 0),
355SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_DACHAL2_REG, 2, 1, 0),
356SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_DACHAL2_REG, 3, 1, 0),
357SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_DACHAL2_REG, 4, 1, 0),
358SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_DACHAL2_REG, 5, 1, 0),
359SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_DACHAL2_REG, 6, 1, 0),
360SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_DACHAL2_REG, 7, 1, 0),
361SOC_DAPM_SINGLE("Sidetone Switch", LM49453_P0_STN_SEL_REG, 4, 0, 0),
362};
363
364static const struct snd_kcontrol_new lm49453_haptic_right_mixer[] = {
365SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_DACHAR1_REG, 0, 1, 0),
366SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_DACHAR1_REG, 1, 1, 0),
367SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_DACHAR1_REG, 2, 1, 0),
368SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_DACHAR1_REG, 3, 1, 0),
369SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_DACHAR1_REG, 4, 1, 0),
370SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_DACHAR1_REG, 5, 1, 0),
371SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_DACHAR1_REG, 6, 1, 0),
372SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_DACHAR1_REG, 7, 1, 0),
373SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_DACHAR2_REG, 0, 1, 0),
374SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_DACHAR2_REG, 1, 1, 0),
375SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_DACHAR2_REG, 2, 1, 0),
376SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_DACHAR2_REG, 3, 1, 0),
377SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_DACHAR2_REG, 4, 1, 0),
378SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_DACHAR2_REG, 5, 1, 0),
379SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_DACHAR2_REG, 6, 1, 0),
380SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_DACHAR2_REG, 7, 1, 0),
381SOC_DAPM_SINGLE("Sidetone Switch", LM49453_P0_STN_SEL_REG, 5, 0, 0),
382};
383
384static const struct snd_kcontrol_new lm49453_lineout_left_mixer[] = {
385SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_DACLOL1_REG, 0, 1, 0),
386SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_DACLOL1_REG, 1, 1, 0),
387SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_DACLOL1_REG, 2, 1, 0),
388SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_DACLOL1_REG, 3, 1, 0),
389SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_DACLOL1_REG, 4, 1, 0),
390SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_DACLOL1_REG, 5, 1, 0),
391SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_DACLOL1_REG, 6, 1, 0),
392SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_DACLOL1_REG, 7, 1, 0),
393SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_DACLOL2_REG, 0, 1, 0),
394SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_DACLOL2_REG, 1, 1, 0),
395SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_DACLOL2_REG, 2, 1, 0),
396SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_DACLOL2_REG, 3, 1, 0),
397SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_DACLOL2_REG, 4, 1, 0),
398SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_DACLOL2_REG, 5, 1, 0),
399SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_DACLOL2_REG, 6, 1, 0),
400SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_DACLOL2_REG, 7, 1, 0),
401SOC_DAPM_SINGLE("Sidetone Switch", LM49453_P0_STN_SEL_REG, 6, 0, 0),
402};
403
404static const struct snd_kcontrol_new lm49453_lineout_right_mixer[] = {
405SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_DACLOR1_REG, 0, 1, 0),
406SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_DACLOR1_REG, 1, 1, 0),
407SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_DACLOR1_REG, 2, 1, 0),
408SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_DACLOR1_REG, 3, 1, 0),
409SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_DACLOR1_REG, 4, 1, 0),
410SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_DACLOR1_REG, 5, 1, 0),
411SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_DACLOR1_REG, 6, 1, 0),
412SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_DACLOR1_REG, 7, 1, 0),
413SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_DACLOR2_REG, 0, 1, 0),
414SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_DACLOR2_REG, 1, 1, 0),
415SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_DACLOR2_REG, 2, 1, 0),
416SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_DACLOR2_REG, 3, 1, 0),
417SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_DACLOR2_REG, 4, 1, 0),
418SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_DACLOR2_REG, 5, 1, 0),
419SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_DACLOR2_REG, 6, 1, 0),
420SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_DACLOR2_REG, 7, 1, 0),
421SOC_DAPM_SINGLE("Sidetone Switch", LM49453_P0_STN_SEL_REG, 7, 0, 0),
422};
423
424static const struct snd_kcontrol_new lm49453_port1_tx1_mixer[] = {
425SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT1_TX1_REG, 0, 1, 0),
426SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT1_TX1_REG, 1, 1, 0),
427SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT1_TX1_REG, 2, 1, 0),
428SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT1_TX1_REG, 3, 1, 0),
429SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT1_TX1_REG, 4, 1, 0),
430SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT1_TX1_REG, 5, 1, 0),
431SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_PORT1_TX1_REG, 6, 1, 0),
432SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_PORT1_TX1_REG, 7, 1, 0),
433};
434
435static const struct snd_kcontrol_new lm49453_port1_tx2_mixer[] = {
436SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT1_TX2_REG, 0, 1, 0),
437SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT1_TX2_REG, 1, 1, 0),
438SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT1_TX2_REG, 2, 1, 0),
439SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT1_TX2_REG, 3, 1, 0),
440SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT1_TX2_REG, 4, 1, 0),
441SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT1_TX2_REG, 5, 1, 0),
442SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_PORT1_TX2_REG, 6, 1, 0),
443SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_PORT1_TX2_REG, 7, 1, 0),
444};
445
446static const struct snd_kcontrol_new lm49453_port1_tx3_mixer[] = {
447SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT1_TX3_REG, 0, 1, 0),
448SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT1_TX3_REG, 1, 1, 0),
449SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT1_TX3_REG, 2, 1, 0),
450SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT1_TX3_REG, 3, 1, 0),
451SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT1_TX3_REG, 4, 1, 0),
452SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT1_TX3_REG, 5, 1, 0),
453SOC_DAPM_SINGLE("Port1_3 Switch", LM49453_P0_PORT1_TX3_REG, 6, 1, 0),
454};
455
456static const struct snd_kcontrol_new lm49453_port1_tx4_mixer[] = {
457SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT1_TX4_REG, 0, 1, 0),
458SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT1_TX4_REG, 1, 1, 0),
459SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT1_TX4_REG, 2, 1, 0),
460SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT1_TX4_REG, 3, 1, 0),
461SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT1_TX4_REG, 4, 1, 0),
462SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT1_TX4_REG, 5, 1, 0),
463SOC_DAPM_SINGLE("Port1_4 Switch", LM49453_P0_PORT1_TX4_REG, 6, 1, 0),
464};
465
466static const struct snd_kcontrol_new lm49453_port1_tx5_mixer[] = {
467SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT1_TX5_REG, 0, 1, 0),
468SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT1_TX5_REG, 1, 1, 0),
469SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT1_TX5_REG, 2, 1, 0),
470SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT1_TX5_REG, 3, 1, 0),
471SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT1_TX5_REG, 4, 1, 0),
472SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT1_TX5_REG, 5, 1, 0),
473SOC_DAPM_SINGLE("Port1_5 Switch", LM49453_P0_PORT1_TX5_REG, 6, 1, 0),
474};
475
476static const struct snd_kcontrol_new lm49453_port1_tx6_mixer[] = {
477SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT1_TX6_REG, 0, 1, 0),
478SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT1_TX6_REG, 1, 1, 0),
479SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT1_TX6_REG, 2, 1, 0),
480SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT1_TX6_REG, 3, 1, 0),
481SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT1_TX6_REG, 4, 1, 0),
482SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT1_TX6_REG, 5, 1, 0),
483SOC_DAPM_SINGLE("Port1_6 Switch", LM49453_P0_PORT1_TX6_REG, 6, 1, 0),
484};
485
486static const struct snd_kcontrol_new lm49453_port1_tx7_mixer[] = {
487SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT1_TX7_REG, 0, 1, 0),
488SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT1_TX7_REG, 1, 1, 0),
489SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT1_TX7_REG, 2, 1, 0),
490SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT1_TX7_REG, 3, 1, 0),
491SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT1_TX7_REG, 4, 1, 0),
492SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT1_TX7_REG, 5, 1, 0),
493SOC_DAPM_SINGLE("Port1_7 Switch", LM49453_P0_PORT1_TX7_REG, 6, 1, 0),
494};
495
496static const struct snd_kcontrol_new lm49453_port1_tx8_mixer[] = {
497SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT1_TX8_REG, 0, 1, 0),
498SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT1_TX8_REG, 1, 1, 0),
499SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT1_TX8_REG, 2, 1, 0),
500SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT1_TX8_REG, 3, 1, 0),
501SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT1_TX8_REG, 4, 1, 0),
502SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT1_TX8_REG, 5, 1, 0),
503SOC_DAPM_SINGLE("Port1_8 Switch", LM49453_P0_PORT1_TX8_REG, 6, 1, 0),
504};
505
506static const struct snd_kcontrol_new lm49453_port2_tx1_mixer[] = {
507SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT2_TX1_REG, 0, 1, 0),
508SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT2_TX1_REG, 1, 1, 0),
509SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT2_TX1_REG, 2, 1, 0),
510SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT2_TX1_REG, 3, 1, 0),
511SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT2_TX1_REG, 4, 1, 0),
512SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT2_TX1_REG, 5, 1, 0),
513SOC_DAPM_SINGLE("Port1_1 Switch", LM49453_P0_PORT2_TX1_REG, 6, 1, 0),
514SOC_DAPM_SINGLE("Port2_1 Switch", LM49453_P0_PORT2_TX1_REG, 7, 1, 0),
515};
516
517static const struct snd_kcontrol_new lm49453_port2_tx2_mixer[] = {
518SOC_DAPM_SINGLE("DMIC1L Switch", LM49453_P0_PORT2_TX2_REG, 0, 1, 0),
519SOC_DAPM_SINGLE("DMIC1R Switch", LM49453_P0_PORT2_TX2_REG, 1, 1, 0),
520SOC_DAPM_SINGLE("DMIC2L Switch", LM49453_P0_PORT2_TX2_REG, 2, 1, 0),
521SOC_DAPM_SINGLE("DMIC2R Switch", LM49453_P0_PORT2_TX2_REG, 3, 1, 0),
522SOC_DAPM_SINGLE("ADCL Switch", LM49453_P0_PORT2_TX2_REG, 4, 1, 0),
523SOC_DAPM_SINGLE("ADCR Switch", LM49453_P0_PORT2_TX2_REG, 5, 1, 0),
524SOC_DAPM_SINGLE("Port1_2 Switch", LM49453_P0_PORT2_TX2_REG, 6, 1, 0),
525SOC_DAPM_SINGLE("Port2_2 Switch", LM49453_P0_PORT2_TX2_REG, 7, 1, 0),
526};
527
528/* TLV Declarations */
529static const DECLARE_TLV_DB_SCALE(digital_tlv, -7650, 150, 1);
530static const DECLARE_TLV_DB_SCALE(port_tlv, 0, 600, 0);
531
532static const struct snd_kcontrol_new lm49453_sidetone_mixer_controls[] = {
533/* Sidetone supports mono only */
534SOC_DAPM_SINGLE_TLV("Sidetone ADCL Volume", LM49453_P0_STN_VOL_ADCL_REG,
535 0, 0x3F, 0, digital_tlv),
536SOC_DAPM_SINGLE_TLV("Sidetone ADCR Volume", LM49453_P0_STN_VOL_ADCR_REG,
537 0, 0x3F, 0, digital_tlv),
538SOC_DAPM_SINGLE_TLV("Sidetone DMIC1L Volume", LM49453_P0_STN_VOL_DMIC1L_REG,
539 0, 0x3F, 0, digital_tlv),
540SOC_DAPM_SINGLE_TLV("Sidetone DMIC1R Volume", LM49453_P0_STN_VOL_DMIC1R_REG,
541 0, 0x3F, 0, digital_tlv),
542SOC_DAPM_SINGLE_TLV("Sidetone DMIC2L Volume", LM49453_P0_STN_VOL_DMIC2L_REG,
543 0, 0x3F, 0, digital_tlv),
544SOC_DAPM_SINGLE_TLV("Sidetone DMIC2R Volume", LM49453_P0_STN_VOL_DMIC2R_REG,
545 0, 0x3F, 0, digital_tlv),
546};
547
548static const struct snd_kcontrol_new lm49453_snd_controls[] = {
549 /* mic1 and mic2 supports mono only */
550 SOC_SINGLE_TLV("Mic1 Volume", LM49453_P0_ADC_LEVELL_REG, 0, 6,
551 0, digital_tlv),
552 SOC_SINGLE_TLV("Mic2 Volume", LM49453_P0_ADC_LEVELR_REG, 0, 6,
553 0, digital_tlv),
554
555 SOC_DOUBLE_R_TLV("DMIC1 Volume", LM49453_P0_DMIC1_LEVELL_REG,
556 LM49453_P0_DMIC1_LEVELR_REG, 0, 6, 0, digital_tlv),
557 SOC_DOUBLE_R_TLV("DMIC2 Volume", LM49453_P0_DMIC2_LEVELL_REG,
558 LM49453_P0_DMIC2_LEVELR_REG, 0, 6, 0, digital_tlv),
559
560 SOC_DAPM_ENUM("Mic2Mode", lm49453_mic2mode_enum),
561 SOC_DAPM_ENUM("DMIC12 SRC", lm49453_dmic12_cfg_enum),
562 SOC_DAPM_ENUM("DMIC34 SRC", lm49453_dmic34_cfg_enum),
563
564 /* Capture path filter enable */
565 SOC_SINGLE("DMIC1 HPFilter Switch", LM49453_P0_ADC_FX_ENABLES_REG,
566 0, 1, 0),
567 SOC_SINGLE("DMIC2 HPFilter Switch", LM49453_P0_ADC_FX_ENABLES_REG,
568 1, 1, 0),
569 SOC_SINGLE("ADC HPFilter Switch", LM49453_P0_ADC_FX_ENABLES_REG,
570 2, 1, 0),
571
572 SOC_DOUBLE_R_TLV("DAC HP Volume", LM49453_P0_DAC_HP_LEVELL_REG,
573 LM49453_P0_DAC_HP_LEVELR_REG, 0, 6, 0, digital_tlv),
574 SOC_DOUBLE_R_TLV("DAC LO Volume", LM49453_P0_DAC_LO_LEVELL_REG,
575 LM49453_P0_DAC_LO_LEVELR_REG, 0, 6, 0, digital_tlv),
576 SOC_DOUBLE_R_TLV("DAC LS Volume", LM49453_P0_DAC_LS_LEVELL_REG,
577 LM49453_P0_DAC_LS_LEVELR_REG, 0, 6, 0, digital_tlv),
578 SOC_DOUBLE_R_TLV("DAC HA Volume", LM49453_P0_DAC_HA_LEVELL_REG,
579 LM49453_P0_DAC_HA_LEVELR_REG, 0, 6, 0, digital_tlv),
580
581 SOC_SINGLE_TLV("EP Volume", LM49453_P0_DAC_LS_LEVELL_REG,
582 0, 6, 0, digital_tlv),
583
584 SOC_SINGLE_TLV("PORT1_1_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL1_REG,
585 0, 3, 0, port_tlv),
586 SOC_SINGLE_TLV("PORT1_2_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL1_REG,
587 2, 3, 0, port_tlv),
588 SOC_SINGLE_TLV("PORT1_3_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL1_REG,
589 4, 3, 0, port_tlv),
590 SOC_SINGLE_TLV("PORT1_4_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL1_REG,
591 6, 3, 0, port_tlv),
592 SOC_SINGLE_TLV("PORT1_5_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL2_REG,
593 0, 3, 0, port_tlv),
594 SOC_SINGLE_TLV("PORT1_6_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL2_REG,
595 2, 3, 0, port_tlv),
596 SOC_SINGLE_TLV("PORT1_7_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL2_REG,
597 4, 3, 0, port_tlv),
598 SOC_SINGLE_TLV("PORT1_8_RX_LVL Volume", LM49453_P0_PORT1_RX_LVL2_REG,
599 6, 3, 0, port_tlv),
600
601 SOC_SINGLE_TLV("PORT2_1_RX_LVL Volume", LM49453_P0_PORT2_RX_LVL_REG,
602 0, 3, 0, port_tlv),
603 SOC_SINGLE_TLV("PORT2_2_RX_LVL Volume", LM49453_P0_PORT2_RX_LVL_REG,
604 2, 3, 0, port_tlv),
605
606 SOC_SINGLE("Port1 Playback Switch", LM49453_P0_AUDIO_PORT1_BASIC_REG,
607 1, 1, 0),
608 SOC_SINGLE("Port2 Playback Switch", LM49453_P0_AUDIO_PORT2_BASIC_REG,
609 1, 1, 0),
610 SOC_SINGLE("Port1 Capture Switch", LM49453_P0_AUDIO_PORT1_BASIC_REG,
611 2, 1, 0),
612 SOC_SINGLE("Port2 Capture Switch", LM49453_P0_AUDIO_PORT2_BASIC_REG,
613 2, 1, 0)
614
615};
616
617/* DAPM widgets */
618static const struct snd_soc_dapm_widget lm49453_dapm_widgets[] = {
619
620 /* All end points HP,EP, LS, Lineout and Haptic */
621 SND_SOC_DAPM_OUTPUT("HPOUTL"),
622 SND_SOC_DAPM_OUTPUT("HPOUTR"),
623 SND_SOC_DAPM_OUTPUT("EPOUT"),
624 SND_SOC_DAPM_OUTPUT("LSOUTL"),
625 SND_SOC_DAPM_OUTPUT("LSOUTR"),
626 SND_SOC_DAPM_OUTPUT("LOOUTR"),
627 SND_SOC_DAPM_OUTPUT("LOOUTL"),
628 SND_SOC_DAPM_OUTPUT("HAOUTL"),
629 SND_SOC_DAPM_OUTPUT("HAOUTR"),
630
631 SND_SOC_DAPM_INPUT("AMIC1"),
632 SND_SOC_DAPM_INPUT("AMIC2"),
633 SND_SOC_DAPM_INPUT("DMIC1DAT"),
634 SND_SOC_DAPM_INPUT("DMIC2DAT"),
635 SND_SOC_DAPM_INPUT("AUXL"),
636 SND_SOC_DAPM_INPUT("AUXR"),
637
638 SND_SOC_DAPM_PGA("PORT1_1_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
639 SND_SOC_DAPM_PGA("PORT1_2_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
640 SND_SOC_DAPM_PGA("PORT1_3_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
641 SND_SOC_DAPM_PGA("PORT1_4_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
642 SND_SOC_DAPM_PGA("PORT1_5_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
643 SND_SOC_DAPM_PGA("PORT1_6_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
644 SND_SOC_DAPM_PGA("PORT1_7_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
645 SND_SOC_DAPM_PGA("PORT1_8_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
646 SND_SOC_DAPM_PGA("PORT2_1_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
647 SND_SOC_DAPM_PGA("PORT2_2_RX", SND_SOC_NOPM, 0, 0, NULL, 0),
648
649 SND_SOC_DAPM_SUPPLY("AMIC1Bias", LM49453_P0_MICL_REG, 6, 0, NULL, 0),
650 SND_SOC_DAPM_SUPPLY("AMIC2Bias", LM49453_P0_MICR_REG, 6, 0, NULL, 0),
651
652 /* playback path driver enables */
653 SND_SOC_DAPM_OUT_DRV("Headset Switch",
654 LM49453_P0_PMC_SETUP_REG, 0, 0, NULL, 0),
655 SND_SOC_DAPM_OUT_DRV("Earpiece Switch",
656 LM49453_P0_EP_REG, 0, 0, NULL, 0),
657 SND_SOC_DAPM_OUT_DRV("Speaker Left Switch",
658 LM49453_P0_DIS_PKVL_FB_REG, 0, 1, NULL, 0),
659 SND_SOC_DAPM_OUT_DRV("Speaker Right Switch",
660 LM49453_P0_DIS_PKVL_FB_REG, 1, 1, NULL, 0),
661 SND_SOC_DAPM_OUT_DRV("Haptic Left Switch",
662 LM49453_P0_DIS_PKVL_FB_REG, 2, 1, NULL, 0),
663 SND_SOC_DAPM_OUT_DRV("Haptic Right Switch",
664 LM49453_P0_DIS_PKVL_FB_REG, 3, 1, NULL, 0),
665
666 /* DAC */
667 SND_SOC_DAPM_DAC("HPL DAC", "Headset", SND_SOC_NOPM, 0, 0),
668 SND_SOC_DAPM_DAC("HPR DAC", "Headset", SND_SOC_NOPM, 0, 0),
669 SND_SOC_DAPM_DAC("LSL DAC", "Speaker", SND_SOC_NOPM, 0, 0),
670 SND_SOC_DAPM_DAC("LSR DAC", "Speaker", SND_SOC_NOPM, 0, 0),
671 SND_SOC_DAPM_DAC("HAL DAC", "Haptic", SND_SOC_NOPM, 0, 0),
672 SND_SOC_DAPM_DAC("HAR DAC", "Haptic", SND_SOC_NOPM, 0, 0),
673 SND_SOC_DAPM_DAC("LOL DAC", "Lineout", SND_SOC_NOPM, 0, 0),
674 SND_SOC_DAPM_DAC("LOR DAC", "Lineout", SND_SOC_NOPM, 0, 0),
675
676
677 SND_SOC_DAPM_PGA("AUXL Input",
678 LM49453_P0_ANALOG_MIXER_ADC_REG, 2, 0, NULL, 0),
679 SND_SOC_DAPM_PGA("AUXR Input",
680 LM49453_P0_ANALOG_MIXER_ADC_REG, 3, 0, NULL, 0),
681
682 SND_SOC_DAPM_PGA("Sidetone", SND_SOC_NOPM, 0, 0, NULL, 0),
683
684 /* ADC */
685 SND_SOC_DAPM_ADC("DMIC1 Left", "Capture", SND_SOC_NOPM, 1, 0),
686 SND_SOC_DAPM_ADC("DMIC1 Right", "Capture", SND_SOC_NOPM, 1, 0),
687 SND_SOC_DAPM_ADC("DMIC2 Left", "Capture", SND_SOC_NOPM, 1, 0),
688 SND_SOC_DAPM_ADC("DMIC2 Right", "Capture", SND_SOC_NOPM, 1, 0),
689
690 SND_SOC_DAPM_ADC("ADC Left", "Capture", SND_SOC_NOPM, 1, 0),
691 SND_SOC_DAPM_ADC("ADC Right", "Capture", SND_SOC_NOPM, 0, 0),
692
693 SND_SOC_DAPM_MUX("ADCL Mux", SND_SOC_NOPM, 0, 0,
694 &lm49453_adcl_mux_control),
695 SND_SOC_DAPM_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0,
696 &lm49453_adcr_mux_control),
697
698 SND_SOC_DAPM_MUX("Mic1 Input",
699 SND_SOC_NOPM, 0, 0, &lm49453_adcl_mux_control),
700
701 SND_SOC_DAPM_MUX("Mic2 Input",
702 SND_SOC_NOPM, 0, 0, &lm49453_adcr_mux_control),
703
704 /* AIF */
705 SND_SOC_DAPM_AIF_IN("PORT1_SDI", NULL, 0,
706 LM49453_P0_PULL_CONFIG1_REG, 2, 0),
707 SND_SOC_DAPM_AIF_IN("PORT2_SDI", NULL, 0,
708 LM49453_P0_PULL_CONFIG1_REG, 6, 0),
709
710 SND_SOC_DAPM_AIF_OUT("PORT1_SDO", NULL, 0,
711 LM49453_P0_PULL_CONFIG1_REG, 3, 0),
712 SND_SOC_DAPM_AIF_OUT("PORT2_SDO", NULL, 0,
713 LM49453_P0_PULL_CONFIG1_REG, 7, 0),
714
715 /* Port1 TX controls */
716 SND_SOC_DAPM_OUT_DRV("P1_1_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
717 SND_SOC_DAPM_OUT_DRV("P1_2_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
718 SND_SOC_DAPM_OUT_DRV("P1_3_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
719 SND_SOC_DAPM_OUT_DRV("P1_4_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
720 SND_SOC_DAPM_OUT_DRV("P1_5_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
721 SND_SOC_DAPM_OUT_DRV("P1_6_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
722 SND_SOC_DAPM_OUT_DRV("P1_7_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
723 SND_SOC_DAPM_OUT_DRV("P1_8_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
724
725 /* Port2 TX controls */
726 SND_SOC_DAPM_OUT_DRV("P2_1_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
727 SND_SOC_DAPM_OUT_DRV("P2_2_TX", SND_SOC_NOPM, 0, 0, NULL, 0),
728
729 /* Sidetone Mixer */
730 SND_SOC_DAPM_MIXER("Sidetone Mixer", SND_SOC_NOPM, 0, 0,
731 lm49453_sidetone_mixer_controls,
732 ARRAY_SIZE(lm49453_sidetone_mixer_controls)),
733
734 /* DAC MIXERS */
735 SND_SOC_DAPM_MIXER("HPL Mixer", SND_SOC_NOPM, 0, 0,
736 lm49453_headset_left_mixer,
737 ARRAY_SIZE(lm49453_headset_left_mixer)),
738 SND_SOC_DAPM_MIXER("HPR Mixer", SND_SOC_NOPM, 0, 0,
739 lm49453_headset_right_mixer,
740 ARRAY_SIZE(lm49453_headset_right_mixer)),
741 SND_SOC_DAPM_MIXER("LOL Mixer", SND_SOC_NOPM, 0, 0,
742 lm49453_lineout_left_mixer,
743 ARRAY_SIZE(lm49453_lineout_left_mixer)),
744 SND_SOC_DAPM_MIXER("LOR Mixer", SND_SOC_NOPM, 0, 0,
745 lm49453_lineout_right_mixer,
746 ARRAY_SIZE(lm49453_lineout_right_mixer)),
747 SND_SOC_DAPM_MIXER("LSL Mixer", SND_SOC_NOPM, 0, 0,
748 lm49453_speaker_left_mixer,
749 ARRAY_SIZE(lm49453_speaker_left_mixer)),
750 SND_SOC_DAPM_MIXER("LSR Mixer", SND_SOC_NOPM, 0, 0,
751 lm49453_speaker_right_mixer,
752 ARRAY_SIZE(lm49453_speaker_right_mixer)),
753 SND_SOC_DAPM_MIXER("HAL Mixer", SND_SOC_NOPM, 0, 0,
754 lm49453_haptic_left_mixer,
755 ARRAY_SIZE(lm49453_haptic_left_mixer)),
756 SND_SOC_DAPM_MIXER("HAR Mixer", SND_SOC_NOPM, 0, 0,
757 lm49453_haptic_right_mixer,
758 ARRAY_SIZE(lm49453_haptic_right_mixer)),
759
760 /* Capture Mixer */
761 SND_SOC_DAPM_MIXER("Port1_1 Mixer", SND_SOC_NOPM, 0, 0,
762 lm49453_port1_tx1_mixer,
763 ARRAY_SIZE(lm49453_port1_tx1_mixer)),
764 SND_SOC_DAPM_MIXER("Port1_2 Mixer", SND_SOC_NOPM, 0, 0,
765 lm49453_port1_tx2_mixer,
766 ARRAY_SIZE(lm49453_port1_tx2_mixer)),
767 SND_SOC_DAPM_MIXER("Port1_3 Mixer", SND_SOC_NOPM, 0, 0,
768 lm49453_port1_tx3_mixer,
769 ARRAY_SIZE(lm49453_port1_tx3_mixer)),
770 SND_SOC_DAPM_MIXER("Port1_4 Mixer", SND_SOC_NOPM, 0, 0,
771 lm49453_port1_tx4_mixer,
772 ARRAY_SIZE(lm49453_port1_tx4_mixer)),
773 SND_SOC_DAPM_MIXER("Port1_5 Mixer", SND_SOC_NOPM, 0, 0,
774 lm49453_port1_tx5_mixer,
775 ARRAY_SIZE(lm49453_port1_tx5_mixer)),
776 SND_SOC_DAPM_MIXER("Port1_6 Mixer", SND_SOC_NOPM, 0, 0,
777 lm49453_port1_tx6_mixer,
778 ARRAY_SIZE(lm49453_port1_tx6_mixer)),
779 SND_SOC_DAPM_MIXER("Port1_7 Mixer", SND_SOC_NOPM, 0, 0,
780 lm49453_port1_tx7_mixer,
781 ARRAY_SIZE(lm49453_port1_tx7_mixer)),
782 SND_SOC_DAPM_MIXER("Port1_8 Mixer", SND_SOC_NOPM, 0, 0,
783 lm49453_port1_tx8_mixer,
784 ARRAY_SIZE(lm49453_port1_tx8_mixer)),
785
786 SND_SOC_DAPM_MIXER("Port2_1 Mixer", SND_SOC_NOPM, 0, 0,
787 lm49453_port2_tx1_mixer,
788 ARRAY_SIZE(lm49453_port2_tx1_mixer)),
789 SND_SOC_DAPM_MIXER("Port2_2 Mixer", SND_SOC_NOPM, 0, 0,
790 lm49453_port2_tx2_mixer,
791 ARRAY_SIZE(lm49453_port2_tx2_mixer)),
792};
793
794static const struct snd_soc_dapm_route lm49453_audio_map[] = {
795 /* Port SDI mapping */
796 { "PORT1_1_RX", "Port1 Playback Switch", "PORT1_SDI" },
797 { "PORT1_2_RX", "Port1 Playback Switch", "PORT1_SDI" },
798 { "PORT1_3_RX", "Port1 Playback Switch", "PORT1_SDI" },
799 { "PORT1_4_RX", "Port1 Playback Switch", "PORT1_SDI" },
800 { "PORT1_5_RX", "Port1 Playback Switch", "PORT1_SDI" },
801 { "PORT1_6_RX", "Port1 Playback Switch", "PORT1_SDI" },
802 { "PORT1_7_RX", "Port1 Playback Switch", "PORT1_SDI" },
803 { "PORT1_8_RX", "Port1 Playback Switch", "PORT1_SDI" },
804
805 { "PORT2_1_RX", "Port2 Playback Switch", "PORT2_SDI" },
806 { "PORT2_2_RX", "Port2 Playback Switch", "PORT2_SDI" },
807
808 /* HP mapping */
809 { "HPL Mixer", "Port1_1 Switch", "PORT1_1_RX" },
810 { "HPL Mixer", "Port1_2 Switch", "PORT1_2_RX" },
811 { "HPL Mixer", "Port1_3 Switch", "PORT1_3_RX" },
812 { "HPL Mixer", "Port1_4 Switch", "PORT1_4_RX" },
813 { "HPL Mixer", "Port1_5 Switch", "PORT1_5_RX" },
814 { "HPL Mixer", "Port1_6 Switch", "PORT1_6_RX" },
815 { "HPL Mixer", "Port1_7 Switch", "PORT1_7_RX" },
816 { "HPL Mixer", "Port1_8 Switch", "PORT1_8_RX" },
817
818 { "HPL Mixer", "Port2_1 Switch", "PORT2_1_RX" },
819 { "HPL Mixer", "Port2_2 Switch", "PORT2_2_RX" },
820
821 { "HPL Mixer", "ADCL Switch", "ADC Left" },
822 { "HPL Mixer", "ADCR Switch", "ADC Right" },
823 { "HPL Mixer", "DMIC1L Switch", "DMIC1 Left" },
824 { "HPL Mixer", "DMIC1R Switch", "DMIC1 Right" },
825 { "HPL Mixer", "DMIC2L Switch", "DMIC2 Left" },
826 { "HPL Mixer", "DMIC2R Switch", "DMIC2 Right" },
827 { "HPL Mixer", "Sidetone Switch", "Sidetone" },
828
829 { "HPL DAC", NULL, "HPL Mixer" },
830
831 { "HPR Mixer", "Port1_1 Switch", "PORT1_1_RX" },
832 { "HPR Mixer", "Port1_2 Switch", "PORT1_2_RX" },
833 { "HPR Mixer", "Port1_3 Switch", "PORT1_3_RX" },
834 { "HPR Mixer", "Port1_4 Switch", "PORT1_4_RX" },
835 { "HPR Mixer", "Port1_5 Switch", "PORT1_5_RX" },
836 { "HPR Mixer", "Port1_6 Switch", "PORT1_6_RX" },
837 { "HPR Mixer", "Port1_7 Switch", "PORT1_7_RX" },
838 { "HPR Mixer", "Port1_8 Switch", "PORT1_8_RX" },
839
840 /* Port 2 */
841 { "HPR Mixer", "Port2_1 Switch", "PORT2_1_RX" },
842 { "HPR Mixer", "Port2_2 Switch", "PORT2_2_RX" },
843
844 { "HPR Mixer", "ADCL Switch", "ADC Left" },
845 { "HPR Mixer", "ADCR Switch", "ADC Right" },
846 { "HPR Mixer", "DMIC1L Switch", "DMIC1 Left" },
847 { "HPR Mixer", "DMIC1R Switch", "DMIC1 Right" },
848 { "HPR Mixer", "DMIC2L Switch", "DMIC2 Left" },
849 { "HPR Mixer", "DMIC2L Switch", "DMIC2 Right" },
850 { "HPR Mixer", "Sidetone Switch", "Sidetone" },
851
852 { "HPR DAC", NULL, "HPR Mixer" },
853
854 { "HPOUTL", "Headset Switch", "HPL DAC"},
855 { "HPOUTR", "Headset Switch", "HPR DAC"},
856
857 /* EP map */
858 { "EPOUT", "Earpiece Switch", "HPL DAC" },
859
860 /* Speaker map */
861 { "LSL Mixer", "Port1_1 Switch", "PORT1_1_RX" },
862 { "LSL Mixer", "Port1_2 Switch", "PORT1_2_RX" },
863 { "LSL Mixer", "Port1_3 Switch", "PORT1_3_RX" },
864 { "LSL Mixer", "Port1_4 Switch", "PORT1_4_RX" },
865 { "LSL Mixer", "Port1_5 Switch", "PORT1_5_RX" },
866 { "LSL Mixer", "Port1_6 Switch", "PORT1_6_RX" },
867 { "LSL Mixer", "Port1_7 Switch", "PORT1_7_RX" },
868 { "LSL Mixer", "Port1_8 Switch", "PORT1_8_RX" },
869
870 /* Port 2 */
871 { "LSL Mixer", "Port2_1 Switch", "PORT2_1_RX" },
872 { "LSL Mixer", "Port2_2 Switch", "PORT2_2_RX" },
873
874 { "LSL Mixer", "ADCL Switch", "ADC Left" },
875 { "LSL Mixer", "ADCR Switch", "ADC Right" },
876 { "LSL Mixer", "DMIC1L Switch", "DMIC1 Left" },
877 { "LSL Mixer", "DMIC1R Switch", "DMIC1 Right" },
878 { "LSL Mixer", "DMIC2L Switch", "DMIC2 Left" },
879 { "LSL Mixer", "DMIC2R Switch", "DMIC2 Right" },
880 { "LSL Mixer", "Sidetone Switch", "Sidetone" },
881
882 { "LSL DAC", NULL, "LSL Mixer" },
883
884 { "LSR Mixer", "Port1_1 Switch", "PORT1_1_RX" },
885 { "LSR Mixer", "Port1_2 Switch", "PORT1_2_RX" },
886 { "LSR Mixer", "Port1_3 Switch", "PORT1_3_RX" },
887 { "LSR Mixer", "Port1_4 Switch", "PORT1_4_RX" },
888 { "LSR Mixer", "Port1_5 Switch", "PORT1_5_RX" },
889 { "LSR Mixer", "Port1_6 Switch", "PORT1_6_RX" },
890 { "LSR Mixer", "Port1_7 Switch", "PORT1_7_RX" },
891 { "LSR Mixer", "Port1_8 Switch", "PORT1_8_RX" },
892
893 /* Port 2 */
894 { "LSR Mixer", "Port2_1 Switch", "PORT2_1_RX" },
895 { "LSR Mixer", "Port2_2 Switch", "PORT2_2_RX" },
896
897 { "LSR Mixer", "ADCL Switch", "ADC Left" },
898 { "LSR Mixer", "ADCR Switch", "ADC Right" },
899 { "LSR Mixer", "DMIC1L Switch", "DMIC1 Left" },
900 { "LSR Mixer", "DMIC1R Switch", "DMIC1 Right" },
901 { "LSR Mixer", "DMIC2L Switch", "DMIC2 Left" },
902 { "LSR Mixer", "DMIC2R Switch", "DMIC2 Right" },
903 { "LSR Mixer", "Sidetone Switch", "Sidetone" },
904
905 { "LSR DAC", NULL, "LSR Mixer" },
906
907 { "LSOUTL", "Speaker Left Switch", "LSL DAC"},
908 { "LSOUTR", "Speaker Left Switch", "LSR DAC"},
909
910 /* Haptic map */
911 { "HAL Mixer", "Port1_1 Switch", "PORT1_1_RX" },
912 { "HAL Mixer", "Port1_2 Switch", "PORT1_2_RX" },
913 { "HAL Mixer", "Port1_3 Switch", "PORT1_3_RX" },
914 { "HAL Mixer", "Port1_4 Switch", "PORT1_4_RX" },
915 { "HAL Mixer", "Port1_5 Switch", "PORT1_5_RX" },
916 { "HAL Mixer", "Port1_6 Switch", "PORT1_6_RX" },
917 { "HAL Mixer", "Port1_7 Switch", "PORT1_7_RX" },
918 { "HAL Mixer", "Port1_8 Switch", "PORT1_8_RX" },
919
920 /* Port 2 */
921 { "HAL Mixer", "Port2_1 Switch", "PORT2_1_RX" },
922 { "HAL Mixer", "Port2_2 Switch", "PORT2_2_RX" },
923
924 { "HAL Mixer", "ADCL Switch", "ADC Left" },
925 { "HAL Mixer", "ADCR Switch", "ADC Right" },
926 { "HAL Mixer", "DMIC1L Switch", "DMIC1 Left" },
927 { "HAL Mixer", "DMIC1R Switch", "DMIC1 Right" },
928 { "HAL Mixer", "DMIC2L Switch", "DMIC2 Left" },
929 { "HAL Mixer", "DMIC2R Switch", "DMIC2 Right" },
930 { "HAL Mixer", "Sidetone Switch", "Sidetone" },
931
932 { "HAL DAC", NULL, "HAL Mixer" },
933
934 { "HAR Mixer", "Port1_1 Switch", "PORT1_1_RX" },
935 { "HAR Mixer", "Port1_2 Switch", "PORT1_2_RX" },
936 { "HAR Mixer", "Port1_3 Switch", "PORT1_3_RX" },
937 { "HAR Mixer", "Port1_4 Switch", "PORT1_4_RX" },
938 { "HAR Mixer", "Port1_5 Switch", "PORT1_5_RX" },
939 { "HAR Mixer", "Port1_6 Switch", "PORT1_6_RX" },
940 { "HAR Mixer", "Port1_7 Switch", "PORT1_7_RX" },
941 { "HAR Mixer", "Port1_8 Switch", "PORT1_8_RX" },
942
943 /* Port 2 */
944 { "HAR Mixer", "Port2_1 Switch", "PORT2_1_RX" },
945 { "HAR Mixer", "Port2_2 Switch", "PORT2_2_RX" },
946
947 { "HAR Mixer", "ADCL Switch", "ADC Left" },
948 { "HAR Mixer", "ADCR Switch", "ADC Right" },
949 { "HAR Mixer", "DMIC1L Switch", "DMIC1 Left" },
950 { "HAR Mixer", "DMIC1R Switch", "DMIC1 Right" },
951 { "HAR Mixer", "DMIC2L Switch", "DMIC2 Left" },
952 { "HAR Mixer", "DMIC2R Switch", "DMIC2 Right" },
953 { "HAR Mixer", "Sideton Switch", "Sidetone" },
954
955 { "HAR DAC", NULL, "HAR Mixer" },
956
957 { "HAOUTL", "Haptic Left Switch", "HAL DAC" },
958 { "HAOUTR", "Haptic Right Switch", "HAR DAC" },
959
960 /* Lineout map */
961 { "LOL Mixer", "Port1_1 Switch", "PORT1_1_RX" },
962 { "LOL Mixer", "Port1_2 Switch", "PORT1_2_RX" },
963 { "LOL Mixer", "Port1_3 Switch", "PORT1_3_RX" },
964 { "LOL Mixer", "Port1_4 Switch", "PORT1_4_RX" },
965 { "LOL Mixer", "Port1_5 Switch", "PORT1_5_RX" },
966 { "LOL Mixer", "Port1_6 Switch", "PORT1_6_RX" },
967 { "LOL Mixer", "Port1_7 Switch", "PORT1_7_RX" },
968 { "LOL Mixer", "Port1_8 Switch", "PORT1_8_RX" },
969
970 /* Port 2 */
971 { "LOL Mixer", "Port2_1 Switch", "PORT2_1_RX" },
972 { "LOL Mixer", "Port2_2 Switch", "PORT2_2_RX" },
973
974 { "LOL Mixer", "ADCL Switch", "ADC Left" },
975 { "LOL Mixer", "ADCR Switch", "ADC Right" },
976 { "LOL Mixer", "DMIC1L Switch", "DMIC1 Left" },
977 { "LOL Mixer", "DMIC1R Switch", "DMIC1 Right" },
978 { "LOL Mixer", "DMIC2L Switch", "DMIC2 Left" },
979 { "LOL Mixer", "DMIC2R Switch", "DMIC2 Right" },
980 { "LOL Mixer", "Sidetone Switch", "Sidetone" },
981
982 { "LOL DAC", NULL, "LOL Mixer" },
983
984 { "LOR Mixer", "Port1_1 Switch", "PORT1_1_RX" },
985 { "LOR Mixer", "Port1_2 Switch", "PORT1_2_RX" },
986 { "LOR Mixer", "Port1_3 Switch", "PORT1_3_RX" },
987 { "LOR Mixer", "Port1_4 Switch", "PORT1_4_RX" },
988 { "LOR Mixer", "Port1_5 Switch", "PORT1_5_RX" },
989 { "LOR Mixer", "Port1_6 Switch", "PORT1_6_RX" },
990 { "LOR Mixer", "Port1_7 Switch", "PORT1_7_RX" },
991 { "LOR Mixer", "Port1_8 Switch", "PORT1_8_RX" },
992
993 /* Port 2 */
994 { "LOR Mixer", "Port2_1 Switch", "PORT2_1_RX" },
995 { "LOR Mixer", "Port2_2 Switch", "PORT2_2_RX" },
996
997 { "LOR Mixer", "ADCL Switch", "ADC Left" },
998 { "LOR Mixer", "ADCR Switch", "ADC Right" },
999 { "LOR Mixer", "DMIC1L Switch", "DMIC1 Left" },
1000 { "LOR Mixer", "DMIC1R Switch", "DMIC1 Right" },
1001 { "LOR Mixer", "DMIC2L Switch", "DMIC2 Left" },
1002 { "LOR Mixer", "DMIC2R Switch", "DMIC2 Right" },
1003 { "LOR Mixer", "Sidetone Switch", "Sidetone" },
1004
1005 { "LOR DAC", NULL, "LOR Mixer" },
1006
1007 { "LOOUTL", NULL, "LOL DAC" },
1008 { "LOOUTR", NULL, "LOR DAC" },
1009
1010 /* TX map */
1011 /* Port1 mappings */
1012 { "Port1_1 Mixer", "ADCL Switch", "ADC Left" },
1013 { "Port1_1 Mixer", "ADCR Switch", "ADC Right" },
1014 { "Port1_1 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1015 { "Port1_1 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1016 { "Port1_1 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1017 { "Port1_1 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1018
1019 { "Port1_2 Mixer", "ADCL Switch", "ADC Left" },
1020 { "Port1_2 Mixer", "ADCR Switch", "ADC Right" },
1021 { "Port1_2 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1022 { "Port1_2 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1023 { "Port1_2 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1024 { "Port1_2 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1025
1026 { "Port1_3 Mixer", "ADCL Switch", "ADC Left" },
1027 { "Port1_3 Mixer", "ADCR Switch", "ADC Right" },
1028 { "Port1_3 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1029 { "Port1_3 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1030 { "Port1_3 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1031 { "Port1_3 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1032
1033 { "Port1_4 Mixer", "ADCL Switch", "ADC Left" },
1034 { "Port1_4 Mixer", "ADCR Switch", "ADC Right" },
1035 { "Port1_4 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1036 { "Port1_4 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1037 { "Port1_4 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1038 { "Port1_4 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1039
1040 { "Port1_5 Mixer", "ADCL Switch", "ADC Left" },
1041 { "Port1_5 Mixer", "ADCR Switch", "ADC Right" },
1042 { "Port1_5 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1043 { "Port1_5 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1044 { "Port1_5 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1045 { "Port1_5 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1046
1047 { "Port1_6 Mixer", "ADCL Switch", "ADC Left" },
1048 { "Port1_6 Mixer", "ADCR Switch", "ADC Right" },
1049 { "Port1_6 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1050 { "Port1_6 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1051 { "Port1_6 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1052 { "Port1_6 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1053
1054 { "Port1_7 Mixer", "ADCL Switch", "ADC Left" },
1055 { "Port1_7 Mixer", "ADCR Switch", "ADC Right" },
1056 { "Port1_7 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1057 { "Port1_7 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1058 { "Port1_7 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1059 { "Port1_7 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1060
1061 { "Port1_8 Mixer", "ADCL Switch", "ADC Left" },
1062 { "Port1_8 Mixer", "ADCR Switch", "ADC Right" },
1063 { "Port1_8 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1064 { "Port1_8 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1065 { "Port1_8 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1066 { "Port1_8 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1067
1068 { "Port2_1 Mixer", "ADCL Switch", "ADC Left" },
1069 { "Port2_1 Mixer", "ADCR Switch", "ADC Right" },
1070 { "Port2_1 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1071 { "Port2_1 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1072 { "Port2_1 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1073 { "Port2_1 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1074
1075 { "Port2_2 Mixer", "ADCL Switch", "ADC Left" },
1076 { "Port2_2 Mixer", "ADCR Switch", "ADC Right" },
1077 { "Port2_2 Mixer", "DMIC1L Switch", "DMIC1 Left" },
1078 { "Port2_2 Mixer", "DMIC1R Switch", "DMIC1 Right" },
1079 { "Port2_2 Mixer", "DMIC2L Switch", "DMIC2 Left" },
1080 { "Port2_2 Mixer", "DMIC2R Switch", "DMIC2 Right" },
1081
1082 { "P1_1_TX", NULL, "Port1_1 Mixer" },
1083 { "P1_2_TX", NULL, "Port1_2 Mixer" },
1084 { "P1_3_TX", NULL, "Port1_3 Mixer" },
1085 { "P1_4_TX", NULL, "Port1_4 Mixer" },
1086 { "P1_5_TX", NULL, "Port1_5 Mixer" },
1087 { "P1_6_TX", NULL, "Port1_6 Mixer" },
1088 { "P1_7_TX", NULL, "Port1_7 Mixer" },
1089 { "P1_8_TX", NULL, "Port1_8 Mixer" },
1090
1091 { "P2_1_TX", NULL, "Port2_1 Mixer" },
1092 { "P2_2_TX", NULL, "Port2_2 Mixer" },
1093
1094 { "PORT1_SDO", "Port1 Capture Switch", "P1_1_TX"},
1095 { "PORT1_SDO", "Port1 Capture Switch", "P1_2_TX"},
1096 { "PORT1_SDO", "Port1 Capture Switch", "P1_3_TX"},
1097 { "PORT1_SDO", "Port1 Capture Switch", "P1_4_TX"},
1098 { "PORT1_SDO", "Port1 Capture Switch", "P1_5_TX"},
1099 { "PORT1_SDO", "Port1 Capture Switch", "P1_6_TX"},
1100 { "PORT1_SDO", "Port1 Capture Switch", "P1_7_TX"},
1101 { "PORT1_SDO", "Port1 Capture Switch", "P1_8_TX"},
1102
1103 { "PORT2_SDO", "Port2 Capture Switch", "P2_1_TX"},
1104 { "PORT2_SDO", "Port2 Capture Switch", "P2_2_TX"},
1105
1106 { "Mic1 Input", NULL, "AMIC1" },
1107 { "Mic2 Input", NULL, "AMIC2" },
1108
1109 { "AUXL Input", NULL, "AUXL" },
1110 { "AUXR Input", NULL, "AUXR" },
1111
1112 /* AUX connections */
1113 { "ADCL Mux", "Aux_L", "AUXL Input" },
1114 { "ADCL Mux", "MIC1", "Mic1 Input" },
1115
1116 { "ADCR Mux", "Aux_R", "AUXR Input" },
1117 { "ADCR Mux", "MIC2", "Mic2 Input" },
1118
1119 /* ADC connection */
1120 { "ADC Left", NULL, "ADCL Mux"},
1121 { "ADC Right", NULL, "ADCR Mux"},
1122
1123 { "DMIC1 Left", NULL, "DMIC1DAT"},
1124 { "DMIC1 Right", NULL, "DMIC1DAT"},
1125 { "DMIC2 Left", NULL, "DMIC2DAT"},
1126 { "DMIC2 Right", NULL, "DMIC2DAT"},
1127
1128 /* Sidetone map */
1129 { "Sidetone Mixer", NULL, "ADC Left" },
1130 { "Sidetone Mixer", NULL, "ADC Right" },
1131 { "Sidetone Mixer", NULL, "DMIC1 Left" },
1132 { "Sidetone Mixer", NULL, "DMIC1 Right" },
1133 { "Sidetone Mixer", NULL, "DMIC2 Left" },
1134 { "Sidetone Mixer", NULL, "DMIC2 Right" },
1135
1136 { "Sidetone", "Sidetone Switch", "Sidetone Mixer" },
1137};
1138
1139static int lm49453_hw_params(struct snd_pcm_substream *substream,
1140 struct snd_pcm_hw_params *params,
1141 struct snd_soc_dai *dai)
1142{
1143 struct snd_soc_codec *codec = dai->codec;
1144 struct lm49453_priv *lm49453 = snd_soc_codec_get_drvdata(codec);
1145 u16 clk_div = 0;
1146
1147 lm49453->fs_rate = params_rate(params);
1148
1149 /* Setting DAC clock dividers based on substream sample rate. */
1150 switch (lm49453->fs_rate) {
1151 case 8000:
1152 case 16000:
1153 case 32000:
1154 case 24000:
1155 case 48000:
1156 clk_div = 256;
1157 break;
1158 case 11025:
1159 case 22050:
1160 case 44100:
1161 clk_div = 216;
1162 break;
1163 case 96000:
1164 clk_div = 127;
1165 break;
1166 default:
1167 return -EINVAL;
1168 }
1169
1170 snd_soc_write(codec, LM49453_P0_ADC_CLK_DIV_REG, clk_div);
1171 snd_soc_write(codec, LM49453_P0_DAC_HP_CLK_DIV_REG, clk_div);
1172
1173 return 0;
1174}
1175
1176static int lm49453_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1177{
1178 struct snd_soc_codec *codec = codec_dai->codec;
1179
1180 u16 aif_val;
1181 int mode = 0;
1182 int clk_phase = 0;
1183 int clk_shift = 0;
1184
1185 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1186 case SND_SOC_DAIFMT_CBS_CFS:
1187 aif_val = 0;
1188 break;
1189 case SND_SOC_DAIFMT_CBS_CFM:
1190 aif_val = LM49453_AUDIO_PORT1_BASIC_SYNC_MS;
1191 break;
1192 case SND_SOC_DAIFMT_CBM_CFS:
1193 aif_val = LM49453_AUDIO_PORT1_BASIC_CLK_MS;
1194 break;
1195 case SND_SOC_DAIFMT_CBM_CFM:
1196 aif_val = LM49453_AUDIO_PORT1_BASIC_CLK_MS |
1197 LM49453_AUDIO_PORT1_BASIC_SYNC_MS;
1198 break;
1199 default:
1200 return -EINVAL;
1201 }
1202
1203
1204 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1205 case SND_SOC_DAIFMT_I2S:
1206 break;
1207 case SND_SOC_DAIFMT_DSP_A:
1208 mode = 1;
1209 clk_phase = (1 << 5);
1210 clk_shift = 1;
1211 break;
1212 case SND_SOC_DAIFMT_DSP_B:
1213 mode = 1;
1214 clk_phase = (1 << 5);
1215 clk_shift = 0;
1216 break;
1217 default:
1218 return -EINVAL;
1219 }
1220
1221 snd_soc_update_bits(codec, LM49453_P0_AUDIO_PORT1_BASIC_REG,
1222 LM49453_AUDIO_PORT1_BASIC_FMT_MASK|BIT(1)|BIT(5),
1223 (aif_val | mode | clk_phase));
1224
1225 snd_soc_write(codec, LM49453_P0_AUDIO_PORT1_RX_MSB_REG, clk_shift);
1226
1227 return 0;
1228}
1229
1230static int lm49453_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
1231 unsigned int freq, int dir)
1232{
1233 struct snd_soc_codec *codec = dai->codec;
1234 u16 pll_clk = 0;
1235
1236 switch (freq) {
1237 case 12288000:
1238 case 26000000:
1239 case 19200000:
1240 /* pll clk slection */
1241 pll_clk = 0;
1242 break;
1243 case 48000:
1244 case 32576:
1245 /* fll clk slection */
1246 pll_clk = BIT(4);
1247 return 0;
1248 default:
1249 return -EINVAL;
1250 }
1251
1252 snd_soc_update_bits(codec, LM49453_P0_PMC_SETUP_REG, BIT(4), pll_clk);
1253
1254 return 0;
1255}
1256
1257static int lm49453_hp_mute(struct snd_soc_dai *dai, int mute)
1258{
1259 snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(1)|BIT(0),
1260 (mute ? (BIT(1)|BIT(0)) : 0));
1261 return 0;
1262}
1263
1264static int lm49453_lo_mute(struct snd_soc_dai *dai, int mute)
1265{
1266 snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(3)|BIT(2),
1267 (mute ? (BIT(3)|BIT(2)) : 0));
1268 return 0;
1269}
1270
1271static int lm49453_ls_mute(struct snd_soc_dai *dai, int mute)
1272{
1273 snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(5)|BIT(4),
1274 (mute ? (BIT(5)|BIT(4)) : 0));
1275 return 0;
1276}
1277
1278static int lm49453_ep_mute(struct snd_soc_dai *dai, int mute)
1279{
1280 snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(4),
1281 (mute ? BIT(4) : 0));
1282 return 0;
1283}
1284
1285static int lm49453_ha_mute(struct snd_soc_dai *dai, int mute)
1286{
1287 snd_soc_update_bits(dai->codec, LM49453_P0_DAC_DSP_REG, BIT(7)|BIT(6),
1288 (mute ? (BIT(7)|BIT(6)) : 0));
1289 return 0;
1290}
1291
1292static int lm49453_set_bias_level(struct snd_soc_codec *codec,
1293 enum snd_soc_bias_level level)
1294{
1295 struct lm49453_priv *lm49453 = snd_soc_codec_get_drvdata(codec);
1296
1297 switch (level) {
1298 case SND_SOC_BIAS_ON:
1299 case SND_SOC_BIAS_PREPARE:
1300 break;
1301
1302 case SND_SOC_BIAS_STANDBY:
1303 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
1304 regcache_sync(lm49453->regmap);
1305
1306 snd_soc_update_bits(codec, LM49453_P0_PMC_SETUP_REG,
1307 LM49453_PMC_SETUP_CHIP_EN, LM49453_CHIP_EN);
1308 break;
1309
1310 case SND_SOC_BIAS_OFF:
1311 snd_soc_update_bits(codec, LM49453_P0_PMC_SETUP_REG,
1312 LM49453_PMC_SETUP_CHIP_EN, 0);
1313 break;
1314 }
1315
1316 codec->dapm.bias_level = level;
1317
1318 return 0;
1319}
1320
1321/* Formates supported by LM49453 driver. */
1322#define LM49453_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1323 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1324
1325static struct snd_soc_dai_ops lm49453_headset_dai_ops = {
1326 .hw_params = lm49453_hw_params,
1327 .set_sysclk = lm49453_set_dai_sysclk,
1328 .set_fmt = lm49453_set_dai_fmt,
1329 .digital_mute = lm49453_hp_mute,
1330};
1331
1332static struct snd_soc_dai_ops lm49453_speaker_dai_ops = {
1333 .hw_params = lm49453_hw_params,
1334 .set_sysclk = lm49453_set_dai_sysclk,
1335 .set_fmt = lm49453_set_dai_fmt,
1336 .digital_mute = lm49453_ls_mute,
1337};
1338
1339static struct snd_soc_dai_ops lm49453_haptic_dai_ops = {
1340 .hw_params = lm49453_hw_params,
1341 .set_sysclk = lm49453_set_dai_sysclk,
1342 .set_fmt = lm49453_set_dai_fmt,
1343 .digital_mute = lm49453_ha_mute,
1344};
1345
1346static struct snd_soc_dai_ops lm49453_ep_dai_ops = {
1347 .hw_params = lm49453_hw_params,
1348 .set_sysclk = lm49453_set_dai_sysclk,
1349 .set_fmt = lm49453_set_dai_fmt,
1350 .digital_mute = lm49453_ep_mute,
1351};
1352
1353static struct snd_soc_dai_ops lm49453_lineout_dai_ops = {
1354 .hw_params = lm49453_hw_params,
1355 .set_sysclk = lm49453_set_dai_sysclk,
1356 .set_fmt = lm49453_set_dai_fmt,
1357 .digital_mute = lm49453_lo_mute,
1358};
1359
1360/* LM49453 dai structure. */
1361static const struct snd_soc_dai_driver lm49453_dai[] = {
1362 {
1363 .name = "LM49453 Headset",
1364 .playback = {
1365 .stream_name = "Headset",
1366 .channels_min = 2,
1367 .channels_max = 2,
1368 .rates = SNDRV_PCM_RATE_8000_192000,
1369 .formats = LM49453_FORMATS,
1370 },
1371 .capture = {
1372 .stream_name = "Capture",
1373 .channels_min = 1,
1374 .channels_max = 5,
1375 .rates = SNDRV_PCM_RATE_8000_192000,
1376 .formats = LM49453_FORMATS,
1377 },
1378 .ops = &lm49453_headset_dai_ops,
1379 .symmetric_rates = 1,
1380 },
1381 {
1382 .name = "LM49453 Speaker",
1383 .playback = {
1384 .stream_name = "Speaker",
1385 .channels_min = 2,
1386 .channels_max = 2,
1387 .rates = SNDRV_PCM_RATE_8000_192000,
1388 .formats = LM49453_FORMATS,
1389 },
1390 .ops = &lm49453_speaker_dai_ops,
1391 },
1392 {
1393 .name = "LM49453 Haptic",
1394 .playback = {
1395 .stream_name = "Haptic",
1396 .channels_min = 2,
1397 .channels_max = 2,
1398 .rates = SNDRV_PCM_RATE_8000_192000,
1399 .formats = LM49453_FORMATS,
1400 },
1401 .ops = &lm49453_haptic_dai_ops,
1402 },
1403 {
1404 .name = "LM49453 Earpiece",
1405 .playback = {
1406 .stream_name = "Earpiece",
1407 .channels_min = 1,
1408 .channels_max = 1,
1409 .rates = SNDRV_PCM_RATE_8000_192000,
1410 .formats = LM49453_FORMATS,
1411 },
1412 .ops = &lm49453_ep_dai_ops,
1413 },
1414 {
1415 .name = "LM49453 line out",
1416 .playback = {
1417 .stream_name = "Lineout",
1418 .channels_min = 2,
1419 .channels_max = 2,
1420 .rates = SNDRV_PCM_RATE_8000_192000,
1421 .formats = LM49453_FORMATS,
1422 },
1423 .ops = &lm49453_lineout_dai_ops,
1424 },
1425};
1426
1427static int lm49453_suspend(struct snd_soc_codec *codec)
1428{
1429 lm49453_set_bias_level(codec, SND_SOC_BIAS_OFF);
1430 return 0;
1431}
1432
1433static int lm49453_resume(struct snd_soc_codec *codec)
1434{
1435 lm49453_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1436 return 0;
1437}
1438
1439static int lm49453_probe(struct snd_soc_codec *codec)
1440{
1441 struct lm49453_priv *lm49453 = snd_soc_codec_get_drvdata(codec);
1442 int ret = 0;
1443
1444 codec->control_data = lm49453->regmap;
1445
1446 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
1447 if (ret < 0) {
1448 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1449 return ret;
1450 }
1451
1452 return 0;
1453}
1454
1455/* power down chip */
1456static int lm49453_remove(struct snd_soc_codec *codec)
1457{
1458 lm49453_set_bias_level(codec, SND_SOC_BIAS_OFF);
1459 return 0;
1460}
1461
1462static struct snd_soc_codec_driver soc_codec_dev_lm49453 = {
1463 .probe = lm49453_probe,
1464 .remove = lm49453_remove,
1465 .suspend = lm49453_suspend,
1466 .resume = lm49453_resume,
1467 .set_bias_level = lm49453_set_bias_level,
1468 .controls = lm49453_snd_controls,
1469 .num_controls = ARRAY_SIZE(lm49453_snd_controls),
1470 .dapm_widgets = lm49453_dapm_widgets,
1471 .num_dapm_widgets = ARRAY_SIZE(lm49453_dapm_widgets),
1472 .dapm_routes = lm49453_audio_map,
1473 .num_dapm_routes = ARRAY_SIZE(lm49453_audio_map),
1474 .idle_bias_off = true,
1475};
1476
1477static const struct regmap_config lm49453_regmap_config = {
1478 .reg_bits = 8,
1479 .val_bits = 8,
1480
1481 .max_register = LM49453_MAX_REGISTER,
1482 .reg_defaults = lm49453_reg_defs,
1483 .num_reg_defaults = ARRAY_SIZE(lm49453_reg_defs),
1484 .cache_type = REGCACHE_RBTREE,
1485};
1486
1487static __devinit int lm49453_i2c_probe(struct i2c_client *i2c,
1488 const struct i2c_device_id *id)
1489{
1490 struct lm49453_priv *lm49453;
1491 int ret = 0;
1492
1493 lm49453 = devm_kzalloc(&i2c->dev, sizeof(struct lm49453_priv),
1494 GFP_KERNEL);
1495
1496 if (lm49453 == NULL)
1497 return -ENOMEM;
1498
1499 i2c_set_clientdata(i2c, lm49453);
1500
1501 lm49453->regmap = regmap_init_i2c(i2c, &lm49453_regmap_config);
1502 if (IS_ERR(lm49453->regmap)) {
1503 ret = PTR_ERR(lm49453->regmap);
1504 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
1505 ret);
1506 return ret;
1507 }
1508
1509 ret = snd_soc_register_codec(&i2c->dev,
1510 &soc_codec_dev_lm49453,
1511 lm49453_dai, ARRAY_SIZE(lm49453_dai));
1512 if (ret < 0) {
1513 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1514 regmap_exit(lm49453->regmap);
1515 return ret;
1516 }
1517
1518 return ret;
1519}
1520
1521static int __devexit lm49453_i2c_remove(struct i2c_client *client)
1522{
1523 struct lm49453_priv *lm49453 = i2c_get_clientdata(client);
1524
1525 snd_soc_unregister_codec(&client->dev);
1526 regmap_exit(lm49453->regmap);
1527 return 0;
1528}
1529
1530static const struct i2c_device_id lm49453_i2c_id[] = {
1531 { "lm49453", 0 },
1532 { }
1533};
1534MODULE_DEVICE_TABLE(i2c, lm49453_i2c_id);
1535
1536static struct i2c_driver lm49453_i2c_driver = {
1537 .driver = {
1538 .name = "lm49453",
1539 .owner = THIS_MODULE,
1540 },
1541 .probe = lm49453_i2c_probe,
1542 .remove = __devexit_p(lm49453_i2c_remove),
1543 .id_table = lm49453_i2c_id,
1544};
1545
1546module_i2c_driver(lm49453_i2c_driver);
1547
1548MODULE_DESCRIPTION("ASoC LM49453 driver");
1549MODULE_AUTHOR("M R Swami Reddy <MR.Swami.Reddy@ti.com>");
1550MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/lm49453.h b/sound/soc/codecs/lm49453.h
new file mode 100644
index 000000000000..a63cfa5c0883
--- /dev/null
+++ b/sound/soc/codecs/lm49453.h
@@ -0,0 +1,380 @@
1/*
2 * lm49453.h - LM49453 ALSA Soc Audio drive
3 *
4 * Copyright (c) 2012 Texas Instruments, Inc
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 */
11
12#ifndef _LM49453_H
13#define _LM49453_H
14
15#include <linux/bitops.h>
16
17/* LM49453_P0 register space for page0 */
18#define LM49453_P0_PMC_SETUP_REG 0x00
19#define LM49453_P0_PLL_CLK_SEL1_REG 0x01
20#define LM49453_P0_PLL_CLK_SEL2_REG 0x02
21#define LM49453_P0_PMC_CLK_DIV_REG 0x03
22#define LM49453_P0_HSDET_CLK_DIV_REG 0x04
23#define LM49453_P0_DMIC_CLK_DIV_REG 0x05
24#define LM49453_P0_ADC_CLK_DIV_REG 0x06
25#define LM49453_P0_DAC_OT_CLK_DIV_REG 0x07
26#define LM49453_P0_PLL_HF_M_REG 0x08
27#define LM49453_P0_PLL_LF_M_REG 0x09
28#define LM49453_P0_PLL_NL_REG 0x0A
29#define LM49453_P0_PLL_N_MODL_REG 0x0B
30#define LM49453_P0_PLL_N_MODH_REG 0x0C
31#define LM49453_P0_PLL_P1_REG 0x0D
32#define LM49453_P0_PLL_P2_REG 0x0E
33#define LM49453_P0_FLL_REF_FREQL_REG 0x0F
34#define LM49453_P0_FLL_REF_FREQH_REG 0x10
35#define LM49453_P0_VCO_TARGETLL_REG 0x11
36#define LM49453_P0_VCO_TARGETLH_REG 0x12
37#define LM49453_P0_VCO_TARGETHL_REG 0x13
38#define LM49453_P0_VCO_TARGETHH_REG 0x14
39#define LM49453_P0_PLL_CONFIG_REG 0x15
40#define LM49453_P0_DAC_CLK_SEL_REG 0x16
41#define LM49453_P0_DAC_HP_CLK_DIV_REG 0x17
42
43/* Analog Mixer Input Stages */
44#define LM49453_P0_MICL_REG 0x20
45#define LM49453_P0_MICR_REG 0x21
46#define LM49453_P0_EP_REG 0x24
47#define LM49453_P0_DIS_PKVL_FB_REG 0x25
48
49/* Analog Mixer Output Stages */
50#define LM49453_P0_ANALOG_MIXER_ADC_REG 0x2E
51
52/*ADC or DAC */
53#define LM49453_P0_ADC_DSP_REG 0x30
54#define LM49453_P0_DAC_DSP_REG 0x31
55
56/* EFFECTS ENABLES */
57#define LM49453_P0_ADC_FX_ENABLES_REG 0x33
58
59/* GPIO */
60#define LM49453_P0_GPIO1_REG 0x38
61#define LM49453_P0_GPIO2_REG 0x39
62#define LM49453_P0_GPIO3_REG 0x3A
63#define LM49453_P0_HAP_CTL_REG 0x3B
64#define LM49453_P0_HAP_FREQ_PROG_LEFTL_REG 0x3C
65#define LM49453_P0_HAP_FREQ_PROG_LEFTH_REG 0x3D
66#define LM49453_P0_HAP_FREQ_PROG_RIGHTL_REG 0x3E
67#define LM49453_P0_HAP_FREQ_PROG_RIGHTH_REG 0x3F
68
69/* DIGITAL MIXER */
70#define LM49453_P0_DMIX_CLK_SEL_REG 0x40
71#define LM49453_P0_PORT1_RX_LVL1_REG 0x41
72#define LM49453_P0_PORT1_RX_LVL2_REG 0x42
73#define LM49453_P0_PORT2_RX_LVL_REG 0x43
74#define LM49453_P0_PORT1_TX1_REG 0x44
75#define LM49453_P0_PORT1_TX2_REG 0x45
76#define LM49453_P0_PORT1_TX3_REG 0x46
77#define LM49453_P0_PORT1_TX4_REG 0x47
78#define LM49453_P0_PORT1_TX5_REG 0x48
79#define LM49453_P0_PORT1_TX6_REG 0x49
80#define LM49453_P0_PORT1_TX7_REG 0x4A
81#define LM49453_P0_PORT1_TX8_REG 0x4B
82#define LM49453_P0_PORT2_TX1_REG 0x4C
83#define LM49453_P0_PORT2_TX2_REG 0x4D
84#define LM49453_P0_STN_SEL_REG 0x4F
85#define LM49453_P0_DACHPL1_REG 0x50
86#define LM49453_P0_DACHPL2_REG 0x51
87#define LM49453_P0_DACHPR1_REG 0x52
88#define LM49453_P0_DACHPR2_REG 0x53
89#define LM49453_P0_DACLOL1_REG 0x54
90#define LM49453_P0_DACLOL2_REG 0x55
91#define LM49453_P0_DACLOR1_REG 0x56
92#define LM49453_P0_DACLOR2_REG 0x57
93#define LM49453_P0_DACLSL1_REG 0x58
94#define LM49453_P0_DACLSL2_REG 0x59
95#define LM49453_P0_DACLSR1_REG 0x5A
96#define LM49453_P0_DACLSR2_REG 0x5B
97#define LM49453_P0_DACHAL1_REG 0x5C
98#define LM49453_P0_DACHAL2_REG 0x5D
99#define LM49453_P0_DACHAR1_REG 0x5E
100#define LM49453_P0_DACHAR2_REG 0x5F
101
102/* AUDIO PORT 1 (TDM) */
103#define LM49453_P0_AUDIO_PORT1_BASIC_REG 0x60
104#define LM49453_P0_AUDIO_PORT1_CLK_GEN1_REG 0x61
105#define LM49453_P0_AUDIO_PORT1_CLK_GEN2_REG 0x62
106#define LM49453_P0_AUDIO_PORT1_CLK_GEN3_REG 0x63
107#define LM49453_P0_AUDIO_PORT1_SYNC_RATE_REG 0x64
108#define LM49453_P0_AUDIO_PORT1_SYNC_SDO_SETUP_REG 0x65
109#define LM49453_P0_AUDIO_PORT1_DATA_WIDTH_REG 0x66
110#define LM49453_P0_AUDIO_PORT1_RX_MSB_REG 0x67
111#define LM49453_P0_AUDIO_PORT1_TX_MSB_REG 0x68
112#define LM49453_P0_AUDIO_PORT1_TDM_CHANNELS_REG 0x69
113
114/* AUDIO PORT 2 */
115#define LM49453_P0_AUDIO_PORT2_BASIC_REG 0x6A
116#define LM49453_P0_AUDIO_PORT2_CLK_GEN1_REG 0x6B
117#define LM49453_P0_AUDIO_PORT2_CLK_GEN2_REG 0x6C
118#define LM49453_P0_AUDIO_PORT2_SYNC_GEN_REG 0x6D
119#define LM49453_P0_AUDIO_PORT2_DATA_WIDTH_REG 0x6E
120#define LM49453_P0_AUDIO_PORT2_RX_MODE_REG 0x6F
121#define LM49453_P0_AUDIO_PORT2_TX_MODE_REG 0x70
122
123/* SAMPLE RATE */
124#define LM49453_P0_PORT1_SR_LSB_REG 0x79
125#define LM49453_P0_PORT1_SR_MSB_REG 0x7A
126#define LM49453_P0_PORT2_SR_LSB_REG 0x7B
127#define LM49453_P0_PORT2_SR_MSB_REG 0x7C
128
129/* EFFECTS - HPFs */
130#define LM49453_P0_HPF_REG 0x80
131
132/* EFFECTS ADC ALC */
133#define LM49453_P0_ADC_ALC1_REG 0x82
134#define LM49453_P0_ADC_ALC2_REG 0x83
135#define LM49453_P0_ADC_ALC3_REG 0x84
136#define LM49453_P0_ADC_ALC4_REG 0x85
137#define LM49453_P0_ADC_ALC5_REG 0x86
138#define LM49453_P0_ADC_ALC6_REG 0x87
139#define LM49453_P0_ADC_ALC7_REG 0x88
140#define LM49453_P0_ADC_ALC8_REG 0x89
141#define LM49453_P0_DMIC1_LEVELL_REG 0x8A
142#define LM49453_P0_DMIC1_LEVELR_REG 0x8B
143#define LM49453_P0_DMIC2_LEVELL_REG 0x8C
144#define LM49453_P0_DMIC2_LEVELR_REG 0x8D
145#define LM49453_P0_ADC_LEVELL_REG 0x8E
146#define LM49453_P0_ADC_LEVELR_REG 0x8F
147#define LM49453_P0_DAC_HP_LEVELL_REG 0x90
148#define LM49453_P0_DAC_HP_LEVELR_REG 0x91
149#define LM49453_P0_DAC_LO_LEVELL_REG 0x92
150#define LM49453_P0_DAC_LO_LEVELR_REG 0x93
151#define LM49453_P0_DAC_LS_LEVELL_REG 0x94
152#define LM49453_P0_DAC_LS_LEVELR_REG 0x95
153#define LM49453_P0_DAC_HA_LEVELL_REG 0x96
154#define LM49453_P0_DAC_HA_LEVELR_REG 0x97
155#define LM49453_P0_SOFT_MUTE_REG 0x98
156#define LM49453_P0_DMIC_MUTE_CFG_REG 0x99
157#define LM49453_P0_ADC_MUTE_CFG_REG 0x9A
158#define LM49453_P0_DAC_MUTE_CFG_REG 0x9B
159
160/*DIGITAL MIC1 */
161#define LM49453_P0_DIGITAL_MIC1_CONFIG_REG 0xB0
162#define LM49453_P0_DIGITAL_MIC1_DATA_DELAYL_REG 0xB1
163#define LM49453_P0_DIGITAL_MIC1_DATA_DELAYR_REG 0xB2
164
165/*DIGITAL MIC2 */
166#define LM49453_P0_DIGITAL_MIC2_CONFIG_REG 0xB3
167#define LM49453_P0_DIGITAL_MIC2_DATA_DELAYL_REG 0xB4
168#define LM49453_P0_DIGITAL_MIC2_DATA_DELAYR_REG 0xB5
169
170/* ADC DECIMATOR */
171#define LM49453_P0_ADC_DECIMATOR_REG 0xB6
172
173/* DAC CONFIGURE */
174#define LM49453_P0_DAC_CONFIG_REG 0xB7
175
176/* SIDETONE */
177#define LM49453_P0_STN_VOL_ADCL_REG 0xB8
178#define LM49453_P0_STN_VOL_ADCR_REG 0xB9
179#define LM49453_P0_STN_VOL_DMIC1L_REG 0xBA
180#define LM49453_P0_STN_VOL_DMIC1R_REG 0xBB
181#define LM49453_P0_STN_VOL_DMIC2L_REG 0xBC
182#define LM49453_P0_STN_VOL_DMIC2R_REG 0xBD
183
184/* ADC/DAC CLIPPING MONITORS (Read Only/Write to Clear) */
185#define LM49453_P0_ADC_DEC_CLIP_REG 0xC2
186#define LM49453_P0_ADC_HPF_CLIP_REG 0xC3
187#define LM49453_P0_ADC_LVL_CLIP_REG 0xC4
188#define LM49453_P0_DAC_LVL_CLIP_REG 0xC5
189
190/* ADC ALC EFFECT MONITORS (Read Only) */
191#define LM49453_P0_ADC_LVLMONL_REG 0xC8
192#define LM49453_P0_ADC_LVLMONR_REG 0xC9
193#define LM49453_P0_ADC_ALCMONL_REG 0xCA
194#define LM49453_P0_ADC_ALCMONR_REG 0xCB
195#define LM49453_P0_ADC_MUTED_REG 0xCC
196#define LM49453_P0_DAC_MUTED_REG 0xCD
197
198/* HEADSET DETECT */
199#define LM49453_P0_HSD_PPB_LONG_CNT_LIMITL_REG 0xD0
200#define LM49453_P0_HSD_PPB_LONG_CNT_LIMITR_REG 0xD1
201#define LM49453_P0_HSD_PIN3_4_EX_LOOP_CNT_LIMITL_REG 0xD2
202#define LM49453_P0_HSD_PIN3_4_EX_LOOP_CNT_LIMITH_REG 0xD3
203#define LM49453_P0_HSD_TIMEOUT1_REG 0xD4
204#define LM49453_P0_HSD_TIMEOUT2_REG 0xD5
205#define LM49453_P0_HSD_TIMEOUT3_REG 0xD6
206#define LM49453_P0_HSD_PIN3_4_CFG_REG 0xD7
207#define LM49453_P0_HSD_IRQ1_REG 0xD8
208#define LM49453_P0_HSD_IRQ2_REG 0xD9
209#define LM49453_P0_HSD_IRQ3_REG 0xDA
210#define LM49453_P0_HSD_IRQ4_REG 0xDB
211#define LM49453_P0_HSD_IRQ_MASK1_REG 0xDC
212#define LM49453_P0_HSD_IRQ_MASK2_REG 0xDD
213#define LM49453_P0_HSD_IRQ_MASK3_REG 0xDE
214#define LM49453_P0_HSD_R_HPLL_REG 0xE0
215#define LM49453_P0_HSD_R_HPLH_REG 0xE1
216#define LM49453_P0_HSD_R_HPLU_REG 0xE2
217#define LM49453_P0_HSD_R_HPRL_REG 0xE3
218#define LM49453_P0_HSD_R_HPRH_REG 0xE4
219#define LM49453_P0_HSD_R_HPRU_REG 0xE5
220#define LM49453_P0_HSD_VEL_L_FINALL_REG 0xE6
221#define LM49453_P0_HSD_VEL_L_FINALH_REG 0xE7
222#define LM49453_P0_HSD_VEL_L_FINALU_REG 0xE8
223#define LM49453_P0_HSD_RO_FINALL_REG 0xE9
224#define LM49453_P0_HSD_RO_FINALH_REG 0xEA
225#define LM49453_P0_HSD_RO_FINALU_REG 0xEB
226#define LM49453_P0_HSD_VMIC_BIAS_FINALL_REG 0xEC
227#define LM49453_P0_HSD_VMIC_BIAS_FINALH_REG 0xED
228#define LM49453_P0_HSD_VMIC_BIAS_FINALU_REG 0xEE
229#define LM49453_P0_HSD_PIN_CONFIG_REG 0xEF
230#define LM49453_P0_HSD_PLUG_DETECT_BB_IRQ_STATUS1_REG 0xF1
231#define LM49453_P0_HSD_PLUG_DETECT_BB_IRQ_STATUS2_REG 0xF2
232#define LM49453_P0_HSD_PLUG_DETECT_BB_IRQ_STATUS3_REG 0xF3
233#define LM49453_P0_HSD_PLUG_DETECT_BB_IRQ_STATEL_REG 0xF4
234#define LM49453_P0_HSD_PLUG_DETECT_BB_IRQ_STATEH_REG 0xF5
235
236/* I/O PULLDOWN CONFIG */
237#define LM49453_P0_PULL_CONFIG1_REG 0xF8
238#define LM49453_P0_PULL_CONFIG2_REG 0xF9
239#define LM49453_P0_PULL_CONFIG3_REG 0xFA
240
241/* RESET */
242#define LM49453_P0_RESET_REG 0xFE
243
244/* PAGE */
245#define LM49453_PAGE_REG 0xFF
246
247#define LM49453_MAX_REGISTER (0xFF+1)
248
249/* LM49453_P0_PMC_SETUP_REG (0x00h) */
250#define LM49453_PMC_SETUP_CHIP_EN (BIT(1)|BIT(0))
251#define LM49453_PMC_SETUP_PLL_EN BIT(2)
252#define LM49453_PMC_SETUP_PLL_P2_EN BIT(3)
253#define LM49453_PMC_SETUP_PLL_FLL BIT(4)
254#define LM49453_PMC_SETUP_MCLK_OVER BIT(5)
255#define LM49453_PMC_SETUP_RTC_CLK_OVER BIT(6)
256#define LM49453_PMC_SETUP_CHIP_ACTIVE BIT(7)
257
258/* Chip Enable bits */
259#define LM49453_CHIP_EN_SHUTDOWN 0x00
260#define LM49453_CHIP_EN 0x01
261#define LM49453_CHIP_EN_HSD_DETECT 0x02
262#define LM49453_CHIP_EN_INVALID_HSD 0x03
263
264/* LM49453_P0_PLL_CLK_SEL1_REG (0x01h) */
265#define LM49453_CLK_SEL1_MCLK_SEL 0x11
266#define LM49453_CLK_SEL1_RTC_SEL 0x11
267#define LM49453_CLK_SEL1_PORT1_SEL 0x10
268#define LM49453_CLK_SEL1_PORT2_SEL 0x11
269
270/* LM49453_P0_PLL_CLK_SEL2_REG (0x02h) */
271#define LM49453_CLK_SEL2_ADC_CLK_SEL 0x38
272
273/* LM49453_P0_FLL_REF_FREQL_REG (0x0F) */
274#define LM49453_FLL_REF_FREQ_VAL 0x8ca0001
275
276/* LM49453_P0_VCO_TARGETLL_REG (0x11) */
277#define LM49453_VCO_TARGET_VAL 0x8ca0001
278
279/* LM49453_P0_ADC_DSP_REG (0x30h) */
280#define LM49453_ADC_DSP_ADC_MUTEL BIT(0)
281#define LM49453_ADC_DSP_ADC_MUTER BIT(1)
282#define LM49453_ADC_DSP_DMIC1_MUTEL BIT(2)
283#define LM49453_ADC_DSP_DMIC1_MUTER BIT(3)
284#define LM49453_ADC_DSP_DMIC2_MUTEL BIT(4)
285#define LM49453_ADC_DSP_DMIC2_MUTER BIT(5)
286#define LM49453_ADC_DSP_MUTE_ALL 0x3F
287
288/* LM49453_P0_DAC_DSP_REG (0x31h) */
289#define LM49453_DAC_DSP_MUTE_ALL 0xFF
290
291/* LM49453_P0_AUDIO_PORT1_BASIC_REG (0x60h) */
292#define LM49453_AUDIO_PORT1_BASIC_FMT_MASK (BIT(4)|BIT(3))
293#define LM49453_AUDIO_PORT1_BASIC_CLK_MS BIT(3)
294#define LM49453_AUDIO_PORT1_BASIC_SYNC_MS BIT(4)
295
296/* LM49453_P0_RESET_REG (0xFEh) */
297#define LM49453_RESET_REG_RST BIT(0)
298
299/* Page select register bits (0xFF) */
300#define LM49453_PAGE0_SELECT 0x0
301#define LM49453_PAGE1_SELECT 0x1
302
303/* LM49453_P0_HSD_PIN3_4_CFG_REG (Jack Pin config - 0xD7) */
304#define LM49453_JACK_DISABLE 0x00
305#define LM49453_JACK_CONFIG1 0x01
306#define LM49453_JACK_CONFIG2 0x02
307#define LM49453_JACK_CONFIG3 0x03
308#define LM49453_JACK_CONFIG4 0x04
309#define LM49453_JACK_CONFIG5 0x05
310
311/* Page 1 REGISTERS */
312
313/* SIDETONE */
314#define LM49453_P1_SIDETONE_SA0L_REG 0x80
315#define LM49453_P1_SIDETONE_SA0H_REG 0x81
316#define LM49453_P1_SIDETONE_SAB0U_REG 0x82
317#define LM49453_P1_SIDETONE_SB0L_REG 0x83
318#define LM49453_P1_SIDETONE_SB0H_REG 0x84
319#define LM49453_P1_SIDETONE_SH0L_REG 0x85
320#define LM49453_P1_SIDETONE_SH0H_REG 0x86
321#define LM49453_P1_SIDETONE_SH0U_REG 0x87
322#define LM49453_P1_SIDETONE_SA1L_REG 0x88
323#define LM49453_P1_SIDETONE_SA1H_REG 0x89
324#define LM49453_P1_SIDETONE_SAB1U_REG 0x8A
325#define LM49453_P1_SIDETONE_SB1L_REG 0x8B
326#define LM49453_P1_SIDETONE_SB1H_REG 0x8C
327#define LM49453_P1_SIDETONE_SH1L_REG 0x8D
328#define LM49453_P1_SIDETONE_SH1H_REG 0x8E
329#define LM49453_P1_SIDETONE_SH1U_REG 0x8F
330#define LM49453_P1_SIDETONE_SA2L_REG 0x90
331#define LM49453_P1_SIDETONE_SA2H_REG 0x91
332#define LM49453_P1_SIDETONE_SAB2U_REG 0x92
333#define LM49453_P1_SIDETONE_SB2L_REG 0x93
334#define LM49453_P1_SIDETONE_SB2H_REG 0x94
335#define LM49453_P1_SIDETONE_SH2L_REG 0x95
336#define LM49453_P1_SIDETONE_SH2H_REG 0x96
337#define LM49453_P1_SIDETONE_SH2U_REG 0x97
338#define LM49453_P1_SIDETONE_SA3L_REG 0x98
339#define LM49453_P1_SIDETONE_SA3H_REG 0x99
340#define LM49453_P1_SIDETONE_SAB3U_REG 0x9A
341#define LM49453_P1_SIDETONE_SB3L_REG 0x9B
342#define LM49453_P1_SIDETONE_SB3H_REG 0x9C
343#define LM49453_P1_SIDETONE_SH3L_REG 0x9D
344#define LM49453_P1_SIDETONE_SH3H_REG 0x9E
345#define LM49453_P1_SIDETONE_SH3U_REG 0x9F
346#define LM49453_P1_SIDETONE_SA4L_REG 0xA0
347#define LM49453_P1_SIDETONE_SA4H_REG 0xA1
348#define LM49453_P1_SIDETONE_SAB4U_REG 0xA2
349#define LM49453_P1_SIDETONE_SB4L_REG 0xA3
350#define LM49453_P1_SIDETONE_SB4H_REG 0xA4
351#define LM49453_P1_SIDETONE_SH4L_REG 0xA5
352#define LM49453_P1_SIDETONE_SH4H_REG 0xA6
353#define LM49453_P1_SIDETONE_SH4U_REG 0xA7
354#define LM49453_P1_SIDETONE_SA5L_REG 0xA8
355#define LM49453_P1_SIDETONE_SA5H_REG 0xA9
356#define LM49453_P1_SIDETONE_SAB5U_REG 0xAA
357#define LM49453_P1_SIDETONE_SB5L_REG 0xAB
358#define LM49453_P1_SIDETONE_SB5H_REG 0xAC
359#define LM49453_P1_SIDETONE_SH5L_REG 0xAD
360#define LM49453_P1_SIDETONE_SH5H_REG 0xAE
361#define LM49453_P1_SIDETONE_SH5U_REG 0xAF
362
363/* CHARGE PUMP CONFIG */
364#define LM49453_P1_CP_CONFIG1_REG 0xB0
365#define LM49453_P1_CP_CONFIG2_REG 0xB1
366#define LM49453_P1_CP_CONFIG3_REG 0xB2
367#define LM49453_P1_CP_CONFIG4_REG 0xB3
368#define LM49453_P1_CP_LA_VTH1L_REG 0xB4
369#define LM49453_P1_CP_LA_VTH1M_REG 0xB5
370#define LM49453_P1_CP_LA_VTH2L_REG 0xB6
371#define LM49453_P1_CP_LA_VTH2M_REG 0xB7
372#define LM49453_P1_CP_LA_VTH3L_REG 0xB8
373#define LM49453_P1_CP_LA_VTH3H_REG 0xB9
374#define LM49453_P1_CP_CLK_DIV_REG 0xBA
375
376/* DAC */
377#define LM49453_P1_DAC_CHOP_REG 0xC0
378
379#define LM49453_CLK_SRC_MCLK 1
380#endif
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 0bb511a0388d..35179e2c23c9 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -24,6 +24,7 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <asm/div64.h> 25#include <asm/div64.h>
26#include <sound/max98095.h> 26#include <sound/max98095.h>
27#include <sound/jack.h>
27#include "max98095.h" 28#include "max98095.h"
28 29
29enum max98095_type { 30enum max98095_type {
@@ -51,6 +52,8 @@ struct max98095_priv {
51 u8 lin_state; 52 u8 lin_state;
52 unsigned int mic1pre; 53 unsigned int mic1pre;
53 unsigned int mic2pre; 54 unsigned int mic2pre;
55 struct snd_soc_jack *headphone_jack;
56 struct snd_soc_jack *mic_jack;
54}; 57};
55 58
56static const u8 max98095_reg_def[M98095_REG_CNT] = { 59static const u8 max98095_reg_def[M98095_REG_CNT] = {
@@ -2173,9 +2176,125 @@ static void max98095_handle_pdata(struct snd_soc_codec *codec)
2173 max98095_handle_bq_pdata(codec); 2176 max98095_handle_bq_pdata(codec);
2174} 2177}
2175 2178
2179static irqreturn_t max98095_report_jack(int irq, void *data)
2180{
2181 struct snd_soc_codec *codec = data;
2182 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2183 unsigned int value;
2184 int hp_report = 0;
2185 int mic_report = 0;
2186
2187 /* Read the Jack Status Register */
2188 value = snd_soc_read(codec, M98095_007_JACK_AUTO_STS);
2189
2190 /* If ddone is not set, then detection isn't finished yet */
2191 if ((value & M98095_DDONE) == 0)
2192 return IRQ_NONE;
2193
2194 /* if hp, check its bit, and if set, clear it */
2195 if ((value & M98095_HP_IN || value & M98095_LO_IN) &&
2196 max98095->headphone_jack)
2197 hp_report |= SND_JACK_HEADPHONE;
2198
2199 /* if mic, check its bit, and if set, clear it */
2200 if ((value & M98095_MIC_IN) && max98095->mic_jack)
2201 mic_report |= SND_JACK_MICROPHONE;
2202
2203 if (max98095->headphone_jack == max98095->mic_jack) {
2204 snd_soc_jack_report(max98095->headphone_jack,
2205 hp_report | mic_report,
2206 SND_JACK_HEADSET);
2207 } else {
2208 if (max98095->headphone_jack)
2209 snd_soc_jack_report(max98095->headphone_jack,
2210 hp_report, SND_JACK_HEADPHONE);
2211 if (max98095->mic_jack)
2212 snd_soc_jack_report(max98095->mic_jack,
2213 mic_report, SND_JACK_MICROPHONE);
2214 }
2215
2216 return IRQ_HANDLED;
2217}
2218
2219int max98095_jack_detect_enable(struct snd_soc_codec *codec)
2220{
2221 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2222 int ret = 0;
2223 int detect_enable = M98095_JDEN;
2224 unsigned int slew = M98095_DEFAULT_SLEW_DELAY;
2225
2226 if (max98095->pdata->jack_detect_pin5en)
2227 detect_enable |= M98095_PIN5EN;
2228
2229 if (max98095->pdata->jack_detect_delay)
2230 slew = max98095->pdata->jack_detect_delay;
2231
2232 ret = snd_soc_write(codec, M98095_08E_JACK_DC_SLEW, slew);
2233 if (ret < 0) {
2234 dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret);
2235 return ret;
2236 }
2237
2238 /* configure auto detection to be enabled */
2239 ret = snd_soc_write(codec, M98095_089_JACK_DET_AUTO, detect_enable);
2240 if (ret < 0) {
2241 dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret);
2242 return ret;
2243 }
2244
2245 return ret;
2246}
2247
2248int max98095_jack_detect_disable(struct snd_soc_codec *codec)
2249{
2250 int ret = 0;
2251
2252 /* configure auto detection to be disabled */
2253 ret = snd_soc_write(codec, M98095_089_JACK_DET_AUTO, 0x0);
2254 if (ret < 0) {
2255 dev_err(codec->dev, "Failed to cfg auto detect %d\n", ret);
2256 return ret;
2257 }
2258
2259 return ret;
2260}
2261
2262int max98095_jack_detect(struct snd_soc_codec *codec,
2263 struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack)
2264{
2265 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2266 struct i2c_client *client = to_i2c_client(codec->dev);
2267 int ret = 0;
2268
2269 max98095->headphone_jack = hp_jack;
2270 max98095->mic_jack = mic_jack;
2271
2272 /* only progress if we have at least 1 jack pointer */
2273 if (!hp_jack && !mic_jack)
2274 return -EINVAL;
2275
2276 max98095_jack_detect_enable(codec);
2277
2278 /* enable interrupts for headphone jack detection */
2279 ret = snd_soc_update_bits(codec, M98095_013_JACK_INT_EN,
2280 M98095_IDDONE, M98095_IDDONE);
2281 if (ret < 0) {
2282 dev_err(codec->dev, "Failed to cfg jack irqs %d\n", ret);
2283 return ret;
2284 }
2285
2286 max98095_report_jack(client->irq, codec);
2287 return 0;
2288}
2289
2176#ifdef CONFIG_PM 2290#ifdef CONFIG_PM
2177static int max98095_suspend(struct snd_soc_codec *codec) 2291static int max98095_suspend(struct snd_soc_codec *codec)
2178{ 2292{
2293 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2294
2295 if (max98095->headphone_jack || max98095->mic_jack)
2296 max98095_jack_detect_disable(codec);
2297
2179 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF); 2298 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
2180 2299
2181 return 0; 2300 return 0;
@@ -2183,8 +2302,16 @@ static int max98095_suspend(struct snd_soc_codec *codec)
2183 2302
2184static int max98095_resume(struct snd_soc_codec *codec) 2303static int max98095_resume(struct snd_soc_codec *codec)
2185{ 2304{
2305 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2306 struct i2c_client *client = to_i2c_client(codec->dev);
2307
2186 max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 2308 max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2187 2309
2310 if (max98095->headphone_jack || max98095->mic_jack) {
2311 max98095_jack_detect_enable(codec);
2312 max98095_report_jack(client->irq, codec);
2313 }
2314
2188 return 0; 2315 return 0;
2189} 2316}
2190#else 2317#else
@@ -2227,6 +2354,7 @@ static int max98095_probe(struct snd_soc_codec *codec)
2227{ 2354{
2228 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); 2355 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2229 struct max98095_cdata *cdata; 2356 struct max98095_cdata *cdata;
2357 struct i2c_client *client;
2230 int ret = 0; 2358 int ret = 0;
2231 2359
2232 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); 2360 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
@@ -2238,6 +2366,8 @@ static int max98095_probe(struct snd_soc_codec *codec)
2238 /* reset the codec, the DSP core, and disable all interrupts */ 2366 /* reset the codec, the DSP core, and disable all interrupts */
2239 max98095_reset(codec); 2367 max98095_reset(codec);
2240 2368
2369 client = to_i2c_client(codec->dev);
2370
2241 /* initialize private data */ 2371 /* initialize private data */
2242 2372
2243 max98095->sysclk = (unsigned)-1; 2373 max98095->sysclk = (unsigned)-1;
@@ -2266,11 +2396,23 @@ static int max98095_probe(struct snd_soc_codec *codec)
2266 max98095->mic1pre = 0; 2396 max98095->mic1pre = 0;
2267 max98095->mic2pre = 0; 2397 max98095->mic2pre = 0;
2268 2398
2399 if (client->irq) {
2400 /* register an audio interrupt */
2401 ret = request_threaded_irq(client->irq, NULL,
2402 max98095_report_jack,
2403 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
2404 "max98095", codec);
2405 if (ret) {
2406 dev_err(codec->dev, "Failed to request IRQ: %d\n", ret);
2407 goto err_access;
2408 }
2409 }
2410
2269 ret = snd_soc_read(codec, M98095_0FF_REV_ID); 2411 ret = snd_soc_read(codec, M98095_0FF_REV_ID);
2270 if (ret < 0) { 2412 if (ret < 0) {
2271 dev_err(codec->dev, "Failure reading hardware revision: %d\n", 2413 dev_err(codec->dev, "Failure reading hardware revision: %d\n",
2272 ret); 2414 ret);
2273 goto err_access; 2415 goto err_irq;
2274 } 2416 }
2275 dev_info(codec->dev, "Hardware revision: %c\n", ret - 0x40 + 'A'); 2417 dev_info(codec->dev, "Hardware revision: %c\n", ret - 0x40 + 'A');
2276 2418
@@ -2306,14 +2448,28 @@ static int max98095_probe(struct snd_soc_codec *codec)
2306 2448
2307 max98095_add_widgets(codec); 2449 max98095_add_widgets(codec);
2308 2450
2451 return 0;
2452
2453err_irq:
2454 if (client->irq)
2455 free_irq(client->irq, codec);
2309err_access: 2456err_access:
2310 return ret; 2457 return ret;
2311} 2458}
2312 2459
2313static int max98095_remove(struct snd_soc_codec *codec) 2460static int max98095_remove(struct snd_soc_codec *codec)
2314{ 2461{
2462 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2463 struct i2c_client *client = to_i2c_client(codec->dev);
2464
2315 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF); 2465 max98095_set_bias_level(codec, SND_SOC_BIAS_OFF);
2316 2466
2467 if (max98095->headphone_jack || max98095->mic_jack)
2468 max98095_jack_detect_disable(codec);
2469
2470 if (client->irq)
2471 free_irq(client->irq, codec);
2472
2317 return 0; 2473 return 0;
2318} 2474}
2319 2475
diff --git a/sound/soc/codecs/max98095.h b/sound/soc/codecs/max98095.h
index 891584a0eb03..2ebbe4e894bf 100644
--- a/sound/soc/codecs/max98095.h
+++ b/sound/soc/codecs/max98095.h
@@ -175,11 +175,23 @@
175 175
176/* MAX98095 Registers Bit Fields */ 176/* MAX98095 Registers Bit Fields */
177 177
178/* M98095_007_JACK_AUTO_STS */
179 #define M98095_MIC_IN (1<<3)
180 #define M98095_LO_IN (1<<5)
181 #define M98095_HP_IN (1<<6)
182 #define M98095_DDONE (1<<7)
183
178/* M98095_00F_HOST_CFG */ 184/* M98095_00F_HOST_CFG */
179 #define M98095_SEG (1<<0) 185 #define M98095_SEG (1<<0)
180 #define M98095_XTEN (1<<1) 186 #define M98095_XTEN (1<<1)
181 #define M98095_MDLLEN (1<<2) 187 #define M98095_MDLLEN (1<<2)
182 188
189/* M98095_013_JACK_INT_EN */
190 #define M98095_IMIC_IN (1<<3)
191 #define M98095_ILO_IN (1<<5)
192 #define M98095_IHP_IN (1<<6)
193 #define M98095_IDDONE (1<<7)
194
183/* M98095_027_DAI1_CLKMODE, M98095_031_DAI2_CLKMODE, M98095_03B_DAI3_CLKMODE */ 195/* M98095_027_DAI1_CLKMODE, M98095_031_DAI2_CLKMODE, M98095_03B_DAI3_CLKMODE */
184 #define M98095_CLKMODE_MASK 0xFF 196 #define M98095_CLKMODE_MASK 0xFF
185 197
@@ -255,6 +267,10 @@
255 #define M98095_EQ2EN (1<<1) 267 #define M98095_EQ2EN (1<<1)
256 #define M98095_EQ1EN (1<<0) 268 #define M98095_EQ1EN (1<<0)
257 269
270/* M98095_089_JACK_DET_AUTO */
271 #define M98095_PIN5EN (1<<2)
272 #define M98095_JDEN (1<<7)
273
258/* M98095_090_PWR_EN_IN */ 274/* M98095_090_PWR_EN_IN */
259 #define M98095_INEN (1<<7) 275 #define M98095_INEN (1<<7)
260 #define M98095_MB2EN (1<<3) 276 #define M98095_MB2EN (1<<3)
@@ -296,4 +312,10 @@
296#define M98095_174_DAI1_BQ_BASE 0x74 312#define M98095_174_DAI1_BQ_BASE 0x74
297#define M98095_17E_DAI2_BQ_BASE 0x7E 313#define M98095_17E_DAI2_BQ_BASE 0x7E
298 314
315/* Default Delay used in Slew Rate Calculation for Jack detection */
316#define M98095_DEFAULT_SLEW_DELAY 0x18
317
318extern int max98095_jack_detect(struct snd_soc_codec *codec,
319 struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack);
320
299#endif 321#endif
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
new file mode 100644
index 000000000000..6276e352125f
--- /dev/null
+++ b/sound/soc/codecs/mc13783.c
@@ -0,0 +1,786 @@
1/*
2 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
3 * Copyright 2009 Sascha Hauer, s.hauer@pengutronix.de
4 * Copyright 2012 Philippe Retornaz, philippe.retornaz@epfl.ch
5 *
6 * Initial development of this code was funded by
7 * Phytec Messtechnik GmbH, http://www.phytec.de
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 * MA 02110-1301, USA.
22 */
23#include <linux/module.h>
24#include <linux/device.h>
25#include <linux/mfd/mc13xxx.h>
26#include <linux/slab.h>
27#include <sound/core.h>
28#include <sound/control.h>
29#include <sound/pcm.h>
30#include <sound/soc.h>
31#include <sound/initval.h>
32#include <sound/soc-dapm.h>
33
34#include "mc13783.h"
35
36#define MC13783_AUDIO_RX0 36
37#define MC13783_AUDIO_RX1 37
38#define MC13783_AUDIO_TX 38
39#define MC13783_SSI_NETWORK 39
40#define MC13783_AUDIO_CODEC 40
41#define MC13783_AUDIO_DAC 41
42
43#define AUDIO_RX0_ALSPEN (1 << 5)
44#define AUDIO_RX0_ALSPSEL (1 << 7)
45#define AUDIO_RX0_ADDCDC (1 << 21)
46#define AUDIO_RX0_ADDSTDC (1 << 22)
47#define AUDIO_RX0_ADDRXIN (1 << 23)
48
49#define AUDIO_RX1_PGARXEN (1 << 0);
50#define AUDIO_RX1_PGASTEN (1 << 5)
51#define AUDIO_RX1_ARXINEN (1 << 10)
52
53#define AUDIO_TX_AMC1REN (1 << 5)
54#define AUDIO_TX_AMC1LEN (1 << 7)
55#define AUDIO_TX_AMC2EN (1 << 9)
56#define AUDIO_TX_ATXINEN (1 << 11)
57#define AUDIO_TX_RXINREC (1 << 13)
58
59#define SSI_NETWORK_CDCTXRXSLOT(x) (((x) & 0x3) << 2)
60#define SSI_NETWORK_CDCTXSECSLOT(x) (((x) & 0x3) << 4)
61#define SSI_NETWORK_CDCRXSECSLOT(x) (((x) & 0x3) << 6)
62#define SSI_NETWORK_CDCRXSECGAIN(x) (((x) & 0x3) << 8)
63#define SSI_NETWORK_CDCSUMGAIN(x) (1 << 10)
64#define SSI_NETWORK_CDCFSDLY(x) (1 << 11)
65#define SSI_NETWORK_DAC_SLOTS_8 (1 << 12)
66#define SSI_NETWORK_DAC_SLOTS_4 (2 << 12)
67#define SSI_NETWORK_DAC_SLOTS_2 (3 << 12)
68#define SSI_NETWORK_DAC_SLOT_MASK (3 << 12)
69#define SSI_NETWORK_DAC_RXSLOT_0_1 (0 << 14)
70#define SSI_NETWORK_DAC_RXSLOT_2_3 (1 << 14)
71#define SSI_NETWORK_DAC_RXSLOT_4_5 (2 << 14)
72#define SSI_NETWORK_DAC_RXSLOT_6_7 (3 << 14)
73#define SSI_NETWORK_DAC_RXSLOT_MASK (3 << 14)
74#define SSI_NETWORK_STDCRXSECSLOT(x) (((x) & 0x3) << 16)
75#define SSI_NETWORK_STDCRXSECGAIN(x) (((x) & 0x3) << 18)
76#define SSI_NETWORK_STDCSUMGAIN (1 << 20)
77
78/*
79 * MC13783_AUDIO_CODEC and MC13783_AUDIO_DAC mostly share the same
80 * register layout
81 */
82#define AUDIO_SSI_SEL (1 << 0)
83#define AUDIO_CLK_SEL (1 << 1)
84#define AUDIO_CSM (1 << 2)
85#define AUDIO_BCL_INV (1 << 3)
86#define AUDIO_CFS_INV (1 << 4)
87#define AUDIO_CFS(x) (((x) & 0x3) << 5)
88#define AUDIO_CLK(x) (((x) & 0x7) << 7)
89#define AUDIO_C_EN (1 << 11)
90#define AUDIO_C_CLK_EN (1 << 12)
91#define AUDIO_C_RESET (1 << 15)
92
93#define AUDIO_CODEC_CDCFS8K16K (1 << 10)
94#define AUDIO_DAC_CFS_DLY_B (1 << 10)
95
96struct mc13783_priv {
97 struct snd_soc_codec codec;
98 struct mc13xxx *mc13xxx;
99
100 enum mc13783_ssi_port adc_ssi_port;
101 enum mc13783_ssi_port dac_ssi_port;
102};
103
104static unsigned int mc13783_read(struct snd_soc_codec *codec,
105 unsigned int reg)
106{
107 struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
108 unsigned int value = 0;
109
110 mc13xxx_lock(priv->mc13xxx);
111
112 mc13xxx_reg_read(priv->mc13xxx, reg, &value);
113
114 mc13xxx_unlock(priv->mc13xxx);
115
116 return value;
117}
118
119static int mc13783_write(struct snd_soc_codec *codec,
120 unsigned int reg, unsigned int value)
121{
122 struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
123 int ret;
124
125 mc13xxx_lock(priv->mc13xxx);
126
127 ret = mc13xxx_reg_write(priv->mc13xxx, reg, value);
128
129 mc13xxx_unlock(priv->mc13xxx);
130
131 return ret;
132}
133
134/* Mapping between sample rates and register value */
135static unsigned int mc13783_rates[] = {
136 8000, 11025, 12000, 16000,
137 22050, 24000, 32000, 44100,
138 48000, 64000, 96000
139};
140
141static int mc13783_pcm_hw_params_dac(struct snd_pcm_substream *substream,
142 struct snd_pcm_hw_params *params,
143 struct snd_soc_dai *dai)
144{
145 struct snd_soc_pcm_runtime *rtd = substream->private_data;
146 struct snd_soc_codec *codec = rtd->codec;
147 unsigned int rate = params_rate(params);
148 int i;
149
150 for (i = 0; i < ARRAY_SIZE(mc13783_rates); i++) {
151 if (rate == mc13783_rates[i]) {
152 snd_soc_update_bits(codec, MC13783_AUDIO_DAC,
153 0xf << 17, i << 17);
154 return 0;
155 }
156 }
157
158 return -EINVAL;
159}
160
161static int mc13783_pcm_hw_params_codec(struct snd_pcm_substream *substream,
162 struct snd_pcm_hw_params *params,
163 struct snd_soc_dai *dai)
164{
165 struct snd_soc_pcm_runtime *rtd = substream->private_data;
166 struct snd_soc_codec *codec = rtd->codec;
167 unsigned int rate = params_rate(params);
168 unsigned int val;
169
170 switch (rate) {
171 case 8000:
172 val = 0;
173 break;
174 case 16000:
175 val = AUDIO_CODEC_CDCFS8K16K;
176 break;
177 default:
178 return -EINVAL;
179 }
180
181 snd_soc_update_bits(codec, MC13783_AUDIO_CODEC, AUDIO_CODEC_CDCFS8K16K,
182 val);
183
184 return 0;
185}
186
187static int mc13783_pcm_hw_params_sync(struct snd_pcm_substream *substream,
188 struct snd_pcm_hw_params *params,
189 struct snd_soc_dai *dai)
190{
191 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
192 return mc13783_pcm_hw_params_dac(substream, params, dai);
193 else
194 return mc13783_pcm_hw_params_codec(substream, params, dai);
195}
196
197static int mc13783_set_fmt(struct snd_soc_dai *dai, unsigned int fmt,
198 unsigned int reg)
199{
200 struct snd_soc_codec *codec = dai->codec;
201 unsigned int val = 0;
202 unsigned int mask = AUDIO_CFS(3) | AUDIO_BCL_INV | AUDIO_CFS_INV |
203 AUDIO_CSM | AUDIO_C_CLK_EN | AUDIO_C_RESET;
204
205
206 /* DAI mode */
207 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
208 case SND_SOC_DAIFMT_I2S:
209 val |= AUDIO_CFS(2);
210 break;
211 case SND_SOC_DAIFMT_DSP_A:
212 val |= AUDIO_CFS(1);
213 break;
214 default:
215 return -EINVAL;
216 }
217
218 /* DAI clock inversion */
219 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
220 case SND_SOC_DAIFMT_NB_NF:
221 val |= AUDIO_BCL_INV;
222 break;
223 case SND_SOC_DAIFMT_NB_IF:
224 val |= AUDIO_BCL_INV | AUDIO_CFS_INV;
225 break;
226 case SND_SOC_DAIFMT_IB_NF:
227 break;
228 case SND_SOC_DAIFMT_IB_IF:
229 val |= AUDIO_CFS_INV;
230 break;
231 }
232
233 /* DAI clock master masks */
234 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
235 case SND_SOC_DAIFMT_CBM_CFM:
236 val |= AUDIO_C_CLK_EN;
237 break;
238 case SND_SOC_DAIFMT_CBS_CFS:
239 val |= AUDIO_CSM;
240 break;
241 case SND_SOC_DAIFMT_CBM_CFS:
242 case SND_SOC_DAIFMT_CBS_CFM:
243 return -EINVAL;
244 }
245
246 val |= AUDIO_C_RESET;
247
248 snd_soc_update_bits(codec, reg, mask, val);
249
250 return 0;
251}
252
253static int mc13783_set_fmt_async(struct snd_soc_dai *dai, unsigned int fmt)
254{
255 if (dai->id == MC13783_ID_STEREO_DAC)
256 return mc13783_set_fmt(dai, fmt, MC13783_AUDIO_DAC);
257 else
258 return mc13783_set_fmt(dai, fmt, MC13783_AUDIO_CODEC);
259}
260
261static int mc13783_set_fmt_sync(struct snd_soc_dai *dai, unsigned int fmt)
262{
263 int ret;
264
265 ret = mc13783_set_fmt(dai, fmt, MC13783_AUDIO_DAC);
266 if (ret)
267 return ret;
268
269 /*
270 * In synchronous mode force the voice codec into slave mode
271 * so that the clock / framesync from the stereo DAC is used
272 */
273 fmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
274 fmt |= SND_SOC_DAIFMT_CBS_CFS;
275 ret = mc13783_set_fmt(dai, fmt, MC13783_AUDIO_CODEC);
276
277 return ret;
278}
279
280static int mc13783_sysclk[] = {
281 13000000,
282 15360000,
283 16800000,
284 -1,
285 26000000,
286 -1, /* 12000000, invalid for voice codec */
287 -1, /* 3686400, invalid for voice codec */
288 33600000,
289};
290
291static int mc13783_set_sysclk(struct snd_soc_dai *dai,
292 int clk_id, unsigned int freq, int dir,
293 unsigned int reg)
294{
295 struct snd_soc_codec *codec = dai->codec;
296 int clk;
297 unsigned int val = 0;
298 unsigned int mask = AUDIO_CLK(0x7) | AUDIO_CLK_SEL;
299
300 for (clk = 0; clk < ARRAY_SIZE(mc13783_sysclk); clk++) {
301 if (mc13783_sysclk[clk] < 0)
302 continue;
303 if (mc13783_sysclk[clk] == freq)
304 break;
305 }
306
307 if (clk == ARRAY_SIZE(mc13783_sysclk))
308 return -EINVAL;
309
310 if (clk_id == MC13783_CLK_CLIB)
311 val |= AUDIO_CLK_SEL;
312
313 val |= AUDIO_CLK(clk);
314
315 snd_soc_update_bits(codec, reg, mask, val);
316
317 return 0;
318}
319
320static int mc13783_set_sysclk_dac(struct snd_soc_dai *dai,
321 int clk_id, unsigned int freq, int dir)
322{
323 return mc13783_set_sysclk(dai, clk_id, freq, dir, MC13783_AUDIO_DAC);
324}
325
326static int mc13783_set_sysclk_codec(struct snd_soc_dai *dai,
327 int clk_id, unsigned int freq, int dir)
328{
329 return mc13783_set_sysclk(dai, clk_id, freq, dir, MC13783_AUDIO_CODEC);
330}
331
332static int mc13783_set_sysclk_sync(struct snd_soc_dai *dai,
333 int clk_id, unsigned int freq, int dir)
334{
335 int ret;
336
337 ret = mc13783_set_sysclk(dai, clk_id, freq, dir, MC13783_AUDIO_DAC);
338 if (ret)
339 return ret;
340
341 return mc13783_set_sysclk(dai, clk_id, freq, dir, MC13783_AUDIO_CODEC);
342}
343
344static int mc13783_set_tdm_slot_dac(struct snd_soc_dai *dai,
345 unsigned int tx_mask, unsigned int rx_mask, int slots,
346 int slot_width)
347{
348 struct snd_soc_codec *codec = dai->codec;
349 unsigned int val = 0;
350 unsigned int mask = SSI_NETWORK_DAC_SLOT_MASK |
351 SSI_NETWORK_DAC_RXSLOT_MASK;
352
353 switch (slots) {
354 case 2:
355 val |= SSI_NETWORK_DAC_SLOTS_2;
356 break;
357 case 4:
358 val |= SSI_NETWORK_DAC_SLOTS_4;
359 break;
360 case 8:
361 val |= SSI_NETWORK_DAC_SLOTS_8;
362 break;
363 default:
364 return -EINVAL;
365 }
366
367 switch (rx_mask) {
368 case 0xfffffffc:
369 val |= SSI_NETWORK_DAC_RXSLOT_0_1;
370 break;
371 case 0xfffffff3:
372 val |= SSI_NETWORK_DAC_RXSLOT_2_3;
373 break;
374 case 0xffffffcf:
375 val |= SSI_NETWORK_DAC_RXSLOT_4_5;
376 break;
377 case 0xffffff3f:
378 val |= SSI_NETWORK_DAC_RXSLOT_6_7;
379 break;
380 default:
381 return -EINVAL;
382 };
383
384 snd_soc_update_bits(codec, MC13783_SSI_NETWORK, mask, val);
385
386 return 0;
387}
388
389static int mc13783_set_tdm_slot_codec(struct snd_soc_dai *dai,
390 unsigned int tx_mask, unsigned int rx_mask, int slots,
391 int slot_width)
392{
393 struct snd_soc_codec *codec = dai->codec;
394 unsigned int val = 0;
395 unsigned int mask = 0x3f;
396
397 if (slots != 4)
398 return -EINVAL;
399
400 if (tx_mask != 0xfffffffc)
401 return -EINVAL;
402
403 val |= (0x00 << 2); /* primary timeslot RX/TX(?) is 0 */
404 val |= (0x01 << 4); /* secondary timeslot TX is 1 */
405
406 snd_soc_update_bits(codec, MC13783_SSI_NETWORK, mask, val);
407
408 return 0;
409}
410
411static int mc13783_set_tdm_slot_sync(struct snd_soc_dai *dai,
412 unsigned int tx_mask, unsigned int rx_mask, int slots,
413 int slot_width)
414{
415 int ret;
416
417 ret = mc13783_set_tdm_slot_dac(dai, tx_mask, rx_mask, slots,
418 slot_width);
419 if (ret)
420 return ret;
421
422 ret = mc13783_set_tdm_slot_codec(dai, tx_mask, rx_mask, slots,
423 slot_width);
424
425 return ret;
426}
427
428static const struct snd_kcontrol_new mc1l_amp_ctl =
429 SOC_DAPM_SINGLE("Switch", 38, 7, 1, 0);
430
431static const struct snd_kcontrol_new mc1r_amp_ctl =
432 SOC_DAPM_SINGLE("Switch", 38, 5, 1, 0);
433
434static const struct snd_kcontrol_new mc2_amp_ctl =
435 SOC_DAPM_SINGLE("Switch", 38, 9, 1, 0);
436
437static const struct snd_kcontrol_new atx_amp_ctl =
438 SOC_DAPM_SINGLE("Switch", 38, 11, 1, 0);
439
440
441/* Virtual mux. The chip does the input selection automatically
442 * as soon as we enable one input. */
443static const char * const adcl_enum_text[] = {
444 "MC1L", "RXINL",
445};
446
447static const struct soc_enum adcl_enum =
448 SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(adcl_enum_text), adcl_enum_text);
449
450static const struct snd_kcontrol_new left_input_mux =
451 SOC_DAPM_ENUM_VIRT("Route", adcl_enum);
452
453static const char * const adcr_enum_text[] = {
454 "MC1R", "MC2", "RXINR", "TXIN",
455};
456
457static const struct soc_enum adcr_enum =
458 SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(adcr_enum_text), adcr_enum_text);
459
460static const struct snd_kcontrol_new right_input_mux =
461 SOC_DAPM_ENUM_VIRT("Route", adcr_enum);
462
463static const struct snd_kcontrol_new samp_ctl =
464 SOC_DAPM_SINGLE("Switch", 36, 3, 1, 0);
465
466static const struct snd_kcontrol_new lamp_ctl =
467 SOC_DAPM_SINGLE("Switch", 36, 5, 1, 0);
468
469static const struct snd_kcontrol_new hlamp_ctl =
470 SOC_DAPM_SINGLE("Switch", 36, 10, 1, 0);
471
472static const struct snd_kcontrol_new hramp_ctl =
473 SOC_DAPM_SINGLE("Switch", 36, 9, 1, 0);
474
475static const struct snd_kcontrol_new llamp_ctl =
476 SOC_DAPM_SINGLE("Switch", 36, 16, 1, 0);
477
478static const struct snd_kcontrol_new lramp_ctl =
479 SOC_DAPM_SINGLE("Switch", 36, 15, 1, 0);
480
481static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = {
482/* Input */
483 SND_SOC_DAPM_INPUT("MC1LIN"),
484 SND_SOC_DAPM_INPUT("MC1RIN"),
485 SND_SOC_DAPM_INPUT("MC2IN"),
486 SND_SOC_DAPM_INPUT("RXINR"),
487 SND_SOC_DAPM_INPUT("RXINL"),
488 SND_SOC_DAPM_INPUT("TXIN"),
489
490 SND_SOC_DAPM_SUPPLY("MC1 Bias", 38, 0, 0, NULL, 0),
491 SND_SOC_DAPM_SUPPLY("MC2 Bias", 38, 1, 0, NULL, 0),
492
493 SND_SOC_DAPM_SWITCH("MC1L Amp", 38, 7, 0, &mc1l_amp_ctl),
494 SND_SOC_DAPM_SWITCH("MC1R Amp", 38, 5, 0, &mc1r_amp_ctl),
495 SND_SOC_DAPM_SWITCH("MC2 Amp", 38, 9, 0, &mc2_amp_ctl),
496 SND_SOC_DAPM_SWITCH("TXIN Amp", 38, 11, 0, &atx_amp_ctl),
497
498 SND_SOC_DAPM_VIRT_MUX("PGA Left Input Mux", SND_SOC_NOPM, 0, 0,
499 &left_input_mux),
500 SND_SOC_DAPM_VIRT_MUX("PGA Right Input Mux", SND_SOC_NOPM, 0, 0,
501 &right_input_mux),
502
503 SND_SOC_DAPM_PGA("PGA Left Input", SND_SOC_NOPM, 0, 0, NULL, 0),
504 SND_SOC_DAPM_PGA("PGA Right Input", SND_SOC_NOPM, 0, 0, NULL, 0),
505
506 SND_SOC_DAPM_ADC("ADC", "Capture", 40, 11, 0),
507 SND_SOC_DAPM_SUPPLY("ADC_Reset", 40, 15, 0, NULL, 0),
508
509/* Output */
510 SND_SOC_DAPM_SUPPLY("DAC_E", 41, 11, 0, NULL, 0),
511 SND_SOC_DAPM_SUPPLY("DAC_Reset", 41, 15, 0, NULL, 0),
512 SND_SOC_DAPM_OUTPUT("RXOUTL"),
513 SND_SOC_DAPM_OUTPUT("RXOUTR"),
514 SND_SOC_DAPM_OUTPUT("HSL"),
515 SND_SOC_DAPM_OUTPUT("HSR"),
516 SND_SOC_DAPM_OUTPUT("LSP"),
517 SND_SOC_DAPM_OUTPUT("SP"),
518
519 SND_SOC_DAPM_SWITCH("Speaker Amp", 36, 3, 0, &samp_ctl),
520 SND_SOC_DAPM_SWITCH("Loudspeaker Amp", SND_SOC_NOPM, 0, 0, &lamp_ctl),
521 SND_SOC_DAPM_SWITCH("Headset Amp Left", 36, 10, 0, &hlamp_ctl),
522 SND_SOC_DAPM_SWITCH("Headset Amp Right", 36, 9, 0, &hramp_ctl),
523 SND_SOC_DAPM_SWITCH("Line out Amp Left", 36, 16, 0, &llamp_ctl),
524 SND_SOC_DAPM_SWITCH("Line out Amp Right", 36, 15, 0, &lramp_ctl),
525 SND_SOC_DAPM_DAC("DAC", "Playback", 36, 22, 0),
526 SND_SOC_DAPM_PGA("DAC PGA", 37, 5, 0, NULL, 0),
527};
528
529static struct snd_soc_dapm_route mc13783_routes[] = {
530/* Input */
531 { "MC1L Amp", NULL, "MC1LIN"},
532 { "MC1R Amp", NULL, "MC1RIN" },
533 { "MC2 Amp", NULL, "MC2IN" },
534 { "TXIN Amp", NULL, "TXIN"},
535
536 { "PGA Left Input Mux", "MC1L", "MC1L Amp" },
537 { "PGA Left Input Mux", "RXINL", "RXINL"},
538 { "PGA Right Input Mux", "MC1R", "MC1R Amp" },
539 { "PGA Right Input Mux", "MC2", "MC2 Amp"},
540 { "PGA Right Input Mux", "TXIN", "TXIN Amp"},
541 { "PGA Right Input Mux", "RXINR", "RXINR"},
542
543 { "PGA Left Input", NULL, "PGA Left Input Mux"},
544 { "PGA Right Input", NULL, "PGA Right Input Mux"},
545
546 { "ADC", NULL, "PGA Left Input"},
547 { "ADC", NULL, "PGA Right Input"},
548 { "ADC", NULL, "ADC_Reset"},
549
550/* Output */
551 { "HSL", NULL, "Headset Amp Left" },
552 { "HSR", NULL, "Headset Amp Right"},
553 { "RXOUTL", NULL, "Line out Amp Left"},
554 { "RXOUTR", NULL, "Line out Amp Right"},
555 { "SP", NULL, "Speaker Amp"},
556 { "Speaker Amp", NULL, "DAC PGA"},
557 { "LSP", NULL, "DAC PGA"},
558 { "Headset Amp Left", NULL, "DAC PGA"},
559 { "Headset Amp Right", NULL, "DAC PGA"},
560 { "Line out Amp Left", NULL, "DAC PGA"},
561 { "Line out Amp Right", NULL, "DAC PGA"},
562 { "DAC PGA", NULL, "DAC"},
563 { "DAC", NULL, "DAC_E"},
564};
565
566static const char * const mc13783_3d_mixer[] = {"Stereo", "Phase Mix",
567 "Mono", "Mono Mix"};
568
569static const struct soc_enum mc13783_enum_3d_mixer =
570 SOC_ENUM_SINGLE(MC13783_AUDIO_RX1, 16, ARRAY_SIZE(mc13783_3d_mixer),
571 mc13783_3d_mixer);
572
573static struct snd_kcontrol_new mc13783_control_list[] = {
574 SOC_SINGLE("Loudspeaker enable", MC13783_AUDIO_RX0, 5, 1, 0),
575 SOC_SINGLE("PCM Playback Volume", MC13783_AUDIO_RX1, 6, 15, 0),
576 SOC_DOUBLE("PCM Capture Volume", MC13783_AUDIO_TX, 19, 14, 31, 0),
577 SOC_ENUM("3D Control", mc13783_enum_3d_mixer),
578};
579
580static int mc13783_probe(struct snd_soc_codec *codec)
581{
582 struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
583
584 mc13xxx_lock(priv->mc13xxx);
585
586 /* these are the reset values */
587 mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX0, 0x25893);
588 mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX1, 0x00d35A);
589 mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_TX, 0x420000);
590 mc13xxx_reg_write(priv->mc13xxx, MC13783_SSI_NETWORK, 0x013060);
591 mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_CODEC, 0x180027);
592 mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_DAC, 0x0e0004);
593
594 if (priv->adc_ssi_port == MC13783_SSI1_PORT)
595 mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_CODEC,
596 AUDIO_SSI_SEL, 0);
597 else
598 mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_CODEC,
599 0, AUDIO_SSI_SEL);
600
601 if (priv->dac_ssi_port == MC13783_SSI1_PORT)
602 mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC,
603 AUDIO_SSI_SEL, 0);
604 else
605 mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_DAC,
606 0, AUDIO_SSI_SEL);
607
608 mc13xxx_unlock(priv->mc13xxx);
609
610 return 0;
611}
612
613static int mc13783_remove(struct snd_soc_codec *codec)
614{
615 struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
616
617 mc13xxx_lock(priv->mc13xxx);
618
619 /* Make sure VAUDIOON is off */
620 mc13xxx_reg_rmw(priv->mc13xxx, MC13783_AUDIO_RX0, 0x3, 0);
621
622 mc13xxx_unlock(priv->mc13xxx);
623
624 return 0;
625}
626
627#define MC13783_RATES_RECORD (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000)
628
629#define MC13783_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
630 SNDRV_PCM_FMTBIT_S24_LE)
631
632static struct snd_soc_dai_ops mc13783_ops_dac = {
633 .hw_params = mc13783_pcm_hw_params_dac,
634 .set_fmt = mc13783_set_fmt_async,
635 .set_sysclk = mc13783_set_sysclk_dac,
636 .set_tdm_slot = mc13783_set_tdm_slot_dac,
637};
638
639static struct snd_soc_dai_ops mc13783_ops_codec = {
640 .hw_params = mc13783_pcm_hw_params_codec,
641 .set_fmt = mc13783_set_fmt_async,
642 .set_sysclk = mc13783_set_sysclk_codec,
643 .set_tdm_slot = mc13783_set_tdm_slot_codec,
644};
645
646/*
647 * The mc13783 has two SSI ports, both of them can be routed either
648 * to the voice codec or the stereo DAC. When two different SSI ports
649 * are used for the voice codec and the stereo DAC we can do different
650 * formats and sysclock settings for playback and capture
651 * (mc13783-hifi-playback and mc13783-hifi-capture). Using the same port
652 * forces us to use symmetric rates (mc13783-hifi).
653 */
654static struct snd_soc_dai_driver mc13783_dai_async[] = {
655 {
656 .name = "mc13783-hifi-playback",
657 .id = MC13783_ID_STEREO_DAC,
658 .playback = {
659 .stream_name = "Playback",
660 .channels_min = 1,
661 .channels_max = 2,
662 .rates = SNDRV_PCM_RATE_8000_96000,
663 .formats = MC13783_FORMATS,
664 },
665 .ops = &mc13783_ops_dac,
666 }, {
667 .name = "mc13783-hifi-capture",
668 .id = MC13783_ID_STEREO_CODEC,
669 .capture = {
670 .stream_name = "Capture",
671 .channels_min = 1,
672 .channels_max = 2,
673 .rates = MC13783_RATES_RECORD,
674 .formats = MC13783_FORMATS,
675 },
676 .ops = &mc13783_ops_codec,
677 },
678};
679
680static struct snd_soc_dai_ops mc13783_ops_sync = {
681 .hw_params = mc13783_pcm_hw_params_sync,
682 .set_fmt = mc13783_set_fmt_sync,
683 .set_sysclk = mc13783_set_sysclk_sync,
684 .set_tdm_slot = mc13783_set_tdm_slot_sync,
685};
686
687static struct snd_soc_dai_driver mc13783_dai_sync[] = {
688 {
689 .name = "mc13783-hifi",
690 .id = MC13783_ID_SYNC,
691 .playback = {
692 .stream_name = "Playback",
693 .channels_min = 1,
694 .channels_max = 2,
695 .rates = SNDRV_PCM_RATE_8000_96000,
696 .formats = MC13783_FORMATS,
697 },
698 .capture = {
699 .stream_name = "Capture",
700 .channels_min = 1,
701 .channels_max = 2,
702 .rates = MC13783_RATES_RECORD,
703 .formats = MC13783_FORMATS,
704 },
705 .ops = &mc13783_ops_sync,
706 .symmetric_rates = 1,
707 }
708};
709
710static struct snd_soc_codec_driver soc_codec_dev_mc13783 = {
711 .probe = mc13783_probe,
712 .remove = mc13783_remove,
713 .read = mc13783_read,
714 .write = mc13783_write,
715 .controls = mc13783_control_list,
716 .num_controls = ARRAY_SIZE(mc13783_control_list),
717 .dapm_widgets = mc13783_dapm_widgets,
718 .num_dapm_widgets = ARRAY_SIZE(mc13783_dapm_widgets),
719 .dapm_routes = mc13783_routes,
720 .num_dapm_routes = ARRAY_SIZE(mc13783_routes),
721};
722
723static int mc13783_codec_probe(struct platform_device *pdev)
724{
725 struct mc13xxx *mc13xxx;
726 struct mc13783_priv *priv;
727 struct mc13xxx_codec_platform_data *pdata = pdev->dev.platform_data;
728 int ret;
729
730 mc13xxx = dev_get_drvdata(pdev->dev.parent);
731
732
733 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
734 if (priv == NULL)
735 return -ENOMEM;
736
737 dev_set_drvdata(&pdev->dev, priv);
738 priv->mc13xxx = mc13xxx;
739 if (pdata) {
740 priv->adc_ssi_port = pdata->adc_ssi_port;
741 priv->dac_ssi_port = pdata->dac_ssi_port;
742 } else {
743 priv->adc_ssi_port = MC13783_SSI1_PORT;
744 priv->dac_ssi_port = MC13783_SSI2_PORT;
745 }
746
747 if (priv->adc_ssi_port == priv->dac_ssi_port)
748 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783,
749 mc13783_dai_sync, ARRAY_SIZE(mc13783_dai_sync));
750 else
751 ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783,
752 mc13783_dai_async, ARRAY_SIZE(mc13783_dai_async));
753
754 if (ret)
755 goto err_register_codec;
756
757 return 0;
758
759err_register_codec:
760 dev_err(&pdev->dev, "register codec failed with %d\n", ret);
761
762 return ret;
763}
764
765static int mc13783_codec_remove(struct platform_device *pdev)
766{
767 snd_soc_unregister_codec(&pdev->dev);
768
769 return 0;
770}
771
772static struct platform_driver mc13783_codec_driver = {
773 .driver = {
774 .name = "mc13783-codec",
775 .owner = THIS_MODULE,
776 },
777 .probe = mc13783_codec_probe,
778 .remove = __devexit_p(mc13783_codec_remove),
779};
780
781module_platform_driver(mc13783_codec_driver);
782
783MODULE_DESCRIPTION("ASoC MC13783 driver");
784MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>");
785MODULE_AUTHOR("Philippe Retornaz <philippe.retornaz@epfl.ch>");
786MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/mc13783.h b/sound/soc/codecs/mc13783.h
new file mode 100644
index 000000000000..3a6d1993a217
--- /dev/null
+++ b/sound/soc/codecs/mc13783.h
@@ -0,0 +1,28 @@
1/*
2 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation, Inc.
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 */
17
18#ifndef MC13783_MIXER_H
19#define MC13783_MIXER_H
20
21#define MC13783_CLK_CLIA 1
22#define MC13783_CLK_CLIB 2
23
24#define MC13783_ID_STEREO_DAC 1
25#define MC13783_ID_STEREO_CODEC 2
26#define MC13783_ID_SYNC 3
27
28#endif /* MC13783_MIXER_H */
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c
new file mode 100644
index 000000000000..22cb5bf59273
--- /dev/null
+++ b/sound/soc/codecs/ml26124.c
@@ -0,0 +1,681 @@
1/*
2 * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/init.h>
21#include <linux/delay.h>
22#include <linux/pm.h>
23#include <linux/i2c.h>
24#include <linux/slab.h>
25#include <linux/platform_device.h>
26#include <linux/regmap.h>
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/soc.h>
31#include <sound/tlv.h>
32#include "ml26124.h"
33
34#define DVOL_CTL_DVMUTE_ON BIT(4) /* Digital volume MUTE On */
35#define DVOL_CTL_DVMUTE_OFF 0 /* Digital volume MUTE Off */
36#define ML26124_SAI_NO_DELAY BIT(1)
37#define ML26124_SAI_FRAME_SYNC (BIT(5) | BIT(0)) /* For mono (Telecodec) */
38#define ML26134_CACHESIZE 212
39#define ML26124_VMID BIT(1)
40#define ML26124_RATES (SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_32000 |\
41 SNDRV_PCM_RATE_48000)
42#define ML26124_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |\
43 SNDRV_PCM_FMTBIT_S32_LE)
44#define ML26124_NUM_REGISTER ML26134_CACHESIZE
45
46struct ml26124_priv {
47 u32 mclk;
48 u32 rate;
49 struct regmap *regmap;
50 int clk_in;
51 struct snd_pcm_substream *substream;
52};
53
54struct clk_coeff {
55 u32 mclk;
56 u32 rate;
57 u8 pllnl;
58 u8 pllnh;
59 u8 pllml;
60 u8 pllmh;
61 u8 plldiv;
62};
63
64/* ML26124 configuration */
65static const DECLARE_TLV_DB_SCALE(digital_tlv, -7150, 50, 0);
66
67static const DECLARE_TLV_DB_SCALE(alclvl, -2250, 150, 0);
68static const DECLARE_TLV_DB_SCALE(mingain, -1200, 600, 0);
69static const DECLARE_TLV_DB_SCALE(maxgain, -675, 600, 0);
70static const DECLARE_TLV_DB_SCALE(boost_vol, -1200, 75, 0);
71static const DECLARE_TLV_DB_SCALE(ngth, -7650, 150, 0);
72
73static const char * const ml26124_companding[] = {"16bit PCM", "u-law",
74 "A-law"};
75
76static const struct soc_enum ml26124_adc_companding_enum
77 = SOC_ENUM_SINGLE(ML26124_SAI_TRANS_CTL, 6, 3, ml26124_companding);
78
79static const struct soc_enum ml26124_dac_companding_enum
80 = SOC_ENUM_SINGLE(ML26124_SAI_RCV_CTL, 6, 3, ml26124_companding);
81
82static const struct snd_kcontrol_new ml26124_snd_controls[] = {
83 SOC_SINGLE_TLV("Capture Digital Volume", ML26124_RECORD_DIG_VOL, 0,
84 0xff, 1, digital_tlv),
85 SOC_SINGLE_TLV("Playback Digital Volume", ML26124_PLBAK_DIG_VOL, 0,
86 0xff, 1, digital_tlv),
87 SOC_SINGLE_TLV("Digital Boost Volume", ML26124_DIGI_BOOST_VOL, 0,
88 0x3f, 0, boost_vol),
89 SOC_SINGLE_TLV("EQ Band0 Volume", ML26124_EQ_GAIN_BRAND0, 0,
90 0xff, 1, digital_tlv),
91 SOC_SINGLE_TLV("EQ Band1 Volume", ML26124_EQ_GAIN_BRAND1, 0,
92 0xff, 1, digital_tlv),
93 SOC_SINGLE_TLV("EQ Band2 Volume", ML26124_EQ_GAIN_BRAND2, 0,
94 0xff, 1, digital_tlv),
95 SOC_SINGLE_TLV("EQ Band3 Volume", ML26124_EQ_GAIN_BRAND3, 0,
96 0xff, 1, digital_tlv),
97 SOC_SINGLE_TLV("EQ Band4 Volume", ML26124_EQ_GAIN_BRAND4, 0,
98 0xff, 1, digital_tlv),
99 SOC_SINGLE_TLV("ALC Target Level", ML26124_ALC_TARGET_LEV, 0,
100 0xf, 1, alclvl),
101 SOC_SINGLE_TLV("ALC Min Input Volume", ML26124_ALC_MAXMIN_GAIN, 0,
102 7, 0, mingain),
103 SOC_SINGLE_TLV("ALC Max Input Volume", ML26124_ALC_MAXMIN_GAIN, 4,
104 7, 1, maxgain),
105 SOC_SINGLE_TLV("Playback Limiter Min Input Volume",
106 ML26124_PL_MAXMIN_GAIN, 0, 7, 0, mingain),
107 SOC_SINGLE_TLV("Playback Limiter Max Input Volume",
108 ML26124_PL_MAXMIN_GAIN, 4, 7, 1, maxgain),
109 SOC_SINGLE_TLV("Playback Boost Volume", ML26124_PLYBAK_BOST_VOL, 0,
110 0x3f, 0, boost_vol),
111 SOC_SINGLE("DC High Pass Filter Switch", ML26124_FILTER_EN, 0, 1, 0),
112 SOC_SINGLE("Noise High Pass Filter Switch", ML26124_FILTER_EN, 1, 1, 0),
113 SOC_SINGLE("ZC Switch", ML26124_PW_ZCCMP_PW_MNG, 1,
114 1, 0),
115 SOC_SINGLE("EQ Band0 Switch", ML26124_FILTER_EN, 2, 1, 0),
116 SOC_SINGLE("EQ Band1 Switch", ML26124_FILTER_EN, 3, 1, 0),
117 SOC_SINGLE("EQ Band2 Switch", ML26124_FILTER_EN, 4, 1, 0),
118 SOC_SINGLE("EQ Band3 Switch", ML26124_FILTER_EN, 5, 1, 0),
119 SOC_SINGLE("EQ Band4 Switch", ML26124_FILTER_EN, 6, 1, 0),
120 SOC_SINGLE("Play Limiter", ML26124_DVOL_CTL, 0, 1, 0),
121 SOC_SINGLE("Capture Limiter", ML26124_DVOL_CTL, 1, 1, 0),
122 SOC_SINGLE("Digital Volume Fade Switch", ML26124_DVOL_CTL, 3, 1, 0),
123 SOC_SINGLE("Digital Switch", ML26124_DVOL_CTL, 4, 1, 0),
124 SOC_ENUM("DAC Companding", ml26124_dac_companding_enum),
125 SOC_ENUM("ADC Companding", ml26124_adc_companding_enum),
126};
127
128static const struct snd_kcontrol_new ml26124_output_mixer_controls[] = {
129 SOC_DAPM_SINGLE("DAC Switch", ML26124_SPK_AMP_OUT, 1, 1, 0),
130 SOC_DAPM_SINGLE("Line in loopback Switch", ML26124_SPK_AMP_OUT, 3, 1,
131 0),
132 SOC_DAPM_SINGLE("PGA Switch", ML26124_SPK_AMP_OUT, 5, 1, 0),
133};
134
135/* Input mux */
136static const char * const ml26124_input_select[] = {"Analog MIC SingleEnded in",
137 "Digital MIC in", "Analog MIC Differential in"};
138
139static const struct soc_enum ml26124_insel_enum =
140 SOC_ENUM_SINGLE(ML26124_MIC_IF_CTL, 0, 3, ml26124_input_select);
141
142static const struct snd_kcontrol_new ml26124_input_mux_controls =
143 SOC_DAPM_ENUM("Input Select", ml26124_insel_enum);
144
145static const struct snd_kcontrol_new ml26124_line_control =
146 SOC_DAPM_SINGLE("Switch", ML26124_PW_LOUT_PW_MNG, 1, 1, 0);
147
148static const struct snd_soc_dapm_widget ml26124_dapm_widgets[] = {
149 SND_SOC_DAPM_SUPPLY("MCLKEN", ML26124_CLK_EN, 0, 0, NULL, 0),
150 SND_SOC_DAPM_SUPPLY("PLLEN", ML26124_CLK_EN, 1, 0, NULL, 0),
151 SND_SOC_DAPM_SUPPLY("PLLOE", ML26124_CLK_EN, 2, 0, NULL, 0),
152 SND_SOC_DAPM_SUPPLY("MICBIAS", ML26124_PW_REF_PW_MNG, 2, 0, NULL, 0),
153 SND_SOC_DAPM_MIXER("Output Mixer", SND_SOC_NOPM, 0, 0,
154 &ml26124_output_mixer_controls[0],
155 ARRAY_SIZE(ml26124_output_mixer_controls)),
156 SND_SOC_DAPM_DAC("DAC", "Playback", ML26124_PW_DAC_PW_MNG, 1, 0),
157 SND_SOC_DAPM_ADC("ADC", "Capture", ML26124_PW_IN_PW_MNG, 1, 0),
158 SND_SOC_DAPM_PGA("PGA", ML26124_PW_IN_PW_MNG, 3, 0, NULL, 0),
159 SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
160 &ml26124_input_mux_controls),
161 SND_SOC_DAPM_SWITCH("Line Out Enable", SND_SOC_NOPM, 0, 0,
162 &ml26124_line_control),
163 SND_SOC_DAPM_INPUT("MDIN"),
164 SND_SOC_DAPM_INPUT("MIN"),
165 SND_SOC_DAPM_INPUT("LIN"),
166 SND_SOC_DAPM_OUTPUT("SPOUT"),
167 SND_SOC_DAPM_OUTPUT("LOUT"),
168};
169
170static const struct snd_soc_dapm_route ml26124_intercon[] = {
171 /* Supply */
172 {"DAC", NULL, "MCLKEN"},
173 {"ADC", NULL, "MCLKEN"},
174 {"DAC", NULL, "PLLEN"},
175 {"ADC", NULL, "PLLEN"},
176 {"DAC", NULL, "PLLOE"},
177 {"ADC", NULL, "PLLOE"},
178
179 /* output mixer */
180 {"Output Mixer", "DAC Switch", "DAC"},
181 {"Output Mixer", "Line in loopback Switch", "LIN"},
182
183 /* outputs */
184 {"LOUT", NULL, "Output Mixer"},
185 {"SPOUT", NULL, "Output Mixer"},
186 {"Line Out Enable", NULL, "LOUT"},
187
188 /* input */
189 {"ADC", NULL, "Input Mux"},
190 {"Input Mux", "Analog MIC SingleEnded in", "PGA"},
191 {"Input Mux", "Analog MIC Differential in", "PGA"},
192 {"PGA", NULL, "MIN"},
193};
194
195/* PLLOutputFreq(Hz) = InputMclkFreq(Hz) * PLLM / (PLLN * PLLDIV) */
196static const struct clk_coeff coeff_div[] = {
197 {12288000, 16000, 0xc, 0x0, 0x20, 0x0, 0x4},
198 {12288000, 32000, 0xc, 0x0, 0x20, 0x0, 0x4},
199 {12288000, 48000, 0xc, 0x0, 0x30, 0x0, 0x4},
200};
201
202static struct reg_default ml26124_reg[] = {
203 /* CLOCK control Register */
204 {0x00, 0x00 }, /* Sampling Rate */
205 {0x02, 0x00}, /* PLL NL */
206 {0x04, 0x00}, /* PLLNH */
207 {0x06, 0x00}, /* PLLML */
208 {0x08, 0x00}, /* MLLMH */
209 {0x0a, 0x00}, /* PLLDIV */
210 {0x0c, 0x00}, /* Clock Enable */
211 {0x0e, 0x00}, /* CLK Input/Output Control */
212
213 /* System Control Register */
214 {0x10, 0x00}, /* Software RESET */
215 {0x12, 0x00}, /* Record/Playback Run */
216 {0x14, 0x00}, /* Mic Input/Output control */
217
218 /* Power Management Register */
219 {0x20, 0x00}, /* Reference Power Management */
220 {0x22, 0x00}, /* Input Power Management */
221 {0x24, 0x00}, /* DAC Power Management */
222 {0x26, 0x00}, /* SP-AMP Power Management */
223 {0x28, 0x00}, /* LINEOUT Power Management */
224 {0x2a, 0x00}, /* VIDEO Power Management */
225 {0x2e, 0x00}, /* AC-CMP Power Management */
226
227 /* Analog reference Control Register */
228 {0x30, 0x04}, /* MICBIAS Voltage Control */
229
230 /* Input/Output Amplifier Control Register */
231 {0x32, 0x10}, /* MIC Input Volume */
232 {0x38, 0x00}, /* Mic Boost Volume */
233 {0x3a, 0x33}, /* Speaker AMP Volume */
234 {0x48, 0x00}, /* AMP Volume Control Function Enable */
235 {0x4a, 0x00}, /* Amplifier Volume Fader Control */
236
237 /* Analog Path Control Register */
238 {0x54, 0x00}, /* Speaker AMP Output Control */
239 {0x5a, 0x00}, /* Mic IF Control */
240 {0xe8, 0x01}, /* Mic Select Control */
241
242 /* Audio Interface Control Register */
243 {0x60, 0x00}, /* SAI-Trans Control */
244 {0x62, 0x00}, /* SAI-Receive Control */
245 {0x64, 0x00}, /* SAI Mode select */
246
247 /* DSP Control Register */
248 {0x66, 0x01}, /* Filter Func Enable */
249 {0x68, 0x00}, /* Volume Control Func Enable */
250 {0x6A, 0x00}, /* Mixer & Volume Control*/
251 {0x6C, 0xff}, /* Record Digital Volume */
252 {0x70, 0xff}, /* Playback Digital Volume */
253 {0x72, 0x10}, /* Digital Boost Volume */
254 {0x74, 0xe7}, /* EQ gain Band0 */
255 {0x76, 0xe7}, /* EQ gain Band1 */
256 {0x78, 0xe7}, /* EQ gain Band2 */
257 {0x7A, 0xe7}, /* EQ gain Band3 */
258 {0x7C, 0xe7}, /* EQ gain Band4 */
259 {0x7E, 0x00}, /* HPF2 CutOff*/
260 {0x80, 0x00}, /* EQ Band0 Coef0L */
261 {0x82, 0x00}, /* EQ Band0 Coef0H */
262 {0x84, 0x00}, /* EQ Band0 Coef0L */
263 {0x86, 0x00}, /* EQ Band0 Coef0H */
264 {0x88, 0x00}, /* EQ Band1 Coef0L */
265 {0x8A, 0x00}, /* EQ Band1 Coef0H */
266 {0x8C, 0x00}, /* EQ Band1 Coef0L */
267 {0x8E, 0x00}, /* EQ Band1 Coef0H */
268 {0x90, 0x00}, /* EQ Band2 Coef0L */
269 {0x92, 0x00}, /* EQ Band2 Coef0H */
270 {0x94, 0x00}, /* EQ Band2 Coef0L */
271 {0x96, 0x00}, /* EQ Band2 Coef0H */
272 {0x98, 0x00}, /* EQ Band3 Coef0L */
273 {0x9A, 0x00}, /* EQ Band3 Coef0H */
274 {0x9C, 0x00}, /* EQ Band3 Coef0L */
275 {0x9E, 0x00}, /* EQ Band3 Coef0H */
276 {0xA0, 0x00}, /* EQ Band4 Coef0L */
277 {0xA2, 0x00}, /* EQ Band4 Coef0H */
278 {0xA4, 0x00}, /* EQ Band4 Coef0L */
279 {0xA6, 0x00}, /* EQ Band4 Coef0H */
280
281 /* ALC Control Register */
282 {0xb0, 0x00}, /* ALC Mode */
283 {0xb2, 0x02}, /* ALC Attack Time */
284 {0xb4, 0x03}, /* ALC Decay Time */
285 {0xb6, 0x00}, /* ALC Hold Time */
286 {0xb8, 0x0b}, /* ALC Target Level */
287 {0xba, 0x70}, /* ALC Max/Min Gain */
288 {0xbc, 0x00}, /* Noise Gate Threshold */
289 {0xbe, 0x00}, /* ALC ZeroCross TimeOut */
290
291 /* Playback Limiter Control Register */
292 {0xc0, 0x04}, /* PL Attack Time */
293 {0xc2, 0x05}, /* PL Decay Time */
294 {0xc4, 0x0d}, /* PL Target Level */
295 {0xc6, 0x70}, /* PL Max/Min Gain */
296 {0xc8, 0x10}, /* Playback Boost Volume */
297 {0xca, 0x00}, /* PL ZeroCross TimeOut */
298
299 /* Video Amplifier Control Register */
300 {0xd0, 0x01}, /* VIDEO AMP Gain Control */
301 {0xd2, 0x01}, /* VIDEO AMP Setup 1 */
302 {0xd4, 0x01}, /* VIDEO AMP Control2 */
303};
304
305/* Get sampling rate value of sampling rate setting register (0x0) */
306static inline int get_srate(int rate)
307{
308 int srate;
309
310 switch (rate) {
311 case 16000:
312 srate = 3;
313 break;
314 case 32000:
315 srate = 6;
316 break;
317 case 48000:
318 srate = 8;
319 break;
320 default:
321 return -EINVAL;
322 }
323 return srate;
324}
325
326static inline int get_coeff(int mclk, int rate)
327{
328 int i;
329
330 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
331 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
332 return i;
333 }
334 return -EINVAL;
335}
336
337static int ml26124_hw_params(struct snd_pcm_substream *substream,
338 struct snd_pcm_hw_params *hw_params,
339 struct snd_soc_dai *dai)
340{
341 struct snd_soc_codec *codec = dai->codec;
342 struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
343 int i = get_coeff(priv->mclk, params_rate(hw_params));
344
345 priv->substream = substream;
346 priv->rate = params_rate(hw_params);
347
348 if (priv->clk_in) {
349 switch (priv->mclk / params_rate(hw_params)) {
350 case 256:
351 snd_soc_update_bits(codec, ML26124_CLK_CTL,
352 BIT(0) | BIT(1), 1);
353 break;
354 case 512:
355 snd_soc_update_bits(codec, ML26124_CLK_CTL,
356 BIT(0) | BIT(1), 2);
357 break;
358 case 1024:
359 snd_soc_update_bits(codec, ML26124_CLK_CTL,
360 BIT(0) | BIT(1), 3);
361 break;
362 default:
363 dev_err(codec->dev, "Unsupported MCLKI\n");
364 break;
365 }
366 } else {
367 snd_soc_update_bits(codec, ML26124_CLK_CTL,
368 BIT(0) | BIT(1), 0);
369 }
370
371 switch (params_rate(hw_params)) {
372 case 16000:
373 snd_soc_update_bits(codec, ML26124_SMPLING_RATE, 0xf,
374 get_srate(params_rate(hw_params)));
375 snd_soc_update_bits(codec, ML26124_PLLNL, 0xff,
376 coeff_div[i].pllnl);
377 snd_soc_update_bits(codec, ML26124_PLLNH, 0x1,
378 coeff_div[i].pllnh);
379 snd_soc_update_bits(codec, ML26124_PLLML, 0xff,
380 coeff_div[i].pllml);
381 snd_soc_update_bits(codec, ML26124_PLLMH, 0x3f,
382 coeff_div[i].pllmh);
383 snd_soc_update_bits(codec, ML26124_PLLDIV, 0x1f,
384 coeff_div[i].plldiv);
385 break;
386 case 32000:
387 snd_soc_update_bits(codec, ML26124_SMPLING_RATE, 0xf,
388 get_srate(params_rate(hw_params)));
389 snd_soc_update_bits(codec, ML26124_PLLNL, 0xff,
390 coeff_div[i].pllnl);
391 snd_soc_update_bits(codec, ML26124_PLLNH, 0x1,
392 coeff_div[i].pllnh);
393 snd_soc_update_bits(codec, ML26124_PLLML, 0xff,
394 coeff_div[i].pllml);
395 snd_soc_update_bits(codec, ML26124_PLLMH, 0x3f,
396 coeff_div[i].pllmh);
397 snd_soc_update_bits(codec, ML26124_PLLDIV, 0x1f,
398 coeff_div[i].plldiv);
399 break;
400 case 48000:
401 snd_soc_update_bits(codec, ML26124_SMPLING_RATE, 0xf,
402 get_srate(params_rate(hw_params)));
403 snd_soc_update_bits(codec, ML26124_PLLNL, 0xff,
404 coeff_div[i].pllnl);
405 snd_soc_update_bits(codec, ML26124_PLLNH, 0x1,
406 coeff_div[i].pllnh);
407 snd_soc_update_bits(codec, ML26124_PLLML, 0xff,
408 coeff_div[i].pllml);
409 snd_soc_update_bits(codec, ML26124_PLLMH, 0x3f,
410 coeff_div[i].pllmh);
411 snd_soc_update_bits(codec, ML26124_PLLDIV, 0x1f,
412 coeff_div[i].plldiv);
413 break;
414 default:
415 pr_err("%s:this rate is no support for ml26124\n", __func__);
416 return -EINVAL;
417 }
418
419 return 0;
420}
421
422static int ml26124_mute(struct snd_soc_dai *dai, int mute)
423{
424 struct snd_soc_codec *codec = dai->codec;
425 struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
426
427 switch (priv->substream->stream) {
428 case SNDRV_PCM_STREAM_CAPTURE:
429 snd_soc_update_bits(codec, ML26124_REC_PLYBAK_RUN, BIT(0), 1);
430 break;
431 case SNDRV_PCM_STREAM_PLAYBACK:
432 snd_soc_update_bits(codec, ML26124_REC_PLYBAK_RUN, BIT(1), 2);
433 break;
434 }
435
436 if (mute)
437 snd_soc_update_bits(codec, ML26124_DVOL_CTL, BIT(4),
438 DVOL_CTL_DVMUTE_ON);
439 else
440 snd_soc_update_bits(codec, ML26124_DVOL_CTL, BIT(4),
441 DVOL_CTL_DVMUTE_OFF);
442
443 return 0;
444}
445
446static int ml26124_set_dai_fmt(struct snd_soc_dai *codec_dai,
447 unsigned int fmt)
448{
449 unsigned char mode;
450 struct snd_soc_codec *codec = codec_dai->codec;
451
452 /* set master/slave audio interface */
453 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
454 case SND_SOC_DAIFMT_CBM_CFM:
455 mode = 1;
456 break;
457 case SND_SOC_DAIFMT_CBS_CFS:
458 mode = 0;
459 break;
460 default:
461 return -EINVAL;
462 }
463 snd_soc_update_bits(codec, ML26124_SAI_MODE_SEL, BIT(0), mode);
464
465 /* interface format */
466 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
467 case SND_SOC_DAIFMT_I2S:
468 break;
469 default:
470 return -EINVAL;
471 }
472
473 /* clock inversion */
474 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
475 case SND_SOC_DAIFMT_NB_NF:
476 break;
477 default:
478 return -EINVAL;
479 }
480
481 return 0;
482}
483
484static int ml26124_set_dai_sysclk(struct snd_soc_dai *codec_dai,
485 int clk_id, unsigned int freq, int dir)
486{
487 struct snd_soc_codec *codec = codec_dai->codec;
488 struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
489
490 switch (clk_id) {
491 case ML26124_USE_PLLOUT:
492 priv->clk_in = ML26124_USE_PLLOUT;
493 break;
494 case ML26124_USE_MCLKI:
495 priv->clk_in = ML26124_USE_MCLKI;
496 break;
497 default:
498 return -EINVAL;
499 }
500
501 priv->mclk = freq;
502
503 return 0;
504}
505
506static int ml26124_set_bias_level(struct snd_soc_codec *codec,
507 enum snd_soc_bias_level level)
508{
509 struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
510
511 switch (level) {
512 case SND_SOC_BIAS_ON:
513 snd_soc_update_bits(codec, ML26124_PW_SPAMP_PW_MNG,
514 ML26124_R26_MASK, ML26124_BLT_PREAMP_ON);
515 msleep(100);
516 snd_soc_update_bits(codec, ML26124_PW_SPAMP_PW_MNG,
517 ML26124_R26_MASK,
518 ML26124_MICBEN_ON | ML26124_BLT_ALL_ON);
519 break;
520 case SND_SOC_BIAS_PREPARE:
521 break;
522 case SND_SOC_BIAS_STANDBY:
523 /* VMID ON */
524 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
525 snd_soc_update_bits(codec, ML26124_PW_REF_PW_MNG,
526 ML26124_VMID, ML26124_VMID);
527 msleep(500);
528 regcache_sync(priv->regmap);
529 }
530 break;
531 case SND_SOC_BIAS_OFF:
532 /* VMID OFF */
533 snd_soc_update_bits(codec, ML26124_PW_REF_PW_MNG,
534 ML26124_VMID, 0);
535 break;
536 }
537 codec->dapm.bias_level = level;
538 return 0;
539}
540
541static const struct snd_soc_dai_ops ml26124_dai_ops = {
542 .hw_params = ml26124_hw_params,
543 .digital_mute = ml26124_mute,
544 .set_fmt = ml26124_set_dai_fmt,
545 .set_sysclk = ml26124_set_dai_sysclk,
546};
547
548static struct snd_soc_dai_driver ml26124_dai = {
549 .name = "ml26124-hifi",
550 .playback = {
551 .stream_name = "Playback",
552 .channels_min = 1,
553 .channels_max = 2,
554 .rates = ML26124_RATES,
555 .formats = ML26124_FORMATS,},
556 .capture = {
557 .stream_name = "Capture",
558 .channels_min = 1,
559 .channels_max = 2,
560 .rates = ML26124_RATES,
561 .formats = ML26124_FORMATS,},
562 .ops = &ml26124_dai_ops,
563 .symmetric_rates = 1,
564};
565
566#ifdef CONFIG_PM
567static int ml26124_suspend(struct snd_soc_codec *codec)
568{
569 ml26124_set_bias_level(codec, SND_SOC_BIAS_OFF);
570
571 return 0;
572}
573
574static int ml26124_resume(struct snd_soc_codec *codec)
575{
576 ml26124_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
577
578 return 0;
579}
580#else
581#define ml26124_suspend NULL
582#define ml26124_resume NULL
583#endif
584
585static int ml26124_probe(struct snd_soc_codec *codec)
586{
587 int ret;
588 struct ml26124_priv *priv = snd_soc_codec_get_drvdata(codec);
589 codec->control_data = priv->regmap;
590
591 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
592 if (ret < 0) {
593 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
594 return ret;
595 }
596
597 /* Software Reset */
598 snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 1);
599 snd_soc_update_bits(codec, ML26124_SW_RST, 0x01, 0);
600
601 ml26124_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
602
603 return 0;
604}
605
606static struct snd_soc_codec_driver soc_codec_dev_ml26124 = {
607 .probe = ml26124_probe,
608 .suspend = ml26124_suspend,
609 .resume = ml26124_resume,
610 .set_bias_level = ml26124_set_bias_level,
611 .dapm_widgets = ml26124_dapm_widgets,
612 .num_dapm_widgets = ARRAY_SIZE(ml26124_dapm_widgets),
613 .dapm_routes = ml26124_intercon,
614 .num_dapm_routes = ARRAY_SIZE(ml26124_intercon),
615 .controls = ml26124_snd_controls,
616 .num_controls = ARRAY_SIZE(ml26124_snd_controls),
617};
618
619static const struct regmap_config ml26124_i2c_regmap = {
620 .val_bits = 8,
621 .reg_bits = 8,
622 .max_register = ML26124_NUM_REGISTER,
623 .reg_defaults = ml26124_reg,
624 .num_reg_defaults = ARRAY_SIZE(ml26124_reg),
625 .cache_type = REGCACHE_RBTREE,
626 .write_flag_mask = 0x01,
627};
628
629static __devinit int ml26124_i2c_probe(struct i2c_client *i2c,
630 const struct i2c_device_id *id)
631{
632 struct ml26124_priv *priv;
633 int ret;
634
635 priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
636 if (!priv)
637 return -ENOMEM;
638
639 i2c_set_clientdata(i2c, priv);
640
641 priv->regmap = regmap_init_i2c(i2c, &ml26124_i2c_regmap);
642 if (IS_ERR(priv->regmap)) {
643 ret = PTR_ERR(priv->regmap);
644 dev_err(&i2c->dev, "regmap_init_i2c() failed: %d\n", ret);
645 return ret;
646 }
647
648 return snd_soc_register_codec(&i2c->dev,
649 &soc_codec_dev_ml26124, &ml26124_dai, 1);
650}
651
652static __devexit int ml26124_i2c_remove(struct i2c_client *client)
653{
654 struct ml26124_priv *priv = i2c_get_clientdata(client);
655
656 snd_soc_unregister_codec(&client->dev);
657 regmap_exit(priv->regmap);
658 return 0;
659}
660
661static const struct i2c_device_id ml26124_i2c_id[] = {
662 { "ml26124", 0 },
663 { }
664};
665MODULE_DEVICE_TABLE(i2c, ml26124_i2c_id);
666
667static struct i2c_driver ml26124_i2c_driver = {
668 .driver = {
669 .name = "ml26124",
670 .owner = THIS_MODULE,
671 },
672 .probe = ml26124_i2c_probe,
673 .remove = __devexit_p(ml26124_i2c_remove),
674 .id_table = ml26124_i2c_id,
675};
676
677module_i2c_driver(ml26124_i2c_driver);
678
679MODULE_AUTHOR("Tomoya MORINAGA <tomoya.rohm@gmail.com>");
680MODULE_DESCRIPTION("LAPIS Semiconductor ML26124 ALSA SoC codec driver");
681MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ml26124.h b/sound/soc/codecs/ml26124.h
new file mode 100644
index 000000000000..5ea0cbb8c46c
--- /dev/null
+++ b/sound/soc/codecs/ml26124.h
@@ -0,0 +1,184 @@
1/*
2 * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
16 */
17
18#ifndef ML26124_H
19#define ML26124_H
20
21/* Clock Control Register */
22#define ML26124_SMPLING_RATE 0x00
23#define ML26124_PLLNL 0x02
24#define ML26124_PLLNH 0x04
25#define ML26124_PLLML 0x06
26#define ML26124_PLLMH 0x08
27#define ML26124_PLLDIV 0x0a
28#define ML26124_CLK_EN 0x0c
29#define ML26124_CLK_CTL 0x0e
30
31/* System Control Register */
32#define ML26124_SW_RST 0x10
33#define ML26124_REC_PLYBAK_RUN 0x12
34#define ML26124_MIC_TIM 0x14
35
36/* Power Mnagement Register */
37#define ML26124_PW_REF_PW_MNG 0x20
38#define ML26124_PW_IN_PW_MNG 0x22
39#define ML26124_PW_DAC_PW_MNG 0x24
40#define ML26124_PW_SPAMP_PW_MNG 0x26
41#define ML26124_PW_LOUT_PW_MNG 0x28
42#define ML26124_PW_VOUT_PW_MNG 0x2a
43#define ML26124_PW_ZCCMP_PW_MNG 0x2e
44
45/* Analog Reference Control Register */
46#define ML26124_PW_MICBIAS_VOL 0x30
47
48/* Input/Output Amplifier Control Register */
49#define ML26124_PW_MIC_IN_VOL 0x32
50#define ML26124_PW_MIC_BOST_VOL 0x38
51#define ML26124_PW_SPK_AMP_VOL 0x3a
52#define ML26124_PW_AMP_VOL_FUNC 0x48
53#define ML26124_PW_AMP_VOL_FADE 0x4a
54
55/* Analog Path Control Register */
56#define ML26124_SPK_AMP_OUT 0x54
57#define ML26124_MIC_IF_CTL 0x5a
58#define ML26124_MIC_SELECT 0xe8
59
60/* Audio Interface Control Register */
61#define ML26124_SAI_TRANS_CTL 0x60
62#define ML26124_SAI_RCV_CTL 0x62
63#define ML26124_SAI_MODE_SEL 0x64
64
65/* DSP Control Register */
66#define ML26124_FILTER_EN 0x66
67#define ML26124_DVOL_CTL 0x68
68#define ML26124_MIXER_VOL_CTL 0x6a
69#define ML26124_RECORD_DIG_VOL 0x6c
70#define ML26124_PLBAK_DIG_VOL 0x70
71#define ML26124_DIGI_BOOST_VOL 0x72
72#define ML26124_EQ_GAIN_BRAND0 0x74
73#define ML26124_EQ_GAIN_BRAND1 0x76
74#define ML26124_EQ_GAIN_BRAND2 0x78
75#define ML26124_EQ_GAIN_BRAND3 0x7a
76#define ML26124_EQ_GAIN_BRAND4 0x7c
77#define ML26124_HPF2_CUTOFF 0x7e
78#define ML26124_EQBRAND0_F0L 0x80
79#define ML26124_EQBRAND0_F0H 0x82
80#define ML26124_EQBRAND0_F1L 0x84
81#define ML26124_EQBRAND0_F1H 0x86
82#define ML26124_EQBRAND1_F0L 0x88
83#define ML26124_EQBRAND1_F0H 0x8a
84#define ML26124_EQBRAND1_F1L 0x8c
85#define ML26124_EQBRAND1_F1H 0x8e
86#define ML26124_EQBRAND2_F0L 0x90
87#define ML26124_EQBRAND2_F0H 0x92
88#define ML26124_EQBRAND2_F1L 0x94
89#define ML26124_EQBRAND2_F1H 0x96
90#define ML26124_EQBRAND3_F0L 0x98
91#define ML26124_EQBRAND3_F0H 0x9a
92#define ML26124_EQBRAND3_F1L 0x9c
93#define ML26124_EQBRAND3_F1H 0x9e
94#define ML26124_EQBRAND4_F0L 0xa0
95#define ML26124_EQBRAND4_F0H 0xa2
96#define ML26124_EQBRAND4_F1L 0xa4
97#define ML26124_EQBRAND4_F1H 0xa6
98
99/* ALC Control Register */
100#define ML26124_ALC_MODE 0xb0
101#define ML26124_ALC_ATTACK_TIM 0xb2
102#define ML26124_ALC_DECAY_TIM 0xb4
103#define ML26124_ALC_HOLD_TIM 0xb6
104#define ML26124_ALC_TARGET_LEV 0xb8
105#define ML26124_ALC_MAXMIN_GAIN 0xba
106#define ML26124_NOIS_GATE_THRSH 0xbc
107#define ML26124_ALC_ZERO_TIMOUT 0xbe
108
109/* Playback Limiter Control Register */
110#define ML26124_PL_ATTACKTIME 0xc0
111#define ML26124_PL_DECAYTIME 0xc2
112#define ML26124_PL_TARGETTIME 0xc4
113#define ML26124_PL_MAXMIN_GAIN 0xc6
114#define ML26124_PLYBAK_BOST_VOL 0xc8
115#define ML26124_PL_0CROSS_TIMOUT 0xca
116
117/* Video Amplifer Control Register */
118#define ML26124_VIDEO_AMP_GAIN_CTL 0xd0
119#define ML26124_VIDEO_AMP_SETUP1 0xd2
120#define ML26124_VIDEO_AMP_CTL2 0xd4
121
122/* Clock select for machine driver */
123#define ML26124_USE_PLL 0
124#define ML26124_USE_MCLKI_256FS 1
125#define ML26124_USE_MCLKI_512FS 2
126#define ML26124_USE_MCLKI_1024FS 3
127
128/* Register Mask */
129#define ML26124_R0_MASK 0xf
130#define ML26124_R2_MASK 0xff
131#define ML26124_R4_MASK 0x1
132#define ML26124_R6_MASK 0xf
133#define ML26124_R8_MASK 0x3f
134#define ML26124_Ra_MASK 0x1f
135#define ML26124_Rc_MASK 0x1f
136#define ML26124_Re_MASK 0x7
137#define ML26124_R10_MASK 0x1
138#define ML26124_R12_MASK 0x17
139#define ML26124_R14_MASK 0x3f
140#define ML26124_R20_MASK 0x47
141#define ML26124_R22_MASK 0xa
142#define ML26124_R24_MASK 0x2
143#define ML26124_R26_MASK 0x1f
144#define ML26124_R28_MASK 0x2
145#define ML26124_R2a_MASK 0x2
146#define ML26124_R2e_MASK 0x2
147#define ML26124_R30_MASK 0x7
148#define ML26124_R32_MASK 0x3f
149#define ML26124_R38_MASK 0x38
150#define ML26124_R3a_MASK 0x3f
151#define ML26124_R48_MASK 0x3
152#define ML26124_R4a_MASK 0x7
153#define ML26124_R54_MASK 0x2a
154#define ML26124_R5a_MASK 0x3
155#define ML26124_Re8_MASK 0x3
156#define ML26124_R60_MASK 0xff
157#define ML26124_R62_MASK 0xff
158#define ML26124_R64_MASK 0x1
159#define ML26124_R66_MASK 0xff
160#define ML26124_R68_MASK 0x3b
161#define ML26124_R6a_MASK 0xf3
162#define ML26124_R6c_MASK 0xff
163#define ML26124_R70_MASK 0xff
164
165#define ML26124_MCLKEN BIT(0)
166#define ML26124_PLLEN BIT(1)
167#define ML26124_PLLOE BIT(2)
168#define ML26124_MCLKOE BIT(3)
169
170#define ML26124_BLT_ALL_ON 0x1f
171#define ML26124_BLT_PREAMP_ON 0x13
172
173#define ML26124_MICBEN_ON BIT(2)
174
175enum ml26124_regs {
176 ML26124_MCLK = 0,
177};
178
179enum ml26124_clk_in {
180 ML26124_USE_PLLOUT = 0,
181 ML26124_USE_MCLKI,
182};
183
184#endif
diff --git a/sound/soc/codecs/omap-hdmi.c b/sound/soc/codecs/omap-hdmi.c
new file mode 100644
index 000000000000..1bf5c74f5f96
--- /dev/null
+++ b/sound/soc/codecs/omap-hdmi.c
@@ -0,0 +1,69 @@
1/*
2 * ALSA SoC codec driver for HDMI audio on OMAP processors.
3 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
4 * Author: Ricardo Neri <ricardo.neri@ti.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21#include <linux/module.h>
22#include <sound/soc.h>
23
24#define DRV_NAME "hdmi-audio-codec"
25
26static struct snd_soc_codec_driver omap_hdmi_codec;
27
28static struct snd_soc_dai_driver omap_hdmi_codec_dai = {
29 .name = "omap-hdmi-hifi",
30 .playback = {
31 .channels_min = 2,
32 .channels_max = 8,
33 .rates = SNDRV_PCM_RATE_32000 |
34 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
35 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
36 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
37 .formats = SNDRV_PCM_FMTBIT_S16_LE |
38 SNDRV_PCM_FMTBIT_S24_LE,
39 },
40};
41
42static __devinit int omap_hdmi_codec_probe(struct platform_device *pdev)
43{
44 return snd_soc_register_codec(&pdev->dev, &omap_hdmi_codec,
45 &omap_hdmi_codec_dai, 1);
46}
47
48static __devexit int omap_hdmi_codec_remove(struct platform_device *pdev)
49{
50 snd_soc_unregister_codec(&pdev->dev);
51 return 0;
52}
53
54static struct platform_driver omap_hdmi_codec_driver = {
55 .driver = {
56 .name = DRV_NAME,
57 .owner = THIS_MODULE,
58 },
59
60 .probe = omap_hdmi_codec_probe,
61 .remove = __devexit_p(omap_hdmi_codec_remove),
62};
63
64module_platform_driver(omap_hdmi_codec_driver);
65
66MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
67MODULE_DESCRIPTION("ASoC OMAP HDMI codec driver");
68MODULE_LICENSE("GPL");
69MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c
index 20c324c7c349..960d0e93cce9 100644
--- a/sound/soc/codecs/rt5631.c
+++ b/sound/soc/codecs/rt5631.c
@@ -18,7 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/spi/spi.h> 21#include <linux/regmap.h>
22#include <sound/core.h> 22#include <sound/core.h>
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -30,6 +30,7 @@
30#include "rt5631.h" 30#include "rt5631.h"
31 31
32struct rt5631_priv { 32struct rt5631_priv {
33 struct regmap *regmap;
33 int codec_version; 34 int codec_version;
34 int master; 35 int master;
35 int sysclk; 36 int sysclk;
@@ -38,33 +39,33 @@ struct rt5631_priv {
38 int dmic_used_flag; 39 int dmic_used_flag;
39}; 40};
40 41
41static const u16 rt5631_reg[RT5631_VENDOR_ID2 + 1] = { 42static const struct reg_default rt5631_reg[] = {
42 [RT5631_SPK_OUT_VOL] = 0x8888, 43 { RT5631_SPK_OUT_VOL, 0x8888 },
43 [RT5631_HP_OUT_VOL] = 0x8080, 44 { RT5631_HP_OUT_VOL, 0x8080 },
44 [RT5631_MONO_AXO_1_2_VOL] = 0xa080, 45 { RT5631_MONO_AXO_1_2_VOL, 0xa080 },
45 [RT5631_AUX_IN_VOL] = 0x0808, 46 { RT5631_AUX_IN_VOL, 0x0808 },
46 [RT5631_ADC_REC_MIXER] = 0xf0f0, 47 { RT5631_ADC_REC_MIXER, 0xf0f0 },
47 [RT5631_VDAC_DIG_VOL] = 0x0010, 48 { RT5631_VDAC_DIG_VOL, 0x0010 },
48 [RT5631_OUTMIXER_L_CTRL] = 0xffc0, 49 { RT5631_OUTMIXER_L_CTRL, 0xffc0 },
49 [RT5631_OUTMIXER_R_CTRL] = 0xffc0, 50 { RT5631_OUTMIXER_R_CTRL, 0xffc0 },
50 [RT5631_AXO1MIXER_CTRL] = 0x88c0, 51 { RT5631_AXO1MIXER_CTRL, 0x88c0 },
51 [RT5631_AXO2MIXER_CTRL] = 0x88c0, 52 { RT5631_AXO2MIXER_CTRL, 0x88c0 },
52 [RT5631_DIG_MIC_CTRL] = 0x3000, 53 { RT5631_DIG_MIC_CTRL, 0x3000 },
53 [RT5631_MONO_INPUT_VOL] = 0x8808, 54 { RT5631_MONO_INPUT_VOL, 0x8808 },
54 [RT5631_SPK_MIXER_CTRL] = 0xf8f8, 55 { RT5631_SPK_MIXER_CTRL, 0xf8f8 },
55 [RT5631_SPK_MONO_OUT_CTRL] = 0xfc00, 56 { RT5631_SPK_MONO_OUT_CTRL, 0xfc00 },
56 [RT5631_SPK_MONO_HP_OUT_CTRL] = 0x4440, 57 { RT5631_SPK_MONO_HP_OUT_CTRL, 0x4440 },
57 [RT5631_SDP_CTRL] = 0x8000, 58 { RT5631_SDP_CTRL, 0x8000 },
58 [RT5631_MONO_SDP_CTRL] = 0x8000, 59 { RT5631_MONO_SDP_CTRL, 0x8000 },
59 [RT5631_STEREO_AD_DA_CLK_CTRL] = 0x2010, 60 { RT5631_STEREO_AD_DA_CLK_CTRL, 0x2010 },
60 [RT5631_GEN_PUR_CTRL_REG] = 0x0e00, 61 { RT5631_GEN_PUR_CTRL_REG, 0x0e00 },
61 [RT5631_INT_ST_IRQ_CTRL_2] = 0x071a, 62 { RT5631_INT_ST_IRQ_CTRL_2, 0x071a },
62 [RT5631_MISC_CTRL] = 0x2040, 63 { RT5631_MISC_CTRL, 0x2040 },
63 [RT5631_DEPOP_FUN_CTRL_2] = 0x8000, 64 { RT5631_DEPOP_FUN_CTRL_2, 0x8000 },
64 [RT5631_SOFT_VOL_CTRL] = 0x07e0, 65 { RT5631_SOFT_VOL_CTRL, 0x07e0 },
65 [RT5631_ALC_CTRL_1] = 0x0206, 66 { RT5631_ALC_CTRL_1, 0x0206 },
66 [RT5631_ALC_CTRL_3] = 0x2000, 67 { RT5631_ALC_CTRL_3, 0x2000 },
67 [RT5631_PSEUDO_SPATL_CTRL] = 0x0553, 68 { RT5631_PSEUDO_SPATL_CTRL, 0x0553 },
68}; 69};
69 70
70/** 71/**
@@ -96,8 +97,7 @@ static int rt5631_reset(struct snd_soc_codec *codec)
96 return snd_soc_write(codec, RT5631_RESET, 0); 97 return snd_soc_write(codec, RT5631_RESET, 0);
97} 98}
98 99
99static int rt5631_volatile_register(struct snd_soc_codec *codec, 100static bool rt5631_volatile_register(struct device *dev, unsigned int reg)
100 unsigned int reg)
101{ 101{
102 switch (reg) { 102 switch (reg) {
103 case RT5631_RESET: 103 case RT5631_RESET:
@@ -111,8 +111,7 @@ static int rt5631_volatile_register(struct snd_soc_codec *codec,
111 } 111 }
112} 112}
113 113
114static int rt5631_readable_register(struct snd_soc_codec *codec, 114static bool rt5631_readable_register(struct device *dev, unsigned int reg)
115 unsigned int reg)
116{ 115{
117 switch (reg) { 116 switch (reg) {
118 case RT5631_RESET: 117 case RT5631_RESET:
@@ -1361,8 +1360,7 @@ static int get_coeff(int mclk, int rate, int timesofbclk)
1361static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream, 1360static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream,
1362 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 1361 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
1363{ 1362{
1364 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1363 struct snd_soc_codec *codec = dai->codec;
1365 struct snd_soc_codec *codec = rtd->codec;
1366 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); 1364 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
1367 int timesofbclk = 32, coeff; 1365 int timesofbclk = 32, coeff;
1368 unsigned int iface = 0; 1366 unsigned int iface = 0;
@@ -1544,6 +1542,8 @@ static int rt5631_codec_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1544static int rt5631_set_bias_level(struct snd_soc_codec *codec, 1542static int rt5631_set_bias_level(struct snd_soc_codec *codec,
1545 enum snd_soc_bias_level level) 1543 enum snd_soc_bias_level level)
1546{ 1544{
1545 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
1546
1547 switch (level) { 1547 switch (level) {
1548 case SND_SOC_BIAS_ON: 1548 case SND_SOC_BIAS_ON:
1549 case SND_SOC_BIAS_PREPARE: 1549 case SND_SOC_BIAS_PREPARE:
@@ -1561,8 +1561,8 @@ static int rt5631_set_bias_level(struct snd_soc_codec *codec,
1561 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3, 1561 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
1562 RT5631_PWR_FAST_VREF_CTRL, 1562 RT5631_PWR_FAST_VREF_CTRL,
1563 RT5631_PWR_FAST_VREF_CTRL); 1563 RT5631_PWR_FAST_VREF_CTRL);
1564 codec->cache_only = false; 1564 regcache_cache_only(rt5631->regmap, false);
1565 snd_soc_cache_sync(codec); 1565 regcache_sync(rt5631->regmap);
1566 } 1566 }
1567 break; 1567 break;
1568 1568
@@ -1587,7 +1587,9 @@ static int rt5631_probe(struct snd_soc_codec *codec)
1587 unsigned int val; 1587 unsigned int val;
1588 int ret; 1588 int ret;
1589 1589
1590 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1590 codec->control_data = rt5631->regmap;
1591
1592 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
1591 if (ret != 0) { 1593 if (ret != 0) {
1592 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 1594 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1593 return ret; 1595 return ret;
@@ -1698,12 +1700,6 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5631 = {
1698 .suspend = rt5631_suspend, 1700 .suspend = rt5631_suspend,
1699 .resume = rt5631_resume, 1701 .resume = rt5631_resume,
1700 .set_bias_level = rt5631_set_bias_level, 1702 .set_bias_level = rt5631_set_bias_level,
1701 .reg_cache_size = RT5631_VENDOR_ID2 + 1,
1702 .reg_word_size = sizeof(u16),
1703 .reg_cache_default = rt5631_reg,
1704 .volatile_register = rt5631_volatile_register,
1705 .readable_register = rt5631_readable_register,
1706 .reg_cache_step = 1,
1707 .controls = rt5631_snd_controls, 1703 .controls = rt5631_snd_controls,
1708 .num_controls = ARRAY_SIZE(rt5631_snd_controls), 1704 .num_controls = ARRAY_SIZE(rt5631_snd_controls),
1709 .dapm_widgets = rt5631_dapm_widgets, 1705 .dapm_widgets = rt5631_dapm_widgets,
@@ -1718,6 +1714,18 @@ static const struct i2c_device_id rt5631_i2c_id[] = {
1718}; 1714};
1719MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id); 1715MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id);
1720 1716
1717static const struct regmap_config rt5631_regmap_config = {
1718 .reg_bits = 8,
1719 .val_bits = 16,
1720
1721 .readable_reg = rt5631_readable_register,
1722 .volatile_reg = rt5631_volatile_register,
1723 .max_register = RT5631_VENDOR_ID2,
1724 .reg_defaults = rt5631_reg,
1725 .num_reg_defaults = ARRAY_SIZE(rt5631_reg),
1726 .cache_type = REGCACHE_RBTREE,
1727};
1728
1721static int rt5631_i2c_probe(struct i2c_client *i2c, 1729static int rt5631_i2c_probe(struct i2c_client *i2c,
1722 const struct i2c_device_id *id) 1730 const struct i2c_device_id *id)
1723{ 1731{
@@ -1731,6 +1739,10 @@ static int rt5631_i2c_probe(struct i2c_client *i2c,
1731 1739
1732 i2c_set_clientdata(i2c, rt5631); 1740 i2c_set_clientdata(i2c, rt5631);
1733 1741
1742 rt5631->regmap = devm_regmap_init_i2c(i2c, &rt5631_regmap_config);
1743 if (IS_ERR(rt5631->regmap))
1744 return PTR_ERR(rt5631->regmap);
1745
1734 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5631, 1746 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5631,
1735 rt5631_dai, ARRAY_SIZE(rt5631_dai)); 1747 rt5631_dai, ARRAY_SIZE(rt5631_dai));
1736 return ret; 1748 return ret;
@@ -1752,17 +1764,7 @@ static struct i2c_driver rt5631_i2c_driver = {
1752 .id_table = rt5631_i2c_id, 1764 .id_table = rt5631_i2c_id,
1753}; 1765};
1754 1766
1755static int __init rt5631_modinit(void) 1767module_i2c_driver(rt5631_i2c_driver);
1756{
1757 return i2c_add_driver(&rt5631_i2c_driver);
1758}
1759module_init(rt5631_modinit);
1760
1761static void __exit rt5631_modexit(void)
1762{
1763 i2c_del_driver(&rt5631_i2c_driver);
1764}
1765module_exit(rt5631_modexit);
1766 1768
1767MODULE_DESCRIPTION("ASoC RT5631 driver"); 1769MODULE_DESCRIPTION("ASoC RT5631 driver");
1768MODULE_AUTHOR("flove <flove@realtek.com>"); 1770MODULE_AUTHOR("flove <flove@realtek.com>");
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index c395ec370445..8af6a5245b18 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -84,8 +84,8 @@ static struct regulator_consumer_supply ldo_consumer[] = {
84 84
85static struct regulator_init_data ldo_init_data = { 85static struct regulator_init_data ldo_init_data = {
86 .constraints = { 86 .constraints = {
87 .min_uV = 850000, 87 .min_uV = 1200000,
88 .max_uV = 1600000, 88 .max_uV = 1200000,
89 .valid_modes_mask = REGULATOR_MODE_NORMAL, 89 .valid_modes_mask = REGULATOR_MODE_NORMAL,
90 .valid_ops_mask = REGULATOR_CHANGE_STATUS, 90 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
91 }, 91 },
@@ -197,9 +197,9 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
197 SND_SOC_DAPM_OUTPUT("HP_OUT"), 197 SND_SOC_DAPM_OUTPUT("HP_OUT"),
198 SND_SOC_DAPM_OUTPUT("LINE_OUT"), 198 SND_SOC_DAPM_OUTPUT("LINE_OUT"),
199 199
200 SND_SOC_DAPM_MICBIAS_E("Mic Bias", SGTL5000_CHIP_MIC_CTRL, 8, 0, 200 SND_SOC_DAPM_SUPPLY("Mic Bias", SGTL5000_CHIP_MIC_CTRL, 8, 0,
201 mic_bias_event, 201 mic_bias_event,
202 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 202 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
203 203
204 SND_SOC_DAPM_PGA("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0), 204 SND_SOC_DAPM_PGA("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0),
205 SND_SOC_DAPM_PGA("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0), 205 SND_SOC_DAPM_PGA("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0),
@@ -665,8 +665,7 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream,
665 struct snd_pcm_hw_params *params, 665 struct snd_pcm_hw_params *params,
666 struct snd_soc_dai *dai) 666 struct snd_soc_dai *dai)
667{ 667{
668 struct snd_soc_pcm_runtime *rtd = substream->private_data; 668 struct snd_soc_codec *codec = dai->codec;
669 struct snd_soc_codec *codec = rtd->codec;
670 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); 669 struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
671 int channels = params_channels(params); 670 int channels = params_channels(params);
672 int i2s_ctl = 0; 671 int i2s_ctl = 0;
@@ -1455,17 +1454,7 @@ static struct i2c_driver sgtl5000_i2c_driver = {
1455 .id_table = sgtl5000_id, 1454 .id_table = sgtl5000_id,
1456}; 1455};
1457 1456
1458static int __init sgtl5000_modinit(void) 1457module_i2c_driver(sgtl5000_i2c_driver);
1459{
1460 return i2c_add_driver(&sgtl5000_i2c_driver);
1461}
1462module_init(sgtl5000_modinit);
1463
1464static void __exit sgtl5000_exit(void)
1465{
1466 i2c_del_driver(&sgtl5000_i2c_driver);
1467}
1468module_exit(sgtl5000_exit);
1469 1458
1470MODULE_DESCRIPTION("Freescale SGTL5000 ALSA SoC Codec Driver"); 1459MODULE_DESCRIPTION("Freescale SGTL5000 ALSA SoC Codec Driver");
1471MODULE_AUTHOR("Zeng Zhaoming <zengzm.kernel@gmail.com>"); 1460MODULE_AUTHOR("Zeng Zhaoming <zengzm.kernel@gmail.com>");
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index de2b20544ceb..079066fef425 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -33,6 +33,7 @@
33#include <linux/pm.h> 33#include <linux/pm.h>
34#include <linux/i2c.h> 34#include <linux/i2c.h>
35#include <linux/spi/spi.h> 35#include <linux/spi/spi.h>
36#include <linux/regmap.h>
36#include <linux/slab.h> 37#include <linux/slab.h>
37#include <sound/core.h> 38#include <sound/core.h>
38#include <sound/pcm.h> 39#include <sound/pcm.h>
@@ -43,8 +44,6 @@
43 44
44#include "ssm2602.h" 45#include "ssm2602.h"
45 46
46#define SSM2602_VERSION "0.1"
47
48enum ssm2602_type { 47enum ssm2602_type {
49 SSM2602, 48 SSM2602,
50 SSM2604, 49 SSM2604,
@@ -53,10 +52,12 @@ enum ssm2602_type {
53/* codec private data */ 52/* codec private data */
54struct ssm2602_priv { 53struct ssm2602_priv {
55 unsigned int sysclk; 54 unsigned int sysclk;
56 enum snd_soc_control_type control_type; 55 struct snd_pcm_hw_constraint_list *sysclk_constraints;
57 struct snd_pcm_substream *master_substream; 56 struct snd_pcm_substream *master_substream;
58 struct snd_pcm_substream *slave_substream; 57 struct snd_pcm_substream *slave_substream;
59 58
59 struct regmap *regmap;
60
60 enum ssm2602_type type; 61 enum ssm2602_type type;
61 unsigned int clk_out_pwr; 62 unsigned int clk_out_pwr;
62}; 63};
@@ -73,7 +74,6 @@ static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = {
73 0x0000, 0x0000 74 0x0000, 0x0000
74}; 75};
75 76
76#define ssm2602_reset(c) snd_soc_write(c, SSM2602_RESET, 0)
77 77
78/*Appending several "None"s just for OSS mixer use*/ 78/*Appending several "None"s just for OSS mixer use*/
79static const char *ssm2602_input_select[] = { 79static const char *ssm2602_input_select[] = {
@@ -195,6 +195,24 @@ static const struct snd_soc_dapm_route ssm2604_routes[] = {
195 {"ADC", NULL, "Line Input"}, 195 {"ADC", NULL, "Line Input"},
196}; 196};
197 197
198static const unsigned int ssm2602_rates_12288000[] = {
199 8000, 32000, 48000, 96000,
200};
201
202static struct snd_pcm_hw_constraint_list ssm2602_constraints_12288000 = {
203 .list = ssm2602_rates_12288000,
204 .count = ARRAY_SIZE(ssm2602_rates_12288000),
205};
206
207static const unsigned int ssm2602_rates_11289600[] = {
208 8000, 44100, 88200,
209};
210
211static struct snd_pcm_hw_constraint_list ssm2602_constraints_11289600 = {
212 .list = ssm2602_rates_11289600,
213 .count = ARRAY_SIZE(ssm2602_rates_11289600),
214};
215
198struct ssm2602_coeff { 216struct ssm2602_coeff {
199 u32 mclk; 217 u32 mclk;
200 u32 rate; 218 u32 rate;
@@ -254,11 +272,10 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
254 struct snd_pcm_hw_params *params, 272 struct snd_pcm_hw_params *params,
255 struct snd_soc_dai *dai) 273 struct snd_soc_dai *dai)
256{ 274{
257 struct snd_soc_pcm_runtime *rtd = substream->private_data; 275 struct snd_soc_codec *codec = dai->codec;
258 struct snd_soc_codec *codec = rtd->codec;
259 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 276 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
260 u16 iface = snd_soc_read(codec, SSM2602_IFACE) & 0xfff3;
261 int srate = ssm2602_get_coeff(ssm2602->sysclk, params_rate(params)); 277 int srate = ssm2602_get_coeff(ssm2602->sysclk, params_rate(params));
278 unsigned int iface;
262 279
263 if (substream == ssm2602->slave_substream) { 280 if (substream == ssm2602->slave_substream) {
264 dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n"); 281 dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n");
@@ -268,31 +285,34 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
268 if (srate < 0) 285 if (srate < 0)
269 return srate; 286 return srate;
270 287
271 snd_soc_write(codec, SSM2602_SRATE, srate); 288 regmap_write(ssm2602->regmap, SSM2602_SRATE, srate);
272 289
273 /* bit size */ 290 /* bit size */
274 switch (params_format(params)) { 291 switch (params_format(params)) {
275 case SNDRV_PCM_FORMAT_S16_LE: 292 case SNDRV_PCM_FORMAT_S16_LE:
293 iface = 0x0;
276 break; 294 break;
277 case SNDRV_PCM_FORMAT_S20_3LE: 295 case SNDRV_PCM_FORMAT_S20_3LE:
278 iface |= 0x0004; 296 iface = 0x4;
279 break; 297 break;
280 case SNDRV_PCM_FORMAT_S24_LE: 298 case SNDRV_PCM_FORMAT_S24_LE:
281 iface |= 0x0008; 299 iface = 0x8;
282 break; 300 break;
283 case SNDRV_PCM_FORMAT_S32_LE: 301 case SNDRV_PCM_FORMAT_S32_LE:
284 iface |= 0x000c; 302 iface = 0xc;
285 break; 303 break;
304 default:
305 return -EINVAL;
286 } 306 }
287 snd_soc_write(codec, SSM2602_IFACE, iface); 307 regmap_update_bits(ssm2602->regmap, SSM2602_IFACE,
308 IFACE_AUDIO_DATA_LEN, iface);
288 return 0; 309 return 0;
289} 310}
290 311
291static int ssm2602_startup(struct snd_pcm_substream *substream, 312static int ssm2602_startup(struct snd_pcm_substream *substream,
292 struct snd_soc_dai *dai) 313 struct snd_soc_dai *dai)
293{ 314{
294 struct snd_soc_pcm_runtime *rtd = substream->private_data; 315 struct snd_soc_codec *codec = dai->codec;
295 struct snd_soc_codec *codec = rtd->codec;
296 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 316 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
297 struct snd_pcm_runtime *master_runtime; 317 struct snd_pcm_runtime *master_runtime;
298 318
@@ -322,14 +342,19 @@ static int ssm2602_startup(struct snd_pcm_substream *substream,
322 } else 342 } else
323 ssm2602->master_substream = substream; 343 ssm2602->master_substream = substream;
324 344
345 if (ssm2602->sysclk_constraints) {
346 snd_pcm_hw_constraint_list(substream->runtime, 0,
347 SNDRV_PCM_HW_PARAM_RATE,
348 ssm2602->sysclk_constraints);
349 }
350
325 return 0; 351 return 0;
326} 352}
327 353
328static void ssm2602_shutdown(struct snd_pcm_substream *substream, 354static void ssm2602_shutdown(struct snd_pcm_substream *substream,
329 struct snd_soc_dai *dai) 355 struct snd_soc_dai *dai)
330{ 356{
331 struct snd_soc_pcm_runtime *rtd = substream->private_data; 357 struct snd_soc_codec *codec = dai->codec;
332 struct snd_soc_codec *codec = rtd->codec;
333 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 358 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
334 359
335 if (ssm2602->master_substream == substream) 360 if (ssm2602->master_substream == substream)
@@ -341,14 +366,14 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream,
341 366
342static int ssm2602_mute(struct snd_soc_dai *dai, int mute) 367static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
343{ 368{
344 struct snd_soc_codec *codec = dai->codec; 369 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(dai->codec);
345 370
346 if (mute) 371 if (mute)
347 snd_soc_update_bits(codec, SSM2602_APDIGI, 372 regmap_update_bits(ssm2602->regmap, SSM2602_APDIGI,
348 APDIGI_ENABLE_DAC_MUTE, 373 APDIGI_ENABLE_DAC_MUTE,
349 APDIGI_ENABLE_DAC_MUTE); 374 APDIGI_ENABLE_DAC_MUTE);
350 else 375 else
351 snd_soc_update_bits(codec, SSM2602_APDIGI, 376 regmap_update_bits(ssm2602->regmap, SSM2602_APDIGI,
352 APDIGI_ENABLE_DAC_MUTE, 0); 377 APDIGI_ENABLE_DAC_MUTE, 0);
353 return 0; 378 return 0;
354} 379}
@@ -364,16 +389,21 @@ static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai,
364 return -EINVAL; 389 return -EINVAL;
365 390
366 switch (freq) { 391 switch (freq) {
367 case 11289600:
368 case 12000000:
369 case 12288000: 392 case 12288000:
370 case 16934400:
371 case 18432000: 393 case 18432000:
372 ssm2602->sysclk = freq; 394 ssm2602->sysclk_constraints = &ssm2602_constraints_12288000;
395 break;
396 case 11289600:
397 case 16934400:
398 ssm2602->sysclk_constraints = &ssm2602_constraints_11289600;
399 break;
400 case 12000000:
401 ssm2602->sysclk_constraints = NULL;
373 break; 402 break;
374 default: 403 default:
375 return -EINVAL; 404 return -EINVAL;
376 } 405 }
406 ssm2602->sysclk = freq;
377 } else { 407 } else {
378 unsigned int mask; 408 unsigned int mask;
379 409
@@ -393,7 +423,7 @@ static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai,
393 else 423 else
394 ssm2602->clk_out_pwr &= ~mask; 424 ssm2602->clk_out_pwr &= ~mask;
395 425
396 snd_soc_update_bits(codec, SSM2602_PWR, 426 regmap_update_bits(ssm2602->regmap, SSM2602_PWR,
397 PWR_CLK_OUT_PDN | PWR_OSC_PDN, ssm2602->clk_out_pwr); 427 PWR_CLK_OUT_PDN | PWR_OSC_PDN, ssm2602->clk_out_pwr);
398 } 428 }
399 429
@@ -403,8 +433,8 @@ static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai,
403static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai, 433static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
404 unsigned int fmt) 434 unsigned int fmt)
405{ 435{
406 struct snd_soc_codec *codec = codec_dai->codec; 436 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec_dai->codec);
407 u16 iface = 0; 437 unsigned int iface = 0;
408 438
409 /* set master/slave audio interface */ 439 /* set master/slave audio interface */
410 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 440 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -455,7 +485,7 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
455 } 485 }
456 486
457 /* set iface */ 487 /* set iface */
458 snd_soc_write(codec, SSM2602_IFACE, iface); 488 regmap_write(ssm2602->regmap, SSM2602_IFACE, iface);
459 return 0; 489 return 0;
460} 490}
461 491
@@ -467,7 +497,7 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
467 switch (level) { 497 switch (level) {
468 case SND_SOC_BIAS_ON: 498 case SND_SOC_BIAS_ON:
469 /* vref/mid on, osc and clkout on if enabled */ 499 /* vref/mid on, osc and clkout on if enabled */
470 snd_soc_update_bits(codec, SSM2602_PWR, 500 regmap_update_bits(ssm2602->regmap, SSM2602_PWR,
471 PWR_POWER_OFF | PWR_CLK_OUT_PDN | PWR_OSC_PDN, 501 PWR_POWER_OFF | PWR_CLK_OUT_PDN | PWR_OSC_PDN,
472 ssm2602->clk_out_pwr); 502 ssm2602->clk_out_pwr);
473 break; 503 break;
@@ -475,13 +505,13 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
475 break; 505 break;
476 case SND_SOC_BIAS_STANDBY: 506 case SND_SOC_BIAS_STANDBY:
477 /* everything off except vref/vmid, */ 507 /* everything off except vref/vmid, */
478 snd_soc_update_bits(codec, SSM2602_PWR, 508 regmap_update_bits(ssm2602->regmap, SSM2602_PWR,
479 PWR_POWER_OFF | PWR_CLK_OUT_PDN | PWR_OSC_PDN, 509 PWR_POWER_OFF | PWR_CLK_OUT_PDN | PWR_OSC_PDN,
480 PWR_CLK_OUT_PDN | PWR_OSC_PDN); 510 PWR_CLK_OUT_PDN | PWR_OSC_PDN);
481 break; 511 break;
482 case SND_SOC_BIAS_OFF: 512 case SND_SOC_BIAS_OFF:
483 /* everything off */ 513 /* everything off */
484 snd_soc_update_bits(codec, SSM2602_PWR, 514 regmap_update_bits(ssm2602->regmap, SSM2602_PWR,
485 PWR_POWER_OFF, PWR_POWER_OFF); 515 PWR_POWER_OFF, PWR_POWER_OFF);
486 break; 516 break;
487 517
@@ -540,12 +570,13 @@ static int ssm2602_resume(struct snd_soc_codec *codec)
540 570
541static int ssm2602_probe(struct snd_soc_codec *codec) 571static int ssm2602_probe(struct snd_soc_codec *codec)
542{ 572{
573 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
543 struct snd_soc_dapm_context *dapm = &codec->dapm; 574 struct snd_soc_dapm_context *dapm = &codec->dapm;
544 int ret; 575 int ret;
545 576
546 snd_soc_update_bits(codec, SSM2602_LOUT1V, 577 regmap_update_bits(ssm2602->regmap, SSM2602_LOUT1V,
547 LOUT1V_LRHP_BOTH, LOUT1V_LRHP_BOTH); 578 LOUT1V_LRHP_BOTH, LOUT1V_LRHP_BOTH);
548 snd_soc_update_bits(codec, SSM2602_ROUT1V, 579 regmap_update_bits(ssm2602->regmap, SSM2602_ROUT1V,
549 ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH); 580 ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH);
550 581
551 ret = snd_soc_add_codec_controls(codec, ssm2602_snd_controls, 582 ret = snd_soc_add_codec_controls(codec, ssm2602_snd_controls,
@@ -581,27 +612,26 @@ static int ssm260x_probe(struct snd_soc_codec *codec)
581 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 612 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
582 int ret; 613 int ret;
583 614
584 pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION); 615 codec->control_data = ssm2602->regmap;
585 616 ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
586 ret = snd_soc_codec_set_cache_io(codec, 7, 9, ssm2602->control_type);
587 if (ret < 0) { 617 if (ret < 0) {
588 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 618 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
589 return ret; 619 return ret;
590 } 620 }
591 621
592 ret = ssm2602_reset(codec); 622 ret = regmap_write(ssm2602->regmap, SSM2602_RESET, 0);
593 if (ret < 0) { 623 if (ret < 0) {
594 dev_err(codec->dev, "Failed to issue reset: %d\n", ret); 624 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
595 return ret; 625 return ret;
596 } 626 }
597 627
598 /* set the update bits */ 628 /* set the update bits */
599 snd_soc_update_bits(codec, SSM2602_LINVOL, 629 regmap_update_bits(ssm2602->regmap, SSM2602_LINVOL,
600 LINVOL_LRIN_BOTH, LINVOL_LRIN_BOTH); 630 LINVOL_LRIN_BOTH, LINVOL_LRIN_BOTH);
601 snd_soc_update_bits(codec, SSM2602_RINVOL, 631 regmap_update_bits(ssm2602->regmap, SSM2602_RINVOL,
602 RINVOL_RLIN_BOTH, RINVOL_RLIN_BOTH); 632 RINVOL_RLIN_BOTH, RINVOL_RLIN_BOTH);
603 /*select Line in as default input*/ 633 /*select Line in as default input*/
604 snd_soc_write(codec, SSM2602_APANA, APANA_SELECT_DAC | 634 regmap_write(ssm2602->regmap, SSM2602_APANA, APANA_SELECT_DAC |
605 APANA_ENABLE_MIC_BOOST); 635 APANA_ENABLE_MIC_BOOST);
606 636
607 switch (ssm2602->type) { 637 switch (ssm2602->type) {
@@ -634,9 +664,6 @@ static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
634 .suspend = ssm2602_suspend, 664 .suspend = ssm2602_suspend,
635 .resume = ssm2602_resume, 665 .resume = ssm2602_resume,
636 .set_bias_level = ssm2602_set_bias_level, 666 .set_bias_level = ssm2602_set_bias_level,
637 .reg_cache_size = ARRAY_SIZE(ssm2602_reg),
638 .reg_word_size = sizeof(u16),
639 .reg_cache_default = ssm2602_reg,
640 667
641 .controls = ssm260x_snd_controls, 668 .controls = ssm260x_snd_controls,
642 .num_controls = ARRAY_SIZE(ssm260x_snd_controls), 669 .num_controls = ARRAY_SIZE(ssm260x_snd_controls),
@@ -646,6 +673,23 @@ static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
646 .num_dapm_routes = ARRAY_SIZE(ssm260x_routes), 673 .num_dapm_routes = ARRAY_SIZE(ssm260x_routes),
647}; 674};
648 675
676static bool ssm2602_register_volatile(struct device *dev, unsigned int reg)
677{
678 return reg == SSM2602_RESET;
679}
680
681static const struct regmap_config ssm2602_regmap_config = {
682 .val_bits = 9,
683 .reg_bits = 7,
684
685 .max_register = SSM2602_RESET,
686 .volatile_reg = ssm2602_register_volatile,
687
688 .cache_type = REGCACHE_RBTREE,
689 .reg_defaults_raw = ssm2602_reg,
690 .num_reg_defaults_raw = ARRAY_SIZE(ssm2602_reg),
691};
692
649#if defined(CONFIG_SPI_MASTER) 693#if defined(CONFIG_SPI_MASTER)
650static int __devinit ssm2602_spi_probe(struct spi_device *spi) 694static int __devinit ssm2602_spi_probe(struct spi_device *spi)
651{ 695{
@@ -658,9 +702,12 @@ static int __devinit ssm2602_spi_probe(struct spi_device *spi)
658 return -ENOMEM; 702 return -ENOMEM;
659 703
660 spi_set_drvdata(spi, ssm2602); 704 spi_set_drvdata(spi, ssm2602);
661 ssm2602->control_type = SND_SOC_SPI;
662 ssm2602->type = SSM2602; 705 ssm2602->type = SSM2602;
663 706
707 ssm2602->regmap = devm_regmap_init_spi(spi, &ssm2602_regmap_config);
708 if (IS_ERR(ssm2602->regmap))
709 return PTR_ERR(ssm2602->regmap);
710
664 ret = snd_soc_register_codec(&spi->dev, 711 ret = snd_soc_register_codec(&spi->dev,
665 &soc_codec_dev_ssm2602, &ssm2602_dai, 1); 712 &soc_codec_dev_ssm2602, &ssm2602_dai, 1);
666 return ret; 713 return ret;
@@ -701,9 +748,12 @@ static int __devinit ssm2602_i2c_probe(struct i2c_client *i2c,
701 return -ENOMEM; 748 return -ENOMEM;
702 749
703 i2c_set_clientdata(i2c, ssm2602); 750 i2c_set_clientdata(i2c, ssm2602);
704 ssm2602->control_type = SND_SOC_I2C;
705 ssm2602->type = id->driver_data; 751 ssm2602->type = id->driver_data;
706 752
753 ssm2602->regmap = devm_regmap_init_i2c(i2c, &ssm2602_regmap_config);
754 if (IS_ERR(ssm2602->regmap))
755 return PTR_ERR(ssm2602->regmap);
756
707 ret = snd_soc_register_codec(&i2c->dev, 757 ret = snd_soc_register_codec(&i2c->dev,
708 &soc_codec_dev_ssm2602, &ssm2602_dai, 1); 758 &soc_codec_dev_ssm2602, &ssm2602_dai, 1);
709 return ret; 759 return ret;
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index 7db6fa515028..8d717f4b5a87 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -609,8 +609,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
609 struct snd_pcm_hw_params *params, 609 struct snd_pcm_hw_params *params,
610 struct snd_soc_dai *dai) 610 struct snd_soc_dai *dai)
611{ 611{
612 struct snd_soc_pcm_runtime *rtd = substream->private_data; 612 struct snd_soc_codec *codec = dai->codec;
613 struct snd_soc_codec *codec = rtd->codec;
614 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); 613 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
615 unsigned int rate; 614 unsigned int rate;
616 int i, mcs = -1, ir = -1; 615 int i, mcs = -1, ir = -1;
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index df1e07ffac32..31762ebdd774 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -34,8 +34,6 @@
34 34
35#include "tlv320aic23.h" 35#include "tlv320aic23.h"
36 36
37#define AIC23_VERSION "0.1"
38
39/* 37/*
40 * AIC23 register cache 38 * AIC23 register cache
41 */ 39 */
@@ -325,8 +323,7 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
325 struct snd_pcm_hw_params *params, 323 struct snd_pcm_hw_params *params,
326 struct snd_soc_dai *dai) 324 struct snd_soc_dai *dai)
327{ 325{
328 struct snd_soc_pcm_runtime *rtd = substream->private_data; 326 struct snd_soc_codec *codec = dai->codec;
329 struct snd_soc_codec *codec = rtd->codec;
330 u16 iface_reg; 327 u16 iface_reg;
331 int ret; 328 int ret;
332 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); 329 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
@@ -371,8 +368,7 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
371static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream, 368static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
372 struct snd_soc_dai *dai) 369 struct snd_soc_dai *dai)
373{ 370{
374 struct snd_soc_pcm_runtime *rtd = substream->private_data; 371 struct snd_soc_codec *codec = dai->codec;
375 struct snd_soc_codec *codec = rtd->codec;
376 372
377 /* set active */ 373 /* set active */
378 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0001); 374 snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0001);
@@ -383,8 +379,7 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
383static void tlv320aic23_shutdown(struct snd_pcm_substream *substream, 379static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
384 struct snd_soc_dai *dai) 380 struct snd_soc_dai *dai)
385{ 381{
386 struct snd_soc_pcm_runtime *rtd = substream->private_data; 382 struct snd_soc_codec *codec = dai->codec;
387 struct snd_soc_codec *codec = rtd->codec;
388 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); 383 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
389 384
390 /* deactivate */ 385 /* deactivate */
@@ -548,8 +543,6 @@ static int tlv320aic23_probe(struct snd_soc_codec *codec)
548 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); 543 struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
549 int ret; 544 int ret;
550 545
551 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
552
553 ret = snd_soc_codec_set_cache_io(codec, 7, 9, aic23->control_type); 546 ret = snd_soc_codec_set_cache_io(codec, 7, 9, aic23->control_type);
554 if (ret < 0) { 547 if (ret < 0) {
555 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 548 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 802064b5030d..85944e953578 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -126,8 +126,7 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
126 struct snd_pcm_hw_params *params, 126 struct snd_pcm_hw_params *params,
127 struct snd_soc_dai *dai) 127 struct snd_soc_dai *dai)
128{ 128{
129 struct snd_soc_pcm_runtime *rtd = substream->private_data; 129 struct snd_soc_codec *codec = dai->codec;
130 struct snd_soc_codec *codec = rtd->codec;
131 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec); 130 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
132 int fsref, divisor, wlen, pval, jval, dval, qval; 131 int fsref, divisor, wlen, pval, jval, dval, qval;
133 u16 reg; 132 u16 reg;
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 8d20f6ec20f3..64d2a4fa34b2 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -802,8 +802,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
802 struct snd_pcm_hw_params *params, 802 struct snd_pcm_hw_params *params,
803 struct snd_soc_dai *dai) 803 struct snd_soc_dai *dai)
804{ 804{
805 struct snd_soc_pcm_runtime *rtd = substream->private_data; 805 struct snd_soc_codec *codec = dai->codec;
806 struct snd_soc_codec *codec =rtd->codec;
807 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 806 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
808 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; 807 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
809 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; 808 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
@@ -1161,24 +1160,6 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
1161 return 0; 1160 return 0;
1162} 1161}
1163 1162
1164void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
1165 int headset_debounce, int button_debounce)
1166{
1167 u8 val;
1168
1169 val = ((detect & AIC3X_HEADSET_DETECT_MASK)
1170 << AIC3X_HEADSET_DETECT_SHIFT) |
1171 ((headset_debounce & AIC3X_HEADSET_DEBOUNCE_MASK)
1172 << AIC3X_HEADSET_DEBOUNCE_SHIFT) |
1173 ((button_debounce & AIC3X_BUTTON_DEBOUNCE_MASK)
1174 << AIC3X_BUTTON_DEBOUNCE_SHIFT);
1175
1176 if (detect & AIC3X_HEADSET_DETECT_MASK)
1177 val |= AIC3X_HEADSET_DETECT_ENABLED;
1178
1179 snd_soc_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val);
1180}
1181
1182#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000 1163#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000
1183#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 1164#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1184 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 1165 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 4587ddd0fbf8..0dd41077ab79 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -62,8 +62,10 @@
62#define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \ 62#define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \
63 (((samples)*5000) / (((burstrate)*5000) / ((burstrate) - (playrate)))) 63 (((samples)*5000) / (((burstrate)*5000) / ((burstrate) - (playrate))))
64 64
65static void dac33_calculate_times(struct snd_pcm_substream *substream); 65static void dac33_calculate_times(struct snd_pcm_substream *substream,
66static int dac33_prepare_chip(struct snd_pcm_substream *substream); 66 struct snd_soc_codec *codec);
67static int dac33_prepare_chip(struct snd_pcm_substream *substream,
68 struct snd_soc_codec *codec);
67 69
68enum dac33_state { 70enum dac33_state {
69 DAC33_IDLE = 0, 71 DAC33_IDLE = 0,
@@ -427,8 +429,8 @@ static int dac33_playback_event(struct snd_soc_dapm_widget *w,
427 switch (event) { 429 switch (event) {
428 case SND_SOC_DAPM_PRE_PMU: 430 case SND_SOC_DAPM_PRE_PMU:
429 if (likely(dac33->substream)) { 431 if (likely(dac33->substream)) {
430 dac33_calculate_times(dac33->substream); 432 dac33_calculate_times(dac33->substream, w->codec);
431 dac33_prepare_chip(dac33->substream); 433 dac33_prepare_chip(dac33->substream, w->codec);
432 } 434 }
433 break; 435 break;
434 case SND_SOC_DAPM_POST_PMD: 436 case SND_SOC_DAPM_POST_PMD:
@@ -799,8 +801,7 @@ static void dac33_oscwait(struct snd_soc_codec *codec)
799static int dac33_startup(struct snd_pcm_substream *substream, 801static int dac33_startup(struct snd_pcm_substream *substream,
800 struct snd_soc_dai *dai) 802 struct snd_soc_dai *dai)
801{ 803{
802 struct snd_soc_pcm_runtime *rtd = substream->private_data; 804 struct snd_soc_codec *codec = dai->codec;
803 struct snd_soc_codec *codec = rtd->codec;
804 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 805 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
805 806
806 /* Stream started, save the substream pointer */ 807 /* Stream started, save the substream pointer */
@@ -812,8 +813,7 @@ static int dac33_startup(struct snd_pcm_substream *substream,
812static void dac33_shutdown(struct snd_pcm_substream *substream, 813static void dac33_shutdown(struct snd_pcm_substream *substream,
813 struct snd_soc_dai *dai) 814 struct snd_soc_dai *dai)
814{ 815{
815 struct snd_soc_pcm_runtime *rtd = substream->private_data; 816 struct snd_soc_codec *codec = dai->codec;
816 struct snd_soc_codec *codec = rtd->codec;
817 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 817 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
818 818
819 dac33->substream = NULL; 819 dac33->substream = NULL;
@@ -825,8 +825,7 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
825 struct snd_pcm_hw_params *params, 825 struct snd_pcm_hw_params *params,
826 struct snd_soc_dai *dai) 826 struct snd_soc_dai *dai)
827{ 827{
828 struct snd_soc_pcm_runtime *rtd = substream->private_data; 828 struct snd_soc_codec *codec = dai->codec;
829 struct snd_soc_codec *codec = rtd->codec;
830 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 829 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
831 830
832 /* Check parameters for validity */ 831 /* Check parameters for validity */
@@ -868,10 +867,9 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
868 * writes happens in different order, than dac33 might end up in unknown state. 867 * writes happens in different order, than dac33 might end up in unknown state.
869 * Use the known, working sequence of register writes to initialize the dac33. 868 * Use the known, working sequence of register writes to initialize the dac33.
870 */ 869 */
871static int dac33_prepare_chip(struct snd_pcm_substream *substream) 870static int dac33_prepare_chip(struct snd_pcm_substream *substream,
871 struct snd_soc_codec *codec)
872{ 872{
873 struct snd_soc_pcm_runtime *rtd = substream->private_data;
874 struct snd_soc_codec *codec = rtd->codec;
875 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 873 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
876 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp; 874 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
877 u8 aictrl_a, aictrl_b, fifoctrl_a; 875 u8 aictrl_a, aictrl_b, fifoctrl_a;
@@ -1067,10 +1065,9 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
1067 return 0; 1065 return 0;
1068} 1066}
1069 1067
1070static void dac33_calculate_times(struct snd_pcm_substream *substream) 1068static void dac33_calculate_times(struct snd_pcm_substream *substream,
1069 struct snd_soc_codec *codec)
1071{ 1070{
1072 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1073 struct snd_soc_codec *codec = rtd->codec;
1074 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1071 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1075 unsigned int period_size = substream->runtime->period_size; 1072 unsigned int period_size = substream->runtime->period_size;
1076 unsigned int rate = substream->runtime->rate; 1073 unsigned int rate = substream->runtime->rate;
@@ -1128,8 +1125,7 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
1128static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd, 1125static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
1129 struct snd_soc_dai *dai) 1126 struct snd_soc_dai *dai)
1130{ 1127{
1131 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1128 struct snd_soc_codec *codec = dai->codec;
1132 struct snd_soc_codec *codec = rtd->codec;
1133 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1129 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1134 int ret = 0; 1130 int ret = 0;
1135 1131
@@ -1161,8 +1157,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
1161 struct snd_pcm_substream *substream, 1157 struct snd_pcm_substream *substream,
1162 struct snd_soc_dai *dai) 1158 struct snd_soc_dai *dai)
1163{ 1159{
1164 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1160 struct snd_soc_codec *codec = dai->codec;
1165 struct snd_soc_codec *codec = rtd->codec;
1166 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 1161 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
1167 unsigned long long t0, t1, t_now; 1162 unsigned long long t0, t1, t_now;
1168 unsigned int time_delta, uthr; 1163 unsigned int time_delta, uthr;
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 170cf9a8fc79..391fcfc7b63b 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -1685,8 +1685,7 @@ static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction,
1685static int twl4030_startup(struct snd_pcm_substream *substream, 1685static int twl4030_startup(struct snd_pcm_substream *substream,
1686 struct snd_soc_dai *dai) 1686 struct snd_soc_dai *dai)
1687{ 1687{
1688 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1688 struct snd_soc_codec *codec = dai->codec;
1689 struct snd_soc_codec *codec = rtd->codec;
1690 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1689 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1691 1690
1692 if (twl4030->master_substream) { 1691 if (twl4030->master_substream) {
@@ -1715,8 +1714,7 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
1715static void twl4030_shutdown(struct snd_pcm_substream *substream, 1714static void twl4030_shutdown(struct snd_pcm_substream *substream,
1716 struct snd_soc_dai *dai) 1715 struct snd_soc_dai *dai)
1717{ 1716{
1718 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1717 struct snd_soc_codec *codec = dai->codec;
1719 struct snd_soc_codec *codec = rtd->codec;
1720 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1718 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1721 1719
1722 if (twl4030->master_substream == substream) 1720 if (twl4030->master_substream == substream)
@@ -1740,8 +1738,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1740 struct snd_pcm_hw_params *params, 1738 struct snd_pcm_hw_params *params,
1741 struct snd_soc_dai *dai) 1739 struct snd_soc_dai *dai)
1742{ 1740{
1743 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1741 struct snd_soc_codec *codec = dai->codec;
1744 struct snd_soc_codec *codec = rtd->codec;
1745 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1742 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1746 u8 mode, old_mode, format, old_format; 1743 u8 mode, old_mode, format, old_format;
1747 1744
@@ -1974,8 +1971,7 @@ static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction,
1974static int twl4030_voice_startup(struct snd_pcm_substream *substream, 1971static int twl4030_voice_startup(struct snd_pcm_substream *substream,
1975 struct snd_soc_dai *dai) 1972 struct snd_soc_dai *dai)
1976{ 1973{
1977 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1974 struct snd_soc_codec *codec = dai->codec;
1978 struct snd_soc_codec *codec = rtd->codec;
1979 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1975 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1980 u8 mode; 1976 u8 mode;
1981 1977
@@ -2007,8 +2003,7 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
2007static void twl4030_voice_shutdown(struct snd_pcm_substream *substream, 2003static void twl4030_voice_shutdown(struct snd_pcm_substream *substream,
2008 struct snd_soc_dai *dai) 2004 struct snd_soc_dai *dai)
2009{ 2005{
2010 struct snd_soc_pcm_runtime *rtd = substream->private_data; 2006 struct snd_soc_codec *codec = dai->codec;
2011 struct snd_soc_codec *codec = rtd->codec;
2012 2007
2013 /* Enable voice digital filters */ 2008 /* Enable voice digital filters */
2014 twl4030_voice_enable(codec, substream->stream, 0); 2009 twl4030_voice_enable(codec, substream->stream, 0);
@@ -2017,8 +2012,7 @@ static void twl4030_voice_shutdown(struct snd_pcm_substream *substream,
2017static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, 2012static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
2018 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 2013 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
2019{ 2014{
2020 struct snd_soc_pcm_runtime *rtd = substream->private_data; 2015 struct snd_soc_codec *codec = dai->codec;
2021 struct snd_soc_codec *codec = rtd->codec;
2022 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 2016 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2023 u8 old_mode, mode; 2017 u8 old_mode, mode;
2024 2018
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index dc7509b9d53a..a36e9fcdf184 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -46,17 +46,6 @@
46#define TWL6040_OUTHF_0dB 0x03 46#define TWL6040_OUTHF_0dB 0x03
47#define TWL6040_OUTHF_M52dB 0x1D 47#define TWL6040_OUTHF_M52dB 0x1D
48 48
49#define TWL6040_RAMP_NONE 0
50#define TWL6040_RAMP_UP 1
51#define TWL6040_RAMP_DOWN 2
52
53#define TWL6040_HSL_VOL_MASK 0x0F
54#define TWL6040_HSL_VOL_SHIFT 0
55#define TWL6040_HSR_VOL_MASK 0xF0
56#define TWL6040_HSR_VOL_SHIFT 4
57#define TWL6040_HF_VOL_MASK 0x1F
58#define TWL6040_HF_VOL_SHIFT 0
59
60/* Shadow register used by the driver */ 49/* Shadow register used by the driver */
61#define TWL6040_REG_SW_SHADOW 0x2F 50#define TWL6040_REG_SW_SHADOW 0x2F
62#define TWL6040_CACHEREGNUM (TWL6040_REG_SW_SHADOW + 1) 51#define TWL6040_CACHEREGNUM (TWL6040_REG_SW_SHADOW + 1)
@@ -64,18 +53,6 @@
64/* TWL6040_REG_SW_SHADOW (0x2F) fields */ 53/* TWL6040_REG_SW_SHADOW (0x2F) fields */
65#define TWL6040_EAR_PATH_ENABLE 0x01 54#define TWL6040_EAR_PATH_ENABLE 0x01
66 55
67struct twl6040_output {
68 u16 active;
69 u16 left_vol;
70 u16 right_vol;
71 u16 left_step;
72 u16 right_step;
73 unsigned int step_delay;
74 u16 ramp;
75 struct delayed_work work;
76 struct completion ramp_done;
77};
78
79struct twl6040_jack_data { 56struct twl6040_jack_data {
80 struct snd_soc_jack *jack; 57 struct snd_soc_jack *jack;
81 struct delayed_work work; 58 struct delayed_work work;
@@ -100,8 +77,6 @@ struct twl6040_data {
100 struct snd_soc_codec *codec; 77 struct snd_soc_codec *codec;
101 struct workqueue_struct *workqueue; 78 struct workqueue_struct *workqueue;
102 struct mutex mutex; 79 struct mutex mutex;
103 struct twl6040_output headset;
104 struct twl6040_output handsfree;
105}; 80};
106 81
107/* 82/*
@@ -311,318 +286,6 @@ static void twl6040_restore_regs(struct snd_soc_codec *codec)
311 } 286 }
312} 287}
313 288
314/*
315 * Ramp HS PGA volume to minimise pops at stream startup and shutdown.
316 */
317static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
318 unsigned int left_step, unsigned int right_step)
319{
320
321 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
322 struct twl6040_output *headset = &priv->headset;
323 int left_complete = 0, right_complete = 0;
324 u8 reg, val;
325
326 /* left channel */
327 left_step = (left_step > 0xF) ? 0xF : left_step;
328 reg = twl6040_read_reg_cache(codec, TWL6040_REG_HSGAIN);
329 val = (~reg & TWL6040_HSL_VOL_MASK);
330
331 if (headset->ramp == TWL6040_RAMP_UP) {
332 /* ramp step up */
333 if (val < headset->left_vol) {
334 if (val + left_step > headset->left_vol)
335 val = headset->left_vol;
336 else
337 val += left_step;
338
339 reg &= ~TWL6040_HSL_VOL_MASK;
340 twl6040_write(codec, TWL6040_REG_HSGAIN,
341 (reg | (~val & TWL6040_HSL_VOL_MASK)));
342 } else {
343 left_complete = 1;
344 }
345 } else if (headset->ramp == TWL6040_RAMP_DOWN) {
346 /* ramp step down */
347 if (val > 0x0) {
348 if ((int)val - (int)left_step < 0)
349 val = 0;
350 else
351 val -= left_step;
352
353 reg &= ~TWL6040_HSL_VOL_MASK;
354 twl6040_write(codec, TWL6040_REG_HSGAIN, reg |
355 (~val & TWL6040_HSL_VOL_MASK));
356 } else {
357 left_complete = 1;
358 }
359 }
360
361 /* right channel */
362 right_step = (right_step > 0xF) ? 0xF : right_step;
363 reg = twl6040_read_reg_cache(codec, TWL6040_REG_HSGAIN);
364 val = (~reg & TWL6040_HSR_VOL_MASK) >> TWL6040_HSR_VOL_SHIFT;
365
366 if (headset->ramp == TWL6040_RAMP_UP) {
367 /* ramp step up */
368 if (val < headset->right_vol) {
369 if (val + right_step > headset->right_vol)
370 val = headset->right_vol;
371 else
372 val += right_step;
373
374 reg &= ~TWL6040_HSR_VOL_MASK;
375 twl6040_write(codec, TWL6040_REG_HSGAIN,
376 (reg | (~val << TWL6040_HSR_VOL_SHIFT)));
377 } else {
378 right_complete = 1;
379 }
380 } else if (headset->ramp == TWL6040_RAMP_DOWN) {
381 /* ramp step down */
382 if (val > 0x0) {
383 if ((int)val - (int)right_step < 0)
384 val = 0;
385 else
386 val -= right_step;
387
388 reg &= ~TWL6040_HSR_VOL_MASK;
389 twl6040_write(codec, TWL6040_REG_HSGAIN,
390 reg | (~val << TWL6040_HSR_VOL_SHIFT));
391 } else {
392 right_complete = 1;
393 }
394 }
395
396 return left_complete & right_complete;
397}
398
399/*
400 * Ramp HF PGA volume to minimise pops at stream startup and shutdown.
401 */
402static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
403 unsigned int left_step, unsigned int right_step)
404{
405 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
406 struct twl6040_output *handsfree = &priv->handsfree;
407 int left_complete = 0, right_complete = 0;
408 u16 reg, val;
409
410 /* left channel */
411 left_step = (left_step > 0x1D) ? 0x1D : left_step;
412 reg = twl6040_read_reg_cache(codec, TWL6040_REG_HFLGAIN);
413 reg = 0x1D - reg;
414 val = (reg & TWL6040_HF_VOL_MASK);
415 if (handsfree->ramp == TWL6040_RAMP_UP) {
416 /* ramp step up */
417 if (val < handsfree->left_vol) {
418 if (val + left_step > handsfree->left_vol)
419 val = handsfree->left_vol;
420 else
421 val += left_step;
422
423 reg &= ~TWL6040_HF_VOL_MASK;
424 twl6040_write(codec, TWL6040_REG_HFLGAIN,
425 reg | (0x1D - val));
426 } else {
427 left_complete = 1;
428 }
429 } else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
430 /* ramp step down */
431 if (val > 0) {
432 if ((int)val - (int)left_step < 0)
433 val = 0;
434 else
435 val -= left_step;
436
437 reg &= ~TWL6040_HF_VOL_MASK;
438 twl6040_write(codec, TWL6040_REG_HFLGAIN,
439 reg | (0x1D - val));
440 } else {
441 left_complete = 1;
442 }
443 }
444
445 /* right channel */
446 right_step = (right_step > 0x1D) ? 0x1D : right_step;
447 reg = twl6040_read_reg_cache(codec, TWL6040_REG_HFRGAIN);
448 reg = 0x1D - reg;
449 val = (reg & TWL6040_HF_VOL_MASK);
450 if (handsfree->ramp == TWL6040_RAMP_UP) {
451 /* ramp step up */
452 if (val < handsfree->right_vol) {
453 if (val + right_step > handsfree->right_vol)
454 val = handsfree->right_vol;
455 else
456 val += right_step;
457
458 reg &= ~TWL6040_HF_VOL_MASK;
459 twl6040_write(codec, TWL6040_REG_HFRGAIN,
460 reg | (0x1D - val));
461 } else {
462 right_complete = 1;
463 }
464 } else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
465 /* ramp step down */
466 if (val > 0) {
467 if ((int)val - (int)right_step < 0)
468 val = 0;
469 else
470 val -= right_step;
471
472 reg &= ~TWL6040_HF_VOL_MASK;
473 twl6040_write(codec, TWL6040_REG_HFRGAIN,
474 reg | (0x1D - val));
475 }
476 }
477
478 return left_complete & right_complete;
479}
480
481/*
482 * This work ramps both output PGAs at stream start/stop time to
483 * minimise pop associated with DAPM power switching.
484 */
485static void twl6040_pga_hs_work(struct work_struct *work)
486{
487 struct twl6040_data *priv =
488 container_of(work, struct twl6040_data, headset.work.work);
489 struct snd_soc_codec *codec = priv->codec;
490 struct twl6040_output *headset = &priv->headset;
491 int i, headset_complete;
492
493 /* do we need to ramp at all ? */
494 if (headset->ramp == TWL6040_RAMP_NONE)
495 return;
496
497 /* HS PGA gain range: 0x0 - 0xf (0 - 15) */
498 for (i = 0; i < 16; i++) {
499 headset_complete = twl6040_hs_ramp_step(codec,
500 headset->left_step,
501 headset->right_step);
502
503 /* ramp finished ? */
504 if (headset_complete)
505 break;
506
507 schedule_timeout_interruptible(
508 msecs_to_jiffies(headset->step_delay));
509 }
510
511 if (headset->ramp == TWL6040_RAMP_DOWN) {
512 headset->active = 0;
513 complete(&headset->ramp_done);
514 } else {
515 headset->active = 1;
516 }
517 headset->ramp = TWL6040_RAMP_NONE;
518}
519
520static void twl6040_pga_hf_work(struct work_struct *work)
521{
522 struct twl6040_data *priv =
523 container_of(work, struct twl6040_data, handsfree.work.work);
524 struct snd_soc_codec *codec = priv->codec;
525 struct twl6040_output *handsfree = &priv->handsfree;
526 int i, handsfree_complete;
527
528 /* do we need to ramp at all ? */
529 if (handsfree->ramp == TWL6040_RAMP_NONE)
530 return;
531
532 /*
533 * HF PGA gain range: 0x00 - 0x1d (0 - 29) */
534 for (i = 0; i < 30; i++) {
535 handsfree_complete = twl6040_hf_ramp_step(codec,
536 handsfree->left_step,
537 handsfree->right_step);
538
539 /* ramp finished ? */
540 if (handsfree_complete)
541 break;
542
543 schedule_timeout_interruptible(
544 msecs_to_jiffies(handsfree->step_delay));
545 }
546
547
548 if (handsfree->ramp == TWL6040_RAMP_DOWN) {
549 handsfree->active = 0;
550 complete(&handsfree->ramp_done);
551 } else
552 handsfree->active = 1;
553 handsfree->ramp = TWL6040_RAMP_NONE;
554}
555
556static int out_drv_event(struct snd_soc_dapm_widget *w,
557 struct snd_kcontrol *kcontrol, int event)
558{
559 struct snd_soc_codec *codec = w->codec;
560 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
561 struct twl6040_output *out;
562 struct delayed_work *work;
563
564 switch (w->shift) {
565 case 2: /* Headset output driver */
566 out = &priv->headset;
567 work = &out->work;
568 /*
569 * Make sure, that we do not mess up variables for already
570 * executing work.
571 */
572 cancel_delayed_work_sync(work);
573
574 out->left_step = priv->hs_left_step;
575 out->right_step = priv->hs_right_step;
576 out->step_delay = 5; /* 5 ms between volume ramp steps */
577 break;
578 case 4: /* Handsfree output driver */
579 out = &priv->handsfree;
580 work = &out->work;
581 /*
582 * Make sure, that we do not mess up variables for already
583 * executing work.
584 */
585 cancel_delayed_work_sync(work);
586
587 out->left_step = priv->hf_left_step;
588 out->right_step = priv->hf_right_step;
589 out->step_delay = 5; /* 5 ms between volume ramp steps */
590 break;
591 default:
592 return -1;
593 }
594
595 switch (event) {
596 case SND_SOC_DAPM_POST_PMU:
597 if (out->active)
598 break;
599
600 /* don't use volume ramp for power-up */
601 out->ramp = TWL6040_RAMP_UP;
602 out->left_step = out->left_vol;
603 out->right_step = out->right_vol;
604
605 queue_delayed_work(priv->workqueue, work, msecs_to_jiffies(1));
606 break;
607
608 case SND_SOC_DAPM_PRE_PMD:
609 if (!out->active)
610 break;
611
612 /* use volume ramp for power-down */
613 out->ramp = TWL6040_RAMP_DOWN;
614 INIT_COMPLETION(out->ramp_done);
615
616 queue_delayed_work(priv->workqueue, work, msecs_to_jiffies(1));
617
618 wait_for_completion_timeout(&out->ramp_done,
619 msecs_to_jiffies(2000));
620 break;
621 }
622
623 return 0;
624}
625
626/* set headset dac and driver power mode */ 289/* set headset dac and driver power mode */
627static int headset_power_mode(struct snd_soc_codec *codec, int high_perf) 290static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
628{ 291{
@@ -747,71 +410,6 @@ static irqreturn_t twl6040_audio_handler(int irq, void *data)
747 return IRQ_HANDLED; 410 return IRQ_HANDLED;
748} 411}
749 412
750static int twl6040_put_volsw(struct snd_kcontrol *kcontrol,
751 struct snd_ctl_elem_value *ucontrol)
752{
753 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
754 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
755 struct twl6040_output *out = NULL;
756 struct soc_mixer_control *mc =
757 (struct soc_mixer_control *)kcontrol->private_value;
758 int ret;
759
760 /* For HS and HF we shadow the values and only actually write
761 * them out when active in order to ensure the amplifier comes on
762 * as quietly as possible. */
763 switch (mc->reg) {
764 case TWL6040_REG_HSGAIN:
765 out = &twl6040_priv->headset;
766 break;
767 case TWL6040_REG_HFLGAIN:
768 out = &twl6040_priv->handsfree;
769 break;
770 default:
771 dev_warn(codec->dev, "%s: Unexpected register: 0x%02x\n",
772 __func__, mc->reg);
773 return -EINVAL;
774 }
775
776 out->left_vol = ucontrol->value.integer.value[0];
777 out->right_vol = ucontrol->value.integer.value[1];
778 if (!out->active)
779 return 1;
780
781 ret = snd_soc_put_volsw(kcontrol, ucontrol);
782 if (ret < 0)
783 return ret;
784
785 return 1;
786}
787
788static int twl6040_get_volsw(struct snd_kcontrol *kcontrol,
789 struct snd_ctl_elem_value *ucontrol)
790{
791 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
792 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
793 struct twl6040_output *out = &twl6040_priv->headset;
794 struct soc_mixer_control *mc =
795 (struct soc_mixer_control *)kcontrol->private_value;
796
797 switch (mc->reg) {
798 case TWL6040_REG_HSGAIN:
799 out = &twl6040_priv->headset;
800 break;
801 case TWL6040_REG_HFLGAIN:
802 out = &twl6040_priv->handsfree;
803 break;
804 default:
805 dev_warn(codec->dev, "%s: Unexpected register: 0x%02x\n",
806 __func__, mc->reg);
807 return -EINVAL;
808 }
809
810 ucontrol->value.integer.value[0] = out->left_vol;
811 ucontrol->value.integer.value[1] = out->right_vol;
812 return 0;
813}
814
815static int twl6040_soc_dapm_put_vibra_enum(struct snd_kcontrol *kcontrol, 413static int twl6040_soc_dapm_put_vibra_enum(struct snd_kcontrol *kcontrol,
816 struct snd_ctl_elem_value *ucontrol) 414 struct snd_ctl_elem_value *ucontrol)
817{ 415{
@@ -1076,12 +674,10 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = {
1076 TWL6040_REG_LINEGAIN, 0, 3, 7, 0, afm_amp_tlv), 674 TWL6040_REG_LINEGAIN, 0, 3, 7, 0, afm_amp_tlv),
1077 675
1078 /* Playback gains */ 676 /* Playback gains */
1079 SOC_DOUBLE_EXT_TLV("Headset Playback Volume", 677 SOC_DOUBLE_TLV("Headset Playback Volume",
1080 TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, twl6040_get_volsw, 678 TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv),
1081 twl6040_put_volsw, hs_tlv), 679 SOC_DOUBLE_R_TLV("Handsfree Playback Volume",
1082 SOC_DOUBLE_R_EXT_TLV("Handsfree Playback Volume", 680 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv),
1083 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1,
1084 twl6040_get_volsw, twl6040_put_volsw, hf_tlv),
1085 SOC_SINGLE_TLV("Earphone Playback Volume", 681 SOC_SINGLE_TLV("Earphone Playback Volume",
1086 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv), 682 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv),
1087 683
@@ -1180,22 +776,14 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
1180 &auxr_switch_control), 776 &auxr_switch_control),
1181 777
1182 /* Analog playback drivers */ 778 /* Analog playback drivers */
1183 SND_SOC_DAPM_OUT_DRV_E("HF Left Driver", 779 SND_SOC_DAPM_OUT_DRV("HF Left Driver",
1184 TWL6040_REG_HFLCTL, 4, 0, NULL, 0, 780 TWL6040_REG_HFLCTL, 4, 0, NULL, 0),
1185 out_drv_event, 781 SND_SOC_DAPM_OUT_DRV("HF Right Driver",
1186 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 782 TWL6040_REG_HFRCTL, 4, 0, NULL, 0),
1187 SND_SOC_DAPM_OUT_DRV_E("HF Right Driver", 783 SND_SOC_DAPM_OUT_DRV("HS Left Driver",
1188 TWL6040_REG_HFRCTL, 4, 0, NULL, 0, 784 TWL6040_REG_HSLCTL, 2, 0, NULL, 0),
1189 out_drv_event, 785 SND_SOC_DAPM_OUT_DRV("HS Right Driver",
1190 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 786 TWL6040_REG_HSRCTL, 2, 0, NULL, 0),
1191 SND_SOC_DAPM_OUT_DRV_E("HS Left Driver",
1192 TWL6040_REG_HSLCTL, 2, 0, NULL, 0,
1193 out_drv_event,
1194 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1195 SND_SOC_DAPM_OUT_DRV_E("HS Right Driver",
1196 TWL6040_REG_HSRCTL, 2, 0, NULL, 0,
1197 out_drv_event,
1198 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1199 SND_SOC_DAPM_OUT_DRV_E("Earphone Driver", 787 SND_SOC_DAPM_OUT_DRV_E("Earphone Driver",
1200 TWL6040_REG_EARCTL, 0, 0, NULL, 0, 788 TWL6040_REG_EARCTL, 0, 0, NULL, 0,
1201 twl6040_ep_drv_event, 789 twl6040_ep_drv_event,
@@ -1339,8 +927,7 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
1339static int twl6040_startup(struct snd_pcm_substream *substream, 927static int twl6040_startup(struct snd_pcm_substream *substream,
1340 struct snd_soc_dai *dai) 928 struct snd_soc_dai *dai)
1341{ 929{
1342 struct snd_soc_pcm_runtime *rtd = substream->private_data; 930 struct snd_soc_codec *codec = dai->codec;
1343 struct snd_soc_codec *codec = rtd->codec;
1344 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 931 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1345 932
1346 snd_pcm_hw_constraint_list(substream->runtime, 0, 933 snd_pcm_hw_constraint_list(substream->runtime, 0,
@@ -1354,8 +941,7 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
1354 struct snd_pcm_hw_params *params, 941 struct snd_pcm_hw_params *params,
1355 struct snd_soc_dai *dai) 942 struct snd_soc_dai *dai)
1356{ 943{
1357 struct snd_soc_pcm_runtime *rtd = substream->private_data; 944 struct snd_soc_codec *codec = dai->codec;
1358 struct snd_soc_codec *codec = rtd->codec;
1359 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 945 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1360 int rate; 946 int rate;
1361 947
@@ -1391,8 +977,7 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
1391static int twl6040_prepare(struct snd_pcm_substream *substream, 977static int twl6040_prepare(struct snd_pcm_substream *substream,
1392 struct snd_soc_dai *dai) 978 struct snd_soc_dai *dai)
1393{ 979{
1394 struct snd_soc_pcm_runtime *rtd = substream->private_data; 980 struct snd_soc_codec *codec = dai->codec;
1395 struct snd_soc_codec *codec = rtd->codec;
1396 struct twl6040 *twl6040 = codec->control_data; 981 struct twl6040 *twl6040 = codec->control_data;
1397 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 982 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
1398 int ret; 983 int ret;
@@ -1570,14 +1155,9 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1570 } 1155 }
1571 1156
1572 INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work); 1157 INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work);
1573 INIT_DELAYED_WORK(&priv->headset.work, twl6040_pga_hs_work);
1574 INIT_DELAYED_WORK(&priv->handsfree.work, twl6040_pga_hf_work);
1575 1158
1576 mutex_init(&priv->mutex); 1159 mutex_init(&priv->mutex);
1577 1160
1578 init_completion(&priv->headset.ramp_done);
1579 init_completion(&priv->handsfree.ramp_done);
1580
1581 ret = request_threaded_irq(priv->plug_irq, NULL, twl6040_audio_handler, 1161 ret = request_threaded_irq(priv->plug_irq, NULL, twl6040_audio_handler,
1582 0, "twl6040_irq_plug", codec); 1162 0, "twl6040_irq_plug", codec);
1583 if (ret) { 1163 if (ret) {
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 797b0dde2c68..6c3d43b8ee85 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -159,8 +159,7 @@ static int uda134x_mute(struct snd_soc_dai *dai, int mute)
159static int uda134x_startup(struct snd_pcm_substream *substream, 159static int uda134x_startup(struct snd_pcm_substream *substream,
160 struct snd_soc_dai *dai) 160 struct snd_soc_dai *dai)
161{ 161{
162 struct snd_soc_pcm_runtime *rtd = substream->private_data; 162 struct snd_soc_codec *codec = dai->codec;
163 struct snd_soc_codec *codec =rtd->codec;
164 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); 163 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
165 struct snd_pcm_runtime *master_runtime; 164 struct snd_pcm_runtime *master_runtime;
166 165
@@ -191,8 +190,7 @@ static int uda134x_startup(struct snd_pcm_substream *substream,
191static void uda134x_shutdown(struct snd_pcm_substream *substream, 190static void uda134x_shutdown(struct snd_pcm_substream *substream,
192 struct snd_soc_dai *dai) 191 struct snd_soc_dai *dai)
193{ 192{
194 struct snd_soc_pcm_runtime *rtd = substream->private_data; 193 struct snd_soc_codec *codec = dai->codec;
195 struct snd_soc_codec *codec = rtd->codec;
196 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); 194 struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
197 195
198 if (uda134x->master_substream == substream) 196 if (uda134x->master_substream == substream)
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 4f1b23d7e404..2502214b84ab 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -502,8 +502,7 @@ static int uda1380_set_dai_fmt_capture(struct snd_soc_dai *codec_dai,
502static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd, 502static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
503 struct snd_soc_dai *dai) 503 struct snd_soc_dai *dai)
504{ 504{
505 struct snd_soc_pcm_runtime *rtd = substream->private_data; 505 struct snd_soc_codec *codec = dai->codec;
506 struct snd_soc_codec *codec = rtd->codec;
507 struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); 506 struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec);
508 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER); 507 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
509 508
@@ -528,8 +527,7 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
528 struct snd_pcm_hw_params *params, 527 struct snd_pcm_hw_params *params,
529 struct snd_soc_dai *dai) 528 struct snd_soc_dai *dai)
530{ 529{
531 struct snd_soc_pcm_runtime *rtd = substream->private_data; 530 struct snd_soc_codec *codec = dai->codec;
532 struct snd_soc_codec *codec = rtd->codec;
533 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); 531 u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK);
534 532
535 /* set WSPLL power and divider if running from this clock */ 533 /* set WSPLL power and divider if running from this clock */
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 3d868dc40092..7b24d6d192e1 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -293,8 +293,7 @@ static const struct snd_kcontrol_new wl1273_controls[] = {
293static int wl1273_startup(struct snd_pcm_substream *substream, 293static int wl1273_startup(struct snd_pcm_substream *substream,
294 struct snd_soc_dai *dai) 294 struct snd_soc_dai *dai)
295{ 295{
296 struct snd_soc_pcm_runtime *rtd = substream->private_data; 296 struct snd_soc_codec *codec = dai->codec;
297 struct snd_soc_codec *codec = rtd->codec;
298 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); 297 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
299 298
300 switch (wl1273->mode) { 299 switch (wl1273->mode) {
@@ -329,8 +328,7 @@ static int wl1273_hw_params(struct snd_pcm_substream *substream,
329 struct snd_pcm_hw_params *params, 328 struct snd_pcm_hw_params *params,
330 struct snd_soc_dai *dai) 329 struct snd_soc_dai *dai)
331{ 330{
332 struct snd_soc_pcm_runtime *rtd = substream->private_data; 331 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(dai->codec);
333 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(rtd->codec);
334 struct wl1273_core *core = wl1273->core; 332 struct wl1273_core *core = wl1273->core;
335 unsigned int rate, width, r; 333 unsigned int rate, width, r;
336 334
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c
index aefb4f89be0e..e0b51e9f8b12 100644
--- a/sound/soc/codecs/wm1250-ev1.c
+++ b/sound/soc/codecs/wm1250-ev1.c
@@ -79,22 +79,65 @@ static const struct snd_soc_dapm_route wm1250_ev1_dapm_routes[] = {
79 { "WM1250 Output", NULL, "DAC" }, 79 { "WM1250 Output", NULL, "DAC" },
80}; 80};
81 81
82static int wm1250_ev1_hw_params(struct snd_pcm_substream *substream,
83 struct snd_pcm_hw_params *params,
84 struct snd_soc_dai *dai)
85{
86 struct wm1250_priv *wm1250 = snd_soc_codec_get_drvdata(dai->codec);
87
88 switch (params_rate(params)) {
89 case 8000:
90 gpio_set_value(wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL0].gpio,
91 1);
92 gpio_set_value(wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL1].gpio,
93 1);
94 break;
95 case 16000:
96 gpio_set_value(wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL0].gpio,
97 0);
98 gpio_set_value(wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL1].gpio,
99 1);
100 break;
101 case 32000:
102 gpio_set_value(wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL0].gpio,
103 1);
104 gpio_set_value(wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL1].gpio,
105 0);
106 break;
107 case 64000:
108 gpio_set_value(wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL0].gpio,
109 0);
110 gpio_set_value(wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL1].gpio,
111 0);
112 break;
113 default:
114 return -EINVAL;
115 }
116
117 return 0;
118}
119
120static const struct snd_soc_dai_ops wm1250_ev1_ops = {
121 .hw_params = wm1250_ev1_hw_params,
122};
123
82static struct snd_soc_dai_driver wm1250_ev1_dai = { 124static struct snd_soc_dai_driver wm1250_ev1_dai = {
83 .name = "wm1250-ev1", 125 .name = "wm1250-ev1",
84 .playback = { 126 .playback = {
85 .stream_name = "Playback", 127 .stream_name = "Playback",
86 .channels_min = 1, 128 .channels_min = 1,
87 .channels_max = 1, 129 .channels_max = 2,
88 .rates = SNDRV_PCM_RATE_8000, 130 .rates = SNDRV_PCM_RATE_8000,
89 .formats = SNDRV_PCM_FMTBIT_S16_LE, 131 .formats = SNDRV_PCM_FMTBIT_S16_LE,
90 }, 132 },
91 .capture = { 133 .capture = {
92 .stream_name = "Capture", 134 .stream_name = "Capture",
93 .channels_min = 1, 135 .channels_min = 1,
94 .channels_max = 1, 136 .channels_max = 2,
95 .rates = SNDRV_PCM_RATE_8000, 137 .rates = SNDRV_PCM_RATE_8000,
96 .formats = SNDRV_PCM_FMTBIT_S16_LE, 138 .formats = SNDRV_PCM_FMTBIT_S16_LE,
97 }, 139 },
140 .ops = &wm1250_ev1_ops,
98}; 141};
99 142
100static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = { 143static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = {
@@ -215,23 +258,7 @@ static struct i2c_driver wm1250_ev1_i2c_driver = {
215 .id_table = wm1250_ev1_i2c_id, 258 .id_table = wm1250_ev1_i2c_id,
216}; 259};
217 260
218static int __init wm1250_ev1_modinit(void) 261module_i2c_driver(wm1250_ev1_i2c_driver);
219{
220 int ret = 0;
221
222 ret = i2c_add_driver(&wm1250_ev1_i2c_driver);
223 if (ret != 0)
224 pr_err("Failed to register WM1250-EV1 I2C driver: %d\n", ret);
225
226 return ret;
227}
228module_init(wm1250_ev1_modinit);
229
230static void __exit wm1250_ev1_exit(void)
231{
232 i2c_del_driver(&wm1250_ev1_i2c_driver);
233}
234module_exit(wm1250_ev1_exit);
235 262
236MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 263MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
237MODULE_DESCRIPTION("WM1250-EV1 audio I/O module driver"); 264MODULE_DESCRIPTION("WM1250-EV1 audio I/O module driver");
diff --git a/sound/soc/codecs/wm5100-tables.c b/sound/soc/codecs/wm5100-tables.c
index 9a18fae68204..e167207a19cc 100644
--- a/sound/soc/codecs/wm5100-tables.c
+++ b/sound/soc/codecs/wm5100-tables.c
@@ -32,7 +32,18 @@ bool wm5100_volatile_register(struct device *dev, unsigned int reg)
32 case WM5100_MIC_DETECT_3: 32 case WM5100_MIC_DETECT_3:
33 return 1; 33 return 1;
34 default: 34 default:
35 return 0; 35 if ((reg >= WM5100_DSP1_PM_0 && reg <= WM5100_DSP1_PM_1535) ||
36 (reg >= WM5100_DSP1_ZM_0 && reg <= WM5100_DSP1_ZM_2047) ||
37 (reg >= WM5100_DSP1_DM_0 && reg <= WM5100_DSP1_DM_511) ||
38 (reg >= WM5100_DSP2_PM_0 && reg <= WM5100_DSP2_PM_1535) ||
39 (reg >= WM5100_DSP2_ZM_0 && reg <= WM5100_DSP2_ZM_2047) ||
40 (reg >= WM5100_DSP2_DM_0 && reg <= WM5100_DSP2_DM_511) ||
41 (reg >= WM5100_DSP3_PM_0 && reg <= WM5100_DSP3_PM_1535) ||
42 (reg >= WM5100_DSP3_ZM_0 && reg <= WM5100_DSP3_ZM_2047) ||
43 (reg >= WM5100_DSP3_DM_0 && reg <= WM5100_DSP3_DM_511))
44 return 1;
45 else
46 return 0;
36 } 47 }
37} 48}
38 49
@@ -697,9 +708,110 @@ bool wm5100_readable_register(struct device *dev, unsigned int reg)
697 case WM5100_HPLPF3_2: 708 case WM5100_HPLPF3_2:
698 case WM5100_HPLPF4_1: 709 case WM5100_HPLPF4_1:
699 case WM5100_HPLPF4_2: 710 case WM5100_HPLPF4_2:
711 case WM5100_DSP1_CONTROL_1:
712 case WM5100_DSP1_CONTROL_2:
713 case WM5100_DSP1_CONTROL_3:
714 case WM5100_DSP1_CONTROL_4:
715 case WM5100_DSP1_CONTROL_5:
716 case WM5100_DSP1_CONTROL_6:
717 case WM5100_DSP1_CONTROL_7:
718 case WM5100_DSP1_CONTROL_8:
719 case WM5100_DSP1_CONTROL_9:
720 case WM5100_DSP1_CONTROL_10:
721 case WM5100_DSP1_CONTROL_11:
722 case WM5100_DSP1_CONTROL_12:
723 case WM5100_DSP1_CONTROL_13:
724 case WM5100_DSP1_CONTROL_14:
725 case WM5100_DSP1_CONTROL_15:
726 case WM5100_DSP1_CONTROL_16:
727 case WM5100_DSP1_CONTROL_17:
728 case WM5100_DSP1_CONTROL_18:
729 case WM5100_DSP1_CONTROL_19:
730 case WM5100_DSP1_CONTROL_20:
731 case WM5100_DSP1_CONTROL_21:
732 case WM5100_DSP1_CONTROL_22:
733 case WM5100_DSP1_CONTROL_23:
734 case WM5100_DSP1_CONTROL_24:
735 case WM5100_DSP1_CONTROL_25:
736 case WM5100_DSP1_CONTROL_26:
737 case WM5100_DSP1_CONTROL_27:
738 case WM5100_DSP1_CONTROL_28:
739 case WM5100_DSP1_CONTROL_29:
740 case WM5100_DSP1_CONTROL_30:
741 case WM5100_DSP2_CONTROL_1:
742 case WM5100_DSP2_CONTROL_2:
743 case WM5100_DSP2_CONTROL_3:
744 case WM5100_DSP2_CONTROL_4:
745 case WM5100_DSP2_CONTROL_5:
746 case WM5100_DSP2_CONTROL_6:
747 case WM5100_DSP2_CONTROL_7:
748 case WM5100_DSP2_CONTROL_8:
749 case WM5100_DSP2_CONTROL_9:
750 case WM5100_DSP2_CONTROL_10:
751 case WM5100_DSP2_CONTROL_11:
752 case WM5100_DSP2_CONTROL_12:
753 case WM5100_DSP2_CONTROL_13:
754 case WM5100_DSP2_CONTROL_14:
755 case WM5100_DSP2_CONTROL_15:
756 case WM5100_DSP2_CONTROL_16:
757 case WM5100_DSP2_CONTROL_17:
758 case WM5100_DSP2_CONTROL_18:
759 case WM5100_DSP2_CONTROL_19:
760 case WM5100_DSP2_CONTROL_20:
761 case WM5100_DSP2_CONTROL_21:
762 case WM5100_DSP2_CONTROL_22:
763 case WM5100_DSP2_CONTROL_23:
764 case WM5100_DSP2_CONTROL_24:
765 case WM5100_DSP2_CONTROL_25:
766 case WM5100_DSP2_CONTROL_26:
767 case WM5100_DSP2_CONTROL_27:
768 case WM5100_DSP2_CONTROL_28:
769 case WM5100_DSP2_CONTROL_29:
770 case WM5100_DSP2_CONTROL_30:
771 case WM5100_DSP3_CONTROL_1:
772 case WM5100_DSP3_CONTROL_2:
773 case WM5100_DSP3_CONTROL_3:
774 case WM5100_DSP3_CONTROL_4:
775 case WM5100_DSP3_CONTROL_5:
776 case WM5100_DSP3_CONTROL_6:
777 case WM5100_DSP3_CONTROL_7:
778 case WM5100_DSP3_CONTROL_8:
779 case WM5100_DSP3_CONTROL_9:
780 case WM5100_DSP3_CONTROL_10:
781 case WM5100_DSP3_CONTROL_11:
782 case WM5100_DSP3_CONTROL_12:
783 case WM5100_DSP3_CONTROL_13:
784 case WM5100_DSP3_CONTROL_14:
785 case WM5100_DSP3_CONTROL_15:
786 case WM5100_DSP3_CONTROL_16:
787 case WM5100_DSP3_CONTROL_17:
788 case WM5100_DSP3_CONTROL_18:
789 case WM5100_DSP3_CONTROL_19:
790 case WM5100_DSP3_CONTROL_20:
791 case WM5100_DSP3_CONTROL_21:
792 case WM5100_DSP3_CONTROL_22:
793 case WM5100_DSP3_CONTROL_23:
794 case WM5100_DSP3_CONTROL_24:
795 case WM5100_DSP3_CONTROL_25:
796 case WM5100_DSP3_CONTROL_26:
797 case WM5100_DSP3_CONTROL_27:
798 case WM5100_DSP3_CONTROL_28:
799 case WM5100_DSP3_CONTROL_29:
800 case WM5100_DSP3_CONTROL_30:
700 return 1; 801 return 1;
701 default: 802 default:
702 return 0; 803 if ((reg >= WM5100_DSP1_PM_0 && reg <= WM5100_DSP1_PM_1535) ||
804 (reg >= WM5100_DSP1_ZM_0 && reg <= WM5100_DSP1_ZM_2047) ||
805 (reg >= WM5100_DSP1_DM_0 && reg <= WM5100_DSP1_DM_511) ||
806 (reg >= WM5100_DSP2_PM_0 && reg <= WM5100_DSP2_PM_1535) ||
807 (reg >= WM5100_DSP2_ZM_0 && reg <= WM5100_DSP2_ZM_2047) ||
808 (reg >= WM5100_DSP2_DM_0 && reg <= WM5100_DSP2_DM_511) ||
809 (reg >= WM5100_DSP3_PM_0 && reg <= WM5100_DSP3_PM_1535) ||
810 (reg >= WM5100_DSP3_ZM_0 && reg <= WM5100_DSP3_ZM_2047) ||
811 (reg >= WM5100_DSP3_DM_0 && reg <= WM5100_DSP3_DM_511))
812 return 1;
813 else
814 return 0;
703 } 815 }
704} 816}
705 817
@@ -1361,4 +1473,13 @@ struct reg_default wm5100_reg_defaults[WM5100_REGISTER_COUNT] = {
1361 { 0x0EC9, 0x0000 }, /* R3785 - HPLPF3_2 */ 1473 { 0x0EC9, 0x0000 }, /* R3785 - HPLPF3_2 */
1362 { 0x0ECC, 0x0000 }, /* R3788 - HPLPF4_1 */ 1474 { 0x0ECC, 0x0000 }, /* R3788 - HPLPF4_1 */
1363 { 0x0ECD, 0x0000 }, /* R3789 - HPLPF4_2 */ 1475 { 0x0ECD, 0x0000 }, /* R3789 - HPLPF4_2 */
1476 { 0x0F02, 0x0000 }, /* R3842 - DSP1 Control 2 */
1477 { 0x0F03, 0x0000 }, /* R3843 - DSP1 Control 3 */
1478 { 0x0F04, 0x0000 }, /* R3844 - DSP1 Control 4 */
1479 { 0x1002, 0x0000 }, /* R4098 - DSP2 Control 2 */
1480 { 0x1003, 0x0000 }, /* R4099 - DSP2 Control 3 */
1481 { 0x1004, 0x0000 }, /* R4100 - DSP2 Control 4 */
1482 { 0x1102, 0x0000 }, /* R4354 - DSP3 Control 2 */
1483 { 0x1103, 0x0000 }, /* R4355 - DSP3 Control 3 */
1484 { 0x1104, 0x0000 }, /* R4356 - DSP3 Control 4 */
1364}; 1485};
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index b9c185ce64e4..cb6d5372103a 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -1265,29 +1265,12 @@ static const __devinitdata struct reg_default wm5100_reva_patches[] = {
1265 { WM5100_AUDIO_IF_3_19, 1 }, 1265 { WM5100_AUDIO_IF_3_19, 1 },
1266}; 1266};
1267 1267
1268static int wm5100_dai_to_base(struct snd_soc_dai *dai)
1269{
1270 switch (dai->id) {
1271 case 0:
1272 return WM5100_AUDIO_IF_1_1 - 1;
1273 case 1:
1274 return WM5100_AUDIO_IF_2_1 - 1;
1275 case 2:
1276 return WM5100_AUDIO_IF_3_1 - 1;
1277 default:
1278 BUG();
1279 return -EINVAL;
1280 }
1281}
1282
1283static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 1268static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1284{ 1269{
1285 struct snd_soc_codec *codec = dai->codec; 1270 struct snd_soc_codec *codec = dai->codec;
1286 int lrclk, bclk, mask, base; 1271 int lrclk, bclk, mask, base;
1287 1272
1288 base = wm5100_dai_to_base(dai); 1273 base = dai->driver->base;
1289 if (base < 0)
1290 return base;
1291 1274
1292 lrclk = 0; 1275 lrclk = 0;
1293 bclk = 0; 1276 bclk = 0;
@@ -1414,9 +1397,7 @@ static int wm5100_hw_params(struct snd_pcm_substream *substream,
1414 int i, base, bclk, aif_rate, lrclk, wl, fl, sr; 1397 int i, base, bclk, aif_rate, lrclk, wl, fl, sr;
1415 int *bclk_rates; 1398 int *bclk_rates;
1416 1399
1417 base = wm5100_dai_to_base(dai); 1400 base = dai->driver->base;
1418 if (base < 0)
1419 return base;
1420 1401
1421 /* Data sizes if not using TDM */ 1402 /* Data sizes if not using TDM */
1422 wl = snd_pcm_format_width(params_format(params)); 1403 wl = snd_pcm_format_width(params_format(params));
@@ -1897,6 +1878,7 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1897static struct snd_soc_dai_driver wm5100_dai[] = { 1878static struct snd_soc_dai_driver wm5100_dai[] = {
1898 { 1879 {
1899 .name = "wm5100-aif1", 1880 .name = "wm5100-aif1",
1881 .base = WM5100_AUDIO_IF_1_1 - 1,
1900 .playback = { 1882 .playback = {
1901 .stream_name = "AIF1 Playback", 1883 .stream_name = "AIF1 Playback",
1902 .channels_min = 2, 1884 .channels_min = 2,
@@ -1916,6 +1898,7 @@ static struct snd_soc_dai_driver wm5100_dai[] = {
1916 { 1898 {
1917 .name = "wm5100-aif2", 1899 .name = "wm5100-aif2",
1918 .id = 1, 1900 .id = 1,
1901 .base = WM5100_AUDIO_IF_2_1 - 1,
1919 .playback = { 1902 .playback = {
1920 .stream_name = "AIF2 Playback", 1903 .stream_name = "AIF2 Playback",
1921 .channels_min = 2, 1904 .channels_min = 2,
@@ -1935,6 +1918,7 @@ static struct snd_soc_dai_driver wm5100_dai[] = {
1935 { 1918 {
1936 .name = "wm5100-aif3", 1919 .name = "wm5100-aif3",
1937 .id = 2, 1920 .id = 2,
1921 .base = WM5100_AUDIO_IF_3_1 - 1,
1938 .playback = { 1922 .playback = {
1939 .stream_name = "AIF3 Playback", 1923 .stream_name = "AIF3 Playback",
1940 .channels_min = 2, 1924 .channels_min = 2,
@@ -2454,7 +2438,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2454 2438
2455 wm5100->dev = &i2c->dev; 2439 wm5100->dev = &i2c->dev;
2456 2440
2457 wm5100->regmap = regmap_init_i2c(i2c, &wm5100_regmap); 2441 wm5100->regmap = devm_regmap_init_i2c(i2c, &wm5100_regmap);
2458 if (IS_ERR(wm5100->regmap)) { 2442 if (IS_ERR(wm5100->regmap)) {
2459 ret = PTR_ERR(wm5100->regmap); 2443 ret = PTR_ERR(wm5100->regmap);
2460 dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 2444 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
@@ -2479,7 +2463,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2479 if (ret != 0) { 2463 if (ret != 0) {
2480 dev_err(&i2c->dev, "Failed to request core supplies: %d\n", 2464 dev_err(&i2c->dev, "Failed to request core supplies: %d\n",
2481 ret); 2465 ret);
2482 goto err_regmap; 2466 goto err;
2483 } 2467 }
2484 2468
2485 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies), 2469 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
@@ -2487,7 +2471,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2487 if (ret != 0) { 2471 if (ret != 0) {
2488 dev_err(&i2c->dev, "Failed to enable core supplies: %d\n", 2472 dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
2489 ret); 2473 ret);
2490 goto err_regmap; 2474 goto err;
2491 } 2475 }
2492 2476
2493 if (wm5100->pdata.ldo_ena) { 2477 if (wm5100->pdata.ldo_ena) {
@@ -2660,8 +2644,6 @@ err_ldo:
2660err_enable: 2644err_enable:
2661 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), 2645 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2662 wm5100->core_supplies); 2646 wm5100->core_supplies);
2663err_regmap:
2664 regmap_exit(wm5100->regmap);
2665err: 2647err:
2666 return ret; 2648 return ret;
2667} 2649}
@@ -2682,7 +2664,6 @@ static __devexit int wm5100_i2c_remove(struct i2c_client *i2c)
2682 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); 2664 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2683 gpio_free(wm5100->pdata.ldo_ena); 2665 gpio_free(wm5100->pdata.ldo_ena);
2684 } 2666 }
2685 regmap_exit(wm5100->regmap);
2686 2667
2687 return 0; 2668 return 0;
2688} 2669}
@@ -2749,17 +2730,7 @@ static struct i2c_driver wm5100_i2c_driver = {
2749 .id_table = wm5100_i2c_id, 2730 .id_table = wm5100_i2c_id,
2750}; 2731};
2751 2732
2752static int __init wm5100_modinit(void) 2733module_i2c_driver(wm5100_i2c_driver);
2753{
2754 return i2c_add_driver(&wm5100_i2c_driver);
2755}
2756module_init(wm5100_modinit);
2757
2758static void __exit wm5100_exit(void)
2759{
2760 i2c_del_driver(&wm5100_i2c_driver);
2761}
2762module_exit(wm5100_exit);
2763 2734
2764MODULE_DESCRIPTION("ASoC WM5100 driver"); 2735MODULE_DESCRIPTION("ASoC WM5100 driver");
2765MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 2736MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm5100.h b/sound/soc/codecs/wm5100.h
index 25cb6016f9d7..935a9b7fb274 100644
--- a/sound/soc/codecs/wm5100.h
+++ b/sound/soc/codecs/wm5100.h
@@ -709,6 +709,96 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
709#define WM5100_HPLPF3_2 0xEC9 709#define WM5100_HPLPF3_2 0xEC9
710#define WM5100_HPLPF4_1 0xECC 710#define WM5100_HPLPF4_1 0xECC
711#define WM5100_HPLPF4_2 0xECD 711#define WM5100_HPLPF4_2 0xECD
712#define WM5100_DSP1_CONTROL_1 0xF00
713#define WM5100_DSP1_CONTROL_2 0xF02
714#define WM5100_DSP1_CONTROL_3 0xF03
715#define WM5100_DSP1_CONTROL_4 0xF04
716#define WM5100_DSP1_CONTROL_5 0xF06
717#define WM5100_DSP1_CONTROL_6 0xF07
718#define WM5100_DSP1_CONTROL_7 0xF08
719#define WM5100_DSP1_CONTROL_8 0xF09
720#define WM5100_DSP1_CONTROL_9 0xF0A
721#define WM5100_DSP1_CONTROL_10 0xF0B
722#define WM5100_DSP1_CONTROL_11 0xF0C
723#define WM5100_DSP1_CONTROL_12 0xF0D
724#define WM5100_DSP1_CONTROL_13 0xF0F
725#define WM5100_DSP1_CONTROL_14 0xF10
726#define WM5100_DSP1_CONTROL_15 0xF11
727#define WM5100_DSP1_CONTROL_16 0xF12
728#define WM5100_DSP1_CONTROL_17 0xF13
729#define WM5100_DSP1_CONTROL_18 0xF14
730#define WM5100_DSP1_CONTROL_19 0xF16
731#define WM5100_DSP1_CONTROL_20 0xF17
732#define WM5100_DSP1_CONTROL_21 0xF18
733#define WM5100_DSP1_CONTROL_22 0xF1A
734#define WM5100_DSP1_CONTROL_23 0xF1B
735#define WM5100_DSP1_CONTROL_24 0xF1C
736#define WM5100_DSP1_CONTROL_25 0xF1E
737#define WM5100_DSP1_CONTROL_26 0xF20
738#define WM5100_DSP1_CONTROL_27 0xF21
739#define WM5100_DSP1_CONTROL_28 0xF22
740#define WM5100_DSP1_CONTROL_29 0xF23
741#define WM5100_DSP1_CONTROL_30 0xF24
742#define WM5100_DSP2_CONTROL_1 0x1000
743#define WM5100_DSP2_CONTROL_2 0x1002
744#define WM5100_DSP2_CONTROL_3 0x1003
745#define WM5100_DSP2_CONTROL_4 0x1004
746#define WM5100_DSP2_CONTROL_5 0x1006
747#define WM5100_DSP2_CONTROL_6 0x1007
748#define WM5100_DSP2_CONTROL_7 0x1008
749#define WM5100_DSP2_CONTROL_8 0x1009
750#define WM5100_DSP2_CONTROL_9 0x100A
751#define WM5100_DSP2_CONTROL_10 0x100B
752#define WM5100_DSP2_CONTROL_11 0x100C
753#define WM5100_DSP2_CONTROL_12 0x100D
754#define WM5100_DSP2_CONTROL_13 0x100F
755#define WM5100_DSP2_CONTROL_14 0x1010
756#define WM5100_DSP2_CONTROL_15 0x1011
757#define WM5100_DSP2_CONTROL_16 0x1012
758#define WM5100_DSP2_CONTROL_17 0x1013
759#define WM5100_DSP2_CONTROL_18 0x1014
760#define WM5100_DSP2_CONTROL_19 0x1016
761#define WM5100_DSP2_CONTROL_20 0x1017
762#define WM5100_DSP2_CONTROL_21 0x1018
763#define WM5100_DSP2_CONTROL_22 0x101A
764#define WM5100_DSP2_CONTROL_23 0x101B
765#define WM5100_DSP2_CONTROL_24 0x101C
766#define WM5100_DSP2_CONTROL_25 0x101E
767#define WM5100_DSP2_CONTROL_26 0x1020
768#define WM5100_DSP2_CONTROL_27 0x1021
769#define WM5100_DSP2_CONTROL_28 0x1022
770#define WM5100_DSP2_CONTROL_29 0x1023
771#define WM5100_DSP2_CONTROL_30 0x1024
772#define WM5100_DSP3_CONTROL_1 0x1100
773#define WM5100_DSP3_CONTROL_2 0x1102
774#define WM5100_DSP3_CONTROL_3 0x1103
775#define WM5100_DSP3_CONTROL_4 0x1104
776#define WM5100_DSP3_CONTROL_5 0x1106
777#define WM5100_DSP3_CONTROL_6 0x1107
778#define WM5100_DSP3_CONTROL_7 0x1108
779#define WM5100_DSP3_CONTROL_8 0x1109
780#define WM5100_DSP3_CONTROL_9 0x110A
781#define WM5100_DSP3_CONTROL_10 0x110B
782#define WM5100_DSP3_CONTROL_11 0x110C
783#define WM5100_DSP3_CONTROL_12 0x110D
784#define WM5100_DSP3_CONTROL_13 0x110F
785#define WM5100_DSP3_CONTROL_14 0x1110
786#define WM5100_DSP3_CONTROL_15 0x1111
787#define WM5100_DSP3_CONTROL_16 0x1112
788#define WM5100_DSP3_CONTROL_17 0x1113
789#define WM5100_DSP3_CONTROL_18 0x1114
790#define WM5100_DSP3_CONTROL_19 0x1116
791#define WM5100_DSP3_CONTROL_20 0x1117
792#define WM5100_DSP3_CONTROL_21 0x1118
793#define WM5100_DSP3_CONTROL_22 0x111A
794#define WM5100_DSP3_CONTROL_23 0x111B
795#define WM5100_DSP3_CONTROL_24 0x111C
796#define WM5100_DSP3_CONTROL_25 0x111E
797#define WM5100_DSP3_CONTROL_26 0x1120
798#define WM5100_DSP3_CONTROL_27 0x1121
799#define WM5100_DSP3_CONTROL_28 0x1122
800#define WM5100_DSP3_CONTROL_29 0x1123
801#define WM5100_DSP3_CONTROL_30 0x1124
712#define WM5100_DSP1_DM_0 0x4000 802#define WM5100_DSP1_DM_0 0x4000
713#define WM5100_DSP1_DM_1 0x4001 803#define WM5100_DSP1_DM_1 0x4001
714#define WM5100_DSP1_DM_2 0x4002 804#define WM5100_DSP1_DM_2 0x4002
@@ -4561,6 +4651,75 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
4561#define WM5100_LHPF4_COEFF_WIDTH 16 /* LHPF4_COEFF - [15:0] */ 4651#define WM5100_LHPF4_COEFF_WIDTH 16 /* LHPF4_COEFF - [15:0] */
4562 4652
4563/* 4653/*
4654 * R4132 (0x1024) - DSP2 Control 30
4655 */
4656#define WM5100_DSP2_RATE_MASK 0xC000 /* DSP2_RATE - [15:14] */
4657#define WM5100_DSP2_RATE_SHIFT 14 /* DSP2_RATE - [15:14] */
4658#define WM5100_DSP2_RATE_WIDTH 2 /* DSP2_RATE - [15:14] */
4659#define WM5100_DSP2_DBG_CLK_ENA 0x0008 /* DSP2_DBG_CLK_ENA */
4660#define WM5100_DSP2_DBG_CLK_ENA_MASK 0x0008 /* DSP2_DBG_CLK_ENA */
4661#define WM5100_DSP2_DBG_CLK_ENA_SHIFT 3 /* DSP2_DBG_CLK_ENA */
4662#define WM5100_DSP2_DBG_CLK_ENA_WIDTH 1 /* DSP2_DBG_CLK_ENA */
4663#define WM5100_DSP2_SYS_ENA 0x0004 /* DSP2_SYS_ENA */
4664#define WM5100_DSP2_SYS_ENA_MASK 0x0004 /* DSP2_SYS_ENA */
4665#define WM5100_DSP2_SYS_ENA_SHIFT 2 /* DSP2_SYS_ENA */
4666#define WM5100_DSP2_SYS_ENA_WIDTH 1 /* DSP2_SYS_ENA */
4667#define WM5100_DSP2_CORE_ENA 0x0002 /* DSP2_CORE_ENA */
4668#define WM5100_DSP2_CORE_ENA_MASK 0x0002 /* DSP2_CORE_ENA */
4669#define WM5100_DSP2_CORE_ENA_SHIFT 1 /* DSP2_CORE_ENA */
4670#define WM5100_DSP2_CORE_ENA_WIDTH 1 /* DSP2_CORE_ENA */
4671#define WM5100_DSP2_START 0x0001 /* DSP2_START */
4672#define WM5100_DSP2_START_MASK 0x0001 /* DSP2_START */
4673#define WM5100_DSP2_START_SHIFT 0 /* DSP2_START */
4674#define WM5100_DSP2_START_WIDTH 1 /* DSP2_START */
4675
4676/*
4677 * R3876 (0xF24) - DSP1 Control 30
4678 */
4679#define WM5100_DSP1_RATE_MASK 0xC000 /* DSP1_RATE - [15:14] */
4680#define WM5100_DSP1_RATE_SHIFT 14 /* DSP1_RATE - [15:14] */
4681#define WM5100_DSP1_RATE_WIDTH 2 /* DSP1_RATE - [15:14] */
4682#define WM5100_DSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */
4683#define WM5100_DSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */
4684#define WM5100_DSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */
4685#define WM5100_DSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */
4686#define WM5100_DSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */
4687#define WM5100_DSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */
4688#define WM5100_DSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */
4689#define WM5100_DSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */
4690#define WM5100_DSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */
4691#define WM5100_DSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */
4692#define WM5100_DSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */
4693#define WM5100_DSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */
4694#define WM5100_DSP1_START 0x0001 /* DSP1_START */
4695#define WM5100_DSP1_START_MASK 0x0001 /* DSP1_START */
4696#define WM5100_DSP1_START_SHIFT 0 /* DSP1_START */
4697#define WM5100_DSP1_START_WIDTH 1 /* DSP1_START */
4698
4699/*
4700 * R4388 (0x1124) - DSP3 Control 30
4701 */
4702#define WM5100_DSP3_RATE_MASK 0xC000 /* DSP3_RATE - [15:14] */
4703#define WM5100_DSP3_RATE_SHIFT 14 /* DSP3_RATE - [15:14] */
4704#define WM5100_DSP3_RATE_WIDTH 2 /* DSP3_RATE - [15:14] */
4705#define WM5100_DSP3_DBG_CLK_ENA 0x0008 /* DSP3_DBG_CLK_ENA */
4706#define WM5100_DSP3_DBG_CLK_ENA_MASK 0x0008 /* DSP3_DBG_CLK_ENA */
4707#define WM5100_DSP3_DBG_CLK_ENA_SHIFT 3 /* DSP3_DBG_CLK_ENA */
4708#define WM5100_DSP3_DBG_CLK_ENA_WIDTH 1 /* DSP3_DBG_CLK_ENA */
4709#define WM5100_DSP3_SYS_ENA 0x0004 /* DSP3_SYS_ENA */
4710#define WM5100_DSP3_SYS_ENA_MASK 0x0004 /* DSP3_SYS_ENA */
4711#define WM5100_DSP3_SYS_ENA_SHIFT 2 /* DSP3_SYS_ENA */
4712#define WM5100_DSP3_SYS_ENA_WIDTH 1 /* DSP3_SYS_ENA */
4713#define WM5100_DSP3_CORE_ENA 0x0002 /* DSP3_CORE_ENA */
4714#define WM5100_DSP3_CORE_ENA_MASK 0x0002 /* DSP3_CORE_ENA */
4715#define WM5100_DSP3_CORE_ENA_SHIFT 1 /* DSP3_CORE_ENA */
4716#define WM5100_DSP3_CORE_ENA_WIDTH 1 /* DSP3_CORE_ENA */
4717#define WM5100_DSP3_START 0x0001 /* DSP3_START */
4718#define WM5100_DSP3_START_MASK 0x0001 /* DSP3_START */
4719#define WM5100_DSP3_START_SHIFT 0 /* DSP3_START */
4720#define WM5100_DSP3_START_WIDTH 1 /* DSP3_START */
4721
4722/*
4564 * R16384 (0x4000) - DSP1 DM 0 4723 * R16384 (0x4000) - DSP1 DM 0
4565 */ 4724 */
4566#define WM5100_DSP1_DM_START_1_MASK 0x00FF /* DSP1_DM_START - [7:0] */ 4725#define WM5100_DSP1_DM_START_1_MASK 0x00FF /* DSP1_DM_START - [7:0] */
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index aa12c6b6beeb..555ee146ae0d 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -71,13 +71,6 @@ struct wm8350_data {
71 int fll_freq_in; 71 int fll_freq_in;
72}; 72};
73 73
74static unsigned int wm8350_codec_cache_read(struct snd_soc_codec *codec,
75 unsigned int reg)
76{
77 struct wm8350 *wm8350 = codec->control_data;
78 return wm8350->reg_cache[reg];
79}
80
81static unsigned int wm8350_codec_read(struct snd_soc_codec *codec, 74static unsigned int wm8350_codec_read(struct snd_soc_codec *codec,
82 unsigned int reg) 75 unsigned int reg)
83{ 76{
@@ -99,7 +92,7 @@ static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec)
99{ 92{
100 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec); 93 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
101 struct wm8350_output *out1 = &wm8350_data->out1; 94 struct wm8350_output *out1 = &wm8350_data->out1;
102 struct wm8350 *wm8350 = codec->control_data; 95 struct wm8350 *wm8350 = wm8350_data->wm8350;
103 int left_complete = 0, right_complete = 0; 96 int left_complete = 0, right_complete = 0;
104 u16 reg, val; 97 u16 reg, val;
105 98
@@ -165,7 +158,7 @@ static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec)
165{ 158{
166 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec); 159 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
167 struct wm8350_output *out2 = &wm8350_data->out2; 160 struct wm8350_output *out2 = &wm8350_data->out2;
168 struct wm8350 *wm8350 = codec->control_data; 161 struct wm8350 *wm8350 = wm8350_data->wm8350;
169 int left_complete = 0, right_complete = 0; 162 int left_complete = 0, right_complete = 0;
170 u16 reg, val; 163 u16 reg, val;
171 164
@@ -360,8 +353,8 @@ static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
360 return ret; 353 return ret;
361 354
362 /* now hit the volume update bits (always bit 8) */ 355 /* now hit the volume update bits (always bit 8) */
363 val = wm8350_codec_read(codec, reg); 356 val = snd_soc_read(codec, reg);
364 wm8350_codec_write(codec, reg, val | WM8350_OUT1_VU); 357 snd_soc_write(codec, reg, val | WM8350_OUT1_VU);
365 return 1; 358 return 1;
366} 359}
367 360
@@ -781,7 +774,8 @@ static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
781 int clk_id, unsigned int freq, int dir) 774 int clk_id, unsigned int freq, int dir)
782{ 775{
783 struct snd_soc_codec *codec = codec_dai->codec; 776 struct snd_soc_codec *codec = codec_dai->codec;
784 struct wm8350 *wm8350 = codec->control_data; 777 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
778 struct wm8350 *wm8350 = wm8350_data->wm8350;
785 u16 fll_4; 779 u16 fll_4;
786 780
787 switch (clk_id) { 781 switch (clk_id) {
@@ -795,9 +789,9 @@ static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
795 case WM8350_MCLK_SEL_PLL_32K: 789 case WM8350_MCLK_SEL_PLL_32K:
796 wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_1, 790 wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_1,
797 WM8350_MCLK_SEL); 791 WM8350_MCLK_SEL);
798 fll_4 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_4) & 792 fll_4 = snd_soc_read(codec, WM8350_FLL_CONTROL_4) &
799 ~WM8350_FLL_CLK_SRC_MASK; 793 ~WM8350_FLL_CLK_SRC_MASK;
800 wm8350_codec_write(codec, WM8350_FLL_CONTROL_4, fll_4 | clk_id); 794 snd_soc_write(codec, WM8350_FLL_CONTROL_4, fll_4 | clk_id);
801 break; 795 break;
802 } 796 }
803 797
@@ -819,39 +813,39 @@ static int wm8350_set_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div)
819 813
820 switch (div_id) { 814 switch (div_id) {
821 case WM8350_ADC_CLKDIV: 815 case WM8350_ADC_CLKDIV:
822 val = wm8350_codec_read(codec, WM8350_ADC_DIVIDER) & 816 val = snd_soc_read(codec, WM8350_ADC_DIVIDER) &
823 ~WM8350_ADC_CLKDIV_MASK; 817 ~WM8350_ADC_CLKDIV_MASK;
824 wm8350_codec_write(codec, WM8350_ADC_DIVIDER, val | div); 818 snd_soc_write(codec, WM8350_ADC_DIVIDER, val | div);
825 break; 819 break;
826 case WM8350_DAC_CLKDIV: 820 case WM8350_DAC_CLKDIV:
827 val = wm8350_codec_read(codec, WM8350_DAC_CLOCK_CONTROL) & 821 val = snd_soc_read(codec, WM8350_DAC_CLOCK_CONTROL) &
828 ~WM8350_DAC_CLKDIV_MASK; 822 ~WM8350_DAC_CLKDIV_MASK;
829 wm8350_codec_write(codec, WM8350_DAC_CLOCK_CONTROL, val | div); 823 snd_soc_write(codec, WM8350_DAC_CLOCK_CONTROL, val | div);
830 break; 824 break;
831 case WM8350_BCLK_CLKDIV: 825 case WM8350_BCLK_CLKDIV:
832 val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) & 826 val = snd_soc_read(codec, WM8350_CLOCK_CONTROL_1) &
833 ~WM8350_BCLK_DIV_MASK; 827 ~WM8350_BCLK_DIV_MASK;
834 wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div); 828 snd_soc_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
835 break; 829 break;
836 case WM8350_OPCLK_CLKDIV: 830 case WM8350_OPCLK_CLKDIV:
837 val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) & 831 val = snd_soc_read(codec, WM8350_CLOCK_CONTROL_1) &
838 ~WM8350_OPCLK_DIV_MASK; 832 ~WM8350_OPCLK_DIV_MASK;
839 wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div); 833 snd_soc_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
840 break; 834 break;
841 case WM8350_SYS_CLKDIV: 835 case WM8350_SYS_CLKDIV:
842 val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) & 836 val = snd_soc_read(codec, WM8350_CLOCK_CONTROL_1) &
843 ~WM8350_MCLK_DIV_MASK; 837 ~WM8350_MCLK_DIV_MASK;
844 wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div); 838 snd_soc_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
845 break; 839 break;
846 case WM8350_DACLR_CLKDIV: 840 case WM8350_DACLR_CLKDIV:
847 val = wm8350_codec_read(codec, WM8350_DAC_LR_RATE) & 841 val = snd_soc_read(codec, WM8350_DAC_LR_RATE) &
848 ~WM8350_DACLRC_RATE_MASK; 842 ~WM8350_DACLRC_RATE_MASK;
849 wm8350_codec_write(codec, WM8350_DAC_LR_RATE, val | div); 843 snd_soc_write(codec, WM8350_DAC_LR_RATE, val | div);
850 break; 844 break;
851 case WM8350_ADCLR_CLKDIV: 845 case WM8350_ADCLR_CLKDIV:
852 val = wm8350_codec_read(codec, WM8350_ADC_LR_RATE) & 846 val = snd_soc_read(codec, WM8350_ADC_LR_RATE) &
853 ~WM8350_ADCLRC_RATE_MASK; 847 ~WM8350_ADCLRC_RATE_MASK;
854 wm8350_codec_write(codec, WM8350_ADC_LR_RATE, val | div); 848 snd_soc_write(codec, WM8350_ADC_LR_RATE, val | div);
855 break; 849 break;
856 default: 850 default:
857 return -EINVAL; 851 return -EINVAL;
@@ -863,13 +857,13 @@ static int wm8350_set_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div)
863static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) 857static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
864{ 858{
865 struct snd_soc_codec *codec = codec_dai->codec; 859 struct snd_soc_codec *codec = codec_dai->codec;
866 u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) & 860 u16 iface = snd_soc_read(codec, WM8350_AI_FORMATING) &
867 ~(WM8350_AIF_BCLK_INV | WM8350_AIF_LRCLK_INV | WM8350_AIF_FMT_MASK); 861 ~(WM8350_AIF_BCLK_INV | WM8350_AIF_LRCLK_INV | WM8350_AIF_FMT_MASK);
868 u16 master = wm8350_codec_read(codec, WM8350_AI_DAC_CONTROL) & 862 u16 master = snd_soc_read(codec, WM8350_AI_DAC_CONTROL) &
869 ~WM8350_BCLK_MSTR; 863 ~WM8350_BCLK_MSTR;
870 u16 dac_lrc = wm8350_codec_read(codec, WM8350_DAC_LR_RATE) & 864 u16 dac_lrc = snd_soc_read(codec, WM8350_DAC_LR_RATE) &
871 ~WM8350_DACLRC_ENA; 865 ~WM8350_DACLRC_ENA;
872 u16 adc_lrc = wm8350_codec_read(codec, WM8350_ADC_LR_RATE) & 866 u16 adc_lrc = snd_soc_read(codec, WM8350_ADC_LR_RATE) &
873 ~WM8350_ADCLRC_ENA; 867 ~WM8350_ADCLRC_ENA;
874 868
875 /* set master/slave audio interface */ 869 /* set master/slave audio interface */
@@ -922,42 +916,10 @@ static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
922 return -EINVAL; 916 return -EINVAL;
923 } 917 }
924 918
925 wm8350_codec_write(codec, WM8350_AI_FORMATING, iface); 919 snd_soc_write(codec, WM8350_AI_FORMATING, iface);
926 wm8350_codec_write(codec, WM8350_AI_DAC_CONTROL, master); 920 snd_soc_write(codec, WM8350_AI_DAC_CONTROL, master);
927 wm8350_codec_write(codec, WM8350_DAC_LR_RATE, dac_lrc); 921 snd_soc_write(codec, WM8350_DAC_LR_RATE, dac_lrc);
928 wm8350_codec_write(codec, WM8350_ADC_LR_RATE, adc_lrc); 922 snd_soc_write(codec, WM8350_ADC_LR_RATE, adc_lrc);
929 return 0;
930}
931
932static int wm8350_pcm_trigger(struct snd_pcm_substream *substream,
933 int cmd, struct snd_soc_dai *codec_dai)
934{
935 struct snd_soc_codec *codec = codec_dai->codec;
936 int master = wm8350_codec_cache_read(codec, WM8350_AI_DAC_CONTROL) &
937 WM8350_BCLK_MSTR;
938 int enabled = 0;
939
940 /* Check that the DACs or ADCs are enabled since they are
941 * required for LRC in master mode. The DACs or ADCs need a
942 * valid audio path i.e. pin -> ADC or DAC -> pin before
943 * the LRC will be enabled in master mode. */
944 if (!master || cmd != SNDRV_PCM_TRIGGER_START)
945 return 0;
946
947 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
948 enabled = wm8350_codec_cache_read(codec, WM8350_POWER_MGMT_4) &
949 (WM8350_ADCR_ENA | WM8350_ADCL_ENA);
950 } else {
951 enabled = wm8350_codec_cache_read(codec, WM8350_POWER_MGMT_4) &
952 (WM8350_DACR_ENA | WM8350_DACL_ENA);
953 }
954
955 if (!enabled) {
956 dev_err(codec->dev,
957 "%s: invalid audio path - no clocks available\n",
958 __func__);
959 return -EINVAL;
960 }
961 return 0; 923 return 0;
962} 924}
963 925
@@ -966,8 +928,9 @@ static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
966 struct snd_soc_dai *codec_dai) 928 struct snd_soc_dai *codec_dai)
967{ 929{
968 struct snd_soc_codec *codec = codec_dai->codec; 930 struct snd_soc_codec *codec = codec_dai->codec;
969 struct wm8350 *wm8350 = codec->control_data; 931 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
970 u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) & 932 struct wm8350 *wm8350 = wm8350_data->wm8350;
933 u16 iface = snd_soc_read(codec, WM8350_AI_FORMATING) &
971 ~WM8350_AIF_WL_MASK; 934 ~WM8350_AIF_WL_MASK;
972 935
973 /* bit size */ 936 /* bit size */
@@ -985,7 +948,7 @@ static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
985 break; 948 break;
986 } 949 }
987 950
988 wm8350_codec_write(codec, WM8350_AI_FORMATING, iface); 951 snd_soc_write(codec, WM8350_AI_FORMATING, iface);
989 952
990 /* The sloping stopband filter is recommended for use with 953 /* The sloping stopband filter is recommended for use with
991 * lower sample rates to improve performance. 954 * lower sample rates to improve performance.
@@ -1005,12 +968,15 @@ static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
1005static int wm8350_mute(struct snd_soc_dai *dai, int mute) 968static int wm8350_mute(struct snd_soc_dai *dai, int mute)
1006{ 969{
1007 struct snd_soc_codec *codec = dai->codec; 970 struct snd_soc_codec *codec = dai->codec;
1008 struct wm8350 *wm8350 = codec->control_data; 971 unsigned int val;
1009 972
1010 if (mute) 973 if (mute)
1011 wm8350_set_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA); 974 val = WM8350_DAC_MUTE_ENA;
1012 else 975 else
1013 wm8350_clear_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA); 976 val = 0;
977
978 snd_soc_update_bits(codec, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA, val);
979
1014 return 0; 980 return 0;
1015} 981}
1016 982
@@ -1079,8 +1045,8 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
1079 unsigned int freq_out) 1045 unsigned int freq_out)
1080{ 1046{
1081 struct snd_soc_codec *codec = codec_dai->codec; 1047 struct snd_soc_codec *codec = codec_dai->codec;
1082 struct wm8350 *wm8350 = codec->control_data;
1083 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); 1048 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1049 struct wm8350 *wm8350 = priv->wm8350;
1084 struct _fll_div fll_div; 1050 struct _fll_div fll_div;
1085 int ret = 0; 1051 int ret = 0;
1086 u16 fll_1, fll_4; 1052 u16 fll_1, fll_4;
@@ -1104,17 +1070,17 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
1104 fll_div.ratio); 1070 fll_div.ratio);
1105 1071
1106 /* set up N.K & dividers */ 1072 /* set up N.K & dividers */
1107 fll_1 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_1) & 1073 fll_1 = snd_soc_read(codec, WM8350_FLL_CONTROL_1) &
1108 ~(WM8350_FLL_OUTDIV_MASK | WM8350_FLL_RSP_RATE_MASK | 0xc000); 1074 ~(WM8350_FLL_OUTDIV_MASK | WM8350_FLL_RSP_RATE_MASK | 0xc000);
1109 wm8350_codec_write(codec, WM8350_FLL_CONTROL_1, 1075 snd_soc_write(codec, WM8350_FLL_CONTROL_1,
1110 fll_1 | (fll_div.div << 8) | 0x50); 1076 fll_1 | (fll_div.div << 8) | 0x50);
1111 wm8350_codec_write(codec, WM8350_FLL_CONTROL_2, 1077 snd_soc_write(codec, WM8350_FLL_CONTROL_2,
1112 (fll_div.ratio << 11) | (fll_div. 1078 (fll_div.ratio << 11) | (fll_div.
1113 n & WM8350_FLL_N_MASK)); 1079 n & WM8350_FLL_N_MASK));
1114 wm8350_codec_write(codec, WM8350_FLL_CONTROL_3, fll_div.k); 1080 snd_soc_write(codec, WM8350_FLL_CONTROL_3, fll_div.k);
1115 fll_4 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_4) & 1081 fll_4 = snd_soc_read(codec, WM8350_FLL_CONTROL_4) &
1116 ~(WM8350_FLL_FRAC | WM8350_FLL_SLOW_LOCK_REF); 1082 ~(WM8350_FLL_FRAC | WM8350_FLL_SLOW_LOCK_REF);
1117 wm8350_codec_write(codec, WM8350_FLL_CONTROL_4, 1083 snd_soc_write(codec, WM8350_FLL_CONTROL_4,
1118 fll_4 | (fll_div.k ? WM8350_FLL_FRAC : 0) | 1084 fll_4 | (fll_div.k ? WM8350_FLL_FRAC : 0) |
1119 (fll_div.ratio == 8 ? WM8350_FLL_SLOW_LOCK_REF : 0)); 1085 (fll_div.ratio == 8 ? WM8350_FLL_SLOW_LOCK_REF : 0));
1120 1086
@@ -1131,8 +1097,8 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
1131static int wm8350_set_bias_level(struct snd_soc_codec *codec, 1097static int wm8350_set_bias_level(struct snd_soc_codec *codec,
1132 enum snd_soc_bias_level level) 1098 enum snd_soc_bias_level level)
1133{ 1099{
1134 struct wm8350 *wm8350 = codec->control_data;
1135 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); 1100 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1101 struct wm8350 *wm8350 = priv->wm8350;
1136 struct wm8350_audio_platform_data *platform = 1102 struct wm8350_audio_platform_data *platform =
1137 wm8350->codec.platform_data; 1103 wm8350->codec.platform_data;
1138 u16 pm1; 1104 u16 pm1;
@@ -1339,35 +1305,36 @@ static void wm8350_hpr_work(struct work_struct *work)
1339 wm8350_hp_work(priv, &priv->hpr, WM8350_JACK_R_LVL); 1305 wm8350_hp_work(priv, &priv->hpr, WM8350_JACK_R_LVL);
1340} 1306}
1341 1307
1342static irqreturn_t wm8350_hp_jack_handler(int irq, void *data) 1308static irqreturn_t wm8350_hpl_jack_handler(int irq, void *data)
1343{ 1309{
1344 struct wm8350_data *priv = data; 1310 struct wm8350_data *priv = data;
1345 struct wm8350 *wm8350 = priv->wm8350; 1311 struct wm8350 *wm8350 = priv->wm8350;
1346 struct wm8350_jack_data *jack = NULL;
1347 1312
1348 switch (irq - wm8350->irq_base) {
1349 case WM8350_IRQ_CODEC_JCK_DET_L:
1350#ifndef CONFIG_SND_SOC_WM8350_MODULE 1313#ifndef CONFIG_SND_SOC_WM8350_MODULE
1351 trace_snd_soc_jack_irq("WM8350 HPL"); 1314 trace_snd_soc_jack_irq("WM8350 HPL");
1352#endif 1315#endif
1353 jack = &priv->hpl;
1354 break;
1355 1316
1356 case WM8350_IRQ_CODEC_JCK_DET_R: 1317 if (device_may_wakeup(wm8350->dev))
1318 pm_wakeup_event(wm8350->dev, 250);
1319
1320 schedule_delayed_work(&priv->hpl.work, 200);
1321
1322 return IRQ_HANDLED;
1323}
1324
1325static irqreturn_t wm8350_hpr_jack_handler(int irq, void *data)
1326{
1327 struct wm8350_data *priv = data;
1328 struct wm8350 *wm8350 = priv->wm8350;
1329
1357#ifndef CONFIG_SND_SOC_WM8350_MODULE 1330#ifndef CONFIG_SND_SOC_WM8350_MODULE
1358 trace_snd_soc_jack_irq("WM8350 HPR"); 1331 trace_snd_soc_jack_irq("WM8350 HPR");
1359#endif 1332#endif
1360 jack = &priv->hpr;
1361 break;
1362
1363 default:
1364 BUG();
1365 }
1366 1333
1367 if (device_may_wakeup(wm8350->dev)) 1334 if (device_may_wakeup(wm8350->dev))
1368 pm_wakeup_event(wm8350->dev, 250); 1335 pm_wakeup_event(wm8350->dev, 250);
1369 1336
1370 schedule_delayed_work(&jack->work, 200); 1337 schedule_delayed_work(&priv->hpr.work, 200);
1371 1338
1372 return IRQ_HANDLED; 1339 return IRQ_HANDLED;
1373} 1340}
@@ -1387,7 +1354,7 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
1387 struct snd_soc_jack *jack, int report) 1354 struct snd_soc_jack *jack, int report)
1388{ 1355{
1389 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); 1356 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1390 struct wm8350 *wm8350 = codec->control_data; 1357 struct wm8350 *wm8350 = priv->wm8350;
1391 int irq; 1358 int irq;
1392 int ena; 1359 int ena;
1393 1360
@@ -1418,7 +1385,14 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which,
1418 } 1385 }
1419 1386
1420 /* Sync status */ 1387 /* Sync status */
1421 wm8350_hp_jack_handler(irq + wm8350->irq_base, priv); 1388 switch (which) {
1389 case WM8350_JDL:
1390 wm8350_hpl_jack_handler(0, priv);
1391 break;
1392 case WM8350_JDR:
1393 wm8350_hpr_jack_handler(0, priv);
1394 break;
1395 }
1422 1396
1423 return 0; 1397 return 0;
1424} 1398}
@@ -1463,7 +1437,7 @@ int wm8350_mic_jack_detect(struct snd_soc_codec *codec,
1463 int detect_report, int short_report) 1437 int detect_report, int short_report)
1464{ 1438{
1465 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); 1439 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1466 struct wm8350 *wm8350 = codec->control_data; 1440 struct wm8350 *wm8350 = priv->wm8350;
1467 1441
1468 priv->mic.jack = jack; 1442 priv->mic.jack = jack;
1469 priv->mic.report = detect_report; 1443 priv->mic.report = detect_report;
@@ -1491,7 +1465,6 @@ EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect);
1491static const struct snd_soc_dai_ops wm8350_dai_ops = { 1465static const struct snd_soc_dai_ops wm8350_dai_ops = {
1492 .hw_params = wm8350_pcm_hw_params, 1466 .hw_params = wm8350_pcm_hw_params,
1493 .digital_mute = wm8350_mute, 1467 .digital_mute = wm8350_mute,
1494 .trigger = wm8350_pcm_trigger,
1495 .set_fmt = wm8350_set_dai_fmt, 1468 .set_fmt = wm8350_set_dai_fmt,
1496 .set_sysclk = wm8350_set_dai_sysclk, 1469 .set_sysclk = wm8350_set_dai_sysclk,
1497 .set_pll = wm8350_set_fll, 1470 .set_pll = wm8350_set_fll,
@@ -1559,9 +1532,9 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec)
1559 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1532 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1560 1533
1561 /* Enable robust clocking mode in ADC */ 1534 /* Enable robust clocking mode in ADC */
1562 wm8350_codec_write(codec, WM8350_SECURITY, 0xa7); 1535 snd_soc_write(codec, WM8350_SECURITY, 0xa7);
1563 wm8350_codec_write(codec, 0xde, 0x13); 1536 snd_soc_write(codec, 0xde, 0x13);
1564 wm8350_codec_write(codec, WM8350_SECURITY, 0); 1537 snd_soc_write(codec, WM8350_SECURITY, 0);
1565 1538
1566 /* read OUT1 & OUT2 volumes */ 1539 /* read OUT1 & OUT2 volumes */
1567 out1 = &priv->out1; 1540 out1 = &priv->out1;
@@ -1601,10 +1574,10 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec)
1601 WM8350_JDL_ENA | WM8350_JDR_ENA); 1574 WM8350_JDL_ENA | WM8350_JDR_ENA);
1602 1575
1603 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, 1576 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L,
1604 wm8350_hp_jack_handler, 0, "Left jack detect", 1577 wm8350_hpl_jack_handler, 0, "Left jack detect",
1605 priv); 1578 priv);
1606 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, 1579 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R,
1607 wm8350_hp_jack_handler, 0, "Right jack detect", 1580 wm8350_hpr_jack_handler, 0, "Right jack detect",
1608 priv); 1581 priv);
1609 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICSCD, 1582 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICSCD,
1610 wm8350_mic_handler, 0, "Microphone short", priv); 1583 wm8350_mic_handler, 0, "Microphone short", priv);
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 898979d23010..5dc31ebcd0e7 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -138,8 +138,8 @@ static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
138 return ret; 138 return ret;
139 139
140 /* now hit the volume update bits (always bit 8) */ 140 /* now hit the volume update bits (always bit 8) */
141 val = wm8400_read(codec, reg); 141 val = snd_soc_read(codec, reg);
142 return wm8400_write(codec, reg, val | 0x0100); 142 return snd_soc_write(codec, reg, val | 0x0100);
143} 143}
144 144
145#define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \ 145#define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \
@@ -362,8 +362,8 @@ static int inmixer_event (struct snd_soc_dapm_widget *w,
362{ 362{
363 u16 reg, fakepower; 363 u16 reg, fakepower;
364 364
365 reg = wm8400_read(w->codec, WM8400_POWER_MANAGEMENT_2); 365 reg = snd_soc_read(w->codec, WM8400_POWER_MANAGEMENT_2);
366 fakepower = wm8400_read(w->codec, WM8400_INTDRIVBITS); 366 fakepower = snd_soc_read(w->codec, WM8400_INTDRIVBITS);
367 367
368 if (fakepower & ((1 << WM8400_INMIXL_PWR) | 368 if (fakepower & ((1 << WM8400_INMIXL_PWR) |
369 (1 << WM8400_AINLMUX_PWR))) { 369 (1 << WM8400_AINLMUX_PWR))) {
@@ -378,7 +378,7 @@ static int inmixer_event (struct snd_soc_dapm_widget *w,
378 } else { 378 } else {
379 reg &= ~WM8400_AINR_ENA; 379 reg &= ~WM8400_AINR_ENA;
380 } 380 }
381 wm8400_write(w->codec, WM8400_POWER_MANAGEMENT_2, reg); 381 snd_soc_write(w->codec, WM8400_POWER_MANAGEMENT_2, reg);
382 382
383 return 0; 383 return 0;
384} 384}
@@ -394,7 +394,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
394 394
395 switch (reg_shift) { 395 switch (reg_shift) {
396 case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) : 396 case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) :
397 reg = wm8400_read(w->codec, WM8400_OUTPUT_MIXER1); 397 reg = snd_soc_read(w->codec, WM8400_OUTPUT_MIXER1);
398 if (reg & WM8400_LDLO) { 398 if (reg & WM8400_LDLO) {
399 printk(KERN_WARNING 399 printk(KERN_WARNING
400 "Cannot set as Output Mixer 1 LDLO Set\n"); 400 "Cannot set as Output Mixer 1 LDLO Set\n");
@@ -402,7 +402,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
402 } 402 }
403 break; 403 break;
404 case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8): 404 case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8):
405 reg = wm8400_read(w->codec, WM8400_OUTPUT_MIXER2); 405 reg = snd_soc_read(w->codec, WM8400_OUTPUT_MIXER2);
406 if (reg & WM8400_RDRO) { 406 if (reg & WM8400_RDRO) {
407 printk(KERN_WARNING 407 printk(KERN_WARNING
408 "Cannot set as Output Mixer 2 RDRO Set\n"); 408 "Cannot set as Output Mixer 2 RDRO Set\n");
@@ -410,7 +410,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
410 } 410 }
411 break; 411 break;
412 case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8): 412 case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8):
413 reg = wm8400_read(w->codec, WM8400_SPEAKER_MIXER); 413 reg = snd_soc_read(w->codec, WM8400_SPEAKER_MIXER);
414 if (reg & WM8400_LDSPK) { 414 if (reg & WM8400_LDSPK) {
415 printk(KERN_WARNING 415 printk(KERN_WARNING
416 "Cannot set as Speaker Mixer LDSPK Set\n"); 416 "Cannot set as Speaker Mixer LDSPK Set\n");
@@ -418,7 +418,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
418 } 418 }
419 break; 419 break;
420 case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8): 420 case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8):
421 reg = wm8400_read(w->codec, WM8400_SPEAKER_MIXER); 421 reg = snd_soc_read(w->codec, WM8400_SPEAKER_MIXER);
422 if (reg & WM8400_RDSPK) { 422 if (reg & WM8400_RDSPK) {
423 printk(KERN_WARNING 423 printk(KERN_WARNING
424 "Cannot set as Speaker Mixer RDSPK Set\n"); 424 "Cannot set as Speaker Mixer RDSPK Set\n");
@@ -1021,13 +1021,13 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1021 wm8400->fll_in = freq_in; 1021 wm8400->fll_in = freq_in;
1022 1022
1023 /* We *must* disable the FLL before any changes */ 1023 /* We *must* disable the FLL before any changes */
1024 reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_2); 1024 reg = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_2);
1025 reg &= ~WM8400_FLL_ENA; 1025 reg &= ~WM8400_FLL_ENA;
1026 wm8400_write(codec, WM8400_POWER_MANAGEMENT_2, reg); 1026 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_2, reg);
1027 1027
1028 reg = wm8400_read(codec, WM8400_FLL_CONTROL_1); 1028 reg = snd_soc_read(codec, WM8400_FLL_CONTROL_1);
1029 reg &= ~WM8400_FLL_OSC_ENA; 1029 reg &= ~WM8400_FLL_OSC_ENA;
1030 wm8400_write(codec, WM8400_FLL_CONTROL_1, reg); 1030 snd_soc_write(codec, WM8400_FLL_CONTROL_1, reg);
1031 1031
1032 if (!freq_out) 1032 if (!freq_out)
1033 return 0; 1033 return 0;
@@ -1035,15 +1035,15 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1035 reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK); 1035 reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK);
1036 reg |= WM8400_FLL_FRAC | factors.fratio; 1036 reg |= WM8400_FLL_FRAC | factors.fratio;
1037 reg |= factors.freq_ref << WM8400_FLL_REF_FREQ_SHIFT; 1037 reg |= factors.freq_ref << WM8400_FLL_REF_FREQ_SHIFT;
1038 wm8400_write(codec, WM8400_FLL_CONTROL_1, reg); 1038 snd_soc_write(codec, WM8400_FLL_CONTROL_1, reg);
1039 1039
1040 wm8400_write(codec, WM8400_FLL_CONTROL_2, factors.k); 1040 snd_soc_write(codec, WM8400_FLL_CONTROL_2, factors.k);
1041 wm8400_write(codec, WM8400_FLL_CONTROL_3, factors.n); 1041 snd_soc_write(codec, WM8400_FLL_CONTROL_3, factors.n);
1042 1042
1043 reg = wm8400_read(codec, WM8400_FLL_CONTROL_4); 1043 reg = snd_soc_read(codec, WM8400_FLL_CONTROL_4);
1044 reg &= ~WM8400_FLL_OUTDIV_MASK; 1044 reg &= ~WM8400_FLL_OUTDIV_MASK;
1045 reg |= factors.outdiv; 1045 reg |= factors.outdiv;
1046 wm8400_write(codec, WM8400_FLL_CONTROL_4, reg); 1046 snd_soc_write(codec, WM8400_FLL_CONTROL_4, reg);
1047 1047
1048 return 0; 1048 return 0;
1049} 1049}
@@ -1057,8 +1057,8 @@ static int wm8400_set_dai_fmt(struct snd_soc_dai *codec_dai,
1057 struct snd_soc_codec *codec = codec_dai->codec; 1057 struct snd_soc_codec *codec = codec_dai->codec;
1058 u16 audio1, audio3; 1058 u16 audio1, audio3;
1059 1059
1060 audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1); 1060 audio1 = snd_soc_read(codec, WM8400_AUDIO_INTERFACE_1);
1061 audio3 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_3); 1061 audio3 = snd_soc_read(codec, WM8400_AUDIO_INTERFACE_3);
1062 1062
1063 /* set master/slave audio interface */ 1063 /* set master/slave audio interface */
1064 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1064 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1099,8 +1099,8 @@ static int wm8400_set_dai_fmt(struct snd_soc_dai *codec_dai,
1099 return -EINVAL; 1099 return -EINVAL;
1100 } 1100 }
1101 1101
1102 wm8400_write(codec, WM8400_AUDIO_INTERFACE_1, audio1); 1102 snd_soc_write(codec, WM8400_AUDIO_INTERFACE_1, audio1);
1103 wm8400_write(codec, WM8400_AUDIO_INTERFACE_3, audio3); 1103 snd_soc_write(codec, WM8400_AUDIO_INTERFACE_3, audio3);
1104 return 0; 1104 return 0;
1105} 1105}
1106 1106
@@ -1112,24 +1112,24 @@ static int wm8400_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1112 1112
1113 switch (div_id) { 1113 switch (div_id) {
1114 case WM8400_MCLK_DIV: 1114 case WM8400_MCLK_DIV:
1115 reg = wm8400_read(codec, WM8400_CLOCKING_2) & 1115 reg = snd_soc_read(codec, WM8400_CLOCKING_2) &
1116 ~WM8400_MCLK_DIV_MASK; 1116 ~WM8400_MCLK_DIV_MASK;
1117 wm8400_write(codec, WM8400_CLOCKING_2, reg | div); 1117 snd_soc_write(codec, WM8400_CLOCKING_2, reg | div);
1118 break; 1118 break;
1119 case WM8400_DACCLK_DIV: 1119 case WM8400_DACCLK_DIV:
1120 reg = wm8400_read(codec, WM8400_CLOCKING_2) & 1120 reg = snd_soc_read(codec, WM8400_CLOCKING_2) &
1121 ~WM8400_DAC_CLKDIV_MASK; 1121 ~WM8400_DAC_CLKDIV_MASK;
1122 wm8400_write(codec, WM8400_CLOCKING_2, reg | div); 1122 snd_soc_write(codec, WM8400_CLOCKING_2, reg | div);
1123 break; 1123 break;
1124 case WM8400_ADCCLK_DIV: 1124 case WM8400_ADCCLK_DIV:
1125 reg = wm8400_read(codec, WM8400_CLOCKING_2) & 1125 reg = snd_soc_read(codec, WM8400_CLOCKING_2) &
1126 ~WM8400_ADC_CLKDIV_MASK; 1126 ~WM8400_ADC_CLKDIV_MASK;
1127 wm8400_write(codec, WM8400_CLOCKING_2, reg | div); 1127 snd_soc_write(codec, WM8400_CLOCKING_2, reg | div);
1128 break; 1128 break;
1129 case WM8400_BCLK_DIV: 1129 case WM8400_BCLK_DIV:
1130 reg = wm8400_read(codec, WM8400_CLOCKING_1) & 1130 reg = snd_soc_read(codec, WM8400_CLOCKING_1) &
1131 ~WM8400_BCLK_DIV_MASK; 1131 ~WM8400_BCLK_DIV_MASK;
1132 wm8400_write(codec, WM8400_CLOCKING_1, reg | div); 1132 snd_soc_write(codec, WM8400_CLOCKING_1, reg | div);
1133 break; 1133 break;
1134 default: 1134 default:
1135 return -EINVAL; 1135 return -EINVAL;
@@ -1145,9 +1145,8 @@ static int wm8400_hw_params(struct snd_pcm_substream *substream,
1145 struct snd_pcm_hw_params *params, 1145 struct snd_pcm_hw_params *params,
1146 struct snd_soc_dai *dai) 1146 struct snd_soc_dai *dai)
1147{ 1147{
1148 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1148 struct snd_soc_codec *codec = dai->codec;
1149 struct snd_soc_codec *codec = rtd->codec; 1149 u16 audio1 = snd_soc_read(codec, WM8400_AUDIO_INTERFACE_1);
1150 u16 audio1 = wm8400_read(codec, WM8400_AUDIO_INTERFACE_1);
1151 1150
1152 audio1 &= ~WM8400_AIF_WL_MASK; 1151 audio1 &= ~WM8400_AIF_WL_MASK;
1153 /* bit size */ 1152 /* bit size */
@@ -1165,19 +1164,19 @@ static int wm8400_hw_params(struct snd_pcm_substream *substream,
1165 break; 1164 break;
1166 } 1165 }
1167 1166
1168 wm8400_write(codec, WM8400_AUDIO_INTERFACE_1, audio1); 1167 snd_soc_write(codec, WM8400_AUDIO_INTERFACE_1, audio1);
1169 return 0; 1168 return 0;
1170} 1169}
1171 1170
1172static int wm8400_mute(struct snd_soc_dai *dai, int mute) 1171static int wm8400_mute(struct snd_soc_dai *dai, int mute)
1173{ 1172{
1174 struct snd_soc_codec *codec = dai->codec; 1173 struct snd_soc_codec *codec = dai->codec;
1175 u16 val = wm8400_read(codec, WM8400_DAC_CTRL) & ~WM8400_DAC_MUTE; 1174 u16 val = snd_soc_read(codec, WM8400_DAC_CTRL) & ~WM8400_DAC_MUTE;
1176 1175
1177 if (mute) 1176 if (mute)
1178 wm8400_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE); 1177 snd_soc_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
1179 else 1178 else
1180 wm8400_write(codec, WM8400_DAC_CTRL, val); 1179 snd_soc_write(codec, WM8400_DAC_CTRL, val);
1181 1180
1182 return 0; 1181 return 0;
1183} 1182}
@@ -1196,9 +1195,9 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
1196 1195
1197 case SND_SOC_BIAS_PREPARE: 1196 case SND_SOC_BIAS_PREPARE:
1198 /* VMID=2*50k */ 1197 /* VMID=2*50k */
1199 val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1) & 1198 val = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1) &
1200 ~WM8400_VMID_MODE_MASK; 1199 ~WM8400_VMID_MODE_MASK;
1201 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x2); 1200 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x2);
1202 break; 1201 break;
1203 1202
1204 case SND_SOC_BIAS_STANDBY: 1203 case SND_SOC_BIAS_STANDBY:
@@ -1212,74 +1211,74 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
1212 return ret; 1211 return ret;
1213 } 1212 }
1214 1213
1215 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, 1214 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1,
1216 WM8400_CODEC_ENA | WM8400_SYSCLK_ENA); 1215 WM8400_CODEC_ENA | WM8400_SYSCLK_ENA);
1217 1216
1218 /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */ 1217 /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
1219 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST | 1218 snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
1220 WM8400_BUFDCOPEN | WM8400_POBCTRL); 1219 WM8400_BUFDCOPEN | WM8400_POBCTRL);
1221 1220
1222 msleep(50); 1221 msleep(50);
1223 1222
1224 /* Enable VREF & VMID at 2x50k */ 1223 /* Enable VREF & VMID at 2x50k */
1225 val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1); 1224 val = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1);
1226 val |= 0x2 | WM8400_VREF_ENA; 1225 val |= 0x2 | WM8400_VREF_ENA;
1227 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val); 1226 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val);
1228 1227
1229 /* Enable BUFIOEN */ 1228 /* Enable BUFIOEN */
1230 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST | 1229 snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
1231 WM8400_BUFDCOPEN | WM8400_POBCTRL | 1230 WM8400_BUFDCOPEN | WM8400_POBCTRL |
1232 WM8400_BUFIOEN); 1231 WM8400_BUFIOEN);
1233 1232
1234 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ 1233 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1235 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_BUFIOEN); 1234 snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_BUFIOEN);
1236 } 1235 }
1237 1236
1238 /* VMID=2*300k */ 1237 /* VMID=2*300k */
1239 val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1) & 1238 val = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1) &
1240 ~WM8400_VMID_MODE_MASK; 1239 ~WM8400_VMID_MODE_MASK;
1241 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x4); 1240 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val | 0x4);
1242 break; 1241 break;
1243 1242
1244 case SND_SOC_BIAS_OFF: 1243 case SND_SOC_BIAS_OFF:
1245 /* Enable POBCTRL and SOFT_ST */ 1244 /* Enable POBCTRL and SOFT_ST */
1246 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST | 1245 snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
1247 WM8400_POBCTRL | WM8400_BUFIOEN); 1246 WM8400_POBCTRL | WM8400_BUFIOEN);
1248 1247
1249 /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */ 1248 /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
1250 wm8400_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST | 1249 snd_soc_write(codec, WM8400_ANTIPOP2, WM8400_SOFTST |
1251 WM8400_BUFDCOPEN | WM8400_POBCTRL | 1250 WM8400_BUFDCOPEN | WM8400_POBCTRL |
1252 WM8400_BUFIOEN); 1251 WM8400_BUFIOEN);
1253 1252
1254 /* mute DAC */ 1253 /* mute DAC */
1255 val = wm8400_read(codec, WM8400_DAC_CTRL); 1254 val = snd_soc_read(codec, WM8400_DAC_CTRL);
1256 wm8400_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE); 1255 snd_soc_write(codec, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
1257 1256
1258 /* Enable any disabled outputs */ 1257 /* Enable any disabled outputs */
1259 val = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1); 1258 val = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1);
1260 val |= WM8400_SPK_ENA | WM8400_OUT3_ENA | 1259 val |= WM8400_SPK_ENA | WM8400_OUT3_ENA |
1261 WM8400_OUT4_ENA | WM8400_LOUT_ENA | 1260 WM8400_OUT4_ENA | WM8400_LOUT_ENA |
1262 WM8400_ROUT_ENA; 1261 WM8400_ROUT_ENA;
1263 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val); 1262 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val);
1264 1263
1265 /* Disable VMID */ 1264 /* Disable VMID */
1266 val &= ~WM8400_VMID_MODE_MASK; 1265 val &= ~WM8400_VMID_MODE_MASK;
1267 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val); 1266 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val);
1268 1267
1269 msleep(300); 1268 msleep(300);
1270 1269
1271 /* Enable all output discharge bits */ 1270 /* Enable all output discharge bits */
1272 wm8400_write(codec, WM8400_ANTIPOP1, WM8400_DIS_LLINE | 1271 snd_soc_write(codec, WM8400_ANTIPOP1, WM8400_DIS_LLINE |
1273 WM8400_DIS_RLINE | WM8400_DIS_OUT3 | 1272 WM8400_DIS_RLINE | WM8400_DIS_OUT3 |
1274 WM8400_DIS_OUT4 | WM8400_DIS_LOUT | 1273 WM8400_DIS_OUT4 | WM8400_DIS_LOUT |
1275 WM8400_DIS_ROUT); 1274 WM8400_DIS_ROUT);
1276 1275
1277 /* Disable VREF */ 1276 /* Disable VREF */
1278 val &= ~WM8400_VREF_ENA; 1277 val &= ~WM8400_VREF_ENA;
1279 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, val); 1278 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, val);
1280 1279
1281 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ 1280 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1282 wm8400_write(codec, WM8400_ANTIPOP2, 0x0); 1281 snd_soc_write(codec, WM8400_ANTIPOP2, 0x0);
1283 1282
1284 ret = regulator_bulk_disable(ARRAY_SIZE(power), 1283 ret = regulator_bulk_disable(ARRAY_SIZE(power),
1285 &power[0]); 1284 &power[0]);
@@ -1385,19 +1384,19 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec)
1385 1384
1386 wm8400_codec_reset(codec); 1385 wm8400_codec_reset(codec);
1387 1386
1388 reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1); 1387 reg = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1);
1389 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, reg | WM8400_CODEC_ENA); 1388 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1, reg | WM8400_CODEC_ENA);
1390 1389
1391 /* Latch volume update bits */ 1390 /* Latch volume update bits */
1392 reg = wm8400_read(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME); 1391 reg = snd_soc_read(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME);
1393 wm8400_write(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME, 1392 snd_soc_write(codec, WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
1394 reg & WM8400_IPVU); 1393 reg & WM8400_IPVU);
1395 reg = wm8400_read(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME); 1394 reg = snd_soc_read(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME);
1396 wm8400_write(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME, 1395 snd_soc_write(codec, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
1397 reg & WM8400_IPVU); 1396 reg & WM8400_IPVU);
1398 1397
1399 wm8400_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1398 snd_soc_write(codec, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1400 wm8400_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1399 snd_soc_write(codec, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1401 1400
1402 if (!schedule_work(&priv->work)) { 1401 if (!schedule_work(&priv->work)) {
1403 ret = -EINVAL; 1402 ret = -EINVAL;
@@ -1414,8 +1413,8 @@ static int wm8400_codec_remove(struct snd_soc_codec *codec)
1414{ 1413{
1415 u16 reg; 1414 u16 reg;
1416 1415
1417 reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1); 1416 reg = snd_soc_read(codec, WM8400_POWER_MANAGEMENT_1);
1418 wm8400_write(codec, WM8400_POWER_MANAGEMENT_1, 1417 snd_soc_write(codec, WM8400_POWER_MANAGEMENT_1,
1419 reg & (~WM8400_CODEC_ENA)); 1418 reg & (~WM8400_CODEC_ENA));
1420 1419
1421 regulator_bulk_free(ARRAY_SIZE(power), power); 1420 regulator_bulk_free(ARRAY_SIZE(power), power);
@@ -1428,7 +1427,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8400 = {
1428 .remove = wm8400_codec_remove, 1427 .remove = wm8400_codec_remove,
1429 .suspend = wm8400_suspend, 1428 .suspend = wm8400_suspend,
1430 .resume = wm8400_resume, 1429 .resume = wm8400_resume,
1431 .read = wm8400_read, 1430 .read = snd_soc_read,
1432 .write = wm8400_write, 1431 .write = wm8400_write,
1433 .set_bias_level = wm8400_set_bias_level, 1432 .set_bias_level = wm8400_set_bias_level,
1434 1433
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 9166126bd312..56a049555e2c 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -392,8 +392,7 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
392 struct snd_pcm_hw_params *params, 392 struct snd_pcm_hw_params *params,
393 struct snd_soc_dai *dai) 393 struct snd_soc_dai *dai)
394{ 394{
395 struct snd_soc_pcm_runtime *rtd = substream->private_data; 395 struct snd_soc_codec *codec = dai->codec;
396 struct snd_soc_codec *codec = rtd->codec;
397 u16 iface = snd_soc_read(codec, WM8510_IFACE) & 0x19f; 396 u16 iface = snd_soc_read(codec, WM8510_IFACE) & 0x19f;
398 u16 adn = snd_soc_read(codec, WM8510_ADD) & 0x1f1; 397 u16 adn = snd_soc_read(codec, WM8510_ADD) & 0x1f1;
399 398
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 7fea2c3bf7e7..1c3ffb290cdc 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -145,8 +145,7 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
145 struct snd_pcm_hw_params *params, 145 struct snd_pcm_hw_params *params,
146 struct snd_soc_dai *dai) 146 struct snd_soc_dai *dai)
147{ 147{
148 struct snd_soc_pcm_runtime *rtd = substream->private_data; 148 struct snd_soc_codec *codec = dai->codec;
149 struct snd_soc_codec *codec = rtd->codec;
150 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); 149 struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
151 int i; 150 int i;
152 u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1); 151 u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index fc3d59e49084..1467f97dce21 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -88,8 +88,7 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream,
88 struct snd_pcm_hw_params *params, 88 struct snd_pcm_hw_params *params,
89 struct snd_soc_dai *dai) 89 struct snd_soc_dai *dai)
90{ 90{
91 struct snd_soc_pcm_runtime *rtd = substream->private_data; 91 struct snd_soc_codec *codec = dai->codec;
92 struct snd_soc_codec *codec = rtd->codec;
93 u16 dac = snd_soc_read(codec, WM8728_DACCTL); 92 u16 dac = snd_soc_read(codec, WM8728_DACCTL);
94 93
95 dac &= ~0x18; 94 dac &= ~0x18;
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index a32caa72bd7d..9d1b9b0271f1 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -635,16 +635,17 @@ static int __devinit wm8731_spi_probe(struct spi_device *spi)
635 struct wm8731_priv *wm8731; 635 struct wm8731_priv *wm8731;
636 int ret; 636 int ret;
637 637
638 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); 638 wm8731 = devm_kzalloc(&spi->dev, sizeof(struct wm8731_priv),
639 GFP_KERNEL);
639 if (wm8731 == NULL) 640 if (wm8731 == NULL)
640 return -ENOMEM; 641 return -ENOMEM;
641 642
642 wm8731->regmap = regmap_init_spi(spi, &wm8731_regmap); 643 wm8731->regmap = devm_regmap_init_spi(spi, &wm8731_regmap);
643 if (IS_ERR(wm8731->regmap)) { 644 if (IS_ERR(wm8731->regmap)) {
644 ret = PTR_ERR(wm8731->regmap); 645 ret = PTR_ERR(wm8731->regmap);
645 dev_err(&spi->dev, "Failed to allocate register map: %d\n", 646 dev_err(&spi->dev, "Failed to allocate register map: %d\n",
646 ret); 647 ret);
647 goto err; 648 return ret;
648 } 649 }
649 650
650 spi_set_drvdata(spi, wm8731); 651 spi_set_drvdata(spi, wm8731);
@@ -653,25 +654,15 @@ static int __devinit wm8731_spi_probe(struct spi_device *spi)
653 &soc_codec_dev_wm8731, &wm8731_dai, 1); 654 &soc_codec_dev_wm8731, &wm8731_dai, 1);
654 if (ret != 0) { 655 if (ret != 0) {
655 dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret); 656 dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret);
656 goto err_regmap; 657 return ret;
657 } 658 }
658 659
659 return 0; 660 return 0;
660
661err_regmap:
662 regmap_exit(wm8731->regmap);
663err:
664 kfree(wm8731);
665 return ret;
666} 661}
667 662
668static int __devexit wm8731_spi_remove(struct spi_device *spi) 663static int __devexit wm8731_spi_remove(struct spi_device *spi)
669{ 664{
670 struct wm8731_priv *wm8731 = spi_get_drvdata(spi);
671
672 snd_soc_unregister_codec(&spi->dev); 665 snd_soc_unregister_codec(&spi->dev);
673 regmap_exit(wm8731->regmap);
674 kfree(wm8731);
675 return 0; 666 return 0;
676} 667}
677 668
@@ -693,16 +684,17 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
693 struct wm8731_priv *wm8731; 684 struct wm8731_priv *wm8731;
694 int ret; 685 int ret;
695 686
696 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); 687 wm8731 = devm_kzalloc(&i2c->dev, sizeof(struct wm8731_priv),
688 GFP_KERNEL);
697 if (wm8731 == NULL) 689 if (wm8731 == NULL)
698 return -ENOMEM; 690 return -ENOMEM;
699 691
700 wm8731->regmap = regmap_init_i2c(i2c, &wm8731_regmap); 692 wm8731->regmap = devm_regmap_init_i2c(i2c, &wm8731_regmap);
701 if (IS_ERR(wm8731->regmap)) { 693 if (IS_ERR(wm8731->regmap)) {
702 ret = PTR_ERR(wm8731->regmap); 694 ret = PTR_ERR(wm8731->regmap);
703 dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 695 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
704 ret); 696 ret);
705 goto err; 697 return ret;
706 } 698 }
707 699
708 i2c_set_clientdata(i2c, wm8731); 700 i2c_set_clientdata(i2c, wm8731);
@@ -711,24 +703,15 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
711 &soc_codec_dev_wm8731, &wm8731_dai, 1); 703 &soc_codec_dev_wm8731, &wm8731_dai, 1);
712 if (ret != 0) { 704 if (ret != 0) {
713 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); 705 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
714 goto err_regmap; 706 return ret;
715 } 707 }
716 708
717 return 0; 709 return 0;
718
719err_regmap:
720 regmap_exit(wm8731->regmap);
721err:
722 kfree(wm8731);
723 return ret;
724} 710}
725 711
726static __devexit int wm8731_i2c_remove(struct i2c_client *client) 712static __devexit int wm8731_i2c_remove(struct i2c_client *client)
727{ 713{
728 struct wm8731_priv *wm8731 = i2c_get_clientdata(client);
729 snd_soc_unregister_codec(&client->dev); 714 snd_soc_unregister_codec(&client->dev);
730 regmap_exit(wm8731->regmap);
731 kfree(wm8731);
732 return 0; 715 return 0;
733} 716}
734 717
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index 4fe9d191e277..d0520124616d 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -329,8 +329,7 @@ static int wm8737_hw_params(struct snd_pcm_substream *substream,
329 struct snd_pcm_hw_params *params, 329 struct snd_pcm_hw_params *params,
330 struct snd_soc_dai *dai) 330 struct snd_soc_dai *dai)
331{ 331{
332 struct snd_soc_pcm_runtime *rtd = substream->private_data; 332 struct snd_soc_codec *codec = dai->codec;
333 struct snd_soc_codec *codec = rtd->codec;
334 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); 333 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
335 int i; 334 int i;
336 u16 clocking = 0; 335 u16 clocking = 0;
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 3941f50bf187..6e849cb04243 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -203,8 +203,7 @@ static int wm8741_hw_params(struct snd_pcm_substream *substream,
203 struct snd_pcm_hw_params *params, 203 struct snd_pcm_hw_params *params,
204 struct snd_soc_dai *dai) 204 struct snd_soc_dai *dai)
205{ 205{
206 struct snd_soc_pcm_runtime *rtd = substream->private_data; 206 struct snd_soc_codec *codec = dai->codec;
207 struct snd_soc_codec *codec = rtd->codec;
208 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); 207 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
209 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC; 208 u16 iface = snd_soc_read(codec, WM8741_FORMAT_CONTROL) & 0x1FC;
210 int i; 209 int i;
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index e4c50ce7d9c0..89151ca5e776 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -547,8 +547,7 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
547 struct snd_pcm_hw_params *params, 547 struct snd_pcm_hw_params *params,
548 struct snd_soc_dai *dai) 548 struct snd_soc_dai *dai)
549{ 549{
550 struct snd_soc_pcm_runtime *rtd = substream->private_data; 550 struct snd_soc_codec *codec = dai->codec;
551 struct snd_soc_codec *codec = rtd->codec;
552 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec); 551 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
553 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3; 552 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3;
554 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0; 553 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0;
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index e27e7b62b365..a26482cd7654 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -931,8 +931,7 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
931 struct snd_pcm_hw_params *params, 931 struct snd_pcm_hw_params *params,
932 struct snd_soc_dai *dai) 932 struct snd_soc_dai *dai)
933{ 933{
934 struct snd_soc_pcm_runtime *rtd = substream->private_data; 934 struct snd_soc_codec *codec = dai->codec;
935 struct snd_soc_codec *codec = rtd->codec;
936 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 935 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
937 u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3; 936 u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3;
938 u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f; 937 u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f;
@@ -1161,8 +1160,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1161 struct snd_pcm_hw_params *params, 1160 struct snd_pcm_hw_params *params,
1162 struct snd_soc_dai *dai) 1161 struct snd_soc_dai *dai)
1163{ 1162{
1164 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1163 struct snd_soc_codec *codec = dai->codec;
1165 struct snd_soc_codec *codec = rtd->codec;
1166 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 1164 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1167 u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0; 1165 u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0;
1168 u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3; 1166 u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3;
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index f18c554efc98..077c9628c70d 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -610,8 +610,7 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream,
610 struct snd_pcm_hw_params *params, 610 struct snd_pcm_hw_params *params,
611 struct snd_soc_dai *dai) 611 struct snd_soc_dai *dai)
612{ 612{
613 struct snd_soc_pcm_runtime *rtd = substream->private_data; 613 struct snd_soc_codec *codec = dai->codec;
614 struct snd_soc_codec *codec = rtd->codec;
615 u16 reg; 614 u16 reg;
616 615
617 reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60; 616 reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60;
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index c91fb2f99c13..86b8a2926591 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -1432,8 +1432,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1432 struct snd_pcm_hw_params *params, 1432 struct snd_pcm_hw_params *params,
1433 struct snd_soc_dai *dai) 1433 struct snd_soc_dai *dai)
1434{ 1434{
1435 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1435 struct snd_soc_codec *codec = dai->codec;
1436 struct snd_soc_codec *codec =rtd->codec;
1437 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 1436 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1438 int fs = params_rate(params); 1437 int fs = params_rate(params);
1439 int bclk; 1438 int bclk;
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index d2883affea3b..481a3d9cfe48 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -371,8 +371,7 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
371 struct snd_pcm_hw_params *params, 371 struct snd_pcm_hw_params *params,
372 struct snd_soc_dai *dai) 372 struct snd_soc_dai *dai)
373{ 373{
374 struct snd_soc_pcm_runtime *rtd = substream->private_data; 374 struct snd_soc_codec *codec = dai->codec;
375 struct snd_soc_codec *codec = rtd->codec;
376 u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFD9F; 375 u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFD9F;
377 u16 addcntrl = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFF1; 376 u16 addcntrl = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFF1;
378 u16 companding = snd_soc_read(codec, 377 u16 companding = snd_soc_read(codec,
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 840d72086d04..8bc659d8dd2e 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -505,8 +505,7 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
505 struct snd_pcm_hw_params *params, 505 struct snd_pcm_hw_params *params,
506 struct snd_soc_dai *dai) 506 struct snd_soc_dai *dai)
507{ 507{
508 struct snd_soc_pcm_runtime *rtd = substream->private_data; 508 struct snd_soc_codec *codec = dai->codec;
509 struct snd_soc_codec *codec = rtd->codec;
510 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 509 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
511 u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3; 510 u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3;
512 int i; 511 int i;
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 15d467ff91b4..0cfce9999c89 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -1478,7 +1478,8 @@ static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
1478 1478
1479static int wm8962_dsp2_write_config(struct snd_soc_codec *codec) 1479static int wm8962_dsp2_write_config(struct snd_soc_codec *codec)
1480{ 1480{
1481 return 0; 1481 return regcache_sync_region(codec->control_data,
1482 WM8962_HDBASS_AI_1, WM8962_MAX_REGISTER);
1482} 1483}
1483 1484
1484static int wm8962_dsp2_set_enable(struct snd_soc_codec *codec, u16 val) 1485static int wm8962_dsp2_set_enable(struct snd_soc_codec *codec, u16 val)
@@ -1755,10 +1756,22 @@ SOC_DOUBLE_R_TLV("EQ4 Volume", WM8962_EQ3, WM8962_EQ23,
1755SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23, 1756SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23,
1756 WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv), 1757 WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv),
1757 1758
1759SOC_SINGLE("3D Switch", WM8962_THREED1, 0, 1, 0),
1760SND_SOC_BYTES_MASK("3D Coefficients", WM8962_THREED1, 4, WM8962_THREED_ENA),
1761
1762SOC_SINGLE("DF1 Switch", WM8962_DF1, 0, 1, 0),
1763SND_SOC_BYTES_MASK("DF1 Coefficients", WM8962_DF1, 7, WM8962_DF1_ENA),
1764
1765SOC_SINGLE("DRC Switch", WM8962_DRC_1, 0, 1, 0),
1766SND_SOC_BYTES_MASK("DRC Coefficients", WM8962_DRC_1, 5, WM8962_DRC_ENA),
1767
1758WM8962_DSP2_ENABLE("VSS Switch", WM8962_VSS_ENA_SHIFT), 1768WM8962_DSP2_ENABLE("VSS Switch", WM8962_VSS_ENA_SHIFT),
1769SND_SOC_BYTES("VSS Coefficients", WM8962_VSS_XHD2_1, 148),
1759WM8962_DSP2_ENABLE("HPF1 Switch", WM8962_HPF1_ENA_SHIFT), 1770WM8962_DSP2_ENABLE("HPF1 Switch", WM8962_HPF1_ENA_SHIFT),
1760WM8962_DSP2_ENABLE("HPF2 Switch", WM8962_HPF2_ENA_SHIFT), 1771WM8962_DSP2_ENABLE("HPF2 Switch", WM8962_HPF2_ENA_SHIFT),
1772SND_SOC_BYTES("HPF Coefficients", WM8962_LHPF2, 1),
1761WM8962_DSP2_ENABLE("HD Bass Switch", WM8962_HDBASS_ENA_SHIFT), 1773WM8962_DSP2_ENABLE("HD Bass Switch", WM8962_HDBASS_ENA_SHIFT),
1774SND_SOC_BYTES("HD Bass Coefficients", WM8962_HDBASS_AI_1, 30),
1762}; 1775};
1763 1776
1764static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = { 1777static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = {
@@ -2519,8 +2532,7 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
2519 struct snd_pcm_hw_params *params, 2532 struct snd_pcm_hw_params *params,
2520 struct snd_soc_dai *dai) 2533 struct snd_soc_dai *dai)
2521{ 2534{
2522 struct snd_soc_pcm_runtime *rtd = substream->private_data; 2535 struct snd_soc_codec *codec = dai->codec;
2523 struct snd_soc_codec *codec = rtd->codec;
2524 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 2536 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2525 int i; 2537 int i;
2526 int aif0 = 0; 2538 int aif0 = 0;
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 28fe59e3ce01..eef783f6b6d6 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -478,8 +478,7 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
478 struct snd_pcm_hw_params *params, 478 struct snd_pcm_hw_params *params,
479 struct snd_soc_dai *dai) 479 struct snd_soc_dai *dai)
480{ 480{
481 struct snd_soc_pcm_runtime *rtd = substream->private_data; 481 struct snd_soc_codec *codec = dai->codec;
482 struct snd_soc_codec *codec = rtd->codec;
483 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec); 482 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
484 u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3; 483 u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3;
485 u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0; 484 u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0;
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 72d5fdcd3cc2..a5be3adecf75 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -723,8 +723,7 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream,
723 struct snd_pcm_hw_params *params, 723 struct snd_pcm_hw_params *params,
724 struct snd_soc_dai *dai) 724 struct snd_soc_dai *dai)
725{ 725{
726 struct snd_soc_pcm_runtime *rtd = substream->private_data; 726 struct snd_soc_codec *codec = dai->codec;
727 struct snd_soc_codec *codec = rtd->codec;
728 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec); 727 struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec);
729 /* Word length mask = 0x60 */ 728 /* Word length mask = 0x60 */
730 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60; 729 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60;
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 6cdf6a2bc283..1d4c5cf47b06 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -668,8 +668,7 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
668 struct snd_pcm_hw_params *params, 668 struct snd_pcm_hw_params *params,
669 struct snd_soc_dai *dai) 669 struct snd_soc_dai *dai)
670{ 670{
671 struct snd_soc_pcm_runtime *rtd = substream->private_data; 671 struct snd_soc_codec *codec = dai->codec;
672 struct snd_soc_codec *codec = rtd->codec;
673 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); 672 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
674 u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3; 673 u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3;
675 u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180; 674 u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180;
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 9d242351e6e8..db63c97ddf51 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -1112,8 +1112,7 @@ static int wm8990_hw_params(struct snd_pcm_substream *substream,
1112 struct snd_pcm_hw_params *params, 1112 struct snd_pcm_hw_params *params,
1113 struct snd_soc_dai *dai) 1113 struct snd_soc_dai *dai)
1114{ 1114{
1115 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1115 struct snd_soc_codec *codec = dai->codec;
1116 struct snd_soc_codec *codec = rtd->codec;
1117 u16 audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1); 1116 u16 audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1);
1118 1117
1119 audio1 &= ~WM8990_AIF_WL_MASK; 1118 audio1 &= ~WM8990_AIF_WL_MASK;
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index d256a9340644..36acfccab999 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -218,7 +218,6 @@ struct wm8993_priv {
218 unsigned int sysclk_rate; 218 unsigned int sysclk_rate;
219 unsigned int fs; 219 unsigned int fs;
220 unsigned int bclk; 220 unsigned int bclk;
221 int class_w_users;
222 unsigned int fll_fref; 221 unsigned int fll_fref;
223 unsigned int fll_fout; 222 unsigned int fll_fout;
224 int fll_src; 223 int fll_src;
@@ -824,84 +823,6 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
824 return 0; 823 return 0;
825} 824}
826 825
827/*
828 * When used with DAC outputs only the WM8993 charge pump supports
829 * operation in class W mode, providing very low power consumption
830 * when used with digital sources. Enable and disable this mode
831 * automatically depending on the mixer configuration.
832 *
833 * Currently the only supported paths are the direct DAC->headphone
834 * paths (which provide minimum power consumption anyway).
835 */
836static int class_w_put(struct snd_kcontrol *kcontrol,
837 struct snd_ctl_elem_value *ucontrol)
838{
839 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
840 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
841 struct snd_soc_codec *codec = widget->codec;
842 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
843 int ret;
844
845 /* Turn it off if we're using the main output mixer */
846 if (ucontrol->value.integer.value[0] == 0) {
847 if (wm8993->class_w_users == 0) {
848 dev_dbg(codec->dev, "Disabling Class W\n");
849 snd_soc_update_bits(codec, WM8993_CLASS_W_0,
850 WM8993_CP_DYN_FREQ |
851 WM8993_CP_DYN_V,
852 0);
853 }
854 wm8993->class_w_users++;
855 wm8993->hubs_data.class_w = true;
856 }
857
858 /* Implement the change */
859 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
860
861 /* Enable it if we're using the direct DAC path */
862 if (ucontrol->value.integer.value[0] == 1) {
863 if (wm8993->class_w_users == 1) {
864 dev_dbg(codec->dev, "Enabling Class W\n");
865 snd_soc_update_bits(codec, WM8993_CLASS_W_0,
866 WM8993_CP_DYN_FREQ |
867 WM8993_CP_DYN_V,
868 WM8993_CP_DYN_FREQ |
869 WM8993_CP_DYN_V);
870 }
871 wm8993->class_w_users--;
872 wm8993->hubs_data.class_w = false;
873 }
874
875 dev_dbg(codec->dev, "Indirect DAC use count now %d\n",
876 wm8993->class_w_users);
877
878 return ret;
879}
880
881#define SOC_DAPM_ENUM_W(xname, xenum) \
882{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
883 .info = snd_soc_info_enum_double, \
884 .get = snd_soc_dapm_get_enum_double, \
885 .put = class_w_put, \
886 .private_value = (unsigned long)&xenum }
887
888static const char *hp_mux_text[] = {
889 "Mixer",
890 "DAC",
891};
892
893static const struct soc_enum hpl_enum =
894 SOC_ENUM_SINGLE(WM8993_OUTPUT_MIXER1, 8, 2, hp_mux_text);
895
896static const struct snd_kcontrol_new hpl_mux =
897 SOC_DAPM_ENUM_W("Left Headphone Mux", hpl_enum);
898
899static const struct soc_enum hpr_enum =
900 SOC_ENUM_SINGLE(WM8993_OUTPUT_MIXER2, 8, 2, hp_mux_text);
901
902static const struct snd_kcontrol_new hpr_mux =
903 SOC_DAPM_ENUM_W("Right Headphone Mux", hpr_enum);
904
905static const struct snd_kcontrol_new left_speaker_mixer[] = { 826static const struct snd_kcontrol_new left_speaker_mixer[] = {
906SOC_DAPM_SINGLE("Input Switch", WM8993_SPEAKER_MIXER, 7, 1, 0), 827SOC_DAPM_SINGLE("Input Switch", WM8993_SPEAKER_MIXER, 7, 1, 0),
907SOC_DAPM_SINGLE("IN1LP Switch", WM8993_SPEAKER_MIXER, 5, 1, 0), 828SOC_DAPM_SINGLE("IN1LP Switch", WM8993_SPEAKER_MIXER, 5, 1, 0),
@@ -988,8 +909,8 @@ SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &sidetoner_mux),
988SND_SOC_DAPM_DAC("DACL", NULL, WM8993_POWER_MANAGEMENT_3, 1, 0), 909SND_SOC_DAPM_DAC("DACL", NULL, WM8993_POWER_MANAGEMENT_3, 1, 0),
989SND_SOC_DAPM_DAC("DACR", NULL, WM8993_POWER_MANAGEMENT_3, 0, 0), 910SND_SOC_DAPM_DAC("DACR", NULL, WM8993_POWER_MANAGEMENT_3, 0, 0),
990 911
991SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux), 912SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &wm_hubs_hpl_mux),
992SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux), 913SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &wm_hubs_hpr_mux),
993 914
994SND_SOC_DAPM_MIXER("SPKL", WM8993_POWER_MANAGEMENT_3, 8, 0, 915SND_SOC_DAPM_MIXER("SPKL", WM8993_POWER_MANAGEMENT_3, 8, 0,
995 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)), 916 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
@@ -1579,9 +1500,6 @@ static int wm8993_probe(struct snd_soc_codec *codec)
1579 return ret; 1500 return ret;
1580 } 1501 }
1581 1502
1582 /* By default we're using the output mixers */
1583 wm8993->class_w_users = 2;
1584
1585 /* Latch volume update bits and default ZC on */ 1503 /* Latch volume update bits and default ZC on */
1586 snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME, 1504 snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME,
1587 WM8993_DAC_VU, WM8993_DAC_VU); 1505 WM8993_DAC_VU, WM8993_DAC_VU);
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 2de12ebe43b5..993639d694ce 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -70,8 +70,8 @@ static const struct wm8958_micd_rate micdet_rates[] = {
70static const struct wm8958_micd_rate jackdet_rates[] = { 70static const struct wm8958_micd_rate jackdet_rates[] = {
71 { 32768, true, 0, 1 }, 71 { 32768, true, 0, 1 },
72 { 32768, false, 0, 1 }, 72 { 32768, false, 0, 1 },
73 { 44100 * 256, true, 7, 10 }, 73 { 44100 * 256, true, 10, 10 },
74 { 44100 * 256, false, 7, 10 }, 74 { 44100 * 256, false, 7, 8 },
75}; 75};
76 76
77static void wm8958_micd_set_rate(struct snd_soc_codec *codec) 77static void wm8958_micd_set_rate(struct snd_soc_codec *codec)
@@ -82,7 +82,8 @@ static void wm8958_micd_set_rate(struct snd_soc_codec *codec)
82 const struct wm8958_micd_rate *rates; 82 const struct wm8958_micd_rate *rates;
83 int num_rates; 83 int num_rates;
84 84
85 if (wm8994->jack_cb != wm8958_default_micdet) 85 if (!(wm8994->pdata && wm8994->pdata->micd_rates) &&
86 wm8994->jack_cb != wm8958_default_micdet)
86 return; 87 return;
87 88
88 idle = !wm8994->jack_mic; 89 idle = !wm8994->jack_mic;
@@ -118,6 +119,10 @@ static void wm8958_micd_set_rate(struct snd_soc_codec *codec)
118 val = rates[best].start << WM8958_MICD_BIAS_STARTTIME_SHIFT 119 val = rates[best].start << WM8958_MICD_BIAS_STARTTIME_SHIFT
119 | rates[best].rate << WM8958_MICD_RATE_SHIFT; 120 | rates[best].rate << WM8958_MICD_RATE_SHIFT;
120 121
122 dev_dbg(codec->dev, "MICD rate %d,%d for %dHz %s\n",
123 rates[best].start, rates[best].rate, sysclk,
124 idle ? "idle" : "active");
125
121 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, 126 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
122 WM8958_MICD_BIAS_STARTTIME_MASK | 127 WM8958_MICD_BIAS_STARTTIME_MASK |
123 WM8958_MICD_RATE_MASK, val); 128 WM8958_MICD_RATE_MASK, val);
@@ -398,7 +403,7 @@ static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block)
398 wm8994->dac_rates[iface]); 403 wm8994->dac_rates[iface]);
399 404
400 /* The EQ will be disabled while reconfiguring it, remember the 405 /* The EQ will be disabled while reconfiguring it, remember the
401 * current configuration. 406 * current configuration.
402 */ 407 */
403 save = snd_soc_read(codec, base); 408 save = snd_soc_read(codec, base);
404 save &= WM8994_AIF1DAC1_EQ_ENA; 409 save &= WM8994_AIF1DAC1_EQ_ENA;
@@ -689,6 +694,9 @@ static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode)
689 if (!wm8994->jackdet || !wm8994->jack_cb) 694 if (!wm8994->jackdet || !wm8994->jack_cb)
690 return; 695 return;
691 696
697 if (!wm8994->jackdet || !wm8994->jack_cb)
698 return;
699
692 if (wm8994->active_refcount) 700 if (wm8994->active_refcount)
693 mode = WM1811_JACKDET_MODE_AUDIO; 701 mode = WM1811_JACKDET_MODE_AUDIO;
694 702
@@ -784,7 +792,7 @@ static void vmid_reference(struct snd_soc_codec *codec)
784 792
785 switch (wm8994->vmid_mode) { 793 switch (wm8994->vmid_mode) {
786 default: 794 default:
787 WARN_ON(0 == "Invalid VMID mode"); 795 WARN_ON(NULL == "Invalid VMID mode");
788 case WM8994_VMID_NORMAL: 796 case WM8994_VMID_NORMAL:
789 /* Startup bias, VMID ramp & buffer */ 797 /* Startup bias, VMID ramp & buffer */
790 snd_soc_update_bits(codec, WM8994_ANTIPOP_2, 798 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
@@ -937,27 +945,12 @@ static int vmid_event(struct snd_soc_dapm_widget *w,
937 return 0; 945 return 0;
938} 946}
939 947
940static void wm8994_update_class_w(struct snd_soc_codec *codec) 948static bool wm8994_check_class_w_digital(struct snd_soc_codec *codec)
941{ 949{
942 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
943 int enable = 1;
944 int source = 0; /* GCC flow analysis can't track enable */ 950 int source = 0; /* GCC flow analysis can't track enable */
945 int reg, reg_r; 951 int reg, reg_r;
946 952
947 /* Only support direct DAC->headphone paths */ 953 /* We also need the same AIF source for L/R and only one path */
948 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_1);
949 if (!(reg & WM8994_DAC1L_TO_HPOUT1L)) {
950 dev_vdbg(codec->dev, "HPL connected to output mixer\n");
951 enable = 0;
952 }
953
954 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_2);
955 if (!(reg & WM8994_DAC1R_TO_HPOUT1R)) {
956 dev_vdbg(codec->dev, "HPR connected to output mixer\n");
957 enable = 0;
958 }
959
960 /* We also need the same setting for L/R and only one path */
961 reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING); 954 reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
962 switch (reg) { 955 switch (reg) {
963 case WM8994_AIF2DACL_TO_DAC1L: 956 case WM8994_AIF2DACL_TO_DAC1L:
@@ -974,30 +967,20 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec)
974 break; 967 break;
975 default: 968 default:
976 dev_vdbg(codec->dev, "DAC mixer setting: %x\n", reg); 969 dev_vdbg(codec->dev, "DAC mixer setting: %x\n", reg);
977 enable = 0; 970 return false;
978 break;
979 } 971 }
980 972
981 reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING); 973 reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
982 if (reg_r != reg) { 974 if (reg_r != reg) {
983 dev_vdbg(codec->dev, "Left and right DAC mixers different\n"); 975 dev_vdbg(codec->dev, "Left and right DAC mixers different\n");
984 enable = 0; 976 return false;
985 } 977 }
986 978
987 if (enable) { 979 /* Set the source up */
988 dev_dbg(codec->dev, "Class W enabled\n"); 980 snd_soc_update_bits(codec, WM8994_CLASS_W_1,
989 snd_soc_update_bits(codec, WM8994_CLASS_W_1, 981 WM8994_CP_DYN_SRC_SEL_MASK, source);
990 WM8994_CP_DYN_PWR | 982
991 WM8994_CP_DYN_SRC_SEL_MASK, 983 return true;
992 source | WM8994_CP_DYN_PWR);
993 wm8994->hubs.class_w = true;
994
995 } else {
996 dev_dbg(codec->dev, "Class W disabled\n");
997 snd_soc_update_bits(codec, WM8994_CLASS_W_1,
998 WM8994_CP_DYN_PWR, 0);
999 wm8994->hubs.class_w = false;
1000 }
1001} 984}
1002 985
1003static int aif1clk_ev(struct snd_soc_dapm_widget *w, 986static int aif1clk_ev(struct snd_soc_dapm_widget *w,
@@ -1280,45 +1263,6 @@ static int dac_ev(struct snd_soc_dapm_widget *w,
1280 return 0; 1263 return 0;
1281} 1264}
1282 1265
1283static const char *hp_mux_text[] = {
1284 "Mixer",
1285 "DAC",
1286};
1287
1288#define WM8994_HP_ENUM(xname, xenum) \
1289{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1290 .info = snd_soc_info_enum_double, \
1291 .get = snd_soc_dapm_get_enum_double, \
1292 .put = wm8994_put_hp_enum, \
1293 .private_value = (unsigned long)&xenum }
1294
1295static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol,
1296 struct snd_ctl_elem_value *ucontrol)
1297{
1298 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
1299 struct snd_soc_dapm_widget *w = wlist->widgets[0];
1300 struct snd_soc_codec *codec = w->codec;
1301 int ret;
1302
1303 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
1304
1305 wm8994_update_class_w(codec);
1306
1307 return ret;
1308}
1309
1310static const struct soc_enum hpl_enum =
1311 SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_1, 8, 2, hp_mux_text);
1312
1313static const struct snd_kcontrol_new hpl_mux =
1314 WM8994_HP_ENUM("Left Headphone Mux", hpl_enum);
1315
1316static const struct soc_enum hpr_enum =
1317 SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_2, 8, 2, hp_mux_text);
1318
1319static const struct snd_kcontrol_new hpr_mux =
1320 WM8994_HP_ENUM("Right Headphone Mux", hpr_enum);
1321
1322static const char *adc_mux_text[] = { 1266static const char *adc_mux_text[] = {
1323 "ADC", 1267 "ADC",
1324 "DMIC", 1268 "DMIC",
@@ -1430,7 +1374,7 @@ static int wm8994_put_class_w(struct snd_kcontrol *kcontrol,
1430 1374
1431 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); 1375 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
1432 1376
1433 wm8994_update_class_w(codec); 1377 wm_hubs_update_class_w(codec);
1434 1378
1435 return ret; 1379 return ret;
1436} 1380}
@@ -1524,7 +1468,7 @@ static const struct snd_kcontrol_new wm8958_aif3adc_mux =
1524 SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum); 1468 SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum);
1525 1469
1526static const char *mono_pcm_out_text[] = { 1470static const char *mono_pcm_out_text[] = {
1527 "None", "AIF2ADCL", "AIF2ADCR", 1471 "None", "AIF2ADCL", "AIF2ADCR",
1528}; 1472};
1529 1473
1530static const struct soc_enum mono_pcm_out_enum = 1474static const struct soc_enum mono_pcm_out_enum =
@@ -1573,9 +1517,9 @@ SND_SOC_DAPM_MIXER_E("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
1573SND_SOC_DAPM_MIXER_E("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0, 1517SND_SOC_DAPM_MIXER_E("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
1574 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer), 1518 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer),
1575 late_enable_ev, SND_SOC_DAPM_PRE_PMU), 1519 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1576SND_SOC_DAPM_MUX_E("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux, 1520SND_SOC_DAPM_MUX_E("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &wm_hubs_hpl_mux,
1577 late_enable_ev, SND_SOC_DAPM_PRE_PMU), 1521 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1578SND_SOC_DAPM_MUX_E("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux, 1522SND_SOC_DAPM_MUX_E("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &wm_hubs_hpr_mux,
1579 late_enable_ev, SND_SOC_DAPM_PRE_PMU), 1523 late_enable_ev, SND_SOC_DAPM_PRE_PMU),
1580 1524
1581SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev) 1525SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev)
@@ -1591,8 +1535,8 @@ SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
1591 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)), 1535 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
1592SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0, 1536SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
1593 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)), 1537 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
1594SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux), 1538SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &wm_hubs_hpl_mux),
1595SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux), 1539SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &wm_hubs_hpr_mux),
1596}; 1540};
1597 1541
1598static const struct snd_soc_dapm_widget wm8994_dac_revd_widgets[] = { 1542static const struct snd_soc_dapm_widget wm8994_dac_revd_widgets[] = {
@@ -1732,6 +1676,7 @@ SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8994_aif3adc_mux),
1732}; 1676};
1733 1677
1734static const struct snd_soc_dapm_widget wm8958_dapm_widgets[] = { 1678static const struct snd_soc_dapm_widget wm8958_dapm_widgets[] = {
1679SND_SOC_DAPM_SUPPLY("AIF3", WM8994_POWER_MANAGEMENT_6, 5, 1, NULL, 0),
1735SND_SOC_DAPM_MUX("Mono PCM Out Mux", SND_SOC_NOPM, 0, 0, &mono_pcm_out_mux), 1680SND_SOC_DAPM_MUX("Mono PCM Out Mux", SND_SOC_NOPM, 0, 0, &mono_pcm_out_mux),
1736SND_SOC_DAPM_MUX("AIF2DACL Mux", SND_SOC_NOPM, 0, 0, &aif2dacl_src_mux), 1681SND_SOC_DAPM_MUX("AIF2DACL Mux", SND_SOC_NOPM, 0, 0, &aif2dacl_src_mux),
1737SND_SOC_DAPM_MUX("AIF2DACR Mux", SND_SOC_NOPM, 0, 0, &aif2dacr_src_mux), 1682SND_SOC_DAPM_MUX("AIF2DACR Mux", SND_SOC_NOPM, 0, 0, &aif2dacr_src_mux),
@@ -1972,6 +1917,9 @@ static const struct snd_soc_dapm_route wm8958_intercon[] = {
1972 { "AIF2DACR Mux", "AIF2", "AIF2DAC Mux" }, 1917 { "AIF2DACR Mux", "AIF2", "AIF2DAC Mux" },
1973 { "AIF2DACR Mux", "AIF3", "AIF3DACDAT" }, 1918 { "AIF2DACR Mux", "AIF3", "AIF3DACDAT" },
1974 1919
1920 { "AIF3DACDAT", NULL, "AIF3" },
1921 { "AIF3ADCDAT", NULL, "AIF3" },
1922
1975 { "Mono PCM Out Mux", "AIF2ADCL", "AIF2ADCL" }, 1923 { "Mono PCM Out Mux", "AIF2ADCL", "AIF2ADCL" },
1976 { "Mono PCM Out Mux", "AIF2ADCR", "AIF2ADCR" }, 1924 { "Mono PCM Out Mux", "AIF2ADCR", "AIF2ADCR" },
1977 1925
@@ -2068,24 +2016,20 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
2068 struct wm8994 *control = wm8994->wm8994; 2016 struct wm8994 *control = wm8994->wm8994;
2069 int reg_offset, ret; 2017 int reg_offset, ret;
2070 struct fll_div fll; 2018 struct fll_div fll;
2071 u16 reg, aif1, aif2; 2019 u16 reg, clk1, aif_reg, aif_src;
2072 unsigned long timeout; 2020 unsigned long timeout;
2073 bool was_enabled; 2021 bool was_enabled;
2074 2022
2075 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
2076 & WM8994_AIF1CLK_ENA;
2077
2078 aif2 = snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
2079 & WM8994_AIF2CLK_ENA;
2080
2081 switch (id) { 2023 switch (id) {
2082 case WM8994_FLL1: 2024 case WM8994_FLL1:
2083 reg_offset = 0; 2025 reg_offset = 0;
2084 id = 0; 2026 id = 0;
2027 aif_src = 0x10;
2085 break; 2028 break;
2086 case WM8994_FLL2: 2029 case WM8994_FLL2:
2087 reg_offset = 0x20; 2030 reg_offset = 0x20;
2088 id = 1; 2031 id = 1;
2032 aif_src = 0x18;
2089 break; 2033 break;
2090 default: 2034 default:
2091 return -EINVAL; 2035 return -EINVAL;
@@ -2127,16 +2071,33 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
2127 if (ret < 0) 2071 if (ret < 0)
2128 return ret; 2072 return ret;
2129 2073
2130 /* Gate the AIF clocks while we reclock */ 2074 /* Make sure that we're not providing SYSCLK right now */
2131 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, 2075 clk1 = snd_soc_read(codec, WM8994_CLOCKING_1);
2132 WM8994_AIF1CLK_ENA, 0); 2076 if (clk1 & WM8994_SYSCLK_SRC)
2133 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, 2077 aif_reg = WM8994_AIF2_CLOCKING_1;
2134 WM8994_AIF2CLK_ENA, 0); 2078 else
2079 aif_reg = WM8994_AIF1_CLOCKING_1;
2080 reg = snd_soc_read(codec, aif_reg);
2081
2082 if ((reg & WM8994_AIF1CLK_ENA) &&
2083 (reg & WM8994_AIF1CLK_SRC_MASK) == aif_src) {
2084 dev_err(codec->dev, "FLL%d is currently providing SYSCLK\n",
2085 id + 1);
2086 return -EBUSY;
2087 }
2135 2088
2136 /* We always need to disable the FLL while reconfiguring */ 2089 /* We always need to disable the FLL while reconfiguring */
2137 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, 2090 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
2138 WM8994_FLL1_ENA, 0); 2091 WM8994_FLL1_ENA, 0);
2139 2092
2093 if (wm8994->fll_byp && src == WM8994_FLL_SRC_BCLK &&
2094 freq_in == freq_out && freq_out) {
2095 dev_dbg(codec->dev, "Bypassing FLL%d\n", id + 1);
2096 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
2097 WM8958_FLL1_BYP, WM8958_FLL1_BYP);
2098 goto out;
2099 }
2100
2140 reg = (fll.outdiv << WM8994_FLL1_OUTDIV_SHIFT) | 2101 reg = (fll.outdiv << WM8994_FLL1_OUTDIV_SHIFT) |
2141 (fll.fll_fratio << WM8994_FLL1_FRATIO_SHIFT); 2102 (fll.fll_fratio << WM8994_FLL1_FRATIO_SHIFT);
2142 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_2 + reg_offset, 2103 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_2 + reg_offset,
@@ -2151,6 +2112,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
2151 fll.n << WM8994_FLL1_N_SHIFT); 2112 fll.n << WM8994_FLL1_N_SHIFT);
2152 2113
2153 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset, 2114 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
2115 WM8958_FLL1_BYP |
2154 WM8994_FLL1_REFCLK_DIV_MASK | 2116 WM8994_FLL1_REFCLK_DIV_MASK |
2155 WM8994_FLL1_REFCLK_SRC_MASK, 2117 WM8994_FLL1_REFCLK_SRC_MASK,
2156 (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) | 2118 (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) |
@@ -2213,16 +2175,11 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
2213 } 2175 }
2214 } 2176 }
2215 2177
2178out:
2216 wm8994->fll[id].in = freq_in; 2179 wm8994->fll[id].in = freq_in;
2217 wm8994->fll[id].out = freq_out; 2180 wm8994->fll[id].out = freq_out;
2218 wm8994->fll[id].src = src; 2181 wm8994->fll[id].src = src;
2219 2182
2220 /* Enable any gated AIF clocks */
2221 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
2222 WM8994_AIF1CLK_ENA, aif1);
2223 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
2224 WM8994_AIF2CLK_ENA, aif2);
2225
2226 configure_clock(codec); 2183 configure_clock(codec);
2227 2184
2228 return 0; 2185 return 0;
@@ -2290,7 +2247,7 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
2290 2247
2291 case WM8994_SYSCLK_OPCLK: 2248 case WM8994_SYSCLK_OPCLK:
2292 /* Special case - a division (times 10) is given and 2249 /* Special case - a division (times 10) is given and
2293 * no effect on main clocking. 2250 * no effect on main clocking.
2294 */ 2251 */
2295 if (freq) { 2252 if (freq) {
2296 for (i = 0; i < ARRAY_SIZE(opclk_divs); i++) 2253 for (i = 0; i < ARRAY_SIZE(opclk_divs); i++)
@@ -2792,33 +2749,6 @@ static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream,
2792 return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1); 2749 return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
2793} 2750}
2794 2751
2795static void wm8994_aif_shutdown(struct snd_pcm_substream *substream,
2796 struct snd_soc_dai *dai)
2797{
2798 struct snd_soc_codec *codec = dai->codec;
2799 int rate_reg = 0;
2800
2801 switch (dai->id) {
2802 case 1:
2803 rate_reg = WM8994_AIF1_RATE;
2804 break;
2805 case 2:
2806 rate_reg = WM8994_AIF2_RATE;
2807 break;
2808 default:
2809 break;
2810 }
2811
2812 /* If the DAI is idle then configure the divider tree for the
2813 * lowest output rate to save a little power if the clock is
2814 * still active (eg, because it is system clock).
2815 */
2816 if (rate_reg && !dai->playback_active && !dai->capture_active)
2817 snd_soc_update_bits(codec, rate_reg,
2818 WM8994_AIF1_SR_MASK |
2819 WM8994_AIF1CLK_RATE_MASK, 0x9);
2820}
2821
2822static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute) 2752static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
2823{ 2753{
2824 struct snd_soc_codec *codec = codec_dai->codec; 2754 struct snd_soc_codec *codec = codec_dai->codec;
@@ -2860,10 +2790,6 @@ static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
2860 reg = WM8994_AIF2_MASTER_SLAVE; 2790 reg = WM8994_AIF2_MASTER_SLAVE;
2861 mask = WM8994_AIF2_TRI; 2791 mask = WM8994_AIF2_TRI;
2862 break; 2792 break;
2863 case 3:
2864 reg = WM8994_POWER_MANAGEMENT_6;
2865 mask = WM8994_AIF3_TRI;
2866 break;
2867 default: 2793 default:
2868 return -EINVAL; 2794 return -EINVAL;
2869 } 2795 }
@@ -2900,7 +2826,6 @@ static const struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
2900 .set_sysclk = wm8994_set_dai_sysclk, 2826 .set_sysclk = wm8994_set_dai_sysclk,
2901 .set_fmt = wm8994_set_dai_fmt, 2827 .set_fmt = wm8994_set_dai_fmt,
2902 .hw_params = wm8994_hw_params, 2828 .hw_params = wm8994_hw_params,
2903 .shutdown = wm8994_aif_shutdown,
2904 .digital_mute = wm8994_aif_mute, 2829 .digital_mute = wm8994_aif_mute,
2905 .set_pll = wm8994_set_fll, 2830 .set_pll = wm8994_set_fll,
2906 .set_tristate = wm8994_set_tristate, 2831 .set_tristate = wm8994_set_tristate,
@@ -2910,7 +2835,6 @@ static const struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
2910 .set_sysclk = wm8994_set_dai_sysclk, 2835 .set_sysclk = wm8994_set_dai_sysclk,
2911 .set_fmt = wm8994_set_dai_fmt, 2836 .set_fmt = wm8994_set_dai_fmt,
2912 .hw_params = wm8994_hw_params, 2837 .hw_params = wm8994_hw_params,
2913 .shutdown = wm8994_aif_shutdown,
2914 .digital_mute = wm8994_aif_mute, 2838 .digital_mute = wm8994_aif_mute,
2915 .set_pll = wm8994_set_fll, 2839 .set_pll = wm8994_set_fll,
2916 .set_tristate = wm8994_set_tristate, 2840 .set_tristate = wm8994_set_tristate,
@@ -2918,7 +2842,6 @@ static const struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
2918 2842
2919static const struct snd_soc_dai_ops wm8994_aif3_dai_ops = { 2843static const struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
2920 .hw_params = wm8994_aif3_hw_params, 2844 .hw_params = wm8994_aif3_hw_params,
2921 .set_tristate = wm8994_set_tristate,
2922}; 2845};
2923 2846
2924static struct snd_soc_dai_driver wm8994_dai[] = { 2847static struct snd_soc_dai_driver wm8994_dai[] = {
@@ -3126,14 +3049,14 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
3126 3049
3127 /* Expand the array... */ 3050 /* Expand the array... */
3128 t = krealloc(wm8994->retune_mobile_texts, 3051 t = krealloc(wm8994->retune_mobile_texts,
3129 sizeof(char *) * 3052 sizeof(char *) *
3130 (wm8994->num_retune_mobile_texts + 1), 3053 (wm8994->num_retune_mobile_texts + 1),
3131 GFP_KERNEL); 3054 GFP_KERNEL);
3132 if (t == NULL) 3055 if (t == NULL)
3133 continue; 3056 continue;
3134 3057
3135 /* ...store the new entry... */ 3058 /* ...store the new entry... */
3136 t[wm8994->num_retune_mobile_texts] = 3059 t[wm8994->num_retune_mobile_texts] =
3137 pdata->retune_mobile_cfgs[i].name; 3060 pdata->retune_mobile_cfgs[i].name;
3138 3061
3139 /* ...and remember the new version. */ 3062 /* ...and remember the new version. */
@@ -3304,25 +3227,25 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3304} 3227}
3305EXPORT_SYMBOL_GPL(wm8994_mic_detect); 3228EXPORT_SYMBOL_GPL(wm8994_mic_detect);
3306 3229
3307static irqreturn_t wm8994_mic_irq(int irq, void *data) 3230static void wm8994_mic_work(struct work_struct *work)
3308{ 3231{
3309 struct wm8994_priv *priv = data; 3232 struct wm8994_priv *priv = container_of(work,
3310 struct snd_soc_codec *codec = priv->codec; 3233 struct wm8994_priv,
3311 int reg; 3234 mic_work.work);
3235 struct regmap *regmap = priv->wm8994->regmap;
3236 struct device *dev = priv->wm8994->dev;
3237 unsigned int reg;
3238 int ret;
3312 int report; 3239 int report;
3313 3240
3314#ifndef CONFIG_SND_SOC_WM8994_MODULE 3241 ret = regmap_read(regmap, WM8994_INTERRUPT_RAW_STATUS_2, &reg);
3315 trace_snd_soc_jack_irq(dev_name(codec->dev)); 3242 if (ret < 0) {
3316#endif 3243 dev_err(dev, "Failed to read microphone status: %d\n",
3317 3244 ret);
3318 reg = snd_soc_read(codec, WM8994_INTERRUPT_RAW_STATUS_2); 3245 return;
3319 if (reg < 0) {
3320 dev_err(codec->dev, "Failed to read microphone status: %d\n",
3321 reg);
3322 return IRQ_HANDLED;
3323 } 3246 }
3324 3247
3325 dev_dbg(codec->dev, "Microphone status: %x\n", reg); 3248 dev_dbg(dev, "Microphone status: %x\n", reg);
3326 3249
3327 report = 0; 3250 report = 0;
3328 if (reg & WM8994_MIC1_DET_STS) { 3251 if (reg & WM8994_MIC1_DET_STS) {
@@ -3361,6 +3284,20 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
3361 3284
3362 snd_soc_jack_report(priv->micdet[1].jack, report, 3285 snd_soc_jack_report(priv->micdet[1].jack, report,
3363 SND_JACK_HEADSET | SND_JACK_BTN_0); 3286 SND_JACK_HEADSET | SND_JACK_BTN_0);
3287}
3288
3289static irqreturn_t wm8994_mic_irq(int irq, void *data)
3290{
3291 struct wm8994_priv *priv = data;
3292 struct snd_soc_codec *codec = priv->codec;
3293
3294#ifndef CONFIG_SND_SOC_WM8994_MODULE
3295 trace_snd_soc_jack_irq(dev_name(codec->dev));
3296#endif
3297
3298 pm_wakeup_event(codec->dev, 300);
3299
3300 schedule_delayed_work(&priv->mic_work, msecs_to_jiffies(250));
3364 3301
3365 return IRQ_HANDLED; 3302 return IRQ_HANDLED;
3366} 3303}
@@ -3415,9 +3352,6 @@ static void wm8958_default_micdet(u16 status, void *data)
3415 3352
3416 wm8958_micd_set_rate(codec); 3353 wm8958_micd_set_rate(codec);
3417 3354
3418 snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE,
3419 SND_JACK_HEADSET);
3420
3421 /* If we have jackdet that will detect removal */ 3355 /* If we have jackdet that will detect removal */
3422 if (wm8994->jackdet) { 3356 if (wm8994->jackdet) {
3423 mutex_lock(&wm8994->accdet_lock); 3357 mutex_lock(&wm8994->accdet_lock);
@@ -3430,14 +3364,13 @@ static void wm8958_default_micdet(u16 status, void *data)
3430 3364
3431 mutex_unlock(&wm8994->accdet_lock); 3365 mutex_unlock(&wm8994->accdet_lock);
3432 3366
3433 if (wm8994->pdata->jd_ext_cap) { 3367 if (wm8994->pdata->jd_ext_cap)
3434 mutex_lock(&codec->mutex);
3435 snd_soc_dapm_disable_pin(&codec->dapm, 3368 snd_soc_dapm_disable_pin(&codec->dapm,
3436 "MICBIAS2"); 3369 "MICBIAS2");
3437 snd_soc_dapm_sync(&codec->dapm);
3438 mutex_unlock(&codec->mutex);
3439 }
3440 } 3370 }
3371
3372 snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE,
3373 SND_JACK_HEADSET);
3441 } 3374 }
3442 3375
3443 /* Report short circuit as a button */ 3376 /* Report short circuit as a button */
@@ -3489,6 +3422,8 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3489 if (present) { 3422 if (present) {
3490 dev_dbg(codec->dev, "Jack detected\n"); 3423 dev_dbg(codec->dev, "Jack detected\n");
3491 3424
3425 wm8958_micd_set_rate(codec);
3426
3492 snd_soc_update_bits(codec, WM8958_MICBIAS2, 3427 snd_soc_update_bits(codec, WM8958_MICBIAS2,
3493 WM8958_MICB2_DISCH, 0); 3428 WM8958_MICB2_DISCH, 0);
3494 3429
@@ -3526,16 +3461,11 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
3526 3461
3527 /* If required for an external cap force MICBIAS on */ 3462 /* If required for an external cap force MICBIAS on */
3528 if (wm8994->pdata->jd_ext_cap) { 3463 if (wm8994->pdata->jd_ext_cap) {
3529 mutex_lock(&codec->mutex);
3530
3531 if (present) 3464 if (present)
3532 snd_soc_dapm_force_enable_pin(&codec->dapm, 3465 snd_soc_dapm_force_enable_pin(&codec->dapm,
3533 "MICBIAS2"); 3466 "MICBIAS2");
3534 else 3467 else
3535 snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); 3468 snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2");
3536
3537 snd_soc_dapm_sync(&codec->dapm);
3538 mutex_unlock(&codec->mutex);
3539 } 3469 }
3540 3470
3541 if (present) 3471 if (present)
@@ -3740,6 +3670,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3740 wm8994->codec = codec; 3670 wm8994->codec = codec;
3741 3671
3742 mutex_init(&wm8994->accdet_lock); 3672 mutex_init(&wm8994->accdet_lock);
3673 INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work);
3743 3674
3744 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) 3675 for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
3745 init_completion(&wm8994->fll_locked[i]); 3676 init_completion(&wm8994->fll_locked[i]);
@@ -3783,13 +3714,22 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3783 case WM8958: 3714 case WM8958:
3784 wm8994->hubs.dcs_readback_mode = 1; 3715 wm8994->hubs.dcs_readback_mode = 1;
3785 wm8994->hubs.hp_startup_mode = 1; 3716 wm8994->hubs.hp_startup_mode = 1;
3717
3718 switch (wm8994->revision) {
3719 case 0:
3720 break;
3721 default:
3722 wm8994->fll_byp = true;
3723 break;
3724 }
3786 break; 3725 break;
3787 3726
3788 case WM1811: 3727 case WM1811:
3789 wm8994->hubs.dcs_readback_mode = 2; 3728 wm8994->hubs.dcs_readback_mode = 2;
3790 wm8994->hubs.no_series_update = 1; 3729 wm8994->hubs.no_series_update = 1;
3791 wm8994->hubs.hp_startup_mode = 1; 3730 wm8994->hubs.hp_startup_mode = 1;
3792 wm8994->hubs.no_cache_class_w = true; 3731 wm8994->hubs.no_cache_dac_hp_direct = true;
3732 wm8994->fll_byp = true;
3793 3733
3794 switch (wm8994->revision) { 3734 switch (wm8994->revision) {
3795 case 0: 3735 case 0:
@@ -4010,7 +3950,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
4010 break; 3950 break;
4011 } 3951 }
4012 3952
4013 wm8994_update_class_w(codec); 3953 wm8994->hubs.check_class_w_digital = wm8994_check_class_w_digital;
3954 wm_hubs_update_class_w(codec);
4014 3955
4015 wm8994_handle_pdata(wm8994); 3956 wm8994_handle_pdata(wm8994);
4016 3957
@@ -4075,7 +4016,6 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
4075 ARRAY_SIZE(wm8994_dac_widgets)); 4016 ARRAY_SIZE(wm8994_dac_widgets));
4076 break; 4017 break;
4077 } 4018 }
4078
4079 4019
4080 wm_hubs_add_analogue_routes(codec, 0, 0); 4020 wm_hubs_add_analogue_routes(codec, 0, 0);
4081 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); 4021 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
@@ -4140,7 +4080,7 @@ err_irq:
4140 return ret; 4080 return ret;
4141} 4081}
4142 4082
4143static int wm8994_codec_remove(struct snd_soc_codec *codec) 4083static int wm8994_codec_remove(struct snd_soc_codec *codec)
4144{ 4084{
4145 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 4085 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
4146 struct wm8994 *control = wm8994->wm8994; 4086 struct wm8994 *control = wm8994->wm8994;
@@ -4181,14 +4121,10 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec)
4181 free_irq(wm8994->micdet_irq, wm8994); 4121 free_irq(wm8994->micdet_irq, wm8994);
4182 break; 4122 break;
4183 } 4123 }
4184 if (wm8994->mbc) 4124 release_firmware(wm8994->mbc);
4185 release_firmware(wm8994->mbc); 4125 release_firmware(wm8994->mbc_vss);
4186 if (wm8994->mbc_vss) 4126 release_firmware(wm8994->enh_eq);
4187 release_firmware(wm8994->mbc_vss);
4188 if (wm8994->enh_eq)
4189 release_firmware(wm8994->enh_eq);
4190 kfree(wm8994->retune_mobile_texts); 4127 kfree(wm8994->retune_mobile_texts);
4191
4192 return 0; 4128 return 0;
4193} 4129}
4194 4130
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index c724112998d8..d77e06f0a675 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -12,6 +12,7 @@
12#include <sound/soc.h> 12#include <sound/soc.h>
13#include <linux/firmware.h> 13#include <linux/firmware.h>
14#include <linux/completion.h> 14#include <linux/completion.h>
15#include <linux/workqueue.h>
15 16
16#include "wm_hubs.h" 17#include "wm_hubs.h"
17 18
@@ -79,6 +80,7 @@ struct wm8994_priv {
79 struct wm8994_fll_config fll[2], fll_suspend[2]; 80 struct wm8994_fll_config fll[2], fll_suspend[2];
80 struct completion fll_locked[2]; 81 struct completion fll_locked[2];
81 bool fll_locked_irq; 82 bool fll_locked_irq;
83 bool fll_byp;
82 84
83 int vmid_refcount; 85 int vmid_refcount;
84 int active_refcount; 86 int active_refcount;
@@ -126,6 +128,7 @@ struct wm8994_priv {
126 128
127 struct mutex accdet_lock; 129 struct mutex accdet_lock;
128 struct wm8994_micdet micdet[2]; 130 struct wm8994_micdet micdet[2];
131 struct delayed_work mic_work;
129 bool mic_detecting; 132 bool mic_detecting;
130 bool jack_mic; 133 bool jack_mic;
131 int btn_mask; 134 int btn_mask;
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index 1fd635494045..8af422e38fd0 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -1770,7 +1770,13 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
1770 1770
1771 switch (level) { 1771 switch (level) {
1772 case SND_SOC_BIAS_ON: 1772 case SND_SOC_BIAS_ON:
1773 break;
1773 case SND_SOC_BIAS_PREPARE: 1774 case SND_SOC_BIAS_PREPARE:
1775 /* Put the MICBIASes into regulating mode */
1776 snd_soc_update_bits(codec, WM8996_MICBIAS_1,
1777 WM8996_MICB1_MODE, 0);
1778 snd_soc_update_bits(codec, WM8996_MICBIAS_2,
1779 WM8996_MICB2_MODE, 0);
1774 break; 1780 break;
1775 1781
1776 case SND_SOC_BIAS_STANDBY: 1782 case SND_SOC_BIAS_STANDBY:
@@ -1793,6 +1799,12 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
1793 regcache_cache_only(codec->control_data, false); 1799 regcache_cache_only(codec->control_data, false);
1794 regcache_sync(codec->control_data); 1800 regcache_sync(codec->control_data);
1795 } 1801 }
1802
1803 /* Bypass the MICBIASes for lowest power */
1804 snd_soc_update_bits(codec, WM8996_MICBIAS_1,
1805 WM8996_MICB1_MODE, WM8996_MICB1_MODE);
1806 snd_soc_update_bits(codec, WM8996_MICBIAS_2,
1807 WM8996_MICB2_MODE, WM8996_MICB2_MODE);
1796 break; 1808 break;
1797 1809
1798 case SND_SOC_BIAS_OFF: 1810 case SND_SOC_BIAS_OFF:
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 076c126ed9b1..9328270df16c 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -774,7 +774,7 @@ static const struct snd_soc_dapm_widget wm9081_dapm_widgets[] = {
774SND_SOC_DAPM_INPUT("IN1"), 774SND_SOC_DAPM_INPUT("IN1"),
775SND_SOC_DAPM_INPUT("IN2"), 775SND_SOC_DAPM_INPUT("IN2"),
776 776
777SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM9081_POWER_MANAGEMENT, 0, 0), 777SND_SOC_DAPM_DAC("DAC", NULL, WM9081_POWER_MANAGEMENT, 0, 0),
778 778
779SND_SOC_DAPM_MIXER_NAMED_CTL("Mixer", SND_SOC_NOPM, 0, 0, 779SND_SOC_DAPM_MIXER_NAMED_CTL("Mixer", SND_SOC_NOPM, 0, 0,
780 mixer, ARRAY_SIZE(mixer)), 780 mixer, ARRAY_SIZE(mixer)),
@@ -799,6 +799,7 @@ SND_SOC_DAPM_SUPPLY("TSENSE", WM9081_POWER_MANAGEMENT, 7, 0, NULL, 0),
799static const struct snd_soc_dapm_route wm9081_audio_paths[] = { 799static const struct snd_soc_dapm_route wm9081_audio_paths[] = {
800 { "DAC", NULL, "CLK_SYS" }, 800 { "DAC", NULL, "CLK_SYS" },
801 { "DAC", NULL, "CLK_DSP" }, 801 { "DAC", NULL, "CLK_DSP" },
802 { "DAC", NULL, "AIF" },
802 803
803 { "Mixer", "IN1 Switch", "IN1" }, 804 { "Mixer", "IN1 Switch", "IN1" },
804 { "Mixer", "IN2 Switch", "IN2" }, 805 { "Mixer", "IN2 Switch", "IN2" },
@@ -1252,7 +1253,7 @@ static const struct snd_soc_dai_ops wm9081_dai_ops = {
1252static struct snd_soc_dai_driver wm9081_dai = { 1253static struct snd_soc_dai_driver wm9081_dai = {
1253 .name = "wm9081-hifi", 1254 .name = "wm9081-hifi",
1254 .playback = { 1255 .playback = {
1255 .stream_name = "HiFi Playback", 1256 .stream_name = "AIF",
1256 .channels_min = 1, 1257 .channels_min = 1,
1257 .channels_max = 2, 1258 .channels_max = 2,
1258 .rates = WM9081_RATES, 1259 .rates = WM9081_RATES,
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index cacc6a86b46f..e8e782a0c78d 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -236,9 +236,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
236static int ac97_prepare(struct snd_pcm_substream *substream, 236static int ac97_prepare(struct snd_pcm_substream *substream,
237 struct snd_soc_dai *dai) 237 struct snd_soc_dai *dai)
238{ 238{
239 struct snd_pcm_runtime *runtime = substream->runtime; 239 struct snd_soc_codec *codec = dai->codec;
240 struct snd_soc_pcm_runtime *rtd = substream->private_data;
241 struct snd_soc_codec *codec = rtd->codec;
242 int reg; 240 int reg;
243 u16 vra; 241 u16 vra;
244 242
@@ -250,7 +248,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
250 else 248 else
251 reg = AC97_PCM_LR_ADC_RATE; 249 reg = AC97_PCM_LR_ADC_RATE;
252 250
253 return ac97_write(codec, reg, runtime->rate); 251 return ac97_write(codec, reg, substream->runtime->rate);
254} 252}
255 253
256#define WM9705_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \ 254#define WM9705_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index b342ae50bcd6..a1541414d904 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -467,11 +467,10 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
467static int ac97_prepare(struct snd_pcm_substream *substream, 467static int ac97_prepare(struct snd_pcm_substream *substream,
468 struct snd_soc_dai *dai) 468 struct snd_soc_dai *dai)
469{ 469{
470 struct snd_pcm_runtime *runtime = substream->runtime; 470 struct snd_soc_codec *codec = dai->codec;
471 struct snd_soc_pcm_runtime *rtd = substream->private_data;
472 struct snd_soc_codec *codec =rtd->codec;
473 int reg; 471 int reg;
474 u16 vra; 472 u16 vra;
473 struct snd_pcm_runtime *runtime = substream->runtime;
475 474
476 vra = ac97_read(codec, AC97_EXTENDED_STATUS); 475 vra = ac97_read(codec, AC97_EXTENDED_STATUS);
477 ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1); 476 ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1);
@@ -487,10 +486,9 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
487static int ac97_aux_prepare(struct snd_pcm_substream *substream, 486static int ac97_aux_prepare(struct snd_pcm_substream *substream,
488 struct snd_soc_dai *dai) 487 struct snd_soc_dai *dai)
489{ 488{
490 struct snd_pcm_runtime *runtime = substream->runtime; 489 struct snd_soc_codec *codec = dai->codec;
491 struct snd_soc_pcm_runtime *rtd = substream->private_data;
492 struct snd_soc_codec *codec = rtd->codec;
493 u16 vra, xsle; 490 u16 vra, xsle;
491 struct snd_pcm_runtime *runtime = substream->runtime;
494 492
495 vra = ac97_read(codec, AC97_EXTENDED_STATUS); 493 vra = ac97_read(codec, AC97_EXTENDED_STATUS);
496 ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1); 494 ac97_write(codec, AC97_EXTENDED_STATUS, vra | 0x1);
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 6c028c470601..dfe957a47f29 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -109,12 +109,103 @@ irqreturn_t wm_hubs_dcs_done(int irq, void *data)
109} 109}
110EXPORT_SYMBOL_GPL(wm_hubs_dcs_done); 110EXPORT_SYMBOL_GPL(wm_hubs_dcs_done);
111 111
112static bool wm_hubs_dac_hp_direct(struct snd_soc_codec *codec)
113{
114 int reg;
115
116 /* If we're going via the mixer we'll need to do additional checks */
117 reg = snd_soc_read(codec, WM8993_OUTPUT_MIXER1);
118 if (!(reg & WM8993_DACL_TO_HPOUT1L)) {
119 if (reg & ~WM8993_DACL_TO_MIXOUTL) {
120 dev_vdbg(codec->dev, "Analogue paths connected: %x\n",
121 reg & ~WM8993_DACL_TO_HPOUT1L);
122 return false;
123 } else {
124 dev_vdbg(codec->dev, "HPL connected to mixer\n");
125 }
126 } else {
127 dev_vdbg(codec->dev, "HPL connected to DAC\n");
128 }
129
130 reg = snd_soc_read(codec, WM8993_OUTPUT_MIXER2);
131 if (!(reg & WM8993_DACR_TO_HPOUT1R)) {
132 if (reg & ~WM8993_DACR_TO_MIXOUTR) {
133 dev_vdbg(codec->dev, "Analogue paths connected: %x\n",
134 reg & ~WM8993_DACR_TO_HPOUT1R);
135 return false;
136 } else {
137 dev_vdbg(codec->dev, "HPR connected to mixer\n");
138 }
139 } else {
140 dev_vdbg(codec->dev, "HPR connected to DAC\n");
141 }
142
143 return true;
144}
145
146struct wm_hubs_dcs_cache {
147 struct list_head list;
148 unsigned int left;
149 unsigned int right;
150 u16 dcs_cfg;
151};
152
153static bool wm_hubs_dcs_cache_get(struct snd_soc_codec *codec,
154 struct wm_hubs_dcs_cache **entry)
155{
156 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
157 struct wm_hubs_dcs_cache *cache;
158 unsigned int left, right;
159
160 left = snd_soc_read(codec, WM8993_LEFT_OUTPUT_VOLUME);
161 left &= WM8993_HPOUT1L_VOL_MASK;
162
163 right = snd_soc_read(codec, WM8993_RIGHT_OUTPUT_VOLUME);
164 right &= WM8993_HPOUT1R_VOL_MASK;
165
166 list_for_each_entry(cache, &hubs->dcs_cache, list) {
167 if (cache->left != left || cache->right != right)
168 continue;
169
170 *entry = cache;
171 return true;
172 }
173
174 return false;
175}
176
177static void wm_hubs_dcs_cache_set(struct snd_soc_codec *codec, u16 dcs_cfg)
178{
179 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
180 struct wm_hubs_dcs_cache *cache;
181
182 if (hubs->no_cache_dac_hp_direct)
183 return;
184
185 cache = devm_kzalloc(codec->dev, sizeof(*cache), GFP_KERNEL);
186 if (!cache) {
187 dev_err(codec->dev, "Failed to allocate DCS cache entry\n");
188 return;
189 }
190
191 cache->left = snd_soc_read(codec, WM8993_LEFT_OUTPUT_VOLUME);
192 cache->left &= WM8993_HPOUT1L_VOL_MASK;
193
194 cache->right = snd_soc_read(codec, WM8993_RIGHT_OUTPUT_VOLUME);
195 cache->right &= WM8993_HPOUT1R_VOL_MASK;
196
197 cache->dcs_cfg = dcs_cfg;
198
199 list_add_tail(&cache->list, &hubs->dcs_cache);
200}
201
112/* 202/*
113 * Startup calibration of the DC servo 203 * Startup calibration of the DC servo
114 */ 204 */
115static void calibrate_dc_servo(struct snd_soc_codec *codec) 205static void calibrate_dc_servo(struct snd_soc_codec *codec)
116{ 206{
117 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); 207 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
208 struct wm_hubs_dcs_cache *cache;
118 s8 offset; 209 s8 offset;
119 u16 reg, reg_l, reg_r, dcs_cfg, dcs_reg; 210 u16 reg, reg_l, reg_r, dcs_cfg, dcs_reg;
120 211
@@ -129,10 +220,11 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
129 220
130 /* If we're using a digital only path and have a previously 221 /* If we're using a digital only path and have a previously
131 * callibrated DC servo offset stored then use that. */ 222 * callibrated DC servo offset stored then use that. */
132 if (hubs->class_w && hubs->class_w_dcs) { 223 if (wm_hubs_dac_hp_direct(codec) &&
133 dev_dbg(codec->dev, "Using cached DC servo offset %x\n", 224 wm_hubs_dcs_cache_get(codec, &cache)) {
134 hubs->class_w_dcs); 225 dev_dbg(codec->dev, "Using cached DCS offset %x for %d,%d\n",
135 snd_soc_write(codec, dcs_reg, hubs->class_w_dcs); 226 cache->dcs_cfg, cache->left, cache->right);
227 snd_soc_write(codec, dcs_reg, cache->dcs_cfg);
136 wait_for_dc_servo(codec, 228 wait_for_dc_servo(codec,
137 WM8993_DCS_TRIG_DAC_WR_0 | 229 WM8993_DCS_TRIG_DAC_WR_0 |
138 WM8993_DCS_TRIG_DAC_WR_1); 230 WM8993_DCS_TRIG_DAC_WR_1);
@@ -207,8 +299,8 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
207 299
208 /* Save the callibrated offset if we're in class W mode and 300 /* Save the callibrated offset if we're in class W mode and
209 * therefore don't have any analogue signal mixed in. */ 301 * therefore don't have any analogue signal mixed in. */
210 if (hubs->class_w && !hubs->no_cache_class_w) 302 if (wm_hubs_dac_hp_direct(codec))
211 hubs->class_w_dcs = dcs_cfg; 303 wm_hubs_dcs_cache_set(codec, dcs_cfg);
212} 304}
213 305
214/* 306/*
@@ -223,9 +315,6 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
223 315
224 ret = snd_soc_put_volsw(kcontrol, ucontrol); 316 ret = snd_soc_put_volsw(kcontrol, ucontrol);
225 317
226 /* Updating the analogue gains invalidates the DC servo cache */
227 hubs->class_w_dcs = 0;
228
229 /* If we're applying an offset correction then updating the 318 /* If we're applying an offset correction then updating the
230 * callibration would be likely to introduce further offsets. */ 319 * callibration would be likely to introduce further offsets. */
231 if (hubs->dcs_codes_l || hubs->dcs_codes_r || hubs->no_series_update) 320 if (hubs->dcs_codes_l || hubs->dcs_codes_r || hubs->no_series_update)
@@ -530,6 +619,86 @@ static int lineout_event(struct snd_soc_dapm_widget *w,
530 return 0; 619 return 0;
531} 620}
532 621
622void wm_hubs_update_class_w(struct snd_soc_codec *codec)
623{
624 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
625 int enable = WM8993_CP_DYN_V | WM8993_CP_DYN_FREQ;
626
627 if (!wm_hubs_dac_hp_direct(codec))
628 enable = false;
629
630 if (hubs->check_class_w_digital && !hubs->check_class_w_digital(codec))
631 enable = false;
632
633 dev_vdbg(codec->dev, "Class W %s\n", enable ? "enabled" : "disabled");
634
635 snd_soc_update_bits(codec, WM8993_CLASS_W_0,
636 WM8993_CP_DYN_V | WM8993_CP_DYN_FREQ, enable);
637}
638EXPORT_SYMBOL_GPL(wm_hubs_update_class_w);
639
640#define WM_HUBS_SINGLE_W(xname, reg, shift, max, invert) \
641{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
642 .info = snd_soc_info_volsw, \
643 .get = snd_soc_dapm_get_volsw, .put = class_w_put_volsw, \
644 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
645
646static int class_w_put_volsw(struct snd_kcontrol *kcontrol,
647 struct snd_ctl_elem_value *ucontrol)
648{
649 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
650 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
651 struct snd_soc_codec *codec = widget->codec;
652 int ret;
653
654 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
655
656 wm_hubs_update_class_w(codec);
657
658 return ret;
659}
660
661#define WM_HUBS_ENUM_W(xname, xenum) \
662{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
663 .info = snd_soc_info_enum_double, \
664 .get = snd_soc_dapm_get_enum_double, \
665 .put = class_w_put_double, \
666 .private_value = (unsigned long)&xenum }
667
668static int class_w_put_double(struct snd_kcontrol *kcontrol,
669 struct snd_ctl_elem_value *ucontrol)
670{
671 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
672 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
673 struct snd_soc_codec *codec = widget->codec;
674 int ret;
675
676 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
677
678 wm_hubs_update_class_w(codec);
679
680 return ret;
681}
682
683static const char *hp_mux_text[] = {
684 "Mixer",
685 "DAC",
686};
687
688static const struct soc_enum hpl_enum =
689 SOC_ENUM_SINGLE(WM8993_OUTPUT_MIXER1, 8, 2, hp_mux_text);
690
691const struct snd_kcontrol_new wm_hubs_hpl_mux =
692 WM_HUBS_ENUM_W("Left Headphone Mux", hpl_enum);
693EXPORT_SYMBOL_GPL(wm_hubs_hpl_mux);
694
695static const struct soc_enum hpr_enum =
696 SOC_ENUM_SINGLE(WM8993_OUTPUT_MIXER2, 8, 2, hp_mux_text);
697
698const struct snd_kcontrol_new wm_hubs_hpr_mux =
699 WM_HUBS_ENUM_W("Right Headphone Mux", hpr_enum);
700EXPORT_SYMBOL_GPL(wm_hubs_hpr_mux);
701
533static const struct snd_kcontrol_new in1l_pga[] = { 702static const struct snd_kcontrol_new in1l_pga[] = {
534SOC_DAPM_SINGLE("IN1LP Switch", WM8993_INPUT_MIXER2, 5, 1, 0), 703SOC_DAPM_SINGLE("IN1LP Switch", WM8993_INPUT_MIXER2, 5, 1, 0),
535SOC_DAPM_SINGLE("IN1LN Switch", WM8993_INPUT_MIXER2, 4, 1, 0), 704SOC_DAPM_SINGLE("IN1LN Switch", WM8993_INPUT_MIXER2, 4, 1, 0),
@@ -561,25 +730,25 @@ SOC_DAPM_SINGLE("IN1R Switch", WM8993_INPUT_MIXER4, 5, 1, 0),
561}; 730};
562 731
563static const struct snd_kcontrol_new left_output_mixer[] = { 732static const struct snd_kcontrol_new left_output_mixer[] = {
564SOC_DAPM_SINGLE("Right Input Switch", WM8993_OUTPUT_MIXER1, 7, 1, 0), 733WM_HUBS_SINGLE_W("Right Input Switch", WM8993_OUTPUT_MIXER1, 7, 1, 0),
565SOC_DAPM_SINGLE("Left Input Switch", WM8993_OUTPUT_MIXER1, 6, 1, 0), 734WM_HUBS_SINGLE_W("Left Input Switch", WM8993_OUTPUT_MIXER1, 6, 1, 0),
566SOC_DAPM_SINGLE("IN2RN Switch", WM8993_OUTPUT_MIXER1, 5, 1, 0), 735WM_HUBS_SINGLE_W("IN2RN Switch", WM8993_OUTPUT_MIXER1, 5, 1, 0),
567SOC_DAPM_SINGLE("IN2LN Switch", WM8993_OUTPUT_MIXER1, 4, 1, 0), 736WM_HUBS_SINGLE_W("IN2LN Switch", WM8993_OUTPUT_MIXER1, 4, 1, 0),
568SOC_DAPM_SINGLE("IN2LP Switch", WM8993_OUTPUT_MIXER1, 1, 1, 0), 737WM_HUBS_SINGLE_W("IN2LP Switch", WM8993_OUTPUT_MIXER1, 1, 1, 0),
569SOC_DAPM_SINGLE("IN1R Switch", WM8993_OUTPUT_MIXER1, 3, 1, 0), 738WM_HUBS_SINGLE_W("IN1R Switch", WM8993_OUTPUT_MIXER1, 3, 1, 0),
570SOC_DAPM_SINGLE("IN1L Switch", WM8993_OUTPUT_MIXER1, 2, 1, 0), 739WM_HUBS_SINGLE_W("IN1L Switch", WM8993_OUTPUT_MIXER1, 2, 1, 0),
571SOC_DAPM_SINGLE("DAC Switch", WM8993_OUTPUT_MIXER1, 0, 1, 0), 740WM_HUBS_SINGLE_W("DAC Switch", WM8993_OUTPUT_MIXER1, 0, 1, 0),
572}; 741};
573 742
574static const struct snd_kcontrol_new right_output_mixer[] = { 743static const struct snd_kcontrol_new right_output_mixer[] = {
575SOC_DAPM_SINGLE("Left Input Switch", WM8993_OUTPUT_MIXER2, 7, 1, 0), 744WM_HUBS_SINGLE_W("Left Input Switch", WM8993_OUTPUT_MIXER2, 7, 1, 0),
576SOC_DAPM_SINGLE("Right Input Switch", WM8993_OUTPUT_MIXER2, 6, 1, 0), 745WM_HUBS_SINGLE_W("Right Input Switch", WM8993_OUTPUT_MIXER2, 6, 1, 0),
577SOC_DAPM_SINGLE("IN2LN Switch", WM8993_OUTPUT_MIXER2, 5, 1, 0), 746WM_HUBS_SINGLE_W("IN2LN Switch", WM8993_OUTPUT_MIXER2, 5, 1, 0),
578SOC_DAPM_SINGLE("IN2RN Switch", WM8993_OUTPUT_MIXER2, 4, 1, 0), 747WM_HUBS_SINGLE_W("IN2RN Switch", WM8993_OUTPUT_MIXER2, 4, 1, 0),
579SOC_DAPM_SINGLE("IN1L Switch", WM8993_OUTPUT_MIXER2, 3, 1, 0), 748WM_HUBS_SINGLE_W("IN1L Switch", WM8993_OUTPUT_MIXER2, 3, 1, 0),
580SOC_DAPM_SINGLE("IN1R Switch", WM8993_OUTPUT_MIXER2, 2, 1, 0), 749WM_HUBS_SINGLE_W("IN1R Switch", WM8993_OUTPUT_MIXER2, 2, 1, 0),
581SOC_DAPM_SINGLE("IN2RP Switch", WM8993_OUTPUT_MIXER2, 1, 1, 0), 750WM_HUBS_SINGLE_W("IN2RP Switch", WM8993_OUTPUT_MIXER2, 1, 1, 0),
582SOC_DAPM_SINGLE("DAC Switch", WM8993_OUTPUT_MIXER2, 0, 1, 0), 751WM_HUBS_SINGLE_W("DAC Switch", WM8993_OUTPUT_MIXER2, 0, 1, 0),
583}; 752};
584 753
585static const struct snd_kcontrol_new earpiece_mixer[] = { 754static const struct snd_kcontrol_new earpiece_mixer[] = {
@@ -943,6 +1112,7 @@ int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
943 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); 1112 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
944 struct snd_soc_dapm_context *dapm = &codec->dapm; 1113 struct snd_soc_dapm_context *dapm = &codec->dapm;
945 1114
1115 INIT_LIST_HEAD(&hubs->dcs_cache);
946 init_completion(&hubs->dcs_done); 1116 init_completion(&hubs->dcs_done);
947 1117
948 snd_soc_dapm_add_routes(dapm, analogue_routes, 1118 snd_soc_dapm_add_routes(dapm, analogue_routes,
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index 5705276f4943..da2dc899ce6d 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -16,6 +16,8 @@
16 16
17#include <linux/completion.h> 17#include <linux/completion.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/list.h>
20#include <sound/control.h>
19 21
20struct snd_soc_codec; 22struct snd_soc_codec;
21 23
@@ -30,9 +32,9 @@ struct wm_hubs_data {
30 int series_startup; 32 int series_startup;
31 int no_series_update; 33 int no_series_update;
32 34
33 bool no_cache_class_w; 35 bool no_cache_dac_hp_direct;
34 bool class_w; 36 struct list_head dcs_cache;
35 u16 class_w_dcs; 37 bool (*check_class_w_digital)(struct snd_soc_codec *);
36 38
37 bool lineout1_se; 39 bool lineout1_se;
38 bool lineout1n_ena; 40 bool lineout1n_ena;
@@ -58,5 +60,9 @@ extern irqreturn_t wm_hubs_dcs_done(int irq, void *data);
58extern void wm_hubs_vmid_ena(struct snd_soc_codec *codec); 60extern void wm_hubs_vmid_ena(struct snd_soc_codec *codec);
59extern void wm_hubs_set_bias_level(struct snd_soc_codec *codec, 61extern void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
60 enum snd_soc_bias_level level); 62 enum snd_soc_bias_level level);
63extern void wm_hubs_update_class_w(struct snd_soc_codec *codec);
64
65extern const struct snd_kcontrol_new wm_hubs_hpl_mux;
66extern const struct snd_kcontrol_new wm_hubs_hpr_mux;
61 67
62#endif 68#endif
diff --git a/sound/soc/ep93xx/ep93xx-ac97.c b/sound/soc/ep93xx/ep93xx-ac97.c
index 0678637abd66..bdffab33e160 100644
--- a/sound/soc/ep93xx/ep93xx-ac97.c
+++ b/sound/soc/ep93xx/ep93xx-ac97.c
@@ -87,17 +87,13 @@
87 * struct ep93xx_ac97_info - EP93xx AC97 controller info structure 87 * struct ep93xx_ac97_info - EP93xx AC97 controller info structure
88 * @lock: mutex serializing access to the bus (slot 1 & 2 ops) 88 * @lock: mutex serializing access to the bus (slot 1 & 2 ops)
89 * @dev: pointer to the platform device dev structure 89 * @dev: pointer to the platform device dev structure
90 * @mem: physical memory resource for the registers
91 * @regs: mapped AC97 controller registers 90 * @regs: mapped AC97 controller registers
92 * @irq: AC97 interrupt number
93 * @done: bus ops wait here for an interrupt 91 * @done: bus ops wait here for an interrupt
94 */ 92 */
95struct ep93xx_ac97_info { 93struct ep93xx_ac97_info {
96 struct mutex lock; 94 struct mutex lock;
97 struct device *dev; 95 struct device *dev;
98 struct resource *mem;
99 void __iomem *regs; 96 void __iomem *regs;
100 int irq;
101 struct completion done; 97 struct completion done;
102}; 98};
103 99
@@ -359,66 +355,50 @@ static struct snd_soc_dai_driver ep93xx_ac97_dai = {
359static int __devinit ep93xx_ac97_probe(struct platform_device *pdev) 355static int __devinit ep93xx_ac97_probe(struct platform_device *pdev)
360{ 356{
361 struct ep93xx_ac97_info *info; 357 struct ep93xx_ac97_info *info;
358 struct resource *res;
359 unsigned int irq;
362 int ret; 360 int ret;
363 361
364 info = kzalloc(sizeof(struct ep93xx_ac97_info), GFP_KERNEL); 362 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
365 if (!info) 363 if (!info)
366 return -ENOMEM; 364 return -ENOMEM;
367 365
368 dev_set_drvdata(&pdev->dev, info); 366 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
369 367 if (!res)
370 mutex_init(&info->lock); 368 return -ENODEV;
371 init_completion(&info->done);
372 info->dev = &pdev->dev;
373 369
374 info->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 370 info->regs = devm_request_and_ioremap(&pdev->dev, res);
375 if (!info->mem) { 371 if (!info->regs)
376 ret = -ENXIO; 372 return -ENXIO;
377 goto fail_free_info;
378 }
379 373
380 info->irq = platform_get_irq(pdev, 0); 374 irq = platform_get_irq(pdev, 0);
381 if (!info->irq) { 375 if (!irq)
382 ret = -ENXIO; 376 return -ENODEV;
383 goto fail_free_info;
384 }
385 377
386 if (!request_mem_region(info->mem->start, resource_size(info->mem), 378 ret = devm_request_irq(&pdev->dev, irq, ep93xx_ac97_interrupt,
387 pdev->name)) { 379 IRQF_TRIGGER_HIGH, pdev->name, info);
388 ret = -EBUSY; 380 if (ret)
389 goto fail_free_info; 381 goto fail;
390 }
391 382
392 info->regs = ioremap(info->mem->start, resource_size(info->mem)); 383 dev_set_drvdata(&pdev->dev, info);
393 if (!info->regs) {
394 ret = -ENOMEM;
395 goto fail_release_mem;
396 }
397 384
398 ret = request_irq(info->irq, ep93xx_ac97_interrupt, IRQF_TRIGGER_HIGH, 385 mutex_init(&info->lock);
399 pdev->name, info); 386 init_completion(&info->done);
400 if (ret) 387 info->dev = &pdev->dev;
401 goto fail_unmap_mem;
402 388
403 ep93xx_ac97_info = info; 389 ep93xx_ac97_info = info;
404 platform_set_drvdata(pdev, info); 390 platform_set_drvdata(pdev, info);
405 391
406 ret = snd_soc_register_dai(&pdev->dev, &ep93xx_ac97_dai); 392 ret = snd_soc_register_dai(&pdev->dev, &ep93xx_ac97_dai);
407 if (ret) 393 if (ret)
408 goto fail_free_irq; 394 goto fail;
409 395
410 return 0; 396 return 0;
411 397
412fail_free_irq: 398fail:
413 platform_set_drvdata(pdev, NULL); 399 platform_set_drvdata(pdev, NULL);
414 free_irq(info->irq, info); 400 ep93xx_ac97_info = NULL;
415fail_unmap_mem: 401 dev_set_drvdata(&pdev->dev, NULL);
416 iounmap(info->regs);
417fail_release_mem:
418 release_mem_region(info->mem->start, resource_size(info->mem));
419fail_free_info:
420 kfree(info);
421
422 return ret; 402 return ret;
423} 403}
424 404
@@ -431,11 +411,9 @@ static int __devexit ep93xx_ac97_remove(struct platform_device *pdev)
431 /* disable the AC97 controller */ 411 /* disable the AC97 controller */
432 ep93xx_ac97_write_reg(info, AC97GCR, 0); 412 ep93xx_ac97_write_reg(info, AC97GCR, 0);
433 413
434 free_irq(info->irq, info);
435 iounmap(info->regs);
436 release_mem_region(info->mem->start, resource_size(info->mem));
437 platform_set_drvdata(pdev, NULL); 414 platform_set_drvdata(pdev, NULL);
438 kfree(info); 415 ep93xx_ac97_info = NULL;
416 dev_set_drvdata(&pdev->dev, NULL);
439 417
440 return 0; 418 return 0;
441} 419}
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c
index f7a62348e3fe..8df8f6dc474f 100644
--- a/sound/soc/ep93xx/ep93xx-i2s.c
+++ b/sound/soc/ep93xx/ep93xx-i2s.c
@@ -63,7 +63,6 @@ struct ep93xx_i2s_info {
63 struct clk *sclk; 63 struct clk *sclk;
64 struct clk *lrclk; 64 struct clk *lrclk;
65 struct ep93xx_pcm_dma_params *dma_params; 65 struct ep93xx_pcm_dma_params *dma_params;
66 struct resource *mem;
67 void __iomem *regs; 66 void __iomem *regs;
68}; 67};
69 68
@@ -373,38 +372,22 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
373 struct resource *res; 372 struct resource *res;
374 int err; 373 int err;
375 374
376 info = kzalloc(sizeof(struct ep93xx_i2s_info), GFP_KERNEL); 375 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
377 if (!info) { 376 if (!info)
378 err = -ENOMEM; 377 return -ENOMEM;
379 goto fail;
380 }
381
382 dev_set_drvdata(&pdev->dev, info);
383 info->dma_params = ep93xx_i2s_dma_params;
384 378
385 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 379 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
386 if (!res) { 380 if (!res)
387 err = -ENODEV; 381 return -ENODEV;
388 goto fail_free_info;
389 }
390 382
391 info->mem = request_mem_region(res->start, resource_size(res), 383 info->regs = devm_request_and_ioremap(&pdev->dev, res);
392 pdev->name); 384 if (!info->regs)
393 if (!info->mem) { 385 return -ENXIO;
394 err = -EBUSY;
395 goto fail_free_info;
396 }
397
398 info->regs = ioremap(info->mem->start, resource_size(info->mem));
399 if (!info->regs) {
400 err = -ENXIO;
401 goto fail_release_mem;
402 }
403 386
404 info->mclk = clk_get(&pdev->dev, "mclk"); 387 info->mclk = clk_get(&pdev->dev, "mclk");
405 if (IS_ERR(info->mclk)) { 388 if (IS_ERR(info->mclk)) {
406 err = PTR_ERR(info->mclk); 389 err = PTR_ERR(info->mclk);
407 goto fail_unmap_mem; 390 goto fail;
408 } 391 }
409 392
410 info->sclk = clk_get(&pdev->dev, "sclk"); 393 info->sclk = clk_get(&pdev->dev, "sclk");
@@ -419,6 +402,9 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
419 goto fail_put_sclk; 402 goto fail_put_sclk;
420 } 403 }
421 404
405 dev_set_drvdata(&pdev->dev, info);
406 info->dma_params = ep93xx_i2s_dma_params;
407
422 err = snd_soc_register_dai(&pdev->dev, &ep93xx_i2s_dai); 408 err = snd_soc_register_dai(&pdev->dev, &ep93xx_i2s_dai);
423 if (err) 409 if (err)
424 goto fail_put_lrclk; 410 goto fail_put_lrclk;
@@ -426,17 +412,12 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
426 return 0; 412 return 0;
427 413
428fail_put_lrclk: 414fail_put_lrclk:
415 dev_set_drvdata(&pdev->dev, NULL);
429 clk_put(info->lrclk); 416 clk_put(info->lrclk);
430fail_put_sclk: 417fail_put_sclk:
431 clk_put(info->sclk); 418 clk_put(info->sclk);
432fail_put_mclk: 419fail_put_mclk:
433 clk_put(info->mclk); 420 clk_put(info->mclk);
434fail_unmap_mem:
435 iounmap(info->regs);
436fail_release_mem:
437 release_mem_region(info->mem->start, resource_size(info->mem));
438fail_free_info:
439 kfree(info);
440fail: 421fail:
441 return err; 422 return err;
442} 423}
@@ -446,12 +427,10 @@ static int __devexit ep93xx_i2s_remove(struct platform_device *pdev)
446 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev); 427 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev);
447 428
448 snd_soc_unregister_dai(&pdev->dev); 429 snd_soc_unregister_dai(&pdev->dev);
430 dev_set_drvdata(&pdev->dev, NULL);
449 clk_put(info->lrclk); 431 clk_put(info->lrclk);
450 clk_put(info->sclk); 432 clk_put(info->sclk);
451 clk_put(info->mclk); 433 clk_put(info->mclk);
452 iounmap(info->regs);
453 release_mem_region(info->mem->start, resource_size(info->mem));
454 kfree(info);
455 return 0; 434 return 0;
456} 435}
457 436
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index d754d34d68a6..d70133086ac3 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -1,18 +1,31 @@
1config SND_MPC52xx_DMA 1config SND_SOC_FSL_SSI
2 tristate 2 tristate
3 3
4# ASoC platform support for the Freescale PowerPC SOCs that have an SSI and 4config SND_SOC_FSL_UTILS
5# an Elo DMA controller, such as the MPC8610 and P1022. You will still need to
6# select a platform driver and a codec driver.
7config SND_SOC_POWERPC_SSI
8 tristate 5 tristate
6
7menuconfig SND_POWERPC_SOC
8 tristate "SoC Audio for Freescale PowerPC CPUs"
9 depends on FSL_SOC 9 depends on FSL_SOC
10 help
11 Say Y or M if you want to add support for codecs attached to
12 the PowerPC CPUs.
13
14if SND_POWERPC_SOC
15
16config SND_MPC52xx_DMA
17 tristate
18
19config SND_SOC_POWERPC_DMA
20 tristate
10 21
11config SND_SOC_MPC8610_HPCD 22config SND_SOC_MPC8610_HPCD
12 tristate "ALSA SoC support for the Freescale MPC8610 HPCD board" 23 tristate "ALSA SoC support for the Freescale MPC8610 HPCD board"
13 # I2C is necessary for the CS4270 driver 24 # I2C is necessary for the CS4270 driver
14 depends on MPC8610_HPCD && I2C 25 depends on MPC8610_HPCD && I2C
15 select SND_SOC_POWERPC_SSI 26 select SND_SOC_FSL_SSI
27 select SND_SOC_FSL_UTILS
28 select SND_SOC_POWERPC_DMA
16 select SND_SOC_CS4270 29 select SND_SOC_CS4270
17 select SND_SOC_CS4270_VD33_ERRATA 30 select SND_SOC_CS4270_VD33_ERRATA
18 default y if MPC8610_HPCD 31 default y if MPC8610_HPCD
@@ -23,7 +36,9 @@ config SND_SOC_P1022_DS
23 tristate "ALSA SoC support for the Freescale P1022 DS board" 36 tristate "ALSA SoC support for the Freescale P1022 DS board"
24 # I2C is necessary for the WM8776 driver 37 # I2C is necessary for the WM8776 driver
25 depends on P1022_DS && I2C 38 depends on P1022_DS && I2C
26 select SND_SOC_POWERPC_SSI 39 select SND_SOC_FSL_SSI
40 select SND_SOC_FSL_UTILS
41 select SND_SOC_POWERPC_DMA
27 select SND_SOC_WM8776 42 select SND_SOC_WM8776
28 default y if P1022_DS 43 default y if P1022_DS
29 help 44 help
@@ -65,3 +80,103 @@ config SND_MPC52xx_SOC_EFIKA
65 help 80 help
66 Say Y if you want to add support for sound on the Efika. 81 Say Y if you want to add support for sound on the Efika.
67 82
83endif # SND_POWERPC_SOC
84
85menuconfig SND_IMX_SOC
86 tristate "SoC Audio for Freescale i.MX CPUs"
87 depends on ARCH_MXC
88 help
89 Say Y or M if you want to add support for codecs attached to
90 the i.MX CPUs.
91
92if SND_IMX_SOC
93
94config SND_SOC_IMX_SSI
95 tristate
96
97config SND_SOC_IMX_PCM
98 tristate
99
100config SND_SOC_IMX_PCM_FIQ
101 tristate
102 select FIQ
103 select SND_SOC_IMX_PCM
104
105config SND_SOC_IMX_PCM_DMA
106 tristate
107 select SND_SOC_DMAENGINE_PCM
108 select SND_SOC_IMX_PCM
109
110config SND_SOC_IMX_AUDMUX
111 tristate
112
113config SND_MXC_SOC_WM1133_EV1
114 tristate "Audio on the i.MX31ADS with WM1133-EV1 fitted"
115 depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL
116 select SND_SOC_WM8350
117 select SND_SOC_IMX_PCM_FIQ
118 select SND_SOC_IMX_AUDMUX
119 select SND_SOC_IMX_SSI
120 help
121 Enable support for audio on the i.MX31ADS with the WM1133-EV1
122 PMIC board with WM8835x fitted.
123
124config SND_SOC_MX27VIS_AIC32X4
125 tristate "SoC audio support for Visstrim M10 boards"
126 depends on MACH_IMX27_VISSTRIM_M10 && I2C
127 select SND_SOC_TLV320AIC32X4
128 select SND_SOC_IMX_PCM_DMA
129 select SND_SOC_IMX_AUDMUX
130 select SND_SOC_IMX_SSI
131 help
132 Say Y if you want to add support for SoC audio on Visstrim SM10
133 board with TLV320AIC32X4 codec.
134
135config SND_SOC_PHYCORE_AC97
136 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
137 depends on MACH_PCM043 || MACH_PCA100
138 select SND_SOC_AC97_BUS
139 select SND_SOC_WM9712
140 select SND_SOC_IMX_PCM_FIQ
141 select SND_SOC_IMX_AUDMUX
142 select SND_SOC_IMX_SSI
143 help
144 Say Y if you want to add support for SoC audio on Phytec phyCORE
145 and phyCARD boards in AC97 mode
146
147config SND_SOC_EUKREA_TLV320
148 tristate "Eukrea TLV320"
149 depends on MACH_EUKREA_MBIMX27_BASEBOARD \
150 || MACH_EUKREA_MBIMXSD25_BASEBOARD \
151 || MACH_EUKREA_MBIMXSD35_BASEBOARD \
152 || MACH_EUKREA_MBIMXSD51_BASEBOARD
153 depends on I2C
154 select SND_SOC_TLV320AIC23
155 select SND_SOC_IMX_PCM_FIQ
156 select SND_SOC_IMX_AUDMUX
157 select SND_SOC_IMX_SSI
158 help
159 Enable I2S based access to the TLV320AIC23B codec attached
160 to the SSI interface
161
162config SND_SOC_IMX_SGTL5000
163 tristate "SoC Audio support for i.MX boards with sgtl5000"
164 depends on OF && I2C
165 select SND_SOC_SGTL5000
166 select SND_SOC_IMX_PCM_DMA
167 select SND_SOC_IMX_AUDMUX
168 select SND_SOC_FSL_SSI
169 select SND_SOC_FSL_UTILS
170 help
171 Say Y if you want to add support for SoC audio on an i.MX board with
172 a sgtl5000 codec.
173
174config SND_SOC_IMX_MC13783
175 tristate "SoC Audio support for I.MX boards with mc13783"
176 depends on MFD_MC13783
177 select SND_SOC_IMX_SSI
178 select SND_SOC_IMX_AUDMUX
179 select SND_SOC_MC13783
180 select SND_SOC_IMX_PCM_DMA
181
182endif # SND_IMX_SOC
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index b4a38c0ac58c..5f3cf3f52ea0 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -8,8 +8,11 @@ obj-$(CONFIG_SND_SOC_P1022_DS) += snd-soc-p1022-ds.o
8 8
9# Freescale PowerPC SSI/DMA Platform Support 9# Freescale PowerPC SSI/DMA Platform Support
10snd-soc-fsl-ssi-objs := fsl_ssi.o 10snd-soc-fsl-ssi-objs := fsl_ssi.o
11snd-soc-fsl-utils-objs := fsl_utils.o
11snd-soc-fsl-dma-objs := fsl_dma.o 12snd-soc-fsl-dma-objs := fsl_dma.o
12obj-$(CONFIG_SND_SOC_POWERPC_SSI) += snd-soc-fsl-ssi.o snd-soc-fsl-dma.o 13obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o
14obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o
15obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
13 16
14# MPC5200 Platform Support 17# MPC5200 Platform Support
15obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o 18obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o
@@ -20,3 +23,29 @@ obj-$(CONFIG_SND_SOC_MPC5200_AC97) += mpc5200_psc_ac97.o
20obj-$(CONFIG_SND_MPC52xx_SOC_PCM030) += pcm030-audio-fabric.o 23obj-$(CONFIG_SND_MPC52xx_SOC_PCM030) += pcm030-audio-fabric.o
21obj-$(CONFIG_SND_MPC52xx_SOC_EFIKA) += efika-audio-fabric.o 24obj-$(CONFIG_SND_MPC52xx_SOC_EFIKA) += efika-audio-fabric.o
22 25
26# i.MX Platform Support
27snd-soc-imx-ssi-objs := imx-ssi.o
28snd-soc-imx-audmux-objs := imx-audmux.o
29
30obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o
31obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o
32
33obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o
34snd-soc-imx-pcm-y := imx-pcm.o
35snd-soc-imx-pcm-$(CONFIG_SND_SOC_IMX_PCM_FIQ) += imx-pcm-fiq.o
36snd-soc-imx-pcm-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o
37
38# i.MX Machine Support
39snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
40snd-soc-phycore-ac97-objs := phycore-ac97.o
41snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
42snd-soc-wm1133-ev1-objs := wm1133-ev1.o
43snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
44snd-soc-imx-mc13783-objs := imx-mc13783.o
45
46obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
47obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
48obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
49obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
50obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
51obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
index 7d4475cfdb24..efb9ede01208 100644
--- a/sound/soc/imx/eukrea-tlv320.c
+++ b/sound/soc/fsl/eukrea-tlv320.c
@@ -7,7 +7,7 @@
7 * which is Copyright 2009 Simtec Electronics 7 * which is Copyright 2009 Simtec Electronics
8 * and on sound/soc/imx/phycore-ac97.c which is 8 * and on sound/soc/imx/phycore-ac97.c which is
9 * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> 9 * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify it 11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the 12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your 13 * Free Software Foundation; either version 2 of the License, or (at your
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 2eb407fa3b48..4ed2afd47782 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -11,11 +11,15 @@
11 */ 11 */
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/io.h>
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/clk.h>
16#include <linux/device.h> 18#include <linux/device.h>
17#include <linux/delay.h> 19#include <linux/delay.h>
18#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/of_address.h>
22#include <linux/of_irq.h>
19#include <linux/of_platform.h> 23#include <linux/of_platform.h>
20 24
21#include <sound/core.h> 25#include <sound/core.h>
@@ -25,6 +29,26 @@
25#include <sound/soc.h> 29#include <sound/soc.h>
26 30
27#include "fsl_ssi.h" 31#include "fsl_ssi.h"
32#include "imx-pcm.h"
33
34#ifdef PPC
35#define read_ssi(addr) in_be32(addr)
36#define write_ssi(val, addr) out_be32(addr, val)
37#define write_ssi_mask(addr, clear, set) clrsetbits_be32(addr, clear, set)
38#elif defined ARM
39#define read_ssi(addr) readl(addr)
40#define write_ssi(val, addr) writel(val, addr)
41/*
42 * FIXME: Proper locking should be added at write_ssi_mask caller level
43 * to ensure this register read/modify/write sequence is race free.
44 */
45static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set)
46{
47 u32 val = readl(addr);
48 val = (val & ~clear) | set;
49 writel(val, addr);
50}
51#endif
28 52
29/** 53/**
30 * FSLSSI_I2S_RATES: sample rates supported by the I2S 54 * FSLSSI_I2S_RATES: sample rates supported by the I2S
@@ -94,6 +118,13 @@ struct fsl_ssi_private {
94 struct device_attribute dev_attr; 118 struct device_attribute dev_attr;
95 struct platform_device *pdev; 119 struct platform_device *pdev;
96 120
121 bool new_binding;
122 bool ssi_on_imx;
123 struct clk *clk;
124 struct platform_device *imx_pcm_pdev;
125 struct imx_pcm_dma_params dma_params_tx;
126 struct imx_pcm_dma_params dma_params_rx;
127
97 struct { 128 struct {
98 unsigned int rfrc; 129 unsigned int rfrc;
99 unsigned int tfrc; 130 unsigned int tfrc;
@@ -145,7 +176,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
145 were interrupted for. We mask it with the Interrupt Enable register 176 were interrupted for. We mask it with the Interrupt Enable register
146 so that we only check for events that we're interested in. 177 so that we only check for events that we're interested in.
147 */ 178 */
148 sisr = in_be32(&ssi->sisr) & SIER_FLAGS; 179 sisr = read_ssi(&ssi->sisr) & SIER_FLAGS;
149 180
150 if (sisr & CCSR_SSI_SISR_RFRC) { 181 if (sisr & CCSR_SSI_SISR_RFRC) {
151 ssi_private->stats.rfrc++; 182 ssi_private->stats.rfrc++;
@@ -260,7 +291,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
260 291
261 /* Clear the bits that we set */ 292 /* Clear the bits that we set */
262 if (sisr2) 293 if (sisr2)
263 out_be32(&ssi->sisr, sisr2); 294 write_ssi(sisr2, &ssi->sisr);
264 295
265 return ret; 296 return ret;
266} 297}
@@ -295,7 +326,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
295 * SSI needs to be disabled before updating the registers we set 326 * SSI needs to be disabled before updating the registers we set
296 * here. 327 * here.
297 */ 328 */
298 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 329 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
299 330
300 /* 331 /*
301 * Program the SSI into I2S Slave Non-Network Synchronous mode. 332 * Program the SSI into I2S Slave Non-Network Synchronous mode.
@@ -303,20 +334,18 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
303 * 334 *
304 * FIXME: Little-endian samples require a different shift dir 335 * FIXME: Little-endian samples require a different shift dir
305 */ 336 */
306 clrsetbits_be32(&ssi->scr, 337 write_ssi_mask(&ssi->scr,
307 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN, 338 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
308 CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE 339 CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE
309 | (synchronous ? CCSR_SSI_SCR_SYN : 0)); 340 | (synchronous ? CCSR_SSI_SCR_SYN : 0));
310 341
311 out_be32(&ssi->stcr, 342 write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
312 CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
313 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS | 343 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
314 CCSR_SSI_STCR_TSCKP); 344 CCSR_SSI_STCR_TSCKP, &ssi->stcr);
315 345
316 out_be32(&ssi->srcr, 346 write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
317 CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
318 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS | 347 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
319 CCSR_SSI_SRCR_RSCKP); 348 CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
320 349
321 /* 350 /*
322 * The DC and PM bits are only used if the SSI is the clock 351 * The DC and PM bits are only used if the SSI is the clock
@@ -324,7 +353,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
324 */ 353 */
325 354
326 /* Enable the interrupts and DMA requests */ 355 /* Enable the interrupts and DMA requests */
327 out_be32(&ssi->sier, SIER_FLAGS); 356 write_ssi(SIER_FLAGS, &ssi->sier);
328 357
329 /* 358 /*
330 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We 359 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
@@ -339,9 +368,9 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
339 * make this value larger (and maybe we should), but this way 368 * make this value larger (and maybe we should), but this way
340 * data will be written to memory as soon as it's available. 369 * data will be written to memory as soon as it's available.
341 */ 370 */
342 out_be32(&ssi->sfcsr, 371 write_ssi(CCSR_SSI_SFCSR_TFWM0(ssi_private->fifo_depth - 2) |
343 CCSR_SSI_SFCSR_TFWM0(ssi_private->fifo_depth - 2) | 372 CCSR_SSI_SFCSR_RFWM0(ssi_private->fifo_depth - 2),
344 CCSR_SSI_SFCSR_RFWM0(ssi_private->fifo_depth - 2)); 373 &ssi->sfcsr);
345 374
346 /* 375 /*
347 * We keep the SSI disabled because if we enable it, then the 376 * We keep the SSI disabled because if we enable it, then the
@@ -393,6 +422,12 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
393 ssi_private->second_stream = substream; 422 ssi_private->second_stream = substream;
394 } 423 }
395 424
425 if (ssi_private->ssi_on_imx)
426 snd_soc_dai_set_dma_data(dai, substream,
427 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
428 &ssi_private->dma_params_tx :
429 &ssi_private->dma_params_rx);
430
396 return 0; 431 return 0;
397} 432}
398 433
@@ -417,7 +452,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
417 unsigned int sample_size = 452 unsigned int sample_size =
418 snd_pcm_format_width(params_format(hw_params)); 453 snd_pcm_format_width(params_format(hw_params));
419 u32 wl = CCSR_SSI_SxCCR_WL(sample_size); 454 u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
420 int enabled = in_be32(&ssi->scr) & CCSR_SSI_SCR_SSIEN; 455 int enabled = read_ssi(&ssi->scr) & CCSR_SSI_SCR_SSIEN;
421 456
422 /* 457 /*
423 * If we're in synchronous mode, and the SSI is already enabled, 458 * If we're in synchronous mode, and the SSI is already enabled,
@@ -439,9 +474,9 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
439 /* In synchronous mode, the SSI uses STCCR for capture */ 474 /* In synchronous mode, the SSI uses STCCR for capture */
440 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) || 475 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ||
441 ssi_private->cpu_dai_drv.symmetric_rates) 476 ssi_private->cpu_dai_drv.symmetric_rates)
442 clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl); 477 write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl);
443 else 478 else
444 clrsetbits_be32(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl); 479 write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl);
445 480
446 return 0; 481 return 0;
447} 482}
@@ -466,19 +501,19 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
466 case SNDRV_PCM_TRIGGER_START: 501 case SNDRV_PCM_TRIGGER_START:
467 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 502 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
468 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 503 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
469 setbits32(&ssi->scr, 504 write_ssi_mask(&ssi->scr, 0,
470 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE); 505 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
471 else 506 else
472 setbits32(&ssi->scr, 507 write_ssi_mask(&ssi->scr, 0,
473 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE); 508 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
474 break; 509 break;
475 510
476 case SNDRV_PCM_TRIGGER_STOP: 511 case SNDRV_PCM_TRIGGER_STOP:
477 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 512 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
478 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 513 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
479 clrbits32(&ssi->scr, CCSR_SSI_SCR_TE); 514 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TE, 0);
480 else 515 else
481 clrbits32(&ssi->scr, CCSR_SSI_SCR_RE); 516 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_RE, 0);
482 break; 517 break;
483 518
484 default: 519 default:
@@ -510,7 +545,7 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
510 if (!ssi_private->first_stream) { 545 if (!ssi_private->first_stream) {
511 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 546 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
512 547
513 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 548 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
514 } 549 }
515} 550}
516 551
@@ -622,12 +657,6 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
622 if (!of_device_is_available(np)) 657 if (!of_device_is_available(np))
623 return -ENODEV; 658 return -ENODEV;
624 659
625 /* Check for a codec-handle property. */
626 if (!of_get_property(np, "codec-handle", NULL)) {
627 dev_err(&pdev->dev, "missing codec-handle property\n");
628 return -ENODEV;
629 }
630
631 /* We only support the SSI in "I2S Slave" mode */ 660 /* We only support the SSI in "I2S Slave" mode */
632 sprop = of_get_property(np, "fsl,mode", NULL); 661 sprop = of_get_property(np, "fsl,mode", NULL);
633 if (!sprop || strcmp(sprop, "i2s-slave")) { 662 if (!sprop || strcmp(sprop, "i2s-slave")) {
@@ -692,6 +721,50 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
692 /* Older 8610 DTs didn't have the fifo-depth property */ 721 /* Older 8610 DTs didn't have the fifo-depth property */
693 ssi_private->fifo_depth = 8; 722 ssi_private->fifo_depth = 8;
694 723
724 if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) {
725 u32 dma_events[2];
726 ssi_private->ssi_on_imx = true;
727
728 ssi_private->clk = clk_get(&pdev->dev, NULL);
729 if (IS_ERR(ssi_private->clk)) {
730 ret = PTR_ERR(ssi_private->clk);
731 dev_err(&pdev->dev, "could not get clock: %d\n", ret);
732 goto error_irq;
733 }
734 clk_prepare_enable(ssi_private->clk);
735
736 /*
737 * We have burstsize be "fifo_depth - 2" to match the SSI
738 * watermark setting in fsl_ssi_startup().
739 */
740 ssi_private->dma_params_tx.burstsize =
741 ssi_private->fifo_depth - 2;
742 ssi_private->dma_params_rx.burstsize =
743 ssi_private->fifo_depth - 2;
744 ssi_private->dma_params_tx.dma_addr =
745 ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0);
746 ssi_private->dma_params_rx.dma_addr =
747 ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0);
748 /*
749 * TODO: This is a temporary solution and should be changed
750 * to use generic DMA binding later when the helplers get in.
751 */
752 ret = of_property_read_u32_array(pdev->dev.of_node,
753 "fsl,ssi-dma-events", dma_events, 2);
754 if (ret) {
755 dev_err(&pdev->dev, "could not get dma events\n");
756 goto error_clk;
757 }
758 ssi_private->dma_params_tx.dma = dma_events[0];
759 ssi_private->dma_params_rx.dma = dma_events[1];
760
761 ssi_private->dma_params_tx.shared_peripheral =
762 of_device_is_compatible(of_get_parent(np),
763 "fsl,spba-bus");
764 ssi_private->dma_params_rx.shared_peripheral =
765 ssi_private->dma_params_tx.shared_peripheral;
766 }
767
695 /* Initialize the the device_attribute structure */ 768 /* Initialize the the device_attribute structure */
696 dev_attr = &ssi_private->dev_attr; 769 dev_attr = &ssi_private->dev_attr;
697 sysfs_attr_init(&dev_attr->attr); 770 sysfs_attr_init(&dev_attr->attr);
@@ -715,6 +788,26 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
715 goto error_dev; 788 goto error_dev;
716 } 789 }
717 790
791 if (ssi_private->ssi_on_imx) {
792 ssi_private->imx_pcm_pdev =
793 platform_device_register_simple("imx-pcm-audio",
794 -1, NULL, 0);
795 if (IS_ERR(ssi_private->imx_pcm_pdev)) {
796 ret = PTR_ERR(ssi_private->imx_pcm_pdev);
797 goto error_dev;
798 }
799 }
800
801 /*
802 * If codec-handle property is missing from SSI node, we assume
803 * that the machine driver uses new binding which does not require
804 * SSI driver to trigger machine driver's probe.
805 */
806 if (!of_get_property(np, "codec-handle", NULL)) {
807 ssi_private->new_binding = true;
808 goto done;
809 }
810
718 /* Trigger the machine driver's probe function. The platform driver 811 /* Trigger the machine driver's probe function. The platform driver
719 * name of the machine driver is taken from /compatible property of the 812 * name of the machine driver is taken from /compatible property of the
720 * device tree. We also pass the address of the CPU DAI driver 813 * device tree. We also pass the address of the CPU DAI driver
@@ -736,15 +829,24 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev)
736 goto error_dai; 829 goto error_dai;
737 } 830 }
738 831
832done:
739 return 0; 833 return 0;
740 834
741error_dai: 835error_dai:
836 if (ssi_private->ssi_on_imx)
837 platform_device_unregister(ssi_private->imx_pcm_pdev);
742 snd_soc_unregister_dai(&pdev->dev); 838 snd_soc_unregister_dai(&pdev->dev);
743 839
744error_dev: 840error_dev:
745 dev_set_drvdata(&pdev->dev, NULL); 841 dev_set_drvdata(&pdev->dev, NULL);
746 device_remove_file(&pdev->dev, dev_attr); 842 device_remove_file(&pdev->dev, dev_attr);
747 843
844error_clk:
845 if (ssi_private->ssi_on_imx) {
846 clk_disable_unprepare(ssi_private->clk);
847 clk_put(ssi_private->clk);
848 }
849
748error_irq: 850error_irq:
749 free_irq(ssi_private->irq, ssi_private); 851 free_irq(ssi_private->irq, ssi_private);
750 852
@@ -764,7 +866,13 @@ static int fsl_ssi_remove(struct platform_device *pdev)
764{ 866{
765 struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev); 867 struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev);
766 868
767 platform_device_unregister(ssi_private->pdev); 869 if (!ssi_private->new_binding)
870 platform_device_unregister(ssi_private->pdev);
871 if (ssi_private->ssi_on_imx) {
872 platform_device_unregister(ssi_private->imx_pcm_pdev);
873 clk_disable_unprepare(ssi_private->clk);
874 clk_put(ssi_private->clk);
875 }
768 snd_soc_unregister_dai(&pdev->dev); 876 snd_soc_unregister_dai(&pdev->dev);
769 device_remove_file(&pdev->dev, &ssi_private->dev_attr); 877 device_remove_file(&pdev->dev, &ssi_private->dev_attr);
770 878
@@ -779,6 +887,7 @@ static int fsl_ssi_remove(struct platform_device *pdev)
779 887
780static const struct of_device_id fsl_ssi_ids[] = { 888static const struct of_device_id fsl_ssi_ids[] = {
781 { .compatible = "fsl,mpc8610-ssi", }, 889 { .compatible = "fsl,mpc8610-ssi", },
890 { .compatible = "fsl,imx21-ssi", },
782 {} 891 {}
783}; 892};
784MODULE_DEVICE_TABLE(of, fsl_ssi_ids); 893MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
diff --git a/sound/soc/fsl/fsl_utils.c b/sound/soc/fsl/fsl_utils.c
new file mode 100644
index 000000000000..b9e42b503a37
--- /dev/null
+++ b/sound/soc/fsl/fsl_utils.c
@@ -0,0 +1,91 @@
1/**
2 * Freescale ALSA SoC Machine driver utility
3 *
4 * Author: Timur Tabi <timur@freescale.com>
5 *
6 * Copyright 2010 Freescale Semiconductor, Inc.
7 *
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
10 * kind, whether express or implied.
11 */
12
13#include <linux/module.h>
14#include <linux/of_address.h>
15#include <sound/soc.h>
16
17#include "fsl_utils.h"
18
19/**
20 * fsl_asoc_get_dma_channel - determine the dma channel for a SSI node
21 *
22 * @ssi_np: pointer to the SSI device tree node
23 * @name: name of the phandle pointing to the dma channel
24 * @dai: ASoC DAI link pointer to be filled with platform_name
25 * @dma_channel_id: dma channel id to be returned
26 * @dma_id: dma id to be returned
27 *
28 * This function determines the dma and channel id for given SSI node. It
29 * also discovers the platform_name for the ASoC DAI link.
30 */
31int fsl_asoc_get_dma_channel(struct device_node *ssi_np,
32 const char *name,
33 struct snd_soc_dai_link *dai,
34 unsigned int *dma_channel_id,
35 unsigned int *dma_id)
36{
37 struct resource res;
38 struct device_node *dma_channel_np, *dma_np;
39 const u32 *iprop;
40 int ret;
41
42 dma_channel_np = of_parse_phandle(ssi_np, name, 0);
43 if (!dma_channel_np)
44 return -EINVAL;
45
46 if (!of_device_is_compatible(dma_channel_np, "fsl,ssi-dma-channel")) {
47 of_node_put(dma_channel_np);
48 return -EINVAL;
49 }
50
51 /* Determine the dev_name for the device_node. This code mimics the
52 * behavior of of_device_make_bus_id(). We need this because ASoC uses
53 * the dev_name() of the device to match the platform (DMA) device with
54 * the CPU (SSI) device. It's all ugly and hackish, but it works (for
55 * now).
56 *
57 * dai->platform name should already point to an allocated buffer.
58 */
59 ret = of_address_to_resource(dma_channel_np, 0, &res);
60 if (ret) {
61 of_node_put(dma_channel_np);
62 return ret;
63 }
64 snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%s",
65 (unsigned long long) res.start, dma_channel_np->name);
66
67 iprop = of_get_property(dma_channel_np, "cell-index", NULL);
68 if (!iprop) {
69 of_node_put(dma_channel_np);
70 return -EINVAL;
71 }
72 *dma_channel_id = be32_to_cpup(iprop);
73
74 dma_np = of_get_parent(dma_channel_np);
75 iprop = of_get_property(dma_np, "cell-index", NULL);
76 if (!iprop) {
77 of_node_put(dma_np);
78 return -EINVAL;
79 }
80 *dma_id = be32_to_cpup(iprop);
81
82 of_node_put(dma_np);
83 of_node_put(dma_channel_np);
84
85 return 0;
86}
87EXPORT_SYMBOL(fsl_asoc_get_dma_channel);
88
89MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
90MODULE_DESCRIPTION("Freescale ASoC utility code");
91MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/fsl/fsl_utils.h b/sound/soc/fsl/fsl_utils.h
new file mode 100644
index 000000000000..b2951126527c
--- /dev/null
+++ b/sound/soc/fsl/fsl_utils.h
@@ -0,0 +1,26 @@
1/**
2 * Freescale ALSA SoC Machine driver utility
3 *
4 * Author: Timur Tabi <timur@freescale.com>
5 *
6 * Copyright 2010 Freescale Semiconductor, Inc.
7 *
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
10 * kind, whether express or implied.
11 */
12
13#ifndef _FSL_UTILS_H
14#define _FSL_UTILS_H
15
16#define DAI_NAME_SIZE 32
17
18struct snd_soc_dai_link;
19struct device_node;
20
21int fsl_asoc_get_dma_channel(struct device_node *ssi_np, const char *name,
22 struct snd_soc_dai_link *dai,
23 unsigned int *dma_channel_id,
24 unsigned int *dma_id);
25
26#endif /* _FSL_UTILS_H */
diff --git a/sound/soc/imx/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index f23700359c67..f23700359c67 100644
--- a/sound/soc/imx/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
diff --git a/sound/soc/imx/imx-audmux.h b/sound/soc/fsl/imx-audmux.h
index 04ebbab8d7b9..04ebbab8d7b9 100644
--- a/sound/soc/imx/imx-audmux.h
+++ b/sound/soc/fsl/imx-audmux.h
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c
new file mode 100644
index 000000000000..f59c34943662
--- /dev/null
+++ b/sound/soc/fsl/imx-mc13783.c
@@ -0,0 +1,156 @@
1/*
2 * imx-mc13783.c -- SoC audio for imx based boards with mc13783 codec
3 *
4 * Copyright 2012 Philippe Retornaz, <philippe.retornaz@epfl.ch>
5 *
6 * Heavly based on phycore-mc13783:
7 * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 */
15
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/device.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23#include <asm/mach-types.h>
24
25#include "../codecs/mc13783.h"
26#include "imx-ssi.h"
27#include "imx-audmux.h"
28
29#define FMT_SSI (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | \
30 SND_SOC_DAIFMT_CBM_CFM)
31
32static int imx_mc13783_hifi_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 *cpu_dai = rtd->cpu_dai;
37 struct snd_soc_dai *codec_dai = rtd->codec_dai;
38 int ret;
39
40 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xfffffffc, 0xfffffffc,
41 4, 16);
42 if (ret)
43 return ret;
44
45 ret = snd_soc_dai_set_sysclk(codec_dai, MC13783_CLK_CLIA, 26000000, 0);
46 if (ret)
47 return ret;
48
49 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x0, 0xfffffffc, 2, 16);
50 if (ret)
51 return ret;
52
53 return 0;
54}
55
56static struct snd_soc_ops imx_mc13783_hifi_ops = {
57 .hw_params = imx_mc13783_hifi_hw_params,
58};
59
60static struct snd_soc_dai_link imx_mc13783_dai_mc13783[] = {
61 {
62 .name = "MC13783",
63 .stream_name = "Sound",
64 .codec_dai_name = "mc13783-hifi",
65 .codec_name = "mc13783-codec",
66 .cpu_dai_name = "imx-ssi.0",
67 .platform_name = "imx-pcm-audio.0",
68 .ops = &imx_mc13783_hifi_ops,
69 .symmetric_rates = 1,
70 .dai_fmt = FMT_SSI,
71 },
72};
73
74static const struct snd_soc_dapm_widget imx_mc13783_widget[] = {
75 SND_SOC_DAPM_MIC("Mic", NULL),
76 SND_SOC_DAPM_HP("Headphone", NULL),
77 SND_SOC_DAPM_SPK("Speaker", NULL),
78};
79
80static const struct snd_soc_dapm_route imx_mc13783_routes[] = {
81 {"Speaker", NULL, "LSP"},
82 {"Headphone", NULL, "HSL"},
83 {"Headphone", NULL, "HSR"},
84
85 {"MC1LIN", NULL, "MC1 Bias"},
86 {"MC2IN", NULL, "MC2 Bias"},
87 {"MC1 Bias", NULL, "Mic"},
88 {"MC2 Bias", NULL, "Mic"},
89};
90
91static struct snd_soc_card imx_mc13783 = {
92 .name = "imx_mc13783",
93 .dai_link = imx_mc13783_dai_mc13783,
94 .num_links = ARRAY_SIZE(imx_mc13783_dai_mc13783),
95 .dapm_widgets = imx_mc13783_widget,
96 .num_dapm_widgets = ARRAY_SIZE(imx_mc13783_widget),
97 .dapm_routes = imx_mc13783_routes,
98 .num_dapm_routes = ARRAY_SIZE(imx_mc13783_routes),
99};
100
101static int __devinit imx_mc13783_probe(struct platform_device *pdev)
102{
103 int ret;
104
105 imx_mc13783.dev = &pdev->dev;
106
107 ret = snd_soc_register_card(&imx_mc13783);
108 if (ret) {
109 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
110 ret);
111 return ret;
112 }
113
114 imx_audmux_v2_configure_port(MX31_AUDMUX_PORT4_SSI_PINS_4,
115 IMX_AUDMUX_V2_PTCR_SYN,
116 IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0) |
117 IMX_AUDMUX_V2_PDCR_MODE(1) |
118 IMX_AUDMUX_V2_PDCR_INMMASK(0xfc));
119 imx_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0,
120 IMX_AUDMUX_V2_PTCR_SYN |
121 IMX_AUDMUX_V2_PTCR_TFSDIR |
122 IMX_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) |
123 IMX_AUDMUX_V2_PTCR_TCLKDIR |
124 IMX_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) |
125 IMX_AUDMUX_V2_PTCR_RFSDIR |
126 IMX_AUDMUX_V2_PTCR_RFSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) |
127 IMX_AUDMUX_V2_PTCR_RCLKDIR |
128 IMX_AUDMUX_V2_PTCR_RCSEL(MX31_AUDMUX_PORT4_SSI_PINS_4),
129 IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT4_SSI_PINS_4));
130
131 return ret;
132}
133
134static int __devexit imx_mc13783_remove(struct platform_device *pdev)
135{
136 snd_soc_unregister_card(&imx_mc13783);
137
138 return 0;
139}
140
141static struct platform_driver imx_mc13783_audio_driver = {
142 .driver = {
143 .name = "imx_mc13783",
144 .owner = THIS_MODULE,
145 },
146 .probe = imx_mc13783_probe,
147 .remove = __devexit_p(imx_mc13783_remove)
148};
149
150module_platform_driver(imx_mc13783_audio_driver);
151
152MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
153MODULE_AUTHOR("Philippe Retornaz <philippe.retornaz@epfl.ch");
154MODULE_DESCRIPTION("imx with mc13783 codec ALSA SoC driver");
155MODULE_LICENSE("GPL");
156MODULE_ALIAS("platform:imx_mc13783");
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/fsl/imx-pcm-dma.c
index 6b818de2fc03..f3c0a5ef35c8 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -109,7 +109,8 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
109 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 109 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
110 110
111 dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL); 111 dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL);
112 dma_data->peripheral_type = IMX_DMATYPE_SSI; 112 dma_data->peripheral_type = dma_params->shared_peripheral ?
113 IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI;
113 dma_data->priority = DMA_PRIO_HIGH; 114 dma_data->priority = DMA_PRIO_HIGH;
114 dma_data->dma_request = dma_params->dma; 115 dma_data->dma_request = dma_params->dma;
115 116
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index 456b7d723d66..456b7d723d66 100644
--- a/sound/soc/imx/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
diff --git a/sound/soc/imx/imx-pcm.c b/sound/soc/fsl/imx-pcm.c
index 93dc360b1777..93dc360b1777 100644
--- a/sound/soc/imx/imx-pcm.c
+++ b/sound/soc/fsl/imx-pcm.c
diff --git a/sound/soc/imx/imx-pcm.h b/sound/soc/fsl/imx-pcm.h
index b5f5c3acf34d..83c0ed7d55c9 100644
--- a/sound/soc/imx/imx-pcm.h
+++ b/sound/soc/fsl/imx-pcm.h
@@ -22,6 +22,7 @@ struct imx_pcm_dma_params {
22 int dma; 22 int dma;
23 unsigned long dma_addr; 23 unsigned long dma_addr;
24 int burstsize; 24 int burstsize;
25 bool shared_peripheral; /* The peripheral is on SPBA bus */
25}; 26};
26 27
27int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, 28int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c
new file mode 100644
index 000000000000..3a729caeb8c8
--- /dev/null
+++ b/sound/soc/fsl/imx-sgtl5000.c
@@ -0,0 +1,221 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 * Copyright 2012 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/module.h>
14#include <linux/of.h>
15#include <linux/of_platform.h>
16#include <linux/of_i2c.h>
17#include <linux/clk.h>
18#include <sound/soc.h>
19
20#include "../codecs/sgtl5000.h"
21#include "imx-audmux.h"
22
23#define DAI_NAME_SIZE 32
24
25struct imx_sgtl5000_data {
26 struct snd_soc_dai_link dai;
27 struct snd_soc_card card;
28 char codec_dai_name[DAI_NAME_SIZE];
29 char platform_name[DAI_NAME_SIZE];
30 struct clk *codec_clk;
31 unsigned int clk_frequency;
32};
33
34static int imx_sgtl5000_dai_init(struct snd_soc_pcm_runtime *rtd)
35{
36 struct imx_sgtl5000_data *data = container_of(rtd->card,
37 struct imx_sgtl5000_data, card);
38 struct device *dev = rtd->card->dev;
39 int ret;
40
41 ret = snd_soc_dai_set_sysclk(rtd->codec_dai, SGTL5000_SYSCLK,
42 data->clk_frequency, SND_SOC_CLOCK_IN);
43 if (ret) {
44 dev_err(dev, "could not set codec driver clock params\n");
45 return ret;
46 }
47
48 return 0;
49}
50
51static const struct snd_soc_dapm_widget imx_sgtl5000_dapm_widgets[] = {
52 SND_SOC_DAPM_MIC("Mic Jack", NULL),
53 SND_SOC_DAPM_LINE("Line In Jack", NULL),
54 SND_SOC_DAPM_HP("Headphone Jack", NULL),
55 SND_SOC_DAPM_SPK("Line Out Jack", NULL),
56 SND_SOC_DAPM_SPK("Ext Spk", NULL),
57};
58
59static int __devinit imx_sgtl5000_probe(struct platform_device *pdev)
60{
61 struct device_node *np = pdev->dev.of_node;
62 struct device_node *ssi_np, *codec_np;
63 struct platform_device *ssi_pdev;
64 struct i2c_client *codec_dev;
65 struct imx_sgtl5000_data *data;
66 int int_port, ext_port;
67 int ret;
68
69 ret = of_property_read_u32(np, "mux-int-port", &int_port);
70 if (ret) {
71 dev_err(&pdev->dev, "mux-int-port missing or invalid\n");
72 return ret;
73 }
74 ret = of_property_read_u32(np, "mux-ext-port", &ext_port);
75 if (ret) {
76 dev_err(&pdev->dev, "mux-ext-port missing or invalid\n");
77 return ret;
78 }
79
80 /*
81 * The port numbering in the hardware manual starts at 1, while
82 * the audmux API expects it starts at 0.
83 */
84 int_port--;
85 ext_port--;
86 ret = imx_audmux_v2_configure_port(int_port,
87 IMX_AUDMUX_V2_PTCR_SYN |
88 IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) |
89 IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) |
90 IMX_AUDMUX_V2_PTCR_TFSDIR |
91 IMX_AUDMUX_V2_PTCR_TCLKDIR,
92 IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port));
93 if (ret) {
94 dev_err(&pdev->dev, "audmux internal port setup failed\n");
95 return ret;
96 }
97 imx_audmux_v2_configure_port(ext_port,
98 IMX_AUDMUX_V2_PTCR_SYN |
99 IMX_AUDMUX_V2_PTCR_TCSEL(int_port),
100 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
101 if (ret) {
102 dev_err(&pdev->dev, "audmux external port setup failed\n");
103 return ret;
104 }
105
106 ssi_np = of_parse_phandle(pdev->dev.of_node, "ssi-controller", 0);
107 codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
108 if (!ssi_np || !codec_np) {
109 dev_err(&pdev->dev, "phandle missing or invalid\n");
110 ret = -EINVAL;
111 goto fail;
112 }
113
114 ssi_pdev = of_find_device_by_node(ssi_np);
115 if (!ssi_pdev) {
116 dev_err(&pdev->dev, "failed to find SSI platform device\n");
117 ret = -EINVAL;
118 goto fail;
119 }
120 codec_dev = of_find_i2c_device_by_node(codec_np);
121 if (!codec_dev) {
122 dev_err(&pdev->dev, "failed to find codec platform device\n");
123 return -EINVAL;
124 }
125
126 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
127 if (!data) {
128 ret = -ENOMEM;
129 goto fail;
130 }
131
132 data->codec_clk = clk_get(&codec_dev->dev, NULL);
133 if (IS_ERR(data->codec_clk)) {
134 /* assuming clock enabled by default */
135 data->codec_clk = NULL;
136 ret = of_property_read_u32(codec_np, "clock-frequency",
137 &data->clk_frequency);
138 if (ret) {
139 dev_err(&codec_dev->dev,
140 "clock-frequency missing or invalid\n");
141 goto fail;
142 }
143 } else {
144 data->clk_frequency = clk_get_rate(data->codec_clk);
145 clk_prepare_enable(data->codec_clk);
146 }
147
148 data->dai.name = "HiFi";
149 data->dai.stream_name = "HiFi";
150 data->dai.codec_dai_name = "sgtl5000";
151 data->dai.codec_of_node = codec_np;
152 data->dai.cpu_dai_name = dev_name(&ssi_pdev->dev);
153 data->dai.platform_name = "imx-pcm-audio";
154 data->dai.init = &imx_sgtl5000_dai_init;
155 data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
156 SND_SOC_DAIFMT_CBM_CFM;
157
158 data->card.dev = &pdev->dev;
159 ret = snd_soc_of_parse_card_name(&data->card, "model");
160 if (ret)
161 goto clk_fail;
162 ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing");
163 if (ret)
164 goto clk_fail;
165 data->card.num_links = 1;
166 data->card.dai_link = &data->dai;
167 data->card.dapm_widgets = imx_sgtl5000_dapm_widgets;
168 data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets);
169
170 ret = snd_soc_register_card(&data->card);
171 if (ret) {
172 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
173 goto clk_fail;
174 }
175
176 platform_set_drvdata(pdev, data);
177clk_fail:
178 clk_put(data->codec_clk);
179fail:
180 if (ssi_np)
181 of_node_put(ssi_np);
182 if (codec_np)
183 of_node_put(codec_np);
184
185 return ret;
186}
187
188static int __devexit imx_sgtl5000_remove(struct platform_device *pdev)
189{
190 struct imx_sgtl5000_data *data = platform_get_drvdata(pdev);
191
192 if (data->codec_clk) {
193 clk_disable_unprepare(data->codec_clk);
194 clk_put(data->codec_clk);
195 }
196 snd_soc_unregister_card(&data->card);
197
198 return 0;
199}
200
201static const struct of_device_id imx_sgtl5000_dt_ids[] = {
202 { .compatible = "fsl,imx-audio-sgtl5000", },
203 { /* sentinel */ }
204};
205MODULE_DEVICE_TABLE(of, imx_sgtl5000_dt_ids);
206
207static struct platform_driver imx_sgtl5000_driver = {
208 .driver = {
209 .name = "imx-sgtl5000",
210 .owner = THIS_MODULE,
211 .of_match_table = imx_sgtl5000_dt_ids,
212 },
213 .probe = imx_sgtl5000_probe,
214 .remove = __devexit_p(imx_sgtl5000_remove),
215};
216module_platform_driver(imx_sgtl5000_driver);
217
218MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
219MODULE_DESCRIPTION("Freescale i.MX SGTL5000 ASoC machine driver");
220MODULE_LICENSE("GPL v2");
221MODULE_ALIAS("platform:imx-sgtl5000");
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index 4f81ed456325..cf3ed0362c9c 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -28,7 +28,7 @@
28 * value. When we read the same register two times (and the register still 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 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. 30 * around this by not polling these bits but only wait a fixed delay.
31 * 31 *
32 */ 32 */
33 33
34#include <linux/clk.h> 34#include <linux/clk.h>
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/fsl/imx-ssi.h
index 5744e86ca878..5744e86ca878 100644
--- a/sound/soc/imx/imx-ssi.h
+++ b/sound/soc/fsl/imx-ssi.h
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 3fea5a15ffe8..60bcba1bc30e 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -14,18 +14,16 @@
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/of_device.h> 15#include <linux/of_device.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/of_i2c.h>
18#include <sound/soc.h> 17#include <sound/soc.h>
19#include <asm/fsl_guts.h> 18#include <asm/fsl_guts.h>
20 19
21#include "fsl_dma.h" 20#include "fsl_dma.h"
22#include "fsl_ssi.h" 21#include "fsl_ssi.h"
22#include "fsl_utils.h"
23 23
24/* There's only one global utilities register */ 24/* There's only one global utilities register */
25static phys_addr_t guts_phys; 25static phys_addr_t guts_phys;
26 26
27#define DAI_NAME_SIZE 32
28
29/** 27/**
30 * mpc8610_hpcd_data: machine-specific ASoC device data 28 * mpc8610_hpcd_data: machine-specific ASoC device data
31 * 29 *
@@ -43,7 +41,6 @@ struct mpc8610_hpcd_data {
43 unsigned int dma_id[2]; /* 0 = DMA1, 1 = DMA2, etc */ 41 unsigned int dma_id[2]; /* 0 = DMA1, 1 = DMA2, etc */
44 unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/ 42 unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/
45 char codec_dai_name[DAI_NAME_SIZE]; 43 char codec_dai_name[DAI_NAME_SIZE];
46 char codec_name[DAI_NAME_SIZE];
47 char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */ 44 char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */
48}; 45};
49 46
@@ -181,141 +178,6 @@ static struct snd_soc_ops mpc8610_hpcd_ops = {
181}; 178};
182 179
183/** 180/**
184 * get_node_by_phandle_name - get a node by its phandle name
185 *
186 * This function takes a node, the name of a property in that node, and a
187 * compatible string. Assuming the property is a phandle to another node,
188 * it returns that node, (optionally) if that node is compatible.
189 *
190 * If the property is not a phandle, or the node it points to is not compatible
191 * with the specific string, then NULL is returned.
192 */
193static struct device_node *get_node_by_phandle_name(struct device_node *np,
194 const char *name,
195 const char *compatible)
196{
197 const phandle *ph;
198 int len;
199
200 ph = of_get_property(np, name, &len);
201 if (!ph || (len != sizeof(phandle)))
202 return NULL;
203
204 np = of_find_node_by_phandle(*ph);
205 if (!np)
206 return NULL;
207
208 if (compatible && !of_device_is_compatible(np, compatible)) {
209 of_node_put(np);
210 return NULL;
211 }
212
213 return np;
214}
215
216/**
217 * get_parent_cell_index -- return the cell-index of the parent of a node
218 *
219 * Return the value of the cell-index property of the parent of the given
220 * node. This is used for DMA channel nodes that need to know the DMA ID
221 * of the controller they are on.
222 */
223static int get_parent_cell_index(struct device_node *np)
224{
225 struct device_node *parent = of_get_parent(np);
226 const u32 *iprop;
227
228 if (!parent)
229 return -1;
230
231 iprop = of_get_property(parent, "cell-index", NULL);
232 of_node_put(parent);
233
234 if (!iprop)
235 return -1;
236
237 return be32_to_cpup(iprop);
238}
239
240/**
241 * codec_node_dev_name - determine the dev_name for a codec node
242 *
243 * This function determines the dev_name for an I2C node. This is the name
244 * that would be returned by dev_name() if this device_node were part of a
245 * 'struct device' It's ugly and hackish, but it works.
246 *
247 * The dev_name for such devices include the bus number and I2C address. For
248 * example, "cs4270.0-004f".
249 */
250static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
251{
252 const u32 *iprop;
253 int addr;
254 char temp[DAI_NAME_SIZE];
255 struct i2c_client *i2c;
256
257 of_modalias_node(np, temp, DAI_NAME_SIZE);
258
259 iprop = of_get_property(np, "reg", NULL);
260 if (!iprop)
261 return -EINVAL;
262
263 addr = be32_to_cpup(iprop);
264
265 /* We need the adapter number */
266 i2c = of_find_i2c_device_by_node(np);
267 if (!i2c)
268 return -ENODEV;
269
270 snprintf(buf, len, "%s.%u-%04x", temp, i2c->adapter->nr, addr);
271
272 return 0;
273}
274
275static int get_dma_channel(struct device_node *ssi_np,
276 const char *name,
277 struct snd_soc_dai_link *dai,
278 unsigned int *dma_channel_id,
279 unsigned int *dma_id)
280{
281 struct resource res;
282 struct device_node *dma_channel_np;
283 const u32 *iprop;
284 int ret;
285
286 dma_channel_np = get_node_by_phandle_name(ssi_np, name,
287 "fsl,ssi-dma-channel");
288 if (!dma_channel_np)
289 return -EINVAL;
290
291 /* Determine the dev_name for the device_node. This code mimics the
292 * behavior of of_device_make_bus_id(). We need this because ASoC uses
293 * the dev_name() of the device to match the platform (DMA) device with
294 * the CPU (SSI) device. It's all ugly and hackish, but it works (for
295 * now).
296 *
297 * dai->platform name should already point to an allocated buffer.
298 */
299 ret = of_address_to_resource(dma_channel_np, 0, &res);
300 if (ret)
301 return ret;
302 snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%s",
303 (unsigned long long) res.start, dma_channel_np->name);
304
305 iprop = of_get_property(dma_channel_np, "cell-index", NULL);
306 if (!iprop) {
307 of_node_put(dma_channel_np);
308 return -EINVAL;
309 }
310
311 *dma_channel_id = be32_to_cpup(iprop);
312 *dma_id = get_parent_cell_index(dma_channel_np);
313 of_node_put(dma_channel_np);
314
315 return 0;
316}
317
318/**
319 * mpc8610_hpcd_probe: platform probe function for the machine driver 181 * mpc8610_hpcd_probe: platform probe function for the machine driver
320 * 182 *
321 * Although this is a machine driver, the SSI node is the "master" node with 183 * Although this is a machine driver, the SSI node is the "master" node with
@@ -352,16 +214,8 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
352 machine_data->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev); 214 machine_data->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev);
353 machine_data->dai[0].ops = &mpc8610_hpcd_ops; 215 machine_data->dai[0].ops = &mpc8610_hpcd_ops;
354 216
355 /* Determine the codec name, it will be used as the codec DAI name */ 217 /* ASoC core can match codec with device node */
356 ret = codec_node_dev_name(codec_np, machine_data->codec_name, 218 machine_data->dai[0].codec_of_node = codec_np;
357 DAI_NAME_SIZE);
358 if (ret) {
359 dev_err(&pdev->dev, "invalid codec node %s\n",
360 codec_np->full_name);
361 ret = -EINVAL;
362 goto error;
363 }
364 machine_data->dai[0].codec_name = machine_data->codec_name;
365 219
366 /* The DAI name from the codec (snd_soc_dai_driver.name) */ 220 /* The DAI name from the codec (snd_soc_dai_driver.name) */
367 machine_data->dai[0].codec_dai_name = "cs4270-hifi"; 221 machine_data->dai[0].codec_dai_name = "cs4270-hifi";
@@ -458,9 +312,10 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
458 312
459 /* Find the playback DMA channel to use. */ 313 /* Find the playback DMA channel to use. */
460 machine_data->dai[0].platform_name = machine_data->platform_name[0]; 314 machine_data->dai[0].platform_name = machine_data->platform_name[0];
461 ret = get_dma_channel(np, "fsl,playback-dma", &machine_data->dai[0], 315 ret = fsl_asoc_get_dma_channel(np, "fsl,playback-dma",
462 &machine_data->dma_channel_id[0], 316 &machine_data->dai[0],
463 &machine_data->dma_id[0]); 317 &machine_data->dma_channel_id[0],
318 &machine_data->dma_id[0]);
464 if (ret) { 319 if (ret) {
465 dev_err(&pdev->dev, "missing/invalid playback DMA phandle\n"); 320 dev_err(&pdev->dev, "missing/invalid playback DMA phandle\n");
466 goto error; 321 goto error;
@@ -468,9 +323,10 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
468 323
469 /* Find the capture DMA channel to use. */ 324 /* Find the capture DMA channel to use. */
470 machine_data->dai[1].platform_name = machine_data->platform_name[1]; 325 machine_data->dai[1].platform_name = machine_data->platform_name[1];
471 ret = get_dma_channel(np, "fsl,capture-dma", &machine_data->dai[1], 326 ret = fsl_asoc_get_dma_channel(np, "fsl,capture-dma",
472 &machine_data->dma_channel_id[1], 327 &machine_data->dai[1],
473 &machine_data->dma_id[1]); 328 &machine_data->dma_channel_id[1],
329 &machine_data->dma_id[1]);
474 if (ret) { 330 if (ret) {
475 dev_err(&pdev->dev, "missing/invalid capture DMA phandle\n"); 331 dev_err(&pdev->dev, "missing/invalid capture DMA phandle\n");
476 goto error; 332 goto error;
diff --git a/sound/soc/imx/mx27vis-aic32x4.c b/sound/soc/fsl/mx27vis-aic32x4.c
index f6d04ad4bb39..f6d04ad4bb39 100644
--- a/sound/soc/imx/mx27vis-aic32x4.c
+++ b/sound/soc/fsl/mx27vis-aic32x4.c
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index 982a1c944983..50adf4032bcc 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -14,12 +14,12 @@
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/of_device.h> 15#include <linux/of_device.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/of_i2c.h>
18#include <sound/soc.h> 17#include <sound/soc.h>
19#include <asm/fsl_guts.h> 18#include <asm/fsl_guts.h>
20 19
21#include "fsl_dma.h" 20#include "fsl_dma.h"
22#include "fsl_ssi.h" 21#include "fsl_ssi.h"
22#include "fsl_utils.h"
23 23
24/* P1022-specific PMUXCR and DMUXCR bit definitions */ 24/* P1022-specific PMUXCR and DMUXCR bit definitions */
25 25
@@ -57,8 +57,6 @@ static inline void guts_set_dmuxcr(struct ccsr_guts __iomem *guts,
57/* There's only one global utilities register */ 57/* There's only one global utilities register */
58static phys_addr_t guts_phys; 58static phys_addr_t guts_phys;
59 59
60#define DAI_NAME_SIZE 32
61
62/** 60/**
63 * machine_data: machine-specific ASoC device data 61 * machine_data: machine-specific ASoC device data
64 * 62 *
@@ -75,7 +73,6 @@ struct machine_data {
75 unsigned int ssi_id; /* 0 = SSI1, 1 = SSI2, etc */ 73 unsigned int ssi_id; /* 0 = SSI1, 1 = SSI2, etc */
76 unsigned int dma_id[2]; /* 0 = DMA1, 1 = DMA2, etc */ 74 unsigned int dma_id[2]; /* 0 = DMA1, 1 = DMA2, etc */
77 unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/ 75 unsigned int dma_channel_id[2]; /* 0 = ch 0, 1 = ch 1, etc*/
78 char codec_name[DAI_NAME_SIZE];
79 char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */ 76 char platform_name[2][DAI_NAME_SIZE]; /* One for each DMA channel */
80}; 77};
81 78
@@ -191,136 +188,6 @@ static struct snd_soc_ops p1022_ds_ops = {
191}; 188};
192 189
193/** 190/**
194 * get_node_by_phandle_name - get a node by its phandle name
195 *
196 * This function takes a node, the name of a property in that node, and a
197 * compatible string. Assuming the property is a phandle to another node,
198 * it returns that node, (optionally) if that node is compatible.
199 *
200 * If the property is not a phandle, or the node it points to is not compatible
201 * with the specific string, then NULL is returned.
202 */
203static struct device_node *get_node_by_phandle_name(struct device_node *np,
204 const char *name, const char *compatible)
205{
206 np = of_parse_phandle(np, name, 0);
207 if (!np)
208 return NULL;
209
210 if (!of_device_is_compatible(np, compatible)) {
211 of_node_put(np);
212 return NULL;
213 }
214
215 return np;
216}
217
218/**
219 * get_parent_cell_index -- return the cell-index of the parent of a node
220 *
221 * Return the value of the cell-index property of the parent of the given
222 * node. This is used for DMA channel nodes that need to know the DMA ID
223 * of the controller they are on.
224 */
225static int get_parent_cell_index(struct device_node *np)
226{
227 struct device_node *parent = of_get_parent(np);
228 const u32 *iprop;
229 int ret = -1;
230
231 if (!parent)
232 return -1;
233
234 iprop = of_get_property(parent, "cell-index", NULL);
235 if (iprop)
236 ret = be32_to_cpup(iprop);
237
238 of_node_put(parent);
239
240 return ret;
241}
242
243/**
244 * codec_node_dev_name - determine the dev_name for a codec node
245 *
246 * This function determines the dev_name for an I2C node. This is the name
247 * that would be returned by dev_name() if this device_node were part of a
248 * 'struct device' It's ugly and hackish, but it works.
249 *
250 * The dev_name for such devices include the bus number and I2C address. For
251 * example, "cs4270-codec.0-004f".
252 */
253static int codec_node_dev_name(struct device_node *np, char *buf, size_t len)
254{
255 const u32 *iprop;
256 int addr;
257 char temp[DAI_NAME_SIZE];
258 struct i2c_client *i2c;
259
260 of_modalias_node(np, temp, DAI_NAME_SIZE);
261
262 iprop = of_get_property(np, "reg", NULL);
263 if (!iprop)
264 return -EINVAL;
265
266 addr = be32_to_cpup(iprop);
267
268 /* We need the adapter number */
269 i2c = of_find_i2c_device_by_node(np);
270 if (!i2c)
271 return -ENODEV;
272
273 snprintf(buf, len, "%s.%u-%04x", temp, i2c->adapter->nr, addr);
274
275 return 0;
276}
277
278static int get_dma_channel(struct device_node *ssi_np,
279 const char *name,
280 struct snd_soc_dai_link *dai,
281 unsigned int *dma_channel_id,
282 unsigned int *dma_id)
283{
284 struct resource res;
285 struct device_node *dma_channel_np;
286 const u32 *iprop;
287 int ret;
288
289 dma_channel_np = get_node_by_phandle_name(ssi_np, name,
290 "fsl,ssi-dma-channel");
291 if (!dma_channel_np)
292 return -EINVAL;
293
294 /* Determine the dev_name for the device_node. This code mimics the
295 * behavior of of_device_make_bus_id(). We need this because ASoC uses
296 * the dev_name() of the device to match the platform (DMA) device with
297 * the CPU (SSI) device. It's all ugly and hackish, but it works (for
298 * now).
299 *
300 * dai->platform name should already point to an allocated buffer.
301 */
302 ret = of_address_to_resource(dma_channel_np, 0, &res);
303 if (ret) {
304 of_node_put(dma_channel_np);
305 return ret;
306 }
307 snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%s",
308 (unsigned long long) res.start, dma_channel_np->name);
309
310 iprop = of_get_property(dma_channel_np, "cell-index", NULL);
311 if (!iprop) {
312 of_node_put(dma_channel_np);
313 return -EINVAL;
314 }
315
316 *dma_channel_id = be32_to_cpup(iprop);
317 *dma_id = get_parent_cell_index(dma_channel_np);
318 of_node_put(dma_channel_np);
319
320 return 0;
321}
322
323/**
324 * p1022_ds_probe: platform probe function for the machine driver 191 * p1022_ds_probe: platform probe function for the machine driver
325 * 192 *
326 * Although this is a machine driver, the SSI node is the "master" node with 193 * Although this is a machine driver, the SSI node is the "master" node with
@@ -357,15 +224,8 @@ static int p1022_ds_probe(struct platform_device *pdev)
357 mdata->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev); 224 mdata->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev);
358 mdata->dai[0].ops = &p1022_ds_ops; 225 mdata->dai[0].ops = &p1022_ds_ops;
359 226
360 /* Determine the codec name, it will be used as the codec DAI name */ 227 /* ASoC core can match codec with device node */
361 ret = codec_node_dev_name(codec_np, mdata->codec_name, DAI_NAME_SIZE); 228 mdata->dai[0].codec_of_node = codec_np;
362 if (ret) {
363 dev_err(&pdev->dev, "invalid codec node %s\n",
364 codec_np->full_name);
365 ret = -EINVAL;
366 goto error;
367 }
368 mdata->dai[0].codec_name = mdata->codec_name;
369 229
370 /* We register two DAIs per SSI, one for playback and the other for 230 /* We register two DAIs per SSI, one for playback and the other for
371 * capture. We support codecs that have separate DAIs for both playback 231 * capture. We support codecs that have separate DAIs for both playback
@@ -462,9 +322,9 @@ static int p1022_ds_probe(struct platform_device *pdev)
462 322
463 /* Find the playback DMA channel to use. */ 323 /* Find the playback DMA channel to use. */
464 mdata->dai[0].platform_name = mdata->platform_name[0]; 324 mdata->dai[0].platform_name = mdata->platform_name[0];
465 ret = get_dma_channel(np, "fsl,playback-dma", &mdata->dai[0], 325 ret = fsl_asoc_get_dma_channel(np, "fsl,playback-dma", &mdata->dai[0],
466 &mdata->dma_channel_id[0], 326 &mdata->dma_channel_id[0],
467 &mdata->dma_id[0]); 327 &mdata->dma_id[0]);
468 if (ret) { 328 if (ret) {
469 dev_err(&pdev->dev, "missing/invalid playback DMA phandle\n"); 329 dev_err(&pdev->dev, "missing/invalid playback DMA phandle\n");
470 goto error; 330 goto error;
@@ -472,9 +332,9 @@ static int p1022_ds_probe(struct platform_device *pdev)
472 332
473 /* Find the capture DMA channel to use. */ 333 /* Find the capture DMA channel to use. */
474 mdata->dai[1].platform_name = mdata->platform_name[1]; 334 mdata->dai[1].platform_name = mdata->platform_name[1];
475 ret = get_dma_channel(np, "fsl,capture-dma", &mdata->dai[1], 335 ret = fsl_asoc_get_dma_channel(np, "fsl,capture-dma", &mdata->dai[1],
476 &mdata->dma_channel_id[1], 336 &mdata->dma_channel_id[1],
477 &mdata->dma_id[1]); 337 &mdata->dma_id[1]);
478 if (ret) { 338 if (ret) {
479 dev_err(&pdev->dev, "missing/invalid capture DMA phandle\n"); 339 dev_err(&pdev->dev, "missing/invalid capture DMA phandle\n");
480 goto error; 340 goto error;
diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/fsl/phycore-ac97.c
index f8da6dd115ed..f8da6dd115ed 100644
--- a/sound/soc/imx/phycore-ac97.c
+++ b/sound/soc/fsl/phycore-ac97.c
diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/fsl/wm1133-ev1.c
index fe54a69073e5..fe54a69073e5 100644
--- a/sound/soc/imx/wm1133-ev1.c
+++ b/sound/soc/fsl/wm1133-ev1.c
diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig
new file mode 100644
index 000000000000..610f61251640
--- /dev/null
+++ b/sound/soc/generic/Kconfig
@@ -0,0 +1,4 @@
1config SND_SIMPLE_CARD
2 tristate "ASoC Simple sound card support"
3 help
4 This option enables generic simple sound card support
diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile
new file mode 100644
index 000000000000..9c3b246792bf
--- /dev/null
+++ b/sound/soc/generic/Makefile
@@ -0,0 +1,3 @@
1snd-soc-simple-card-objs := simple-card.o
2
3obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
new file mode 100644
index 000000000000..b4b4cab30232
--- /dev/null
+++ b/sound/soc/generic/simple-card.c
@@ -0,0 +1,114 @@
1/*
2 * ASoC simple sound card support
3 *
4 * Copyright (C) 2012 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/platform_device.h>
13#include <linux/module.h>
14#include <sound/simple_card.h>
15
16#define asoc_simple_get_card_info(p) \
17 container_of(p->dai_link, struct asoc_simple_card_info, snd_link)
18
19static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
20{
21 struct asoc_simple_card_info *cinfo = asoc_simple_get_card_info(rtd);
22 struct asoc_simple_dai_init_info *iinfo = cinfo->init;
23 struct snd_soc_dai *codec = rtd->codec_dai;
24 struct snd_soc_dai *cpu = rtd->cpu_dai;
25 unsigned int cpu_daifmt = iinfo->fmt | iinfo->cpu_daifmt;
26 unsigned int codec_daifmt = iinfo->fmt | iinfo->codec_daifmt;
27 int ret;
28
29 if (codec_daifmt) {
30 ret = snd_soc_dai_set_fmt(codec, codec_daifmt);
31 if (ret < 0)
32 return ret;
33 }
34
35 if (iinfo->sysclk) {
36 ret = snd_soc_dai_set_sysclk(codec, 0, iinfo->sysclk, 0);
37 if (ret < 0)
38 return ret;
39 }
40
41 if (cpu_daifmt) {
42 ret = snd_soc_dai_set_fmt(cpu, cpu_daifmt);
43 if (ret < 0)
44 return ret;
45 }
46
47 return 0;
48}
49
50static int asoc_simple_card_probe(struct platform_device *pdev)
51{
52 struct asoc_simple_card_info *cinfo = pdev->dev.platform_data;
53
54 if (!cinfo) {
55 dev_err(&pdev->dev, "no info for asoc-simple-card\n");
56 return -EINVAL;
57 }
58
59 if (!cinfo->name ||
60 !cinfo->card ||
61 !cinfo->cpu_dai ||
62 !cinfo->codec ||
63 !cinfo->platform ||
64 !cinfo->codec_dai) {
65 dev_err(&pdev->dev, "insufficient asoc_simple_card_info settings\n");
66 return -EINVAL;
67 }
68
69 /*
70 * init snd_soc_dai_link
71 */
72 cinfo->snd_link.name = cinfo->name;
73 cinfo->snd_link.stream_name = cinfo->name;
74 cinfo->snd_link.cpu_dai_name = cinfo->cpu_dai;
75 cinfo->snd_link.platform_name = cinfo->platform;
76 cinfo->snd_link.codec_name = cinfo->codec;
77 cinfo->snd_link.codec_dai_name = cinfo->codec_dai;
78
79 /* enable snd_link.init if cinfo has settings */
80 if (cinfo->init)
81 cinfo->snd_link.init = asoc_simple_card_dai_init;
82
83 /*
84 * init snd_soc_card
85 */
86 cinfo->snd_card.name = cinfo->card;
87 cinfo->snd_card.owner = THIS_MODULE;
88 cinfo->snd_card.dai_link = &cinfo->snd_link;
89 cinfo->snd_card.num_links = 1;
90 cinfo->snd_card.dev = &pdev->dev;
91
92 return snd_soc_register_card(&cinfo->snd_card);
93}
94
95static int asoc_simple_card_remove(struct platform_device *pdev)
96{
97 struct asoc_simple_card_info *cinfo = pdev->dev.platform_data;
98
99 return snd_soc_unregister_card(&cinfo->snd_card);
100}
101
102static struct platform_driver asoc_simple_card = {
103 .driver = {
104 .name = "asoc-simple-card",
105 },
106 .probe = asoc_simple_card_probe,
107 .remove = asoc_simple_card_remove,
108};
109
110module_platform_driver(asoc_simple_card);
111
112MODULE_LICENSE("GPL");
113MODULE_DESCRIPTION("ASoC Simple Sound Card");
114MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
deleted file mode 100644
index d83e5d0b5d52..000000000000
--- a/sound/soc/imx/Kconfig
+++ /dev/null
@@ -1,79 +0,0 @@
1menuconfig SND_IMX_SOC
2 tristate "SoC Audio for Freescale i.MX CPUs"
3 depends on ARCH_MXC
4 help
5 Say Y or M if you want to add support for codecs attached to
6 the i.MX SSI interface.
7
8
9if SND_IMX_SOC
10
11config SND_SOC_IMX_SSI
12 tristate
13
14config SND_SOC_IMX_PCM
15 tristate
16
17config SND_MXC_SOC_FIQ
18 tristate
19 select FIQ
20 select SND_SOC_IMX_PCM
21
22config SND_MXC_SOC_MX2
23 select SND_SOC_DMAENGINE_PCM
24 tristate
25 select SND_SOC_IMX_PCM
26
27config SND_SOC_IMX_AUDMUX
28 tristate
29
30config SND_MXC_SOC_WM1133_EV1
31 tristate "Audio on the i.MX31ADS with WM1133-EV1 fitted"
32 depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL
33 select SND_SOC_WM8350
34 select SND_MXC_SOC_FIQ
35 select SND_SOC_IMX_AUDMUX
36 select SND_SOC_IMX_SSI
37 help
38 Enable support for audio on the i.MX31ADS with the WM1133-EV1
39 PMIC board with WM8835x fitted.
40
41config SND_SOC_MX27VIS_AIC32X4
42 tristate "SoC audio support for Visstrim M10 boards"
43 depends on MACH_IMX27_VISSTRIM_M10 && I2C
44 select SND_SOC_TLV320AIC32X4
45 select SND_MXC_SOC_MX2
46 select SND_SOC_IMX_AUDMUX
47 select SND_SOC_IMX_SSI
48 help
49 Say Y if you want to add support for SoC audio on Visstrim SM10
50 board with TLV320AIC32X4 codec.
51
52config SND_SOC_PHYCORE_AC97
53 tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards"
54 depends on MACH_PCM043 || MACH_PCA100
55 select SND_SOC_AC97_BUS
56 select SND_SOC_WM9712
57 select SND_MXC_SOC_FIQ
58 select SND_SOC_IMX_AUDMUX
59 select SND_SOC_IMX_SSI
60 help
61 Say Y if you want to add support for SoC audio on Phytec phyCORE
62 and phyCARD boards in AC97 mode
63
64config SND_SOC_EUKREA_TLV320
65 tristate "Eukrea TLV320"
66 depends on MACH_EUKREA_MBIMX27_BASEBOARD \
67 || MACH_EUKREA_MBIMXSD25_BASEBOARD \
68 || MACH_EUKREA_MBIMXSD35_BASEBOARD \
69 || MACH_EUKREA_MBIMXSD51_BASEBOARD
70 depends on I2C
71 select SND_SOC_TLV320AIC23
72 select SND_MXC_SOC_FIQ
73 select SND_SOC_IMX_AUDMUX
74 select SND_SOC_IMX_SSI
75 help
76 Enable I2S based access to the TLV320AIC23B codec attached
77 to the SSI interface
78
79endif # SND_IMX_SOC
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
deleted file mode 100644
index f5db3e92d0d1..000000000000
--- a/sound/soc/imx/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
1# i.MX Platform Support
2snd-soc-imx-ssi-objs := imx-ssi.o
3snd-soc-imx-audmux-objs := imx-audmux.o
4
5obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o
6obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o
7
8obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o
9snd-soc-imx-pcm-y := imx-pcm.o
10snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_FIQ) += imx-pcm-fiq.o
11snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_MX2) += imx-pcm-dma-mx2.o
12
13# i.MX Machine Support
14snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
15snd-soc-phycore-ac97-objs := phycore-ac97.o
16snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
17snd-soc-wm1133-ev1-objs := wm1133-ev1.o
18
19obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
20obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
21obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
22obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index a5af7c42e62b..41349670adab 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -346,7 +346,7 @@ static void jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s)
346 346
347 /* Playback */ 347 /* Playback */
348 dma_config = &i2s->pcm_config_playback.dma_config; 348 dma_config = &i2s->pcm_config_playback.dma_config;
349 dma_config->src_width = JZ4740_DMA_WIDTH_32BIT, 349 dma_config->src_width = JZ4740_DMA_WIDTH_32BIT;
350 dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE; 350 dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE;
351 dma_config->request_type = JZ4740_DMA_TYPE_AIC_TRANSMIT; 351 dma_config->request_type = JZ4740_DMA_TYPE_AIC_TRANSMIT;
352 dma_config->flags = JZ4740_DMA_SRC_AUTOINC; 352 dma_config->flags = JZ4740_DMA_SRC_AUTOINC;
@@ -355,7 +355,7 @@ static void jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s)
355 355
356 /* Capture */ 356 /* Capture */
357 dma_config = &i2s->pcm_config_capture.dma_config; 357 dma_config = &i2s->pcm_config_capture.dma_config;
358 dma_config->dst_width = JZ4740_DMA_WIDTH_32BIT, 358 dma_config->dst_width = JZ4740_DMA_WIDTH_32BIT;
359 dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE; 359 dma_config->transfer_size = JZ4740_DMA_TRANSFER_SIZE_16BYTE;
360 dma_config->request_type = JZ4740_DMA_TYPE_AIC_RECEIVE; 360 dma_config->request_type = JZ4740_DMA_TYPE_AIC_RECEIVE;
361 dma_config->flags = JZ4740_DMA_DST_AUTOINC; 361 dma_config->flags = JZ4740_DMA_DST_AUTOINC;
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
index e373fbbc97a0..373dec90579f 100644
--- a/sound/soc/mxs/mxs-pcm.c
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -220,28 +220,16 @@ static struct snd_soc_platform_driver mxs_soc_platform = {
220 .pcm_free = mxs_pcm_free, 220 .pcm_free = mxs_pcm_free,
221}; 221};
222 222
223static int __devinit mxs_soc_platform_probe(struct platform_device *pdev) 223int __devinit mxs_pcm_platform_register(struct device *dev)
224{ 224{
225 return snd_soc_register_platform(&pdev->dev, &mxs_soc_platform); 225 return snd_soc_register_platform(dev, &mxs_soc_platform);
226} 226}
227EXPORT_SYMBOL_GPL(mxs_pcm_platform_register);
227 228
228static int __devexit mxs_soc_platform_remove(struct platform_device *pdev) 229void __devexit mxs_pcm_platform_unregister(struct device *dev)
229{ 230{
230 snd_soc_unregister_platform(&pdev->dev); 231 snd_soc_unregister_platform(dev);
231
232 return 0;
233} 232}
234 233EXPORT_SYMBOL_GPL(mxs_pcm_platform_unregister);
235static struct platform_driver mxs_pcm_driver = {
236 .driver = {
237 .name = "mxs-pcm-audio",
238 .owner = THIS_MODULE,
239 },
240 .probe = mxs_soc_platform_probe,
241 .remove = __devexit_p(mxs_soc_platform_remove),
242};
243
244module_platform_driver(mxs_pcm_driver);
245 234
246MODULE_LICENSE("GPL"); 235MODULE_LICENSE("GPL");
247MODULE_ALIAS("platform:mxs-pcm-audio");
diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h
index 5f01a9124b3d..35ba2ca42384 100644
--- a/sound/soc/mxs/mxs-pcm.h
+++ b/sound/soc/mxs/mxs-pcm.h
@@ -24,4 +24,7 @@ struct mxs_pcm_dma_params {
24 int chan_num; 24 int chan_num;
25}; 25};
26 26
27int mxs_pcm_platform_register(struct device *dev);
28void mxs_pcm_platform_unregister(struct device *dev);
29
27#endif 30#endif
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index 7fd224bb7324..aba71bfa33b1 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -18,6 +18,8 @@
18 18
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/of.h>
22#include <linux/of_device.h>
21#include <linux/platform_device.h> 23#include <linux/platform_device.h>
22#include <linux/slab.h> 24#include <linux/slab.h>
23#include <linux/dma-mapping.h> 25#include <linux/dma-mapping.h>
@@ -621,37 +623,57 @@ static irqreturn_t mxs_saif_irq(int irq, void *dev_id)
621 return IRQ_HANDLED; 623 return IRQ_HANDLED;
622} 624}
623 625
624static int mxs_saif_probe(struct platform_device *pdev) 626static int __devinit mxs_saif_probe(struct platform_device *pdev)
625{ 627{
628 struct device_node *np = pdev->dev.of_node;
626 struct resource *iores, *dmares; 629 struct resource *iores, *dmares;
627 struct mxs_saif *saif; 630 struct mxs_saif *saif;
628 struct mxs_saif_platform_data *pdata; 631 struct mxs_saif_platform_data *pdata;
629 struct pinctrl *pinctrl; 632 struct pinctrl *pinctrl;
630 int ret = 0; 633 int ret = 0;
631 634
632 if (pdev->id >= ARRAY_SIZE(mxs_saif)) 635
636 if (!np && pdev->id >= ARRAY_SIZE(mxs_saif))
633 return -EINVAL; 637 return -EINVAL;
634 638
635 saif = devm_kzalloc(&pdev->dev, sizeof(*saif), GFP_KERNEL); 639 saif = devm_kzalloc(&pdev->dev, sizeof(*saif), GFP_KERNEL);
636 if (!saif) 640 if (!saif)
637 return -ENOMEM; 641 return -ENOMEM;
638 642
639 mxs_saif[pdev->id] = saif; 643 if (np) {
640 saif->id = pdev->id; 644 struct device_node *master;
641 645 saif->id = of_alias_get_id(np, "saif");
642 pdata = pdev->dev.platform_data; 646 if (saif->id < 0)
643 if (pdata && !pdata->master_mode) { 647 return saif->id;
644 saif->master_id = pdata->master_id; 648 /*
645 if (saif->master_id < 0 || 649 * If there is no "fsl,saif-master" phandle, it's a saif
646 saif->master_id >= ARRAY_SIZE(mxs_saif) || 650 * master. Otherwise, it's a slave and its phandle points
647 saif->master_id == saif->id) { 651 * to the master.
648 dev_err(&pdev->dev, "get wrong master id\n"); 652 */
649 return -EINVAL; 653 master = of_parse_phandle(np, "fsl,saif-master", 0);
654 if (!master) {
655 saif->master_id = saif->id;
656 } else {
657 saif->master_id = of_alias_get_id(master, "saif");
658 if (saif->master_id < 0)
659 return saif->master_id;
650 } 660 }
651 } else { 661 } else {
652 saif->master_id = saif->id; 662 saif->id = pdev->id;
663 pdata = pdev->dev.platform_data;
664 if (pdata && !pdata->master_mode)
665 saif->master_id = pdata->master_id;
666 else
667 saif->master_id = saif->id;
668 }
669
670 if (saif->master_id < 0 || saif->master_id >= ARRAY_SIZE(mxs_saif)) {
671 dev_err(&pdev->dev, "get wrong master id\n");
672 return -EINVAL;
653 } 673 }
654 674
675 mxs_saif[saif->id] = saif;
676
655 pinctrl = devm_pinctrl_get_select_default(&pdev->dev); 677 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
656 if (IS_ERR(pinctrl)) { 678 if (IS_ERR(pinctrl)) {
657 ret = PTR_ERR(pinctrl); 679 ret = PTR_ERR(pinctrl);
@@ -677,12 +699,19 @@ static int mxs_saif_probe(struct platform_device *pdev)
677 699
678 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); 700 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
679 if (!dmares) { 701 if (!dmares) {
680 ret = -ENODEV; 702 /*
681 dev_err(&pdev->dev, "failed to get dma resource: %d\n", 703 * TODO: This is a temporary solution and should be changed
682 ret); 704 * to use generic DMA binding later when the helplers get in.
683 goto failed_get_resource; 705 */
706 ret = of_property_read_u32(np, "fsl,saif-dma-channel",
707 &saif->dma_param.chan_num);
708 if (ret) {
709 dev_err(&pdev->dev, "failed to get dma channel\n");
710 goto failed_get_resource;
711 }
712 } else {
713 saif->dma_param.chan_num = dmares->start;
684 } 714 }
685 saif->dma_param.chan_num = dmares->start;
686 715
687 saif->irq = platform_get_irq(pdev, 0); 716 saif->irq = platform_get_irq(pdev, 0);
688 if (saif->irq < 0) { 717 if (saif->irq < 0) {
@@ -716,24 +745,14 @@ static int mxs_saif_probe(struct platform_device *pdev)
716 goto failed_get_resource; 745 goto failed_get_resource;
717 } 746 }
718 747
719 saif->soc_platform_pdev = platform_device_alloc( 748 ret = mxs_pcm_platform_register(&pdev->dev);
720 "mxs-pcm-audio", pdev->id);
721 if (!saif->soc_platform_pdev) {
722 ret = -ENOMEM;
723 goto failed_pdev_alloc;
724 }
725
726 platform_set_drvdata(saif->soc_platform_pdev, saif);
727 ret = platform_device_add(saif->soc_platform_pdev);
728 if (ret) { 749 if (ret) {
729 dev_err(&pdev->dev, "failed to add soc platform device\n"); 750 dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
730 goto failed_pdev_add; 751 goto failed_pdev_alloc;
731 } 752 }
732 753
733 return 0; 754 return 0;
734 755
735failed_pdev_add:
736 platform_device_put(saif->soc_platform_pdev);
737failed_pdev_alloc: 756failed_pdev_alloc:
738 snd_soc_unregister_dai(&pdev->dev); 757 snd_soc_unregister_dai(&pdev->dev);
739failed_get_resource: 758failed_get_resource:
@@ -746,13 +765,19 @@ static int __devexit mxs_saif_remove(struct platform_device *pdev)
746{ 765{
747 struct mxs_saif *saif = platform_get_drvdata(pdev); 766 struct mxs_saif *saif = platform_get_drvdata(pdev);
748 767
749 platform_device_unregister(saif->soc_platform_pdev); 768 mxs_pcm_platform_unregister(&pdev->dev);
750 snd_soc_unregister_dai(&pdev->dev); 769 snd_soc_unregister_dai(&pdev->dev);
751 clk_put(saif->clk); 770 clk_put(saif->clk);
752 771
753 return 0; 772 return 0;
754} 773}
755 774
775static const struct of_device_id mxs_saif_dt_ids[] = {
776 { .compatible = "fsl,imx28-saif", },
777 { /* sentinel */ }
778};
779MODULE_DEVICE_TABLE(of, mxs_saif_dt_ids);
780
756static struct platform_driver mxs_saif_driver = { 781static struct platform_driver mxs_saif_driver = {
757 .probe = mxs_saif_probe, 782 .probe = mxs_saif_probe,
758 .remove = __devexit_p(mxs_saif_remove), 783 .remove = __devexit_p(mxs_saif_remove),
@@ -760,6 +785,7 @@ static struct platform_driver mxs_saif_driver = {
760 .driver = { 785 .driver = {
761 .name = "mxs-saif", 786 .name = "mxs-saif",
762 .owner = THIS_MODULE, 787 .owner = THIS_MODULE,
788 .of_match_table = mxs_saif_dt_ids,
763 }, 789 },
764}; 790};
765 791
diff --git a/sound/soc/mxs/mxs-saif.h b/sound/soc/mxs/mxs-saif.h
index 12c91e4eb941..3cb342e5bc90 100644
--- a/sound/soc/mxs/mxs-saif.h
+++ b/sound/soc/mxs/mxs-saif.h
@@ -123,7 +123,6 @@ struct mxs_saif {
123 unsigned int cur_rate; 123 unsigned int cur_rate;
124 unsigned int ongoing; 124 unsigned int ongoing;
125 125
126 struct platform_device *soc_platform_pdev;
127 u32 fifo_underrun; 126 u32 fifo_underrun;
128 u32 fifo_overrun; 127 u32 fifo_overrun;
129}; 128};
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
index 60f052b7cf22..3e6e8764b2e6 100644
--- a/sound/soc/mxs/mxs-sgtl5000.c
+++ b/sound/soc/mxs/mxs-sgtl5000.c
@@ -18,6 +18,8 @@
18 18
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/of.h>
22#include <linux/of_device.h>
21#include <sound/core.h> 23#include <sound/core.h>
22#include <sound/pcm.h> 24#include <sound/pcm.h>
23#include <sound/soc.h> 25#include <sound/soc.h>
@@ -90,7 +92,7 @@ static struct snd_soc_dai_link mxs_sgtl5000_dai[] = {
90 .codec_dai_name = "sgtl5000", 92 .codec_dai_name = "sgtl5000",
91 .codec_name = "sgtl5000.0-000a", 93 .codec_name = "sgtl5000.0-000a",
92 .cpu_dai_name = "mxs-saif.0", 94 .cpu_dai_name = "mxs-saif.0",
93 .platform_name = "mxs-pcm-audio.0", 95 .platform_name = "mxs-saif.0",
94 .ops = &mxs_sgtl5000_hifi_ops, 96 .ops = &mxs_sgtl5000_hifi_ops,
95 }, { 97 }, {
96 .name = "HiFi Rx", 98 .name = "HiFi Rx",
@@ -98,7 +100,7 @@ static struct snd_soc_dai_link mxs_sgtl5000_dai[] = {
98 .codec_dai_name = "sgtl5000", 100 .codec_dai_name = "sgtl5000",
99 .codec_name = "sgtl5000.0-000a", 101 .codec_name = "sgtl5000.0-000a",
100 .cpu_dai_name = "mxs-saif.1", 102 .cpu_dai_name = "mxs-saif.1",
101 .platform_name = "mxs-pcm-audio.1", 103 .platform_name = "mxs-saif.1",
102 .ops = &mxs_sgtl5000_hifi_ops, 104 .ops = &mxs_sgtl5000_hifi_ops,
103 }, 105 },
104}; 106};
@@ -110,11 +112,48 @@ static struct snd_soc_card mxs_sgtl5000 = {
110 .num_links = ARRAY_SIZE(mxs_sgtl5000_dai), 112 .num_links = ARRAY_SIZE(mxs_sgtl5000_dai),
111}; 113};
112 114
115static int __devinit mxs_sgtl5000_probe_dt(struct platform_device *pdev)
116{
117 struct device_node *np = pdev->dev.of_node;
118 struct device_node *saif_np[2], *codec_np;
119 int i, ret = 0;
120
121 if (!np)
122 return 1; /* no device tree */
123
124 saif_np[0] = of_parse_phandle(np, "saif-controllers", 0);
125 saif_np[1] = of_parse_phandle(np, "saif-controllers", 1);
126 codec_np = of_parse_phandle(np, "audio-codec", 0);
127 if (!saif_np[0] || !saif_np[1] || !codec_np) {
128 dev_err(&pdev->dev, "phandle missing or invalid\n");
129 return -EINVAL;
130 }
131
132 for (i = 0; i < 2; i++) {
133 mxs_sgtl5000_dai[i].codec_name = NULL;
134 mxs_sgtl5000_dai[i].codec_of_node = codec_np;
135 mxs_sgtl5000_dai[i].cpu_dai_name = NULL;
136 mxs_sgtl5000_dai[i].cpu_dai_of_node = saif_np[i];
137 mxs_sgtl5000_dai[i].platform_name = NULL;
138 mxs_sgtl5000_dai[i].platform_of_node = saif_np[i];
139 }
140
141 of_node_put(codec_np);
142 of_node_put(saif_np[0]);
143 of_node_put(saif_np[1]);
144
145 return ret;
146}
147
113static int __devinit mxs_sgtl5000_probe(struct platform_device *pdev) 148static int __devinit mxs_sgtl5000_probe(struct platform_device *pdev)
114{ 149{
115 struct snd_soc_card *card = &mxs_sgtl5000; 150 struct snd_soc_card *card = &mxs_sgtl5000;
116 int ret; 151 int ret;
117 152
153 ret = mxs_sgtl5000_probe_dt(pdev);
154 if (ret < 0)
155 return ret;
156
118 /* 157 /*
119 * Set an init clock(11.28Mhz) for sgtl5000 initialization(i2c r/w). 158 * Set an init clock(11.28Mhz) for sgtl5000 initialization(i2c r/w).
120 * The Sgtl5000 sysclk is derived from saif0 mclk and it's range 159 * The Sgtl5000 sysclk is derived from saif0 mclk and it's range
@@ -148,10 +187,17 @@ static int __devexit mxs_sgtl5000_remove(struct platform_device *pdev)
148 return 0; 187 return 0;
149} 188}
150 189
190static const struct of_device_id mxs_sgtl5000_dt_ids[] = {
191 { .compatible = "fsl,mxs-audio-sgtl5000", },
192 { /* sentinel */ }
193};
194MODULE_DEVICE_TABLE(of, mxs_sgtl5000_dt_ids);
195
151static struct platform_driver mxs_sgtl5000_audio_driver = { 196static struct platform_driver mxs_sgtl5000_audio_driver = {
152 .driver = { 197 .driver = {
153 .name = "mxs-sgtl5000", 198 .name = "mxs-sgtl5000",
154 .owner = THIS_MODULE, 199 .owner = THIS_MODULE,
200 .of_match_table = mxs_sgtl5000_dt_ids,
155 }, 201 },
156 .probe = mxs_sgtl5000_probe, 202 .probe = mxs_sgtl5000_probe,
157 .remove = __devexit_p(mxs_sgtl5000_remove), 203 .remove = __devexit_p(mxs_sgtl5000_remove),
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index deafbfaacdbf..9ccfa5e1c11b 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -113,6 +113,7 @@ config SND_OMAP_SOC_OMAP4_HDMI
113 tristate "SoC Audio support for Texas Instruments OMAP4 HDMI" 113 tristate "SoC Audio support for Texas Instruments OMAP4 HDMI"
114 depends on SND_OMAP_SOC && OMAP4_DSS_HDMI && OMAP2_DSS && ARCH_OMAP4 114 depends on SND_OMAP_SOC && OMAP4_DSS_HDMI && OMAP2_DSS && ARCH_OMAP4
115 select SND_OMAP_SOC_HDMI 115 select SND_OMAP_SOC_HDMI
116 select SND_SOC_OMAP_HDMI_CODEC
116 help 117 help
117 Say Y if you want to add support for SoC HDMI audio on Texas Instruments 118 Say Y if you want to add support for SoC HDMI audio on Texas Instruments
118 OMAP4 chips 119 OMAP4 chips
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index fd04ce139031..1c2aa7fab3fd 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -85,14 +85,12 @@ struct pxa2xx_pcm_dma_data {
85 char name[20]; 85 char name[20];
86}; 86};
87 87
88static struct pxa2xx_pcm_dma_params * 88static void pxa_ssp_set_dma_params(struct ssp_device *ssp, int width4,
89pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out) 89 int out, struct pxa2xx_pcm_dma_params *dma_data)
90{ 90{
91 struct pxa2xx_pcm_dma_data *dma; 91 struct pxa2xx_pcm_dma_data *dma;
92 92
93 dma = kzalloc(sizeof(struct pxa2xx_pcm_dma_data), GFP_KERNEL); 93 dma = container_of(dma_data, struct pxa2xx_pcm_dma_data, params);
94 if (dma == NULL)
95 return NULL;
96 94
97 snprintf(dma->name, 20, "SSP%d PCM %s %s", ssp->port_id, 95 snprintf(dma->name, 20, "SSP%d PCM %s %s", ssp->port_id,
98 width4 ? "32-bit" : "16-bit", out ? "out" : "in"); 96 width4 ? "32-bit" : "16-bit", out ? "out" : "in");
@@ -103,8 +101,6 @@ pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
103 (DCMD_INCTRGADDR | DCMD_FLOWSRC)) | 101 (DCMD_INCTRGADDR | DCMD_FLOWSRC)) |
104 (width4 ? DCMD_WIDTH4 : DCMD_WIDTH2) | DCMD_BURST16; 102 (width4 ? DCMD_WIDTH4 : DCMD_WIDTH2) | DCMD_BURST16;
105 dma->params.dev_addr = ssp->phys_base + SSDR; 103 dma->params.dev_addr = ssp->phys_base + SSDR;
106
107 return &dma->params;
108} 104}
109 105
110static int pxa_ssp_startup(struct snd_pcm_substream *substream, 106static int pxa_ssp_startup(struct snd_pcm_substream *substream,
@@ -112,6 +108,7 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
112{ 108{
113 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai); 109 struct ssp_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
114 struct ssp_device *ssp = priv->ssp; 110 struct ssp_device *ssp = priv->ssp;
111 struct pxa2xx_pcm_dma_data *dma;
115 int ret = 0; 112 int ret = 0;
116 113
117 if (!cpu_dai->active) { 114 if (!cpu_dai->active) {
@@ -119,8 +116,10 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
119 pxa_ssp_disable(ssp); 116 pxa_ssp_disable(ssp);
120 } 117 }
121 118
122 kfree(snd_soc_dai_get_dma_data(cpu_dai, substream)); 119 dma = kzalloc(sizeof(struct pxa2xx_pcm_dma_data), GFP_KERNEL);
123 snd_soc_dai_set_dma_data(cpu_dai, substream, NULL); 120 if (!dma)
121 return -ENOMEM;
122 snd_soc_dai_set_dma_data(cpu_dai, substream, &dma->params);
124 123
125 return ret; 124 return ret;
126} 125}
@@ -573,18 +572,13 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
573 572
574 dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream); 573 dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
575 574
576 /* generate correct DMA params */
577 kfree(dma_data);
578
579 /* Network mode with one active slot (ttsa == 1) can be used 575 /* Network mode with one active slot (ttsa == 1) can be used
580 * to force 16-bit frame width on the wire (for S16_LE), even 576 * to force 16-bit frame width on the wire (for S16_LE), even
581 * with two channels. Use 16-bit DMA transfers for this case. 577 * with two channels. Use 16-bit DMA transfers for this case.
582 */ 578 */
583 dma_data = pxa_ssp_get_dma_params(ssp, 579 pxa_ssp_set_dma_params(ssp,
584 ((chn == 2) && (ttsa != 1)) || (width == 32), 580 ((chn == 2) && (ttsa != 1)) || (width == 32),
585 substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 581 substream->stream == SNDRV_PCM_STREAM_PLAYBACK, dma_data);
586
587 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
588 582
589 /* we can only change the settings if the port is not in use */ 583 /* we can only change the settings if the port is not in use */
590 if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) 584 if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index d08583790d23..3075a426124c 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -166,7 +166,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
166 struct pxa2xx_pcm_dma_params *dma_data; 166 struct pxa2xx_pcm_dma_params *dma_data;
167 167
168 BUG_ON(IS_ERR(clk_i2s)); 168 BUG_ON(IS_ERR(clk_i2s));
169 clk_enable(clk_i2s); 169 clk_prepare_enable(clk_i2s);
170 clk_ena = 1; 170 clk_ena = 1;
171 pxa_i2s_wait(); 171 pxa_i2s_wait();
172 172
@@ -259,7 +259,7 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream,
259 SACR0 &= ~SACR0_ENB; 259 SACR0 &= ~SACR0_ENB;
260 pxa_i2s_wait(); 260 pxa_i2s_wait();
261 if (clk_ena) { 261 if (clk_ena) {
262 clk_disable(clk_i2s); 262 clk_disable_unprepare(clk_i2s);
263 clk_ena = 0; 263 clk_ena = 0;
264 } 264 }
265 } 265 }
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c
index e7416851bf7d..c82c646b8a08 100644
--- a/sound/soc/samsung/littlemill.c
+++ b/sound/soc/samsung/littlemill.c
@@ -23,10 +23,10 @@ static int littlemill_set_bias_level(struct snd_soc_card *card,
23 struct snd_soc_dapm_context *dapm, 23 struct snd_soc_dapm_context *dapm,
24 enum snd_soc_bias_level level) 24 enum snd_soc_bias_level level)
25{ 25{
26 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 26 struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai;
27 int ret; 27 int ret;
28 28
29 if (dapm->dev != codec_dai->dev) 29 if (dapm->dev != aif1_dai->dev)
30 return 0; 30 return 0;
31 31
32 switch (level) { 32 switch (level) {
@@ -36,7 +36,7 @@ static int littlemill_set_bias_level(struct snd_soc_card *card,
36 * then do so now, otherwise these are noops. 36 * then do so now, otherwise these are noops.
37 */ 37 */
38 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { 38 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
39 ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 39 ret = snd_soc_dai_set_pll(aif1_dai, WM8994_FLL1,
40 WM8994_FLL_SRC_MCLK2, 32768, 40 WM8994_FLL_SRC_MCLK2, 32768,
41 sample_rate * 512); 41 sample_rate * 512);
42 if (ret < 0) { 42 if (ret < 0) {
@@ -44,7 +44,7 @@ static int littlemill_set_bias_level(struct snd_soc_card *card,
44 return ret; 44 return ret;
45 } 45 }
46 46
47 ret = snd_soc_dai_set_sysclk(codec_dai, 47 ret = snd_soc_dai_set_sysclk(aif1_dai,
48 WM8994_SYSCLK_FLL1, 48 WM8994_SYSCLK_FLL1,
49 sample_rate * 512, 49 sample_rate * 512,
50 SND_SOC_CLOCK_IN); 50 SND_SOC_CLOCK_IN);
@@ -66,25 +66,25 @@ static int littlemill_set_bias_level_post(struct snd_soc_card *card,
66 struct snd_soc_dapm_context *dapm, 66 struct snd_soc_dapm_context *dapm,
67 enum snd_soc_bias_level level) 67 enum snd_soc_bias_level level)
68{ 68{
69 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 69 struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai;
70 int ret; 70 int ret;
71 71
72 if (dapm->dev != codec_dai->dev) 72 if (dapm->dev != aif1_dai->dev)
73 return 0; 73 return 0;
74 74
75 switch (level) { 75 switch (level) {
76 case SND_SOC_BIAS_STANDBY: 76 case SND_SOC_BIAS_STANDBY:
77 ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK2, 77 ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2,
78 32768, SND_SOC_CLOCK_IN); 78 32768, SND_SOC_CLOCK_IN);
79 if (ret < 0) { 79 if (ret < 0) {
80 pr_err("Failed to switch away from FLL: %d\n", ret); 80 pr_err("Failed to switch away from FLL1: %d\n", ret);
81 return ret; 81 return ret;
82 } 82 }
83 83
84 ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 84 ret = snd_soc_dai_set_pll(aif1_dai, WM8994_FLL1,
85 0, 0, 0); 85 0, 0, 0);
86 if (ret < 0) { 86 if (ret < 0) {
87 pr_err("Failed to stop FLL: %d\n", ret); 87 pr_err("Failed to stop FLL1: %d\n", ret);
88 return ret; 88 return ret;
89 } 89 }
90 break; 90 break;
@@ -131,6 +131,14 @@ static struct snd_soc_ops littlemill_ops = {
131 .hw_params = littlemill_hw_params, 131 .hw_params = littlemill_hw_params,
132}; 132};
133 133
134static const struct snd_soc_pcm_stream baseband_params = {
135 .formats = SNDRV_PCM_FMTBIT_S32_LE,
136 .rate_min = 8000,
137 .rate_max = 8000,
138 .channels_min = 2,
139 .channels_max = 2,
140};
141
134static struct snd_soc_dai_link littlemill_dai[] = { 142static struct snd_soc_dai_link littlemill_dai[] = {
135 { 143 {
136 .name = "CPU", 144 .name = "CPU",
@@ -143,13 +151,75 @@ static struct snd_soc_dai_link littlemill_dai[] = {
143 | SND_SOC_DAIFMT_CBM_CFM, 151 | SND_SOC_DAIFMT_CBM_CFM,
144 .ops = &littlemill_ops, 152 .ops = &littlemill_ops,
145 }, 153 },
154 {
155 .name = "Baseband",
156 .stream_name = "Baseband",
157 .cpu_dai_name = "wm8994-aif2",
158 .codec_dai_name = "wm1250-ev1",
159 .codec_name = "wm1250-ev1.1-0027",
160 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
161 | SND_SOC_DAIFMT_CBM_CFM,
162 .ignore_suspend = 1,
163 .params = &baseband_params,
164 },
146}; 165};
147 166
167static int bbclk_ev(struct snd_soc_dapm_widget *w,
168 struct snd_kcontrol *kcontrol, int event)
169{
170 struct snd_soc_card *card = w->dapm->card;
171 struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai;
172 int ret;
173
174 switch (event) {
175 case SND_SOC_DAPM_PRE_PMU:
176 ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2,
177 WM8994_FLL_SRC_BCLK, 64 * 8000,
178 8000 * 256);
179 if (ret < 0) {
180 pr_err("Failed to start FLL: %d\n", ret);
181 return ret;
182 }
183
184 ret = snd_soc_dai_set_sysclk(aif2_dai, WM8994_SYSCLK_FLL2,
185 8000 * 256,
186 SND_SOC_CLOCK_IN);
187 if (ret < 0) {
188 pr_err("Failed to set SYSCLK: %d\n", ret);
189 return ret;
190 }
191 break;
192 case SND_SOC_DAPM_POST_PMD:
193 ret = snd_soc_dai_set_sysclk(aif2_dai, WM8994_SYSCLK_MCLK2,
194 32768, SND_SOC_CLOCK_IN);
195 if (ret < 0) {
196 pr_err("Failed to switch away from FLL2: %d\n", ret);
197 return ret;
198 }
199
200 ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2,
201 0, 0, 0);
202 if (ret < 0) {
203 pr_err("Failed to stop FLL2: %d\n", ret);
204 return ret;
205 }
206 break;
207 default:
208 return -EINVAL;
209 }
210
211 return 0;
212}
213
148static struct snd_soc_dapm_widget widgets[] = { 214static struct snd_soc_dapm_widget widgets[] = {
149 SND_SOC_DAPM_HP("Headphone", NULL), 215 SND_SOC_DAPM_HP("Headphone", NULL),
150 216
151 SND_SOC_DAPM_MIC("AMIC", NULL), 217 SND_SOC_DAPM_MIC("AMIC", NULL),
152 SND_SOC_DAPM_MIC("DMIC", NULL), 218 SND_SOC_DAPM_MIC("DMIC", NULL),
219
220 SND_SOC_DAPM_SUPPLY_S("Baseband Clock", -1, SND_SOC_NOPM, 0, 0,
221 bbclk_ev,
222 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
153}; 223};
154 224
155static struct snd_soc_dapm_route audio_paths[] = { 225static struct snd_soc_dapm_route audio_paths[] = {
@@ -162,6 +232,8 @@ static struct snd_soc_dapm_route audio_paths[] = {
162 { "DMIC", NULL, "MICBIAS2" }, /* Default for DMICBIAS jumper */ 232 { "DMIC", NULL, "MICBIAS2" }, /* Default for DMICBIAS jumper */
163 { "DMIC1DAT", NULL, "DMIC" }, 233 { "DMIC1DAT", NULL, "DMIC" },
164 { "DMIC2DAT", NULL, "DMIC" }, 234 { "DMIC2DAT", NULL, "DMIC" },
235
236 { "AIF2CLK", NULL, "Baseband Clock" },
165}; 237};
166 238
167static struct snd_soc_jack littlemill_headset; 239static struct snd_soc_jack littlemill_headset;
@@ -169,10 +241,16 @@ static struct snd_soc_jack littlemill_headset;
169static int littlemill_late_probe(struct snd_soc_card *card) 241static int littlemill_late_probe(struct snd_soc_card *card)
170{ 242{
171 struct snd_soc_codec *codec = card->rtd[0].codec; 243 struct snd_soc_codec *codec = card->rtd[0].codec;
172 struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; 244 struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai;
245 struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai;
173 int ret; 246 int ret;
174 247
175 ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK2, 248 ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2,
249 32768, SND_SOC_CLOCK_IN);
250 if (ret < 0)
251 return ret;
252
253 ret = snd_soc_dai_set_sysclk(aif2_dai, WM8994_SYSCLK_MCLK2,
176 32768, SND_SOC_CLOCK_IN); 254 32768, SND_SOC_CLOCK_IN);
177 if (ret < 0) 255 if (ret < 0)
178 return ret; 256 return ret;
diff --git a/sound/soc/samsung/lowland.c b/sound/soc/samsung/lowland.c
index 4adff934f771..6abf341c4a2a 100644
--- a/sound/soc/samsung/lowland.c
+++ b/sound/soc/samsung/lowland.c
@@ -21,33 +21,6 @@
21#define MCLK1_RATE (44100 * 512) 21#define MCLK1_RATE (44100 * 512)
22#define CLKOUT_RATE (44100 * 256) 22#define CLKOUT_RATE (44100 * 256)
23 23
24static int lowland_hw_params(struct snd_pcm_substream *substream,
25 struct snd_pcm_hw_params *params)
26{
27 struct snd_soc_pcm_runtime *rtd = substream->private_data;
28 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
29 struct snd_soc_dai *codec_dai = rtd->codec_dai;
30 int ret;
31
32 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
33 | SND_SOC_DAIFMT_NB_NF
34 | SND_SOC_DAIFMT_CBM_CFM);
35 if (ret < 0)
36 return ret;
37
38 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
39 | SND_SOC_DAIFMT_NB_NF
40 | SND_SOC_DAIFMT_CBM_CFM);
41 if (ret < 0)
42 return ret;
43
44 return 0;
45}
46
47static struct snd_soc_ops lowland_ops = {
48 .hw_params = lowland_hw_params,
49};
50
51static struct snd_soc_jack lowland_headset; 24static struct snd_soc_jack lowland_headset;
52 25
53/* Headset jack detection DAPM pins */ 26/* Headset jack detection DAPM pins */
@@ -101,6 +74,25 @@ static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd)
101 return 0; 74 return 0;
102} 75}
103 76
77static int lowland_wm9081_init(struct snd_soc_pcm_runtime *rtd)
78{
79 struct snd_soc_codec *codec = rtd->codec;
80
81 snd_soc_dapm_nc_pin(&codec->dapm, "LINEOUT");
82
83 /* At any time the WM9081 is active it will have this clock */
84 return snd_soc_codec_set_sysclk(codec, WM9081_SYSCLK_MCLK, 0,
85 CLKOUT_RATE, 0);
86}
87
88static const struct snd_soc_pcm_stream sub_params = {
89 .formats = SNDRV_PCM_FMTBIT_S32_LE,
90 .rate_min = 44100,
91 .rate_max = 44100,
92 .channels_min = 2,
93 .channels_max = 2,
94};
95
104static struct snd_soc_dai_link lowland_dai[] = { 96static struct snd_soc_dai_link lowland_dai[] = {
105 { 97 {
106 .name = "CPU", 98 .name = "CPU",
@@ -109,7 +101,8 @@ static struct snd_soc_dai_link lowland_dai[] = {
109 .codec_dai_name = "wm5100-aif1", 101 .codec_dai_name = "wm5100-aif1",
110 .platform_name = "samsung-audio", 102 .platform_name = "samsung-audio",
111 .codec_name = "wm5100.1-001a", 103 .codec_name = "wm5100.1-001a",
112 .ops = &lowland_ops, 104 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
105 SND_SOC_DAIFMT_CBM_CFM,
113 .init = lowland_wm5100_init, 106 .init = lowland_wm5100_init,
114 }, 107 },
115 { 108 {
@@ -118,24 +111,20 @@ static struct snd_soc_dai_link lowland_dai[] = {
118 .cpu_dai_name = "wm5100-aif2", 111 .cpu_dai_name = "wm5100-aif2",
119 .codec_dai_name = "wm1250-ev1", 112 .codec_dai_name = "wm1250-ev1",
120 .codec_name = "wm1250-ev1.1-0027", 113 .codec_name = "wm1250-ev1.1-0027",
121 .ops = &lowland_ops, 114 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
115 SND_SOC_DAIFMT_CBM_CFM,
122 .ignore_suspend = 1, 116 .ignore_suspend = 1,
123 }, 117 },
124};
125
126static int lowland_wm9081_init(struct snd_soc_dapm_context *dapm)
127{
128 snd_soc_dapm_nc_pin(dapm, "LINEOUT");
129
130 /* At any time the WM9081 is active it will have this clock */
131 return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0,
132 CLKOUT_RATE, 0);
133}
134
135static struct snd_soc_aux_dev lowland_aux_dev[] = {
136 { 118 {
137 .name = "wm9081", 119 .name = "Sub Speaker",
120 .stream_name = "Sub Speaker",
121 .cpu_dai_name = "wm5100-aif3",
122 .codec_dai_name = "wm9081-hifi",
138 .codec_name = "wm9081.1-006c", 123 .codec_name = "wm9081.1-006c",
124 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
125 SND_SOC_DAIFMT_CBM_CFM,
126 .ignore_suspend = 1,
127 .params = &sub_params,
139 .init = lowland_wm9081_init, 128 .init = lowland_wm9081_init,
140 }, 129 },
141}; 130};
@@ -180,8 +169,6 @@ static struct snd_soc_card lowland = {
180 .owner = THIS_MODULE, 169 .owner = THIS_MODULE,
181 .dai_link = lowland_dai, 170 .dai_link = lowland_dai,
182 .num_links = ARRAY_SIZE(lowland_dai), 171 .num_links = ARRAY_SIZE(lowland_dai),
183 .aux_dev = lowland_aux_dev,
184 .num_aux_devs = ARRAY_SIZE(lowland_aux_dev),
185 .codec_conf = lowland_codec_conf, 172 .codec_conf = lowland_codec_conf,
186 .num_configs = ARRAY_SIZE(lowland_codec_conf), 173 .num_configs = ARRAY_SIZE(lowland_codec_conf),
187 174
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index f9ab7707a3e4..a4a9fc7e8c76 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -92,33 +92,6 @@ static int speyside_set_bias_level_post(struct snd_soc_card *card,
92 return 0; 92 return 0;
93} 93}
94 94
95static int speyside_hw_params(struct snd_pcm_substream *substream,
96 struct snd_pcm_hw_params *params)
97{
98 struct snd_soc_pcm_runtime *rtd = substream->private_data;
99 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
100 struct snd_soc_dai *codec_dai = rtd->codec_dai;
101 int ret;
102
103 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
104 | SND_SOC_DAIFMT_NB_NF
105 | SND_SOC_DAIFMT_CBM_CFM);
106 if (ret < 0)
107 return ret;
108
109 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
110 | SND_SOC_DAIFMT_NB_NF
111 | SND_SOC_DAIFMT_CBM_CFM);
112 if (ret < 0)
113 return ret;
114
115 return 0;
116}
117
118static struct snd_soc_ops speyside_ops = {
119 .hw_params = speyside_hw_params,
120};
121
122static struct snd_soc_jack speyside_headset; 95static struct snd_soc_jack speyside_headset;
123 96
124/* Headset jack detection DAPM pins */ 97/* Headset jack detection DAPM pins */
@@ -208,7 +181,8 @@ static struct snd_soc_dai_link speyside_dai[] = {
208 .platform_name = "samsung-audio", 181 .platform_name = "samsung-audio",
209 .codec_name = "wm8996.1-001a", 182 .codec_name = "wm8996.1-001a",
210 .init = speyside_wm8996_init, 183 .init = speyside_wm8996_init,
211 .ops = &speyside_ops, 184 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
185 | SND_SOC_DAIFMT_CBM_CFM,
212 }, 186 },
213 { 187 {
214 .name = "Baseband", 188 .name = "Baseband",
@@ -216,7 +190,8 @@ static struct snd_soc_dai_link speyside_dai[] = {
216 .cpu_dai_name = "wm8996-aif2", 190 .cpu_dai_name = "wm8996-aif2",
217 .codec_dai_name = "wm1250-ev1", 191 .codec_dai_name = "wm1250-ev1",
218 .codec_name = "wm1250-ev1.1-0027", 192 .codec_name = "wm1250-ev1.1-0027",
219 .ops = &speyside_ops, 193 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
194 | SND_SOC_DAIFMT_CBM_CFM,
220 .ignore_suspend = 1, 195 .ignore_suspend = 1,
221 }, 196 },
222}; 197};
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index d8e06a607a22..6bcb1164d599 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -22,6 +22,7 @@ config SND_SOC_SH4_SSI
22 22
23config SND_SOC_SH4_FSI 23config SND_SOC_SH4_FSI
24 tristate "SH4 FSI support" 24 tristate "SH4 FSI support"
25 select SND_SIMPLE_CARD
25 help 26 help
26 This option enables FSI sound support 27 This option enables FSI sound support
27 28
@@ -46,29 +47,6 @@ config SND_SH7760_AC97
46 This option enables generic sound support for the first 47 This option enables generic sound support for the first
47 AC97 unit of the SH7760. 48 AC97 unit of the SH7760.
48 49
49config SND_FSI_AK4642
50 tristate "FSI-AK4642 sound support"
51 depends on SND_SOC_SH4_FSI && I2C
52 select SND_SOC_AK4642
53 help
54 This option enables generic sound support for the
55 FSI - AK4642 unit
56
57config SND_FSI_DA7210
58 tristate "FSI-DA7210 sound support"
59 depends on SND_SOC_SH4_FSI && I2C
60 select SND_SOC_DA7210
61 help
62 This option enables generic sound support for the
63 FSI - DA7210 unit
64
65config SND_FSI_HDMI
66 tristate "FSI-HDMI sound support"
67 depends on SND_SOC_SH4_FSI && FB_SH_MOBILE_HDMI
68 help
69 This option enables generic sound support for the
70 FSI - HDMI unit
71
72config SND_SIU_MIGOR 50config SND_SIU_MIGOR
73 tristate "SIU sound support on Migo-R" 51 tristate "SIU sound support on Migo-R"
74 depends on SH_MIGOR 52 depends on SH_MIGOR
diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile
index 94476d4c0fd5..849b387d17d9 100644
--- a/sound/soc/sh/Makefile
+++ b/sound/soc/sh/Makefile
@@ -14,13 +14,7 @@ obj-$(CONFIG_SND_SOC_SH4_SIU) += snd-soc-siu.o
14 14
15## boards 15## boards
16snd-soc-sh7760-ac97-objs := sh7760-ac97.o 16snd-soc-sh7760-ac97-objs := sh7760-ac97.o
17snd-soc-fsi-ak4642-objs := fsi-ak4642.o
18snd-soc-fsi-da7210-objs := fsi-da7210.o
19snd-soc-fsi-hdmi-objs := fsi-hdmi.o
20snd-soc-migor-objs := migor.o 17snd-soc-migor-objs := migor.o
21 18
22obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o 19obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o
23obj-$(CONFIG_SND_FSI_AK4642) += snd-soc-fsi-ak4642.o
24obj-$(CONFIG_SND_FSI_DA7210) += snd-soc-fsi-da7210.o
25obj-$(CONFIG_SND_FSI_HDMI) += snd-soc-fsi-hdmi.o
26obj-$(CONFIG_SND_SIU_MIGOR) += snd-soc-migor.o 20obj-$(CONFIG_SND_SIU_MIGOR) += snd-soc-migor.o
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
deleted file mode 100644
index 97f540aabbdd..000000000000
--- a/sound/soc/sh/fsi-ak4642.c
+++ /dev/null
@@ -1,108 +0,0 @@
1/*
2 * FSI-AK464x sound support for ms7724se
3 *
4 * Copyright (C) 2009 Renesas Solutions Corp.
5 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11
12#include <linux/platform_device.h>
13#include <linux/module.h>
14#include <sound/sh_fsi.h>
15
16struct fsi_ak4642_data {
17 const char *name;
18 const char *card;
19 const char *cpu_dai;
20 const char *codec;
21 const char *platform;
22 int id;
23};
24
25static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
26{
27 struct snd_soc_dai *codec = rtd->codec_dai;
28 struct snd_soc_dai *cpu = rtd->cpu_dai;
29 int ret;
30
31 ret = snd_soc_dai_set_fmt(codec, SND_SOC_DAIFMT_LEFT_J |
32 SND_SOC_DAIFMT_CBM_CFM);
33 if (ret < 0)
34 return ret;
35
36 ret = snd_soc_dai_set_sysclk(codec, 0, 11289600, 0);
37 if (ret < 0)
38 return ret;
39
40 ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_LEFT_J |
41 SND_SOC_DAIFMT_CBS_CFS);
42
43 return ret;
44}
45
46static struct snd_soc_dai_link fsi_dai_link = {
47 .codec_dai_name = "ak4642-hifi",
48 .init = fsi_ak4642_dai_init,
49};
50
51static struct snd_soc_card fsi_soc_card = {
52 .owner = THIS_MODULE,
53 .dai_link = &fsi_dai_link,
54 .num_links = 1,
55};
56
57static struct platform_device *fsi_snd_device;
58
59static int fsi_ak4642_probe(struct platform_device *pdev)
60{
61 int ret = -ENOMEM;
62 struct fsi_ak4642_info *pinfo = pdev->dev.platform_data;
63
64 if (!pinfo) {
65 dev_err(&pdev->dev, "no info for fsi ak4642\n");
66 goto out;
67 }
68
69 fsi_snd_device = platform_device_alloc("soc-audio", pinfo->id);
70 if (!fsi_snd_device)
71 goto out;
72
73 fsi_dai_link.name = pinfo->name;
74 fsi_dai_link.stream_name = pinfo->name;
75 fsi_dai_link.cpu_dai_name = pinfo->cpu_dai;
76 fsi_dai_link.platform_name = pinfo->platform;
77 fsi_dai_link.codec_name = pinfo->codec;
78 fsi_soc_card.name = pinfo->card;
79
80 platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
81 ret = platform_device_add(fsi_snd_device);
82
83 if (ret)
84 platform_device_put(fsi_snd_device);
85
86out:
87 return ret;
88}
89
90static int fsi_ak4642_remove(struct platform_device *pdev)
91{
92 platform_device_unregister(fsi_snd_device);
93 return 0;
94}
95
96static struct platform_driver fsi_ak4642 = {
97 .driver = {
98 .name = "fsi-ak4642-audio",
99 },
100 .probe = fsi_ak4642_probe,
101 .remove = fsi_ak4642_remove,
102};
103
104module_platform_driver(fsi_ak4642);
105
106MODULE_LICENSE("GPL");
107MODULE_DESCRIPTION("Generic SH4 FSI-AK4642 sound card");
108MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
deleted file mode 100644
index 1dd3354c7411..000000000000
--- a/sound/soc/sh/fsi-da7210.c
+++ /dev/null
@@ -1,81 +0,0 @@
1/*
2 * fsi-da7210.c
3 *
4 * Copyright (C) 2009 Renesas Solutions Corp.
5 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/platform_device.h>
14#include <linux/module.h>
15#include <sound/sh_fsi.h>
16
17static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd)
18{
19 struct snd_soc_dai *codec = rtd->codec_dai;
20 struct snd_soc_dai *cpu = rtd->cpu_dai;
21 int ret;
22
23 ret = snd_soc_dai_set_fmt(codec,
24 SND_SOC_DAIFMT_I2S |
25 SND_SOC_DAIFMT_CBM_CFM);
26 if (ret < 0)
27 return ret;
28
29 ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_I2S |
30 SND_SOC_DAIFMT_CBS_CFS);
31
32 return ret;
33}
34
35static struct snd_soc_dai_link fsi_da7210_dai = {
36 .name = "DA7210",
37 .stream_name = "DA7210",
38 .cpu_dai_name = "fsib-dai", /* FSI B */
39 .codec_dai_name = "da7210-hifi",
40 .platform_name = "sh_fsi.0",
41 .codec_name = "da7210-codec.0-001a",
42 .init = fsi_da7210_init,
43};
44
45static struct snd_soc_card fsi_soc_card = {
46 .name = "FSI-DA7210",
47 .owner = THIS_MODULE,
48 .dai_link = &fsi_da7210_dai,
49 .num_links = 1,
50};
51
52static struct platform_device *fsi_da7210_snd_device;
53
54static int __init fsi_da7210_sound_init(void)
55{
56 int ret;
57
58 fsi_da7210_snd_device = platform_device_alloc("soc-audio", FSI_PORT_B);
59 if (!fsi_da7210_snd_device)
60 return -ENOMEM;
61
62 platform_set_drvdata(fsi_da7210_snd_device, &fsi_soc_card);
63 ret = platform_device_add(fsi_da7210_snd_device);
64 if (ret)
65 platform_device_put(fsi_da7210_snd_device);
66
67 return ret;
68}
69
70static void __exit fsi_da7210_sound_exit(void)
71{
72 platform_device_unregister(fsi_da7210_snd_device);
73}
74
75module_init(fsi_da7210_sound_init);
76module_exit(fsi_da7210_sound_exit);
77
78/* Module information */
79MODULE_DESCRIPTION("ALSA SoC FSI DA2710");
80MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
81MODULE_LICENSE("GPL");
diff --git a/sound/soc/sh/fsi-hdmi.c b/sound/soc/sh/fsi-hdmi.c
deleted file mode 100644
index 6e41908323e8..000000000000
--- a/sound/soc/sh/fsi-hdmi.c
+++ /dev/null
@@ -1,118 +0,0 @@
1/*
2 * FSI - HDMI sound support
3 *
4 * Copyright (C) 2010 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11
12#include <linux/platform_device.h>
13#include <linux/module.h>
14#include <sound/sh_fsi.h>
15
16struct fsi_hdmi_data {
17 const char *cpu_dai;
18 const char *card;
19 int id;
20};
21
22static int fsi_hdmi_dai_init(struct snd_soc_pcm_runtime *rtd)
23{
24 struct snd_soc_dai *cpu = rtd->cpu_dai;
25 int ret;
26
27 ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_CBM_CFM);
28
29 return ret;
30}
31
32static struct snd_soc_dai_link fsi_dai_link = {
33 .name = "HDMI",
34 .stream_name = "HDMI",
35 .codec_dai_name = "sh_mobile_hdmi-hifi",
36 .platform_name = "sh_fsi2",
37 .codec_name = "sh-mobile-hdmi",
38 .init = fsi_hdmi_dai_init,
39};
40
41static struct snd_soc_card fsi_soc_card = {
42 .owner = THIS_MODULE,
43 .dai_link = &fsi_dai_link,
44 .num_links = 1,
45};
46
47static struct platform_device *fsi_snd_device;
48
49static int fsi_hdmi_probe(struct platform_device *pdev)
50{
51 int ret = -ENOMEM;
52 const struct platform_device_id *id_entry;
53 struct fsi_hdmi_data *pdata;
54
55 id_entry = pdev->id_entry;
56 if (!id_entry) {
57 dev_err(&pdev->dev, "unknown fsi hdmi\n");
58 return -ENODEV;
59 }
60
61 pdata = (struct fsi_hdmi_data *)id_entry->driver_data;
62
63 fsi_snd_device = platform_device_alloc("soc-audio", pdata->id);
64 if (!fsi_snd_device)
65 goto out;
66
67 fsi_dai_link.cpu_dai_name = pdata->cpu_dai;
68 fsi_soc_card.name = pdata->card;
69
70 platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
71 ret = platform_device_add(fsi_snd_device);
72
73 if (ret)
74 platform_device_put(fsi_snd_device);
75
76out:
77 return ret;
78}
79
80static int fsi_hdmi_remove(struct platform_device *pdev)
81{
82 platform_device_unregister(fsi_snd_device);
83 return 0;
84}
85
86static struct fsi_hdmi_data fsi2_a_hdmi = {
87 .cpu_dai = "fsia-dai",
88 .card = "FSI2A-HDMI",
89 .id = FSI_PORT_A,
90};
91
92static struct fsi_hdmi_data fsi2_b_hdmi = {
93 .cpu_dai = "fsib-dai",
94 .card = "FSI2B-HDMI",
95 .id = FSI_PORT_B,
96};
97
98static struct platform_device_id fsi_id_table[] = {
99 /* FSI 2 */
100 { "sh_fsi2_a_hdmi", (kernel_ulong_t)&fsi2_a_hdmi },
101 { "sh_fsi2_b_hdmi", (kernel_ulong_t)&fsi2_b_hdmi },
102 {},
103};
104
105static struct platform_driver fsi_hdmi = {
106 .driver = {
107 .name = "fsi-hdmi-audio",
108 },
109 .probe = fsi_hdmi_probe,
110 .remove = fsi_hdmi_remove,
111 .id_table = fsi_id_table,
112};
113
114module_platform_driver(fsi_hdmi);
115
116MODULE_LICENSE("GPL");
117MODULE_DESCRIPTION("Generic SH4 FSI-HDMI sound card");
118MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 74ed2dffbffd..7cee22515d9d 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -132,6 +132,25 @@
132typedef int (*set_rate_func)(struct device *dev, int rate, int enable); 132typedef int (*set_rate_func)(struct device *dev, int rate, int enable);
133 133
134/* 134/*
135 * bus options
136 *
137 * 0x000000BA
138 *
139 * A : sample widtht 16bit setting
140 * B : sample widtht 24bit setting
141 */
142
143#define SHIFT_16DATA 0
144#define SHIFT_24DATA 4
145
146#define PACKAGE_24BITBUS_BACK 0
147#define PACKAGE_24BITBUS_FRONT 1
148#define PACKAGE_16BITBUS_STREAM 2
149
150#define BUSOP_SET(s, a) ((a) << SHIFT_ ## s ## DATA)
151#define BUSOP_GET(s, a) (((a) >> SHIFT_ ## s ## DATA) & 0xF)
152
153/*
135 * FSI driver use below type name for variable 154 * FSI driver use below type name for variable
136 * 155 *
137 * xxx_num : number of data 156 * xxx_num : number of data
@@ -189,6 +208,11 @@ struct fsi_stream {
189 int oerr_num; 208 int oerr_num;
190 209
191 /* 210 /*
211 * bus options
212 */
213 u32 bus_option;
214
215 /*
192 * thse are initialized by fsi_handler_init() 216 * thse are initialized by fsi_handler_init()
193 */ 217 */
194 struct fsi_stream_handler *handler; 218 struct fsi_stream_handler *handler;
@@ -211,8 +235,7 @@ struct fsi_priv {
211 struct fsi_stream playback; 235 struct fsi_stream playback;
212 struct fsi_stream capture; 236 struct fsi_stream capture;
213 237
214 u32 do_fmt; 238 u32 fmt;
215 u32 di_fmt;
216 239
217 int chan_num:16; 240 int chan_num:16;
218 int clk_master:1; 241 int clk_master:1;
@@ -321,6 +344,10 @@ static void _fsi_master_mask_set(struct fsi_master *master,
321/* 344/*
322 * basic function 345 * basic function
323 */ 346 */
347static int fsi_version(struct fsi_master *master)
348{
349 return master->core->ver;
350}
324 351
325static struct fsi_master *fsi_get_master(struct fsi_priv *fsi) 352static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
326{ 353{
@@ -495,6 +522,7 @@ static void fsi_stream_init(struct fsi_priv *fsi,
495 io->period_samples = fsi_frame2sample(fsi, runtime->period_size); 522 io->period_samples = fsi_frame2sample(fsi, runtime->period_size);
496 io->period_pos = 0; 523 io->period_pos = 0;
497 io->sample_width = samples_to_bytes(runtime, 1); 524 io->sample_width = samples_to_bytes(runtime, 1);
525 io->bus_option = 0;
498 io->oerr_num = -1; /* ignore 1st err */ 526 io->oerr_num = -1; /* ignore 1st err */
499 io->uerr_num = -1; /* ignore 1st err */ 527 io->uerr_num = -1; /* ignore 1st err */
500 fsi_stream_handler_call(io, init, fsi, io); 528 fsi_stream_handler_call(io, init, fsi, io);
@@ -522,6 +550,7 @@ static void fsi_stream_quit(struct fsi_priv *fsi, struct fsi_stream *io)
522 io->period_samples = 0; 550 io->period_samples = 0;
523 io->period_pos = 0; 551 io->period_pos = 0;
524 io->sample_width = 0; 552 io->sample_width = 0;
553 io->bus_option = 0;
525 io->oerr_num = 0; 554 io->oerr_num = 0;
526 io->uerr_num = 0; 555 io->uerr_num = 0;
527 spin_unlock_irqrestore(&master->lock, flags); 556 spin_unlock_irqrestore(&master->lock, flags);
@@ -581,6 +610,53 @@ static int fsi_stream_remove(struct fsi_priv *fsi)
581} 610}
582 611
583/* 612/*
613 * format/bus/dma setting
614 */
615static void fsi_format_bus_setup(struct fsi_priv *fsi, struct fsi_stream *io,
616 u32 bus, struct device *dev)
617{
618 struct fsi_master *master = fsi_get_master(fsi);
619 int is_play = fsi_stream_is_play(fsi, io);
620 u32 fmt = fsi->fmt;
621
622 if (fsi_version(master) >= 2) {
623 u32 dma = 0;
624
625 /*
626 * FSI2 needs DMA/Bus setting
627 */
628 switch (bus) {
629 case PACKAGE_24BITBUS_FRONT:
630 fmt |= CR_BWS_24;
631 dma |= VDMD_FRONT;
632 dev_dbg(dev, "24bit bus / package in front\n");
633 break;
634 case PACKAGE_16BITBUS_STREAM:
635 fmt |= CR_BWS_16;
636 dma |= VDMD_STREAM;
637 dev_dbg(dev, "16bit bus / stream mode\n");
638 break;
639 case PACKAGE_24BITBUS_BACK:
640 default:
641 fmt |= CR_BWS_24;
642 dma |= VDMD_BACK;
643 dev_dbg(dev, "24bit bus / package in back\n");
644 break;
645 }
646
647 if (is_play)
648 fsi_reg_write(fsi, OUT_DMAC, dma);
649 else
650 fsi_reg_write(fsi, IN_DMAC, dma);
651 }
652
653 if (is_play)
654 fsi_reg_write(fsi, DO_FMT, fmt);
655 else
656 fsi_reg_write(fsi, DI_FMT, fmt);
657}
658
659/*
584 * irq function 660 * irq function
585 */ 661 */
586 662
@@ -629,11 +705,6 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
629 struct fsi_master *master = fsi_get_master(fsi); 705 struct fsi_master *master = fsi_get_master(fsi);
630 u32 mask, val; 706 u32 mask, val;
631 707
632 if (master->core->ver < 2) {
633 pr_err("fsi: register access err (%s)\n", __func__);
634 return;
635 }
636
637 mask = BP | SE; 708 mask = BP | SE;
638 val = enable ? mask : 0; 709 val = enable ? mask : 0;
639 710
@@ -648,9 +719,7 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
648static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, 719static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
649 long rate, int enable) 720 long rate, int enable)
650{ 721{
651 struct fsi_master *master = fsi_get_master(fsi);
652 set_rate_func set_rate = fsi_get_info_set_rate(fsi); 722 set_rate_func set_rate = fsi_get_info_set_rate(fsi);
653 int fsi_ver = master->core->ver;
654 int ret; 723 int ret;
655 724
656 if (!set_rate) 725 if (!set_rate)
@@ -682,10 +751,7 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
682 data |= (0x3 << 12); 751 data |= (0x3 << 12);
683 break; 752 break;
684 case SH_FSI_ACKMD_32: 753 case SH_FSI_ACKMD_32:
685 if (fsi_ver < 2) 754 data |= (0x4 << 12);
686 dev_err(dev, "unsupported ACKMD\n");
687 else
688 data |= (0x4 << 12);
689 break; 755 break;
690 } 756 }
691 757
@@ -708,10 +774,7 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
708 data |= (0x4 << 8); 774 data |= (0x4 << 8);
709 break; 775 break;
710 case SH_FSI_BPFMD_16: 776 case SH_FSI_BPFMD_16:
711 if (fsi_ver < 2) 777 data |= (0x7 << 8);
712 dev_err(dev, "unsupported ACKMD\n");
713 else
714 data |= (0x7 << 8);
715 break; 778 break;
716 } 779 }
717 780
@@ -728,11 +791,26 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
728 */ 791 */
729static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples) 792static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples)
730{ 793{
731 u16 *buf = (u16 *)_buf; 794 u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE;
732 int i; 795 int i;
733 796
734 for (i = 0; i < samples; i++) 797 if (enable_stream) {
735 fsi_reg_write(fsi, DODT, ((u32)*(buf + i) << 8)); 798 /*
799 * stream mode
800 * see
801 * fsi_pio_push_init()
802 */
803 u32 *buf = (u32 *)_buf;
804
805 for (i = 0; i < samples / 2; i++)
806 fsi_reg_write(fsi, DODT, buf[i]);
807 } else {
808 /* normal mode */
809 u16 *buf = (u16 *)_buf;
810
811 for (i = 0; i < samples; i++)
812 fsi_reg_write(fsi, DODT, ((u32)*(buf + i) << 8));
813 }
736} 814}
737 815
738static void fsi_pio_pop16(struct fsi_priv *fsi, u8 *_buf, int samples) 816static void fsi_pio_pop16(struct fsi_priv *fsi, u8 *_buf, int samples)
@@ -872,12 +950,44 @@ static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
872 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); 950 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
873} 951}
874 952
953static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io)
954{
955 u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE;
956
957 /*
958 * we can use 16bit stream mode
959 * when "playback" and "16bit data"
960 * and platform allows "stream mode"
961 * see
962 * fsi_pio_push16()
963 */
964 if (enable_stream)
965 io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) |
966 BUSOP_SET(16, PACKAGE_16BITBUS_STREAM);
967 else
968 io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) |
969 BUSOP_SET(16, PACKAGE_24BITBUS_BACK);
970 return 0;
971}
972
973static int fsi_pio_pop_init(struct fsi_priv *fsi, struct fsi_stream *io)
974{
975 /*
976 * always 24bit bus, package back when "capture"
977 */
978 io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) |
979 BUSOP_SET(16, PACKAGE_24BITBUS_BACK);
980 return 0;
981}
982
875static struct fsi_stream_handler fsi_pio_push_handler = { 983static struct fsi_stream_handler fsi_pio_push_handler = {
984 .init = fsi_pio_push_init,
876 .transfer = fsi_pio_push, 985 .transfer = fsi_pio_push,
877 .start_stop = fsi_pio_start_stop, 986 .start_stop = fsi_pio_start_stop,
878}; 987};
879 988
880static struct fsi_stream_handler fsi_pio_pop_handler = { 989static struct fsi_stream_handler fsi_pio_pop_handler = {
990 .init = fsi_pio_pop_init,
881 .transfer = fsi_pio_pop, 991 .transfer = fsi_pio_pop,
882 .start_stop = fsi_pio_start_stop, 992 .start_stop = fsi_pio_start_stop,
883}; 993};
@@ -919,6 +1029,13 @@ static int fsi_dma_init(struct fsi_priv *fsi, struct fsi_stream *io)
919 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ? 1029 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
920 DMA_TO_DEVICE : DMA_FROM_DEVICE; 1030 DMA_TO_DEVICE : DMA_FROM_DEVICE;
921 1031
1032 /*
1033 * 24bit data : 24bit bus / package in back
1034 * 16bit data : 16bit bus / stream mode
1035 */
1036 io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) |
1037 BUSOP_SET(16, PACKAGE_16BITBUS_STREAM);
1038
922 io->dma = dma_map_single(dai->dev, runtime->dma_area, 1039 io->dma = dma_map_single(dai->dev, runtime->dma_area,
923 snd_pcm_lib_buffer_bytes(io->substream), dir); 1040 snd_pcm_lib_buffer_bytes(io->substream), dir);
924 return 0; 1041 return 0;
@@ -1055,25 +1172,9 @@ static int fsi_dma_transfer(struct fsi_priv *fsi, struct fsi_stream *io)
1055static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, 1172static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
1056 int start) 1173 int start)
1057{ 1174{
1058 u32 bws; 1175 u32 enable = start ? DMA_ON : 0;
1059 u32 dma;
1060 1176
1061 switch (io->sample_width * start) { 1177 fsi_reg_mask_set(fsi, OUT_DMAC, DMA_ON, enable);
1062 case 2:
1063 bws = CR_BWS_16;
1064 dma = VDMD_STREAM | DMA_ON;
1065 break;
1066 case 4:
1067 bws = CR_BWS_24;
1068 dma = VDMD_BACK | DMA_ON;
1069 break;
1070 default:
1071 bws = 0;
1072 dma = 0;
1073 }
1074
1075 fsi_reg_mask_set(fsi, DO_FMT, CR_BWS_MASK, bws);
1076 fsi_reg_write(fsi, OUT_DMAC, dma);
1077} 1178}
1078 1179
1079static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io) 1180static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io)
@@ -1176,8 +1277,6 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
1176 struct fsi_stream *io, 1277 struct fsi_stream *io,
1177 struct device *dev) 1278 struct device *dev)
1178{ 1279{
1179 struct fsi_master *master = fsi_get_master(fsi);
1180 int fsi_ver = master->core->ver;
1181 u32 flags = fsi_get_info_flags(fsi); 1280 u32 flags = fsi_get_info_flags(fsi);
1182 u32 data = 0; 1281 u32 data = 0;
1183 1282
@@ -1200,10 +1299,6 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
1200 1299
1201 fsi_reg_write(fsi, CKG2, data); 1300 fsi_reg_write(fsi, CKG2, data);
1202 1301
1203 /* set format */
1204 fsi_reg_write(fsi, DO_FMT, fsi->do_fmt);
1205 fsi_reg_write(fsi, DI_FMT, fsi->di_fmt);
1206
1207 /* spdif ? */ 1302 /* spdif ? */
1208 if (fsi_is_spdif(fsi)) { 1303 if (fsi_is_spdif(fsi)) {
1209 fsi_spdif_clk_ctrl(fsi, 1); 1304 fsi_spdif_clk_ctrl(fsi, 1);
@@ -1211,15 +1306,18 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
1211 } 1306 }
1212 1307
1213 /* 1308 /*
1214 * FIXME 1309 * get bus settings
1215 *
1216 * FSI driver assumed that data package is in-back.
1217 * FSI2 chip can select it.
1218 */ 1310 */
1219 if (fsi_ver >= 2) { 1311 data = 0;
1220 fsi_reg_write(fsi, OUT_DMAC, (1 << 4)); 1312 switch (io->sample_width) {
1221 fsi_reg_write(fsi, IN_DMAC, (1 << 4)); 1313 case 2:
1314 data = BUSOP_GET(16, io->bus_option);
1315 break;
1316 case 4:
1317 data = BUSOP_GET(24, io->bus_option);
1318 break;
1222 } 1319 }
1320 fsi_format_bus_setup(fsi, io, data, dev);
1223 1321
1224 /* irq clear */ 1322 /* irq clear */
1225 fsi_irq_disable(fsi, io); 1323 fsi_irq_disable(fsi, io);
@@ -1243,7 +1341,9 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
1243{ 1341{
1244 struct fsi_priv *fsi = fsi_get_priv(substream); 1342 struct fsi_priv *fsi = fsi_get_priv(substream);
1245 1343
1246 return fsi_hw_startup(fsi, fsi_stream_get(fsi, substream), dai->dev); 1344 fsi->rate = 0;
1345
1346 return 0;
1247} 1347}
1248 1348
1249static void fsi_dai_shutdown(struct snd_pcm_substream *substream, 1349static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
@@ -1251,7 +1351,6 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
1251{ 1351{
1252 struct fsi_priv *fsi = fsi_get_priv(substream); 1352 struct fsi_priv *fsi = fsi_get_priv(substream);
1253 1353
1254 fsi_hw_shutdown(fsi, dai->dev);
1255 fsi->rate = 0; 1354 fsi->rate = 0;
1256} 1355}
1257 1356
@@ -1265,11 +1364,13 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
1265 switch (cmd) { 1364 switch (cmd) {
1266 case SNDRV_PCM_TRIGGER_START: 1365 case SNDRV_PCM_TRIGGER_START:
1267 fsi_stream_init(fsi, io, substream); 1366 fsi_stream_init(fsi, io, substream);
1367 fsi_hw_startup(fsi, io, dai->dev);
1268 ret = fsi_stream_transfer(io); 1368 ret = fsi_stream_transfer(io);
1269 if (0 == ret) 1369 if (0 == ret)
1270 fsi_stream_start(fsi, io); 1370 fsi_stream_start(fsi, io);
1271 break; 1371 break;
1272 case SNDRV_PCM_TRIGGER_STOP: 1372 case SNDRV_PCM_TRIGGER_STOP:
1373 fsi_hw_shutdown(fsi, dai->dev);
1273 fsi_stream_stop(fsi, io); 1374 fsi_stream_stop(fsi, io);
1274 fsi_stream_quit(fsi, io); 1375 fsi_stream_quit(fsi, io);
1275 break; 1376 break;
@@ -1280,42 +1381,33 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
1280 1381
1281static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt) 1382static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt)
1282{ 1383{
1283 u32 data = 0;
1284
1285 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 1384 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1286 case SND_SOC_DAIFMT_I2S: 1385 case SND_SOC_DAIFMT_I2S:
1287 data = CR_I2S; 1386 fsi->fmt = CR_I2S;
1288 fsi->chan_num = 2; 1387 fsi->chan_num = 2;
1289 break; 1388 break;
1290 case SND_SOC_DAIFMT_LEFT_J: 1389 case SND_SOC_DAIFMT_LEFT_J:
1291 data = CR_PCM; 1390 fsi->fmt = CR_PCM;
1292 fsi->chan_num = 2; 1391 fsi->chan_num = 2;
1293 break; 1392 break;
1294 default: 1393 default:
1295 return -EINVAL; 1394 return -EINVAL;
1296 } 1395 }
1297 1396
1298 fsi->do_fmt = data;
1299 fsi->di_fmt = data;
1300
1301 return 0; 1397 return 0;
1302} 1398}
1303 1399
1304static int fsi_set_fmt_spdif(struct fsi_priv *fsi) 1400static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
1305{ 1401{
1306 struct fsi_master *master = fsi_get_master(fsi); 1402 struct fsi_master *master = fsi_get_master(fsi);
1307 u32 data = 0;
1308 1403
1309 if (master->core->ver < 2) 1404 if (fsi_version(master) < 2)
1310 return -EINVAL; 1405 return -EINVAL;
1311 1406
1312 data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM; 1407 fsi->fmt = CR_DTMD_SPDIF_PCM | CR_PCM;
1313 fsi->chan_num = 2; 1408 fsi->chan_num = 2;
1314 fsi->spdif = 1; 1409 fsi->spdif = 1;
1315 1410
1316 fsi->do_fmt = data;
1317 fsi->di_fmt = data;
1318
1319 return 0; 1411 return 0;
1320} 1412}
1321 1413
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index c88d9741b9e7..b37ee8077ed1 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -39,6 +39,7 @@
39#include <sound/pcm.h> 39#include <sound/pcm.h>
40#include <sound/pcm_params.h> 40#include <sound/pcm_params.h>
41#include <sound/soc.h> 41#include <sound/soc.h>
42#include <sound/soc-dpcm.h>
42#include <sound/initval.h> 43#include <sound/initval.h>
43 44
44#define CREATE_TRACE_POINTS 45#define CREATE_TRACE_POINTS
@@ -54,7 +55,6 @@ EXPORT_SYMBOL_GPL(snd_soc_debugfs_root);
54#endif 55#endif
55 56
56static DEFINE_MUTEX(client_mutex); 57static DEFINE_MUTEX(client_mutex);
57static LIST_HEAD(card_list);
58static LIST_HEAD(dai_list); 58static LIST_HEAD(dai_list);
59static LIST_HEAD(platform_list); 59static LIST_HEAD(platform_list);
60static LIST_HEAD(codec_list); 60static LIST_HEAD(codec_list);
@@ -465,6 +465,35 @@ static inline void soc_cleanup_card_debugfs(struct snd_soc_card *card)
465} 465}
466#endif 466#endif
467 467
468struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
469 const char *dai_link, int stream)
470{
471 int i;
472
473 for (i = 0; i < card->num_links; i++) {
474 if (card->rtd[i].dai_link->no_pcm &&
475 !strcmp(card->rtd[i].dai_link->name, dai_link))
476 return card->rtd[i].pcm->streams[stream].substream;
477 }
478 dev_dbg(card->dev, "failed to find dai link %s\n", dai_link);
479 return NULL;
480}
481EXPORT_SYMBOL_GPL(snd_soc_get_dai_substream);
482
483struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card,
484 const char *dai_link)
485{
486 int i;
487
488 for (i = 0; i < card->num_links; i++) {
489 if (!strcmp(card->rtd[i].dai_link->name, dai_link))
490 return &card->rtd[i];
491 }
492 dev_dbg(card->dev, "failed to find rtd %s\n", dai_link);
493 return NULL;
494}
495EXPORT_SYMBOL_GPL(snd_soc_get_pcm_runtime);
496
468#ifdef CONFIG_SND_SOC_AC97_BUS 497#ifdef CONFIG_SND_SOC_AC97_BUS
469/* unregister ac97 codec */ 498/* unregister ac97 codec */
470static int soc_ac97_dev_unregister(struct snd_soc_codec *codec) 499static int soc_ac97_dev_unregister(struct snd_soc_codec *codec)
@@ -567,19 +596,16 @@ int snd_soc_suspend(struct device *dev)
567 } 596 }
568 597
569 for (i = 0; i < card->num_rtd; i++) { 598 for (i = 0; i < card->num_rtd; i++) {
570 struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai;
571 599
572 if (card->rtd[i].dai_link->ignore_suspend) 600 if (card->rtd[i].dai_link->ignore_suspend)
573 continue; 601 continue;
574 602
575 snd_soc_dapm_stream_event(&card->rtd[i], 603 snd_soc_dapm_stream_event(&card->rtd[i],
576 SNDRV_PCM_STREAM_PLAYBACK, 604 SNDRV_PCM_STREAM_PLAYBACK,
577 codec_dai,
578 SND_SOC_DAPM_STREAM_SUSPEND); 605 SND_SOC_DAPM_STREAM_SUSPEND);
579 606
580 snd_soc_dapm_stream_event(&card->rtd[i], 607 snd_soc_dapm_stream_event(&card->rtd[i],
581 SNDRV_PCM_STREAM_CAPTURE, 608 SNDRV_PCM_STREAM_CAPTURE,
582 codec_dai,
583 SND_SOC_DAPM_STREAM_SUSPEND); 609 SND_SOC_DAPM_STREAM_SUSPEND);
584 } 610 }
585 611
@@ -683,17 +709,16 @@ static void soc_resume_deferred(struct work_struct *work)
683 } 709 }
684 710
685 for (i = 0; i < card->num_rtd; i++) { 711 for (i = 0; i < card->num_rtd; i++) {
686 struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai;
687 712
688 if (card->rtd[i].dai_link->ignore_suspend) 713 if (card->rtd[i].dai_link->ignore_suspend)
689 continue; 714 continue;
690 715
691 snd_soc_dapm_stream_event(&card->rtd[i], 716 snd_soc_dapm_stream_event(&card->rtd[i],
692 SNDRV_PCM_STREAM_PLAYBACK, codec_dai, 717 SNDRV_PCM_STREAM_PLAYBACK,
693 SND_SOC_DAPM_STREAM_RESUME); 718 SND_SOC_DAPM_STREAM_RESUME);
694 719
695 snd_soc_dapm_stream_event(&card->rtd[i], 720 snd_soc_dapm_stream_event(&card->rtd[i],
696 SNDRV_PCM_STREAM_CAPTURE, codec_dai, 721 SNDRV_PCM_STREAM_CAPTURE,
697 SND_SOC_DAPM_STREAM_RESUME); 722 SND_SOC_DAPM_STREAM_RESUME);
698 } 723 }
699 724
@@ -783,15 +808,9 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
783 struct snd_soc_dai *codec_dai, *cpu_dai; 808 struct snd_soc_dai *codec_dai, *cpu_dai;
784 const char *platform_name; 809 const char *platform_name;
785 810
786 if (rtd->complete)
787 return 1;
788 dev_dbg(card->dev, "binding %s at idx %d\n", dai_link->name, num); 811 dev_dbg(card->dev, "binding %s at idx %d\n", dai_link->name, num);
789 812
790 /* do we already have the CPU DAI for this link ? */ 813 /* Find CPU DAI from registered DAIs*/
791 if (rtd->cpu_dai) {
792 goto find_codec;
793 }
794 /* no, then find CPU DAI from registered DAIs*/
795 list_for_each_entry(cpu_dai, &dai_list, list) { 814 list_for_each_entry(cpu_dai, &dai_list, list) {
796 if (dai_link->cpu_dai_of_node) { 815 if (dai_link->cpu_dai_of_node) {
797 if (cpu_dai->dev->of_node != dai_link->cpu_dai_of_node) 816 if (cpu_dai->dev->of_node != dai_link->cpu_dai_of_node)
@@ -802,18 +821,15 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
802 } 821 }
803 822
804 rtd->cpu_dai = cpu_dai; 823 rtd->cpu_dai = cpu_dai;
805 goto find_codec;
806 } 824 }
807 dev_dbg(card->dev, "CPU DAI %s not registered\n",
808 dai_link->cpu_dai_name);
809 825
810find_codec: 826 if (!rtd->cpu_dai) {
811 /* do we already have the CODEC for this link ? */ 827 dev_dbg(card->dev, "CPU DAI %s not registered\n",
812 if (rtd->codec) { 828 dai_link->cpu_dai_name);
813 goto find_platform; 829 return -EPROBE_DEFER;
814 } 830 }
815 831
816 /* no, then find CODEC from registered CODECs*/ 832 /* Find CODEC from registered CODECs */
817 list_for_each_entry(codec, &codec_list, list) { 833 list_for_each_entry(codec, &codec_list, list) {
818 if (dai_link->codec_of_node) { 834 if (dai_link->codec_of_node) {
819 if (codec->dev->of_node != dai_link->codec_of_node) 835 if (codec->dev->of_node != dai_link->codec_of_node)
@@ -835,28 +851,28 @@ find_codec:
835 dai_link->codec_dai_name)) { 851 dai_link->codec_dai_name)) {
836 852
837 rtd->codec_dai = codec_dai; 853 rtd->codec_dai = codec_dai;
838 goto find_platform;
839 } 854 }
840 } 855 }
841 dev_dbg(card->dev, "CODEC DAI %s not registered\n",
842 dai_link->codec_dai_name);
843 856
844 goto find_platform; 857 if (!rtd->codec_dai) {
858 dev_dbg(card->dev, "CODEC DAI %s not registered\n",
859 dai_link->codec_dai_name);
860 return -EPROBE_DEFER;
861 }
845 } 862 }
846 dev_dbg(card->dev, "CODEC %s not registered\n",
847 dai_link->codec_name);
848 863
849find_platform: 864 if (!rtd->codec) {
850 /* do we need a platform? */ 865 dev_dbg(card->dev, "CODEC %s not registered\n",
851 if (rtd->platform) 866 dai_link->codec_name);
852 goto out; 867 return -EPROBE_DEFER;
868 }
853 869
854 /* if there's no platform we match on the empty platform */ 870 /* if there's no platform we match on the empty platform */
855 platform_name = dai_link->platform_name; 871 platform_name = dai_link->platform_name;
856 if (!platform_name && !dai_link->platform_of_node) 872 if (!platform_name && !dai_link->platform_of_node)
857 platform_name = "snd-soc-dummy"; 873 platform_name = "snd-soc-dummy";
858 874
859 /* no, then find one from the set of registered platforms */ 875 /* find one from the set of registered platforms */
860 list_for_each_entry(platform, &platform_list, list) { 876 list_for_each_entry(platform, &platform_list, list) {
861 if (dai_link->platform_of_node) { 877 if (dai_link->platform_of_node) {
862 if (platform->dev->of_node != 878 if (platform->dev->of_node !=
@@ -868,20 +884,16 @@ find_platform:
868 } 884 }
869 885
870 rtd->platform = platform; 886 rtd->platform = platform;
871 goto out;
872 } 887 }
873 888 if (!rtd->platform) {
874 dev_dbg(card->dev, "platform %s not registered\n", 889 dev_dbg(card->dev, "platform %s not registered\n",
875 dai_link->platform_name); 890 dai_link->platform_name);
876 return 0; 891 return -EPROBE_DEFER;
877
878out:
879 /* mark rtd as complete if we found all 4 of our client devices */
880 if (rtd->codec && rtd->codec_dai && rtd->platform && rtd->cpu_dai) {
881 rtd->complete = 1;
882 card->num_rtd++;
883 } 892 }
884 return 1; 893
894 card->num_rtd++;
895
896 return 0;
885} 897}
886 898
887static void soc_remove_codec(struct snd_soc_codec *codec) 899static void soc_remove_codec(struct snd_soc_codec *codec)
@@ -1068,6 +1080,7 @@ static int soc_probe_platform(struct snd_soc_card *card,
1068{ 1080{
1069 int ret = 0; 1081 int ret = 0;
1070 const struct snd_soc_platform_driver *driver = platform->driver; 1082 const struct snd_soc_platform_driver *driver = platform->driver;
1083 struct snd_soc_dai *dai;
1071 1084
1072 platform->card = card; 1085 platform->card = card;
1073 platform->dapm.card = card; 1086 platform->dapm.card = card;
@@ -1081,6 +1094,14 @@ static int soc_probe_platform(struct snd_soc_card *card,
1081 snd_soc_dapm_new_controls(&platform->dapm, 1094 snd_soc_dapm_new_controls(&platform->dapm,
1082 driver->dapm_widgets, driver->num_dapm_widgets); 1095 driver->dapm_widgets, driver->num_dapm_widgets);
1083 1096
1097 /* Create DAPM widgets for each DAI stream */
1098 list_for_each_entry(dai, &dai_list, list) {
1099 if (dai->dev != platform->dev)
1100 continue;
1101
1102 snd_soc_dapm_new_dai_widgets(&platform->dapm, dai);
1103 }
1104
1084 platform->dapm.idle_bias_off = 1; 1105 platform->dapm.idle_bias_off = 1;
1085 1106
1086 if (driver->probe) { 1107 if (driver->probe) {
@@ -1170,6 +1191,10 @@ static int soc_post_component_init(struct snd_soc_card *card,
1170 rtd->dev->init_name = name; 1191 rtd->dev->init_name = name;
1171 dev_set_drvdata(rtd->dev, rtd); 1192 dev_set_drvdata(rtd->dev, rtd);
1172 mutex_init(&rtd->pcm_mutex); 1193 mutex_init(&rtd->pcm_mutex);
1194 INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients);
1195 INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].be_clients);
1196 INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_PLAYBACK].fe_clients);
1197 INIT_LIST_HEAD(&rtd->dpcm[SNDRV_PCM_STREAM_CAPTURE].fe_clients);
1173 ret = device_add(rtd->dev); 1198 ret = device_add(rtd->dev);
1174 if (ret < 0) { 1199 if (ret < 0) {
1175 dev_err(card->dev, 1200 dev_err(card->dev,
@@ -1191,6 +1216,17 @@ static int soc_post_component_init(struct snd_soc_card *card,
1191 dev_err(codec->dev, 1216 dev_err(codec->dev,
1192 "asoc: failed to add codec sysfs files: %d\n", ret); 1217 "asoc: failed to add codec sysfs files: %d\n", ret);
1193 1218
1219#ifdef CONFIG_DEBUG_FS
1220 /* add DPCM sysfs entries */
1221 if (!dailess && !dai_link->dynamic)
1222 goto out;
1223
1224 ret = soc_dpcm_debugfs_add(rtd);
1225 if (ret < 0)
1226 dev_err(rtd->dev, "asoc: failed to add dpcm sysfs entries: %d\n", ret);
1227
1228out:
1229#endif
1194 return 0; 1230 return 0;
1195} 1231}
1196 1232
@@ -1200,14 +1236,15 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
1200 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 1236 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1201 struct snd_soc_codec *codec = rtd->codec; 1237 struct snd_soc_codec *codec = rtd->codec;
1202 struct snd_soc_platform *platform = rtd->platform; 1238 struct snd_soc_platform *platform = rtd->platform;
1203 struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai; 1239 struct snd_soc_dai *codec_dai = rtd->codec_dai;
1240 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1241 struct snd_soc_dapm_widget *play_w, *capture_w;
1204 int ret; 1242 int ret;
1205 1243
1206 dev_dbg(card->dev, "probe %s dai link %d late %d\n", 1244 dev_dbg(card->dev, "probe %s dai link %d late %d\n",
1207 card->name, num, order); 1245 card->name, num, order);
1208 1246
1209 /* config components */ 1247 /* config components */
1210 codec_dai->codec = codec;
1211 cpu_dai->platform = platform; 1248 cpu_dai->platform = platform;
1212 codec_dai->card = card; 1249 codec_dai->card = card;
1213 cpu_dai->card = card; 1250 cpu_dai->card = card;
@@ -1218,9 +1255,12 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
1218 /* probe the cpu_dai */ 1255 /* probe the cpu_dai */
1219 if (!cpu_dai->probed && 1256 if (!cpu_dai->probed &&
1220 cpu_dai->driver->probe_order == order) { 1257 cpu_dai->driver->probe_order == order) {
1258 cpu_dai->dapm.card = card;
1221 if (!try_module_get(cpu_dai->dev->driver->owner)) 1259 if (!try_module_get(cpu_dai->dev->driver->owner))
1222 return -ENODEV; 1260 return -ENODEV;
1223 1261
1262 snd_soc_dapm_new_dai_widgets(&cpu_dai->dapm, cpu_dai);
1263
1224 if (cpu_dai->driver->probe) { 1264 if (cpu_dai->driver->probe) {
1225 ret = cpu_dai->driver->probe(cpu_dai); 1265 ret = cpu_dai->driver->probe(cpu_dai);
1226 if (ret < 0) { 1266 if (ret < 0) {
@@ -1279,12 +1319,39 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
1279 if (ret < 0) 1319 if (ret < 0)
1280 pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret); 1320 pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret);
1281 1321
1282 /* create the pcm */ 1322 if (!dai_link->params) {
1283 ret = soc_new_pcm(rtd, num); 1323 /* create the pcm */
1284 if (ret < 0) { 1324 ret = soc_new_pcm(rtd, num);
1285 pr_err("asoc: can't create pcm %s :%d\n", 1325 if (ret < 0) {
1286 dai_link->stream_name, ret); 1326 pr_err("asoc: can't create pcm %s :%d\n",
1287 return ret; 1327 dai_link->stream_name, ret);
1328 return ret;
1329 }
1330 } else {
1331 /* link the DAI widgets */
1332 play_w = codec_dai->playback_widget;
1333 capture_w = cpu_dai->capture_widget;
1334 if (play_w && capture_w) {
1335 ret = snd_soc_dapm_new_pcm(card, dai_link->params,
1336 capture_w, play_w);
1337 if (ret != 0) {
1338 dev_err(card->dev, "Can't link %s to %s: %d\n",
1339 play_w->name, capture_w->name, ret);
1340 return ret;
1341 }
1342 }
1343
1344 play_w = cpu_dai->playback_widget;
1345 capture_w = codec_dai->capture_widget;
1346 if (play_w && capture_w) {
1347 ret = snd_soc_dapm_new_pcm(card, dai_link->params,
1348 capture_w, play_w);
1349 if (ret != 0) {
1350 dev_err(card->dev, "Can't link %s to %s: %d\n",
1351 play_w->name, capture_w->name, ret);
1352 return ret;
1353 }
1354 }
1288 } 1355 }
1289 1356
1290 /* add platform data for AC97 devices */ 1357 /* add platform data for AC97 devices */
@@ -1334,6 +1401,20 @@ static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec)
1334} 1401}
1335#endif 1402#endif
1336 1403
1404static int soc_check_aux_dev(struct snd_soc_card *card, int num)
1405{
1406 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1407 struct snd_soc_codec *codec;
1408
1409 /* find CODEC from registered CODECs*/
1410 list_for_each_entry(codec, &codec_list, list) {
1411 if (!strcmp(codec->name, aux_dev->codec_name))
1412 return 0;
1413 }
1414
1415 return -EPROBE_DEFER;
1416}
1417
1337static int soc_probe_aux_dev(struct snd_soc_card *card, int num) 1418static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
1338{ 1419{
1339 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; 1420 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
@@ -1354,7 +1435,7 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
1354 } 1435 }
1355 /* codec not found */ 1436 /* codec not found */
1356 dev_err(card->dev, "asoc: codec %s not found", aux_dev->codec_name); 1437 dev_err(card->dev, "asoc: codec %s not found", aux_dev->codec_name);
1357 goto out; 1438 return -EPROBE_DEFER;
1358 1439
1359found: 1440found:
1360 ret = soc_probe_codec(card, codec); 1441 ret = soc_probe_codec(card, codec);
@@ -1404,29 +1485,28 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
1404 return 0; 1485 return 0;
1405} 1486}
1406 1487
1407static void snd_soc_instantiate_card(struct snd_soc_card *card) 1488static int snd_soc_instantiate_card(struct snd_soc_card *card)
1408{ 1489{
1409 struct snd_soc_codec *codec; 1490 struct snd_soc_codec *codec;
1410 struct snd_soc_codec_conf *codec_conf; 1491 struct snd_soc_codec_conf *codec_conf;
1411 enum snd_soc_compress_type compress_type; 1492 enum snd_soc_compress_type compress_type;
1412 struct snd_soc_dai_link *dai_link; 1493 struct snd_soc_dai_link *dai_link;
1413 int ret, i, order; 1494 int ret, i, order, dai_fmt;
1414 1495
1415 mutex_lock(&card->mutex); 1496 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT);
1416
1417 if (card->instantiated) {
1418 mutex_unlock(&card->mutex);
1419 return;
1420 }
1421 1497
1422 /* bind DAIs */ 1498 /* bind DAIs */
1423 for (i = 0; i < card->num_links; i++) 1499 for (i = 0; i < card->num_links; i++) {
1424 soc_bind_dai_link(card, i); 1500 ret = soc_bind_dai_link(card, i);
1501 if (ret != 0)
1502 goto base_error;
1503 }
1425 1504
1426 /* bind completed ? */ 1505 /* check aux_devs too */
1427 if (card->num_rtd != card->num_links) { 1506 for (i = 0; i < card->num_aux_devs; i++) {
1428 mutex_unlock(&card->mutex); 1507 ret = soc_check_aux_dev(card, i);
1429 return; 1508 if (ret != 0)
1509 goto base_error;
1430 } 1510 }
1431 1511
1432 /* initialize the register cache for each available codec */ 1512 /* initialize the register cache for each available codec */
@@ -1446,10 +1526,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1446 } 1526 }
1447 } 1527 }
1448 ret = snd_soc_init_codec_cache(codec, compress_type); 1528 ret = snd_soc_init_codec_cache(codec, compress_type);
1449 if (ret < 0) { 1529 if (ret < 0)
1450 mutex_unlock(&card->mutex); 1530 goto base_error;
1451 return;
1452 }
1453 } 1531 }
1454 1532
1455 /* card bind complete so register a sound card */ 1533 /* card bind complete so register a sound card */
@@ -1458,8 +1536,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1458 if (ret < 0) { 1536 if (ret < 0) {
1459 pr_err("asoc: can't create sound card for card %s: %d\n", 1537 pr_err("asoc: can't create sound card for card %s: %d\n",
1460 card->name, ret); 1538 card->name, ret);
1461 mutex_unlock(&card->mutex); 1539 goto base_error;
1462 return;
1463 } 1540 }
1464 card->snd_card->dev = card->dev; 1541 card->snd_card->dev = card->dev;
1465 1542
@@ -1523,17 +1600,47 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1523 1600
1524 for (i = 0; i < card->num_links; i++) { 1601 for (i = 0; i < card->num_links; i++) {
1525 dai_link = &card->dai_link[i]; 1602 dai_link = &card->dai_link[i];
1603 dai_fmt = dai_link->dai_fmt;
1526 1604
1527 if (dai_link->dai_fmt) { 1605 if (dai_fmt) {
1528 ret = snd_soc_dai_set_fmt(card->rtd[i].codec_dai, 1606 ret = snd_soc_dai_set_fmt(card->rtd[i].codec_dai,
1529 dai_link->dai_fmt); 1607 dai_fmt);
1530 if (ret != 0 && ret != -ENOTSUPP) 1608 if (ret != 0 && ret != -ENOTSUPP)
1531 dev_warn(card->rtd[i].codec_dai->dev, 1609 dev_warn(card->rtd[i].codec_dai->dev,
1532 "Failed to set DAI format: %d\n", 1610 "Failed to set DAI format: %d\n",
1533 ret); 1611 ret);
1612 }
1534 1613
1614 /* If this is a regular CPU link there will be a platform */
1615 if (dai_fmt &&
1616 (dai_link->platform_name || dai_link->platform_of_node)) {
1535 ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai, 1617 ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai,
1536 dai_link->dai_fmt); 1618 dai_fmt);
1619 if (ret != 0 && ret != -ENOTSUPP)
1620 dev_warn(card->rtd[i].cpu_dai->dev,
1621 "Failed to set DAI format: %d\n",
1622 ret);
1623 } else if (dai_fmt) {
1624 /* Flip the polarity for the "CPU" end */
1625 dai_fmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
1626 switch (dai_link->dai_fmt &
1627 SND_SOC_DAIFMT_MASTER_MASK) {
1628 case SND_SOC_DAIFMT_CBM_CFM:
1629 dai_fmt |= SND_SOC_DAIFMT_CBS_CFS;
1630 break;
1631 case SND_SOC_DAIFMT_CBM_CFS:
1632 dai_fmt |= SND_SOC_DAIFMT_CBS_CFM;
1633 break;
1634 case SND_SOC_DAIFMT_CBS_CFM:
1635 dai_fmt |= SND_SOC_DAIFMT_CBM_CFS;
1636 break;
1637 case SND_SOC_DAIFMT_CBS_CFS:
1638 dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
1639 break;
1640 }
1641
1642 ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai,
1643 dai_fmt);
1537 if (ret != 0 && ret != -ENOTSUPP) 1644 if (ret != 0 && ret != -ENOTSUPP)
1538 dev_warn(card->rtd[i].cpu_dai->dev, 1645 dev_warn(card->rtd[i].cpu_dai->dev,
1539 "Failed to set DAI format: %d\n", 1646 "Failed to set DAI format: %d\n",
@@ -1599,7 +1706,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1599 card->instantiated = 1; 1706 card->instantiated = 1;
1600 snd_soc_dapm_sync(&card->dapm); 1707 snd_soc_dapm_sync(&card->dapm);
1601 mutex_unlock(&card->mutex); 1708 mutex_unlock(&card->mutex);
1602 return; 1709
1710 return 0;
1603 1711
1604probe_aux_dev_err: 1712probe_aux_dev_err:
1605 for (i = 0; i < card->num_aux_devs; i++) 1713 for (i = 0; i < card->num_aux_devs; i++)
@@ -1614,18 +1722,10 @@ card_probe_error:
1614 1722
1615 snd_card_free(card->snd_card); 1723 snd_card_free(card->snd_card);
1616 1724
1725base_error:
1617 mutex_unlock(&card->mutex); 1726 mutex_unlock(&card->mutex);
1618}
1619 1727
1620/* 1728 return ret;
1621 * Attempt to initialise any uninitialised cards. Must be called with
1622 * client_mutex.
1623 */
1624static void snd_soc_instantiate_cards(void)
1625{
1626 struct snd_soc_card *card;
1627 list_for_each_entry(card, &card_list, list)
1628 snd_soc_instantiate_card(card);
1629} 1729}
1630 1730
1631/* probes a new socdev */ 1731/* probes a new socdev */
@@ -2527,6 +2627,87 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
2527EXPORT_SYMBOL_GPL(snd_soc_put_volsw); 2627EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
2528 2628
2529/** 2629/**
2630 * snd_soc_get_volsw_sx - single mixer get callback
2631 * @kcontrol: mixer control
2632 * @ucontrol: control element information
2633 *
2634 * Callback to get the value of a single mixer control, or a double mixer
2635 * control that spans 2 registers.
2636 *
2637 * Returns 0 for success.
2638 */
2639int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol,
2640 struct snd_ctl_elem_value *ucontrol)
2641{
2642 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2643 struct soc_mixer_control *mc =
2644 (struct soc_mixer_control *)kcontrol->private_value;
2645
2646 unsigned int reg = mc->reg;
2647 unsigned int reg2 = mc->rreg;
2648 unsigned int shift = mc->shift;
2649 unsigned int rshift = mc->rshift;
2650 int max = mc->max;
2651 int min = mc->min;
2652 int mask = (1 << (fls(min + max) - 1)) - 1;
2653
2654 ucontrol->value.integer.value[0] =
2655 ((snd_soc_read(codec, reg) >> shift) - min) & mask;
2656
2657 if (snd_soc_volsw_is_stereo(mc))
2658 ucontrol->value.integer.value[1] =
2659 ((snd_soc_read(codec, reg2) >> rshift) - min) & mask;
2660
2661 return 0;
2662}
2663EXPORT_SYMBOL_GPL(snd_soc_get_volsw_sx);
2664
2665/**
2666 * snd_soc_put_volsw_sx - double mixer set callback
2667 * @kcontrol: mixer control
2668 * @uinfo: control element information
2669 *
2670 * Callback to set the value of a double mixer control that spans 2 registers.
2671 *
2672 * Returns 0 for success.
2673 */
2674int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
2675 struct snd_ctl_elem_value *ucontrol)
2676{
2677 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2678 struct soc_mixer_control *mc =
2679 (struct soc_mixer_control *)kcontrol->private_value;
2680
2681 unsigned int reg = mc->reg;
2682 unsigned int reg2 = mc->rreg;
2683 unsigned int shift = mc->shift;
2684 unsigned int rshift = mc->rshift;
2685 int max = mc->max;
2686 int min = mc->min;
2687 int mask = (1 << (fls(min + max) - 1)) - 1;
2688 int err = 0;
2689 unsigned short val, val_mask, val2 = 0;
2690
2691 val_mask = mask << shift;
2692 val = (ucontrol->value.integer.value[0] + min) & mask;
2693 val = val << shift;
2694
2695 if (snd_soc_update_bits_locked(codec, reg, val_mask, val))
2696 return err;
2697
2698 if (snd_soc_volsw_is_stereo(mc)) {
2699 val_mask = mask << rshift;
2700 val2 = (ucontrol->value.integer.value[1] + min) & mask;
2701 val2 = val2 << rshift;
2702
2703 if (snd_soc_update_bits_locked(codec, reg2, val_mask, val2))
2704 return err;
2705 }
2706 return 0;
2707}
2708EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx);
2709
2710/**
2530 * snd_soc_info_volsw_s8 - signed mixer info callback 2711 * snd_soc_info_volsw_s8 - signed mixer info callback
2531 * @kcontrol: mixer control 2712 * @kcontrol: mixer control
2532 * @uinfo: control element information 2713 * @uinfo: control element information
@@ -2647,99 +2828,6 @@ int snd_soc_limit_volume(struct snd_soc_codec *codec,
2647} 2828}
2648EXPORT_SYMBOL_GPL(snd_soc_limit_volume); 2829EXPORT_SYMBOL_GPL(snd_soc_limit_volume);
2649 2830
2650/**
2651 * snd_soc_info_volsw_2r_sx - double with tlv and variable data size
2652 * mixer info callback
2653 * @kcontrol: mixer control
2654 * @uinfo: control element information
2655 *
2656 * Returns 0 for success.
2657 */
2658int snd_soc_info_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2659 struct snd_ctl_elem_info *uinfo)
2660{
2661 struct soc_mixer_control *mc =
2662 (struct soc_mixer_control *)kcontrol->private_value;
2663 int max = mc->max;
2664 int min = mc->min;
2665
2666 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2667 uinfo->count = 2;
2668 uinfo->value.integer.min = 0;
2669 uinfo->value.integer.max = max-min;
2670
2671 return 0;
2672}
2673EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r_sx);
2674
2675/**
2676 * snd_soc_get_volsw_2r_sx - double with tlv and variable data size
2677 * mixer get callback
2678 * @kcontrol: mixer control
2679 * @uinfo: control element information
2680 *
2681 * Returns 0 for success.
2682 */
2683int snd_soc_get_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2684 struct snd_ctl_elem_value *ucontrol)
2685{
2686 struct soc_mixer_control *mc =
2687 (struct soc_mixer_control *)kcontrol->private_value;
2688 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2689 unsigned int mask = (1<<mc->shift)-1;
2690 int min = mc->min;
2691 int val = snd_soc_read(codec, mc->reg) & mask;
2692 int valr = snd_soc_read(codec, mc->rreg) & mask;
2693
2694 ucontrol->value.integer.value[0] = ((val & 0xff)-min) & mask;
2695 ucontrol->value.integer.value[1] = ((valr & 0xff)-min) & mask;
2696 return 0;
2697}
2698EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r_sx);
2699
2700/**
2701 * snd_soc_put_volsw_2r_sx - double with tlv and variable data size
2702 * mixer put callback
2703 * @kcontrol: mixer control
2704 * @uinfo: control element information
2705 *
2706 * Returns 0 for success.
2707 */
2708int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
2709 struct snd_ctl_elem_value *ucontrol)
2710{
2711 struct soc_mixer_control *mc =
2712 (struct soc_mixer_control *)kcontrol->private_value;
2713 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2714 unsigned int mask = (1<<mc->shift)-1;
2715 int min = mc->min;
2716 int ret;
2717 unsigned int val, valr, oval, ovalr;
2718
2719 val = ((ucontrol->value.integer.value[0]+min) & 0xff);
2720 val &= mask;
2721 valr = ((ucontrol->value.integer.value[1]+min) & 0xff);
2722 valr &= mask;
2723
2724 oval = snd_soc_read(codec, mc->reg) & mask;
2725 ovalr = snd_soc_read(codec, mc->rreg) & mask;
2726
2727 ret = 0;
2728 if (oval != val) {
2729 ret = snd_soc_write(codec, mc->reg, val);
2730 if (ret < 0)
2731 return ret;
2732 }
2733 if (ovalr != valr) {
2734 ret = snd_soc_write(codec, mc->rreg, valr);
2735 if (ret < 0)
2736 return ret;
2737 }
2738
2739 return 0;
2740}
2741EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx);
2742
2743int snd_soc_bytes_info(struct snd_kcontrol *kcontrol, 2831int snd_soc_bytes_info(struct snd_kcontrol *kcontrol,
2744 struct snd_ctl_elem_info *uinfo) 2832 struct snd_ctl_elem_info *uinfo)
2745{ 2833{
@@ -2850,6 +2938,186 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol,
2850EXPORT_SYMBOL_GPL(snd_soc_bytes_put); 2938EXPORT_SYMBOL_GPL(snd_soc_bytes_put);
2851 2939
2852/** 2940/**
2941 * snd_soc_info_xr_sx - signed multi register info callback
2942 * @kcontrol: mreg control
2943 * @uinfo: control element information
2944 *
2945 * Callback to provide information of a control that can
2946 * span multiple codec registers which together
2947 * forms a single signed value in a MSB/LSB manner.
2948 *
2949 * Returns 0 for success.
2950 */
2951int snd_soc_info_xr_sx(struct snd_kcontrol *kcontrol,
2952 struct snd_ctl_elem_info *uinfo)
2953{
2954 struct soc_mreg_control *mc =
2955 (struct soc_mreg_control *)kcontrol->private_value;
2956 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2957 uinfo->count = 1;
2958 uinfo->value.integer.min = mc->min;
2959 uinfo->value.integer.max = mc->max;
2960
2961 return 0;
2962}
2963EXPORT_SYMBOL_GPL(snd_soc_info_xr_sx);
2964
2965/**
2966 * snd_soc_get_xr_sx - signed multi register get callback
2967 * @kcontrol: mreg control
2968 * @ucontrol: control element information
2969 *
2970 * Callback to get the value of a control that can span
2971 * multiple codec registers which together forms a single
2972 * signed value in a MSB/LSB manner. The control supports
2973 * specifying total no of bits used to allow for bitfields
2974 * across the multiple codec registers.
2975 *
2976 * Returns 0 for success.
2977 */
2978int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol,
2979 struct snd_ctl_elem_value *ucontrol)
2980{
2981 struct soc_mreg_control *mc =
2982 (struct soc_mreg_control *)kcontrol->private_value;
2983 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2984 unsigned int regbase = mc->regbase;
2985 unsigned int regcount = mc->regcount;
2986 unsigned int regwshift = codec->driver->reg_word_size * BITS_PER_BYTE;
2987 unsigned int regwmask = (1<<regwshift)-1;
2988 unsigned int invert = mc->invert;
2989 unsigned long mask = (1UL<<mc->nbits)-1;
2990 long min = mc->min;
2991 long max = mc->max;
2992 long val = 0;
2993 unsigned long regval;
2994 unsigned int i;
2995
2996 for (i = 0; i < regcount; i++) {
2997 regval = snd_soc_read(codec, regbase+i) & regwmask;
2998 val |= regval << (regwshift*(regcount-i-1));
2999 }
3000 val &= mask;
3001 if (min < 0 && val > max)
3002 val |= ~mask;
3003 if (invert)
3004 val = max - val;
3005 ucontrol->value.integer.value[0] = val;
3006
3007 return 0;
3008}
3009EXPORT_SYMBOL_GPL(snd_soc_get_xr_sx);
3010
3011/**
3012 * snd_soc_put_xr_sx - signed multi register get callback
3013 * @kcontrol: mreg control
3014 * @ucontrol: control element information
3015 *
3016 * Callback to set the value of a control that can span
3017 * multiple codec registers which together forms a single
3018 * signed value in a MSB/LSB manner. The control supports
3019 * specifying total no of bits used to allow for bitfields
3020 * across the multiple codec registers.
3021 *
3022 * Returns 0 for success.
3023 */
3024int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol,
3025 struct snd_ctl_elem_value *ucontrol)
3026{
3027 struct soc_mreg_control *mc =
3028 (struct soc_mreg_control *)kcontrol->private_value;
3029 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
3030 unsigned int regbase = mc->regbase;
3031 unsigned int regcount = mc->regcount;
3032 unsigned int regwshift = codec->driver->reg_word_size * BITS_PER_BYTE;
3033 unsigned int regwmask = (1<<regwshift)-1;
3034 unsigned int invert = mc->invert;
3035 unsigned long mask = (1UL<<mc->nbits)-1;
3036 long max = mc->max;
3037 long val = ucontrol->value.integer.value[0];
3038 unsigned int i, regval, regmask;
3039 int err;
3040
3041 if (invert)
3042 val = max - val;
3043 val &= mask;
3044 for (i = 0; i < regcount; i++) {
3045 regval = (val >> (regwshift*(regcount-i-1))) & regwmask;
3046 regmask = (mask >> (regwshift*(regcount-i-1))) & regwmask;
3047 err = snd_soc_update_bits_locked(codec, regbase+i,
3048 regmask, regval);
3049 if (err < 0)
3050 return err;
3051 }
3052
3053 return 0;
3054}
3055EXPORT_SYMBOL_GPL(snd_soc_put_xr_sx);
3056
3057/**
3058 * snd_soc_get_strobe - strobe get callback
3059 * @kcontrol: mixer control
3060 * @ucontrol: control element information
3061 *
3062 * Callback get the value of a strobe mixer control.
3063 *
3064 * Returns 0 for success.
3065 */
3066int snd_soc_get_strobe(struct snd_kcontrol *kcontrol,
3067 struct snd_ctl_elem_value *ucontrol)
3068{
3069 struct soc_mixer_control *mc =
3070 (struct soc_mixer_control *)kcontrol->private_value;
3071 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
3072 unsigned int reg = mc->reg;
3073 unsigned int shift = mc->shift;
3074 unsigned int mask = 1 << shift;
3075 unsigned int invert = mc->invert != 0;
3076 unsigned int val = snd_soc_read(codec, reg) & mask;
3077
3078 if (shift != 0 && val != 0)
3079 val = val >> shift;
3080 ucontrol->value.enumerated.item[0] = val ^ invert;
3081
3082 return 0;
3083}
3084EXPORT_SYMBOL_GPL(snd_soc_get_strobe);
3085
3086/**
3087 * snd_soc_put_strobe - strobe put callback
3088 * @kcontrol: mixer control
3089 * @ucontrol: control element information
3090 *
3091 * Callback strobe a register bit to high then low (or the inverse)
3092 * in one pass of a single mixer enum control.
3093 *
3094 * Returns 1 for success.
3095 */
3096int snd_soc_put_strobe(struct snd_kcontrol *kcontrol,
3097 struct snd_ctl_elem_value *ucontrol)
3098{
3099 struct soc_mixer_control *mc =
3100 (struct soc_mixer_control *)kcontrol->private_value;
3101 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
3102 unsigned int reg = mc->reg;
3103 unsigned int shift = mc->shift;
3104 unsigned int mask = 1 << shift;
3105 unsigned int invert = mc->invert != 0;
3106 unsigned int strobe = ucontrol->value.enumerated.item[0] != 0;
3107 unsigned int val1 = (strobe ^ invert) ? mask : 0;
3108 unsigned int val2 = (strobe ^ invert) ? 0 : mask;
3109 int err;
3110
3111 err = snd_soc_update_bits_locked(codec, reg, mask, val1);
3112 if (err < 0)
3113 return err;
3114
3115 err = snd_soc_update_bits_locked(codec, reg, mask, val2);
3116 return err;
3117}
3118EXPORT_SYMBOL_GPL(snd_soc_put_strobe);
3119
3120/**
2853 * snd_soc_dai_set_sysclk - configure DAI system or master clock. 3121 * snd_soc_dai_set_sysclk - configure DAI system or master clock.
2854 * @dai: DAI 3122 * @dai: DAI
2855 * @clk_id: DAI specific clock ID 3123 * @clk_id: DAI specific clock ID
@@ -3048,7 +3316,7 @@ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute)
3048 if (dai->driver && dai->driver->ops->digital_mute) 3316 if (dai->driver && dai->driver->ops->digital_mute)
3049 return dai->driver->ops->digital_mute(dai, mute); 3317 return dai->driver->ops->digital_mute(dai, mute);
3050 else 3318 else
3051 return -EINVAL; 3319 return -ENOTSUPP;
3052} 3320}
3053EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute); 3321EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
3054 3322
@@ -3060,7 +3328,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
3060 */ 3328 */
3061int snd_soc_register_card(struct snd_soc_card *card) 3329int snd_soc_register_card(struct snd_soc_card *card)
3062{ 3330{
3063 int i; 3331 int i, ret;
3064 3332
3065 if (!card->name || !card->dev) 3333 if (!card->name || !card->dev)
3066 return -EINVAL; 3334 return -EINVAL;
@@ -3123,15 +3391,13 @@ int snd_soc_register_card(struct snd_soc_card *card)
3123 INIT_LIST_HEAD(&card->dapm_dirty); 3391 INIT_LIST_HEAD(&card->dapm_dirty);
3124 card->instantiated = 0; 3392 card->instantiated = 0;
3125 mutex_init(&card->mutex); 3393 mutex_init(&card->mutex);
3394 mutex_init(&card->dapm_mutex);
3126 3395
3127 mutex_lock(&client_mutex); 3396 ret = snd_soc_instantiate_card(card);
3128 list_add(&card->list, &card_list); 3397 if (ret != 0)
3129 snd_soc_instantiate_cards(); 3398 soc_cleanup_card_debugfs(card);
3130 mutex_unlock(&client_mutex);
3131
3132 dev_dbg(card->dev, "Registered card '%s'\n", card->name);
3133 3399
3134 return 0; 3400 return ret;
3135} 3401}
3136EXPORT_SYMBOL_GPL(snd_soc_register_card); 3402EXPORT_SYMBOL_GPL(snd_soc_register_card);
3137 3403
@@ -3145,9 +3411,6 @@ int snd_soc_unregister_card(struct snd_soc_card *card)
3145{ 3411{
3146 if (card->instantiated) 3412 if (card->instantiated)
3147 soc_cleanup_card_resources(card); 3413 soc_cleanup_card_resources(card);
3148 mutex_lock(&client_mutex);
3149 list_del(&card->list);
3150 mutex_unlock(&client_mutex);
3151 dev_dbg(card->dev, "Unregistered card '%s'\n", card->name); 3414 dev_dbg(card->dev, "Unregistered card '%s'\n", card->name);
3152 3415
3153 return 0; 3416 return 0;
@@ -3221,6 +3484,7 @@ static inline char *fmt_multiple_name(struct device *dev,
3221int snd_soc_register_dai(struct device *dev, 3484int snd_soc_register_dai(struct device *dev,
3222 struct snd_soc_dai_driver *dai_drv) 3485 struct snd_soc_dai_driver *dai_drv)
3223{ 3486{
3487 struct snd_soc_codec *codec;
3224 struct snd_soc_dai *dai; 3488 struct snd_soc_dai *dai;
3225 3489
3226 dev_dbg(dev, "dai register %s\n", dev_name(dev)); 3490 dev_dbg(dev, "dai register %s\n", dev_name(dev));
@@ -3238,12 +3502,23 @@ int snd_soc_register_dai(struct device *dev,
3238 3502
3239 dai->dev = dev; 3503 dai->dev = dev;
3240 dai->driver = dai_drv; 3504 dai->driver = dai_drv;
3505 dai->dapm.dev = dev;
3241 if (!dai->driver->ops) 3506 if (!dai->driver->ops)
3242 dai->driver->ops = &null_dai_ops; 3507 dai->driver->ops = &null_dai_ops;
3243 3508
3244 mutex_lock(&client_mutex); 3509 mutex_lock(&client_mutex);
3510
3511 list_for_each_entry(codec, &codec_list, list) {
3512 if (codec->dev == dev) {
3513 dev_dbg(dev, "Mapped DAI %s to CODEC %s\n",
3514 dai->name, codec->name);
3515 dai->codec = codec;
3516 break;
3517 }
3518 }
3519
3245 list_add(&dai->list, &dai_list); 3520 list_add(&dai->list, &dai_list);
3246 snd_soc_instantiate_cards(); 3521
3247 mutex_unlock(&client_mutex); 3522 mutex_unlock(&client_mutex);
3248 3523
3249 pr_debug("Registered DAI '%s'\n", dai->name); 3524 pr_debug("Registered DAI '%s'\n", dai->name);
@@ -3287,6 +3562,7 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_dai);
3287int snd_soc_register_dais(struct device *dev, 3562int snd_soc_register_dais(struct device *dev,
3288 struct snd_soc_dai_driver *dai_drv, size_t count) 3563 struct snd_soc_dai_driver *dai_drv, size_t count)
3289{ 3564{
3565 struct snd_soc_codec *codec;
3290 struct snd_soc_dai *dai; 3566 struct snd_soc_dai *dai;
3291 int i, ret = 0; 3567 int i, ret = 0;
3292 3568
@@ -3314,19 +3590,28 @@ int snd_soc_register_dais(struct device *dev,
3314 dai->id = dai->driver->id; 3590 dai->id = dai->driver->id;
3315 else 3591 else
3316 dai->id = i; 3592 dai->id = i;
3593 dai->dapm.dev = dev;
3317 if (!dai->driver->ops) 3594 if (!dai->driver->ops)
3318 dai->driver->ops = &null_dai_ops; 3595 dai->driver->ops = &null_dai_ops;
3319 3596
3320 mutex_lock(&client_mutex); 3597 mutex_lock(&client_mutex);
3598
3599 list_for_each_entry(codec, &codec_list, list) {
3600 if (codec->dev == dev) {
3601 dev_dbg(dev, "Mapped DAI %s to CODEC %s\n",
3602 dai->name, codec->name);
3603 dai->codec = codec;
3604 break;
3605 }
3606 }
3607
3321 list_add(&dai->list, &dai_list); 3608 list_add(&dai->list, &dai_list);
3609
3322 mutex_unlock(&client_mutex); 3610 mutex_unlock(&client_mutex);
3323 3611
3324 pr_debug("Registered DAI '%s'\n", dai->name); 3612 pr_debug("Registered DAI '%s'\n", dai->name);
3325 } 3613 }
3326 3614
3327 mutex_lock(&client_mutex);
3328 snd_soc_instantiate_cards();
3329 mutex_unlock(&client_mutex);
3330 return 0; 3615 return 0;
3331 3616
3332err: 3617err:
@@ -3384,7 +3669,6 @@ int snd_soc_register_platform(struct device *dev,
3384 3669
3385 mutex_lock(&client_mutex); 3670 mutex_lock(&client_mutex);
3386 list_add(&platform->list, &platform_list); 3671 list_add(&platform->list, &platform_list);
3387 snd_soc_instantiate_cards();
3388 mutex_unlock(&client_mutex); 3672 mutex_unlock(&client_mutex);
3389 3673
3390 pr_debug("Registered platform '%s'\n", platform->name); 3674 pr_debug("Registered platform '%s'\n", platform->name);
@@ -3534,18 +3818,18 @@ int snd_soc_register_codec(struct device *dev,
3534 fixup_codec_formats(&dai_drv[i].capture); 3818 fixup_codec_formats(&dai_drv[i].capture);
3535 } 3819 }
3536 3820
3821 mutex_lock(&client_mutex);
3822 list_add(&codec->list, &codec_list);
3823 mutex_unlock(&client_mutex);
3824
3537 /* register any DAIs */ 3825 /* register any DAIs */
3538 if (num_dai) { 3826 if (num_dai) {
3539 ret = snd_soc_register_dais(dev, dai_drv, num_dai); 3827 ret = snd_soc_register_dais(dev, dai_drv, num_dai);
3540 if (ret < 0) 3828 if (ret < 0)
3541 goto fail; 3829 dev_err(codec->dev, "Failed to regster DAIs: %d\n",
3830 ret);
3542 } 3831 }
3543 3832
3544 mutex_lock(&client_mutex);
3545 list_add(&codec->list, &codec_list);
3546 snd_soc_instantiate_cards();
3547 mutex_unlock(&client_mutex);
3548
3549 pr_debug("Registered codec '%s'\n", codec->name); 3833 pr_debug("Registered codec '%s'\n", codec->name);
3550 return 0; 3834 return 0;
3551 3835
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 1bb6d4a63cd8..90ee77d2409d 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -52,6 +52,7 @@ static int dapm_up_seq[] = {
52 [snd_soc_dapm_supply] = 1, 52 [snd_soc_dapm_supply] = 1,
53 [snd_soc_dapm_regulator_supply] = 1, 53 [snd_soc_dapm_regulator_supply] = 1,
54 [snd_soc_dapm_micbias] = 2, 54 [snd_soc_dapm_micbias] = 2,
55 [snd_soc_dapm_dai_link] = 2,
55 [snd_soc_dapm_dai] = 3, 56 [snd_soc_dapm_dai] = 3,
56 [snd_soc_dapm_aif_in] = 3, 57 [snd_soc_dapm_aif_in] = 3,
57 [snd_soc_dapm_aif_out] = 3, 58 [snd_soc_dapm_aif_out] = 3,
@@ -90,9 +91,10 @@ static int dapm_down_seq[] = {
90 [snd_soc_dapm_aif_in] = 10, 91 [snd_soc_dapm_aif_in] = 10,
91 [snd_soc_dapm_aif_out] = 10, 92 [snd_soc_dapm_aif_out] = 10,
92 [snd_soc_dapm_dai] = 10, 93 [snd_soc_dapm_dai] = 10,
93 [snd_soc_dapm_regulator_supply] = 11, 94 [snd_soc_dapm_dai_link] = 11,
94 [snd_soc_dapm_supply] = 11, 95 [snd_soc_dapm_regulator_supply] = 12,
95 [snd_soc_dapm_post] = 12, 96 [snd_soc_dapm_supply] = 12,
97 [snd_soc_dapm_post] = 13,
96}; 98};
97 99
98static void pop_wait(u32 pop_time) 100static void pop_wait(u32 pop_time)
@@ -208,7 +210,23 @@ static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val)
208 return -1; 210 return -1;
209} 211}
210 212
211static int soc_widget_update_bits(struct snd_soc_dapm_widget *w, 213static inline void soc_widget_lock(struct snd_soc_dapm_widget *w)
214{
215 if (w->codec && !w->codec->using_regmap)
216 mutex_lock(&w->codec->mutex);
217 else if (w->platform)
218 mutex_lock(&w->platform->mutex);
219}
220
221static inline void soc_widget_unlock(struct snd_soc_dapm_widget *w)
222{
223 if (w->codec && !w->codec->using_regmap)
224 mutex_unlock(&w->codec->mutex);
225 else if (w->platform)
226 mutex_unlock(&w->platform->mutex);
227}
228
229static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w,
212 unsigned short reg, unsigned int mask, unsigned int value) 230 unsigned short reg, unsigned int mask, unsigned int value)
213{ 231{
214 bool change; 232 bool change;
@@ -221,18 +239,24 @@ static int soc_widget_update_bits(struct snd_soc_dapm_widget *w,
221 if (ret != 0) 239 if (ret != 0)
222 return ret; 240 return ret;
223 } else { 241 } else {
242 soc_widget_lock(w);
224 ret = soc_widget_read(w, reg); 243 ret = soc_widget_read(w, reg);
225 if (ret < 0) 244 if (ret < 0) {
245 soc_widget_unlock(w);
226 return ret; 246 return ret;
247 }
227 248
228 old = ret; 249 old = ret;
229 new = (old & ~mask) | (value & mask); 250 new = (old & ~mask) | (value & mask);
230 change = old != new; 251 change = old != new;
231 if (change) { 252 if (change) {
232 ret = soc_widget_write(w, reg, new); 253 ret = soc_widget_write(w, reg, new);
233 if (ret < 0) 254 if (ret < 0) {
255 soc_widget_unlock(w);
234 return ret; 256 return ret;
257 }
235 } 258 }
259 soc_widget_unlock(w);
236 } 260 }
237 261
238 return change; 262 return change;
@@ -374,6 +398,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
374 case snd_soc_dapm_mic: 398 case snd_soc_dapm_mic:
375 case snd_soc_dapm_spk: 399 case snd_soc_dapm_spk:
376 case snd_soc_dapm_line: 400 case snd_soc_dapm_line:
401 case snd_soc_dapm_dai_link:
377 p->connect = 1; 402 p->connect = 1;
378 break; 403 break;
379 /* does affect routing - dynamically connected */ 404 /* does affect routing - dynamically connected */
@@ -682,11 +707,51 @@ static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget)
682 } 707 }
683} 708}
684 709
710/* add widget to list if it's not already in the list */
711static int dapm_list_add_widget(struct snd_soc_dapm_widget_list **list,
712 struct snd_soc_dapm_widget *w)
713{
714 struct snd_soc_dapm_widget_list *wlist;
715 int wlistsize, wlistentries, i;
716
717 if (*list == NULL)
718 return -EINVAL;
719
720 wlist = *list;
721
722 /* is this widget already in the list */
723 for (i = 0; i < wlist->num_widgets; i++) {
724 if (wlist->widgets[i] == w)
725 return 0;
726 }
727
728 /* allocate some new space */
729 wlistentries = wlist->num_widgets + 1;
730 wlistsize = sizeof(struct snd_soc_dapm_widget_list) +
731 wlistentries * sizeof(struct snd_soc_dapm_widget *);
732 *list = krealloc(wlist, wlistsize, GFP_KERNEL);
733 if (*list == NULL) {
734 dev_err(w->dapm->dev, "can't allocate widget list for %s\n",
735 w->name);
736 return -ENOMEM;
737 }
738 wlist = *list;
739
740 /* insert the widget */
741 dev_dbg(w->dapm->dev, "added %s in widget list pos %d\n",
742 w->name, wlist->num_widgets);
743
744 wlist->widgets[wlist->num_widgets] = w;
745 wlist->num_widgets++;
746 return 1;
747}
748
685/* 749/*
686 * Recursively check for a completed path to an active or physically connected 750 * Recursively check for a completed path to an active or physically connected
687 * output widget. Returns number of complete paths. 751 * output widget. Returns number of complete paths.
688 */ 752 */
689static int is_connected_output_ep(struct snd_soc_dapm_widget *widget) 753static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
754 struct snd_soc_dapm_widget_list **list)
690{ 755{
691 struct snd_soc_dapm_path *path; 756 struct snd_soc_dapm_path *path;
692 int con = 0; 757 int con = 0;
@@ -742,9 +807,23 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
742 if (path->walked) 807 if (path->walked)
743 continue; 808 continue;
744 809
810 trace_snd_soc_dapm_output_path(widget, path);
811
745 if (path->sink && path->connect) { 812 if (path->sink && path->connect) {
746 path->walked = 1; 813 path->walked = 1;
747 con += is_connected_output_ep(path->sink); 814
815 /* do we need to add this widget to the list ? */
816 if (list) {
817 int err;
818 err = dapm_list_add_widget(list, path->sink);
819 if (err < 0) {
820 dev_err(widget->dapm->dev, "could not add widget %s\n",
821 widget->name);
822 return con;
823 }
824 }
825
826 con += is_connected_output_ep(path->sink, list);
748 } 827 }
749 } 828 }
750 829
@@ -757,7 +836,8 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
757 * Recursively check for a completed path to an active or physically connected 836 * Recursively check for a completed path to an active or physically connected
758 * input widget. Returns number of complete paths. 837 * input widget. Returns number of complete paths.
759 */ 838 */
760static int is_connected_input_ep(struct snd_soc_dapm_widget *widget) 839static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
840 struct snd_soc_dapm_widget_list **list)
761{ 841{
762 struct snd_soc_dapm_path *path; 842 struct snd_soc_dapm_path *path;
763 int con = 0; 843 int con = 0;
@@ -825,9 +905,23 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
825 if (path->walked) 905 if (path->walked)
826 continue; 906 continue;
827 907
908 trace_snd_soc_dapm_input_path(widget, path);
909
828 if (path->source && path->connect) { 910 if (path->source && path->connect) {
829 path->walked = 1; 911 path->walked = 1;
830 con += is_connected_input_ep(path->source); 912
913 /* do we need to add this widget to the list ? */
914 if (list) {
915 int err;
916 err = dapm_list_add_widget(list, path->sink);
917 if (err < 0) {
918 dev_err(widget->dapm->dev, "could not add widget %s\n",
919 widget->name);
920 return con;
921 }
922 }
923
924 con += is_connected_input_ep(path->source, list);
831 } 925 }
832 } 926 }
833 927
@@ -836,6 +930,39 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
836 return con; 930 return con;
837} 931}
838 932
933/**
934 * snd_soc_dapm_get_connected_widgets - query audio path and it's widgets.
935 * @dai: the soc DAI.
936 * @stream: stream direction.
937 * @list: list of active widgets for this stream.
938 *
939 * Queries DAPM graph as to whether an valid audio stream path exists for
940 * the initial stream specified by name. This takes into account
941 * current mixer and mux kcontrol settings. Creates list of valid widgets.
942 *
943 * Returns the number of valid paths or negative error.
944 */
945int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
946 struct snd_soc_dapm_widget_list **list)
947{
948 struct snd_soc_card *card = dai->card;
949 int paths;
950
951 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
952 dapm_reset(card);
953
954 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
955 paths = is_connected_output_ep(dai->playback_widget, list);
956 else
957 paths = is_connected_input_ep(dai->playback_widget, list);
958
959 trace_snd_soc_dapm_connected(paths, stream);
960 dapm_clear_walk(&card->dapm);
961 mutex_unlock(&card->dapm_mutex);
962
963 return paths;
964}
965
839/* 966/*
840 * Handler for generic register modifier widget. 967 * Handler for generic register modifier widget.
841 */ 968 */
@@ -849,7 +976,7 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w,
849 else 976 else
850 val = w->off_val; 977 val = w->off_val;
851 978
852 soc_widget_update_bits(w, -(w->reg + 1), 979 soc_widget_update_bits_locked(w, -(w->reg + 1),
853 w->mask << w->shift, val << w->shift); 980 w->mask << w->shift, val << w->shift);
854 981
855 return 0; 982 return 0;
@@ -863,9 +990,9 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
863 struct snd_kcontrol *kcontrol, int event) 990 struct snd_kcontrol *kcontrol, int event)
864{ 991{
865 if (SND_SOC_DAPM_EVENT_ON(event)) 992 if (SND_SOC_DAPM_EVENT_ON(event))
866 return regulator_enable(w->priv); 993 return regulator_enable(w->regulator);
867 else 994 else
868 return regulator_disable_deferred(w->priv, w->shift); 995 return regulator_disable_deferred(w->regulator, w->shift);
869} 996}
870EXPORT_SYMBOL_GPL(dapm_regulator_event); 997EXPORT_SYMBOL_GPL(dapm_regulator_event);
871 998
@@ -892,9 +1019,9 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
892 1019
893 DAPM_UPDATE_STAT(w, power_checks); 1020 DAPM_UPDATE_STAT(w, power_checks);
894 1021
895 in = is_connected_input_ep(w); 1022 in = is_connected_input_ep(w, NULL);
896 dapm_clear_walk(w->dapm); 1023 dapm_clear_walk(w->dapm);
897 out = is_connected_output_ep(w); 1024 out = is_connected_output_ep(w, NULL);
898 dapm_clear_walk(w->dapm); 1025 dapm_clear_walk(w->dapm);
899 return out != 0 && in != 0; 1026 return out != 0 && in != 0;
900} 1027}
@@ -903,7 +1030,10 @@ static int dapm_dai_check_power(struct snd_soc_dapm_widget *w)
903{ 1030{
904 DAPM_UPDATE_STAT(w, power_checks); 1031 DAPM_UPDATE_STAT(w, power_checks);
905 1032
906 return w->active; 1033 if (w->active)
1034 return w->active;
1035
1036 return dapm_generic_check_power(w);
907} 1037}
908 1038
909/* Check to see if an ADC has power */ 1039/* Check to see if an ADC has power */
@@ -914,7 +1044,7 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
914 DAPM_UPDATE_STAT(w, power_checks); 1044 DAPM_UPDATE_STAT(w, power_checks);
915 1045
916 if (w->active) { 1046 if (w->active) {
917 in = is_connected_input_ep(w); 1047 in = is_connected_input_ep(w, NULL);
918 dapm_clear_walk(w->dapm); 1048 dapm_clear_walk(w->dapm);
919 return in != 0; 1049 return in != 0;
920 } else { 1050 } else {
@@ -930,7 +1060,7 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
930 DAPM_UPDATE_STAT(w, power_checks); 1060 DAPM_UPDATE_STAT(w, power_checks);
931 1061
932 if (w->active) { 1062 if (w->active) {
933 out = is_connected_output_ep(w); 1063 out = is_connected_output_ep(w, NULL);
934 dapm_clear_walk(w->dapm); 1064 dapm_clear_walk(w->dapm);
935 return out != 0; 1065 return out != 0;
936 } else { 1066 } else {
@@ -1107,7 +1237,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm,
1107 "pop test : Applying 0x%x/0x%x to %x in %dms\n", 1237 "pop test : Applying 0x%x/0x%x to %x in %dms\n",
1108 value, mask, reg, card->pop_time); 1238 value, mask, reg, card->pop_time);
1109 pop_wait(card->pop_time); 1239 pop_wait(card->pop_time);
1110 soc_widget_update_bits(w, reg, mask, value); 1240 soc_widget_update_bits_locked(w, reg, mask, value);
1111 } 1241 }
1112 1242
1113 list_for_each_entry(w, pending, power_list) { 1243 list_for_each_entry(w, pending, power_list) {
@@ -1237,7 +1367,7 @@ static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
1237 w->name, ret); 1367 w->name, ret);
1238 } 1368 }
1239 1369
1240 ret = snd_soc_update_bits(w->codec, update->reg, update->mask, 1370 ret = soc_widget_update_bits_locked(w, update->reg, update->mask,
1241 update->val); 1371 update->val);
1242 if (ret < 0) 1372 if (ret < 0)
1243 pr_err("%s DAPM update failed: %d\n", w->name, ret); 1373 pr_err("%s DAPM update failed: %d\n", w->name, ret);
@@ -1421,12 +1551,10 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1421 trace_snd_soc_dapm_start(card); 1551 trace_snd_soc_dapm_start(card);
1422 1552
1423 list_for_each_entry(d, &card->dapm_list, list) { 1553 list_for_each_entry(d, &card->dapm_list, list) {
1424 if (d->n_widgets || d->codec == NULL) { 1554 if (d->idle_bias_off)
1425 if (d->idle_bias_off) 1555 d->target_bias_level = SND_SOC_BIAS_OFF;
1426 d->target_bias_level = SND_SOC_BIAS_OFF; 1556 else
1427 else 1557 d->target_bias_level = SND_SOC_BIAS_STANDBY;
1428 d->target_bias_level = SND_SOC_BIAS_STANDBY;
1429 }
1430 } 1558 }
1431 1559
1432 dapm_reset(card); 1560 dapm_reset(card);
@@ -1471,32 +1599,6 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1471 1599
1472 } 1600 }
1473 1601
1474 /* If there are no DAPM widgets then try to figure out power from the
1475 * event type.
1476 */
1477 if (!dapm->n_widgets) {
1478 switch (event) {
1479 case SND_SOC_DAPM_STREAM_START:
1480 case SND_SOC_DAPM_STREAM_RESUME:
1481 dapm->target_bias_level = SND_SOC_BIAS_ON;
1482 break;
1483 case SND_SOC_DAPM_STREAM_STOP:
1484 if (dapm->codec && dapm->codec->active)
1485 dapm->target_bias_level = SND_SOC_BIAS_ON;
1486 else
1487 dapm->target_bias_level = SND_SOC_BIAS_STANDBY;
1488 break;
1489 case SND_SOC_DAPM_STREAM_SUSPEND:
1490 dapm->target_bias_level = SND_SOC_BIAS_STANDBY;
1491 break;
1492 case SND_SOC_DAPM_STREAM_NOP:
1493 dapm->target_bias_level = dapm->bias_level;
1494 break;
1495 default:
1496 break;
1497 }
1498 }
1499
1500 /* Force all contexts in the card to the same bias state if 1602 /* Force all contexts in the card to the same bias state if
1501 * they're not ground referenced. 1603 * they're not ground referenced.
1502 */ 1604 */
@@ -1560,9 +1662,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1560 if (!buf) 1662 if (!buf)
1561 return -ENOMEM; 1663 return -ENOMEM;
1562 1664
1563 in = is_connected_input_ep(w); 1665 in = is_connected_input_ep(w, NULL);
1564 dapm_clear_walk(w->dapm); 1666 dapm_clear_walk(w->dapm);
1565 out = is_connected_output_ep(w); 1667 out = is_connected_output_ep(w, NULL);
1566 dapm_clear_walk(w->dapm); 1668 dapm_clear_walk(w->dapm);
1567 1669
1568 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d", 1670 ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d",
@@ -1709,7 +1811,7 @@ static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm)
1709#endif 1811#endif
1710 1812
1711/* test and update the power status of a mux widget */ 1813/* test and update the power status of a mux widget */
1712int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 1814static int soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1713 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e) 1815 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e)
1714{ 1816{
1715 struct snd_soc_dapm_path *path; 1817 struct snd_soc_dapm_path *path;
@@ -1746,12 +1848,26 @@ int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1746 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP); 1848 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
1747 } 1849 }
1748 1850
1749 return 0; 1851 return found;
1852}
1853
1854int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1855 struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e)
1856{
1857 struct snd_soc_card *card = widget->dapm->card;
1858 int ret;
1859
1860 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
1861 ret = soc_dapm_mux_update_power(widget, kcontrol, mux, e);
1862 mutex_unlock(&card->dapm_mutex);
1863 if (ret > 0)
1864 soc_dpcm_runtime_update(widget);
1865 return ret;
1750} 1866}
1751EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power); 1867EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power);
1752 1868
1753/* test and update the power status of a mixer or switch widget */ 1869/* test and update the power status of a mixer or switch widget */
1754int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, 1870static int soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1755 struct snd_kcontrol *kcontrol, int connect) 1871 struct snd_kcontrol *kcontrol, int connect)
1756{ 1872{
1757 struct snd_soc_dapm_path *path; 1873 struct snd_soc_dapm_path *path;
@@ -1778,7 +1894,21 @@ int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1778 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP); 1894 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
1779 } 1895 }
1780 1896
1781 return 0; 1897 return found;
1898}
1899
1900int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1901 struct snd_kcontrol *kcontrol, int connect)
1902{
1903 struct snd_soc_card *card = widget->dapm->card;
1904 int ret;
1905
1906 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
1907 ret = soc_dapm_mixer_update_power(widget, kcontrol, connect);
1908 mutex_unlock(&card->dapm_mutex);
1909 if (ret > 0)
1910 soc_dpcm_runtime_update(widget);
1911 return ret;
1782} 1912}
1783EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power); 1913EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power);
1784 1914
@@ -1939,6 +2069,8 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
1939 */ 2069 */
1940int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) 2070int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
1941{ 2071{
2072 int ret;
2073
1942 /* 2074 /*
1943 * Suppress early reports (eg, jacks syncing their state) to avoid 2075 * Suppress early reports (eg, jacks syncing their state) to avoid
1944 * silly DAPM runs during card startup. 2076 * silly DAPM runs during card startup.
@@ -1946,7 +2078,10 @@ int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
1946 if (!dapm->card || !dapm->card->instantiated) 2078 if (!dapm->card || !dapm->card->instantiated)
1947 return 0; 2079 return 0;
1948 2080
1949 return dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); 2081 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2082 ret = dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
2083 mutex_unlock(&dapm->card->dapm_mutex);
2084 return ret;
1950} 2085}
1951EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 2086EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
1952 2087
@@ -2055,6 +2190,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
2055 case snd_soc_dapm_aif_in: 2190 case snd_soc_dapm_aif_in:
2056 case snd_soc_dapm_aif_out: 2191 case snd_soc_dapm_aif_out:
2057 case snd_soc_dapm_dai: 2192 case snd_soc_dapm_dai:
2193 case snd_soc_dapm_dai_link:
2058 list_add(&path->list, &dapm->card->paths); 2194 list_add(&path->list, &dapm->card->paths);
2059 list_add(&path->list_sink, &wsink->sources); 2195 list_add(&path->list_sink, &wsink->sources);
2060 list_add(&path->list_source, &wsource->sinks); 2196 list_add(&path->list_source, &wsource->sinks);
@@ -2110,19 +2246,21 @@ err:
2110int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, 2246int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
2111 const struct snd_soc_dapm_route *route, int num) 2247 const struct snd_soc_dapm_route *route, int num)
2112{ 2248{
2113 int i, ret; 2249 int i, ret = 0;
2114 2250
2251 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
2115 for (i = 0; i < num; i++) { 2252 for (i = 0; i < num; i++) {
2116 ret = snd_soc_dapm_add_route(dapm, route); 2253 ret = snd_soc_dapm_add_route(dapm, route);
2117 if (ret < 0) { 2254 if (ret < 0) {
2118 dev_err(dapm->dev, "Failed to add route %s->%s\n", 2255 dev_err(dapm->dev, "Failed to add route %s->%s\n",
2119 route->source, route->sink); 2256 route->source, route->sink);
2120 return ret; 2257 break;
2121 } 2258 }
2122 route++; 2259 route++;
2123 } 2260 }
2261 mutex_unlock(&dapm->card->dapm_mutex);
2124 2262
2125 return 0; 2263 return ret;
2126} 2264}
2127EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes); 2265EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes);
2128 2266
@@ -2193,12 +2331,14 @@ int snd_soc_dapm_weak_routes(struct snd_soc_dapm_context *dapm,
2193 int i, err; 2331 int i, err;
2194 int ret = 0; 2332 int ret = 0;
2195 2333
2334 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
2196 for (i = 0; i < num; i++) { 2335 for (i = 0; i < num; i++) {
2197 err = snd_soc_dapm_weak_route(dapm, route); 2336 err = snd_soc_dapm_weak_route(dapm, route);
2198 if (err) 2337 if (err)
2199 ret = err; 2338 ret = err;
2200 route++; 2339 route++;
2201 } 2340 }
2341 mutex_unlock(&dapm->card->dapm_mutex);
2202 2342
2203 return ret; 2343 return ret;
2204} 2344}
@@ -2217,6 +2357,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
2217 struct snd_soc_dapm_widget *w; 2357 struct snd_soc_dapm_widget *w;
2218 unsigned int val; 2358 unsigned int val;
2219 2359
2360 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
2361
2220 list_for_each_entry(w, &dapm->card->widgets, list) 2362 list_for_each_entry(w, &dapm->card->widgets, list)
2221 { 2363 {
2222 if (w->new) 2364 if (w->new)
@@ -2226,8 +2368,10 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
2226 w->kcontrols = kzalloc(w->num_kcontrols * 2368 w->kcontrols = kzalloc(w->num_kcontrols *
2227 sizeof(struct snd_kcontrol *), 2369 sizeof(struct snd_kcontrol *),
2228 GFP_KERNEL); 2370 GFP_KERNEL);
2229 if (!w->kcontrols) 2371 if (!w->kcontrols) {
2372 mutex_unlock(&dapm->card->dapm_mutex);
2230 return -ENOMEM; 2373 return -ENOMEM;
2374 }
2231 } 2375 }
2232 2376
2233 switch(w->id) { 2377 switch(w->id) {
@@ -2267,6 +2411,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
2267 } 2411 }
2268 2412
2269 dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); 2413 dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
2414 mutex_unlock(&dapm->card->dapm_mutex);
2270 return 0; 2415 return 0;
2271} 2416}
2272EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets); 2417EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
@@ -2326,6 +2471,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2326 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2471 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2327 struct snd_soc_dapm_widget *widget = wlist->widgets[0]; 2472 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2328 struct snd_soc_codec *codec = widget->codec; 2473 struct snd_soc_codec *codec = widget->codec;
2474 struct snd_soc_card *card = codec->card;
2329 struct soc_mixer_control *mc = 2475 struct soc_mixer_control *mc =
2330 (struct soc_mixer_control *)kcontrol->private_value; 2476 (struct soc_mixer_control *)kcontrol->private_value;
2331 unsigned int reg = mc->reg; 2477 unsigned int reg = mc->reg;
@@ -2352,7 +2498,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2352 /* old connection must be powered down */ 2498 /* old connection must be powered down */
2353 connect = invert ? 1 : 0; 2499 connect = invert ? 1 : 0;
2354 2500
2355 mutex_lock(&codec->mutex); 2501 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2356 2502
2357 change = snd_soc_test_bits(widget->codec, reg, mask, val); 2503 change = snd_soc_test_bits(widget->codec, reg, mask, val);
2358 if (change) { 2504 if (change) {
@@ -2368,13 +2514,13 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2368 update.val = val; 2514 update.val = val;
2369 widget->dapm->update = &update; 2515 widget->dapm->update = &update;
2370 2516
2371 snd_soc_dapm_mixer_update_power(widget, kcontrol, connect); 2517 soc_dapm_mixer_update_power(widget, kcontrol, connect);
2372 2518
2373 widget->dapm->update = NULL; 2519 widget->dapm->update = NULL;
2374 } 2520 }
2375 } 2521 }
2376 2522
2377 mutex_unlock(&codec->mutex); 2523 mutex_unlock(&card->dapm_mutex);
2378 return 0; 2524 return 0;
2379} 2525}
2380EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw); 2526EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
@@ -2423,6 +2569,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
2423 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2569 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2424 struct snd_soc_dapm_widget *widget = wlist->widgets[0]; 2570 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2425 struct snd_soc_codec *codec = widget->codec; 2571 struct snd_soc_codec *codec = widget->codec;
2572 struct snd_soc_card *card = codec->card;
2426 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2573 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2427 unsigned int val, mux, change; 2574 unsigned int val, mux, change;
2428 unsigned int mask, bitmask; 2575 unsigned int mask, bitmask;
@@ -2443,7 +2590,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
2443 mask |= (bitmask - 1) << e->shift_r; 2590 mask |= (bitmask - 1) << e->shift_r;
2444 } 2591 }
2445 2592
2446 mutex_lock(&codec->mutex); 2593 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2447 2594
2448 change = snd_soc_test_bits(widget->codec, e->reg, mask, val); 2595 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
2449 if (change) { 2596 if (change) {
@@ -2459,13 +2606,13 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
2459 update.val = val; 2606 update.val = val;
2460 widget->dapm->update = &update; 2607 widget->dapm->update = &update;
2461 2608
2462 snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e); 2609 soc_dapm_mux_update_power(widget, kcontrol, mux, e);
2463 2610
2464 widget->dapm->update = NULL; 2611 widget->dapm->update = NULL;
2465 } 2612 }
2466 } 2613 }
2467 2614
2468 mutex_unlock(&codec->mutex); 2615 mutex_unlock(&card->dapm_mutex);
2469 return change; 2616 return change;
2470} 2617}
2471EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); 2618EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
@@ -2502,6 +2649,7 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
2502 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2649 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2503 struct snd_soc_dapm_widget *widget = wlist->widgets[0]; 2650 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2504 struct snd_soc_codec *codec = widget->codec; 2651 struct snd_soc_codec *codec = widget->codec;
2652 struct snd_soc_card *card = codec->card;
2505 struct soc_enum *e = 2653 struct soc_enum *e =
2506 (struct soc_enum *)kcontrol->private_value; 2654 (struct soc_enum *)kcontrol->private_value;
2507 int change; 2655 int change;
@@ -2511,7 +2659,7 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
2511 if (ucontrol->value.enumerated.item[0] >= e->max) 2659 if (ucontrol->value.enumerated.item[0] >= e->max)
2512 return -EINVAL; 2660 return -EINVAL;
2513 2661
2514 mutex_lock(&codec->mutex); 2662 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2515 2663
2516 change = widget->value != ucontrol->value.enumerated.item[0]; 2664 change = widget->value != ucontrol->value.enumerated.item[0];
2517 if (change) { 2665 if (change) {
@@ -2520,11 +2668,11 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
2520 2668
2521 widget->value = ucontrol->value.enumerated.item[0]; 2669 widget->value = ucontrol->value.enumerated.item[0];
2522 2670
2523 snd_soc_dapm_mux_update_power(widget, kcontrol, widget->value, e); 2671 soc_dapm_mux_update_power(widget, kcontrol, widget->value, e);
2524 } 2672 }
2525 } 2673 }
2526 2674
2527 mutex_unlock(&codec->mutex); 2675 mutex_unlock(&card->dapm_mutex);
2528 return ret; 2676 return ret;
2529} 2677}
2530EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt); 2678EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
@@ -2589,6 +2737,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
2589 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2737 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
2590 struct snd_soc_dapm_widget *widget = wlist->widgets[0]; 2738 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2591 struct snd_soc_codec *codec = widget->codec; 2739 struct snd_soc_codec *codec = widget->codec;
2740 struct snd_soc_card *card = codec->card;
2592 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2741 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
2593 unsigned int val, mux, change; 2742 unsigned int val, mux, change;
2594 unsigned int mask; 2743 unsigned int mask;
@@ -2607,7 +2756,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
2607 mask |= e->mask << e->shift_r; 2756 mask |= e->mask << e->shift_r;
2608 } 2757 }
2609 2758
2610 mutex_lock(&codec->mutex); 2759 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2611 2760
2612 change = snd_soc_test_bits(widget->codec, e->reg, mask, val); 2761 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
2613 if (change) { 2762 if (change) {
@@ -2623,13 +2772,13 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
2623 update.val = val; 2772 update.val = val;
2624 widget->dapm->update = &update; 2773 widget->dapm->update = &update;
2625 2774
2626 snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e); 2775 soc_dapm_mux_update_power(widget, kcontrol, mux, e);
2627 2776
2628 widget->dapm->update = NULL; 2777 widget->dapm->update = NULL;
2629 } 2778 }
2630 } 2779 }
2631 2780
2632 mutex_unlock(&codec->mutex); 2781 mutex_unlock(&card->dapm_mutex);
2633 return change; 2782 return change;
2634} 2783}
2635EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double); 2784EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double);
@@ -2666,12 +2815,12 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
2666 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); 2815 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
2667 const char *pin = (const char *)kcontrol->private_value; 2816 const char *pin = (const char *)kcontrol->private_value;
2668 2817
2669 mutex_lock(&card->mutex); 2818 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2670 2819
2671 ucontrol->value.integer.value[0] = 2820 ucontrol->value.integer.value[0] =
2672 snd_soc_dapm_get_pin_status(&card->dapm, pin); 2821 snd_soc_dapm_get_pin_status(&card->dapm, pin);
2673 2822
2674 mutex_unlock(&card->mutex); 2823 mutex_unlock(&card->dapm_mutex);
2675 2824
2676 return 0; 2825 return 0;
2677} 2826}
@@ -2689,17 +2838,16 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
2689 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); 2838 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
2690 const char *pin = (const char *)kcontrol->private_value; 2839 const char *pin = (const char *)kcontrol->private_value;
2691 2840
2692 mutex_lock(&card->mutex); 2841 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2693 2842
2694 if (ucontrol->value.integer.value[0]) 2843 if (ucontrol->value.integer.value[0])
2695 snd_soc_dapm_enable_pin(&card->dapm, pin); 2844 snd_soc_dapm_enable_pin(&card->dapm, pin);
2696 else 2845 else
2697 snd_soc_dapm_disable_pin(&card->dapm, pin); 2846 snd_soc_dapm_disable_pin(&card->dapm, pin);
2698 2847
2699 snd_soc_dapm_sync(&card->dapm); 2848 mutex_unlock(&card->dapm_mutex);
2700
2701 mutex_unlock(&card->mutex);
2702 2849
2850 snd_soc_dapm_sync(&card->dapm);
2703 return 0; 2851 return 0;
2704} 2852}
2705EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); 2853EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch);
@@ -2717,9 +2865,9 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2717 2865
2718 switch (w->id) { 2866 switch (w->id) {
2719 case snd_soc_dapm_regulator_supply: 2867 case snd_soc_dapm_regulator_supply:
2720 w->priv = devm_regulator_get(dapm->dev, w->name); 2868 w->regulator = devm_regulator_get(dapm->dev, w->name);
2721 if (IS_ERR(w->priv)) { 2869 if (IS_ERR(w->regulator)) {
2722 ret = PTR_ERR(w->priv); 2870 ret = PTR_ERR(w->regulator);
2723 dev_err(dapm->dev, "Failed to request %s: %d\n", 2871 dev_err(dapm->dev, "Failed to request %s: %d\n",
2724 w->name, ret); 2872 w->name, ret);
2725 return NULL; 2873 return NULL;
@@ -2771,6 +2919,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2771 case snd_soc_dapm_hp: 2919 case snd_soc_dapm_hp:
2772 case snd_soc_dapm_mic: 2920 case snd_soc_dapm_mic:
2773 case snd_soc_dapm_line: 2921 case snd_soc_dapm_line:
2922 case snd_soc_dapm_dai_link:
2774 w->power_check = dapm_generic_check_power; 2923 w->power_check = dapm_generic_check_power;
2775 break; 2924 break;
2776 case snd_soc_dapm_supply: 2925 case snd_soc_dapm_supply:
@@ -2816,21 +2965,177 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
2816{ 2965{
2817 struct snd_soc_dapm_widget *w; 2966 struct snd_soc_dapm_widget *w;
2818 int i; 2967 int i;
2968 int ret = 0;
2819 2969
2970 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
2820 for (i = 0; i < num; i++) { 2971 for (i = 0; i < num; i++) {
2821 w = snd_soc_dapm_new_control(dapm, widget); 2972 w = snd_soc_dapm_new_control(dapm, widget);
2822 if (!w) { 2973 if (!w) {
2823 dev_err(dapm->dev, 2974 dev_err(dapm->dev,
2824 "ASoC: Failed to create DAPM control %s\n", 2975 "ASoC: Failed to create DAPM control %s\n",
2825 widget->name); 2976 widget->name);
2826 return -ENOMEM; 2977 ret = -ENOMEM;
2978 break;
2827 } 2979 }
2828 widget++; 2980 widget++;
2829 } 2981 }
2830 return 0; 2982 mutex_unlock(&dapm->card->dapm_mutex);
2983 return ret;
2831} 2984}
2832EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); 2985EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
2833 2986
2987static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
2988 struct snd_kcontrol *kcontrol, int event)
2989{
2990 struct snd_soc_dapm_path *source_p, *sink_p;
2991 struct snd_soc_dai *source, *sink;
2992 const struct snd_soc_pcm_stream *config = w->params;
2993 struct snd_pcm_substream substream;
2994 struct snd_pcm_hw_params *params = NULL;
2995 u64 fmt;
2996 int ret;
2997
2998 BUG_ON(!config);
2999 BUG_ON(list_empty(&w->sources) || list_empty(&w->sinks));
3000
3001 /* We only support a single source and sink, pick the first */
3002 source_p = list_first_entry(&w->sources, struct snd_soc_dapm_path,
3003 list_sink);
3004 sink_p = list_first_entry(&w->sinks, struct snd_soc_dapm_path,
3005 list_source);
3006
3007 BUG_ON(!source_p || !sink_p);
3008 BUG_ON(!sink_p->source || !source_p->sink);
3009 BUG_ON(!source_p->source || !sink_p->sink);
3010
3011 source = source_p->source->priv;
3012 sink = sink_p->sink->priv;
3013
3014 /* Be a little careful as we don't want to overflow the mask array */
3015 if (config->formats) {
3016 fmt = ffs(config->formats) - 1;
3017 } else {
3018 dev_warn(w->dapm->dev, "Invalid format %llx specified\n",
3019 config->formats);
3020 fmt = 0;
3021 }
3022
3023 /* Currently very limited parameter selection */
3024 params = kzalloc(sizeof(*params), GFP_KERNEL);
3025 if (!params) {
3026 ret = -ENOMEM;
3027 goto out;
3028 }
3029 snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), fmt);
3030
3031 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min =
3032 config->rate_min;
3033 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max =
3034 config->rate_max;
3035
3036 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min
3037 = config->channels_min;
3038 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max
3039 = config->channels_max;
3040
3041 memset(&substream, 0, sizeof(substream));
3042
3043 switch (event) {
3044 case SND_SOC_DAPM_PRE_PMU:
3045 if (source->driver->ops && source->driver->ops->hw_params) {
3046 substream.stream = SNDRV_PCM_STREAM_CAPTURE;
3047 ret = source->driver->ops->hw_params(&substream,
3048 params, source);
3049 if (ret != 0) {
3050 dev_err(source->dev,
3051 "hw_params() failed: %d\n", ret);
3052 goto out;
3053 }
3054 }
3055
3056 if (sink->driver->ops && sink->driver->ops->hw_params) {
3057 substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
3058 ret = sink->driver->ops->hw_params(&substream, params,
3059 sink);
3060 if (ret != 0) {
3061 dev_err(sink->dev,
3062 "hw_params() failed: %d\n", ret);
3063 goto out;
3064 }
3065 }
3066 break;
3067
3068 case SND_SOC_DAPM_POST_PMU:
3069 ret = snd_soc_dai_digital_mute(sink, 0);
3070 if (ret != 0 && ret != -ENOTSUPP)
3071 dev_warn(sink->dev, "Failed to unmute: %d\n", ret);
3072 ret = 0;
3073 break;
3074
3075 case SND_SOC_DAPM_PRE_PMD:
3076 ret = snd_soc_dai_digital_mute(sink, 1);
3077 if (ret != 0 && ret != -ENOTSUPP)
3078 dev_warn(sink->dev, "Failed to mute: %d\n", ret);
3079 ret = 0;
3080 break;
3081
3082 default:
3083 BUG();
3084 return -EINVAL;
3085 }
3086
3087out:
3088 kfree(params);
3089 return ret;
3090}
3091
3092int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
3093 const struct snd_soc_pcm_stream *params,
3094 struct snd_soc_dapm_widget *source,
3095 struct snd_soc_dapm_widget *sink)
3096{
3097 struct snd_soc_dapm_route routes[2];
3098 struct snd_soc_dapm_widget template;
3099 struct snd_soc_dapm_widget *w;
3100 size_t len;
3101 char *link_name;
3102
3103 len = strlen(source->name) + strlen(sink->name) + 2;
3104 link_name = devm_kzalloc(card->dev, len, GFP_KERNEL);
3105 if (!link_name)
3106 return -ENOMEM;
3107 snprintf(link_name, len, "%s-%s", source->name, sink->name);
3108
3109 memset(&template, 0, sizeof(template));
3110 template.reg = SND_SOC_NOPM;
3111 template.id = snd_soc_dapm_dai_link;
3112 template.name = link_name;
3113 template.event = snd_soc_dai_link_event;
3114 template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3115 SND_SOC_DAPM_PRE_PMD;
3116
3117 dev_dbg(card->dev, "adding %s widget\n", link_name);
3118
3119 w = snd_soc_dapm_new_control(&card->dapm, &template);
3120 if (!w) {
3121 dev_err(card->dev, "Failed to create %s widget\n",
3122 link_name);
3123 return -ENOMEM;
3124 }
3125
3126 w->params = params;
3127
3128 memset(&routes, 0, sizeof(routes));
3129
3130 routes[0].source = source->name;
3131 routes[0].sink = link_name;
3132 routes[1].source = link_name;
3133 routes[1].sink = sink->name;
3134
3135 return snd_soc_dapm_add_routes(&card->dapm, routes,
3136 ARRAY_SIZE(routes));
3137}
3138
2834int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, 3139int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
2835 struct snd_soc_dai *dai) 3140 struct snd_soc_dai *dai)
2836{ 3141{
@@ -2934,37 +3239,61 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card)
2934 return 0; 3239 return 0;
2935} 3240}
2936 3241
2937static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm, 3242static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
2938 int stream, struct snd_soc_dai *dai, 3243 int event)
2939 int event)
2940{ 3244{
2941 struct snd_soc_dapm_widget *w;
2942 3245
2943 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 3246 struct snd_soc_dapm_widget *w_cpu, *w_codec;
2944 w = dai->playback_widget; 3247 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
2945 else 3248 struct snd_soc_dai *codec_dai = rtd->codec_dai;
2946 w = dai->capture_widget;
2947 3249
2948 if (!w) 3250 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
2949 return; 3251 w_cpu = cpu_dai->playback_widget;
3252 w_codec = codec_dai->playback_widget;
3253 } else {
3254 w_cpu = cpu_dai->capture_widget;
3255 w_codec = codec_dai->capture_widget;
3256 }
2950 3257
2951 dapm_mark_dirty(w, "stream event"); 3258 if (w_cpu) {
2952 3259
2953 switch (event) { 3260 dapm_mark_dirty(w_cpu, "stream event");
2954 case SND_SOC_DAPM_STREAM_START: 3261
2955 w->active = 1; 3262 switch (event) {
2956 break; 3263 case SND_SOC_DAPM_STREAM_START:
2957 case SND_SOC_DAPM_STREAM_STOP: 3264 w_cpu->active = 1;
2958 w->active = 0; 3265 break;
2959 break; 3266 case SND_SOC_DAPM_STREAM_STOP:
2960 case SND_SOC_DAPM_STREAM_SUSPEND: 3267 w_cpu->active = 0;
2961 case SND_SOC_DAPM_STREAM_RESUME: 3268 break;
2962 case SND_SOC_DAPM_STREAM_PAUSE_PUSH: 3269 case SND_SOC_DAPM_STREAM_SUSPEND:
2963 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE: 3270 case SND_SOC_DAPM_STREAM_RESUME:
2964 break; 3271 case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
3272 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
3273 break;
3274 }
3275 }
3276
3277 if (w_codec) {
3278
3279 dapm_mark_dirty(w_codec, "stream event");
3280
3281 switch (event) {
3282 case SND_SOC_DAPM_STREAM_START:
3283 w_codec->active = 1;
3284 break;
3285 case SND_SOC_DAPM_STREAM_STOP:
3286 w_codec->active = 0;
3287 break;
3288 case SND_SOC_DAPM_STREAM_SUSPEND:
3289 case SND_SOC_DAPM_STREAM_RESUME:
3290 case SND_SOC_DAPM_STREAM_PAUSE_PUSH:
3291 case SND_SOC_DAPM_STREAM_PAUSE_RELEASE:
3292 break;
3293 }
2965 } 3294 }
2966 3295
2967 dapm_power_widgets(dapm, event); 3296 dapm_power_widgets(&rtd->card->dapm, event);
2968} 3297}
2969 3298
2970/** 3299/**
@@ -2978,15 +3307,14 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
2978 * 3307 *
2979 * Returns 0 for success else error. 3308 * Returns 0 for success else error.
2980 */ 3309 */
2981int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, 3310void snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream,
2982 struct snd_soc_dai *dai, int event) 3311 int event)
2983{ 3312{
2984 struct snd_soc_codec *codec = rtd->codec; 3313 struct snd_soc_card *card = rtd->card;
2985 3314
2986 mutex_lock(&codec->mutex); 3315 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2987 soc_dapm_stream_event(&codec->dapm, stream, dai, event); 3316 soc_dapm_stream_event(rtd, stream, event);
2988 mutex_unlock(&codec->mutex); 3317 mutex_unlock(&card->dapm_mutex);
2989 return 0;
2990} 3318}
2991 3319
2992/** 3320/**
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index ee4353f843ea..7f8b3b7428bb 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -36,6 +36,7 @@
36int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type, 36int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type,
37 struct snd_soc_jack *jack) 37 struct snd_soc_jack *jack)
38{ 38{
39 mutex_init(&jack->mutex);
39 jack->codec = codec; 40 jack->codec = codec;
40 INIT_LIST_HEAD(&jack->pins); 41 INIT_LIST_HEAD(&jack->pins);
41 INIT_LIST_HEAD(&jack->jack_zones); 42 INIT_LIST_HEAD(&jack->jack_zones);
@@ -75,7 +76,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
75 codec = jack->codec; 76 codec = jack->codec;
76 dapm = &codec->dapm; 77 dapm = &codec->dapm;
77 78
78 mutex_lock(&codec->mutex); 79 mutex_lock(&jack->mutex);
79 80
80 oldstatus = jack->status; 81 oldstatus = jack->status;
81 82
@@ -109,7 +110,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
109 snd_jack_report(jack->jack, jack->status); 110 snd_jack_report(jack->jack, jack->status);
110 111
111out: 112out:
112 mutex_unlock(&codec->mutex); 113 mutex_unlock(&jack->mutex);
113} 114}
114EXPORT_SYMBOL_GPL(snd_soc_jack_report); 115EXPORT_SYMBOL_GPL(snd_soc_jack_report);
115 116
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 0ad8dcacd2f3..bedd1717a373 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -22,12 +22,38 @@
22#include <linux/pm_runtime.h> 22#include <linux/pm_runtime.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/workqueue.h> 24#include <linux/workqueue.h>
25#include <linux/export.h>
26#include <linux/debugfs.h>
25#include <sound/core.h> 27#include <sound/core.h>
26#include <sound/pcm.h> 28#include <sound/pcm.h>
27#include <sound/pcm_params.h> 29#include <sound/pcm_params.h>
28#include <sound/soc.h> 30#include <sound/soc.h>
31#include <sound/soc-dpcm.h>
29#include <sound/initval.h> 32#include <sound/initval.h>
30 33
34#define DPCM_MAX_BE_USERS 8
35
36/* DPCM stream event, send event to FE and all active BEs. */
37static int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
38 int event)
39{
40 struct snd_soc_dpcm *dpcm;
41
42 list_for_each_entry(dpcm, &fe->dpcm[dir].be_clients, list_be) {
43
44 struct snd_soc_pcm_runtime *be = dpcm->be;
45
46 dev_dbg(be->dev, "pm: BE %s event %d dir %d\n",
47 be->dai_link->name, event, dir);
48
49 snd_soc_dapm_stream_event(be, dir, event);
50 }
51
52 snd_soc_dapm_stream_event(fe, dir, event);
53
54 return 0;
55}
56
31static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, 57static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
32 struct snd_soc_dai *soc_dai) 58 struct snd_soc_dai *soc_dai)
33{ 59{
@@ -156,6 +182,10 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
156 } 182 }
157 } 183 }
158 184
185 /* Dynamic PCM DAI links compat checks use dynamic capabilities */
186 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm)
187 goto dynamic;
188
159 /* Check that the codec and cpu DAIs are compatible */ 189 /* Check that the codec and cpu DAIs are compatible */
160 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 190 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
161 runtime->hw.rate_min = 191 runtime->hw.rate_min =
@@ -248,6 +278,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
248 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min, 278 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min,
249 runtime->hw.rate_max); 279 runtime->hw.rate_max);
250 280
281dynamic:
251 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 282 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
252 cpu_dai->playback_active++; 283 cpu_dai->playback_active++;
253 codec_dai->playback_active++; 284 codec_dai->playback_active++;
@@ -308,7 +339,7 @@ static void close_delayed_work(struct work_struct *work)
308 if (codec_dai->pop_wait == 1) { 339 if (codec_dai->pop_wait == 1) {
309 codec_dai->pop_wait = 0; 340 codec_dai->pop_wait = 0;
310 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, 341 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
311 codec_dai, SND_SOC_DAPM_STREAM_STOP); 342 SND_SOC_DAPM_STREAM_STOP);
312 } 343 }
313 344
314 mutex_unlock(&rtd->pcm_mutex); 345 mutex_unlock(&rtd->pcm_mutex);
@@ -373,7 +404,6 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
373 /* powered down playback stream now */ 404 /* powered down playback stream now */
374 snd_soc_dapm_stream_event(rtd, 405 snd_soc_dapm_stream_event(rtd,
375 SNDRV_PCM_STREAM_PLAYBACK, 406 SNDRV_PCM_STREAM_PLAYBACK,
376 codec_dai,
377 SND_SOC_DAPM_STREAM_STOP); 407 SND_SOC_DAPM_STREAM_STOP);
378 } else { 408 } else {
379 /* start delayed pop wq here for playback streams */ 409 /* start delayed pop wq here for playback streams */
@@ -384,7 +414,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
384 } else { 414 } else {
385 /* capture streams can be powered down now */ 415 /* capture streams can be powered down now */
386 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE, 416 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
387 codec_dai, SND_SOC_DAPM_STREAM_STOP); 417 SND_SOC_DAPM_STREAM_STOP);
388 } 418 }
389 419
390 mutex_unlock(&rtd->pcm_mutex); 420 mutex_unlock(&rtd->pcm_mutex);
@@ -453,8 +483,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
453 cancel_delayed_work(&rtd->delayed_work); 483 cancel_delayed_work(&rtd->delayed_work);
454 } 484 }
455 485
456 snd_soc_dapm_stream_event(rtd, substream->stream, codec_dai, 486 snd_soc_dapm_stream_event(rtd, substream->stream,
457 SND_SOC_DAPM_STREAM_START); 487 SND_SOC_DAPM_STREAM_START);
458 488
459 snd_soc_dai_digital_mute(codec_dai, 0); 489 snd_soc_dai_digital_mute(codec_dai, 0);
460 490
@@ -602,6 +632,34 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
602 return 0; 632 return 0;
603} 633}
604 634
635static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream,
636 int cmd)
637{
638 struct snd_soc_pcm_runtime *rtd = substream->private_data;
639 struct snd_soc_platform *platform = rtd->platform;
640 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
641 struct snd_soc_dai *codec_dai = rtd->codec_dai;
642 int ret;
643
644 if (codec_dai->driver->ops->bespoke_trigger) {
645 ret = codec_dai->driver->ops->bespoke_trigger(substream, cmd, codec_dai);
646 if (ret < 0)
647 return ret;
648 }
649
650 if (platform->driver->bespoke_trigger) {
651 ret = platform->driver->bespoke_trigger(substream, cmd);
652 if (ret < 0)
653 return ret;
654 }
655
656 if (cpu_dai->driver->ops->bespoke_trigger) {
657 ret = cpu_dai->driver->ops->bespoke_trigger(substream, cmd, cpu_dai);
658 if (ret < 0)
659 return ret;
660 }
661 return 0;
662}
605/* 663/*
606 * soc level wrapper for pointer callback 664 * soc level wrapper for pointer callback
607 * If cpu_dai, codec_dai, platform driver has the delay callback, than 665 * If cpu_dai, codec_dai, platform driver has the delay callback, than
@@ -634,6 +692,1308 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
634 return offset; 692 return offset;
635} 693}
636 694
695/* connect a FE and BE */
696static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
697 struct snd_soc_pcm_runtime *be, int stream)
698{
699 struct snd_soc_dpcm *dpcm;
700
701 /* only add new dpcms */
702 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
703 if (dpcm->be == be && dpcm->fe == fe)
704 return 0;
705 }
706
707 dpcm = kzalloc(sizeof(struct snd_soc_dpcm), GFP_KERNEL);
708 if (!dpcm)
709 return -ENOMEM;
710
711 dpcm->be = be;
712 dpcm->fe = fe;
713 be->dpcm[stream].runtime = fe->dpcm[stream].runtime;
714 dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW;
715 list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients);
716 list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients);
717
718 dev_dbg(fe->dev, " connected new DPCM %s path %s %s %s\n",
719 stream ? "capture" : "playback", fe->dai_link->name,
720 stream ? "<-" : "->", be->dai_link->name);
721
722#ifdef CONFIG_DEBUG_FS
723 dpcm->debugfs_state = debugfs_create_u32(be->dai_link->name, 0644,
724 fe->debugfs_dpcm_root, &dpcm->state);
725#endif
726 return 1;
727}
728
729/* reparent a BE onto another FE */
730static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe,
731 struct snd_soc_pcm_runtime *be, int stream)
732{
733 struct snd_soc_dpcm *dpcm;
734 struct snd_pcm_substream *fe_substream, *be_substream;
735
736 /* reparent if BE is connected to other FEs */
737 if (!be->dpcm[stream].users)
738 return;
739
740 be_substream = snd_soc_dpcm_get_substream(be, stream);
741
742 list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) {
743 if (dpcm->fe == fe)
744 continue;
745
746 dev_dbg(fe->dev, " reparent %s path %s %s %s\n",
747 stream ? "capture" : "playback",
748 dpcm->fe->dai_link->name,
749 stream ? "<-" : "->", dpcm->be->dai_link->name);
750
751 fe_substream = snd_soc_dpcm_get_substream(dpcm->fe, stream);
752 be_substream->runtime = fe_substream->runtime;
753 break;
754 }
755}
756
757/* disconnect a BE and FE */
758static void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
759{
760 struct snd_soc_dpcm *dpcm, *d;
761
762 list_for_each_entry_safe(dpcm, d, &fe->dpcm[stream].be_clients, list_be) {
763 dev_dbg(fe->dev, "BE %s disconnect check for %s\n",
764 stream ? "capture" : "playback",
765 dpcm->be->dai_link->name);
766
767 if (dpcm->state != SND_SOC_DPCM_LINK_STATE_FREE)
768 continue;
769
770 dev_dbg(fe->dev, " freed DSP %s path %s %s %s\n",
771 stream ? "capture" : "playback", fe->dai_link->name,
772 stream ? "<-" : "->", dpcm->be->dai_link->name);
773
774 /* BEs still alive need new FE */
775 dpcm_be_reparent(fe, dpcm->be, stream);
776
777#ifdef CONFIG_DEBUG_FS
778 debugfs_remove(dpcm->debugfs_state);
779#endif
780 list_del(&dpcm->list_be);
781 list_del(&dpcm->list_fe);
782 kfree(dpcm);
783 }
784}
785
786/* get BE for DAI widget and stream */
787static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
788 struct snd_soc_dapm_widget *widget, int stream)
789{
790 struct snd_soc_pcm_runtime *be;
791 int i;
792
793 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
794 for (i = 0; i < card->num_links; i++) {
795 be = &card->rtd[i];
796
797 if (be->cpu_dai->playback_widget == widget ||
798 be->codec_dai->playback_widget == widget)
799 return be;
800 }
801 } else {
802
803 for (i = 0; i < card->num_links; i++) {
804 be = &card->rtd[i];
805
806 if (be->cpu_dai->capture_widget == widget ||
807 be->codec_dai->capture_widget == widget)
808 return be;
809 }
810 }
811
812 dev_err(card->dev, "can't get %s BE for %s\n",
813 stream ? "capture" : "playback", widget->name);
814 return NULL;
815}
816
817static inline struct snd_soc_dapm_widget *
818 rtd_get_cpu_widget(struct snd_soc_pcm_runtime *rtd, int stream)
819{
820 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
821 return rtd->cpu_dai->playback_widget;
822 else
823 return rtd->cpu_dai->capture_widget;
824}
825
826static inline struct snd_soc_dapm_widget *
827 rtd_get_codec_widget(struct snd_soc_pcm_runtime *rtd, int stream)
828{
829 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
830 return rtd->codec_dai->playback_widget;
831 else
832 return rtd->codec_dai->capture_widget;
833}
834
835static int widget_in_list(struct snd_soc_dapm_widget_list *list,
836 struct snd_soc_dapm_widget *widget)
837{
838 int i;
839
840 for (i = 0; i < list->num_widgets; i++) {
841 if (widget == list->widgets[i])
842 return 1;
843 }
844
845 return 0;
846}
847
848static int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
849 int stream, struct snd_soc_dapm_widget_list **list_)
850{
851 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
852 struct snd_soc_dapm_widget_list *list;
853 int paths;
854
855 list = kzalloc(sizeof(struct snd_soc_dapm_widget_list) +
856 sizeof(struct snd_soc_dapm_widget *), GFP_KERNEL);
857 if (list == NULL)
858 return -ENOMEM;
859
860 /* get number of valid DAI paths and their widgets */
861 paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, &list);
862
863 dev_dbg(fe->dev, "found %d audio %s paths\n", paths,
864 stream ? "capture" : "playback");
865
866 *list_ = list;
867 return paths;
868}
869
870static inline void dpcm_path_put(struct snd_soc_dapm_widget_list **list)
871{
872 kfree(*list);
873}
874
875static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream,
876 struct snd_soc_dapm_widget_list **list_)
877{
878 struct snd_soc_dpcm *dpcm;
879 struct snd_soc_dapm_widget_list *list = *list_;
880 struct snd_soc_dapm_widget *widget;
881 int prune = 0;
882
883 /* Destroy any old FE <--> BE connections */
884 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
885
886 /* is there a valid CPU DAI widget for this BE */
887 widget = rtd_get_cpu_widget(dpcm->be, stream);
888
889 /* prune the BE if it's no longer in our active list */
890 if (widget && widget_in_list(list, widget))
891 continue;
892
893 /* is there a valid CODEC DAI widget for this BE */
894 widget = rtd_get_codec_widget(dpcm->be, stream);
895
896 /* prune the BE if it's no longer in our active list */
897 if (widget && widget_in_list(list, widget))
898 continue;
899
900 dev_dbg(fe->dev, "pruning %s BE %s for %s\n",
901 stream ? "capture" : "playback",
902 dpcm->be->dai_link->name, fe->dai_link->name);
903 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
904 dpcm->be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
905 prune++;
906 }
907
908 dev_dbg(fe->dev, "found %d old BE paths for pruning\n", prune);
909 return prune;
910}
911
912static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,
913 struct snd_soc_dapm_widget_list **list_)
914{
915 struct snd_soc_card *card = fe->card;
916 struct snd_soc_dapm_widget_list *list = *list_;
917 struct snd_soc_pcm_runtime *be;
918 int i, new = 0, err;
919
920 /* Create any new FE <--> BE connections */
921 for (i = 0; i < list->num_widgets; i++) {
922
923 if (list->widgets[i]->id != snd_soc_dapm_dai)
924 continue;
925
926 /* is there a valid BE rtd for this widget */
927 be = dpcm_get_be(card, list->widgets[i], stream);
928 if (!be) {
929 dev_err(fe->dev, "no BE found for %s\n",
930 list->widgets[i]->name);
931 continue;
932 }
933
934 /* make sure BE is a real BE */
935 if (!be->dai_link->no_pcm)
936 continue;
937
938 /* don't connect if FE is not running */
939 if (!fe->dpcm[stream].runtime)
940 continue;
941
942 /* newly connected FE and BE */
943 err = dpcm_be_connect(fe, be, stream);
944 if (err < 0) {
945 dev_err(fe->dev, "can't connect %s\n",
946 list->widgets[i]->name);
947 break;
948 } else if (err == 0) /* already connected */
949 continue;
950
951 /* new */
952 be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
953 new++;
954 }
955
956 dev_dbg(fe->dev, "found %d new BE paths\n", new);
957 return new;
958}
959
960/*
961 * Find the corresponding BE DAIs that source or sink audio to this
962 * FE substream.
963 */
964static int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
965 int stream, struct snd_soc_dapm_widget_list **list, int new)
966{
967 if (new)
968 return dpcm_add_paths(fe, stream, list);
969 else
970 return dpcm_prune_paths(fe, stream, list);
971}
972
973static void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream)
974{
975 struct snd_soc_dpcm *dpcm;
976
977 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
978 dpcm->be->dpcm[stream].runtime_update =
979 SND_SOC_DPCM_UPDATE_NO;
980}
981
982static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe,
983 int stream)
984{
985 struct snd_soc_dpcm *dpcm;
986
987 /* disable any enabled and non active backends */
988 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
989
990 struct snd_soc_pcm_runtime *be = dpcm->be;
991 struct snd_pcm_substream *be_substream =
992 snd_soc_dpcm_get_substream(be, stream);
993
994 if (be->dpcm[stream].users == 0)
995 dev_err(be->dev, "no users %s at close - state %d\n",
996 stream ? "capture" : "playback",
997 be->dpcm[stream].state);
998
999 if (--be->dpcm[stream].users != 0)
1000 continue;
1001
1002 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)
1003 continue;
1004
1005 soc_pcm_close(be_substream);
1006 be_substream->runtime = NULL;
1007 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1008 }
1009}
1010
1011static int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream)
1012{
1013 struct snd_soc_dpcm *dpcm;
1014 int err, count = 0;
1015
1016 /* only startup BE DAIs that are either sinks or sources to this FE DAI */
1017 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1018
1019 struct snd_soc_pcm_runtime *be = dpcm->be;
1020 struct snd_pcm_substream *be_substream =
1021 snd_soc_dpcm_get_substream(be, stream);
1022
1023 /* is this op for this BE ? */
1024 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1025 continue;
1026
1027 /* first time the dpcm is open ? */
1028 if (be->dpcm[stream].users == DPCM_MAX_BE_USERS)
1029 dev_err(be->dev, "too many users %s at open %d\n",
1030 stream ? "capture" : "playback",
1031 be->dpcm[stream].state);
1032
1033 if (be->dpcm[stream].users++ != 0)
1034 continue;
1035
1036 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_NEW) &&
1037 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE))
1038 continue;
1039
1040 dev_dbg(be->dev, "dpcm: open BE %s\n", be->dai_link->name);
1041
1042 be_substream->runtime = be->dpcm[stream].runtime;
1043 err = soc_pcm_open(be_substream);
1044 if (err < 0) {
1045 dev_err(be->dev, "BE open failed %d\n", err);
1046 be->dpcm[stream].users--;
1047 if (be->dpcm[stream].users < 0)
1048 dev_err(be->dev, "no users %s at unwind %d\n",
1049 stream ? "capture" : "playback",
1050 be->dpcm[stream].state);
1051
1052 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1053 goto unwind;
1054 }
1055
1056 be->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
1057 count++;
1058 }
1059
1060 return count;
1061
1062unwind:
1063 /* disable any enabled and non active backends */
1064 list_for_each_entry_continue_reverse(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1065 struct snd_soc_pcm_runtime *be = dpcm->be;
1066 struct snd_pcm_substream *be_substream =
1067 snd_soc_dpcm_get_substream(be, stream);
1068
1069 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1070 continue;
1071
1072 if (be->dpcm[stream].users == 0)
1073 dev_err(be->dev, "no users %s at close %d\n",
1074 stream ? "capture" : "playback",
1075 be->dpcm[stream].state);
1076
1077 if (--be->dpcm[stream].users != 0)
1078 continue;
1079
1080 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)
1081 continue;
1082
1083 soc_pcm_close(be_substream);
1084 be_substream->runtime = NULL;
1085 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1086 }
1087
1088 return err;
1089}
1090
1091static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream)
1092{
1093 struct snd_pcm_runtime *runtime = substream->runtime;
1094 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1095 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1096 struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver;
1097
1098 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1099 runtime->hw.rate_min = cpu_dai_drv->playback.rate_min;
1100 runtime->hw.rate_max = cpu_dai_drv->playback.rate_max;
1101 runtime->hw.channels_min = cpu_dai_drv->playback.channels_min;
1102 runtime->hw.channels_max = cpu_dai_drv->playback.channels_max;
1103 runtime->hw.formats &= cpu_dai_drv->playback.formats;
1104 runtime->hw.rates = cpu_dai_drv->playback.rates;
1105 } else {
1106 runtime->hw.rate_min = cpu_dai_drv->capture.rate_min;
1107 runtime->hw.rate_max = cpu_dai_drv->capture.rate_max;
1108 runtime->hw.channels_min = cpu_dai_drv->capture.channels_min;
1109 runtime->hw.channels_max = cpu_dai_drv->capture.channels_max;
1110 runtime->hw.formats &= cpu_dai_drv->capture.formats;
1111 runtime->hw.rates = cpu_dai_drv->capture.rates;
1112 }
1113}
1114
1115static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream)
1116{
1117 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
1118 struct snd_pcm_runtime *runtime = fe_substream->runtime;
1119 int stream = fe_substream->stream, ret = 0;
1120
1121 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1122
1123 ret = dpcm_be_dai_startup(fe, fe_substream->stream);
1124 if (ret < 0) {
1125 dev_err(fe->dev,"dpcm: failed to start some BEs %d\n", ret);
1126 goto be_err;
1127 }
1128
1129 dev_dbg(fe->dev, "dpcm: open FE %s\n", fe->dai_link->name);
1130
1131 /* start the DAI frontend */
1132 ret = soc_pcm_open(fe_substream);
1133 if (ret < 0) {
1134 dev_err(fe->dev,"dpcm: failed to start FE %d\n", ret);
1135 goto unwind;
1136 }
1137
1138 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
1139
1140 dpcm_set_fe_runtime(fe_substream);
1141 snd_pcm_limit_hw_rates(runtime);
1142
1143 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1144 return 0;
1145
1146unwind:
1147 dpcm_be_dai_startup_unwind(fe, fe_substream->stream);
1148be_err:
1149 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1150 return ret;
1151}
1152
1153static int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
1154{
1155 struct snd_soc_dpcm *dpcm;
1156
1157 /* only shutdown BEs that are either sinks or sources to this FE DAI */
1158 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1159
1160 struct snd_soc_pcm_runtime *be = dpcm->be;
1161 struct snd_pcm_substream *be_substream =
1162 snd_soc_dpcm_get_substream(be, stream);
1163
1164 /* is this op for this BE ? */
1165 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1166 continue;
1167
1168 if (be->dpcm[stream].users == 0)
1169 dev_err(be->dev, "no users %s at close - state %d\n",
1170 stream ? "capture" : "playback",
1171 be->dpcm[stream].state);
1172
1173 if (--be->dpcm[stream].users != 0)
1174 continue;
1175
1176 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
1177 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN))
1178 continue;
1179
1180 dev_dbg(be->dev, "dpcm: close BE %s\n",
1181 dpcm->fe->dai_link->name);
1182
1183 soc_pcm_close(be_substream);
1184 be_substream->runtime = NULL;
1185
1186 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1187 }
1188 return 0;
1189}
1190
1191static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream)
1192{
1193 struct snd_soc_pcm_runtime *fe = substream->private_data;
1194 int stream = substream->stream;
1195
1196 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1197
1198 /* shutdown the BEs */
1199 dpcm_be_dai_shutdown(fe, substream->stream);
1200
1201 dev_dbg(fe->dev, "dpcm: close FE %s\n", fe->dai_link->name);
1202
1203 /* now shutdown the frontend */
1204 soc_pcm_close(substream);
1205
1206 /* run the stream event for each BE */
1207 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
1208
1209 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1210 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1211 return 0;
1212}
1213
1214static int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream)
1215{
1216 struct snd_soc_dpcm *dpcm;
1217
1218 /* only hw_params backends that are either sinks or sources
1219 * to this frontend DAI */
1220 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1221
1222 struct snd_soc_pcm_runtime *be = dpcm->be;
1223 struct snd_pcm_substream *be_substream =
1224 snd_soc_dpcm_get_substream(be, stream);
1225
1226 /* is this op for this BE ? */
1227 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1228 continue;
1229
1230 /* only free hw when no longer used - check all FEs */
1231 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1232 continue;
1233
1234 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
1235 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
1236 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
1237 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
1238 continue;
1239
1240 dev_dbg(be->dev, "dpcm: hw_free BE %s\n",
1241 dpcm->fe->dai_link->name);
1242
1243 soc_pcm_hw_free(be_substream);
1244
1245 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
1246 }
1247
1248 return 0;
1249}
1250
1251static int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream)
1252{
1253 struct snd_soc_pcm_runtime *fe = substream->private_data;
1254 int err, stream = substream->stream;
1255
1256 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1257 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1258
1259 dev_dbg(fe->dev, "dpcm: hw_free FE %s\n", fe->dai_link->name);
1260
1261 /* call hw_free on the frontend */
1262 err = soc_pcm_hw_free(substream);
1263 if (err < 0)
1264 dev_err(fe->dev,"dpcm: hw_free FE %s failed\n",
1265 fe->dai_link->name);
1266
1267 /* only hw_params backends that are either sinks or sources
1268 * to this frontend DAI */
1269 err = dpcm_be_dai_hw_free(fe, stream);
1270
1271 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
1272 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1273
1274 mutex_unlock(&fe->card->mutex);
1275 return 0;
1276}
1277
1278static int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream)
1279{
1280 struct snd_soc_dpcm *dpcm;
1281 int ret;
1282
1283 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1284
1285 struct snd_soc_pcm_runtime *be = dpcm->be;
1286 struct snd_pcm_substream *be_substream =
1287 snd_soc_dpcm_get_substream(be, stream);
1288
1289 /* is this op for this BE ? */
1290 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1291 continue;
1292
1293 /* only allow hw_params() if no connected FEs are running */
1294 if (!snd_soc_dpcm_can_be_params(fe, be, stream))
1295 continue;
1296
1297 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) &&
1298 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
1299 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE))
1300 continue;
1301
1302 dev_dbg(be->dev, "dpcm: hw_params BE %s\n",
1303 dpcm->fe->dai_link->name);
1304
1305 /* copy params for each dpcm */
1306 memcpy(&dpcm->hw_params, &fe->dpcm[stream].hw_params,
1307 sizeof(struct snd_pcm_hw_params));
1308
1309 /* perform any hw_params fixups */
1310 if (be->dai_link->be_hw_params_fixup) {
1311 ret = be->dai_link->be_hw_params_fixup(be,
1312 &dpcm->hw_params);
1313 if (ret < 0) {
1314 dev_err(be->dev,
1315 "dpcm: hw_params BE fixup failed %d\n",
1316 ret);
1317 goto unwind;
1318 }
1319 }
1320
1321 ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params);
1322 if (ret < 0) {
1323 dev_err(dpcm->be->dev,
1324 "dpcm: hw_params BE failed %d\n", ret);
1325 goto unwind;
1326 }
1327
1328 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS;
1329 }
1330 return 0;
1331
1332unwind:
1333 /* disable any enabled and non active backends */
1334 list_for_each_entry_continue_reverse(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1335 struct snd_soc_pcm_runtime *be = dpcm->be;
1336 struct snd_pcm_substream *be_substream =
1337 snd_soc_dpcm_get_substream(be, stream);
1338
1339 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1340 continue;
1341
1342 /* only allow hw_free() if no connected FEs are running */
1343 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1344 continue;
1345
1346 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) &&
1347 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
1348 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
1349 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
1350 continue;
1351
1352 soc_pcm_hw_free(be_substream);
1353 }
1354
1355 return ret;
1356}
1357
1358static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream,
1359 struct snd_pcm_hw_params *params)
1360{
1361 struct snd_soc_pcm_runtime *fe = substream->private_data;
1362 int ret, stream = substream->stream;
1363
1364 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1365 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1366
1367 memcpy(&fe->dpcm[substream->stream].hw_params, params,
1368 sizeof(struct snd_pcm_hw_params));
1369 ret = dpcm_be_dai_hw_params(fe, substream->stream);
1370 if (ret < 0) {
1371 dev_err(fe->dev,"dpcm: hw_params BE failed %d\n", ret);
1372 goto out;
1373 }
1374
1375 dev_dbg(fe->dev, "dpcm: hw_params FE %s rate %d chan %x fmt %d\n",
1376 fe->dai_link->name, params_rate(params),
1377 params_channels(params), params_format(params));
1378
1379 /* call hw_params on the frontend */
1380 ret = soc_pcm_hw_params(substream, params);
1381 if (ret < 0) {
1382 dev_err(fe->dev,"dpcm: hw_params FE failed %d\n", ret);
1383 dpcm_be_dai_hw_free(fe, stream);
1384 } else
1385 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS;
1386
1387out:
1388 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1389 mutex_unlock(&fe->card->mutex);
1390 return ret;
1391}
1392
1393static int dpcm_do_trigger(struct snd_soc_dpcm *dpcm,
1394 struct snd_pcm_substream *substream, int cmd)
1395{
1396 int ret;
1397
1398 dev_dbg(dpcm->be->dev, "dpcm: trigger BE %s cmd %d\n",
1399 dpcm->fe->dai_link->name, cmd);
1400
1401 ret = soc_pcm_trigger(substream, cmd);
1402 if (ret < 0)
1403 dev_err(dpcm->be->dev,"dpcm: trigger BE failed %d\n", ret);
1404
1405 return ret;
1406}
1407
1408static int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream,
1409 int cmd)
1410{
1411 struct snd_soc_dpcm *dpcm;
1412 int ret = 0;
1413
1414 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1415
1416 struct snd_soc_pcm_runtime *be = dpcm->be;
1417 struct snd_pcm_substream *be_substream =
1418 snd_soc_dpcm_get_substream(be, stream);
1419
1420 /* is this op for this BE ? */
1421 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1422 continue;
1423
1424 switch (cmd) {
1425 case SNDRV_PCM_TRIGGER_START:
1426 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
1427 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
1428 continue;
1429
1430 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1431 if (ret)
1432 return ret;
1433
1434 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
1435 break;
1436 case SNDRV_PCM_TRIGGER_RESUME:
1437 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND))
1438 continue;
1439
1440 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1441 if (ret)
1442 return ret;
1443
1444 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
1445 break;
1446 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1447 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED))
1448 continue;
1449
1450 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1451 if (ret)
1452 return ret;
1453
1454 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
1455 break;
1456 case SNDRV_PCM_TRIGGER_STOP:
1457 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
1458 continue;
1459
1460 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1461 continue;
1462
1463 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1464 if (ret)
1465 return ret;
1466
1467 be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
1468 break;
1469 case SNDRV_PCM_TRIGGER_SUSPEND:
1470 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)
1471 continue;
1472
1473 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1474 continue;
1475
1476 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1477 if (ret)
1478 return ret;
1479
1480 be->dpcm[stream].state = SND_SOC_DPCM_STATE_SUSPEND;
1481 break;
1482 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1483 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
1484 continue;
1485
1486 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1487 continue;
1488
1489 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1490 if (ret)
1491 return ret;
1492
1493 be->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
1494 break;
1495 }
1496 }
1497
1498 return ret;
1499}
1500EXPORT_SYMBOL_GPL(dpcm_be_dai_trigger);
1501
1502static int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd)
1503{
1504 struct snd_soc_pcm_runtime *fe = substream->private_data;
1505 int stream = substream->stream, ret;
1506 enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
1507
1508 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1509
1510 switch (trigger) {
1511 case SND_SOC_DPCM_TRIGGER_PRE:
1512 /* call trigger on the frontend before the backend. */
1513
1514 dev_dbg(fe->dev, "dpcm: pre trigger FE %s cmd %d\n",
1515 fe->dai_link->name, cmd);
1516
1517 ret = soc_pcm_trigger(substream, cmd);
1518 if (ret < 0) {
1519 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret);
1520 goto out;
1521 }
1522
1523 ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
1524 break;
1525 case SND_SOC_DPCM_TRIGGER_POST:
1526 /* call trigger on the frontend after the backend. */
1527
1528 ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
1529 if (ret < 0) {
1530 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret);
1531 goto out;
1532 }
1533
1534 dev_dbg(fe->dev, "dpcm: post trigger FE %s cmd %d\n",
1535 fe->dai_link->name, cmd);
1536
1537 ret = soc_pcm_trigger(substream, cmd);
1538 break;
1539 case SND_SOC_DPCM_TRIGGER_BESPOKE:
1540 /* bespoke trigger() - handles both FE and BEs */
1541
1542 dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd %d\n",
1543 fe->dai_link->name, cmd);
1544
1545 ret = soc_pcm_bespoke_trigger(substream, cmd);
1546 if (ret < 0) {
1547 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret);
1548 goto out;
1549 }
1550 break;
1551 default:
1552 dev_err(fe->dev, "dpcm: invalid trigger cmd %d for %s\n", cmd,
1553 fe->dai_link->name);
1554 ret = -EINVAL;
1555 goto out;
1556 }
1557
1558 switch (cmd) {
1559 case SNDRV_PCM_TRIGGER_START:
1560 case SNDRV_PCM_TRIGGER_RESUME:
1561 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1562 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
1563 break;
1564 case SNDRV_PCM_TRIGGER_STOP:
1565 case SNDRV_PCM_TRIGGER_SUSPEND:
1566 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1567 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
1568 break;
1569 }
1570
1571out:
1572 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1573 return ret;
1574}
1575
1576static int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream)
1577{
1578 struct snd_soc_dpcm *dpcm;
1579 int ret = 0;
1580
1581 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1582
1583 struct snd_soc_pcm_runtime *be = dpcm->be;
1584 struct snd_pcm_substream *be_substream =
1585 snd_soc_dpcm_get_substream(be, stream);
1586
1587 /* is this op for this BE ? */
1588 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1589 continue;
1590
1591 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
1592 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
1593 continue;
1594
1595 dev_dbg(be->dev, "dpcm: prepare BE %s\n",
1596 dpcm->fe->dai_link->name);
1597
1598 ret = soc_pcm_prepare(be_substream);
1599 if (ret < 0) {
1600 dev_err(be->dev, "dpcm: backend prepare failed %d\n",
1601 ret);
1602 break;
1603 }
1604
1605 be->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
1606 }
1607 return ret;
1608}
1609
1610static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream)
1611{
1612 struct snd_soc_pcm_runtime *fe = substream->private_data;
1613 int stream = substream->stream, ret = 0;
1614
1615 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1616
1617 dev_dbg(fe->dev, "dpcm: prepare FE %s\n", fe->dai_link->name);
1618
1619 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1620
1621 /* there is no point preparing this FE if there are no BEs */
1622 if (list_empty(&fe->dpcm[stream].be_clients)) {
1623 dev_err(fe->dev, "dpcm: no backend DAIs enabled for %s\n",
1624 fe->dai_link->name);
1625 ret = -EINVAL;
1626 goto out;
1627 }
1628
1629 ret = dpcm_be_dai_prepare(fe, substream->stream);
1630 if (ret < 0)
1631 goto out;
1632
1633 /* call prepare on the frontend */
1634 ret = soc_pcm_prepare(substream);
1635 if (ret < 0) {
1636 dev_err(fe->dev,"dpcm: prepare FE %s failed\n",
1637 fe->dai_link->name);
1638 goto out;
1639 }
1640
1641 /* run the stream event for each BE */
1642 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
1643 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
1644
1645out:
1646 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1647 mutex_unlock(&fe->card->mutex);
1648
1649 return ret;
1650}
1651
1652static int soc_pcm_ioctl(struct snd_pcm_substream *substream,
1653 unsigned int cmd, void *arg)
1654{
1655 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1656 struct snd_soc_platform *platform = rtd->platform;
1657
1658 if (platform->driver->ops->ioctl)
1659 return platform->driver->ops->ioctl(substream, cmd, arg);
1660 return snd_pcm_lib_ioctl(substream, cmd, arg);
1661}
1662
1663static int dpcm_run_update_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
1664{
1665 struct snd_pcm_substream *substream =
1666 snd_soc_dpcm_get_substream(fe, stream);
1667 enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
1668 int err;
1669
1670 dev_dbg(fe->dev, "runtime %s close on FE %s\n",
1671 stream ? "capture" : "playback", fe->dai_link->name);
1672
1673 if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) {
1674 /* call bespoke trigger - FE takes care of all BE triggers */
1675 dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd stop\n",
1676 fe->dai_link->name);
1677
1678 err = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_STOP);
1679 if (err < 0)
1680 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", err);
1681 } else {
1682 dev_dbg(fe->dev, "dpcm: trigger FE %s cmd stop\n",
1683 fe->dai_link->name);
1684
1685 err = dpcm_be_dai_trigger(fe, stream, SNDRV_PCM_TRIGGER_STOP);
1686 if (err < 0)
1687 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", err);
1688 }
1689
1690 err = dpcm_be_dai_hw_free(fe, stream);
1691 if (err < 0)
1692 dev_err(fe->dev,"dpcm: hw_free FE failed %d\n", err);
1693
1694 err = dpcm_be_dai_shutdown(fe, stream);
1695 if (err < 0)
1696 dev_err(fe->dev,"dpcm: shutdown FE failed %d\n", err);
1697
1698 /* run the stream event for each BE */
1699 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_NOP);
1700
1701 return 0;
1702}
1703
1704static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream)
1705{
1706 struct snd_pcm_substream *substream =
1707 snd_soc_dpcm_get_substream(fe, stream);
1708 struct snd_soc_dpcm *dpcm;
1709 enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
1710 int ret;
1711
1712 dev_dbg(fe->dev, "runtime %s open on FE %s\n",
1713 stream ? "capture" : "playback", fe->dai_link->name);
1714
1715 /* Only start the BE if the FE is ready */
1716 if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_HW_FREE ||
1717 fe->dpcm[stream].state == SND_SOC_DPCM_STATE_CLOSE)
1718 return -EINVAL;
1719
1720 /* startup must always be called for new BEs */
1721 ret = dpcm_be_dai_startup(fe, stream);
1722 if (ret < 0) {
1723 goto disconnect;
1724 return ret;
1725 }
1726
1727 /* keep going if FE state is > open */
1728 if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_OPEN)
1729 return 0;
1730
1731 ret = dpcm_be_dai_hw_params(fe, stream);
1732 if (ret < 0) {
1733 goto close;
1734 return ret;
1735 }
1736
1737 /* keep going if FE state is > hw_params */
1738 if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_HW_PARAMS)
1739 return 0;
1740
1741
1742 ret = dpcm_be_dai_prepare(fe, stream);
1743 if (ret < 0) {
1744 goto hw_free;
1745 return ret;
1746 }
1747
1748 /* run the stream event for each BE */
1749 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_NOP);
1750
1751 /* keep going if FE state is > prepare */
1752 if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_PREPARE ||
1753 fe->dpcm[stream].state == SND_SOC_DPCM_STATE_STOP)
1754 return 0;
1755
1756 if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) {
1757 /* call trigger on the frontend - FE takes care of all BE triggers */
1758 dev_dbg(fe->dev, "dpcm: bespoke trigger FE %s cmd start\n",
1759 fe->dai_link->name);
1760
1761 ret = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_START);
1762 if (ret < 0) {
1763 dev_err(fe->dev,"dpcm: bespoke trigger FE failed %d\n", ret);
1764 goto hw_free;
1765 }
1766 } else {
1767 dev_dbg(fe->dev, "dpcm: trigger FE %s cmd start\n",
1768 fe->dai_link->name);
1769
1770 ret = dpcm_be_dai_trigger(fe, stream,
1771 SNDRV_PCM_TRIGGER_START);
1772 if (ret < 0) {
1773 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret);
1774 goto hw_free;
1775 }
1776 }
1777
1778 return 0;
1779
1780hw_free:
1781 dpcm_be_dai_hw_free(fe, stream);
1782close:
1783 dpcm_be_dai_shutdown(fe, stream);
1784disconnect:
1785 /* disconnect any non started BEs */
1786 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1787 struct snd_soc_pcm_runtime *be = dpcm->be;
1788 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
1789 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
1790 }
1791
1792 return ret;
1793}
1794
1795static int dpcm_run_new_update(struct snd_soc_pcm_runtime *fe, int stream)
1796{
1797 int ret;
1798
1799 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
1800 ret = dpcm_run_update_startup(fe, stream);
1801 if (ret < 0)
1802 dev_err(fe->dev, "failed to startup some BEs\n");
1803 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1804
1805 return ret;
1806}
1807
1808static int dpcm_run_old_update(struct snd_soc_pcm_runtime *fe, int stream)
1809{
1810 int ret;
1811
1812 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
1813 ret = dpcm_run_update_shutdown(fe, stream);
1814 if (ret < 0)
1815 dev_err(fe->dev, "failed to shutdown some BEs\n");
1816 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1817
1818 return ret;
1819}
1820
1821/* Called by DAPM mixer/mux changes to update audio routing between PCMs and
1822 * any DAI links.
1823 */
1824int soc_dpcm_runtime_update(struct snd_soc_dapm_widget *widget)
1825{
1826 struct snd_soc_card *card;
1827 int i, old, new, paths;
1828
1829 if (widget->codec)
1830 card = widget->codec->card;
1831 else if (widget->platform)
1832 card = widget->platform->card;
1833 else
1834 return -EINVAL;
1835
1836 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1837 for (i = 0; i < card->num_rtd; i++) {
1838 struct snd_soc_dapm_widget_list *list;
1839 struct snd_soc_pcm_runtime *fe = &card->rtd[i];
1840
1841 /* make sure link is FE */
1842 if (!fe->dai_link->dynamic)
1843 continue;
1844
1845 /* only check active links */
1846 if (!fe->cpu_dai->active)
1847 continue;
1848
1849 /* DAPM sync will call this to update DSP paths */
1850 dev_dbg(fe->dev, "DPCM runtime update for FE %s\n",
1851 fe->dai_link->name);
1852
1853 /* skip if FE doesn't have playback capability */
1854 if (!fe->cpu_dai->driver->playback.channels_min)
1855 goto capture;
1856
1857 paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_PLAYBACK, &list);
1858 if (paths < 0) {
1859 dev_warn(fe->dev, "%s no valid %s path\n",
1860 fe->dai_link->name, "playback");
1861 mutex_unlock(&card->mutex);
1862 return paths;
1863 }
1864
1865 /* update any new playback paths */
1866 new = dpcm_process_paths(fe, SNDRV_PCM_STREAM_PLAYBACK, &list, 1);
1867 if (new) {
1868 dpcm_run_new_update(fe, SNDRV_PCM_STREAM_PLAYBACK);
1869 dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_PLAYBACK);
1870 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_PLAYBACK);
1871 }
1872
1873 /* update any old playback paths */
1874 old = dpcm_process_paths(fe, SNDRV_PCM_STREAM_PLAYBACK, &list, 0);
1875 if (old) {
1876 dpcm_run_old_update(fe, SNDRV_PCM_STREAM_PLAYBACK);
1877 dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_PLAYBACK);
1878 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_PLAYBACK);
1879 }
1880
1881capture:
1882 /* skip if FE doesn't have capture capability */
1883 if (!fe->cpu_dai->driver->capture.channels_min)
1884 continue;
1885
1886 paths = dpcm_path_get(fe, SNDRV_PCM_STREAM_CAPTURE, &list);
1887 if (paths < 0) {
1888 dev_warn(fe->dev, "%s no valid %s path\n",
1889 fe->dai_link->name, "capture");
1890 mutex_unlock(&card->mutex);
1891 return paths;
1892 }
1893
1894 /* update any new capture paths */
1895 new = dpcm_process_paths(fe, SNDRV_PCM_STREAM_CAPTURE, &list, 1);
1896 if (new) {
1897 dpcm_run_new_update(fe, SNDRV_PCM_STREAM_CAPTURE);
1898 dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_CAPTURE);
1899 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_CAPTURE);
1900 }
1901
1902 /* update any old capture paths */
1903 old = dpcm_process_paths(fe, SNDRV_PCM_STREAM_CAPTURE, &list, 0);
1904 if (old) {
1905 dpcm_run_old_update(fe, SNDRV_PCM_STREAM_CAPTURE);
1906 dpcm_clear_pending_state(fe, SNDRV_PCM_STREAM_CAPTURE);
1907 dpcm_be_disconnect(fe, SNDRV_PCM_STREAM_CAPTURE);
1908 }
1909
1910 dpcm_path_put(&list);
1911 }
1912
1913 mutex_unlock(&card->mutex);
1914 return 0;
1915}
1916int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute)
1917{
1918 struct snd_soc_dpcm *dpcm;
1919 struct list_head *clients =
1920 &fe->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients;
1921
1922 list_for_each_entry(dpcm, clients, list_be) {
1923
1924 struct snd_soc_pcm_runtime *be = dpcm->be;
1925 struct snd_soc_dai *dai = be->codec_dai;
1926 struct snd_soc_dai_driver *drv = dai->driver;
1927
1928 if (be->dai_link->ignore_suspend)
1929 continue;
1930
1931 dev_dbg(be->dev, "BE digital mute %s\n", be->dai_link->name);
1932
1933 if (drv->ops->digital_mute && dai->playback_active)
1934 drv->ops->digital_mute(dai, mute);
1935 }
1936
1937 return 0;
1938}
1939
1940static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream)
1941{
1942 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
1943 struct snd_soc_dpcm *dpcm;
1944 struct snd_soc_dapm_widget_list *list;
1945 int ret;
1946 int stream = fe_substream->stream;
1947
1948 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1949 fe->dpcm[stream].runtime = fe_substream->runtime;
1950
1951 if (dpcm_path_get(fe, stream, &list) <= 0) {
1952 dev_warn(fe->dev, "asoc: %s no valid %s route\n",
1953 fe->dai_link->name, stream ? "capture" : "playback");
1954 mutex_unlock(&fe->card->mutex);
1955 return -EINVAL;
1956 }
1957
1958 /* calculate valid and active FE <-> BE dpcms */
1959 dpcm_process_paths(fe, stream, &list, 1);
1960
1961 ret = dpcm_fe_dai_startup(fe_substream);
1962 if (ret < 0) {
1963 /* clean up all links */
1964 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
1965 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
1966
1967 dpcm_be_disconnect(fe, stream);
1968 fe->dpcm[stream].runtime = NULL;
1969 }
1970
1971 dpcm_clear_pending_state(fe, stream);
1972 dpcm_path_put(&list);
1973 mutex_unlock(&fe->card->mutex);
1974 return ret;
1975}
1976
1977static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream)
1978{
1979 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
1980 struct snd_soc_dpcm *dpcm;
1981 int stream = fe_substream->stream, ret;
1982
1983 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1984 ret = dpcm_fe_dai_shutdown(fe_substream);
1985
1986 /* mark FE's links ready to prune */
1987 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
1988 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
1989
1990 dpcm_be_disconnect(fe, stream);
1991
1992 fe->dpcm[stream].runtime = NULL;
1993 mutex_unlock(&fe->card->mutex);
1994 return ret;
1995}
1996
637/* create a new pcm */ 1997/* create a new pcm */
638int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) 1998int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
639{ 1999{
@@ -641,56 +2001,94 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
641 struct snd_soc_platform *platform = rtd->platform; 2001 struct snd_soc_platform *platform = rtd->platform;
642 struct snd_soc_dai *codec_dai = rtd->codec_dai; 2002 struct snd_soc_dai *codec_dai = rtd->codec_dai;
643 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 2003 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
644 struct snd_pcm_ops *soc_pcm_ops = &rtd->ops;
645 struct snd_pcm *pcm; 2004 struct snd_pcm *pcm;
646 char new_name[64]; 2005 char new_name[64];
647 int ret = 0, playback = 0, capture = 0; 2006 int ret = 0, playback = 0, capture = 0;
648 2007
649 soc_pcm_ops->open = soc_pcm_open; 2008 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) {
650 soc_pcm_ops->close = soc_pcm_close; 2009 if (cpu_dai->driver->playback.channels_min)
651 soc_pcm_ops->hw_params = soc_pcm_hw_params; 2010 playback = 1;
652 soc_pcm_ops->hw_free = soc_pcm_hw_free; 2011 if (cpu_dai->driver->capture.channels_min)
653 soc_pcm_ops->prepare = soc_pcm_prepare; 2012 capture = 1;
654 soc_pcm_ops->trigger = soc_pcm_trigger; 2013 } else {
655 soc_pcm_ops->pointer = soc_pcm_pointer; 2014 if (codec_dai->driver->playback.channels_min)
656 2015 playback = 1;
657 /* check client and interface hw capabilities */ 2016 if (codec_dai->driver->capture.channels_min)
658 snprintf(new_name, sizeof(new_name), "%s %s-%d", 2017 capture = 1;
659 rtd->dai_link->stream_name, codec_dai->name, num); 2018 }
660 2019
661 if (codec_dai->driver->playback.channels_min) 2020 /* create the PCM */
662 playback = 1; 2021 if (rtd->dai_link->no_pcm) {
663 if (codec_dai->driver->capture.channels_min) 2022 snprintf(new_name, sizeof(new_name), "(%s)",
664 capture = 1; 2023 rtd->dai_link->stream_name);
665 2024
666 dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num,new_name); 2025 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
667 ret = snd_pcm_new(rtd->card->snd_card, new_name, 2026 playback, capture, &pcm);
668 num, playback, capture, &pcm); 2027 } else {
2028 if (rtd->dai_link->dynamic)
2029 snprintf(new_name, sizeof(new_name), "%s (*)",
2030 rtd->dai_link->stream_name);
2031 else
2032 snprintf(new_name, sizeof(new_name), "%s %s-%d",
2033 rtd->dai_link->stream_name, codec_dai->name, num);
2034
2035 ret = snd_pcm_new(rtd->card->snd_card, new_name, num, playback,
2036 capture, &pcm);
2037 }
669 if (ret < 0) { 2038 if (ret < 0) {
670 printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name); 2039 printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name);
671 return ret; 2040 return ret;
672 } 2041 }
2042 dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num, new_name);
673 2043
674 /* DAPM dai link stream work */ 2044 /* DAPM dai link stream work */
675 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); 2045 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
676 2046
677 rtd->pcm = pcm; 2047 rtd->pcm = pcm;
678 pcm->private_data = rtd; 2048 pcm->private_data = rtd;
2049
2050 if (rtd->dai_link->no_pcm) {
2051 if (playback)
2052 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
2053 if (capture)
2054 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
2055 goto out;
2056 }
2057
2058 /* ASoC PCM operations */
2059 if (rtd->dai_link->dynamic) {
2060 rtd->ops.open = dpcm_fe_dai_open;
2061 rtd->ops.hw_params = dpcm_fe_dai_hw_params;
2062 rtd->ops.prepare = dpcm_fe_dai_prepare;
2063 rtd->ops.trigger = dpcm_fe_dai_trigger;
2064 rtd->ops.hw_free = dpcm_fe_dai_hw_free;
2065 rtd->ops.close = dpcm_fe_dai_close;
2066 rtd->ops.pointer = soc_pcm_pointer;
2067 rtd->ops.ioctl = soc_pcm_ioctl;
2068 } else {
2069 rtd->ops.open = soc_pcm_open;
2070 rtd->ops.hw_params = soc_pcm_hw_params;
2071 rtd->ops.prepare = soc_pcm_prepare;
2072 rtd->ops.trigger = soc_pcm_trigger;
2073 rtd->ops.hw_free = soc_pcm_hw_free;
2074 rtd->ops.close = soc_pcm_close;
2075 rtd->ops.pointer = soc_pcm_pointer;
2076 rtd->ops.ioctl = soc_pcm_ioctl;
2077 }
2078
679 if (platform->driver->ops) { 2079 if (platform->driver->ops) {
680 soc_pcm_ops->mmap = platform->driver->ops->mmap; 2080 rtd->ops.ack = platform->driver->ops->ack;
681 soc_pcm_ops->pointer = platform->driver->ops->pointer; 2081 rtd->ops.copy = platform->driver->ops->copy;
682 soc_pcm_ops->ioctl = platform->driver->ops->ioctl; 2082 rtd->ops.silence = platform->driver->ops->silence;
683 soc_pcm_ops->copy = platform->driver->ops->copy; 2083 rtd->ops.page = platform->driver->ops->page;
684 soc_pcm_ops->silence = platform->driver->ops->silence; 2084 rtd->ops.mmap = platform->driver->ops->mmap;
685 soc_pcm_ops->ack = platform->driver->ops->ack;
686 soc_pcm_ops->page = platform->driver->ops->page;
687 } 2085 }
688 2086
689 if (playback) 2087 if (playback)
690 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, soc_pcm_ops); 2088 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &rtd->ops);
691 2089
692 if (capture) 2090 if (capture)
693 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, soc_pcm_ops); 2091 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops);
694 2092
695 if (platform->driver->pcm_new) { 2093 if (platform->driver->pcm_new) {
696 ret = platform->driver->pcm_new(rtd); 2094 ret = platform->driver->pcm_new(rtd);
@@ -701,7 +2099,257 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
701 } 2099 }
702 2100
703 pcm->private_free = platform->driver->pcm_free; 2101 pcm->private_free = platform->driver->pcm_free;
2102out:
704 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name, 2103 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name,
705 cpu_dai->name); 2104 cpu_dai->name);
706 return ret; 2105 return ret;
707} 2106}
2107
2108/* is the current PCM operation for this FE ? */
2109int snd_soc_dpcm_fe_can_update(struct snd_soc_pcm_runtime *fe, int stream)
2110{
2111 if (fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE)
2112 return 1;
2113 return 0;
2114}
2115EXPORT_SYMBOL_GPL(snd_soc_dpcm_fe_can_update);
2116
2117/* is the current PCM operation for this BE ? */
2118int snd_soc_dpcm_be_can_update(struct snd_soc_pcm_runtime *fe,
2119 struct snd_soc_pcm_runtime *be, int stream)
2120{
2121 if ((fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE) ||
2122 ((fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_BE) &&
2123 be->dpcm[stream].runtime_update))
2124 return 1;
2125 return 0;
2126}
2127EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_can_update);
2128
2129/* get the substream for this BE */
2130struct snd_pcm_substream *
2131 snd_soc_dpcm_get_substream(struct snd_soc_pcm_runtime *be, int stream)
2132{
2133 return be->pcm->streams[stream].substream;
2134}
2135EXPORT_SYMBOL_GPL(snd_soc_dpcm_get_substream);
2136
2137/* get the BE runtime state */
2138enum snd_soc_dpcm_state
2139 snd_soc_dpcm_be_get_state(struct snd_soc_pcm_runtime *be, int stream)
2140{
2141 return be->dpcm[stream].state;
2142}
2143EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_get_state);
2144
2145/* set the BE runtime state */
2146void snd_soc_dpcm_be_set_state(struct snd_soc_pcm_runtime *be,
2147 int stream, enum snd_soc_dpcm_state state)
2148{
2149 be->dpcm[stream].state = state;
2150}
2151EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_set_state);
2152
2153/*
2154 * We can only hw_free, stop, pause or suspend a BE DAI if any of it's FE
2155 * are not running, paused or suspended for the specified stream direction.
2156 */
2157int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe,
2158 struct snd_soc_pcm_runtime *be, int stream)
2159{
2160 struct snd_soc_dpcm *dpcm;
2161 int state;
2162
2163 list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) {
2164
2165 if (dpcm->fe == fe)
2166 continue;
2167
2168 state = dpcm->fe->dpcm[stream].state;
2169 if (state == SND_SOC_DPCM_STATE_START ||
2170 state == SND_SOC_DPCM_STATE_PAUSED ||
2171 state == SND_SOC_DPCM_STATE_SUSPEND)
2172 return 0;
2173 }
2174
2175 /* it's safe to free/stop this BE DAI */
2176 return 1;
2177}
2178EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_free_stop);
2179
2180/*
2181 * We can only change hw params a BE DAI if any of it's FE are not prepared,
2182 * running, paused or suspended for the specified stream direction.
2183 */
2184int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe,
2185 struct snd_soc_pcm_runtime *be, int stream)
2186{
2187 struct snd_soc_dpcm *dpcm;
2188 int state;
2189
2190 list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) {
2191
2192 if (dpcm->fe == fe)
2193 continue;
2194
2195 state = dpcm->fe->dpcm[stream].state;
2196 if (state == SND_SOC_DPCM_STATE_START ||
2197 state == SND_SOC_DPCM_STATE_PAUSED ||
2198 state == SND_SOC_DPCM_STATE_SUSPEND ||
2199 state == SND_SOC_DPCM_STATE_PREPARE)
2200 return 0;
2201 }
2202
2203 /* it's safe to change hw_params */
2204 return 1;
2205}
2206EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params);
2207
2208int snd_soc_platform_trigger(struct snd_pcm_substream *substream,
2209 int cmd, struct snd_soc_platform *platform)
2210{
2211 if (platform->driver->ops->trigger)
2212 return platform->driver->ops->trigger(substream, cmd);
2213 return 0;
2214}
2215EXPORT_SYMBOL_GPL(snd_soc_platform_trigger);
2216
2217#ifdef CONFIG_DEBUG_FS
2218static char *dpcm_state_string(enum snd_soc_dpcm_state state)
2219{
2220 switch (state) {
2221 case SND_SOC_DPCM_STATE_NEW:
2222 return "new";
2223 case SND_SOC_DPCM_STATE_OPEN:
2224 return "open";
2225 case SND_SOC_DPCM_STATE_HW_PARAMS:
2226 return "hw_params";
2227 case SND_SOC_DPCM_STATE_PREPARE:
2228 return "prepare";
2229 case SND_SOC_DPCM_STATE_START:
2230 return "start";
2231 case SND_SOC_DPCM_STATE_STOP:
2232 return "stop";
2233 case SND_SOC_DPCM_STATE_SUSPEND:
2234 return "suspend";
2235 case SND_SOC_DPCM_STATE_PAUSED:
2236 return "paused";
2237 case SND_SOC_DPCM_STATE_HW_FREE:
2238 return "hw_free";
2239 case SND_SOC_DPCM_STATE_CLOSE:
2240 return "close";
2241 }
2242
2243 return "unknown";
2244}
2245
2246static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe,
2247 int stream, char *buf, size_t size)
2248{
2249 struct snd_pcm_hw_params *params = &fe->dpcm[stream].hw_params;
2250 struct snd_soc_dpcm *dpcm;
2251 ssize_t offset = 0;
2252
2253 /* FE state */
2254 offset += snprintf(buf + offset, size - offset,
2255 "[%s - %s]\n", fe->dai_link->name,
2256 stream ? "Capture" : "Playback");
2257
2258 offset += snprintf(buf + offset, size - offset, "State: %s\n",
2259 dpcm_state_string(fe->dpcm[stream].state));
2260
2261 if ((fe->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) &&
2262 (fe->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP))
2263 offset += snprintf(buf + offset, size - offset,
2264 "Hardware Params: "
2265 "Format = %s, Channels = %d, Rate = %d\n",
2266 snd_pcm_format_name(params_format(params)),
2267 params_channels(params),
2268 params_rate(params));
2269
2270 /* BEs state */
2271 offset += snprintf(buf + offset, size - offset, "Backends:\n");
2272
2273 if (list_empty(&fe->dpcm[stream].be_clients)) {
2274 offset += snprintf(buf + offset, size - offset,
2275 " No active DSP links\n");
2276 goto out;
2277 }
2278
2279 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
2280 struct snd_soc_pcm_runtime *be = dpcm->be;
2281 params = &dpcm->hw_params;
2282
2283 offset += snprintf(buf + offset, size - offset,
2284 "- %s\n", be->dai_link->name);
2285
2286 offset += snprintf(buf + offset, size - offset,
2287 " State: %s\n",
2288 dpcm_state_string(be->dpcm[stream].state));
2289
2290 if ((be->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) &&
2291 (be->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP))
2292 offset += snprintf(buf + offset, size - offset,
2293 " Hardware Params: "
2294 "Format = %s, Channels = %d, Rate = %d\n",
2295 snd_pcm_format_name(params_format(params)),
2296 params_channels(params),
2297 params_rate(params));
2298 }
2299
2300out:
2301 return offset;
2302}
2303
2304static ssize_t dpcm_state_read_file(struct file *file, char __user *user_buf,
2305 size_t count, loff_t *ppos)
2306{
2307 struct snd_soc_pcm_runtime *fe = file->private_data;
2308 ssize_t out_count = PAGE_SIZE, offset = 0, ret = 0;
2309 char *buf;
2310
2311 buf = kmalloc(out_count, GFP_KERNEL);
2312 if (!buf)
2313 return -ENOMEM;
2314
2315 if (fe->cpu_dai->driver->playback.channels_min)
2316 offset += dpcm_show_state(fe, SNDRV_PCM_STREAM_PLAYBACK,
2317 buf + offset, out_count - offset);
2318
2319 if (fe->cpu_dai->driver->capture.channels_min)
2320 offset += dpcm_show_state(fe, SNDRV_PCM_STREAM_CAPTURE,
2321 buf + offset, out_count - offset);
2322
2323 ret = simple_read_from_buffer(user_buf, count, ppos, buf, offset);
2324
2325 kfree(buf);
2326 return ret;
2327}
2328
2329static const struct file_operations dpcm_state_fops = {
2330 .open = simple_open,
2331 .read = dpcm_state_read_file,
2332 .llseek = default_llseek,
2333};
2334
2335int soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd)
2336{
2337 if (!rtd->dai_link)
2338 return 0;
2339
2340 rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name,
2341 rtd->card->debugfs_card_root);
2342 if (!rtd->debugfs_dpcm_root) {
2343 dev_dbg(rtd->dev,
2344 "ASoC: Failed to create dpcm debugfs directory %s\n",
2345 rtd->dai_link->name);
2346 return -EINVAL;
2347 }
2348
2349 rtd->debugfs_dpcm_state = debugfs_create_file("state", 0444,
2350 rtd->debugfs_dpcm_root,
2351 rtd, &dpcm_state_fops);
2352
2353 return 0;
2354}
2355#endif
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index ce1b773c351f..c1c8e955f4d3 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -1,26 +1,63 @@
1config SND_SOC_TEGRA 1config SND_SOC_TEGRA
2 tristate "SoC Audio for the Tegra System-on-Chip" 2 tristate "SoC Audio for the Tegra System-on-Chip"
3 depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA 3 depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA
4 select REGMAP_MMIO
4 help 5 help
5 Say Y or M here if you want support for SoC audio on Tegra. 6 Say Y or M here if you want support for SoC audio on Tegra.
6 7
7config SND_SOC_TEGRA_I2S 8config SND_SOC_TEGRA20_DAS
8 tristate 9 tristate
9 depends on SND_SOC_TEGRA 10 depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC
11 help
12 Say Y or M if you want to add support for the Tegra20 DAS module.
13 You will also need to select the individual machine drivers to
14 support below.
15
16config SND_SOC_TEGRA20_I2S
17 tristate
18 depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC
19 select SND_SOC_TEGRA20_DAS
10 help 20 help
11 Say Y or M if you want to add support for codecs attached to the 21 Say Y or M if you want to add support for codecs attached to the
12 Tegra I2S interface. You will also need to select the individual 22 Tegra20 I2S interface. You will also need to select the individual
13 machine drivers to support below. 23 machine drivers to support below.
14 24
15config SND_SOC_TEGRA_SPDIF 25config SND_SOC_TEGRA20_SPDIF
16 tristate 26 tristate
17 depends on SND_SOC_TEGRA 27 depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC
18 default m 28 default m
19 help 29 help
20 Say Y or M if you want to add support for the SPDIF interface. 30 Say Y or M if you want to add support for the Tegra20 SPDIF interface.
21 You will also need to select the individual machine drivers to support 31 You will also need to select the individual machine drivers to support
22 below. 32 below.
23 33
34config SND_SOC_TEGRA30_AHUB
35 tristate
36 depends on SND_SOC_TEGRA && ARCH_TEGRA_3x_SOC
37 help
38 Say Y or M if you want to add support for the Tegra20 AHUB module.
39 You will also need to select the individual machine drivers to
40 support below.
41
42config SND_SOC_TEGRA30_I2S
43 tristate
44 depends on SND_SOC_TEGRA && ARCH_TEGRA_3x_SOC
45 select SND_SOC_TEGRA30_AHUB
46 help
47 Say Y or M if you want to add support for codecs attached to the
48 Tegra30 I2S interface. You will also need to select the individual
49 machine drivers to support below.
50
51config SND_SOC_TEGRA_WM8753
52 tristate "SoC Audio support for Tegra boards using a WM8753 codec"
53 depends on SND_SOC_TEGRA && I2C
54 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
55 select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC
56 select SND_SOC_WM8753
57 help
58 Say Y or M here if you want to add support for SoC audio on Tegra
59 boards using the WM8753 codec, such as Whistler.
60
24config MACH_HAS_SND_SOC_TEGRA_WM8903 61config MACH_HAS_SND_SOC_TEGRA_WM8903
25 bool 62 bool
26 help 63 help
@@ -32,7 +69,8 @@ config SND_SOC_TEGRA_WM8903
32 tristate "SoC Audio support for Tegra boards using a WM8903 codec" 69 tristate "SoC Audio support for Tegra boards using a WM8903 codec"
33 depends on SND_SOC_TEGRA && I2C 70 depends on SND_SOC_TEGRA && I2C
34 depends on MACH_HAS_SND_SOC_TEGRA_WM8903 71 depends on MACH_HAS_SND_SOC_TEGRA_WM8903
35 select SND_SOC_TEGRA_I2S 72 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
73 select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC
36 select SND_SOC_WM8903 74 select SND_SOC_WM8903
37 help 75 help
38 Say Y or M here if you want to add support for SoC audio on Tegra 76 Say Y or M here if you want to add support for SoC audio on Tegra
@@ -42,17 +80,17 @@ config SND_SOC_TEGRA_WM8903
42config SND_SOC_TEGRA_TRIMSLICE 80config SND_SOC_TEGRA_TRIMSLICE
43 tristate "SoC Audio support for TrimSlice board" 81 tristate "SoC Audio support for TrimSlice board"
44 depends on SND_SOC_TEGRA && MACH_TRIMSLICE && I2C 82 depends on SND_SOC_TEGRA && MACH_TRIMSLICE && I2C
45 select SND_SOC_TEGRA_I2S 83 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
46 select SND_SOC_TLV320AIC23 84 select SND_SOC_TLV320AIC23
47 help 85 help
48 Say Y or M here if you want to add support for SoC audio on the 86 Say Y or M here if you want to add support for SoC audio on the
49 TrimSlice platform. 87 TrimSlice platform.
50 88
51config SND_SOC_TEGRA_ALC5632 89config SND_SOC_TEGRA_ALC5632
52 tristate "SoC Audio support for Tegra boards using an ALC5632 codec" 90 tristate "SoC Audio support for Tegra boards using an ALC5632 codec"
53 depends on SND_SOC_TEGRA && I2C 91 depends on SND_SOC_TEGRA && I2C
54 select SND_SOC_TEGRA_I2S 92 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
55 select SND_SOC_ALC5632 93 select SND_SOC_ALC5632
56 help 94 help
57 Say Y or M here if you want to add support for SoC audio on the 95 Say Y or M here if you want to add support for SoC audio on the
58 Toshiba AC100 netbook. 96 Toshiba AC100 netbook.
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index 8e584b8fcfba..391e78a34c06 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -1,21 +1,27 @@
1# Tegra platform Support 1# Tegra platform Support
2snd-soc-tegra-das-objs := tegra_das.o
3snd-soc-tegra-pcm-objs := tegra_pcm.o 2snd-soc-tegra-pcm-objs := tegra_pcm.o
4snd-soc-tegra-i2s-objs := tegra_i2s.o
5snd-soc-tegra-spdif-objs := tegra_spdif.o
6snd-soc-tegra-utils-objs += tegra_asoc_utils.o 3snd-soc-tegra-utils-objs += tegra_asoc_utils.o
4snd-soc-tegra20-das-objs := tegra20_das.o
5snd-soc-tegra20-i2s-objs := tegra20_i2s.o
6snd-soc-tegra20-spdif-objs := tegra20_spdif.o
7snd-soc-tegra30-ahub-objs := tegra30_ahub.o
8snd-soc-tegra30-i2s-objs := tegra30_i2s.o
7 9
8obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-utils.o
9obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-das.o
10obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o 10obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-pcm.o
11obj-$(CONFIG_SND_SOC_TEGRA_I2S) += snd-soc-tegra-i2s.o 11obj-$(CONFIG_SND_SOC_TEGRA) += snd-soc-tegra-utils.o
12obj-$(CONFIG_SND_SOC_TEGRA_SPDIF) += snd-soc-tegra-spdif.o 12obj-$(CONFIG_SND_SOC_TEGRA20_DAS) += snd-soc-tegra20-das.o
13obj-$(CONFIG_SND_SOC_TEGRA20_I2S) += snd-soc-tegra20-i2s.o
14obj-$(CONFIG_SND_SOC_TEGRA20_SPDIF) += snd-soc-tegra20-spdif.o
15obj-$(CONFIG_SND_SOC_TEGRA30_AHUB) += snd-soc-tegra30-ahub.o
16obj-$(CONFIG_SND_SOC_TEGRA30_I2S) += snd-soc-tegra30-i2s.o
13 17
14# Tegra machine Support 18# Tegra machine Support
19snd-soc-tegra-wm8753-objs := tegra_wm8753.o
15snd-soc-tegra-wm8903-objs := tegra_wm8903.o 20snd-soc-tegra-wm8903-objs := tegra_wm8903.o
16snd-soc-tegra-trimslice-objs := trimslice.o 21snd-soc-tegra-trimslice-objs := trimslice.o
17snd-soc-tegra-alc5632-objs := tegra_alc5632.o 22snd-soc-tegra-alc5632-objs := tegra_alc5632.o
18 23
24obj-$(CONFIG_SND_SOC_TEGRA_WM8753) += snd-soc-tegra-wm8753.o
19obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o 25obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o
20obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o 26obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o
21obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o 27obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o
diff --git a/sound/soc/tegra/tegra20_das.c b/sound/soc/tegra/tegra20_das.c
new file mode 100644
index 000000000000..bf99296bce95
--- /dev/null
+++ b/sound/soc/tegra/tegra20_das.c
@@ -0,0 +1,233 @@
1/*
2 * tegra20_das.c - Tegra20 DAS driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
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 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include <linux/device.h>
24#include <linux/io.h>
25#include <linux/module.h>
26#include <linux/platform_device.h>
27#include <linux/regmap.h>
28#include <linux/slab.h>
29#include <sound/soc.h>
30#include "tegra20_das.h"
31
32#define DRV_NAME "tegra20-das"
33
34static struct tegra20_das *das;
35
36static inline void tegra20_das_write(u32 reg, u32 val)
37{
38 regmap_write(das->regmap, reg, val);
39}
40
41static inline u32 tegra20_das_read(u32 reg)
42{
43 u32 val;
44 regmap_read(das->regmap, reg, &val);
45 return val;
46}
47
48int tegra20_das_connect_dap_to_dac(int dap, int dac)
49{
50 u32 addr;
51 u32 reg;
52
53 if (!das)
54 return -ENODEV;
55
56 addr = TEGRA20_DAS_DAP_CTRL_SEL +
57 (dap * TEGRA20_DAS_DAP_CTRL_SEL_STRIDE);
58 reg = dac << TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P;
59
60 tegra20_das_write(addr, reg);
61
62 return 0;
63}
64EXPORT_SYMBOL_GPL(tegra20_das_connect_dap_to_dac);
65
66int tegra20_das_connect_dap_to_dap(int dap, int otherdap, int master,
67 int sdata1rx, int sdata2rx)
68{
69 u32 addr;
70 u32 reg;
71
72 if (!das)
73 return -ENODEV;
74
75 addr = TEGRA20_DAS_DAP_CTRL_SEL +
76 (dap * TEGRA20_DAS_DAP_CTRL_SEL_STRIDE);
77 reg = otherdap << TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P |
78 !!sdata2rx << TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P |
79 !!sdata1rx << TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P |
80 !!master << TEGRA20_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P;
81
82 tegra20_das_write(addr, reg);
83
84 return 0;
85}
86EXPORT_SYMBOL_GPL(tegra20_das_connect_dap_to_dap);
87
88int tegra20_das_connect_dac_to_dap(int dac, int dap)
89{
90 u32 addr;
91 u32 reg;
92
93 if (!das)
94 return -ENODEV;
95
96 addr = TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL +
97 (dac * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE);
98 reg = dap << TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P |
99 dap << TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P |
100 dap << TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P;
101
102 tegra20_das_write(addr, reg);
103
104 return 0;
105}
106EXPORT_SYMBOL_GPL(tegra20_das_connect_dac_to_dap);
107
108#define LAST_REG(name) \
109 (TEGRA20_DAS_##name + \
110 (TEGRA20_DAS_##name##_STRIDE * (TEGRA20_DAS_##name##_COUNT - 1)))
111
112static bool tegra20_das_wr_rd_reg(struct device *dev, unsigned int reg)
113{
114 if ((reg >= TEGRA20_DAS_DAP_CTRL_SEL) &&
115 (reg <= LAST_REG(DAP_CTRL_SEL)))
116 return true;
117 if ((reg >= TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL) &&
118 (reg <= LAST_REG(DAC_INPUT_DATA_CLK_SEL)))
119 return true;
120
121 return false;
122}
123
124static const struct regmap_config tegra20_das_regmap_config = {
125 .reg_bits = 32,
126 .reg_stride = 4,
127 .val_bits = 32,
128 .max_register = LAST_REG(DAC_INPUT_DATA_CLK_SEL),
129 .writeable_reg = tegra20_das_wr_rd_reg,
130 .readable_reg = tegra20_das_wr_rd_reg,
131 .cache_type = REGCACHE_RBTREE,
132};
133
134static int __devinit tegra20_das_probe(struct platform_device *pdev)
135{
136 struct resource *res, *region;
137 void __iomem *regs;
138 int ret = 0;
139
140 if (das)
141 return -ENODEV;
142
143 das = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_das), GFP_KERNEL);
144 if (!das) {
145 dev_err(&pdev->dev, "Can't allocate tegra20_das\n");
146 ret = -ENOMEM;
147 goto err;
148 }
149 das->dev = &pdev->dev;
150
151 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
152 if (!res) {
153 dev_err(&pdev->dev, "No memory resource\n");
154 ret = -ENODEV;
155 goto err;
156 }
157
158 region = devm_request_mem_region(&pdev->dev, res->start,
159 resource_size(res), pdev->name);
160 if (!region) {
161 dev_err(&pdev->dev, "Memory region already claimed\n");
162 ret = -EBUSY;
163 goto err;
164 }
165
166 regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
167 if (!regs) {
168 dev_err(&pdev->dev, "ioremap failed\n");
169 ret = -ENOMEM;
170 goto err;
171 }
172
173 das->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
174 &tegra20_das_regmap_config);
175 if (IS_ERR(das->regmap)) {
176 dev_err(&pdev->dev, "regmap init failed\n");
177 ret = PTR_ERR(das->regmap);
178 goto err;
179 }
180
181 ret = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_1,
182 TEGRA20_DAS_DAP_SEL_DAC1);
183 if (ret) {
184 dev_err(&pdev->dev, "Can't set up DAS DAP connection\n");
185 goto err;
186 }
187 ret = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAC_ID_1,
188 TEGRA20_DAS_DAC_SEL_DAP1);
189 if (ret) {
190 dev_err(&pdev->dev, "Can't set up DAS DAC connection\n");
191 goto err;
192 }
193
194 platform_set_drvdata(pdev, das);
195
196 return 0;
197
198err:
199 das = NULL;
200 return ret;
201}
202
203static int __devexit tegra20_das_remove(struct platform_device *pdev)
204{
205 if (!das)
206 return -ENODEV;
207
208 das = NULL;
209
210 return 0;
211}
212
213static const struct of_device_id tegra20_das_of_match[] __devinitconst = {
214 { .compatible = "nvidia,tegra20-das", },
215 {},
216};
217
218static struct platform_driver tegra20_das_driver = {
219 .probe = tegra20_das_probe,
220 .remove = __devexit_p(tegra20_das_remove),
221 .driver = {
222 .name = DRV_NAME,
223 .owner = THIS_MODULE,
224 .of_match_table = tegra20_das_of_match,
225 },
226};
227module_platform_driver(tegra20_das_driver);
228
229MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
230MODULE_DESCRIPTION("Tegra20 DAS driver");
231MODULE_LICENSE("GPL");
232MODULE_ALIAS("platform:" DRV_NAME);
233MODULE_DEVICE_TABLE(of, tegra20_das_of_match);
diff --git a/sound/soc/tegra/tegra20_das.h b/sound/soc/tegra/tegra20_das.h
new file mode 100644
index 000000000000..be217f3d3a75
--- /dev/null
+++ b/sound/soc/tegra/tegra20_das.h
@@ -0,0 +1,134 @@
1/*
2 * tegra20_das.h - Definitions for Tegra20 DAS driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
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 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#ifndef __TEGRA20_DAS_H__
24#define __TEGRA20_DAS_H__
25
26/* Register TEGRA20_DAS_DAP_CTRL_SEL */
27#define TEGRA20_DAS_DAP_CTRL_SEL 0x00
28#define TEGRA20_DAS_DAP_CTRL_SEL_COUNT 5
29#define TEGRA20_DAS_DAP_CTRL_SEL_STRIDE 4
30#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P 31
31#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_MS_SEL_S 1
32#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P 30
33#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_S 1
34#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P 29
35#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_S 1
36#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P 0
37#define TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_S 5
38
39/* Values for field TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL */
40#define TEGRA20_DAS_DAP_SEL_DAC1 0
41#define TEGRA20_DAS_DAP_SEL_DAC2 1
42#define TEGRA20_DAS_DAP_SEL_DAC3 2
43#define TEGRA20_DAS_DAP_SEL_DAP1 16
44#define TEGRA20_DAS_DAP_SEL_DAP2 17
45#define TEGRA20_DAS_DAP_SEL_DAP3 18
46#define TEGRA20_DAS_DAP_SEL_DAP4 19
47#define TEGRA20_DAS_DAP_SEL_DAP5 20
48
49/* Register TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL */
50#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL 0x40
51#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT 3
52#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE 4
53#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P 28
54#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_S 4
55#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P 24
56#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_S 4
57#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P 0
58#define TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_S 4
59
60/*
61 * Values for:
62 * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL
63 * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL
64 * TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL
65 */
66#define TEGRA20_DAS_DAC_SEL_DAP1 0
67#define TEGRA20_DAS_DAC_SEL_DAP2 1
68#define TEGRA20_DAS_DAC_SEL_DAP3 2
69#define TEGRA20_DAS_DAC_SEL_DAP4 3
70#define TEGRA20_DAS_DAC_SEL_DAP5 4
71
72/*
73 * Names/IDs of the DACs/DAPs.
74 */
75
76#define TEGRA20_DAS_DAP_ID_1 0
77#define TEGRA20_DAS_DAP_ID_2 1
78#define TEGRA20_DAS_DAP_ID_3 2
79#define TEGRA20_DAS_DAP_ID_4 3
80#define TEGRA20_DAS_DAP_ID_5 4
81
82#define TEGRA20_DAS_DAC_ID_1 0
83#define TEGRA20_DAS_DAC_ID_2 1
84#define TEGRA20_DAS_DAC_ID_3 2
85
86struct tegra20_das {
87 struct device *dev;
88 struct regmap *regmap;
89};
90
91/*
92 * Terminology:
93 * DAS: Digital audio switch (HW module controlled by this driver)
94 * DAP: Digital audio port (port/pins on Tegra device)
95 * DAC: Digital audio controller (e.g. I2S or AC97 controller elsewhere)
96 *
97 * The Tegra DAS is a mux/cross-bar which can connect each DAP to a specific
98 * DAC, or another DAP. When DAPs are connected, one must be the master and
99 * one the slave. Each DAC allows selection of a specific DAP for input, to
100 * cater for the case where N DAPs are connected to 1 DAC for broadcast
101 * output.
102 *
103 * This driver is dumb; no attempt is made to ensure that a valid routing
104 * configuration is programmed.
105 */
106
107/*
108 * Connect a DAP to to a DAC
109 * dap_id: DAP to connect: TEGRA20_DAS_DAP_ID_*
110 * dac_sel: DAC to connect to: TEGRA20_DAS_DAP_SEL_DAC*
111 */
112extern int tegra20_das_connect_dap_to_dac(int dap_id, int dac_sel);
113
114/*
115 * Connect a DAP to to another DAP
116 * dap_id: DAP to connect: TEGRA20_DAS_DAP_ID_*
117 * other_dap_sel: DAP to connect to: TEGRA20_DAS_DAP_SEL_DAP*
118 * master: Is this DAP the master (1) or slave (0)
119 * sdata1rx: Is this DAP's SDATA1 pin RX (1) or TX (0)
120 * sdata2rx: Is this DAP's SDATA2 pin RX (1) or TX (0)
121 */
122extern int tegra20_das_connect_dap_to_dap(int dap_id, int other_dap_sel,
123 int master, int sdata1rx,
124 int sdata2rx);
125
126/*
127 * Connect a DAC's input to a DAP
128 * (DAC outputs are selected by the DAP)
129 * dac_id: DAC ID to connect: TEGRA20_DAS_DAC_ID_*
130 * dap_sel: DAP to receive input from: TEGRA20_DAS_DAC_SEL_DAP*
131 */
132extern int tegra20_das_connect_dac_to_dap(int dac_id, int dap_sel);
133
134#endif
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c
new file mode 100644
index 000000000000..0c7af63d444b
--- /dev/null
+++ b/sound/soc/tegra/tegra20_i2s.c
@@ -0,0 +1,494 @@
1/*
2 * tegra20_i2s.c - Tegra20 I2S driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2010, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 *
12 * Copyright (C) 2010 Google, Inc.
13 * Iliyan Malchev <malchev@google.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#include <linux/clk.h>
32#include <linux/device.h>
33#include <linux/io.h>
34#include <linux/module.h>
35#include <linux/of.h>
36#include <linux/platform_device.h>
37#include <linux/pm_runtime.h>
38#include <linux/regmap.h>
39#include <linux/slab.h>
40#include <sound/core.h>
41#include <sound/pcm.h>
42#include <sound/pcm_params.h>
43#include <sound/soc.h>
44
45#include "tegra20_i2s.h"
46
47#define DRV_NAME "tegra20-i2s"
48
49static inline void tegra20_i2s_write(struct tegra20_i2s *i2s, u32 reg, u32 val)
50{
51 regmap_write(i2s->regmap, reg, val);
52}
53
54static inline u32 tegra20_i2s_read(struct tegra20_i2s *i2s, u32 reg)
55{
56 u32 val;
57 regmap_read(i2s->regmap, reg, &val);
58 return val;
59}
60
61static int tegra20_i2s_runtime_suspend(struct device *dev)
62{
63 struct tegra20_i2s *i2s = dev_get_drvdata(dev);
64
65 clk_disable(i2s->clk_i2s);
66
67 return 0;
68}
69
70static int tegra20_i2s_runtime_resume(struct device *dev)
71{
72 struct tegra20_i2s *i2s = dev_get_drvdata(dev);
73 int ret;
74
75 ret = clk_enable(i2s->clk_i2s);
76 if (ret) {
77 dev_err(dev, "clk_enable failed: %d\n", ret);
78 return ret;
79 }
80
81 return 0;
82}
83
84static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
85 unsigned int fmt)
86{
87 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
88
89 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
90 case SND_SOC_DAIFMT_NB_NF:
91 break;
92 default:
93 return -EINVAL;
94 }
95
96 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_MASTER_ENABLE;
97 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
98 case SND_SOC_DAIFMT_CBS_CFS:
99 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_MASTER_ENABLE;
100 break;
101 case SND_SOC_DAIFMT_CBM_CFM:
102 break;
103 default:
104 return -EINVAL;
105 }
106
107 i2s->reg_ctrl &= ~(TEGRA20_I2S_CTRL_BIT_FORMAT_MASK |
108 TEGRA20_I2S_CTRL_LRCK_MASK);
109 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
110 case SND_SOC_DAIFMT_DSP_A:
111 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP;
112 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
113 break;
114 case SND_SOC_DAIFMT_DSP_B:
115 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP;
116 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_R_LOW;
117 break;
118 case SND_SOC_DAIFMT_I2S:
119 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S;
120 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
121 break;
122 case SND_SOC_DAIFMT_RIGHT_J:
123 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM;
124 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
125 break;
126 case SND_SOC_DAIFMT_LEFT_J:
127 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM;
128 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
129 break;
130 default:
131 return -EINVAL;
132 }
133
134 return 0;
135}
136
137static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream,
138 struct snd_pcm_hw_params *params,
139 struct snd_soc_dai *dai)
140{
141 struct device *dev = substream->pcm->card->dev;
142 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
143 u32 reg;
144 int ret, sample_size, srate, i2sclock, bitcnt;
145
146 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_BIT_SIZE_MASK;
147 switch (params_format(params)) {
148 case SNDRV_PCM_FORMAT_S16_LE:
149 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_16;
150 sample_size = 16;
151 break;
152 case SNDRV_PCM_FORMAT_S24_LE:
153 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_24;
154 sample_size = 24;
155 break;
156 case SNDRV_PCM_FORMAT_S32_LE:
157 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_32;
158 sample_size = 32;
159 break;
160 default:
161 return -EINVAL;
162 }
163
164 srate = params_rate(params);
165
166 /* Final "* 2" required by Tegra hardware */
167 i2sclock = srate * params_channels(params) * sample_size * 2;
168
169 ret = clk_set_rate(i2s->clk_i2s, i2sclock);
170 if (ret) {
171 dev_err(dev, "Can't set I2S clock rate: %d\n", ret);
172 return ret;
173 }
174
175 bitcnt = (i2sclock / (2 * srate)) - 1;
176 if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US)
177 return -EINVAL;
178 reg = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT;
179
180 if (i2sclock % (2 * srate))
181 reg |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE;
182
183 tegra20_i2s_write(i2s, TEGRA20_I2S_TIMING, reg);
184
185 tegra20_i2s_write(i2s, TEGRA20_I2S_FIFO_SCR,
186 TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS |
187 TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS);
188
189 return 0;
190}
191
192static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s)
193{
194 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO1_ENABLE;
195 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl);
196}
197
198static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s)
199{
200 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO1_ENABLE;
201 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl);
202}
203
204static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s)
205{
206 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO2_ENABLE;
207 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl);
208}
209
210static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s)
211{
212 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO2_ENABLE;
213 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl);
214}
215
216static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
217 struct snd_soc_dai *dai)
218{
219 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
220
221 switch (cmd) {
222 case SNDRV_PCM_TRIGGER_START:
223 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
224 case SNDRV_PCM_TRIGGER_RESUME:
225 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
226 tegra20_i2s_start_playback(i2s);
227 else
228 tegra20_i2s_start_capture(i2s);
229 break;
230 case SNDRV_PCM_TRIGGER_STOP:
231 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
232 case SNDRV_PCM_TRIGGER_SUSPEND:
233 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
234 tegra20_i2s_stop_playback(i2s);
235 else
236 tegra20_i2s_stop_capture(i2s);
237 break;
238 default:
239 return -EINVAL;
240 }
241
242 return 0;
243}
244
245static int tegra20_i2s_probe(struct snd_soc_dai *dai)
246{
247 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
248
249 dai->capture_dma_data = &i2s->capture_dma_data;
250 dai->playback_dma_data = &i2s->playback_dma_data;
251
252 return 0;
253}
254
255static const struct snd_soc_dai_ops tegra20_i2s_dai_ops = {
256 .set_fmt = tegra20_i2s_set_fmt,
257 .hw_params = tegra20_i2s_hw_params,
258 .trigger = tegra20_i2s_trigger,
259};
260
261static const struct snd_soc_dai_driver tegra20_i2s_dai_template = {
262 .probe = tegra20_i2s_probe,
263 .playback = {
264 .channels_min = 2,
265 .channels_max = 2,
266 .rates = SNDRV_PCM_RATE_8000_96000,
267 .formats = SNDRV_PCM_FMTBIT_S16_LE,
268 },
269 .capture = {
270 .channels_min = 2,
271 .channels_max = 2,
272 .rates = SNDRV_PCM_RATE_8000_96000,
273 .formats = SNDRV_PCM_FMTBIT_S16_LE,
274 },
275 .ops = &tegra20_i2s_dai_ops,
276 .symmetric_rates = 1,
277};
278
279static bool tegra20_i2s_wr_rd_reg(struct device *dev, unsigned int reg)
280{
281 switch (reg) {
282 case TEGRA20_I2S_CTRL:
283 case TEGRA20_I2S_STATUS:
284 case TEGRA20_I2S_TIMING:
285 case TEGRA20_I2S_FIFO_SCR:
286 case TEGRA20_I2S_PCM_CTRL:
287 case TEGRA20_I2S_NW_CTRL:
288 case TEGRA20_I2S_TDM_CTRL:
289 case TEGRA20_I2S_TDM_TX_RX_CTRL:
290 case TEGRA20_I2S_FIFO1:
291 case TEGRA20_I2S_FIFO2:
292 return true;
293 default:
294 return false;
295 };
296}
297
298static bool tegra20_i2s_volatile_reg(struct device *dev, unsigned int reg)
299{
300 switch (reg) {
301 case TEGRA20_I2S_STATUS:
302 case TEGRA20_I2S_FIFO_SCR:
303 case TEGRA20_I2S_FIFO1:
304 case TEGRA20_I2S_FIFO2:
305 return true;
306 default:
307 return false;
308 };
309}
310
311static bool tegra20_i2s_precious_reg(struct device *dev, unsigned int reg)
312{
313 switch (reg) {
314 case TEGRA20_I2S_FIFO1:
315 case TEGRA20_I2S_FIFO2:
316 return true;
317 default:
318 return false;
319 };
320}
321
322static const struct regmap_config tegra20_i2s_regmap_config = {
323 .reg_bits = 32,
324 .reg_stride = 4,
325 .val_bits = 32,
326 .max_register = TEGRA20_I2S_FIFO2,
327 .writeable_reg = tegra20_i2s_wr_rd_reg,
328 .readable_reg = tegra20_i2s_wr_rd_reg,
329 .volatile_reg = tegra20_i2s_volatile_reg,
330 .precious_reg = tegra20_i2s_precious_reg,
331 .cache_type = REGCACHE_RBTREE,
332};
333
334static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev)
335{
336 struct tegra20_i2s *i2s;
337 struct resource *mem, *memregion, *dmareq;
338 u32 of_dma[2];
339 u32 dma_ch;
340 void __iomem *regs;
341 int ret;
342
343 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_i2s), GFP_KERNEL);
344 if (!i2s) {
345 dev_err(&pdev->dev, "Can't allocate tegra20_i2s\n");
346 ret = -ENOMEM;
347 goto err;
348 }
349 dev_set_drvdata(&pdev->dev, i2s);
350
351 i2s->dai = tegra20_i2s_dai_template;
352 i2s->dai.name = dev_name(&pdev->dev);
353
354 i2s->clk_i2s = clk_get(&pdev->dev, NULL);
355 if (IS_ERR(i2s->clk_i2s)) {
356 dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
357 ret = PTR_ERR(i2s->clk_i2s);
358 goto err;
359 }
360
361 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
362 if (!mem) {
363 dev_err(&pdev->dev, "No memory resource\n");
364 ret = -ENODEV;
365 goto err_clk_put;
366 }
367
368 dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
369 if (!dmareq) {
370 if (of_property_read_u32_array(pdev->dev.of_node,
371 "nvidia,dma-request-selector",
372 of_dma, 2) < 0) {
373 dev_err(&pdev->dev, "No DMA resource\n");
374 ret = -ENODEV;
375 goto err_clk_put;
376 }
377 dma_ch = of_dma[1];
378 } else {
379 dma_ch = dmareq->start;
380 }
381
382 memregion = devm_request_mem_region(&pdev->dev, mem->start,
383 resource_size(mem), DRV_NAME);
384 if (!memregion) {
385 dev_err(&pdev->dev, "Memory region already claimed\n");
386 ret = -EBUSY;
387 goto err_clk_put;
388 }
389
390 regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
391 if (!regs) {
392 dev_err(&pdev->dev, "ioremap failed\n");
393 ret = -ENOMEM;
394 goto err_clk_put;
395 }
396
397 i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
398 &tegra20_i2s_regmap_config);
399 if (IS_ERR(i2s->regmap)) {
400 dev_err(&pdev->dev, "regmap init failed\n");
401 ret = PTR_ERR(i2s->regmap);
402 goto err_clk_put;
403 }
404
405 i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2;
406 i2s->capture_dma_data.wrap = 4;
407 i2s->capture_dma_data.width = 32;
408 i2s->capture_dma_data.req_sel = dma_ch;
409
410 i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1;
411 i2s->playback_dma_data.wrap = 4;
412 i2s->playback_dma_data.width = 32;
413 i2s->playback_dma_data.req_sel = dma_ch;
414
415 i2s->reg_ctrl = TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED;
416
417 pm_runtime_enable(&pdev->dev);
418 if (!pm_runtime_enabled(&pdev->dev)) {
419 ret = tegra20_i2s_runtime_resume(&pdev->dev);
420 if (ret)
421 goto err_pm_disable;
422 }
423
424 ret = snd_soc_register_dai(&pdev->dev, &i2s->dai);
425 if (ret) {
426 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
427 ret = -ENOMEM;
428 goto err_suspend;
429 }
430
431 ret = tegra_pcm_platform_register(&pdev->dev);
432 if (ret) {
433 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
434 goto err_unregister_dai;
435 }
436
437 return 0;
438
439err_unregister_dai:
440 snd_soc_unregister_dai(&pdev->dev);
441err_suspend:
442 if (!pm_runtime_status_suspended(&pdev->dev))
443 tegra20_i2s_runtime_suspend(&pdev->dev);
444err_pm_disable:
445 pm_runtime_disable(&pdev->dev);
446err_clk_put:
447 clk_put(i2s->clk_i2s);
448err:
449 return ret;
450}
451
452static int __devexit tegra20_i2s_platform_remove(struct platform_device *pdev)
453{
454 struct tegra20_i2s *i2s = dev_get_drvdata(&pdev->dev);
455
456 pm_runtime_disable(&pdev->dev);
457 if (!pm_runtime_status_suspended(&pdev->dev))
458 tegra20_i2s_runtime_suspend(&pdev->dev);
459
460 tegra_pcm_platform_unregister(&pdev->dev);
461 snd_soc_unregister_dai(&pdev->dev);
462
463 clk_put(i2s->clk_i2s);
464
465 return 0;
466}
467
468static const struct of_device_id tegra20_i2s_of_match[] __devinitconst = {
469 { .compatible = "nvidia,tegra20-i2s", },
470 {},
471};
472
473static const struct dev_pm_ops tegra20_i2s_pm_ops __devinitconst = {
474 SET_RUNTIME_PM_OPS(tegra20_i2s_runtime_suspend,
475 tegra20_i2s_runtime_resume, NULL)
476};
477
478static struct platform_driver tegra20_i2s_driver = {
479 .driver = {
480 .name = DRV_NAME,
481 .owner = THIS_MODULE,
482 .of_match_table = tegra20_i2s_of_match,
483 .pm = &tegra20_i2s_pm_ops,
484 },
485 .probe = tegra20_i2s_platform_probe,
486 .remove = __devexit_p(tegra20_i2s_platform_remove),
487};
488module_platform_driver(tegra20_i2s_driver);
489
490MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
491MODULE_DESCRIPTION("Tegra20 I2S ASoC driver");
492MODULE_LICENSE("GPL");
493MODULE_ALIAS("platform:" DRV_NAME);
494MODULE_DEVICE_TABLE(of, tegra20_i2s_of_match);
diff --git a/sound/soc/tegra/tegra20_i2s.h b/sound/soc/tegra/tegra20_i2s.h
new file mode 100644
index 000000000000..a57efc6a597e
--- /dev/null
+++ b/sound/soc/tegra/tegra20_i2s.h
@@ -0,0 +1,164 @@
1/*
2 * tegra20_i2s.h - Definitions for Tegra20 I2S driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2010, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 *
12 * Copyright (C) 2010 Google, Inc.
13 * Iliyan Malchev <malchev@google.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#ifndef __TEGRA20_I2S_H__
32#define __TEGRA20_I2S_H__
33
34#include "tegra_pcm.h"
35
36/* Register offsets from TEGRA20_I2S1_BASE and TEGRA20_I2S2_BASE */
37
38#define TEGRA20_I2S_CTRL 0x00
39#define TEGRA20_I2S_STATUS 0x04
40#define TEGRA20_I2S_TIMING 0x08
41#define TEGRA20_I2S_FIFO_SCR 0x0c
42#define TEGRA20_I2S_PCM_CTRL 0x10
43#define TEGRA20_I2S_NW_CTRL 0x14
44#define TEGRA20_I2S_TDM_CTRL 0x20
45#define TEGRA20_I2S_TDM_TX_RX_CTRL 0x24
46#define TEGRA20_I2S_FIFO1 0x40
47#define TEGRA20_I2S_FIFO2 0x80
48
49/* Fields in TEGRA20_I2S_CTRL */
50
51#define TEGRA20_I2S_CTRL_FIFO2_TX_ENABLE (1 << 30)
52#define TEGRA20_I2S_CTRL_FIFO1_ENABLE (1 << 29)
53#define TEGRA20_I2S_CTRL_FIFO2_ENABLE (1 << 28)
54#define TEGRA20_I2S_CTRL_FIFO1_RX_ENABLE (1 << 27)
55#define TEGRA20_I2S_CTRL_FIFO_LPBK_ENABLE (1 << 26)
56#define TEGRA20_I2S_CTRL_MASTER_ENABLE (1 << 25)
57
58#define TEGRA20_I2S_LRCK_LEFT_LOW 0
59#define TEGRA20_I2S_LRCK_RIGHT_LOW 1
60
61#define TEGRA20_I2S_CTRL_LRCK_SHIFT 24
62#define TEGRA20_I2S_CTRL_LRCK_MASK (1 << TEGRA20_I2S_CTRL_LRCK_SHIFT)
63#define TEGRA20_I2S_CTRL_LRCK_L_LOW (TEGRA20_I2S_LRCK_LEFT_LOW << TEGRA20_I2S_CTRL_LRCK_SHIFT)
64#define TEGRA20_I2S_CTRL_LRCK_R_LOW (TEGRA20_I2S_LRCK_RIGHT_LOW << TEGRA20_I2S_CTRL_LRCK_SHIFT)
65
66#define TEGRA20_I2S_BIT_FORMAT_I2S 0
67#define TEGRA20_I2S_BIT_FORMAT_RJM 1
68#define TEGRA20_I2S_BIT_FORMAT_LJM 2
69#define TEGRA20_I2S_BIT_FORMAT_DSP 3
70
71#define TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT 10
72#define TEGRA20_I2S_CTRL_BIT_FORMAT_MASK (3 << TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT)
73#define TEGRA20_I2S_CTRL_BIT_FORMAT_I2S (TEGRA20_I2S_BIT_FORMAT_I2S << TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT)
74#define TEGRA20_I2S_CTRL_BIT_FORMAT_RJM (TEGRA20_I2S_BIT_FORMAT_RJM << TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT)
75#define TEGRA20_I2S_CTRL_BIT_FORMAT_LJM (TEGRA20_I2S_BIT_FORMAT_LJM << TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT)
76#define TEGRA20_I2S_CTRL_BIT_FORMAT_DSP (TEGRA20_I2S_BIT_FORMAT_DSP << TEGRA20_I2S_CTRL_BIT_FORMAT_SHIFT)
77
78#define TEGRA20_I2S_BIT_SIZE_16 0
79#define TEGRA20_I2S_BIT_SIZE_20 1
80#define TEGRA20_I2S_BIT_SIZE_24 2
81#define TEGRA20_I2S_BIT_SIZE_32 3
82
83#define TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT 8
84#define TEGRA20_I2S_CTRL_BIT_SIZE_MASK (3 << TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT)
85#define TEGRA20_I2S_CTRL_BIT_SIZE_16 (TEGRA20_I2S_BIT_SIZE_16 << TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT)
86#define TEGRA20_I2S_CTRL_BIT_SIZE_20 (TEGRA20_I2S_BIT_SIZE_20 << TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT)
87#define TEGRA20_I2S_CTRL_BIT_SIZE_24 (TEGRA20_I2S_BIT_SIZE_24 << TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT)
88#define TEGRA20_I2S_CTRL_BIT_SIZE_32 (TEGRA20_I2S_BIT_SIZE_32 << TEGRA20_I2S_CTRL_BIT_SIZE_SHIFT)
89
90#define TEGRA20_I2S_FIFO_16_LSB 0
91#define TEGRA20_I2S_FIFO_20_LSB 1
92#define TEGRA20_I2S_FIFO_24_LSB 2
93#define TEGRA20_I2S_FIFO_32 3
94#define TEGRA20_I2S_FIFO_PACKED 7
95
96#define TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT 4
97#define TEGRA20_I2S_CTRL_FIFO_FORMAT_MASK (7 << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
98#define TEGRA20_I2S_CTRL_FIFO_FORMAT_16_LSB (TEGRA20_I2S_FIFO_16_LSB << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
99#define TEGRA20_I2S_CTRL_FIFO_FORMAT_20_LSB (TEGRA20_I2S_FIFO_20_LSB << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
100#define TEGRA20_I2S_CTRL_FIFO_FORMAT_24_LSB (TEGRA20_I2S_FIFO_24_LSB << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
101#define TEGRA20_I2S_CTRL_FIFO_FORMAT_32 (TEGRA20_I2S_FIFO_32 << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
102#define TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED (TEGRA20_I2S_FIFO_PACKED << TEGRA20_I2S_CTRL_FIFO_FORMAT_SHIFT)
103
104#define TEGRA20_I2S_CTRL_IE_FIFO1_ERR (1 << 3)
105#define TEGRA20_I2S_CTRL_IE_FIFO2_ERR (1 << 2)
106#define TEGRA20_I2S_CTRL_QE_FIFO1 (1 << 1)
107#define TEGRA20_I2S_CTRL_QE_FIFO2 (1 << 0)
108
109/* Fields in TEGRA20_I2S_STATUS */
110
111#define TEGRA20_I2S_STATUS_FIFO1_RDY (1 << 31)
112#define TEGRA20_I2S_STATUS_FIFO2_RDY (1 << 30)
113#define TEGRA20_I2S_STATUS_FIFO1_BSY (1 << 29)
114#define TEGRA20_I2S_STATUS_FIFO2_BSY (1 << 28)
115#define TEGRA20_I2S_STATUS_FIFO1_ERR (1 << 3)
116#define TEGRA20_I2S_STATUS_FIFO2_ERR (1 << 2)
117#define TEGRA20_I2S_STATUS_QS_FIFO1 (1 << 1)
118#define TEGRA20_I2S_STATUS_QS_FIFO2 (1 << 0)
119
120/* Fields in TEGRA20_I2S_TIMING */
121
122#define TEGRA20_I2S_TIMING_NON_SYM_ENABLE (1 << 12)
123#define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT 0
124#define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US 0x7fff
125#define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK (TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT)
126
127/* Fields in TEGRA20_I2S_FIFO_SCR */
128
129#define TEGRA20_I2S_FIFO_SCR_FIFO2_FULL_EMPTY_COUNT_SHIFT 24
130#define TEGRA20_I2S_FIFO_SCR_FIFO1_FULL_EMPTY_COUNT_SHIFT 16
131#define TEGRA20_I2S_FIFO_SCR_FIFO_FULL_EMPTY_COUNT_MASK 0x3f
132
133#define TEGRA20_I2S_FIFO_SCR_FIFO2_CLR (1 << 12)
134#define TEGRA20_I2S_FIFO_SCR_FIFO1_CLR (1 << 8)
135
136#define TEGRA20_I2S_FIFO_ATN_LVL_ONE_SLOT 0
137#define TEGRA20_I2S_FIFO_ATN_LVL_FOUR_SLOTS 1
138#define TEGRA20_I2S_FIFO_ATN_LVL_EIGHT_SLOTS 2
139#define TEGRA20_I2S_FIFO_ATN_LVL_TWELVE_SLOTS 3
140
141#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT 4
142#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_MASK (3 << TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
143#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_ONE_SLOT (TEGRA20_I2S_FIFO_ATN_LVL_ONE_SLOT << TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
144#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_FOUR_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
145#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_EIGHT_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_EIGHT_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
146#define TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_TWELVE_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
147
148#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT 0
149#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_MASK (3 << TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
150#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_ONE_SLOT (TEGRA20_I2S_FIFO_ATN_LVL_ONE_SLOT << TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
151#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_FOUR_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
152#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_EIGHT_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_EIGHT_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
153#define TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS (TEGRA20_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
154
155struct tegra20_i2s {
156 struct snd_soc_dai_driver dai;
157 struct clk *clk_i2s;
158 struct tegra_pcm_dma_params capture_dma_data;
159 struct tegra_pcm_dma_params playback_dma_data;
160 struct regmap *regmap;
161 u32 reg_ctrl;
162};
163
164#endif
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c
new file mode 100644
index 000000000000..f9b57418bd08
--- /dev/null
+++ b/sound/soc/tegra/tegra20_spdif.c
@@ -0,0 +1,404 @@
1/*
2 * tegra20_spdif.c - Tegra20 SPDIF driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2011-2012 - NVIDIA, Inc.
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 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include <linux/clk.h>
24#include <linux/device.h>
25#include <linux/io.h>
26#include <linux/module.h>
27#include <linux/platform_device.h>
28#include <linux/pm_runtime.h>
29#include <linux/regmap.h>
30#include <linux/slab.h>
31#include <sound/core.h>
32#include <sound/pcm.h>
33#include <sound/pcm_params.h>
34#include <sound/soc.h>
35
36#include "tegra20_spdif.h"
37
38#define DRV_NAME "tegra20-spdif"
39
40static inline void tegra20_spdif_write(struct tegra20_spdif *spdif, u32 reg,
41 u32 val)
42{
43 regmap_write(spdif->regmap, reg, val);
44}
45
46static inline u32 tegra20_spdif_read(struct tegra20_spdif *spdif, u32 reg)
47{
48 u32 val;
49 regmap_read(spdif->regmap, reg, &val);
50 return val;
51}
52
53static int tegra20_spdif_runtime_suspend(struct device *dev)
54{
55 struct tegra20_spdif *spdif = dev_get_drvdata(dev);
56
57 clk_disable(spdif->clk_spdif_out);
58
59 return 0;
60}
61
62static int tegra20_spdif_runtime_resume(struct device *dev)
63{
64 struct tegra20_spdif *spdif = dev_get_drvdata(dev);
65 int ret;
66
67 ret = clk_enable(spdif->clk_spdif_out);
68 if (ret) {
69 dev_err(dev, "clk_enable failed: %d\n", ret);
70 return ret;
71 }
72
73 return 0;
74}
75
76static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream,
77 struct snd_pcm_hw_params *params,
78 struct snd_soc_dai *dai)
79{
80 struct device *dev = substream->pcm->card->dev;
81 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
82 int ret, spdifclock;
83
84 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_PACK;
85 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_BIT_MODE_MASK;
86 switch (params_format(params)) {
87 case SNDRV_PCM_FORMAT_S16_LE:
88 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_PACK;
89 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT;
90 break;
91 default:
92 return -EINVAL;
93 }
94
95 switch (params_rate(params)) {
96 case 32000:
97 spdifclock = 4096000;
98 break;
99 case 44100:
100 spdifclock = 5644800;
101 break;
102 case 48000:
103 spdifclock = 6144000;
104 break;
105 case 88200:
106 spdifclock = 11289600;
107 break;
108 case 96000:
109 spdifclock = 12288000;
110 break;
111 case 176400:
112 spdifclock = 22579200;
113 break;
114 case 192000:
115 spdifclock = 24576000;
116 break;
117 default:
118 return -EINVAL;
119 }
120
121 ret = clk_set_rate(spdif->clk_spdif_out, spdifclock);
122 if (ret) {
123 dev_err(dev, "Can't set SPDIF clock rate: %d\n", ret);
124 return ret;
125 }
126
127 return 0;
128}
129
130static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif)
131{
132 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_TX_EN;
133 tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl);
134}
135
136static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif)
137{
138 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_TX_EN;
139 tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl);
140}
141
142static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
143 struct snd_soc_dai *dai)
144{
145 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
146
147 switch (cmd) {
148 case SNDRV_PCM_TRIGGER_START:
149 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
150 case SNDRV_PCM_TRIGGER_RESUME:
151 tegra20_spdif_start_playback(spdif);
152 break;
153 case SNDRV_PCM_TRIGGER_STOP:
154 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
155 case SNDRV_PCM_TRIGGER_SUSPEND:
156 tegra20_spdif_stop_playback(spdif);
157 break;
158 default:
159 return -EINVAL;
160 }
161
162 return 0;
163}
164
165static int tegra20_spdif_probe(struct snd_soc_dai *dai)
166{
167 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
168
169 dai->capture_dma_data = NULL;
170 dai->playback_dma_data = &spdif->playback_dma_data;
171
172 return 0;
173}
174
175static const struct snd_soc_dai_ops tegra20_spdif_dai_ops = {
176 .hw_params = tegra20_spdif_hw_params,
177 .trigger = tegra20_spdif_trigger,
178};
179
180static struct snd_soc_dai_driver tegra20_spdif_dai = {
181 .name = DRV_NAME,
182 .probe = tegra20_spdif_probe,
183 .playback = {
184 .channels_min = 2,
185 .channels_max = 2,
186 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
187 SNDRV_PCM_RATE_48000,
188 .formats = SNDRV_PCM_FMTBIT_S16_LE,
189 },
190 .ops = &tegra20_spdif_dai_ops,
191};
192
193static bool tegra20_spdif_wr_rd_reg(struct device *dev, unsigned int reg)
194{
195 switch (reg) {
196 case TEGRA20_SPDIF_CTRL:
197 case TEGRA20_SPDIF_STATUS:
198 case TEGRA20_SPDIF_STROBE_CTRL:
199 case TEGRA20_SPDIF_DATA_FIFO_CSR:
200 case TEGRA20_SPDIF_DATA_OUT:
201 case TEGRA20_SPDIF_DATA_IN:
202 case TEGRA20_SPDIF_CH_STA_RX_A:
203 case TEGRA20_SPDIF_CH_STA_RX_B:
204 case TEGRA20_SPDIF_CH_STA_RX_C:
205 case TEGRA20_SPDIF_CH_STA_RX_D:
206 case TEGRA20_SPDIF_CH_STA_RX_E:
207 case TEGRA20_SPDIF_CH_STA_RX_F:
208 case TEGRA20_SPDIF_CH_STA_TX_A:
209 case TEGRA20_SPDIF_CH_STA_TX_B:
210 case TEGRA20_SPDIF_CH_STA_TX_C:
211 case TEGRA20_SPDIF_CH_STA_TX_D:
212 case TEGRA20_SPDIF_CH_STA_TX_E:
213 case TEGRA20_SPDIF_CH_STA_TX_F:
214 case TEGRA20_SPDIF_USR_STA_RX_A:
215 case TEGRA20_SPDIF_USR_DAT_TX_A:
216 return true;
217 default:
218 return false;
219 };
220}
221
222static bool tegra20_spdif_volatile_reg(struct device *dev, unsigned int reg)
223{
224 switch (reg) {
225 case TEGRA20_SPDIF_STATUS:
226 case TEGRA20_SPDIF_DATA_FIFO_CSR:
227 case TEGRA20_SPDIF_DATA_OUT:
228 case TEGRA20_SPDIF_DATA_IN:
229 case TEGRA20_SPDIF_CH_STA_RX_A:
230 case TEGRA20_SPDIF_CH_STA_RX_B:
231 case TEGRA20_SPDIF_CH_STA_RX_C:
232 case TEGRA20_SPDIF_CH_STA_RX_D:
233 case TEGRA20_SPDIF_CH_STA_RX_E:
234 case TEGRA20_SPDIF_CH_STA_RX_F:
235 case TEGRA20_SPDIF_USR_STA_RX_A:
236 case TEGRA20_SPDIF_USR_DAT_TX_A:
237 return true;
238 default:
239 return false;
240 };
241}
242
243static bool tegra20_spdif_precious_reg(struct device *dev, unsigned int reg)
244{
245 switch (reg) {
246 case TEGRA20_SPDIF_DATA_OUT:
247 case TEGRA20_SPDIF_DATA_IN:
248 case TEGRA20_SPDIF_USR_STA_RX_A:
249 case TEGRA20_SPDIF_USR_DAT_TX_A:
250 return true;
251 default:
252 return false;
253 };
254}
255
256static const struct regmap_config tegra20_spdif_regmap_config = {
257 .reg_bits = 32,
258 .reg_stride = 4,
259 .val_bits = 32,
260 .max_register = TEGRA20_SPDIF_USR_DAT_TX_A,
261 .writeable_reg = tegra20_spdif_wr_rd_reg,
262 .readable_reg = tegra20_spdif_wr_rd_reg,
263 .volatile_reg = tegra20_spdif_volatile_reg,
264 .precious_reg = tegra20_spdif_precious_reg,
265 .cache_type = REGCACHE_RBTREE,
266};
267
268static __devinit int tegra20_spdif_platform_probe(struct platform_device *pdev)
269{
270 struct tegra20_spdif *spdif;
271 struct resource *mem, *memregion, *dmareq;
272 void __iomem *regs;
273 int ret;
274
275 spdif = devm_kzalloc(&pdev->dev, sizeof(struct tegra20_spdif),
276 GFP_KERNEL);
277 if (!spdif) {
278 dev_err(&pdev->dev, "Can't allocate tegra20_spdif\n");
279 ret = -ENOMEM;
280 goto err;
281 }
282 dev_set_drvdata(&pdev->dev, spdif);
283
284 spdif->clk_spdif_out = clk_get(&pdev->dev, "spdif_out");
285 if (IS_ERR(spdif->clk_spdif_out)) {
286 pr_err("Can't retrieve spdif clock\n");
287 ret = PTR_ERR(spdif->clk_spdif_out);
288 goto err;
289 }
290
291 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
292 if (!mem) {
293 dev_err(&pdev->dev, "No memory resource\n");
294 ret = -ENODEV;
295 goto err_clk_put;
296 }
297
298 dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
299 if (!dmareq) {
300 dev_err(&pdev->dev, "No DMA resource\n");
301 ret = -ENODEV;
302 goto err_clk_put;
303 }
304
305 memregion = devm_request_mem_region(&pdev->dev, mem->start,
306 resource_size(mem), DRV_NAME);
307 if (!memregion) {
308 dev_err(&pdev->dev, "Memory region already claimed\n");
309 ret = -EBUSY;
310 goto err_clk_put;
311 }
312
313 regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
314 if (!regs) {
315 dev_err(&pdev->dev, "ioremap failed\n");
316 ret = -ENOMEM;
317 goto err_clk_put;
318 }
319
320 spdif->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
321 &tegra20_spdif_regmap_config);
322 if (IS_ERR(spdif->regmap)) {
323 dev_err(&pdev->dev, "regmap init failed\n");
324 ret = PTR_ERR(spdif->regmap);
325 goto err_clk_put;
326 }
327
328 spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT;
329 spdif->playback_dma_data.wrap = 4;
330 spdif->playback_dma_data.width = 32;
331 spdif->playback_dma_data.req_sel = dmareq->start;
332
333 pm_runtime_enable(&pdev->dev);
334 if (!pm_runtime_enabled(&pdev->dev)) {
335 ret = tegra20_spdif_runtime_resume(&pdev->dev);
336 if (ret)
337 goto err_pm_disable;
338 }
339
340 ret = snd_soc_register_dai(&pdev->dev, &tegra20_spdif_dai);
341 if (ret) {
342 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
343 ret = -ENOMEM;
344 goto err_suspend;
345 }
346
347 ret = tegra_pcm_platform_register(&pdev->dev);
348 if (ret) {
349 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
350 goto err_unregister_dai;
351 }
352
353 return 0;
354
355err_unregister_dai:
356 snd_soc_unregister_dai(&pdev->dev);
357err_suspend:
358 if (!pm_runtime_status_suspended(&pdev->dev))
359 tegra20_spdif_runtime_suspend(&pdev->dev);
360err_pm_disable:
361 pm_runtime_disable(&pdev->dev);
362err_clk_put:
363 clk_put(spdif->clk_spdif_out);
364err:
365 return ret;
366}
367
368static int __devexit tegra20_spdif_platform_remove(struct platform_device *pdev)
369{
370 struct tegra20_spdif *spdif = dev_get_drvdata(&pdev->dev);
371
372 pm_runtime_disable(&pdev->dev);
373 if (!pm_runtime_status_suspended(&pdev->dev))
374 tegra20_spdif_runtime_suspend(&pdev->dev);
375
376 tegra_pcm_platform_unregister(&pdev->dev);
377 snd_soc_unregister_dai(&pdev->dev);
378
379 clk_put(spdif->clk_spdif_out);
380
381 return 0;
382}
383
384static const struct dev_pm_ops tegra20_spdif_pm_ops __devinitconst = {
385 SET_RUNTIME_PM_OPS(tegra20_spdif_runtime_suspend,
386 tegra20_spdif_runtime_resume, NULL)
387};
388
389static struct platform_driver tegra20_spdif_driver = {
390 .driver = {
391 .name = DRV_NAME,
392 .owner = THIS_MODULE,
393 .pm = &tegra20_spdif_pm_ops,
394 },
395 .probe = tegra20_spdif_platform_probe,
396 .remove = __devexit_p(tegra20_spdif_platform_remove),
397};
398
399module_platform_driver(tegra20_spdif_driver);
400
401MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
402MODULE_DESCRIPTION("Tegra20 SPDIF ASoC driver");
403MODULE_LICENSE("GPL");
404MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra20_spdif.h b/sound/soc/tegra/tegra20_spdif.h
new file mode 100644
index 000000000000..ed756527efea
--- /dev/null
+++ b/sound/soc/tegra/tegra20_spdif.h
@@ -0,0 +1,471 @@
1/*
2 * tegra20_spdif.h - Definitions for Tegra20 SPDIF driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2011 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 * Copyright (c) 2008-2009, NVIDIA Corporation
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 */
25
26#ifndef __TEGRA20_SPDIF_H__
27#define __TEGRA20_SPDIF_H__
28
29#include "tegra_pcm.h"
30
31/* Offsets from TEGRA20_SPDIF_BASE */
32
33#define TEGRA20_SPDIF_CTRL 0x0
34#define TEGRA20_SPDIF_STATUS 0x4
35#define TEGRA20_SPDIF_STROBE_CTRL 0x8
36#define TEGRA20_SPDIF_DATA_FIFO_CSR 0x0C
37#define TEGRA20_SPDIF_DATA_OUT 0x40
38#define TEGRA20_SPDIF_DATA_IN 0x80
39#define TEGRA20_SPDIF_CH_STA_RX_A 0x100
40#define TEGRA20_SPDIF_CH_STA_RX_B 0x104
41#define TEGRA20_SPDIF_CH_STA_RX_C 0x108
42#define TEGRA20_SPDIF_CH_STA_RX_D 0x10C
43#define TEGRA20_SPDIF_CH_STA_RX_E 0x110
44#define TEGRA20_SPDIF_CH_STA_RX_F 0x114
45#define TEGRA20_SPDIF_CH_STA_TX_A 0x140
46#define TEGRA20_SPDIF_CH_STA_TX_B 0x144
47#define TEGRA20_SPDIF_CH_STA_TX_C 0x148
48#define TEGRA20_SPDIF_CH_STA_TX_D 0x14C
49#define TEGRA20_SPDIF_CH_STA_TX_E 0x150
50#define TEGRA20_SPDIF_CH_STA_TX_F 0x154
51#define TEGRA20_SPDIF_USR_STA_RX_A 0x180
52#define TEGRA20_SPDIF_USR_DAT_TX_A 0x1C0
53
54/* Fields in TEGRA20_SPDIF_CTRL */
55
56/* Start capturing from 0=right, 1=left channel */
57#define TEGRA20_SPDIF_CTRL_CAP_LC (1 << 30)
58
59/* SPDIF receiver(RX) enable */
60#define TEGRA20_SPDIF_CTRL_RX_EN (1 << 29)
61
62/* SPDIF Transmitter(TX) enable */
63#define TEGRA20_SPDIF_CTRL_TX_EN (1 << 28)
64
65/* Transmit Channel status */
66#define TEGRA20_SPDIF_CTRL_TC_EN (1 << 27)
67
68/* Transmit user Data */
69#define TEGRA20_SPDIF_CTRL_TU_EN (1 << 26)
70
71/* Interrupt on transmit error */
72#define TEGRA20_SPDIF_CTRL_IE_TXE (1 << 25)
73
74/* Interrupt on receive error */
75#define TEGRA20_SPDIF_CTRL_IE_RXE (1 << 24)
76
77/* Interrupt on invalid preamble */
78#define TEGRA20_SPDIF_CTRL_IE_P (1 << 23)
79
80/* Interrupt on "B" preamble */
81#define TEGRA20_SPDIF_CTRL_IE_B (1 << 22)
82
83/* Interrupt when block of channel status received */
84#define TEGRA20_SPDIF_CTRL_IE_C (1 << 21)
85
86/* Interrupt when a valid information unit (IU) is received */
87#define TEGRA20_SPDIF_CTRL_IE_U (1 << 20)
88
89/* Interrupt when RX user FIFO attention level is reached */
90#define TEGRA20_SPDIF_CTRL_QE_RU (1 << 19)
91
92/* Interrupt when TX user FIFO attention level is reached */
93#define TEGRA20_SPDIF_CTRL_QE_TU (1 << 18)
94
95/* Interrupt when RX data FIFO attention level is reached */
96#define TEGRA20_SPDIF_CTRL_QE_RX (1 << 17)
97
98/* Interrupt when TX data FIFO attention level is reached */
99#define TEGRA20_SPDIF_CTRL_QE_TX (1 << 16)
100
101/* Loopback test mode enable */
102#define TEGRA20_SPDIF_CTRL_LBK_EN (1 << 15)
103
104/*
105 * Pack data mode:
106 * 0 = Single data (16 bit needs to be padded to match the
107 * interface data bit size).
108 * 1 = Packeted left/right channel data into a single word.
109 */
110#define TEGRA20_SPDIF_CTRL_PACK (1 << 14)
111
112/*
113 * 00 = 16bit data
114 * 01 = 20bit data
115 * 10 = 24bit data
116 * 11 = raw data
117 */
118#define TEGRA20_SPDIF_BIT_MODE_16BIT 0
119#define TEGRA20_SPDIF_BIT_MODE_20BIT 1
120#define TEGRA20_SPDIF_BIT_MODE_24BIT 2
121#define TEGRA20_SPDIF_BIT_MODE_RAW 3
122
123#define TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT 12
124#define TEGRA20_SPDIF_CTRL_BIT_MODE_MASK (3 << TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT)
125#define TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT (TEGRA20_SPDIF_BIT_MODE_16BIT << TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT)
126#define TEGRA20_SPDIF_CTRL_BIT_MODE_20BIT (TEGRA20_SPDIF_BIT_MODE_20BIT << TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT)
127#define TEGRA20_SPDIF_CTRL_BIT_MODE_24BIT (TEGRA20_SPDIF_BIT_MODE_24BIT << TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT)
128#define TEGRA20_SPDIF_CTRL_BIT_MODE_RAW (TEGRA20_SPDIF_BIT_MODE_RAW << TEGRA20_SPDIF_CTRL_BIT_MODE_SHIFT)
129
130/* Fields in TEGRA20_SPDIF_STATUS */
131
132/*
133 * Note: IS_P, IS_B, IS_C, and IS_U are sticky bits. Software must
134 * write a 1 to the corresponding bit location to clear the status.
135 */
136
137/*
138 * Receiver(RX) shifter is busy receiving data.
139 * This bit is asserted when the receiver first locked onto the
140 * preamble of the data stream after RX_EN is asserted. This bit is
141 * deasserted when either,
142 * (a) the end of a frame is reached after RX_EN is deeasserted, or
143 * (b) the SPDIF data stream becomes inactive.
144 */
145#define TEGRA20_SPDIF_STATUS_RX_BSY (1 << 29)
146
147/*
148 * Transmitter(TX) shifter is busy transmitting data.
149 * This bit is asserted when TX_EN is asserted.
150 * This bit is deasserted when the end of a frame is reached after
151 * TX_EN is deasserted.
152 */
153#define TEGRA20_SPDIF_STATUS_TX_BSY (1 << 28)
154
155/*
156 * TX is busy shifting out channel status.
157 * This bit is asserted when both TX_EN and TC_EN are asserted and
158 * data from CH_STA_TX_A register is loaded into the internal shifter.
159 * This bit is deasserted when either,
160 * (a) the end of a frame is reached after TX_EN is deasserted, or
161 * (b) CH_STA_TX_F register is loaded into the internal shifter.
162 */
163#define TEGRA20_SPDIF_STATUS_TC_BSY (1 << 27)
164
165/*
166 * TX User data FIFO busy.
167 * This bit is asserted when TX_EN and TXU_EN are asserted and
168 * there's data in the TX user FIFO. This bit is deassert when either,
169 * (a) the end of a frame is reached after TX_EN is deasserted, or
170 * (b) there's no data left in the TX user FIFO.
171 */
172#define TEGRA20_SPDIF_STATUS_TU_BSY (1 << 26)
173
174/* TX FIFO Underrun error status */
175#define TEGRA20_SPDIF_STATUS_TX_ERR (1 << 25)
176
177/* RX FIFO Overrun error status */
178#define TEGRA20_SPDIF_STATUS_RX_ERR (1 << 24)
179
180/* Preamble status: 0=Preamble OK, 1=bad/missing preamble */
181#define TEGRA20_SPDIF_STATUS_IS_P (1 << 23)
182
183/* B-preamble detection status: 0=not detected, 1=B-preamble detected */
184#define TEGRA20_SPDIF_STATUS_IS_B (1 << 22)
185
186/*
187 * RX channel block data receive status:
188 * 0=entire block not recieved yet.
189 * 1=received entire block of channel status,
190 */
191#define TEGRA20_SPDIF_STATUS_IS_C (1 << 21)
192
193/* RX User Data Valid flag: 1=valid IU detected, 0 = no IU detected. */
194#define TEGRA20_SPDIF_STATUS_IS_U (1 << 20)
195
196/*
197 * RX User FIFO Status:
198 * 1=attention level reached, 0=attention level not reached.
199 */
200#define TEGRA20_SPDIF_STATUS_QS_RU (1 << 19)
201
202/*
203 * TX User FIFO Status:
204 * 1=attention level reached, 0=attention level not reached.
205 */
206#define TEGRA20_SPDIF_STATUS_QS_TU (1 << 18)
207
208/*
209 * RX Data FIFO Status:
210 * 1=attention level reached, 0=attention level not reached.
211 */
212#define TEGRA20_SPDIF_STATUS_QS_RX (1 << 17)
213
214/*
215 * TX Data FIFO Status:
216 * 1=attention level reached, 0=attention level not reached.
217 */
218#define TEGRA20_SPDIF_STATUS_QS_TX (1 << 16)
219
220/* Fields in TEGRA20_SPDIF_STROBE_CTRL */
221
222/*
223 * Indicates the approximate number of detected SPDIFIN clocks within a
224 * bi-phase period.
225 */
226#define TEGRA20_SPDIF_STROBE_CTRL_PERIOD_SHIFT 16
227#define TEGRA20_SPDIF_STROBE_CTRL_PERIOD_MASK (0xff << TEGRA20_SPDIF_STROBE_CTRL_PERIOD_SHIFT)
228
229/* Data strobe mode: 0=Auto-locked 1=Manual locked */
230#define TEGRA20_SPDIF_STROBE_CTRL_STROBE (1 << 15)
231
232/*
233 * Manual data strobe time within the bi-phase clock period (in terms of
234 * the number of over-sampling clocks).
235 */
236#define TEGRA20_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT 8
237#define TEGRA20_SPDIF_STROBE_CTRL_DATA_STROBES_MASK (0x1f << TEGRA20_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT)
238
239/*
240 * Manual SPDIFIN bi-phase clock period (in terms of the number of
241 * over-sampling clocks).
242 */
243#define TEGRA20_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT 0
244#define TEGRA20_SPDIF_STROBE_CTRL_CLOCK_PERIOD_MASK (0x3f << TEGRA20_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT)
245
246/* Fields in SPDIF_DATA_FIFO_CSR */
247
248/* Clear Receiver User FIFO (RX USR.FIFO) */
249#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_CLR (1 << 31)
250
251#define TEGRA20_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT 0
252#define TEGRA20_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS 1
253#define TEGRA20_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS 2
254#define TEGRA20_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS 3
255
256/* RU FIFO attention level */
257#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT 29
258#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_MASK \
259 (0x3 << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
260#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU1_WORD_FULL \
261 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
262#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU2_WORD_FULL \
263 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
264#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU3_WORD_FULL \
265 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
266#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU4_WORD_FULL \
267 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
268
269/* Number of RX USR.FIFO levels with valid data. */
270#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_SHIFT 24
271#define TEGRA20_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_MASK (0x1f << TEGRA20_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_SHIFT)
272
273/* Clear Transmitter User FIFO (TX USR.FIFO) */
274#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_CLR (1 << 23)
275
276/* TU FIFO attention level */
277#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT 21
278#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_MASK \
279 (0x3 << TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
280#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU1_WORD_FULL \
281 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT << TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
282#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU2_WORD_FULL \
283 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
284#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU3_WORD_FULL \
285 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
286#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU4_WORD_FULL \
287 (TEGRA20_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
288
289/* Number of TX USR.FIFO levels that could be filled. */
290#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_SHIFT 16
291#define TEGRA20_SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_MASK (0x1f << SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_SHIFT)
292
293/* Clear Receiver Data FIFO (RX DATA.FIFO) */
294#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_CLR (1 << 15)
295
296#define TEGRA20_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT 0
297#define TEGRA20_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS 1
298#define TEGRA20_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS 2
299#define TEGRA20_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS 3
300
301/* RU FIFO attention level */
302#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT 13
303#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_MASK \
304 (0x3 << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
305#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU1_WORD_FULL \
306 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
307#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU4_WORD_FULL \
308 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
309#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU8_WORD_FULL \
310 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
311#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU12_WORD_FULL \
312 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
313
314/* Number of RX DATA.FIFO levels with valid data. */
315#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_SHIFT 8
316#define TEGRA20_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_MASK (0x1f << TEGRA20_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_SHIFT)
317
318/* Clear Transmitter Data FIFO (TX DATA.FIFO) */
319#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_CLR (1 << 7)
320
321/* TU FIFO attention level */
322#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT 5
323#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_MASK \
324 (0x3 << TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
325#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU1_WORD_FULL \
326 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT << TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
327#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU4_WORD_FULL \
328 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
329#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU8_WORD_FULL \
330 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
331#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU12_WORD_FULL \
332 (TEGRA20_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS << TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
333
334/* Number of TX DATA.FIFO levels that could be filled. */
335#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_SHIFT 0
336#define TEGRA20_SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_MASK (0x1f << SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_SHIFT)
337
338/* Fields in TEGRA20_SPDIF_DATA_OUT */
339
340/*
341 * This register has 5 different formats:
342 * 16-bit (BIT_MODE=00, PACK=0)
343 * 20-bit (BIT_MODE=01, PACK=0)
344 * 24-bit (BIT_MODE=10, PACK=0)
345 * raw (BIT_MODE=11, PACK=0)
346 * 16-bit packed (BIT_MODE=00, PACK=1)
347 */
348
349#define TEGRA20_SPDIF_DATA_OUT_DATA_16_SHIFT 0
350#define TEGRA20_SPDIF_DATA_OUT_DATA_16_MASK (0xffff << TEGRA20_SPDIF_DATA_OUT_DATA_16_SHIFT)
351
352#define TEGRA20_SPDIF_DATA_OUT_DATA_20_SHIFT 0
353#define TEGRA20_SPDIF_DATA_OUT_DATA_20_MASK (0xfffff << TEGRA20_SPDIF_DATA_OUT_DATA_20_SHIFT)
354
355#define TEGRA20_SPDIF_DATA_OUT_DATA_24_SHIFT 0
356#define TEGRA20_SPDIF_DATA_OUT_DATA_24_MASK (0xffffff << TEGRA20_SPDIF_DATA_OUT_DATA_24_SHIFT)
357
358#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_P (1 << 31)
359#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_C (1 << 30)
360#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_U (1 << 29)
361#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_V (1 << 28)
362
363#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_DATA_SHIFT 8
364#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_DATA_MASK (0xfffff << TEGRA20_SPDIF_DATA_OUT_DATA_RAW_DATA_SHIFT)
365
366#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_AUX_SHIFT 4
367#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_AUX_MASK (0xf << TEGRA20_SPDIF_DATA_OUT_DATA_RAW_AUX_SHIFT)
368
369#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_SHIFT 0
370#define TEGRA20_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_MASK (0xf << TEGRA20_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_SHIFT)
371
372#define TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_SHIFT 16
373#define TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_MASK (0xffff << TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_SHIFT)
374
375#define TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_SHIFT 0
376#define TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_MASK (0xffff << TEGRA20_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_SHIFT)
377
378/* Fields in TEGRA20_SPDIF_DATA_IN */
379
380/*
381 * This register has 5 different formats:
382 * 16-bit (BIT_MODE=00, PACK=0)
383 * 20-bit (BIT_MODE=01, PACK=0)
384 * 24-bit (BIT_MODE=10, PACK=0)
385 * raw (BIT_MODE=11, PACK=0)
386 * 16-bit packed (BIT_MODE=00, PACK=1)
387 *
388 * Bits 31:24 are common to all modes except 16-bit packed
389 */
390
391#define TEGRA20_SPDIF_DATA_IN_DATA_P (1 << 31)
392#define TEGRA20_SPDIF_DATA_IN_DATA_C (1 << 30)
393#define TEGRA20_SPDIF_DATA_IN_DATA_U (1 << 29)
394#define TEGRA20_SPDIF_DATA_IN_DATA_V (1 << 28)
395
396#define TEGRA20_SPDIF_DATA_IN_DATA_PREAMBLE_SHIFT 24
397#define TEGRA20_SPDIF_DATA_IN_DATA_PREAMBLE_MASK (0xf << TEGRA20_SPDIF_DATA_IN_DATA_PREAMBLE_SHIFT)
398
399#define TEGRA20_SPDIF_DATA_IN_DATA_16_SHIFT 0
400#define TEGRA20_SPDIF_DATA_IN_DATA_16_MASK (0xffff << TEGRA20_SPDIF_DATA_IN_DATA_16_SHIFT)
401
402#define TEGRA20_SPDIF_DATA_IN_DATA_20_SHIFT 0
403#define TEGRA20_SPDIF_DATA_IN_DATA_20_MASK (0xfffff << TEGRA20_SPDIF_DATA_IN_DATA_20_SHIFT)
404
405#define TEGRA20_SPDIF_DATA_IN_DATA_24_SHIFT 0
406#define TEGRA20_SPDIF_DATA_IN_DATA_24_MASK (0xffffff << TEGRA20_SPDIF_DATA_IN_DATA_24_SHIFT)
407
408#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_DATA_SHIFT 8
409#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_DATA_MASK (0xfffff << TEGRA20_SPDIF_DATA_IN_DATA_RAW_DATA_SHIFT)
410
411#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_AUX_SHIFT 4
412#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_AUX_MASK (0xf << TEGRA20_SPDIF_DATA_IN_DATA_RAW_AUX_SHIFT)
413
414#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_SHIFT 0
415#define TEGRA20_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_MASK (0xf << TEGRA20_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_SHIFT)
416
417#define TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_SHIFT 16
418#define TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_MASK (0xffff << TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_SHIFT)
419
420#define TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_SHIFT 0
421#define TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_MASK (0xffff << TEGRA20_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_SHIFT)
422
423/* Fields in TEGRA20_SPDIF_CH_STA_RX_A */
424/* Fields in TEGRA20_SPDIF_CH_STA_RX_B */
425/* Fields in TEGRA20_SPDIF_CH_STA_RX_C */
426/* Fields in TEGRA20_SPDIF_CH_STA_RX_D */
427/* Fields in TEGRA20_SPDIF_CH_STA_RX_E */
428/* Fields in TEGRA20_SPDIF_CH_STA_RX_F */
429
430/*
431 * The 6-word receive channel data page buffer holds a block (192 frames) of
432 * channel status information. The order of receive is from LSB to MSB
433 * bit, and from CH_STA_RX_A to CH_STA_RX_F then back to CH_STA_RX_A.
434 */
435
436/* Fields in TEGRA20_SPDIF_CH_STA_TX_A */
437/* Fields in TEGRA20_SPDIF_CH_STA_TX_B */
438/* Fields in TEGRA20_SPDIF_CH_STA_TX_C */
439/* Fields in TEGRA20_SPDIF_CH_STA_TX_D */
440/* Fields in TEGRA20_SPDIF_CH_STA_TX_E */
441/* Fields in TEGRA20_SPDIF_CH_STA_TX_F */
442
443/*
444 * The 6-word transmit channel data page buffer holds a block (192 frames) of
445 * channel status information. The order of transmission is from LSB to MSB
446 * bit, and from CH_STA_TX_A to CH_STA_TX_F then back to CH_STA_TX_A.
447 */
448
449/* Fields in TEGRA20_SPDIF_USR_STA_RX_A */
450
451/*
452 * This 4-word deep FIFO receives user FIFO field information. The order of
453 * receive is from LSB to MSB bit.
454 */
455
456/* Fields in TEGRA20_SPDIF_USR_DAT_TX_A */
457
458/*
459 * This 4-word deep FIFO transmits user FIFO field information. The order of
460 * transmission is from LSB to MSB bit.
461 */
462
463struct tegra20_spdif {
464 struct clk *clk_spdif_out;
465 struct tegra_pcm_dma_params capture_dma_data;
466 struct tegra_pcm_dma_params playback_dma_data;
467 struct regmap *regmap;
468 u32 reg_ctrl;
469};
470
471#endif
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
new file mode 100644
index 000000000000..57cd419f743e
--- /dev/null
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -0,0 +1,631 @@
1/*
2 * tegra30_ahub.c - Tegra30 AHUB driver
3 *
4 * Copyright (c) 2011,2012, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/clk.h>
20#include <linux/device.h>
21#include <linux/io.h>
22#include <linux/module.h>
23#include <linux/of_platform.h>
24#include <linux/platform_device.h>
25#include <linux/pm_runtime.h>
26#include <linux/regmap.h>
27#include <linux/slab.h>
28#include <mach/clk.h>
29#include <mach/dma.h>
30#include <sound/soc.h>
31#include "tegra30_ahub.h"
32
33#define DRV_NAME "tegra30-ahub"
34
35static struct tegra30_ahub *ahub;
36
37static inline void tegra30_apbif_write(u32 reg, u32 val)
38{
39 regmap_write(ahub->regmap_apbif, reg, val);
40}
41
42static inline u32 tegra30_apbif_read(u32 reg)
43{
44 u32 val;
45 regmap_read(ahub->regmap_apbif, reg, &val);
46 return val;
47}
48
49static inline void tegra30_audio_write(u32 reg, u32 val)
50{
51 regmap_write(ahub->regmap_ahub, reg, val);
52}
53
54static int tegra30_ahub_runtime_suspend(struct device *dev)
55{
56 regcache_cache_only(ahub->regmap_apbif, true);
57 regcache_cache_only(ahub->regmap_ahub, true);
58
59 clk_disable(ahub->clk_apbif);
60 clk_disable(ahub->clk_d_audio);
61
62 return 0;
63}
64
65/*
66 * clk_apbif isn't required for an I2S<->I2S configuration where no PCM data
67 * is read from or sent to memory. However, that's not something the rest of
68 * the driver supports right now, so we'll just treat the two clocks as one
69 * for now.
70 *
71 * These functions should not be a plain ref-count. Instead, each active stream
72 * contributes some requirement to the minimum clock rate, so starting or
73 * stopping streams should dynamically adjust the clock as required. However,
74 * this is not yet implemented.
75 */
76static int tegra30_ahub_runtime_resume(struct device *dev)
77{
78 int ret;
79
80 ret = clk_enable(ahub->clk_d_audio);
81 if (ret) {
82 dev_err(dev, "clk_enable d_audio failed: %d\n", ret);
83 return ret;
84 }
85 ret = clk_enable(ahub->clk_apbif);
86 if (ret) {
87 dev_err(dev, "clk_enable apbif failed: %d\n", ret);
88 clk_disable(ahub->clk_d_audio);
89 return ret;
90 }
91
92 regcache_cache_only(ahub->regmap_apbif, false);
93 regcache_cache_only(ahub->regmap_ahub, false);
94
95 return 0;
96}
97
98int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
99 unsigned long *fiforeg,
100 unsigned long *reqsel)
101{
102 int channel;
103 u32 reg, val;
104
105 channel = find_first_zero_bit(ahub->rx_usage,
106 TEGRA30_AHUB_CHANNEL_CTRL_COUNT);
107 if (channel >= TEGRA30_AHUB_CHANNEL_CTRL_COUNT)
108 return -EBUSY;
109
110 __set_bit(channel, ahub->rx_usage);
111
112 *rxcif = TEGRA30_AHUB_RXCIF_APBIF_RX0 + channel;
113 *fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_RXFIFO +
114 (channel * TEGRA30_AHUB_CHANNEL_RXFIFO_STRIDE);
115 *reqsel = ahub->dma_sel + channel;
116
117 reg = TEGRA30_AHUB_CHANNEL_CTRL +
118 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
119 val = tegra30_apbif_read(reg);
120 val &= ~(TEGRA30_AHUB_CHANNEL_CTRL_RX_THRESHOLD_MASK |
121 TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_MASK);
122 val |= (7 << TEGRA30_AHUB_CHANNEL_CTRL_RX_THRESHOLD_SHIFT) |
123 TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_EN |
124 TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_16;
125 tegra30_apbif_write(reg, val);
126
127 reg = TEGRA30_AHUB_CIF_RX_CTRL +
128 (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE);
129 val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) |
130 (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) |
131 (1 << TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) |
132 TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_16 |
133 TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_16 |
134 TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX;
135 tegra30_apbif_write(reg, val);
136
137 return 0;
138}
139EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_rx_fifo);
140
141int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif)
142{
143 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
144 int reg, val;
145
146 reg = TEGRA30_AHUB_CHANNEL_CTRL +
147 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
148 val = tegra30_apbif_read(reg);
149 val |= TEGRA30_AHUB_CHANNEL_CTRL_RX_EN;
150 tegra30_apbif_write(reg, val);
151
152 return 0;
153}
154EXPORT_SYMBOL_GPL(tegra30_ahub_enable_rx_fifo);
155
156int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif)
157{
158 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
159 int reg, val;
160
161 reg = TEGRA30_AHUB_CHANNEL_CTRL +
162 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
163 val = tegra30_apbif_read(reg);
164 val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_EN;
165 tegra30_apbif_write(reg, val);
166
167 return 0;
168}
169EXPORT_SYMBOL_GPL(tegra30_ahub_disable_rx_fifo);
170
171int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif)
172{
173 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
174
175 __clear_bit(channel, ahub->rx_usage);
176
177 return 0;
178}
179EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo);
180
181int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
182 unsigned long *fiforeg,
183 unsigned long *reqsel)
184{
185 int channel;
186 u32 reg, val;
187
188 channel = find_first_zero_bit(ahub->tx_usage,
189 TEGRA30_AHUB_CHANNEL_CTRL_COUNT);
190 if (channel >= TEGRA30_AHUB_CHANNEL_CTRL_COUNT)
191 return -EBUSY;
192
193 __set_bit(channel, ahub->tx_usage);
194
195 *txcif = TEGRA30_AHUB_TXCIF_APBIF_TX0 + channel;
196 *fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_TXFIFO +
197 (channel * TEGRA30_AHUB_CHANNEL_TXFIFO_STRIDE);
198 *reqsel = ahub->dma_sel + channel;
199
200 reg = TEGRA30_AHUB_CHANNEL_CTRL +
201 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
202 val = tegra30_apbif_read(reg);
203 val &= ~(TEGRA30_AHUB_CHANNEL_CTRL_TX_THRESHOLD_MASK |
204 TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_MASK);
205 val |= (7 << TEGRA30_AHUB_CHANNEL_CTRL_TX_THRESHOLD_SHIFT) |
206 TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_EN |
207 TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_16;
208 tegra30_apbif_write(reg, val);
209
210 reg = TEGRA30_AHUB_CIF_TX_CTRL +
211 (channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE);
212 val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) |
213 (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) |
214 (1 << TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) |
215 TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_16 |
216 TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_16 |
217 TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX;
218 tegra30_apbif_write(reg, val);
219
220 return 0;
221}
222EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_tx_fifo);
223
224int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif)
225{
226 int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
227 int reg, val;
228
229 reg = TEGRA30_AHUB_CHANNEL_CTRL +
230 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
231 val = tegra30_apbif_read(reg);
232 val |= TEGRA30_AHUB_CHANNEL_CTRL_TX_EN;
233 tegra30_apbif_write(reg, val);
234
235 return 0;
236}
237EXPORT_SYMBOL_GPL(tegra30_ahub_enable_tx_fifo);
238
239int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif)
240{
241 int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
242 int reg, val;
243
244 reg = TEGRA30_AHUB_CHANNEL_CTRL +
245 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
246 val = tegra30_apbif_read(reg);
247 val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_EN;
248 tegra30_apbif_write(reg, val);
249
250 return 0;
251}
252EXPORT_SYMBOL_GPL(tegra30_ahub_disable_tx_fifo);
253
254int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif)
255{
256 int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
257
258 __clear_bit(channel, ahub->tx_usage);
259
260 return 0;
261}
262EXPORT_SYMBOL_GPL(tegra30_ahub_free_tx_fifo);
263
264int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif,
265 enum tegra30_ahub_txcif txcif)
266{
267 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
268 int reg;
269
270 reg = TEGRA30_AHUB_AUDIO_RX +
271 (channel * TEGRA30_AHUB_AUDIO_RX_STRIDE);
272 tegra30_audio_write(reg, 1 << txcif);
273
274 return 0;
275}
276EXPORT_SYMBOL_GPL(tegra30_ahub_set_rx_cif_source);
277
278int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif)
279{
280 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
281 int reg;
282
283 reg = TEGRA30_AHUB_AUDIO_RX +
284 (channel * TEGRA30_AHUB_AUDIO_RX_STRIDE);
285 tegra30_audio_write(reg, 0);
286
287 return 0;
288}
289EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source);
290
291static const char * const configlink_clocks[] __devinitconst = {
292 "i2s0",
293 "i2s1",
294 "i2s2",
295 "i2s3",
296 "i2s4",
297 "dam0",
298 "dam1",
299 "dam2",
300 "spdif_in",
301};
302
303struct of_dev_auxdata ahub_auxdata[] __devinitdata = {
304 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080300, "tegra30-i2s.0", NULL),
305 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080400, "tegra30-i2s.1", NULL),
306 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080500, "tegra30-i2s.2", NULL),
307 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080600, "tegra30-i2s.3", NULL),
308 OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080700, "tegra30-i2s.4", NULL),
309 {}
310};
311
312#define LAST_REG(name) \
313 (TEGRA30_AHUB_##name + \
314 (TEGRA30_AHUB_##name##_STRIDE * TEGRA30_AHUB_##name##_COUNT) - 4)
315
316#define REG_IN_ARRAY(reg, name) \
317 ((reg >= TEGRA30_AHUB_##name) && \
318 (reg <= LAST_REG(name) && \
319 (!((reg - TEGRA30_AHUB_##name) % TEGRA30_AHUB_##name##_STRIDE))))
320
321static bool tegra30_ahub_apbif_wr_rd_reg(struct device *dev, unsigned int reg)
322{
323 switch (reg) {
324 case TEGRA30_AHUB_CONFIG_LINK_CTRL:
325 case TEGRA30_AHUB_MISC_CTRL:
326 case TEGRA30_AHUB_APBDMA_LIVE_STATUS:
327 case TEGRA30_AHUB_I2S_LIVE_STATUS:
328 case TEGRA30_AHUB_SPDIF_LIVE_STATUS:
329 case TEGRA30_AHUB_I2S_INT_MASK:
330 case TEGRA30_AHUB_DAM_INT_MASK:
331 case TEGRA30_AHUB_SPDIF_INT_MASK:
332 case TEGRA30_AHUB_APBIF_INT_MASK:
333 case TEGRA30_AHUB_I2S_INT_STATUS:
334 case TEGRA30_AHUB_DAM_INT_STATUS:
335 case TEGRA30_AHUB_SPDIF_INT_STATUS:
336 case TEGRA30_AHUB_APBIF_INT_STATUS:
337 case TEGRA30_AHUB_I2S_INT_SOURCE:
338 case TEGRA30_AHUB_DAM_INT_SOURCE:
339 case TEGRA30_AHUB_SPDIF_INT_SOURCE:
340 case TEGRA30_AHUB_APBIF_INT_SOURCE:
341 case TEGRA30_AHUB_I2S_INT_SET:
342 case TEGRA30_AHUB_DAM_INT_SET:
343 case TEGRA30_AHUB_SPDIF_INT_SET:
344 case TEGRA30_AHUB_APBIF_INT_SET:
345 return true;
346 default:
347 break;
348 };
349
350 if (REG_IN_ARRAY(reg, CHANNEL_CTRL) ||
351 REG_IN_ARRAY(reg, CHANNEL_CLEAR) ||
352 REG_IN_ARRAY(reg, CHANNEL_STATUS) ||
353 REG_IN_ARRAY(reg, CHANNEL_TXFIFO) ||
354 REG_IN_ARRAY(reg, CHANNEL_RXFIFO) ||
355 REG_IN_ARRAY(reg, CIF_TX_CTRL) ||
356 REG_IN_ARRAY(reg, CIF_RX_CTRL) ||
357 REG_IN_ARRAY(reg, DAM_LIVE_STATUS))
358 return true;
359
360 return false;
361}
362
363static bool tegra30_ahub_apbif_volatile_reg(struct device *dev,
364 unsigned int reg)
365{
366 switch (reg) {
367 case TEGRA30_AHUB_CONFIG_LINK_CTRL:
368 case TEGRA30_AHUB_MISC_CTRL:
369 case TEGRA30_AHUB_APBDMA_LIVE_STATUS:
370 case TEGRA30_AHUB_I2S_LIVE_STATUS:
371 case TEGRA30_AHUB_SPDIF_LIVE_STATUS:
372 case TEGRA30_AHUB_I2S_INT_STATUS:
373 case TEGRA30_AHUB_DAM_INT_STATUS:
374 case TEGRA30_AHUB_SPDIF_INT_STATUS:
375 case TEGRA30_AHUB_APBIF_INT_STATUS:
376 case TEGRA30_AHUB_I2S_INT_SET:
377 case TEGRA30_AHUB_DAM_INT_SET:
378 case TEGRA30_AHUB_SPDIF_INT_SET:
379 case TEGRA30_AHUB_APBIF_INT_SET:
380 return true;
381 default:
382 break;
383 };
384
385 if (REG_IN_ARRAY(reg, CHANNEL_CLEAR) ||
386 REG_IN_ARRAY(reg, CHANNEL_STATUS) ||
387 REG_IN_ARRAY(reg, CHANNEL_TXFIFO) ||
388 REG_IN_ARRAY(reg, CHANNEL_RXFIFO) ||
389 REG_IN_ARRAY(reg, DAM_LIVE_STATUS))
390 return true;
391
392 return false;
393}
394
395static bool tegra30_ahub_apbif_precious_reg(struct device *dev,
396 unsigned int reg)
397{
398 if (REG_IN_ARRAY(reg, CHANNEL_TXFIFO) ||
399 REG_IN_ARRAY(reg, CHANNEL_RXFIFO))
400 return true;
401
402 return false;
403}
404
405static const struct regmap_config tegra30_ahub_apbif_regmap_config = {
406 .name = "apbif",
407 .reg_bits = 32,
408 .val_bits = 32,
409 .reg_stride = 4,
410 .max_register = TEGRA30_AHUB_APBIF_INT_SET,
411 .writeable_reg = tegra30_ahub_apbif_wr_rd_reg,
412 .readable_reg = tegra30_ahub_apbif_wr_rd_reg,
413 .volatile_reg = tegra30_ahub_apbif_volatile_reg,
414 .precious_reg = tegra30_ahub_apbif_precious_reg,
415 .cache_type = REGCACHE_RBTREE,
416};
417
418static bool tegra30_ahub_ahub_wr_rd_reg(struct device *dev, unsigned int reg)
419{
420 if (REG_IN_ARRAY(reg, AUDIO_RX))
421 return true;
422
423 return false;
424}
425
426static const struct regmap_config tegra30_ahub_ahub_regmap_config = {
427 .name = "ahub",
428 .reg_bits = 32,
429 .val_bits = 32,
430 .reg_stride = 4,
431 .max_register = LAST_REG(AUDIO_RX),
432 .writeable_reg = tegra30_ahub_ahub_wr_rd_reg,
433 .readable_reg = tegra30_ahub_ahub_wr_rd_reg,
434 .cache_type = REGCACHE_RBTREE,
435};
436
437static int __devinit tegra30_ahub_probe(struct platform_device *pdev)
438{
439 struct clk *clk;
440 int i;
441 struct resource *res0, *res1, *region;
442 u32 of_dma[2];
443 void __iomem *regs_apbif, *regs_ahub;
444 int ret = 0;
445
446 if (ahub)
447 return -ENODEV;
448
449 /*
450 * The AHUB hosts a register bus: the "configlink". For this to
451 * operate correctly, all devices on this bus must be out of reset.
452 * Ensure that here.
453 */
454 for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) {
455 clk = clk_get_sys(NULL, configlink_clocks[i]);
456 if (IS_ERR(clk)) {
457 dev_err(&pdev->dev, "Can't get clock %s\n",
458 configlink_clocks[i]);
459 ret = PTR_ERR(clk);
460 goto err;
461 }
462 tegra_periph_reset_deassert(clk);
463 clk_put(clk);
464 }
465
466 ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub),
467 GFP_KERNEL);
468 if (!ahub) {
469 dev_err(&pdev->dev, "Can't allocate tegra30_ahub\n");
470 ret = -ENOMEM;
471 goto err;
472 }
473 dev_set_drvdata(&pdev->dev, ahub);
474
475 ahub->dev = &pdev->dev;
476
477 ahub->clk_d_audio = clk_get(&pdev->dev, "d_audio");
478 if (IS_ERR(ahub->clk_d_audio)) {
479 dev_err(&pdev->dev, "Can't retrieve ahub d_audio clock\n");
480 ret = PTR_ERR(ahub->clk_d_audio);
481 goto err;
482 }
483
484 ahub->clk_apbif = clk_get(&pdev->dev, "apbif");
485 if (IS_ERR(ahub->clk_apbif)) {
486 dev_err(&pdev->dev, "Can't retrieve ahub apbif clock\n");
487 ret = PTR_ERR(ahub->clk_apbif);
488 goto err_clk_put_d_audio;
489 }
490
491 if (of_property_read_u32_array(pdev->dev.of_node,
492 "nvidia,dma-request-selector",
493 of_dma, 2) < 0) {
494 dev_err(&pdev->dev,
495 "Missing property nvidia,dma-request-selector\n");
496 ret = -ENODEV;
497 goto err_clk_put_d_audio;
498 }
499 ahub->dma_sel = of_dma[1];
500
501 res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
502 if (!res0) {
503 dev_err(&pdev->dev, "No apbif memory resource\n");
504 ret = -ENODEV;
505 goto err_clk_put_apbif;
506 }
507
508 region = devm_request_mem_region(&pdev->dev, res0->start,
509 resource_size(res0), DRV_NAME);
510 if (!region) {
511 dev_err(&pdev->dev, "request region apbif failed\n");
512 ret = -EBUSY;
513 goto err_clk_put_apbif;
514 }
515 ahub->apbif_addr = res0->start;
516
517 regs_apbif = devm_ioremap(&pdev->dev, res0->start,
518 resource_size(res0));
519 if (!regs_apbif) {
520 dev_err(&pdev->dev, "ioremap apbif failed\n");
521 ret = -ENOMEM;
522 goto err_clk_put_apbif;
523 }
524
525 ahub->regmap_apbif = devm_regmap_init_mmio(&pdev->dev, regs_apbif,
526 &tegra30_ahub_apbif_regmap_config);
527 if (IS_ERR(ahub->regmap_apbif)) {
528 dev_err(&pdev->dev, "apbif regmap init failed\n");
529 ret = PTR_ERR(ahub->regmap_apbif);
530 goto err_clk_put_apbif;
531 }
532 regcache_cache_only(ahub->regmap_apbif, true);
533
534 res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
535 if (!res1) {
536 dev_err(&pdev->dev, "No ahub memory resource\n");
537 ret = -ENODEV;
538 goto err_clk_put_apbif;
539 }
540
541 region = devm_request_mem_region(&pdev->dev, res1->start,
542 resource_size(res1), DRV_NAME);
543 if (!region) {
544 dev_err(&pdev->dev, "request region ahub failed\n");
545 ret = -EBUSY;
546 goto err_clk_put_apbif;
547 }
548
549 regs_ahub = devm_ioremap(&pdev->dev, res1->start,
550 resource_size(res1));
551 if (!regs_ahub) {
552 dev_err(&pdev->dev, "ioremap ahub failed\n");
553 ret = -ENOMEM;
554 goto err_clk_put_apbif;
555 }
556
557 ahub->regmap_ahub = devm_regmap_init_mmio(&pdev->dev, regs_ahub,
558 &tegra30_ahub_ahub_regmap_config);
559 if (IS_ERR(ahub->regmap_ahub)) {
560 dev_err(&pdev->dev, "ahub regmap init failed\n");
561 ret = PTR_ERR(ahub->regmap_ahub);
562 goto err_clk_put_apbif;
563 }
564 regcache_cache_only(ahub->regmap_ahub, true);
565
566 pm_runtime_enable(&pdev->dev);
567 if (!pm_runtime_enabled(&pdev->dev)) {
568 ret = tegra30_ahub_runtime_resume(&pdev->dev);
569 if (ret)
570 goto err_pm_disable;
571 }
572
573 of_platform_populate(pdev->dev.of_node, NULL, ahub_auxdata,
574 &pdev->dev);
575
576 return 0;
577
578err_pm_disable:
579 pm_runtime_disable(&pdev->dev);
580err_clk_put_apbif:
581 clk_put(ahub->clk_apbif);
582err_clk_put_d_audio:
583 clk_put(ahub->clk_d_audio);
584 ahub = 0;
585err:
586 return ret;
587}
588
589static int __devexit tegra30_ahub_remove(struct platform_device *pdev)
590{
591 if (!ahub)
592 return -ENODEV;
593
594 pm_runtime_disable(&pdev->dev);
595 if (!pm_runtime_status_suspended(&pdev->dev))
596 tegra30_ahub_runtime_suspend(&pdev->dev);
597
598 clk_put(ahub->clk_apbif);
599 clk_put(ahub->clk_d_audio);
600
601 ahub = 0;
602
603 return 0;
604}
605
606static const struct of_device_id tegra30_ahub_of_match[] __devinitconst = {
607 { .compatible = "nvidia,tegra30-ahub", },
608 {},
609};
610
611static const struct dev_pm_ops tegra30_ahub_pm_ops __devinitconst = {
612 SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend,
613 tegra30_ahub_runtime_resume, NULL)
614};
615
616static struct platform_driver tegra30_ahub_driver = {
617 .probe = tegra30_ahub_probe,
618 .remove = __devexit_p(tegra30_ahub_remove),
619 .driver = {
620 .name = DRV_NAME,
621 .owner = THIS_MODULE,
622 .of_match_table = tegra30_ahub_of_match,
623 .pm = &tegra30_ahub_pm_ops,
624 },
625};
626module_platform_driver(tegra30_ahub_driver);
627
628MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
629MODULE_DESCRIPTION("Tegra30 AHUB driver");
630MODULE_LICENSE("GPL v2");
631MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra30_ahub.h b/sound/soc/tegra/tegra30_ahub.h
new file mode 100644
index 000000000000..e690e2eecc92
--- /dev/null
+++ b/sound/soc/tegra/tegra30_ahub.h
@@ -0,0 +1,483 @@
1/*
2 * tegra30_ahub.h - Definitions for Tegra30 AHUB driver
3 *
4 * Copyright (c) 2011,2012, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef __TEGRA30_AHUB_H__
20#define __TEGRA30_AHUB_H__
21
22/* Fields in *_CIF_RX/TX_CTRL; used by AHUB FIFOs, and all other audio modules */
23
24#define TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT 28
25#define TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_MASK_US 0xf
26#define TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_MASK (TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_MASK_US << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT)
27
28/* Channel count minus 1 */
29#define TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT 24
30#define TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK_US 7
31#define TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK (TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_MASK_US << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT)
32
33/* Channel count minus 1 */
34#define TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT 16
35#define TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK_US 7
36#define TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK (TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_MASK_US << TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT)
37
38#define TEGRA30_AUDIOCIF_BITS_4 0
39#define TEGRA30_AUDIOCIF_BITS_8 1
40#define TEGRA30_AUDIOCIF_BITS_12 2
41#define TEGRA30_AUDIOCIF_BITS_16 3
42#define TEGRA30_AUDIOCIF_BITS_20 4
43#define TEGRA30_AUDIOCIF_BITS_24 5
44#define TEGRA30_AUDIOCIF_BITS_28 6
45#define TEGRA30_AUDIOCIF_BITS_32 7
46
47#define TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT 12
48#define TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_MASK (7 << TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT)
49#define TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_4 (TEGRA30_AUDIOCIF_BITS_4 << TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT)
50#define TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_8 (TEGRA30_AUDIOCIF_BITS_8 << TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT)
51#define TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_12 (TEGRA30_AUDIOCIF_BITS_12 << TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT)
52#define TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_16 (TEGRA30_AUDIOCIF_BITS_16 << TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT)
53#define TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_20 (TEGRA30_AUDIOCIF_BITS_20 << TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT)
54#define TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_24 (TEGRA30_AUDIOCIF_BITS_24 << TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT)
55#define TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_28 (TEGRA30_AUDIOCIF_BITS_28 << TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT)
56#define TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_32 (TEGRA30_AUDIOCIF_BITS_32 << TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT)
57
58#define TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT 8
59#define TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_MASK (7 << TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT)
60#define TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_4 (TEGRA30_AUDIOCIF_BITS_4 << TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT)
61#define TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_8 (TEGRA30_AUDIOCIF_BITS_8 << TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT)
62#define TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_12 (TEGRA30_AUDIOCIF_BITS_12 << TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT)
63#define TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_16 (TEGRA30_AUDIOCIF_BITS_16 << TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT)
64#define TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_20 (TEGRA30_AUDIOCIF_BITS_20 << TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT)
65#define TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_24 (TEGRA30_AUDIOCIF_BITS_24 << TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT)
66#define TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_28 (TEGRA30_AUDIOCIF_BITS_28 << TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT)
67#define TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_32 (TEGRA30_AUDIOCIF_BITS_32 << TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT)
68
69#define TEGRA30_AUDIOCIF_EXPAND_ZERO 0
70#define TEGRA30_AUDIOCIF_EXPAND_ONE 1
71#define TEGRA30_AUDIOCIF_EXPAND_LFSR 2
72
73#define TEGRA30_AUDIOCIF_CTRL_EXPAND_SHIFT 6
74#define TEGRA30_AUDIOCIF_CTRL_EXPAND_MASK (3 << TEGRA30_AUDIOCIF_CTRL_EXPAND_SHIFT)
75#define TEGRA30_AUDIOCIF_CTRL_EXPAND_ZERO (TEGRA30_AUDIOCIF_EXPAND_ZERO << TEGRA30_AUDIOCIF_CTRL_EXPAND_SHIFT)
76#define TEGRA30_AUDIOCIF_CTRL_EXPAND_ONE (TEGRA30_AUDIOCIF_EXPAND_ONE << TEGRA30_AUDIOCIF_CTRL_EXPAND_SHIFT)
77#define TEGRA30_AUDIOCIF_CTRL_EXPAND_LFSR (TEGRA30_AUDIOCIF_EXPAND_LFSR << TEGRA30_AUDIOCIF_CTRL_EXPAND_SHIFT)
78
79#define TEGRA30_AUDIOCIF_STEREO_CONV_CH0 0
80#define TEGRA30_AUDIOCIF_STEREO_CONV_CH1 1
81#define TEGRA30_AUDIOCIF_STEREO_CONV_AVG 2
82
83#define TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_SHIFT 4
84#define TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_MASK (3 << TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_SHIFT)
85#define TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_CH0 (TEGRA30_AUDIOCIF_STEREO_CONV_CH0 << TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_SHIFT)
86#define TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_CH1 (TEGRA30_AUDIOCIF_STEREO_CONV_CH1 << TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_SHIFT)
87#define TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_AVG (TEGRA30_AUDIOCIF_STEREO_CONV_AVG << TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_SHIFT)
88
89#define TEGRA30_AUDIOCIF_CTRL_REPLICATE 3
90
91#define TEGRA30_AUDIOCIF_DIRECTION_TX 0
92#define TEGRA30_AUDIOCIF_DIRECTION_RX 1
93
94#define TEGRA30_AUDIOCIF_CTRL_DIRECTION_SHIFT 2
95#define TEGRA30_AUDIOCIF_CTRL_DIRECTION_MASK (1 << TEGRA30_AUDIOCIF_CTRL_DIRECTION_SHIFT)
96#define TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX (TEGRA30_AUDIOCIF_DIRECTION_TX << TEGRA30_AUDIOCIF_CTRL_DIRECTION_SHIFT)
97#define TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX (TEGRA30_AUDIOCIF_DIRECTION_RX << TEGRA30_AUDIOCIF_CTRL_DIRECTION_SHIFT)
98
99#define TEGRA30_AUDIOCIF_TRUNCATE_ROUND 0
100#define TEGRA30_AUDIOCIF_TRUNCATE_CHOP 1
101
102#define TEGRA30_AUDIOCIF_CTRL_TRUNCATE_SHIFT 1
103#define TEGRA30_AUDIOCIF_CTRL_TRUNCATE_MASK (1 << TEGRA30_AUDIOCIF_CTRL_TRUNCATE_SHIFT)
104#define TEGRA30_AUDIOCIF_CTRL_TRUNCATE_ROUND (TEGRA30_AUDIOCIF_TRUNCATE_ROUND << TEGRA30_AUDIOCIF_CTRL_TRUNCATE_SHIFT)
105#define TEGRA30_AUDIOCIF_CTRL_TRUNCATE_CHOP (TEGRA30_AUDIOCIF_TRUNCATE_CHOP << TEGRA30_AUDIOCIF_CTRL_TRUNCATE_SHIFT)
106
107#define TEGRA30_AUDIOCIF_MONO_CONV_ZERO 0
108#define TEGRA30_AUDIOCIF_MONO_CONV_COPY 1
109
110#define TEGRA30_AUDIOCIF_CTRL_MONO_CONV_SHIFT 0
111#define TEGRA30_AUDIOCIF_CTRL_MONO_CONV_MASK (1 << TEGRA30_AUDIOCIF_CTRL_MONO_CONV_SHIFT)
112#define TEGRA30_AUDIOCIF_CTRL_MONO_CONV_ZERO (TEGRA30_AUDIOCIF_MONO_CONV_ZERO << TEGRA30_AUDIOCIF_CTRL_MONO_CONV_SHIFT)
113#define TEGRA30_AUDIOCIF_CTRL_MONO_CONV_COPY (TEGRA30_AUDIOCIF_MONO_CONV_COPY << TEGRA30_AUDIOCIF_CTRL_MONO_CONV_SHIFT)
114
115/* Registers within TEGRA30_AUDIO_CLUSTER_BASE */
116
117/* TEGRA30_AHUB_CHANNEL_CTRL */
118
119#define TEGRA30_AHUB_CHANNEL_CTRL 0x0
120#define TEGRA30_AHUB_CHANNEL_CTRL_STRIDE 0x20
121#define TEGRA30_AHUB_CHANNEL_CTRL_COUNT 4
122#define TEGRA30_AHUB_CHANNEL_CTRL_TX_EN (1 << 31)
123#define TEGRA30_AHUB_CHANNEL_CTRL_RX_EN (1 << 30)
124#define TEGRA30_AHUB_CHANNEL_CTRL_LOOPBACK (1 << 29)
125
126#define TEGRA30_AHUB_CHANNEL_CTRL_TX_THRESHOLD_SHIFT 16
127#define TEGRA30_AHUB_CHANNEL_CTRL_TX_THRESHOLD_MASK_US 0xff
128#define TEGRA30_AHUB_CHANNEL_CTRL_TX_THRESHOLD_MASK (TEGRA30_AHUB_CHANNEL_CTRL_TX_THRESHOLD_MASK_US << TEGRA30_AHUB_CHANNEL_CTRL_TX_THRESHOLD_SHIFT)
129
130#define TEGRA30_AHUB_CHANNEL_CTRL_RX_THRESHOLD_SHIFT 8
131#define TEGRA30_AHUB_CHANNEL_CTRL_RX_THRESHOLD_MASK_US 0xff
132#define TEGRA30_AHUB_CHANNEL_CTRL_RX_THRESHOLD_MASK (TEGRA30_AHUB_CHANNEL_CTRL_RX_THRESHOLD_MASK_US << TEGRA30_AHUB_CHANNEL_CTRL_RX_THRESHOLD_SHIFT)
133
134#define TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_EN (1 << 6)
135
136#define TEGRA30_PACK_8_4 2
137#define TEGRA30_PACK_16 3
138
139#define TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_SHIFT 4
140#define TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_MASK_US 3
141#define TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_MASK (TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_MASK_US << TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_SHIFT)
142#define TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_8_4 (TEGRA30_PACK_8_4 << TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_SHIFT)
143#define TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_16 (TEGRA30_PACK_16 << TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_SHIFT)
144
145#define TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_EN (1 << 2)
146
147#define TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_SHIFT 0
148#define TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_MASK_US 3
149#define TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_MASK (TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_MASK_US << TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_SHIFT)
150#define TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_8_4 (TEGRA30_PACK_8_4 << TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_SHIFT)
151#define TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_16 (TEGRA30_PACK_16 << TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_SHIFT)
152
153/* TEGRA30_AHUB_CHANNEL_CLEAR */
154
155#define TEGRA30_AHUB_CHANNEL_CLEAR 0x4
156#define TEGRA30_AHUB_CHANNEL_CLEAR_STRIDE 0x20
157#define TEGRA30_AHUB_CHANNEL_CLEAR_COUNT 4
158#define TEGRA30_AHUB_CHANNEL_CLEAR_TX_SOFT_RESET (1 << 31)
159#define TEGRA30_AHUB_CHANNEL_CLEAR_RX_SOFT_RESET (1 << 30)
160
161/* TEGRA30_AHUB_CHANNEL_STATUS */
162
163#define TEGRA30_AHUB_CHANNEL_STATUS 0x8
164#define TEGRA30_AHUB_CHANNEL_STATUS_STRIDE 0x20
165#define TEGRA30_AHUB_CHANNEL_STATUS_COUNT 4
166#define TEGRA30_AHUB_CHANNEL_STATUS_TX_FREE_SHIFT 24
167#define TEGRA30_AHUB_CHANNEL_STATUS_TX_FREE_MASK_US 0xff
168#define TEGRA30_AHUB_CHANNEL_STATUS_TX_FREE_MASK (TEGRA30_AHUB_CHANNEL_STATUS_TX_FREE_MASK_US << TEGRA30_AHUB_CHANNEL_STATUS_TX_FREE_SHIFT)
169#define TEGRA30_AHUB_CHANNEL_STATUS_RX_FREE_SHIFT 16
170#define TEGRA30_AHUB_CHANNEL_STATUS_RX_FREE_MASK_US 0xff
171#define TEGRA30_AHUB_CHANNEL_STATUS_RX_FREE_MASK (TEGRA30_AHUB_CHANNEL_STATUS_RX_FREE_MASK_US << TEGRA30_AHUB_CHANNEL_STATUS_RX_FREE_SHIFT)
172#define TEGRA30_AHUB_CHANNEL_STATUS_TX_TRIG (1 << 1)
173#define TEGRA30_AHUB_CHANNEL_STATUS_RX_TRIG (1 << 0)
174
175/* TEGRA30_AHUB_CHANNEL_TXFIFO */
176
177#define TEGRA30_AHUB_CHANNEL_TXFIFO 0xc
178#define TEGRA30_AHUB_CHANNEL_TXFIFO_STRIDE 0x20
179#define TEGRA30_AHUB_CHANNEL_TXFIFO_COUNT 4
180
181/* TEGRA30_AHUB_CHANNEL_RXFIFO */
182
183#define TEGRA30_AHUB_CHANNEL_RXFIFO 0x10
184#define TEGRA30_AHUB_CHANNEL_RXFIFO_STRIDE 0x20
185#define TEGRA30_AHUB_CHANNEL_RXFIFO_COUNT 4
186
187/* TEGRA30_AHUB_CIF_TX_CTRL */
188
189#define TEGRA30_AHUB_CIF_TX_CTRL 0x14
190#define TEGRA30_AHUB_CIF_TX_CTRL_STRIDE 0x20
191#define TEGRA30_AHUB_CIF_TX_CTRL_COUNT 4
192/* Uses field from TEGRA30_AUDIOCIF_CTRL_* */
193
194/* TEGRA30_AHUB_CIF_RX_CTRL */
195
196#define TEGRA30_AHUB_CIF_RX_CTRL 0x18
197#define TEGRA30_AHUB_CIF_RX_CTRL_STRIDE 0x20
198#define TEGRA30_AHUB_CIF_RX_CTRL_COUNT 4
199/* Uses field from TEGRA30_AUDIOCIF_CTRL_* */
200
201/* TEGRA30_AHUB_CONFIG_LINK_CTRL */
202
203#define TEGRA30_AHUB_CONFIG_LINK_CTRL 0x80
204#define TEGRA30_AHUB_CONFIG_LINK_CTRL_MASTER_FIFO_FULL_CNT_SHIFT 28
205#define TEGRA30_AHUB_CONFIG_LINK_CTRL_MASTER_FIFO_FULL_CNT_MASK_US 0xf
206#define TEGRA30_AHUB_CONFIG_LINK_CTRL_MASTER_FIFO_FULL_CNT_MASK (TEGRA30_AHUB_CONFIG_LINK_CTRL_MASTER_FIFO_FULL_CNT_MASK_US << TEGRA30_AHUB_CONFIG_LINK_CTRL_MASTER_FIFO_FULL_CNT_SHIFT)
207#define TEGRA30_AHUB_CONFIG_LINK_CTRL_TIMEOUT_CNT_SHIFT 16
208#define TEGRA30_AHUB_CONFIG_LINK_CTRL_TIMEOUT_CNT_MASK_US 0xfff
209#define TEGRA30_AHUB_CONFIG_LINK_CTRL_TIMEOUT_CNT_MASK (TEGRA30_AHUB_CONFIG_LINK_CTRL_TIMEOUT_CNT_MASK_US << TEGRA30_AHUB_CONFIG_LINK_CTRL_TIMEOUT_CNT_SHIFT)
210#define TEGRA30_AHUB_CONFIG_LINK_CTRL_IDLE_CNT_SHIFT 4
211#define TEGRA30_AHUB_CONFIG_LINK_CTRL_IDLE_CNT_MASK_US 0xfff
212#define TEGRA30_AHUB_CONFIG_LINK_CTRL_IDLE_CNT_MASK (TEGRA30_AHUB_CONFIG_LINK_CTRL_IDLE_CNT_MASK_US << TEGRA30_AHUB_CONFIG_LINK_CTRL_IDLE_CNT_SHIFT)
213#define TEGRA30_AHUB_CONFIG_LINK_CTRL_CG_EN (1 << 2)
214#define TEGRA30_AHUB_CONFIG_LINK_CTRL_CLEAR_TIMEOUT_CNTR (1 << 1)
215#define TEGRA30_AHUB_CONFIG_LINK_CTRL_SOFT_RESET (1 << 0)
216
217/* TEGRA30_AHUB_MISC_CTRL */
218
219#define TEGRA30_AHUB_MISC_CTRL 0x84
220#define TEGRA30_AHUB_MISC_CTRL_AUDIO_ACTIVE (1 << 31)
221#define TEGRA30_AHUB_MISC_CTRL_AUDIO_CG_EN (1 << 8)
222#define TEGRA30_AHUB_MISC_CTRL_AUDIO_OBS_SEL_SHIFT 0
223#define TEGRA30_AHUB_MISC_CTRL_AUDIO_OBS_SEL_MASK (0x1f << TEGRA30_AHUB_MISC_CTRL_AUDIO_OBS_SEL_SHIFT)
224
225/* TEGRA30_AHUB_APBDMA_LIVE_STATUS */
226
227#define TEGRA30_AHUB_APBDMA_LIVE_STATUS 0x88
228#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH3_RX_CIF_FIFO_FULL (1 << 31)
229#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH3_TX_CIF_FIFO_FULL (1 << 30)
230#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH2_RX_CIF_FIFO_FULL (1 << 29)
231#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH2_TX_CIF_FIFO_FULL (1 << 28)
232#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH1_RX_CIF_FIFO_FULL (1 << 27)
233#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH1_TX_CIF_FIFO_FULL (1 << 26)
234#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH0_RX_CIF_FIFO_FULL (1 << 25)
235#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH0_TX_CIF_FIFO_FULL (1 << 24)
236#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH3_RX_CIF_FIFO_EMPTY (1 << 23)
237#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH3_TX_CIF_FIFO_EMPTY (1 << 22)
238#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH2_RX_CIF_FIFO_EMPTY (1 << 21)
239#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH2_TX_CIF_FIFO_EMPTY (1 << 20)
240#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH1_RX_CIF_FIFO_EMPTY (1 << 19)
241#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH1_TX_CIF_FIFO_EMPTY (1 << 18)
242#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH0_RX_CIF_FIFO_EMPTY (1 << 17)
243#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH0_TX_CIF_FIFO_EMPTY (1 << 16)
244#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH3_RX_DMA_FIFO_FULL (1 << 15)
245#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH3_TX_DMA_FIFO_FULL (1 << 14)
246#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH2_RX_DMA_FIFO_FULL (1 << 13)
247#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH2_TX_DMA_FIFO_FULL (1 << 12)
248#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH1_RX_DMA_FIFO_FULL (1 << 11)
249#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH1_TX_DMA_FIFO_FULL (1 << 10)
250#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH0_RX_DMA_FIFO_FULL (1 << 9)
251#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH0_TX_DMA_FIFO_FULL (1 << 8)
252#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH3_RX_DMA_FIFO_EMPTY (1 << 7)
253#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH3_TX_DMA_FIFO_EMPTY (1 << 6)
254#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH2_RX_DMA_FIFO_EMPTY (1 << 5)
255#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH2_TX_DMA_FIFO_EMPTY (1 << 4)
256#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH1_RX_DMA_FIFO_EMPTY (1 << 3)
257#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH1_TX_DMA_FIFO_EMPTY (1 << 2)
258#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH0_RX_DMA_FIFO_EMPTY (1 << 1)
259#define TEGRA30_AHUB_APBDMA_LIVE_STATUS_CH0_TX_DMA_FIFO_EMPTY (1 << 0)
260
261/* TEGRA30_AHUB_I2S_LIVE_STATUS */
262
263#define TEGRA30_AHUB_I2S_LIVE_STATUS 0x8c
264#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S4_RX_FIFO_FULL (1 << 29)
265#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S4_TX_FIFO_FULL (1 << 28)
266#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S3_RX_FIFO_FULL (1 << 27)
267#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S3_TX_FIFO_FULL (1 << 26)
268#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S2_RX_FIFO_FULL (1 << 25)
269#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S2_TX_FIFO_FULL (1 << 24)
270#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S1_RX_FIFO_FULL (1 << 23)
271#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S1_TX_FIFO_FULL (1 << 22)
272#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S0_RX_FIFO_FULL (1 << 21)
273#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S0_TX_FIFO_FULL (1 << 20)
274#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S4_RX_FIFO_ENABLED (1 << 19)
275#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S4_TX_FIFO_ENABLED (1 << 18)
276#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S3_RX_FIFO_ENABLED (1 << 17)
277#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S3_TX_FIFO_ENABLED (1 << 16)
278#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S2_RX_FIFO_ENABLED (1 << 15)
279#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S2_TX_FIFO_ENABLED (1 << 14)
280#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S1_RX_FIFO_ENABLED (1 << 13)
281#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S1_TX_FIFO_ENABLED (1 << 12)
282#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S0_RX_FIFO_ENABLED (1 << 11)
283#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S0_TX_FIFO_ENABLED (1 << 10)
284#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S4_RX_FIFO_EMPTY (1 << 9)
285#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S4_TX_FIFO_EMPTY (1 << 8)
286#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S3_RX_FIFO_EMPTY (1 << 7)
287#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S3_TX_FIFO_EMPTY (1 << 6)
288#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S2_RX_FIFO_EMPTY (1 << 5)
289#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S2_TX_FIFO_EMPTY (1 << 4)
290#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S1_RX_FIFO_EMPTY (1 << 3)
291#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S1_TX_FIFO_EMPTY (1 << 2)
292#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S0_RX_FIFO_EMPTY (1 << 1)
293#define TEGRA30_AHUB_I2S_LIVE_STATUS_I2S0_TX_FIFO_EMPTY (1 << 0)
294
295/* TEGRA30_AHUB_DAM0_LIVE_STATUS */
296
297#define TEGRA30_AHUB_DAM_LIVE_STATUS 0x90
298#define TEGRA30_AHUB_DAM_LIVE_STATUS_STRIDE 0x8
299#define TEGRA30_AHUB_DAM_LIVE_STATUS_COUNT 3
300#define TEGRA30_AHUB_DAM_LIVE_STATUS_TX_ENABLED (1 << 26)
301#define TEGRA30_AHUB_DAM_LIVE_STATUS_RX1_ENABLED (1 << 25)
302#define TEGRA30_AHUB_DAM_LIVE_STATUS_RX0_ENABLED (1 << 24)
303#define TEGRA30_AHUB_DAM_LIVE_STATUS_TXFIFO_FULL (1 << 15)
304#define TEGRA30_AHUB_DAM_LIVE_STATUS_RX1FIFO_FULL (1 << 9)
305#define TEGRA30_AHUB_DAM_LIVE_STATUS_RX0FIFO_FULL (1 << 8)
306#define TEGRA30_AHUB_DAM_LIVE_STATUS_TXFIFO_EMPTY (1 << 7)
307#define TEGRA30_AHUB_DAM_LIVE_STATUS_RX1FIFO_EMPTY (1 << 1)
308#define TEGRA30_AHUB_DAM_LIVE_STATUS_RX0FIFO_EMPTY (1 << 0)
309
310/* TEGRA30_AHUB_SPDIF_LIVE_STATUS */
311
312#define TEGRA30_AHUB_SPDIF_LIVE_STATUS 0xa8
313#define TEGRA30_AHUB_SPDIF_LIVE_STATUS_USER_TX_ENABLED (1 << 11)
314#define TEGRA30_AHUB_SPDIF_LIVE_STATUS_USER_RX_ENABLED (1 << 10)
315#define TEGRA30_AHUB_SPDIF_LIVE_STATUS_DATA_TX_ENABLED (1 << 9)
316#define TEGRA30_AHUB_SPDIF_LIVE_STATUS_DATA_RX_ENABLED (1 << 8)
317#define TEGRA30_AHUB_SPDIF_LIVE_STATUS_USER_TXFIFO_FULL (1 << 7)
318#define TEGRA30_AHUB_SPDIF_LIVE_STATUS_USER_RXFIFO_FULL (1 << 6)
319#define TEGRA30_AHUB_SPDIF_LIVE_STATUS_DATA_TXFIFO_FULL (1 << 5)
320#define TEGRA30_AHUB_SPDIF_LIVE_STATUS_DATA_RXFIFO_FULL (1 << 4)
321#define TEGRA30_AHUB_SPDIF_LIVE_STATUS_USER_TXFIFO_EMPTY (1 << 3)
322#define TEGRA30_AHUB_SPDIF_LIVE_STATUS_USER_RXFIFO_EMPTY (1 << 2)
323#define TEGRA30_AHUB_SPDIF_LIVE_STATUS_DATA_TXFIFO_EMPTY (1 << 1)
324#define TEGRA30_AHUB_SPDIF_LIVE_STATUS_DATA_RXFIFO_EMPTY (1 << 0)
325
326/* TEGRA30_AHUB_I2S_INT_MASK */
327
328#define TEGRA30_AHUB_I2S_INT_MASK 0xb0
329
330/* TEGRA30_AHUB_DAM_INT_MASK */
331
332#define TEGRA30_AHUB_DAM_INT_MASK 0xb4
333
334/* TEGRA30_AHUB_SPDIF_INT_MASK */
335
336#define TEGRA30_AHUB_SPDIF_INT_MASK 0xbc
337
338/* TEGRA30_AHUB_APBIF_INT_MASK */
339
340#define TEGRA30_AHUB_APBIF_INT_MASK 0xc0
341
342/* TEGRA30_AHUB_I2S_INT_STATUS */
343
344#define TEGRA30_AHUB_I2S_INT_STATUS 0xc8
345
346/* TEGRA30_AHUB_DAM_INT_STATUS */
347
348#define TEGRA30_AHUB_DAM_INT_STATUS 0xcc
349
350/* TEGRA30_AHUB_SPDIF_INT_STATUS */
351
352#define TEGRA30_AHUB_SPDIF_INT_STATUS 0xd4
353
354/* TEGRA30_AHUB_APBIF_INT_STATUS */
355
356#define TEGRA30_AHUB_APBIF_INT_STATUS 0xd8
357
358/* TEGRA30_AHUB_I2S_INT_SOURCE */
359
360#define TEGRA30_AHUB_I2S_INT_SOURCE 0xe0
361
362/* TEGRA30_AHUB_DAM_INT_SOURCE */
363
364#define TEGRA30_AHUB_DAM_INT_SOURCE 0xe4
365
366/* TEGRA30_AHUB_SPDIF_INT_SOURCE */
367
368#define TEGRA30_AHUB_SPDIF_INT_SOURCE 0xec
369
370/* TEGRA30_AHUB_APBIF_INT_SOURCE */
371
372#define TEGRA30_AHUB_APBIF_INT_SOURCE 0xf0
373
374/* TEGRA30_AHUB_I2S_INT_SET */
375
376#define TEGRA30_AHUB_I2S_INT_SET 0xf8
377
378/* TEGRA30_AHUB_DAM_INT_SET */
379
380#define TEGRA30_AHUB_DAM_INT_SET 0xfc
381
382/* TEGRA30_AHUB_SPDIF_INT_SET */
383
384#define TEGRA30_AHUB_SPDIF_INT_SET 0x100
385
386/* TEGRA30_AHUB_APBIF_INT_SET */
387
388#define TEGRA30_AHUB_APBIF_INT_SET 0x104
389
390/* Registers within TEGRA30_AHUB_BASE */
391
392#define TEGRA30_AHUB_AUDIO_RX 0x0
393#define TEGRA30_AHUB_AUDIO_RX_STRIDE 0x4
394#define TEGRA30_AHUB_AUDIO_RX_COUNT 17
395/* This register repeats once for each entry in enum tegra30_ahub_rxcif */
396/* The fields in this register are 1 bit per entry in tegra30_ahub_txcif */
397
398/*
399 * Terminology:
400 * AHUB: Audio Hub; a cross-bar switch between the audio devices: DMA FIFOs,
401 * I2S controllers, SPDIF controllers, and DAMs.
402 * XBAR: The core cross-bar component of the AHUB.
403 * CIF: Client Interface; the HW module connecting an audio device to the
404 * XBAR.
405 * DAM: Digital Audio Mixer: A HW module that mixes multiple audio streams,
406 * possibly including sample-rate conversion.
407 *
408 * Each TX CIF transmits data into the XBAR. Each RX CIF can receive audio
409 * transmitted by a particular TX CIF.
410 *
411 * This driver is currently very simplistic; many HW features are not
412 * exposed; DAMs are not supported, only 16-bit stereo audio is supported,
413 * etc.
414 */
415
416enum tegra30_ahub_txcif {
417 TEGRA30_AHUB_TXCIF_APBIF_TX0,
418 TEGRA30_AHUB_TXCIF_APBIF_TX1,
419 TEGRA30_AHUB_TXCIF_APBIF_TX2,
420 TEGRA30_AHUB_TXCIF_APBIF_TX3,
421 TEGRA30_AHUB_TXCIF_I2S0_TX0,
422 TEGRA30_AHUB_TXCIF_I2S1_TX0,
423 TEGRA30_AHUB_TXCIF_I2S2_TX0,
424 TEGRA30_AHUB_TXCIF_I2S3_TX0,
425 TEGRA30_AHUB_TXCIF_I2S4_TX0,
426 TEGRA30_AHUB_TXCIF_DAM0_TX0,
427 TEGRA30_AHUB_TXCIF_DAM1_TX0,
428 TEGRA30_AHUB_TXCIF_DAM2_TX0,
429 TEGRA30_AHUB_TXCIF_SPDIF_TX0,
430 TEGRA30_AHUB_TXCIF_SPDIF_TX1,
431};
432
433enum tegra30_ahub_rxcif {
434 TEGRA30_AHUB_RXCIF_APBIF_RX0,
435 TEGRA30_AHUB_RXCIF_APBIF_RX1,
436 TEGRA30_AHUB_RXcIF_APBIF_RX2,
437 TEGRA30_AHUB_RXCIF_APBIF_RX3,
438 TEGRA30_AHUB_RXCIF_I2S0_RX0,
439 TEGRA30_AHUB_RXCIF_I2S1_RX0,
440 TEGRA30_AHUB_RXCIF_I2S2_RX0,
441 TEGRA30_AHUB_RXCIF_I2S3_RX0,
442 TEGRA30_AHUB_RXCIF_I2S4_RX0,
443 TEGRA30_AHUB_RXCIF_DAM0_RX0,
444 TEGRA30_AHUB_RXCIF_DAM0_RX1,
445 TEGRA30_AHUB_RXCIF_DAM1_RX0,
446 TEGRA30_AHUB_RXCIF_DAM2_RX1,
447 TEGRA30_AHUB_RXCIF_DAM3_RX0,
448 TEGRA30_AHUB_RXCIF_DAM3_RX1,
449 TEGRA30_AHUB_RXCIF_SPDIF_RX0,
450 TEGRA30_AHUB_RXCIF_SPDIF_RX1,
451};
452
453extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
454 unsigned long *fiforeg,
455 unsigned long *reqsel);
456extern int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif);
457extern int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif);
458extern int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif);
459
460extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
461 unsigned long *fiforeg,
462 unsigned long *reqsel);
463extern int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif);
464extern int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif);
465extern int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif);
466
467extern int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif,
468 enum tegra30_ahub_txcif txcif);
469extern int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif);
470
471struct tegra30_ahub {
472 struct device *dev;
473 struct clk *clk_d_audio;
474 struct clk *clk_apbif;
475 int dma_sel;
476 resource_size_t apbif_addr;
477 struct regmap *regmap_apbif;
478 struct regmap *regmap_ahub;
479 DECLARE_BITMAP(rx_usage, TEGRA30_AHUB_CHANNEL_CTRL_COUNT);
480 DECLARE_BITMAP(tx_usage, TEGRA30_AHUB_CHANNEL_CTRL_COUNT);
481};
482
483#endif
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
new file mode 100644
index 000000000000..8596032985dc
--- /dev/null
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -0,0 +1,536 @@
1/*
2 * tegra30_i2s.c - Tegra30 I2S driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2010, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 *
12 * Copyright (C) 2010 Google, Inc.
13 * Iliyan Malchev <malchev@google.com>
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms and conditions of the GNU General Public License,
17 * version 2, as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope it will be useful, but WITHOUT
20 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
22 * more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26 */
27
28#include <linux/clk.h>
29#include <linux/device.h>
30#include <linux/io.h>
31#include <linux/module.h>
32#include <linux/of.h>
33#include <linux/platform_device.h>
34#include <linux/pm_runtime.h>
35#include <linux/regmap.h>
36#include <linux/slab.h>
37#include <sound/core.h>
38#include <sound/pcm.h>
39#include <sound/pcm_params.h>
40#include <sound/soc.h>
41
42#include "tegra30_ahub.h"
43#include "tegra30_i2s.h"
44
45#define DRV_NAME "tegra30-i2s"
46
47static inline void tegra30_i2s_write(struct tegra30_i2s *i2s, u32 reg, u32 val)
48{
49 regmap_write(i2s->regmap, reg, val);
50}
51
52static inline u32 tegra30_i2s_read(struct tegra30_i2s *i2s, u32 reg)
53{
54 u32 val;
55 regmap_read(i2s->regmap, reg, &val);
56 return val;
57}
58
59static int tegra30_i2s_runtime_suspend(struct device *dev)
60{
61 struct tegra30_i2s *i2s = dev_get_drvdata(dev);
62
63 regcache_cache_only(i2s->regmap, true);
64
65 clk_disable(i2s->clk_i2s);
66
67 return 0;
68}
69
70static int tegra30_i2s_runtime_resume(struct device *dev)
71{
72 struct tegra30_i2s *i2s = dev_get_drvdata(dev);
73 int ret;
74
75 ret = clk_enable(i2s->clk_i2s);
76 if (ret) {
77 dev_err(dev, "clk_enable failed: %d\n", ret);
78 return ret;
79 }
80
81 regcache_cache_only(i2s->regmap, false);
82
83 return 0;
84}
85
86int tegra30_i2s_startup(struct snd_pcm_substream *substream,
87 struct snd_soc_dai *dai)
88{
89 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
90 int ret;
91
92 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
93 ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif,
94 &i2s->playback_dma_data.addr,
95 &i2s->playback_dma_data.req_sel);
96 i2s->playback_dma_data.wrap = 4;
97 i2s->playback_dma_data.width = 32;
98 tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
99 i2s->playback_fifo_cif);
100 } else {
101 ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif,
102 &i2s->capture_dma_data.addr,
103 &i2s->capture_dma_data.req_sel);
104 i2s->capture_dma_data.wrap = 4;
105 i2s->capture_dma_data.width = 32;
106 tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif,
107 i2s->capture_i2s_cif);
108 }
109
110 return ret;
111}
112
113void tegra30_i2s_shutdown(struct snd_pcm_substream *substream,
114 struct snd_soc_dai *dai)
115{
116 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
117
118 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
119 tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
120 tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
121 } else {
122 tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
123 tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
124 }
125}
126
127static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
128 unsigned int fmt)
129{
130 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
131
132 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
133 case SND_SOC_DAIFMT_NB_NF:
134 break;
135 default:
136 return -EINVAL;
137 }
138
139 i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_MASTER_ENABLE;
140 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
141 case SND_SOC_DAIFMT_CBS_CFS:
142 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_MASTER_ENABLE;
143 break;
144 case SND_SOC_DAIFMT_CBM_CFM:
145 break;
146 default:
147 return -EINVAL;
148 }
149
150 i2s->reg_ctrl &= ~(TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK |
151 TEGRA30_I2S_CTRL_LRCK_MASK);
152 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
153 case SND_SOC_DAIFMT_DSP_A:
154 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC;
155 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
156 break;
157 case SND_SOC_DAIFMT_DSP_B:
158 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC;
159 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_R_LOW;
160 break;
161 case SND_SOC_DAIFMT_I2S:
162 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
163 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
164 break;
165 case SND_SOC_DAIFMT_RIGHT_J:
166 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
167 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
168 break;
169 case SND_SOC_DAIFMT_LEFT_J:
170 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
171 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
172 break;
173 default:
174 return -EINVAL;
175 }
176
177 return 0;
178}
179
180static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
181 struct snd_pcm_hw_params *params,
182 struct snd_soc_dai *dai)
183{
184 struct device *dev = substream->pcm->card->dev;
185 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
186 u32 val;
187 int ret, sample_size, srate, i2sclock, bitcnt;
188
189 if (params_channels(params) != 2)
190 return -EINVAL;
191
192 i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_BIT_SIZE_MASK;
193 switch (params_format(params)) {
194 case SNDRV_PCM_FORMAT_S16_LE:
195 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_BIT_SIZE_16;
196 sample_size = 16;
197 break;
198 default:
199 return -EINVAL;
200 }
201
202 srate = params_rate(params);
203
204 /* Final "* 2" required by Tegra hardware */
205 i2sclock = srate * params_channels(params) * sample_size * 2;
206
207 bitcnt = (i2sclock / (2 * srate)) - 1;
208 if (bitcnt < 0 || bitcnt > TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US)
209 return -EINVAL;
210
211 ret = clk_set_rate(i2s->clk_i2s, i2sclock);
212 if (ret) {
213 dev_err(dev, "Can't set I2S clock rate: %d\n", ret);
214 return ret;
215 }
216
217 val = bitcnt << TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT;
218
219 if (i2sclock % (2 * srate))
220 val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE;
221
222 tegra30_i2s_write(i2s, TEGRA30_I2S_TIMING, val);
223
224 val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) |
225 (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) |
226 (1 << TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT) |
227 TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_16 |
228 TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_16;
229
230 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
231 val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX;
232 tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_RX_CTRL, val);
233 } else {
234 val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX;
235 tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_TX_CTRL, val);
236 }
237
238 val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) |
239 (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT);
240 tegra30_i2s_write(i2s, TEGRA30_I2S_OFFSET, val);
241
242 return 0;
243}
244
245static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s)
246{
247 tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif);
248 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_TX;
249 tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl);
250}
251
252static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s)
253{
254 tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif);
255 i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_TX;
256 tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl);
257}
258
259static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s)
260{
261 tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif);
262 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_RX;
263 tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl);
264}
265
266static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s)
267{
268 tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif);
269 i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_RX;
270 tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl);
271}
272
273static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
274 struct snd_soc_dai *dai)
275{
276 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
277
278 switch (cmd) {
279 case SNDRV_PCM_TRIGGER_START:
280 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
281 case SNDRV_PCM_TRIGGER_RESUME:
282 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
283 tegra30_i2s_start_playback(i2s);
284 else
285 tegra30_i2s_start_capture(i2s);
286 break;
287 case SNDRV_PCM_TRIGGER_STOP:
288 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
289 case SNDRV_PCM_TRIGGER_SUSPEND:
290 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
291 tegra30_i2s_stop_playback(i2s);
292 else
293 tegra30_i2s_stop_capture(i2s);
294 break;
295 default:
296 return -EINVAL;
297 }
298
299 return 0;
300}
301
302static int tegra30_i2s_probe(struct snd_soc_dai *dai)
303{
304 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
305
306 dai->capture_dma_data = &i2s->capture_dma_data;
307 dai->playback_dma_data = &i2s->playback_dma_data;
308
309 return 0;
310}
311
312static struct snd_soc_dai_ops tegra30_i2s_dai_ops = {
313 .startup = tegra30_i2s_startup,
314 .shutdown = tegra30_i2s_shutdown,
315 .set_fmt = tegra30_i2s_set_fmt,
316 .hw_params = tegra30_i2s_hw_params,
317 .trigger = tegra30_i2s_trigger,
318};
319
320static const struct snd_soc_dai_driver tegra30_i2s_dai_template = {
321 .probe = tegra30_i2s_probe,
322 .playback = {
323 .channels_min = 2,
324 .channels_max = 2,
325 .rates = SNDRV_PCM_RATE_8000_96000,
326 .formats = SNDRV_PCM_FMTBIT_S16_LE,
327 },
328 .capture = {
329 .channels_min = 2,
330 .channels_max = 2,
331 .rates = SNDRV_PCM_RATE_8000_96000,
332 .formats = SNDRV_PCM_FMTBIT_S16_LE,
333 },
334 .ops = &tegra30_i2s_dai_ops,
335 .symmetric_rates = 1,
336};
337
338static bool tegra30_i2s_wr_rd_reg(struct device *dev, unsigned int reg)
339{
340 switch (reg) {
341 case TEGRA30_I2S_CTRL:
342 case TEGRA30_I2S_TIMING:
343 case TEGRA30_I2S_OFFSET:
344 case TEGRA30_I2S_CH_CTRL:
345 case TEGRA30_I2S_SLOT_CTRL:
346 case TEGRA30_I2S_CIF_RX_CTRL:
347 case TEGRA30_I2S_CIF_TX_CTRL:
348 case TEGRA30_I2S_FLOWCTL:
349 case TEGRA30_I2S_TX_STEP:
350 case TEGRA30_I2S_FLOW_STATUS:
351 case TEGRA30_I2S_FLOW_TOTAL:
352 case TEGRA30_I2S_FLOW_OVER:
353 case TEGRA30_I2S_FLOW_UNDER:
354 case TEGRA30_I2S_LCOEF_1_4_0:
355 case TEGRA30_I2S_LCOEF_1_4_1:
356 case TEGRA30_I2S_LCOEF_1_4_2:
357 case TEGRA30_I2S_LCOEF_1_4_3:
358 case TEGRA30_I2S_LCOEF_1_4_4:
359 case TEGRA30_I2S_LCOEF_1_4_5:
360 case TEGRA30_I2S_LCOEF_2_4_0:
361 case TEGRA30_I2S_LCOEF_2_4_1:
362 case TEGRA30_I2S_LCOEF_2_4_2:
363 return true;
364 default:
365 return false;
366 };
367}
368
369static bool tegra30_i2s_volatile_reg(struct device *dev, unsigned int reg)
370{
371 switch (reg) {
372 case TEGRA30_I2S_FLOW_STATUS:
373 case TEGRA30_I2S_FLOW_TOTAL:
374 case TEGRA30_I2S_FLOW_OVER:
375 case TEGRA30_I2S_FLOW_UNDER:
376 return true;
377 default:
378 return false;
379 };
380}
381
382static const struct regmap_config tegra30_i2s_regmap_config = {
383 .reg_bits = 32,
384 .reg_stride = 4,
385 .val_bits = 32,
386 .max_register = TEGRA30_I2S_LCOEF_2_4_2,
387 .writeable_reg = tegra30_i2s_wr_rd_reg,
388 .readable_reg = tegra30_i2s_wr_rd_reg,
389 .volatile_reg = tegra30_i2s_volatile_reg,
390 .cache_type = REGCACHE_RBTREE,
391};
392
393static __devinit int tegra30_i2s_platform_probe(struct platform_device *pdev)
394{
395 struct tegra30_i2s *i2s;
396 u32 cif_ids[2];
397 struct resource *mem, *memregion;
398 void __iomem *regs;
399 int ret;
400
401 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_i2s), GFP_KERNEL);
402 if (!i2s) {
403 dev_err(&pdev->dev, "Can't allocate tegra30_i2s\n");
404 ret = -ENOMEM;
405 goto err;
406 }
407 dev_set_drvdata(&pdev->dev, i2s);
408
409 i2s->dai = tegra30_i2s_dai_template;
410 i2s->dai.name = dev_name(&pdev->dev);
411
412 ret = of_property_read_u32_array(pdev->dev.of_node,
413 "nvidia,ahub-cif-ids", cif_ids,
414 ARRAY_SIZE(cif_ids));
415 if (ret < 0)
416 goto err;
417
418 i2s->playback_i2s_cif = cif_ids[0];
419 i2s->capture_i2s_cif = cif_ids[1];
420
421 i2s->clk_i2s = clk_get(&pdev->dev, NULL);
422 if (IS_ERR(i2s->clk_i2s)) {
423 dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
424 ret = PTR_ERR(i2s->clk_i2s);
425 goto err;
426 }
427
428 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
429 if (!mem) {
430 dev_err(&pdev->dev, "No memory resource\n");
431 ret = -ENODEV;
432 goto err_clk_put;
433 }
434
435 memregion = devm_request_mem_region(&pdev->dev, mem->start,
436 resource_size(mem), DRV_NAME);
437 if (!memregion) {
438 dev_err(&pdev->dev, "Memory region already claimed\n");
439 ret = -EBUSY;
440 goto err_clk_put;
441 }
442
443 regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
444 if (!regs) {
445 dev_err(&pdev->dev, "ioremap failed\n");
446 ret = -ENOMEM;
447 goto err_clk_put;
448 }
449
450 i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
451 &tegra30_i2s_regmap_config);
452 if (IS_ERR(i2s->regmap)) {
453 dev_err(&pdev->dev, "regmap init failed\n");
454 ret = PTR_ERR(i2s->regmap);
455 goto err_clk_put;
456 }
457 regcache_cache_only(i2s->regmap, true);
458
459 pm_runtime_enable(&pdev->dev);
460 if (!pm_runtime_enabled(&pdev->dev)) {
461 ret = tegra30_i2s_runtime_resume(&pdev->dev);
462 if (ret)
463 goto err_pm_disable;
464 }
465
466 ret = snd_soc_register_dai(&pdev->dev, &i2s->dai);
467 if (ret) {
468 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
469 ret = -ENOMEM;
470 goto err_suspend;
471 }
472
473 ret = tegra_pcm_platform_register(&pdev->dev);
474 if (ret) {
475 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
476 goto err_unregister_dai;
477 }
478
479 return 0;
480
481err_unregister_dai:
482 snd_soc_unregister_dai(&pdev->dev);
483err_suspend:
484 if (!pm_runtime_status_suspended(&pdev->dev))
485 tegra30_i2s_runtime_suspend(&pdev->dev);
486err_pm_disable:
487 pm_runtime_disable(&pdev->dev);
488err_clk_put:
489 clk_put(i2s->clk_i2s);
490err:
491 return ret;
492}
493
494static int __devexit tegra30_i2s_platform_remove(struct platform_device *pdev)
495{
496 struct tegra30_i2s *i2s = dev_get_drvdata(&pdev->dev);
497
498 pm_runtime_disable(&pdev->dev);
499 if (!pm_runtime_status_suspended(&pdev->dev))
500 tegra30_i2s_runtime_suspend(&pdev->dev);
501
502 tegra_pcm_platform_unregister(&pdev->dev);
503 snd_soc_unregister_dai(&pdev->dev);
504
505 clk_put(i2s->clk_i2s);
506
507 return 0;
508}
509
510static const struct of_device_id tegra30_i2s_of_match[] __devinitconst = {
511 { .compatible = "nvidia,tegra30-i2s", },
512 {},
513};
514
515static const struct dev_pm_ops tegra30_i2s_pm_ops __devinitconst = {
516 SET_RUNTIME_PM_OPS(tegra30_i2s_runtime_suspend,
517 tegra30_i2s_runtime_resume, NULL)
518};
519
520static struct platform_driver tegra30_i2s_driver = {
521 .driver = {
522 .name = DRV_NAME,
523 .owner = THIS_MODULE,
524 .of_match_table = tegra30_i2s_of_match,
525 .pm = &tegra30_i2s_pm_ops,
526 },
527 .probe = tegra30_i2s_platform_probe,
528 .remove = __devexit_p(tegra30_i2s_platform_remove),
529};
530module_platform_driver(tegra30_i2s_driver);
531
532MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
533MODULE_DESCRIPTION("Tegra30 I2S ASoC driver");
534MODULE_LICENSE("GPL");
535MODULE_ALIAS("platform:" DRV_NAME);
536MODULE_DEVICE_TABLE(of, tegra30_i2s_of_match);
diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h
new file mode 100644
index 000000000000..91adf29c7a87
--- /dev/null
+++ b/sound/soc/tegra/tegra30_i2s.h
@@ -0,0 +1,242 @@
1/*
2 * tegra30_i2s.h - Definitions for Tegra30 I2S driver
3 *
4 * Copyright (c) 2011,2012, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifndef __TEGRA30_I2S_H__
20#define __TEGRA30_I2S_H__
21
22#include "tegra_pcm.h"
23
24/* Register offsets from TEGRA30_I2S*_BASE */
25
26#define TEGRA30_I2S_CTRL 0x0
27#define TEGRA30_I2S_TIMING 0x4
28#define TEGRA30_I2S_OFFSET 0x08
29#define TEGRA30_I2S_CH_CTRL 0x0c
30#define TEGRA30_I2S_SLOT_CTRL 0x10
31#define TEGRA30_I2S_CIF_RX_CTRL 0x14
32#define TEGRA30_I2S_CIF_TX_CTRL 0x18
33#define TEGRA30_I2S_FLOWCTL 0x1c
34#define TEGRA30_I2S_TX_STEP 0x20
35#define TEGRA30_I2S_FLOW_STATUS 0x24
36#define TEGRA30_I2S_FLOW_TOTAL 0x28
37#define TEGRA30_I2S_FLOW_OVER 0x2c
38#define TEGRA30_I2S_FLOW_UNDER 0x30
39#define TEGRA30_I2S_LCOEF_1_4_0 0x34
40#define TEGRA30_I2S_LCOEF_1_4_1 0x38
41#define TEGRA30_I2S_LCOEF_1_4_2 0x3c
42#define TEGRA30_I2S_LCOEF_1_4_3 0x40
43#define TEGRA30_I2S_LCOEF_1_4_4 0x44
44#define TEGRA30_I2S_LCOEF_1_4_5 0x48
45#define TEGRA30_I2S_LCOEF_2_4_0 0x4c
46#define TEGRA30_I2S_LCOEF_2_4_1 0x50
47#define TEGRA30_I2S_LCOEF_2_4_2 0x54
48
49/* Fields in TEGRA30_I2S_CTRL */
50
51#define TEGRA30_I2S_CTRL_XFER_EN_TX (1 << 31)
52#define TEGRA30_I2S_CTRL_XFER_EN_RX (1 << 30)
53#define TEGRA30_I2S_CTRL_CG_EN (1 << 29)
54#define TEGRA30_I2S_CTRL_SOFT_RESET (1 << 28)
55#define TEGRA30_I2S_CTRL_TX_FLOWCTL_EN (1 << 27)
56
57#define TEGRA30_I2S_CTRL_OBS_SEL_SHIFT 24
58#define TEGRA30_I2S_CTRL_OBS_SEL_MASK (7 << TEGRA30_I2S_CTRL_OBS_SEL_SHIFT)
59
60#define TEGRA30_I2S_FRAME_FORMAT_LRCK 0
61#define TEGRA30_I2S_FRAME_FORMAT_FSYNC 1
62
63#define TEGRA30_I2S_CTRL_FRAME_FORMAT_SHIFT 12
64#define TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK (7 << TEGRA30_I2S_CTRL_FRAME_FORMAT_SHIFT)
65#define TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK (TEGRA30_I2S_FRAME_FORMAT_LRCK << TEGRA30_I2S_CTRL_FRAME_FORMAT_SHIFT)
66#define TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC (TEGRA30_I2S_FRAME_FORMAT_FSYNC << TEGRA30_I2S_CTRL_FRAME_FORMAT_SHIFT)
67
68#define TEGRA30_I2S_CTRL_MASTER_ENABLE (1 << 10)
69
70#define TEGRA30_I2S_LRCK_LEFT_LOW 0
71#define TEGRA30_I2S_LRCK_RIGHT_LOW 1
72
73#define TEGRA30_I2S_CTRL_LRCK_SHIFT 9
74#define TEGRA30_I2S_CTRL_LRCK_MASK (1 << TEGRA30_I2S_CTRL_LRCK_SHIFT)
75#define TEGRA30_I2S_CTRL_LRCK_L_LOW (TEGRA30_I2S_LRCK_LEFT_LOW << TEGRA30_I2S_CTRL_LRCK_SHIFT)
76#define TEGRA30_I2S_CTRL_LRCK_R_LOW (TEGRA30_I2S_LRCK_RIGHT_LOW << TEGRA30_I2S_CTRL_LRCK_SHIFT)
77
78#define TEGRA30_I2S_CTRL_LPBK_ENABLE (1 << 8)
79
80#define TEGRA30_I2S_BIT_CODE_LINEAR 0
81#define TEGRA30_I2S_BIT_CODE_ULAW 1
82#define TEGRA30_I2S_BIT_CODE_ALAW 2
83
84#define TEGRA30_I2S_CTRL_BIT_CODE_SHIFT 4
85#define TEGRA30_I2S_CTRL_BIT_CODE_MASK (3 << TEGRA30_I2S_CTRL_BIT_CODE_SHIFT)
86#define TEGRA30_I2S_CTRL_BIT_CODE_LINEAR (TEGRA30_I2S_BIT_CODE_LINEAR << TEGRA30_I2S_CTRL_BIT_CODE_SHIFT)
87#define TEGRA30_I2S_CTRL_BIT_CODE_ULAW (TEGRA30_I2S_BIT_CODE_ULAW << TEGRA30_I2S_CTRL_BIT_CODE_SHIFT)
88#define TEGRA30_I2S_CTRL_BIT_CODE_ALAW (TEGRA30_I2S_BIT_CODE_ALAW << TEGRA30_I2S_CTRL_BIT_CODE_SHIFT)
89
90#define TEGRA30_I2S_BITS_8 1
91#define TEGRA30_I2S_BITS_12 2
92#define TEGRA30_I2S_BITS_16 3
93#define TEGRA30_I2S_BITS_20 4
94#define TEGRA30_I2S_BITS_24 5
95#define TEGRA30_I2S_BITS_28 6
96#define TEGRA30_I2S_BITS_32 7
97
98/* Sample container size; see {RX,TX}_MASK field in CH_CTRL below */
99#define TEGRA30_I2S_CTRL_BIT_SIZE_SHIFT 0
100#define TEGRA30_I2S_CTRL_BIT_SIZE_MASK (7 << TEGRA30_I2S_CTRL_BIT_SIZE_SHIFT)
101#define TEGRA30_I2S_CTRL_BIT_SIZE_8 (TEGRA30_I2S_BITS_8 << TEGRA30_I2S_CTRL_BIT_SIZE_SHIFT)
102#define TEGRA30_I2S_CTRL_BIT_SIZE_12 (TEGRA30_I2S_BITS_12 << TEGRA30_I2S_CTRL_BIT_SIZE_SHIFT)
103#define TEGRA30_I2S_CTRL_BIT_SIZE_16 (TEGRA30_I2S_BITS_16 << TEGRA30_I2S_CTRL_BIT_SIZE_SHIFT)
104#define TEGRA30_I2S_CTRL_BIT_SIZE_20 (TEGRA30_I2S_BITS_20 << TEGRA30_I2S_CTRL_BIT_SIZE_SHIFT)
105#define TEGRA30_I2S_CTRL_BIT_SIZE_24 (TEGRA30_I2S_BITS_24 << TEGRA30_I2S_CTRL_BIT_SIZE_SHIFT)
106#define TEGRA30_I2S_CTRL_BIT_SIZE_28 (TEGRA30_I2S_BITS_28 << TEGRA30_I2S_CTRL_BIT_SIZE_SHIFT)
107#define TEGRA30_I2S_CTRL_BIT_SIZE_32 (TEGRA30_I2S_BITS_32 << TEGRA30_I2S_CTRL_BIT_SIZE_SHIFT)
108
109/* Fields in TEGRA30_I2S_TIMING */
110
111#define TEGRA30_I2S_TIMING_NON_SYM_ENABLE (1 << 12)
112#define TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT 0
113#define TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US 0x7fff
114#define TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_MASK (TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US << TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT)
115
116/* Fields in TEGRA30_I2S_OFFSET */
117
118#define TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT 16
119#define TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_MASK_US 0x7ff
120#define TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_MASK (TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_MASK_US << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT)
121#define TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT 0
122#define TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_MASK_US 0x7ff
123#define TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_MASK (TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_MASK_US << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT)
124
125/* Fields in TEGRA30_I2S_CH_CTRL */
126
127/* (FSYNC width - 1) in bit clocks */
128#define TEGRA30_I2S_CH_CTRL_FSYNC_WIDTH_SHIFT 24
129#define TEGRA30_I2S_CH_CTRL_FSYNC_WIDTH_MASK_US 0xff
130#define TEGRA30_I2S_CH_CTRL_FSYNC_WIDTH_MASK (TEGRA30_I2S_CH_CTRL_FSYNC_WIDTH_MASK_US << TEGRA30_I2S_CH_CTRL_FSYNC_WIDTH_SHIFT)
131
132#define TEGRA30_I2S_HIGHZ_NO 0
133#define TEGRA30_I2S_HIGHZ_YES 1
134#define TEGRA30_I2S_HIGHZ_ON_HALF_BIT_CLK 2
135
136#define TEGRA30_I2S_CH_CTRL_HIGHZ_CTRL_SHIFT 12
137#define TEGRA30_I2S_CH_CTRL_HIGHZ_CTRL_MASK (3 << TEGRA30_I2S_CH_CTRL_HIGHZ_CTRL_SHIFT)
138#define TEGRA30_I2S_CH_CTRL_HIGHZ_CTRL_NO (TEGRA30_I2S_HIGHZ_NO << TEGRA30_I2S_CH_CTRL_HIGHZ_CTRL_SHIFT)
139#define TEGRA30_I2S_CH_CTRL_HIGHZ_CTRL_YES (TEGRA30_I2S_HIGHZ_YES << TEGRA30_I2S_CH_CTRL_HIGHZ_CTRL_SHIFT)
140#define TEGRA30_I2S_CH_CTRL_HIGHZ_CTRL_ON_HALF_BIT_CLK (TEGRA30_I2S_HIGHZ_ON_HALF_BIT_CLK << TEGRA30_I2S_CH_CTRL_HIGHZ_CTRL_SHIFT)
141
142#define TEGRA30_I2S_MSB_FIRST 0
143#define TEGRA30_I2S_LSB_FIRST 1
144
145#define TEGRA30_I2S_CH_CTRL_RX_BIT_ORDER_SHIFT 10
146#define TEGRA30_I2S_CH_CTRL_RX_BIT_ORDER_MASK (1 << TEGRA30_I2S_CH_CTRL_RX_BIT_ORDER_SHIFT)
147#define TEGRA30_I2S_CH_CTRL_RX_BIT_ORDER_MSB_FIRST (TEGRA30_I2S_MSB_FIRST << TEGRA30_I2S_CH_CTRL_RX_BIT_ORDER_SHIFT)
148#define TEGRA30_I2S_CH_CTRL_RX_BIT_ORDER_LSB_FIRST (TEGRA30_I2S_LSB_FIRST << TEGRA30_I2S_CH_CTRL_RX_BIT_ORDER_SHIFT)
149#define TEGRA30_I2S_CH_CTRL_TX_BIT_ORDER_SHIFT 9
150#define TEGRA30_I2S_CH_CTRL_TX_BIT_ORDER_MASK (1 << TEGRA30_I2S_CH_CTRL_TX_BIT_ORDER_SHIFT)
151#define TEGRA30_I2S_CH_CTRL_TX_BIT_ORDER_MSB_FIRST (TEGRA30_I2S_MSB_FIRST << TEGRA30_I2S_CH_CTRL_TX_BIT_ORDER_SHIFT)
152#define TEGRA30_I2S_CH_CTRL_TX_BIT_ORDER_LSB_FIRST (TEGRA30_I2S_LSB_FIRST << TEGRA30_I2S_CH_CTRL_TX_BIT_ORDER_SHIFT)
153
154#define TEGRA30_I2S_POS_EDGE 0
155#define TEGRA30_I2S_NEG_EDGE 1
156
157#define TEGRA30_I2S_CH_CTRL_EGDE_CTRL_SHIFT 8
158#define TEGRA30_I2S_CH_CTRL_EGDE_CTRL_MASK (1 << TEGRA30_I2S_CH_CTRL_EGDE_CTRL_SHIFT)
159#define TEGRA30_I2S_CH_CTRL_EGDE_CTRL_POS_EDGE (TEGRA30_I2S_POS_EDGE << TEGRA30_I2S_CH_CTRL_EGDE_CTRL_SHIFT)
160#define TEGRA30_I2S_CH_CTRL_EGDE_CTRL_NEG_EDGE (TEGRA30_I2S_NEG_EDGE << TEGRA30_I2S_CH_CTRL_EGDE_CTRL_SHIFT)
161
162/* Sample size is # bits from BIT_SIZE minus this field */
163#define TEGRA30_I2S_CH_CTRL_RX_MASK_BITS_SHIFT 4
164#define TEGRA30_I2S_CH_CTRL_RX_MASK_BITS_MASK_US 7
165#define TEGRA30_I2S_CH_CTRL_RX_MASK_BITS_MASK (TEGRA30_I2S_CH_CTRL_RX_MASK_BITS_MASK_US << TEGRA30_I2S_CH_CTRL_RX_MASK_BITS_SHIFT)
166
167#define TEGRA30_I2S_CH_CTRL_TX_MASK_BITS_SHIFT 0
168#define TEGRA30_I2S_CH_CTRL_TX_MASK_BITS_MASK_US 7
169#define TEGRA30_I2S_CH_CTRL_TX_MASK_BITS_MASK (TEGRA30_I2S_CH_CTRL_TX_MASK_BITS_MASK_US << TEGRA30_I2S_CH_CTRL_TX_MASK_BITS_SHIFT)
170
171/* Fields in TEGRA30_I2S_SLOT_CTRL */
172
173/* Number of slots in frame, minus 1 */
174#define TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_SHIFT 16
175#define TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_MASK_US 7
176#define TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_MASK (TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOT_MASK_US << TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOT_SHIFT)
177
178/* TDM mode slot enable bitmask */
179#define TEGRA30_I2S_SLOT_CTRL_RX_SLOT_ENABLES_SHIFT 8
180#define TEGRA30_I2S_SLOT_CTRL_RX_SLOT_ENABLES_MASK (0xff << TEGRA30_I2S_SLOT_CTRL_RX_SLOT_ENABLES_SHIFT)
181
182#define TEGRA30_I2S_SLOT_CTRL_TX_SLOT_ENABLES_SHIFT 0
183#define TEGRA30_I2S_SLOT_CTRL_TX_SLOT_ENABLES_MASK (0xff << TEGRA30_I2S_SLOT_CTRL_TX_SLOT_ENABLES_SHIFT)
184
185/* Fields in TEGRA30_I2S_CIF_RX_CTRL */
186/* Uses field from TEGRA30_AUDIOCIF_CTRL_* in tegra30_ahub.h */
187
188/* Fields in TEGRA30_I2S_CIF_TX_CTRL */
189/* Uses field from TEGRA30_AUDIOCIF_CTRL_* in tegra30_ahub.h */
190
191/* Fields in TEGRA30_I2S_FLOWCTL */
192
193#define TEGRA30_I2S_FILTER_LINEAR 0
194#define TEGRA30_I2S_FILTER_QUAD 1
195
196#define TEGRA30_I2S_FLOWCTL_FILTER_SHIFT 31
197#define TEGRA30_I2S_FLOWCTL_FILTER_MASK (1 << TEGRA30_I2S_FLOWCTL_FILTER_SHIFT)
198#define TEGRA30_I2S_FLOWCTL_FILTER_LINEAR (TEGRA30_I2S_FILTER_LINEAR << TEGRA30_I2S_FLOWCTL_FILTER_SHIFT)
199#define TEGRA30_I2S_FLOWCTL_FILTER_QUAD (TEGRA30_I2S_FILTER_QUAD << TEGRA30_I2S_FLOWCTL_FILTER_SHIFT)
200
201/* Fields in TEGRA30_I2S_TX_STEP */
202
203#define TEGRA30_I2S_TX_STEP_SHIFT 0
204#define TEGRA30_I2S_TX_STEP_MASK_US 0xffff
205#define TEGRA30_I2S_TX_STEP_MASK (TEGRA30_I2S_TX_STEP_MASK_US << TEGRA30_I2S_TX_STEP_SHIFT)
206
207/* Fields in TEGRA30_I2S_FLOW_STATUS */
208
209#define TEGRA30_I2S_FLOW_STATUS_UNDERFLOW (1 << 31)
210#define TEGRA30_I2S_FLOW_STATUS_OVERFLOW (1 << 30)
211#define TEGRA30_I2S_FLOW_STATUS_MONITOR_INT_EN (1 << 4)
212#define TEGRA30_I2S_FLOW_STATUS_COUNTER_CLR (1 << 3)
213#define TEGRA30_I2S_FLOW_STATUS_MONITOR_CLR (1 << 2)
214#define TEGRA30_I2S_FLOW_STATUS_COUNTER_EN (1 << 1)
215#define TEGRA30_I2S_FLOW_STATUS_MONITOR_EN (1 << 0)
216
217/*
218 * There are no fields in TEGRA30_I2S_FLOW_TOTAL, TEGRA30_I2S_FLOW_OVER,
219 * TEGRA30_I2S_FLOW_UNDER; they are counters taking the whole register.
220 */
221
222/* Fields in TEGRA30_I2S_LCOEF_* */
223
224#define TEGRA30_I2S_LCOEF_COEF_SHIFT 0
225#define TEGRA30_I2S_LCOEF_COEF_MASK_US 0xffff
226#define TEGRA30_I2S_LCOEF_COEF_MASK (TEGRA30_I2S_LCOEF_COEF_MASK_US << TEGRA30_I2S_LCOEF_COEF_SHIFT)
227
228struct tegra30_i2s {
229 struct snd_soc_dai_driver dai;
230 int cif_id;
231 struct clk *clk_i2s;
232 enum tegra30_ahub_txcif capture_i2s_cif;
233 enum tegra30_ahub_rxcif capture_fifo_cif;
234 struct tegra_pcm_dma_params capture_dma_data;
235 enum tegra30_ahub_rxcif playback_i2s_cif;
236 enum tegra30_ahub_txcif playback_fifo_cif;
237 struct tegra_pcm_dma_params playback_dma_data;
238 struct regmap *regmap;
239 u32 reg_ctrl;
240};
241
242#endif
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index e45ccd851f6a..32de7006daf0 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -1,16 +1,17 @@
1/* 1/*
2* tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver 2 * tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver
3* 3 *
4* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net> 4 * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
5* 5 * Copyright (C) 2012 - NVIDIA, Inc.
6* Authors: Leon Romanovsky <leon@leon.nu> 6 *
7* Andrey Danin <danindrey@mail.ru> 7 * Authors: Leon Romanovsky <leon@leon.nu>
8* Marc Dietrich <marvin24@gmx.de> 8 * Andrey Danin <danindrey@mail.ru>
9* 9 * Marc Dietrich <marvin24@gmx.de>
10* This program is free software; you can redistribute it and/or modify 10 *
11* it under the terms of the GNU General Public License version 2 as 11 * This program is free software; you can redistribute it and/or modify
12* published by the Free Software Foundation. 12 * it under the terms of the GNU General Public License version 2 as
13*/ 13 * published by the Free Software Foundation.
14 */
14 15
15#include <asm/mach-types.h> 16#include <asm/mach-types.h>
16 17
@@ -28,9 +29,6 @@
28 29
29#include "../codecs/alc5632.h" 30#include "../codecs/alc5632.h"
30 31
31#include "tegra_das.h"
32#include "tegra_i2s.h"
33#include "tegra_pcm.h"
34#include "tegra_asoc_utils.h" 32#include "tegra_asoc_utils.h"
35 33
36#define DRV_NAME "tegra-alc5632" 34#define DRV_NAME "tegra-alc5632"
@@ -39,7 +37,6 @@
39 37
40struct tegra_alc5632 { 38struct tegra_alc5632 {
41 struct tegra_asoc_utils_data util_data; 39 struct tegra_asoc_utils_data util_data;
42 struct platform_device *pcm_dev;
43 int gpio_requested; 40 int gpio_requested;
44 int gpio_hp_det; 41 int gpio_hp_det;
45}; 42};
@@ -140,7 +137,6 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
140static struct snd_soc_dai_link tegra_alc5632_dai = { 137static struct snd_soc_dai_link tegra_alc5632_dai = {
141 .name = "ALC5632", 138 .name = "ALC5632",
142 .stream_name = "ALC5632 PCM", 139 .stream_name = "ALC5632 PCM",
143 .platform_name = "tegra-pcm-audio",
144 .codec_dai_name = "alc5632-hifi", 140 .codec_dai_name = "alc5632-hifi",
145 .init = tegra_alc5632_asoc_init, 141 .init = tegra_alc5632_asoc_init,
146 .ops = &tegra_alc5632_asoc_ops, 142 .ops = &tegra_alc5632_asoc_ops,
@@ -179,8 +175,6 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
179 platform_set_drvdata(pdev, card); 175 platform_set_drvdata(pdev, card);
180 snd_soc_card_set_drvdata(card, alc5632); 176 snd_soc_card_set_drvdata(card, alc5632);
181 177
182 alc5632->pcm_dev = ERR_PTR(-EINVAL);
183
184 if (!(pdev->dev.of_node)) { 178 if (!(pdev->dev.of_node)) {
185 dev_err(&pdev->dev, "Must be instantiated using device tree\n"); 179 dev_err(&pdev->dev, "Must be instantiated using device tree\n");
186 ret = -EINVAL; 180 ret = -EINVAL;
@@ -214,18 +208,11 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
214 goto err; 208 goto err;
215 } 209 }
216 210
217 alc5632->pcm_dev = platform_device_register_simple( 211 tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_dai_of_node;
218 "tegra-pcm-audio", -1, NULL, 0);
219 if (IS_ERR(alc5632->pcm_dev)) {
220 dev_err(&pdev->dev,
221 "Can't instantiate tegra-pcm-audio\n");
222 ret = PTR_ERR(alc5632->pcm_dev);
223 goto err;
224 }
225 212
226 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); 213 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
227 if (ret) 214 if (ret)
228 goto err_unregister; 215 goto err;
229 216
230 ret = snd_soc_register_card(card); 217 ret = snd_soc_register_card(card);
231 if (ret) { 218 if (ret) {
@@ -238,9 +225,6 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
238 225
239err_fini_utils: 226err_fini_utils:
240 tegra_asoc_utils_fini(&alc5632->util_data); 227 tegra_asoc_utils_fini(&alc5632->util_data);
241err_unregister:
242 if (!IS_ERR(alc5632->pcm_dev))
243 platform_device_unregister(alc5632->pcm_dev);
244err: 228err:
245 return ret; 229 return ret;
246} 230}
@@ -259,8 +243,6 @@ static int __devexit tegra_alc5632_remove(struct platform_device *pdev)
259 snd_soc_unregister_card(card); 243 snd_soc_unregister_card(card);
260 244
261 tegra_asoc_utils_fini(&machine->util_data); 245 tegra_asoc_utils_fini(&machine->util_data);
262 if (!IS_ERR(machine->pcm_dev))
263 platform_device_unregister(machine->pcm_dev);
264 246
265 return 0; 247 return 0;
266} 248}
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c
index f8428e410e05..9515ce58ea02 100644
--- a/sound/soc/tegra/tegra_asoc_utils.c
+++ b/sound/soc/tegra/tegra_asoc_utils.c
@@ -2,7 +2,7 @@
2 * tegra_asoc_utils.c - Harmony machine ASoC driver 2 * tegra_asoc_utils.c - Harmony machine ASoC driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc. 5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
@@ -25,6 +25,7 @@
25#include <linux/err.h> 25#include <linux/err.h>
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/of.h>
28 29
29#include "tegra_asoc_utils.h" 30#include "tegra_asoc_utils.h"
30 31
@@ -40,7 +41,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
40 case 22050: 41 case 22050:
41 case 44100: 42 case 44100:
42 case 88200: 43 case 88200:
43 new_baseclock = 56448000; 44 if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
45 new_baseclock = 56448000;
46 else
47 new_baseclock = 564480000;
44 break; 48 break;
45 case 8000: 49 case 8000:
46 case 16000: 50 case 16000:
@@ -48,7 +52,10 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
48 case 48000: 52 case 48000:
49 case 64000: 53 case 64000:
50 case 96000: 54 case 96000:
51 new_baseclock = 73728000; 55 if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
56 new_baseclock = 73728000;
57 else
58 new_baseclock = 552960000;
52 break; 59 break;
53 default: 60 default:
54 return -EINVAL; 61 return -EINVAL;
@@ -78,7 +85,7 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
78 return err; 85 return err;
79 } 86 }
80 87
81 /* Don't set cdev1 rate; its locked to pll_a_out0 */ 88 /* Don't set cdev1/extern1 rate; it's locked to pll_a_out0 */
82 89
83 err = clk_enable(data->clk_pll_a); 90 err = clk_enable(data->clk_pll_a);
84 if (err) { 91 if (err) {
@@ -112,6 +119,17 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
112 119
113 data->dev = dev; 120 data->dev = dev;
114 121
122 if (of_machine_is_compatible("nvidia,tegra20"))
123 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20;
124 else if (of_machine_is_compatible("nvidia,tegra30"))
125 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30;
126 else if (!dev->of_node)
127 /* non-DT is always Tegra20 */
128 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20;
129 else
130 /* DT boot, but unknown SoC */
131 return -EINVAL;
132
115 data->clk_pll_a = clk_get_sys(NULL, "pll_a"); 133 data->clk_pll_a = clk_get_sys(NULL, "pll_a");
116 if (IS_ERR(data->clk_pll_a)) { 134 if (IS_ERR(data->clk_pll_a)) {
117 dev_err(data->dev, "Can't retrieve clk pll_a\n"); 135 dev_err(data->dev, "Can't retrieve clk pll_a\n");
@@ -126,15 +144,24 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
126 goto err_put_pll_a; 144 goto err_put_pll_a;
127 } 145 }
128 146
129 data->clk_cdev1 = clk_get_sys(NULL, "cdev1"); 147 if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
148 data->clk_cdev1 = clk_get_sys(NULL, "cdev1");
149 else
150 data->clk_cdev1 = clk_get_sys("extern1", NULL);
130 if (IS_ERR(data->clk_cdev1)) { 151 if (IS_ERR(data->clk_cdev1)) {
131 dev_err(data->dev, "Can't retrieve clk cdev1\n"); 152 dev_err(data->dev, "Can't retrieve clk cdev1\n");
132 ret = PTR_ERR(data->clk_cdev1); 153 ret = PTR_ERR(data->clk_cdev1);
133 goto err_put_pll_a_out0; 154 goto err_put_pll_a_out0;
134 } 155 }
135 156
157 ret = tegra_asoc_utils_set_rate(data, 44100, 256 * 44100);
158 if (ret)
159 goto err_put_cdev1;
160
136 return 0; 161 return 0;
137 162
163err_put_cdev1:
164 clk_put(data->clk_cdev1);
138err_put_pll_a_out0: 165err_put_pll_a_out0:
139 clk_put(data->clk_pll_a_out0); 166 clk_put(data->clk_pll_a_out0);
140err_put_pll_a: 167err_put_pll_a:
diff --git a/sound/soc/tegra/tegra_asoc_utils.h b/sound/soc/tegra/tegra_asoc_utils.h
index 4818195da25c..44db1dbb8f21 100644
--- a/sound/soc/tegra/tegra_asoc_utils.h
+++ b/sound/soc/tegra/tegra_asoc_utils.h
@@ -2,7 +2,7 @@
2 * tegra_asoc_utils.h - Definitions for Tegra DAS driver 2 * tegra_asoc_utils.h - Definitions for Tegra DAS driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc. 5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License 8 * modify it under the terms of the GNU General Public License
@@ -26,8 +26,14 @@
26struct clk; 26struct clk;
27struct device; 27struct device;
28 28
29enum tegra_asoc_utils_soc {
30 TEGRA_ASOC_UTILS_SOC_TEGRA20,
31 TEGRA_ASOC_UTILS_SOC_TEGRA30,
32};
33
29struct tegra_asoc_utils_data { 34struct tegra_asoc_utils_data {
30 struct device *dev; 35 struct device *dev;
36 enum tegra_asoc_utils_soc soc;
31 struct clk *clk_pll_a; 37 struct clk *clk_pll_a;
32 struct clk *clk_pll_a_out0; 38 struct clk *clk_pll_a_out0;
33 struct clk *clk_cdev1; 39 struct clk *clk_cdev1;
@@ -42,4 +48,3 @@ int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
42void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data); 48void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data);
43 49
44#endif 50#endif
45
diff --git a/sound/soc/tegra/tegra_das.c b/sound/soc/tegra/tegra_das.c
deleted file mode 100644
index 3b3c1ba4d235..000000000000
--- a/sound/soc/tegra/tegra_das.c
+++ /dev/null
@@ -1,261 +0,0 @@
1/*
2 * tegra_das.c - Tegra DAS driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
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 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include <linux/module.h>
24#include <linux/debugfs.h>
25#include <linux/device.h>
26#include <linux/platform_device.h>
27#include <linux/seq_file.h>
28#include <linux/slab.h>
29#include <linux/io.h>
30#include <mach/iomap.h>
31#include <sound/soc.h>
32#include "tegra_das.h"
33
34#define DRV_NAME "tegra-das"
35
36static struct tegra_das *das;
37
38static inline void tegra_das_write(u32 reg, u32 val)
39{
40 __raw_writel(val, das->regs + reg);
41}
42
43static inline u32 tegra_das_read(u32 reg)
44{
45 return __raw_readl(das->regs + reg);
46}
47
48int tegra_das_connect_dap_to_dac(int dap, int dac)
49{
50 u32 addr;
51 u32 reg;
52
53 if (!das)
54 return -ENODEV;
55
56 addr = TEGRA_DAS_DAP_CTRL_SEL +
57 (dap * TEGRA_DAS_DAP_CTRL_SEL_STRIDE);
58 reg = dac << TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P;
59
60 tegra_das_write(addr, reg);
61
62 return 0;
63}
64EXPORT_SYMBOL_GPL(tegra_das_connect_dap_to_dac);
65
66int tegra_das_connect_dap_to_dap(int dap, int otherdap, int master,
67 int sdata1rx, int sdata2rx)
68{
69 u32 addr;
70 u32 reg;
71
72 if (!das)
73 return -ENODEV;
74
75 addr = TEGRA_DAS_DAP_CTRL_SEL +
76 (dap * TEGRA_DAS_DAP_CTRL_SEL_STRIDE);
77 reg = otherdap << TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P |
78 !!sdata2rx << TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P |
79 !!sdata1rx << TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P |
80 !!master << TEGRA_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P;
81
82 tegra_das_write(addr, reg);
83
84 return 0;
85}
86EXPORT_SYMBOL_GPL(tegra_das_connect_dap_to_dap);
87
88int tegra_das_connect_dac_to_dap(int dac, int dap)
89{
90 u32 addr;
91 u32 reg;
92
93 if (!das)
94 return -ENODEV;
95
96 addr = TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL +
97 (dac * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE);
98 reg = dap << TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P |
99 dap << TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P |
100 dap << TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P;
101
102 tegra_das_write(addr, reg);
103
104 return 0;
105}
106EXPORT_SYMBOL_GPL(tegra_das_connect_dac_to_dap);
107
108#ifdef CONFIG_DEBUG_FS
109static int tegra_das_show(struct seq_file *s, void *unused)
110{
111 int i;
112 u32 addr;
113 u32 reg;
114
115 for (i = 0; i < TEGRA_DAS_DAP_CTRL_SEL_COUNT; i++) {
116 addr = TEGRA_DAS_DAP_CTRL_SEL +
117 (i * TEGRA_DAS_DAP_CTRL_SEL_STRIDE);
118 reg = tegra_das_read(addr);
119 seq_printf(s, "TEGRA_DAS_DAP_CTRL_SEL[%d] = %08x\n", i, reg);
120 }
121
122 for (i = 0; i < TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT; i++) {
123 addr = TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL +
124 (i * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE);
125 reg = tegra_das_read(addr);
126 seq_printf(s, "TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL[%d] = %08x\n",
127 i, reg);
128 }
129
130 return 0;
131}
132
133static int tegra_das_debug_open(struct inode *inode, struct file *file)
134{
135 return single_open(file, tegra_das_show, inode->i_private);
136}
137
138static const struct file_operations tegra_das_debug_fops = {
139 .open = tegra_das_debug_open,
140 .read = seq_read,
141 .llseek = seq_lseek,
142 .release = single_release,
143};
144
145static void tegra_das_debug_add(struct tegra_das *das)
146{
147 das->debug = debugfs_create_file(DRV_NAME, S_IRUGO,
148 snd_soc_debugfs_root, das,
149 &tegra_das_debug_fops);
150}
151
152static void tegra_das_debug_remove(struct tegra_das *das)
153{
154 if (das->debug)
155 debugfs_remove(das->debug);
156}
157#else
158static inline void tegra_das_debug_add(struct tegra_das *das)
159{
160}
161
162static inline void tegra_das_debug_remove(struct tegra_das *das)
163{
164}
165#endif
166
167static int __devinit tegra_das_probe(struct platform_device *pdev)
168{
169 struct resource *res, *region;
170 int ret = 0;
171
172 if (das)
173 return -ENODEV;
174
175 das = devm_kzalloc(&pdev->dev, sizeof(struct tegra_das), GFP_KERNEL);
176 if (!das) {
177 dev_err(&pdev->dev, "Can't allocate tegra_das\n");
178 ret = -ENOMEM;
179 goto err;
180 }
181 das->dev = &pdev->dev;
182
183 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
184 if (!res) {
185 dev_err(&pdev->dev, "No memory resource\n");
186 ret = -ENODEV;
187 goto err;
188 }
189
190 region = devm_request_mem_region(&pdev->dev, res->start,
191 resource_size(res), pdev->name);
192 if (!region) {
193 dev_err(&pdev->dev, "Memory region already claimed\n");
194 ret = -EBUSY;
195 goto err;
196 }
197
198 das->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
199 if (!das->regs) {
200 dev_err(&pdev->dev, "ioremap failed\n");
201 ret = -ENOMEM;
202 goto err;
203 }
204
205 ret = tegra_das_connect_dap_to_dac(TEGRA_DAS_DAP_ID_1,
206 TEGRA_DAS_DAP_SEL_DAC1);
207 if (ret) {
208 dev_err(&pdev->dev, "Can't set up DAS DAP connection\n");
209 goto err;
210 }
211 ret = tegra_das_connect_dac_to_dap(TEGRA_DAS_DAC_ID_1,
212 TEGRA_DAS_DAC_SEL_DAP1);
213 if (ret) {
214 dev_err(&pdev->dev, "Can't set up DAS DAC connection\n");
215 goto err;
216 }
217
218 tegra_das_debug_add(das);
219
220 platform_set_drvdata(pdev, das);
221
222 return 0;
223
224err:
225 das = NULL;
226 return ret;
227}
228
229static int __devexit tegra_das_remove(struct platform_device *pdev)
230{
231 if (!das)
232 return -ENODEV;
233
234 tegra_das_debug_remove(das);
235
236 das = NULL;
237
238 return 0;
239}
240
241static const struct of_device_id tegra_das_of_match[] __devinitconst = {
242 { .compatible = "nvidia,tegra20-das", },
243 {},
244};
245
246static struct platform_driver tegra_das_driver = {
247 .probe = tegra_das_probe,
248 .remove = __devexit_p(tegra_das_remove),
249 .driver = {
250 .name = DRV_NAME,
251 .owner = THIS_MODULE,
252 .of_match_table = tegra_das_of_match,
253 },
254};
255module_platform_driver(tegra_das_driver);
256
257MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
258MODULE_DESCRIPTION("Tegra DAS driver");
259MODULE_LICENSE("GPL");
260MODULE_ALIAS("platform:" DRV_NAME);
261MODULE_DEVICE_TABLE(of, tegra_das_of_match);
diff --git a/sound/soc/tegra/tegra_das.h b/sound/soc/tegra/tegra_das.h
deleted file mode 100644
index 2c96c7b3c459..000000000000
--- a/sound/soc/tegra/tegra_das.h
+++ /dev/null
@@ -1,135 +0,0 @@
1/*
2 * tegra_das.h - Definitions for Tegra DAS driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
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 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#ifndef __TEGRA_DAS_H__
24#define __TEGRA_DAS_H__
25
26/* Register TEGRA_DAS_DAP_CTRL_SEL */
27#define TEGRA_DAS_DAP_CTRL_SEL 0x00
28#define TEGRA_DAS_DAP_CTRL_SEL_COUNT 5
29#define TEGRA_DAS_DAP_CTRL_SEL_STRIDE 4
30#define TEGRA_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P 31
31#define TEGRA_DAS_DAP_CTRL_SEL_DAP_MS_SEL_S 1
32#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P 30
33#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_S 1
34#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P 29
35#define TEGRA_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_S 1
36#define TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P 0
37#define TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_S 5
38
39/* Values for field TEGRA_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL */
40#define TEGRA_DAS_DAP_SEL_DAC1 0
41#define TEGRA_DAS_DAP_SEL_DAC2 1
42#define TEGRA_DAS_DAP_SEL_DAC3 2
43#define TEGRA_DAS_DAP_SEL_DAP1 16
44#define TEGRA_DAS_DAP_SEL_DAP2 17
45#define TEGRA_DAS_DAP_SEL_DAP3 18
46#define TEGRA_DAS_DAP_SEL_DAP4 19
47#define TEGRA_DAS_DAP_SEL_DAP5 20
48
49/* Register TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL */
50#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL 0x40
51#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_COUNT 3
52#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE 4
53#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P 28
54#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_S 4
55#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P 24
56#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_S 4
57#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P 0
58#define TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_S 4
59
60/*
61 * Values for:
62 * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL
63 * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL
64 * TEGRA_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL
65 */
66#define TEGRA_DAS_DAC_SEL_DAP1 0
67#define TEGRA_DAS_DAC_SEL_DAP2 1
68#define TEGRA_DAS_DAC_SEL_DAP3 2
69#define TEGRA_DAS_DAC_SEL_DAP4 3
70#define TEGRA_DAS_DAC_SEL_DAP5 4
71
72/*
73 * Names/IDs of the DACs/DAPs.
74 */
75
76#define TEGRA_DAS_DAP_ID_1 0
77#define TEGRA_DAS_DAP_ID_2 1
78#define TEGRA_DAS_DAP_ID_3 2
79#define TEGRA_DAS_DAP_ID_4 3
80#define TEGRA_DAS_DAP_ID_5 4
81
82#define TEGRA_DAS_DAC_ID_1 0
83#define TEGRA_DAS_DAC_ID_2 1
84#define TEGRA_DAS_DAC_ID_3 2
85
86struct tegra_das {
87 struct device *dev;
88 void __iomem *regs;
89 struct dentry *debug;
90};
91
92/*
93 * Terminology:
94 * DAS: Digital audio switch (HW module controlled by this driver)
95 * DAP: Digital audio port (port/pins on Tegra device)
96 * DAC: Digital audio controller (e.g. I2S or AC97 controller elsewhere)
97 *
98 * The Tegra DAS is a mux/cross-bar which can connect each DAP to a specific
99 * DAC, or another DAP. When DAPs are connected, one must be the master and
100 * one the slave. Each DAC allows selection of a specific DAP for input, to
101 * cater for the case where N DAPs are connected to 1 DAC for broadcast
102 * output.
103 *
104 * This driver is dumb; no attempt is made to ensure that a valid routing
105 * configuration is programmed.
106 */
107
108/*
109 * Connect a DAP to to a DAC
110 * dap_id: DAP to connect: TEGRA_DAS_DAP_ID_*
111 * dac_sel: DAC to connect to: TEGRA_DAS_DAP_SEL_DAC*
112 */
113extern int tegra_das_connect_dap_to_dac(int dap_id, int dac_sel);
114
115/*
116 * Connect a DAP to to another DAP
117 * dap_id: DAP to connect: TEGRA_DAS_DAP_ID_*
118 * other_dap_sel: DAP to connect to: TEGRA_DAS_DAP_SEL_DAP*
119 * master: Is this DAP the master (1) or slave (0)
120 * sdata1rx: Is this DAP's SDATA1 pin RX (1) or TX (0)
121 * sdata2rx: Is this DAP's SDATA2 pin RX (1) or TX (0)
122 */
123extern int tegra_das_connect_dap_to_dap(int dap_id, int other_dap_sel,
124 int master, int sdata1rx,
125 int sdata2rx);
126
127/*
128 * Connect a DAC's input to a DAP
129 * (DAC outputs are selected by the DAP)
130 * dac_id: DAC ID to connect: TEGRA_DAS_DAC_ID_*
131 * dap_sel: DAP to receive input from: TEGRA_DAS_DAC_SEL_DAP*
132 */
133extern int tegra_das_connect_dac_to_dap(int dac_id, int dap_sel);
134
135#endif
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c
deleted file mode 100644
index e53349912b2e..000000000000
--- a/sound/soc/tegra/tegra_i2s.c
+++ /dev/null
@@ -1,459 +0,0 @@
1/*
2 * tegra_i2s.c - Tegra I2S driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2010, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 *
12 * Copyright (C) 2010 Google, Inc.
13 * Iliyan Malchev <malchev@google.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#include <linux/clk.h>
32#include <linux/module.h>
33#include <linux/debugfs.h>
34#include <linux/device.h>
35#include <linux/platform_device.h>
36#include <linux/seq_file.h>
37#include <linux/slab.h>
38#include <linux/io.h>
39#include <linux/of.h>
40#include <mach/iomap.h>
41#include <sound/core.h>
42#include <sound/pcm.h>
43#include <sound/pcm_params.h>
44#include <sound/soc.h>
45
46#include "tegra_i2s.h"
47
48#define DRV_NAME "tegra-i2s"
49
50static inline void tegra_i2s_write(struct tegra_i2s *i2s, u32 reg, u32 val)
51{
52 __raw_writel(val, i2s->regs + reg);
53}
54
55static inline u32 tegra_i2s_read(struct tegra_i2s *i2s, u32 reg)
56{
57 return __raw_readl(i2s->regs + reg);
58}
59
60#ifdef CONFIG_DEBUG_FS
61static int tegra_i2s_show(struct seq_file *s, void *unused)
62{
63#define REG(r) { r, #r }
64 static const struct {
65 int offset;
66 const char *name;
67 } regs[] = {
68 REG(TEGRA_I2S_CTRL),
69 REG(TEGRA_I2S_STATUS),
70 REG(TEGRA_I2S_TIMING),
71 REG(TEGRA_I2S_FIFO_SCR),
72 REG(TEGRA_I2S_PCM_CTRL),
73 REG(TEGRA_I2S_NW_CTRL),
74 REG(TEGRA_I2S_TDM_CTRL),
75 REG(TEGRA_I2S_TDM_TX_RX_CTRL),
76 };
77#undef REG
78
79 struct tegra_i2s *i2s = s->private;
80 int i;
81
82 clk_enable(i2s->clk_i2s);
83
84 for (i = 0; i < ARRAY_SIZE(regs); i++) {
85 u32 val = tegra_i2s_read(i2s, regs[i].offset);
86 seq_printf(s, "%s = %08x\n", regs[i].name, val);
87 }
88
89 clk_disable(i2s->clk_i2s);
90
91 return 0;
92}
93
94static int tegra_i2s_debug_open(struct inode *inode, struct file *file)
95{
96 return single_open(file, tegra_i2s_show, inode->i_private);
97}
98
99static const struct file_operations tegra_i2s_debug_fops = {
100 .open = tegra_i2s_debug_open,
101 .read = seq_read,
102 .llseek = seq_lseek,
103 .release = single_release,
104};
105
106static void tegra_i2s_debug_add(struct tegra_i2s *i2s)
107{
108 i2s->debug = debugfs_create_file(i2s->dai.name, S_IRUGO,
109 snd_soc_debugfs_root, i2s,
110 &tegra_i2s_debug_fops);
111}
112
113static void tegra_i2s_debug_remove(struct tegra_i2s *i2s)
114{
115 if (i2s->debug)
116 debugfs_remove(i2s->debug);
117}
118#else
119static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s)
120{
121}
122
123static inline void tegra_i2s_debug_remove(struct tegra_i2s *i2s)
124{
125}
126#endif
127
128static int tegra_i2s_set_fmt(struct snd_soc_dai *dai,
129 unsigned int fmt)
130{
131 struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai);
132
133 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
134 case SND_SOC_DAIFMT_NB_NF:
135 break;
136 default:
137 return -EINVAL;
138 }
139
140 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_MASTER_ENABLE;
141 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
142 case SND_SOC_DAIFMT_CBS_CFS:
143 i2s->reg_ctrl |= TEGRA_I2S_CTRL_MASTER_ENABLE;
144 break;
145 case SND_SOC_DAIFMT_CBM_CFM:
146 break;
147 default:
148 return -EINVAL;
149 }
150
151 i2s->reg_ctrl &= ~(TEGRA_I2S_CTRL_BIT_FORMAT_MASK |
152 TEGRA_I2S_CTRL_LRCK_MASK);
153 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
154 case SND_SOC_DAIFMT_DSP_A:
155 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_DSP;
156 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
157 break;
158 case SND_SOC_DAIFMT_DSP_B:
159 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_DSP;
160 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_R_LOW;
161 break;
162 case SND_SOC_DAIFMT_I2S:
163 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_I2S;
164 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
165 break;
166 case SND_SOC_DAIFMT_RIGHT_J:
167 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_RJM;
168 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
169 break;
170 case SND_SOC_DAIFMT_LEFT_J:
171 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_FORMAT_LJM;
172 i2s->reg_ctrl |= TEGRA_I2S_CTRL_LRCK_L_LOW;
173 break;
174 default:
175 return -EINVAL;
176 }
177
178 return 0;
179}
180
181static int tegra_i2s_hw_params(struct snd_pcm_substream *substream,
182 struct snd_pcm_hw_params *params,
183 struct snd_soc_dai *dai)
184{
185 struct device *dev = substream->pcm->card->dev;
186 struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai);
187 u32 reg;
188 int ret, sample_size, srate, i2sclock, bitcnt;
189
190 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_BIT_SIZE_MASK;
191 switch (params_format(params)) {
192 case SNDRV_PCM_FORMAT_S16_LE:
193 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_16;
194 sample_size = 16;
195 break;
196 case SNDRV_PCM_FORMAT_S24_LE:
197 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_24;
198 sample_size = 24;
199 break;
200 case SNDRV_PCM_FORMAT_S32_LE:
201 i2s->reg_ctrl |= TEGRA_I2S_CTRL_BIT_SIZE_32;
202 sample_size = 32;
203 break;
204 default:
205 return -EINVAL;
206 }
207
208 srate = params_rate(params);
209
210 /* Final "* 2" required by Tegra hardware */
211 i2sclock = srate * params_channels(params) * sample_size * 2;
212
213 ret = clk_set_rate(i2s->clk_i2s, i2sclock);
214 if (ret) {
215 dev_err(dev, "Can't set I2S clock rate: %d\n", ret);
216 return ret;
217 }
218
219 bitcnt = (i2sclock / (2 * srate)) - 1;
220 if (bitcnt < 0 || bitcnt > TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US)
221 return -EINVAL;
222 reg = bitcnt << TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT;
223
224 if (i2sclock % (2 * srate))
225 reg |= TEGRA_I2S_TIMING_NON_SYM_ENABLE;
226
227 if (!i2s->clk_refs)
228 clk_enable(i2s->clk_i2s);
229
230 tegra_i2s_write(i2s, TEGRA_I2S_TIMING, reg);
231
232 tegra_i2s_write(i2s, TEGRA_I2S_FIFO_SCR,
233 TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS |
234 TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS);
235
236 if (!i2s->clk_refs)
237 clk_disable(i2s->clk_i2s);
238
239 return 0;
240}
241
242static void tegra_i2s_start_playback(struct tegra_i2s *i2s)
243{
244 i2s->reg_ctrl |= TEGRA_I2S_CTRL_FIFO1_ENABLE;
245 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
246}
247
248static void tegra_i2s_stop_playback(struct tegra_i2s *i2s)
249{
250 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_FIFO1_ENABLE;
251 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
252}
253
254static void tegra_i2s_start_capture(struct tegra_i2s *i2s)
255{
256 i2s->reg_ctrl |= TEGRA_I2S_CTRL_FIFO2_ENABLE;
257 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
258}
259
260static void tegra_i2s_stop_capture(struct tegra_i2s *i2s)
261{
262 i2s->reg_ctrl &= ~TEGRA_I2S_CTRL_FIFO2_ENABLE;
263 tegra_i2s_write(i2s, TEGRA_I2S_CTRL, i2s->reg_ctrl);
264}
265
266static int tegra_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
267 struct snd_soc_dai *dai)
268{
269 struct tegra_i2s *i2s = snd_soc_dai_get_drvdata(dai);
270
271 switch (cmd) {
272 case SNDRV_PCM_TRIGGER_START:
273 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
274 case SNDRV_PCM_TRIGGER_RESUME:
275 if (!i2s->clk_refs)
276 clk_enable(i2s->clk_i2s);
277 i2s->clk_refs++;
278 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
279 tegra_i2s_start_playback(i2s);
280 else
281 tegra_i2s_start_capture(i2s);
282 break;
283 case SNDRV_PCM_TRIGGER_STOP:
284 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
285 case SNDRV_PCM_TRIGGER_SUSPEND:
286 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
287 tegra_i2s_stop_playback(i2s);
288 else
289 tegra_i2s_stop_capture(i2s);
290 i2s->clk_refs--;
291 if (!i2s->clk_refs)
292 clk_disable(i2s->clk_i2s);
293 break;
294 default:
295 return -EINVAL;
296 }
297
298 return 0;
299}
300
301static int tegra_i2s_probe(struct snd_soc_dai *dai)
302{
303 struct tegra_i2s * i2s = snd_soc_dai_get_drvdata(dai);
304
305 dai->capture_dma_data = &i2s->capture_dma_data;
306 dai->playback_dma_data = &i2s->playback_dma_data;
307
308 return 0;
309}
310
311static const struct snd_soc_dai_ops tegra_i2s_dai_ops = {
312 .set_fmt = tegra_i2s_set_fmt,
313 .hw_params = tegra_i2s_hw_params,
314 .trigger = tegra_i2s_trigger,
315};
316
317static const struct snd_soc_dai_driver tegra_i2s_dai_template = {
318 .probe = tegra_i2s_probe,
319 .playback = {
320 .channels_min = 2,
321 .channels_max = 2,
322 .rates = SNDRV_PCM_RATE_8000_96000,
323 .formats = SNDRV_PCM_FMTBIT_S16_LE,
324 },
325 .capture = {
326 .channels_min = 2,
327 .channels_max = 2,
328 .rates = SNDRV_PCM_RATE_8000_96000,
329 .formats = SNDRV_PCM_FMTBIT_S16_LE,
330 },
331 .ops = &tegra_i2s_dai_ops,
332 .symmetric_rates = 1,
333};
334
335static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev)
336{
337 struct tegra_i2s * i2s;
338 struct resource *mem, *memregion, *dmareq;
339 u32 of_dma[2];
340 u32 dma_ch;
341 int ret;
342
343 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra_i2s), GFP_KERNEL);
344 if (!i2s) {
345 dev_err(&pdev->dev, "Can't allocate tegra_i2s\n");
346 ret = -ENOMEM;
347 goto err;
348 }
349 dev_set_drvdata(&pdev->dev, i2s);
350
351 i2s->dai = tegra_i2s_dai_template;
352 i2s->dai.name = dev_name(&pdev->dev);
353
354 i2s->clk_i2s = clk_get(&pdev->dev, NULL);
355 if (IS_ERR(i2s->clk_i2s)) {
356 dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
357 ret = PTR_ERR(i2s->clk_i2s);
358 goto err;
359 }
360
361 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
362 if (!mem) {
363 dev_err(&pdev->dev, "No memory resource\n");
364 ret = -ENODEV;
365 goto err_clk_put;
366 }
367
368 dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
369 if (!dmareq) {
370 if (of_property_read_u32_array(pdev->dev.of_node,
371 "nvidia,dma-request-selector",
372 of_dma, 2) < 0) {
373 dev_err(&pdev->dev, "No DMA resource\n");
374 ret = -ENODEV;
375 goto err_clk_put;
376 }
377 dma_ch = of_dma[1];
378 } else {
379 dma_ch = dmareq->start;
380 }
381
382 memregion = devm_request_mem_region(&pdev->dev, mem->start,
383 resource_size(mem), DRV_NAME);
384 if (!memregion) {
385 dev_err(&pdev->dev, "Memory region already claimed\n");
386 ret = -EBUSY;
387 goto err_clk_put;
388 }
389
390 i2s->regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
391 if (!i2s->regs) {
392 dev_err(&pdev->dev, "ioremap failed\n");
393 ret = -ENOMEM;
394 goto err_clk_put;
395 }
396
397 i2s->capture_dma_data.addr = mem->start + TEGRA_I2S_FIFO2;
398 i2s->capture_dma_data.wrap = 4;
399 i2s->capture_dma_data.width = 32;
400 i2s->capture_dma_data.req_sel = dma_ch;
401
402 i2s->playback_dma_data.addr = mem->start + TEGRA_I2S_FIFO1;
403 i2s->playback_dma_data.wrap = 4;
404 i2s->playback_dma_data.width = 32;
405 i2s->playback_dma_data.req_sel = dma_ch;
406
407 i2s->reg_ctrl = TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED;
408
409 ret = snd_soc_register_dai(&pdev->dev, &i2s->dai);
410 if (ret) {
411 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
412 ret = -ENOMEM;
413 goto err_clk_put;
414 }
415
416 tegra_i2s_debug_add(i2s);
417
418 return 0;
419
420err_clk_put:
421 clk_put(i2s->clk_i2s);
422err:
423 return ret;
424}
425
426static int __devexit tegra_i2s_platform_remove(struct platform_device *pdev)
427{
428 struct tegra_i2s *i2s = dev_get_drvdata(&pdev->dev);
429
430 snd_soc_unregister_dai(&pdev->dev);
431
432 tegra_i2s_debug_remove(i2s);
433
434 clk_put(i2s->clk_i2s);
435
436 return 0;
437}
438
439static const struct of_device_id tegra_i2s_of_match[] __devinitconst = {
440 { .compatible = "nvidia,tegra20-i2s", },
441 {},
442};
443
444static struct platform_driver tegra_i2s_driver = {
445 .driver = {
446 .name = DRV_NAME,
447 .owner = THIS_MODULE,
448 .of_match_table = tegra_i2s_of_match,
449 },
450 .probe = tegra_i2s_platform_probe,
451 .remove = __devexit_p(tegra_i2s_platform_remove),
452};
453module_platform_driver(tegra_i2s_driver);
454
455MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
456MODULE_DESCRIPTION("Tegra I2S ASoC driver");
457MODULE_LICENSE("GPL");
458MODULE_ALIAS("platform:" DRV_NAME);
459MODULE_DEVICE_TABLE(of, tegra_i2s_of_match);
diff --git a/sound/soc/tegra/tegra_i2s.h b/sound/soc/tegra/tegra_i2s.h
deleted file mode 100644
index 15ce1e2e8bde..000000000000
--- a/sound/soc/tegra/tegra_i2s.h
+++ /dev/null
@@ -1,166 +0,0 @@
1/*
2 * tegra_i2s.h - Definitions for Tegra I2S driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2010, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 *
12 * Copyright (C) 2010 Google, Inc.
13 * Iliyan Malchev <malchev@google.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#ifndef __TEGRA_I2S_H__
32#define __TEGRA_I2S_H__
33
34#include "tegra_pcm.h"
35
36/* Register offsets from TEGRA_I2S1_BASE and TEGRA_I2S2_BASE */
37
38#define TEGRA_I2S_CTRL 0x00
39#define TEGRA_I2S_STATUS 0x04
40#define TEGRA_I2S_TIMING 0x08
41#define TEGRA_I2S_FIFO_SCR 0x0c
42#define TEGRA_I2S_PCM_CTRL 0x10
43#define TEGRA_I2S_NW_CTRL 0x14
44#define TEGRA_I2S_TDM_CTRL 0x20
45#define TEGRA_I2S_TDM_TX_RX_CTRL 0x24
46#define TEGRA_I2S_FIFO1 0x40
47#define TEGRA_I2S_FIFO2 0x80
48
49/* Fields in TEGRA_I2S_CTRL */
50
51#define TEGRA_I2S_CTRL_FIFO2_TX_ENABLE (1 << 30)
52#define TEGRA_I2S_CTRL_FIFO1_ENABLE (1 << 29)
53#define TEGRA_I2S_CTRL_FIFO2_ENABLE (1 << 28)
54#define TEGRA_I2S_CTRL_FIFO1_RX_ENABLE (1 << 27)
55#define TEGRA_I2S_CTRL_FIFO_LPBK_ENABLE (1 << 26)
56#define TEGRA_I2S_CTRL_MASTER_ENABLE (1 << 25)
57
58#define TEGRA_I2S_LRCK_LEFT_LOW 0
59#define TEGRA_I2S_LRCK_RIGHT_LOW 1
60
61#define TEGRA_I2S_CTRL_LRCK_SHIFT 24
62#define TEGRA_I2S_CTRL_LRCK_MASK (1 << TEGRA_I2S_CTRL_LRCK_SHIFT)
63#define TEGRA_I2S_CTRL_LRCK_L_LOW (TEGRA_I2S_LRCK_LEFT_LOW << TEGRA_I2S_CTRL_LRCK_SHIFT)
64#define TEGRA_I2S_CTRL_LRCK_R_LOW (TEGRA_I2S_LRCK_RIGHT_LOW << TEGRA_I2S_CTRL_LRCK_SHIFT)
65
66#define TEGRA_I2S_BIT_FORMAT_I2S 0
67#define TEGRA_I2S_BIT_FORMAT_RJM 1
68#define TEGRA_I2S_BIT_FORMAT_LJM 2
69#define TEGRA_I2S_BIT_FORMAT_DSP 3
70
71#define TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT 10
72#define TEGRA_I2S_CTRL_BIT_FORMAT_MASK (3 << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
73#define TEGRA_I2S_CTRL_BIT_FORMAT_I2S (TEGRA_I2S_BIT_FORMAT_I2S << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
74#define TEGRA_I2S_CTRL_BIT_FORMAT_RJM (TEGRA_I2S_BIT_FORMAT_RJM << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
75#define TEGRA_I2S_CTRL_BIT_FORMAT_LJM (TEGRA_I2S_BIT_FORMAT_LJM << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
76#define TEGRA_I2S_CTRL_BIT_FORMAT_DSP (TEGRA_I2S_BIT_FORMAT_DSP << TEGRA_I2S_CTRL_BIT_FORMAT_SHIFT)
77
78#define TEGRA_I2S_BIT_SIZE_16 0
79#define TEGRA_I2S_BIT_SIZE_20 1
80#define TEGRA_I2S_BIT_SIZE_24 2
81#define TEGRA_I2S_BIT_SIZE_32 3
82
83#define TEGRA_I2S_CTRL_BIT_SIZE_SHIFT 8
84#define TEGRA_I2S_CTRL_BIT_SIZE_MASK (3 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
85#define TEGRA_I2S_CTRL_BIT_SIZE_16 (TEGRA_I2S_BIT_SIZE_16 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
86#define TEGRA_I2S_CTRL_BIT_SIZE_20 (TEGRA_I2S_BIT_SIZE_20 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
87#define TEGRA_I2S_CTRL_BIT_SIZE_24 (TEGRA_I2S_BIT_SIZE_24 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
88#define TEGRA_I2S_CTRL_BIT_SIZE_32 (TEGRA_I2S_BIT_SIZE_32 << TEGRA_I2S_CTRL_BIT_SIZE_SHIFT)
89
90#define TEGRA_I2S_FIFO_16_LSB 0
91#define TEGRA_I2S_FIFO_20_LSB 1
92#define TEGRA_I2S_FIFO_24_LSB 2
93#define TEGRA_I2S_FIFO_32 3
94#define TEGRA_I2S_FIFO_PACKED 7
95
96#define TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT 4
97#define TEGRA_I2S_CTRL_FIFO_FORMAT_MASK (7 << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
98#define TEGRA_I2S_CTRL_FIFO_FORMAT_16_LSB (TEGRA_I2S_FIFO_16_LSB << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
99#define TEGRA_I2S_CTRL_FIFO_FORMAT_20_LSB (TEGRA_I2S_FIFO_20_LSB << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
100#define TEGRA_I2S_CTRL_FIFO_FORMAT_24_LSB (TEGRA_I2S_FIFO_24_LSB << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
101#define TEGRA_I2S_CTRL_FIFO_FORMAT_32 (TEGRA_I2S_FIFO_32 << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
102#define TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED (TEGRA_I2S_FIFO_PACKED << TEGRA_I2S_CTRL_FIFO_FORMAT_SHIFT)
103
104#define TEGRA_I2S_CTRL_IE_FIFO1_ERR (1 << 3)
105#define TEGRA_I2S_CTRL_IE_FIFO2_ERR (1 << 2)
106#define TEGRA_I2S_CTRL_QE_FIFO1 (1 << 1)
107#define TEGRA_I2S_CTRL_QE_FIFO2 (1 << 0)
108
109/* Fields in TEGRA_I2S_STATUS */
110
111#define TEGRA_I2S_STATUS_FIFO1_RDY (1 << 31)
112#define TEGRA_I2S_STATUS_FIFO2_RDY (1 << 30)
113#define TEGRA_I2S_STATUS_FIFO1_BSY (1 << 29)
114#define TEGRA_I2S_STATUS_FIFO2_BSY (1 << 28)
115#define TEGRA_I2S_STATUS_FIFO1_ERR (1 << 3)
116#define TEGRA_I2S_STATUS_FIFO2_ERR (1 << 2)
117#define TEGRA_I2S_STATUS_QS_FIFO1 (1 << 1)
118#define TEGRA_I2S_STATUS_QS_FIFO2 (1 << 0)
119
120/* Fields in TEGRA_I2S_TIMING */
121
122#define TEGRA_I2S_TIMING_NON_SYM_ENABLE (1 << 12)
123#define TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT 0
124#define TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US 0x7fff
125#define TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK (TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US << TEGRA_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT)
126
127/* Fields in TEGRA_I2S_FIFO_SCR */
128
129#define TEGRA_I2S_FIFO_SCR_FIFO2_FULL_EMPTY_COUNT_SHIFT 24
130#define TEGRA_I2S_FIFO_SCR_FIFO1_FULL_EMPTY_COUNT_SHIFT 16
131#define TEGRA_I2S_FIFO_SCR_FIFO_FULL_EMPTY_COUNT_MASK 0x3f
132
133#define TEGRA_I2S_FIFO_SCR_FIFO2_CLR (1 << 12)
134#define TEGRA_I2S_FIFO_SCR_FIFO1_CLR (1 << 8)
135
136#define TEGRA_I2S_FIFO_ATN_LVL_ONE_SLOT 0
137#define TEGRA_I2S_FIFO_ATN_LVL_FOUR_SLOTS 1
138#define TEGRA_I2S_FIFO_ATN_LVL_EIGHT_SLOTS 2
139#define TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS 3
140
141#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT 4
142#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_MASK (3 << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
143#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_ONE_SLOT (TEGRA_I2S_FIFO_ATN_LVL_ONE_SLOT << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
144#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_FOUR_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
145#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_EIGHT_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_EIGHT_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
146#define TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_TWELVE_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_SHIFT)
147
148#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT 0
149#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_MASK (3 << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
150#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_ONE_SLOT (TEGRA_I2S_FIFO_ATN_LVL_ONE_SLOT << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
151#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_FOUR_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
152#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_EIGHT_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_EIGHT_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
153#define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT)
154
155struct tegra_i2s {
156 struct snd_soc_dai_driver dai;
157 struct clk *clk_i2s;
158 int clk_refs;
159 struct tegra_pcm_dma_params capture_dma_data;
160 struct tegra_pcm_dma_params playback_dma_data;
161 void __iomem *regs;
162 struct dentry *debug;
163 u32 reg_ctrl;
164};
165
166#endif
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 8b4457137c7c..127348dc09b1 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -2,7 +2,7 @@
2 * tegra_pcm.c - Tegra PCM driver 2 * tegra_pcm.c - Tegra PCM driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc. 5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 * 6 *
7 * Based on code copyright/by: 7 * Based on code copyright/by:
8 * 8 *
@@ -29,8 +29,8 @@
29 * 29 *
30 */ 30 */
31 31
32#include <linux/module.h>
33#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
33#include <linux/module.h>
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <sound/core.h> 35#include <sound/core.h>
36#include <sound/pcm.h> 36#include <sound/pcm.h>
@@ -39,8 +39,6 @@
39 39
40#include "tegra_pcm.h" 40#include "tegra_pcm.h"
41 41
42#define DRV_NAME "tegra-pcm-audio"
43
44static const struct snd_pcm_hardware tegra_pcm_hardware = { 42static const struct snd_pcm_hardware tegra_pcm_hardware = {
45 .info = SNDRV_PCM_INFO_MMAP | 43 .info = SNDRV_PCM_INFO_MMAP |
46 SNDRV_PCM_INFO_MMAP_VALID | 44 SNDRV_PCM_INFO_MMAP_VALID |
@@ -372,28 +370,18 @@ static struct snd_soc_platform_driver tegra_pcm_platform = {
372 .pcm_free = tegra_pcm_free, 370 .pcm_free = tegra_pcm_free,
373}; 371};
374 372
375static int __devinit tegra_pcm_platform_probe(struct platform_device *pdev) 373int __devinit tegra_pcm_platform_register(struct device *dev)
376{ 374{
377 return snd_soc_register_platform(&pdev->dev, &tegra_pcm_platform); 375 return snd_soc_register_platform(dev, &tegra_pcm_platform);
378} 376}
377EXPORT_SYMBOL_GPL(tegra_pcm_platform_register);
379 378
380static int __devexit tegra_pcm_platform_remove(struct platform_device *pdev) 379void __devexit tegra_pcm_platform_unregister(struct device *dev)
381{ 380{
382 snd_soc_unregister_platform(&pdev->dev); 381 snd_soc_unregister_platform(dev);
383 return 0;
384} 382}
385 383EXPORT_SYMBOL_GPL(tegra_pcm_platform_unregister);
386static struct platform_driver tegra_pcm_driver = {
387 .driver = {
388 .name = DRV_NAME,
389 .owner = THIS_MODULE,
390 },
391 .probe = tegra_pcm_platform_probe,
392 .remove = __devexit_p(tegra_pcm_platform_remove),
393};
394module_platform_driver(tegra_pcm_driver);
395 384
396MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); 385MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
397MODULE_DESCRIPTION("Tegra PCM ASoC driver"); 386MODULE_DESCRIPTION("Tegra PCM ASoC driver");
398MODULE_LICENSE("GPL"); 387MODULE_LICENSE("GPL");
399MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h
index dbb90339fe0d..985d418a35e7 100644
--- a/sound/soc/tegra/tegra_pcm.h
+++ b/sound/soc/tegra/tegra_pcm.h
@@ -2,7 +2,7 @@
2 * tegra_pcm.h - Definitions for Tegra PCM driver 2 * tegra_pcm.h - Definitions for Tegra PCM driver
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc. 5 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6 * 6 *
7 * Based on code copyright/by: 7 * Based on code copyright/by:
8 * 8 *
@@ -52,4 +52,7 @@ struct tegra_runtime_data {
52 struct tegra_dma_channel *dma_chan; 52 struct tegra_dma_channel *dma_chan;
53}; 53};
54 54
55int tegra_pcm_platform_register(struct device *dev);
56void tegra_pcm_platform_unregister(struct device *dev);
57
55#endif 58#endif
diff --git a/sound/soc/tegra/tegra_spdif.c b/sound/soc/tegra/tegra_spdif.c
deleted file mode 100644
index 9ff2c601445f..000000000000
--- a/sound/soc/tegra/tegra_spdif.c
+++ /dev/null
@@ -1,364 +0,0 @@
1/*
2 * tegra_spdif.c - Tegra SPDIF driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2011 - NVIDIA, Inc.
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 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include <linux/clk.h>
24#include <linux/module.h>
25#include <linux/debugfs.h>
26#include <linux/device.h>
27#include <linux/platform_device.h>
28#include <linux/seq_file.h>
29#include <linux/slab.h>
30#include <linux/io.h>
31#include <mach/iomap.h>
32#include <sound/core.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/soc.h>
36
37#include "tegra_spdif.h"
38
39#define DRV_NAME "tegra-spdif"
40
41static inline void tegra_spdif_write(struct tegra_spdif *spdif, u32 reg,
42 u32 val)
43{
44 __raw_writel(val, spdif->regs + reg);
45}
46
47static inline u32 tegra_spdif_read(struct tegra_spdif *spdif, u32 reg)
48{
49 return __raw_readl(spdif->regs + reg);
50}
51
52#ifdef CONFIG_DEBUG_FS
53static int tegra_spdif_show(struct seq_file *s, void *unused)
54{
55#define REG(r) { r, #r }
56 static const struct {
57 int offset;
58 const char *name;
59 } regs[] = {
60 REG(TEGRA_SPDIF_CTRL),
61 REG(TEGRA_SPDIF_STATUS),
62 REG(TEGRA_SPDIF_STROBE_CTRL),
63 REG(TEGRA_SPDIF_DATA_FIFO_CSR),
64 REG(TEGRA_SPDIF_CH_STA_RX_A),
65 REG(TEGRA_SPDIF_CH_STA_RX_B),
66 REG(TEGRA_SPDIF_CH_STA_RX_C),
67 REG(TEGRA_SPDIF_CH_STA_RX_D),
68 REG(TEGRA_SPDIF_CH_STA_RX_E),
69 REG(TEGRA_SPDIF_CH_STA_RX_F),
70 REG(TEGRA_SPDIF_CH_STA_TX_A),
71 REG(TEGRA_SPDIF_CH_STA_TX_B),
72 REG(TEGRA_SPDIF_CH_STA_TX_C),
73 REG(TEGRA_SPDIF_CH_STA_TX_D),
74 REG(TEGRA_SPDIF_CH_STA_TX_E),
75 REG(TEGRA_SPDIF_CH_STA_TX_F),
76 };
77#undef REG
78
79 struct tegra_spdif *spdif = s->private;
80 int i;
81
82 clk_enable(spdif->clk_spdif_out);
83
84 for (i = 0; i < ARRAY_SIZE(regs); i++) {
85 u32 val = tegra_spdif_read(spdif, regs[i].offset);
86 seq_printf(s, "%s = %08x\n", regs[i].name, val);
87 }
88
89 clk_disable(spdif->clk_spdif_out);
90
91 return 0;
92}
93
94static int tegra_spdif_debug_open(struct inode *inode, struct file *file)
95{
96 return single_open(file, tegra_spdif_show, inode->i_private);
97}
98
99static const struct file_operations tegra_spdif_debug_fops = {
100 .open = tegra_spdif_debug_open,
101 .read = seq_read,
102 .llseek = seq_lseek,
103 .release = single_release,
104};
105
106static void tegra_spdif_debug_add(struct tegra_spdif *spdif)
107{
108 spdif->debug = debugfs_create_file(DRV_NAME, S_IRUGO,
109 snd_soc_debugfs_root, spdif,
110 &tegra_spdif_debug_fops);
111}
112
113static void tegra_spdif_debug_remove(struct tegra_spdif *spdif)
114{
115 if (spdif->debug)
116 debugfs_remove(spdif->debug);
117}
118#else
119static inline void tegra_spdif_debug_add(struct tegra_spdif *spdif)
120{
121}
122
123static inline void tegra_spdif_debug_remove(struct tegra_spdif *spdif)
124{
125}
126#endif
127
128static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
129 struct snd_pcm_hw_params *params,
130 struct snd_soc_dai *dai)
131{
132 struct device *dev = substream->pcm->card->dev;
133 struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai);
134 int ret, spdifclock;
135
136 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_PACK;
137 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_BIT_MODE_MASK;
138 switch (params_format(params)) {
139 case SNDRV_PCM_FORMAT_S16_LE:
140 spdif->reg_ctrl |= TEGRA_SPDIF_CTRL_PACK;
141 spdif->reg_ctrl |= TEGRA_SPDIF_CTRL_BIT_MODE_16BIT;
142 break;
143 default:
144 return -EINVAL;
145 }
146
147 switch (params_rate(params)) {
148 case 32000:
149 spdifclock = 4096000;
150 break;
151 case 44100:
152 spdifclock = 5644800;
153 break;
154 case 48000:
155 spdifclock = 6144000;
156 break;
157 case 88200:
158 spdifclock = 11289600;
159 break;
160 case 96000:
161 spdifclock = 12288000;
162 break;
163 case 176400:
164 spdifclock = 22579200;
165 break;
166 case 192000:
167 spdifclock = 24576000;
168 break;
169 default:
170 return -EINVAL;
171 }
172
173 ret = clk_set_rate(spdif->clk_spdif_out, spdifclock);
174 if (ret) {
175 dev_err(dev, "Can't set SPDIF clock rate: %d\n", ret);
176 return ret;
177 }
178
179 return 0;
180}
181
182static void tegra_spdif_start_playback(struct tegra_spdif *spdif)
183{
184 spdif->reg_ctrl |= TEGRA_SPDIF_CTRL_TX_EN;
185 tegra_spdif_write(spdif, TEGRA_SPDIF_CTRL, spdif->reg_ctrl);
186}
187
188static void tegra_spdif_stop_playback(struct tegra_spdif *spdif)
189{
190 spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_TX_EN;
191 tegra_spdif_write(spdif, TEGRA_SPDIF_CTRL, spdif->reg_ctrl);
192}
193
194static int tegra_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
195 struct snd_soc_dai *dai)
196{
197 struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai);
198
199 switch (cmd) {
200 case SNDRV_PCM_TRIGGER_START:
201 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
202 case SNDRV_PCM_TRIGGER_RESUME:
203 if (!spdif->clk_refs)
204 clk_enable(spdif->clk_spdif_out);
205 spdif->clk_refs++;
206 tegra_spdif_start_playback(spdif);
207 break;
208 case SNDRV_PCM_TRIGGER_STOP:
209 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
210 case SNDRV_PCM_TRIGGER_SUSPEND:
211 tegra_spdif_stop_playback(spdif);
212 spdif->clk_refs--;
213 if (!spdif->clk_refs)
214 clk_disable(spdif->clk_spdif_out);
215 break;
216 default:
217 return -EINVAL;
218 }
219
220 return 0;
221}
222
223static int tegra_spdif_probe(struct snd_soc_dai *dai)
224{
225 struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai);
226
227 dai->capture_dma_data = NULL;
228 dai->playback_dma_data = &spdif->playback_dma_data;
229
230 return 0;
231}
232
233static const struct snd_soc_dai_ops tegra_spdif_dai_ops = {
234 .hw_params = tegra_spdif_hw_params,
235 .trigger = tegra_spdif_trigger,
236};
237
238static struct snd_soc_dai_driver tegra_spdif_dai = {
239 .name = DRV_NAME,
240 .probe = tegra_spdif_probe,
241 .playback = {
242 .channels_min = 2,
243 .channels_max = 2,
244 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
245 SNDRV_PCM_RATE_48000,
246 .formats = SNDRV_PCM_FMTBIT_S16_LE,
247 },
248 .ops = &tegra_spdif_dai_ops,
249};
250
251static __devinit int tegra_spdif_platform_probe(struct platform_device *pdev)
252{
253 struct tegra_spdif *spdif;
254 struct resource *mem, *memregion, *dmareq;
255 int ret;
256
257 spdif = kzalloc(sizeof(struct tegra_spdif), GFP_KERNEL);
258 if (!spdif) {
259 dev_err(&pdev->dev, "Can't allocate tegra_spdif\n");
260 ret = -ENOMEM;
261 goto exit;
262 }
263 dev_set_drvdata(&pdev->dev, spdif);
264
265 spdif->clk_spdif_out = clk_get(&pdev->dev, "spdif_out");
266 if (IS_ERR(spdif->clk_spdif_out)) {
267 pr_err("Can't retrieve spdif clock\n");
268 ret = PTR_ERR(spdif->clk_spdif_out);
269 goto err_free;
270 }
271
272 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
273 if (!mem) {
274 dev_err(&pdev->dev, "No memory resource\n");
275 ret = -ENODEV;
276 goto err_clk_put;
277 }
278
279 dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
280 if (!dmareq) {
281 dev_err(&pdev->dev, "No DMA resource\n");
282 ret = -ENODEV;
283 goto err_clk_put;
284 }
285
286 memregion = request_mem_region(mem->start, resource_size(mem),
287 DRV_NAME);
288 if (!memregion) {
289 dev_err(&pdev->dev, "Memory region already claimed\n");
290 ret = -EBUSY;
291 goto err_clk_put;
292 }
293
294 spdif->regs = ioremap(mem->start, resource_size(mem));
295 if (!spdif->regs) {
296 dev_err(&pdev->dev, "ioremap failed\n");
297 ret = -ENOMEM;
298 goto err_release;
299 }
300
301 spdif->playback_dma_data.addr = mem->start + TEGRA_SPDIF_DATA_OUT;
302 spdif->playback_dma_data.wrap = 4;
303 spdif->playback_dma_data.width = 32;
304 spdif->playback_dma_data.req_sel = dmareq->start;
305
306 ret = snd_soc_register_dai(&pdev->dev, &tegra_spdif_dai);
307 if (ret) {
308 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
309 ret = -ENOMEM;
310 goto err_unmap;
311 }
312
313 tegra_spdif_debug_add(spdif);
314
315 return 0;
316
317err_unmap:
318 iounmap(spdif->regs);
319err_release:
320 release_mem_region(mem->start, resource_size(mem));
321err_clk_put:
322 clk_put(spdif->clk_spdif_out);
323err_free:
324 kfree(spdif);
325exit:
326 return ret;
327}
328
329static int __devexit tegra_spdif_platform_remove(struct platform_device *pdev)
330{
331 struct tegra_spdif *spdif = dev_get_drvdata(&pdev->dev);
332 struct resource *res;
333
334 snd_soc_unregister_dai(&pdev->dev);
335
336 tegra_spdif_debug_remove(spdif);
337
338 iounmap(spdif->regs);
339
340 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
341 release_mem_region(res->start, resource_size(res));
342
343 clk_put(spdif->clk_spdif_out);
344
345 kfree(spdif);
346
347 return 0;
348}
349
350static struct platform_driver tegra_spdif_driver = {
351 .driver = {
352 .name = DRV_NAME,
353 .owner = THIS_MODULE,
354 },
355 .probe = tegra_spdif_platform_probe,
356 .remove = __devexit_p(tegra_spdif_platform_remove),
357};
358
359module_platform_driver(tegra_spdif_driver);
360
361MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
362MODULE_DESCRIPTION("Tegra SPDIF ASoC driver");
363MODULE_LICENSE("GPL");
364MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_spdif.h b/sound/soc/tegra/tegra_spdif.h
deleted file mode 100644
index 2e03db430279..000000000000
--- a/sound/soc/tegra/tegra_spdif.h
+++ /dev/null
@@ -1,473 +0,0 @@
1/*
2 * tegra_spdif.h - Definitions for Tegra SPDIF driver
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2011 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 * Copyright (c) 2008-2009, NVIDIA Corporation
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 */
25
26#ifndef __TEGRA_SPDIF_H__
27#define __TEGRA_SPDIF_H__
28
29#include "tegra_pcm.h"
30
31/* Offsets from TEGRA_SPDIF_BASE */
32
33#define TEGRA_SPDIF_CTRL 0x0
34#define TEGRA_SPDIF_STATUS 0x4
35#define TEGRA_SPDIF_STROBE_CTRL 0x8
36#define TEGRA_SPDIF_DATA_FIFO_CSR 0x0C
37#define TEGRA_SPDIF_DATA_OUT 0x40
38#define TEGRA_SPDIF_DATA_IN 0x80
39#define TEGRA_SPDIF_CH_STA_RX_A 0x100
40#define TEGRA_SPDIF_CH_STA_RX_B 0x104
41#define TEGRA_SPDIF_CH_STA_RX_C 0x108
42#define TEGRA_SPDIF_CH_STA_RX_D 0x10C
43#define TEGRA_SPDIF_CH_STA_RX_E 0x110
44#define TEGRA_SPDIF_CH_STA_RX_F 0x114
45#define TEGRA_SPDIF_CH_STA_TX_A 0x140
46#define TEGRA_SPDIF_CH_STA_TX_B 0x144
47#define TEGRA_SPDIF_CH_STA_TX_C 0x148
48#define TEGRA_SPDIF_CH_STA_TX_D 0x14C
49#define TEGRA_SPDIF_CH_STA_TX_E 0x150
50#define TEGRA_SPDIF_CH_STA_TX_F 0x154
51#define TEGRA_SPDIF_USR_STA_RX_A 0x180
52#define TEGRA_SPDIF_USR_DAT_TX_A 0x1C0
53
54/* Fields in TEGRA_SPDIF_CTRL */
55
56/* Start capturing from 0=right, 1=left channel */
57#define TEGRA_SPDIF_CTRL_CAP_LC (1 << 30)
58
59/* SPDIF receiver(RX) enable */
60#define TEGRA_SPDIF_CTRL_RX_EN (1 << 29)
61
62/* SPDIF Transmitter(TX) enable */
63#define TEGRA_SPDIF_CTRL_TX_EN (1 << 28)
64
65/* Transmit Channel status */
66#define TEGRA_SPDIF_CTRL_TC_EN (1 << 27)
67
68/* Transmit user Data */
69#define TEGRA_SPDIF_CTRL_TU_EN (1 << 26)
70
71/* Interrupt on transmit error */
72#define TEGRA_SPDIF_CTRL_IE_TXE (1 << 25)
73
74/* Interrupt on receive error */
75#define TEGRA_SPDIF_CTRL_IE_RXE (1 << 24)
76
77/* Interrupt on invalid preamble */
78#define TEGRA_SPDIF_CTRL_IE_P (1 << 23)
79
80/* Interrupt on "B" preamble */
81#define TEGRA_SPDIF_CTRL_IE_B (1 << 22)
82
83/* Interrupt when block of channel status received */
84#define TEGRA_SPDIF_CTRL_IE_C (1 << 21)
85
86/* Interrupt when a valid information unit (IU) is received */
87#define TEGRA_SPDIF_CTRL_IE_U (1 << 20)
88
89/* Interrupt when RX user FIFO attention level is reached */
90#define TEGRA_SPDIF_CTRL_QE_RU (1 << 19)
91
92/* Interrupt when TX user FIFO attention level is reached */
93#define TEGRA_SPDIF_CTRL_QE_TU (1 << 18)
94
95/* Interrupt when RX data FIFO attention level is reached */
96#define TEGRA_SPDIF_CTRL_QE_RX (1 << 17)
97
98/* Interrupt when TX data FIFO attention level is reached */
99#define TEGRA_SPDIF_CTRL_QE_TX (1 << 16)
100
101/* Loopback test mode enable */
102#define TEGRA_SPDIF_CTRL_LBK_EN (1 << 15)
103
104/*
105 * Pack data mode:
106 * 0 = Single data (16 bit needs to be padded to match the
107 * interface data bit size).
108 * 1 = Packeted left/right channel data into a single word.
109 */
110#define TEGRA_SPDIF_CTRL_PACK (1 << 14)
111
112/*
113 * 00 = 16bit data
114 * 01 = 20bit data
115 * 10 = 24bit data
116 * 11 = raw data
117 */
118#define TEGRA_SPDIF_BIT_MODE_16BIT 0
119#define TEGRA_SPDIF_BIT_MODE_20BIT 1
120#define TEGRA_SPDIF_BIT_MODE_24BIT 2
121#define TEGRA_SPDIF_BIT_MODE_RAW 3
122
123#define TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT 12
124#define TEGRA_SPDIF_CTRL_BIT_MODE_MASK (3 << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
125#define TEGRA_SPDIF_CTRL_BIT_MODE_16BIT (TEGRA_SPDIF_BIT_MODE_16BIT << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
126#define TEGRA_SPDIF_CTRL_BIT_MODE_20BIT (TEGRA_SPDIF_BIT_MODE_20BIT << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
127#define TEGRA_SPDIF_CTRL_BIT_MODE_24BIT (TEGRA_SPDIF_BIT_MODE_24BIT << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
128#define TEGRA_SPDIF_CTRL_BIT_MODE_RAW (TEGRA_SPDIF_BIT_MODE_RAW << TEGRA_SPDIF_CTRL_BIT_MODE_SHIFT)
129
130/* Fields in TEGRA_SPDIF_STATUS */
131
132/*
133 * Note: IS_P, IS_B, IS_C, and IS_U are sticky bits. Software must
134 * write a 1 to the corresponding bit location to clear the status.
135 */
136
137/*
138 * Receiver(RX) shifter is busy receiving data.
139 * This bit is asserted when the receiver first locked onto the
140 * preamble of the data stream after RX_EN is asserted. This bit is
141 * deasserted when either,
142 * (a) the end of a frame is reached after RX_EN is deeasserted, or
143 * (b) the SPDIF data stream becomes inactive.
144 */
145#define TEGRA_SPDIF_STATUS_RX_BSY (1 << 29)
146
147/*
148 * Transmitter(TX) shifter is busy transmitting data.
149 * This bit is asserted when TX_EN is asserted.
150 * This bit is deasserted when the end of a frame is reached after
151 * TX_EN is deasserted.
152 */
153#define TEGRA_SPDIF_STATUS_TX_BSY (1 << 28)
154
155/*
156 * TX is busy shifting out channel status.
157 * This bit is asserted when both TX_EN and TC_EN are asserted and
158 * data from CH_STA_TX_A register is loaded into the internal shifter.
159 * This bit is deasserted when either,
160 * (a) the end of a frame is reached after TX_EN is deasserted, or
161 * (b) CH_STA_TX_F register is loaded into the internal shifter.
162 */
163#define TEGRA_SPDIF_STATUS_TC_BSY (1 << 27)
164
165/*
166 * TX User data FIFO busy.
167 * This bit is asserted when TX_EN and TXU_EN are asserted and
168 * there's data in the TX user FIFO. This bit is deassert when either,
169 * (a) the end of a frame is reached after TX_EN is deasserted, or
170 * (b) there's no data left in the TX user FIFO.
171 */
172#define TEGRA_SPDIF_STATUS_TU_BSY (1 << 26)
173
174/* TX FIFO Underrun error status */
175#define TEGRA_SPDIF_STATUS_TX_ERR (1 << 25)
176
177/* RX FIFO Overrun error status */
178#define TEGRA_SPDIF_STATUS_RX_ERR (1 << 24)
179
180/* Preamble status: 0=Preamble OK, 1=bad/missing preamble */
181#define TEGRA_SPDIF_STATUS_IS_P (1 << 23)
182
183/* B-preamble detection status: 0=not detected, 1=B-preamble detected */
184#define TEGRA_SPDIF_STATUS_IS_B (1 << 22)
185
186/*
187 * RX channel block data receive status:
188 * 0=entire block not recieved yet.
189 * 1=received entire block of channel status,
190 */
191#define TEGRA_SPDIF_STATUS_IS_C (1 << 21)
192
193/* RX User Data Valid flag: 1=valid IU detected, 0 = no IU detected. */
194#define TEGRA_SPDIF_STATUS_IS_U (1 << 20)
195
196/*
197 * RX User FIFO Status:
198 * 1=attention level reached, 0=attention level not reached.
199 */
200#define TEGRA_SPDIF_STATUS_QS_RU (1 << 19)
201
202/*
203 * TX User FIFO Status:
204 * 1=attention level reached, 0=attention level not reached.
205 */
206#define TEGRA_SPDIF_STATUS_QS_TU (1 << 18)
207
208/*
209 * RX Data FIFO Status:
210 * 1=attention level reached, 0=attention level not reached.
211 */
212#define TEGRA_SPDIF_STATUS_QS_RX (1 << 17)
213
214/*
215 * TX Data FIFO Status:
216 * 1=attention level reached, 0=attention level not reached.
217 */
218#define TEGRA_SPDIF_STATUS_QS_TX (1 << 16)
219
220/* Fields in TEGRA_SPDIF_STROBE_CTRL */
221
222/*
223 * Indicates the approximate number of detected SPDIFIN clocks within a
224 * bi-phase period.
225 */
226#define TEGRA_SPDIF_STROBE_CTRL_PERIOD_SHIFT 16
227#define TEGRA_SPDIF_STROBE_CTRL_PERIOD_MASK (0xff << TEGRA_SPDIF_STROBE_CTRL_PERIOD_SHIFT)
228
229/* Data strobe mode: 0=Auto-locked 1=Manual locked */
230#define TEGRA_SPDIF_STROBE_CTRL_STROBE (1 << 15)
231
232/*
233 * Manual data strobe time within the bi-phase clock period (in terms of
234 * the number of over-sampling clocks).
235 */
236#define TEGRA_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT 8
237#define TEGRA_SPDIF_STROBE_CTRL_DATA_STROBES_MASK (0x1f << TEGRA_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT)
238
239/*
240 * Manual SPDIFIN bi-phase clock period (in terms of the number of
241 * over-sampling clocks).
242 */
243#define TEGRA_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT 0
244#define TEGRA_SPDIF_STROBE_CTRL_CLOCK_PERIOD_MASK (0x3f << TEGRA_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT)
245
246/* Fields in SPDIF_DATA_FIFO_CSR */
247
248/* Clear Receiver User FIFO (RX USR.FIFO) */
249#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_CLR (1 << 31)
250
251#define TEGRA_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT 0
252#define TEGRA_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS 1
253#define TEGRA_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS 2
254#define TEGRA_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS 3
255
256/* RU FIFO attention level */
257#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT 29
258#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_MASK \
259 (0x3 << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
260#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU1_WORD_FULL \
261 (TEGRA_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
262#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU2_WORD_FULL \
263 (TEGRA_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
264#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU3_WORD_FULL \
265 (TEGRA_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
266#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_RU4_WORD_FULL \
267 (TEGRA_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RU_ATN_LVL_SHIFT)
268
269/* Number of RX USR.FIFO levels with valid data. */
270#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_SHIFT 24
271#define TEGRA_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_MASK (0x1f << TEGRA_SPDIF_DATA_FIFO_CSR_RU_FULL_COUNT_SHIFT)
272
273/* Clear Transmitter User FIFO (TX USR.FIFO) */
274#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_CLR (1 << 23)
275
276/* TU FIFO attention level */
277#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT 21
278#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_MASK \
279 (0x3 << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
280#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU1_WORD_FULL \
281 (TEGRA_SPDIF_FIFO_ATN_LVL_U_ONE_SLOT << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
282#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU2_WORD_FULL \
283 (TEGRA_SPDIF_FIFO_ATN_LVL_U_TWO_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
284#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU3_WORD_FULL \
285 (TEGRA_SPDIF_FIFO_ATN_LVL_U_THREE_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
286#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_TU4_WORD_FULL \
287 (TEGRA_SPDIF_FIFO_ATN_LVL_U_FOUR_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TU_ATN_LVL_SHIFT)
288
289/* Number of TX USR.FIFO levels that could be filled. */
290#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_SHIFT 16
291#define TEGRA_SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_MASK (0x1f << SPDIF_DATA_FIFO_CSR_TU_EMPTY_COUNT_SHIFT)
292
293/* Clear Receiver Data FIFO (RX DATA.FIFO) */
294#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_CLR (1 << 15)
295
296#define TEGRA_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT 0
297#define TEGRA_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS 1
298#define TEGRA_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS 2
299#define TEGRA_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS 3
300
301/* RU FIFO attention level */
302#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT 13
303#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_MASK \
304 (0x3 << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
305#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU1_WORD_FULL \
306 (TEGRA_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
307#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU4_WORD_FULL \
308 (TEGRA_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
309#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU8_WORD_FULL \
310 (TEGRA_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
311#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_RU12_WORD_FULL \
312 (TEGRA_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_RX_ATN_LVL_SHIFT)
313
314/* Number of RX DATA.FIFO levels with valid data. */
315#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_SHIFT 8
316#define TEGRA_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_MASK (0x1f << TEGRA_SPDIF_DATA_FIFO_CSR_RX_FULL_COUNT_SHIFT)
317
318/* Clear Transmitter Data FIFO (TX DATA.FIFO) */
319#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_CLR (1 << 7)
320
321/* TU FIFO attention level */
322#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT 5
323#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_MASK \
324 (0x3 << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
325#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU1_WORD_FULL \
326 (TEGRA_SPDIF_FIFO_ATN_LVL_D_ONE_SLOT << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
327#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU4_WORD_FULL \
328 (TEGRA_SPDIF_FIFO_ATN_LVL_D_FOUR_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
329#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU8_WORD_FULL \
330 (TEGRA_SPDIF_FIFO_ATN_LVL_D_EIGHT_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
331#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU12_WORD_FULL \
332 (TEGRA_SPDIF_FIFO_ATN_LVL_D_TWELVE_SLOTS << TEGRA_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_SHIFT)
333
334/* Number of TX DATA.FIFO levels that could be filled. */
335#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_SHIFT 0
336#define TEGRA_SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_MASK (0x1f << SPDIF_DATA_FIFO_CSR_TX_EMPTY_COUNT_SHIFT)
337
338/* Fields in TEGRA_SPDIF_DATA_OUT */
339
340/*
341 * This register has 5 different formats:
342 * 16-bit (BIT_MODE=00, PACK=0)
343 * 20-bit (BIT_MODE=01, PACK=0)
344 * 24-bit (BIT_MODE=10, PACK=0)
345 * raw (BIT_MODE=11, PACK=0)
346 * 16-bit packed (BIT_MODE=00, PACK=1)
347 */
348
349#define TEGRA_SPDIF_DATA_OUT_DATA_16_SHIFT 0
350#define TEGRA_SPDIF_DATA_OUT_DATA_16_MASK (0xffff << TEGRA_SPDIF_DATA_OUT_DATA_16_SHIFT)
351
352#define TEGRA_SPDIF_DATA_OUT_DATA_20_SHIFT 0
353#define TEGRA_SPDIF_DATA_OUT_DATA_20_MASK (0xfffff << TEGRA_SPDIF_DATA_OUT_DATA_20_SHIFT)
354
355#define TEGRA_SPDIF_DATA_OUT_DATA_24_SHIFT 0
356#define TEGRA_SPDIF_DATA_OUT_DATA_24_MASK (0xffffff << TEGRA_SPDIF_DATA_OUT_DATA_24_SHIFT)
357
358#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_P (1 << 31)
359#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_C (1 << 30)
360#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_U (1 << 29)
361#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_V (1 << 28)
362
363#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_DATA_SHIFT 8
364#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_DATA_MASK (0xfffff << TEGRA_SPDIF_DATA_OUT_DATA_RAW_DATA_SHIFT)
365
366#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_AUX_SHIFT 4
367#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_AUX_MASK (0xf << TEGRA_SPDIF_DATA_OUT_DATA_RAW_AUX_SHIFT)
368
369#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_SHIFT 0
370#define TEGRA_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_MASK (0xf << TEGRA_SPDIF_DATA_OUT_DATA_RAW_PREAMBLE_SHIFT)
371
372#define TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_SHIFT 16
373#define TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_MASK (0xffff << TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_RIGHT_SHIFT)
374
375#define TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_SHIFT 0
376#define TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_MASK (0xffff << TEGRA_SPDIF_DATA_OUT_DATA_16_PACKED_LEFT_SHIFT)
377
378/* Fields in TEGRA_SPDIF_DATA_IN */
379
380/*
381 * This register has 5 different formats:
382 * 16-bit (BIT_MODE=00, PACK=0)
383 * 20-bit (BIT_MODE=01, PACK=0)
384 * 24-bit (BIT_MODE=10, PACK=0)
385 * raw (BIT_MODE=11, PACK=0)
386 * 16-bit packed (BIT_MODE=00, PACK=1)
387 *
388 * Bits 31:24 are common to all modes except 16-bit packed
389 */
390
391#define TEGRA_SPDIF_DATA_IN_DATA_P (1 << 31)
392#define TEGRA_SPDIF_DATA_IN_DATA_C (1 << 30)
393#define TEGRA_SPDIF_DATA_IN_DATA_U (1 << 29)
394#define TEGRA_SPDIF_DATA_IN_DATA_V (1 << 28)
395
396#define TEGRA_SPDIF_DATA_IN_DATA_PREAMBLE_SHIFT 24
397#define TEGRA_SPDIF_DATA_IN_DATA_PREAMBLE_MASK (0xf << TEGRA_SPDIF_DATA_IN_DATA_PREAMBLE_SHIFT)
398
399#define TEGRA_SPDIF_DATA_IN_DATA_16_SHIFT 0
400#define TEGRA_SPDIF_DATA_IN_DATA_16_MASK (0xffff << TEGRA_SPDIF_DATA_IN_DATA_16_SHIFT)
401
402#define TEGRA_SPDIF_DATA_IN_DATA_20_SHIFT 0
403#define TEGRA_SPDIF_DATA_IN_DATA_20_MASK (0xfffff << TEGRA_SPDIF_DATA_IN_DATA_20_SHIFT)
404
405#define TEGRA_SPDIF_DATA_IN_DATA_24_SHIFT 0
406#define TEGRA_SPDIF_DATA_IN_DATA_24_MASK (0xffffff << TEGRA_SPDIF_DATA_IN_DATA_24_SHIFT)
407
408#define TEGRA_SPDIF_DATA_IN_DATA_RAW_DATA_SHIFT 8
409#define TEGRA_SPDIF_DATA_IN_DATA_RAW_DATA_MASK (0xfffff << TEGRA_SPDIF_DATA_IN_DATA_RAW_DATA_SHIFT)
410
411#define TEGRA_SPDIF_DATA_IN_DATA_RAW_AUX_SHIFT 4
412#define TEGRA_SPDIF_DATA_IN_DATA_RAW_AUX_MASK (0xf << TEGRA_SPDIF_DATA_IN_DATA_RAW_AUX_SHIFT)
413
414#define TEGRA_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_SHIFT 0
415#define TEGRA_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_MASK (0xf << TEGRA_SPDIF_DATA_IN_DATA_RAW_PREAMBLE_SHIFT)
416
417#define TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_SHIFT 16
418#define TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_MASK (0xffff << TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_RIGHT_SHIFT)
419
420#define TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_SHIFT 0
421#define TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_MASK (0xffff << TEGRA_SPDIF_DATA_IN_DATA_16_PACKED_LEFT_SHIFT)
422
423/* Fields in TEGRA_SPDIF_CH_STA_RX_A */
424/* Fields in TEGRA_SPDIF_CH_STA_RX_B */
425/* Fields in TEGRA_SPDIF_CH_STA_RX_C */
426/* Fields in TEGRA_SPDIF_CH_STA_RX_D */
427/* Fields in TEGRA_SPDIF_CH_STA_RX_E */
428/* Fields in TEGRA_SPDIF_CH_STA_RX_F */
429
430/*
431 * The 6-word receive channel data page buffer holds a block (192 frames) of
432 * channel status information. The order of receive is from LSB to MSB
433 * bit, and from CH_STA_RX_A to CH_STA_RX_F then back to CH_STA_RX_A.
434 */
435
436/* Fields in TEGRA_SPDIF_CH_STA_TX_A */
437/* Fields in TEGRA_SPDIF_CH_STA_TX_B */
438/* Fields in TEGRA_SPDIF_CH_STA_TX_C */
439/* Fields in TEGRA_SPDIF_CH_STA_TX_D */
440/* Fields in TEGRA_SPDIF_CH_STA_TX_E */
441/* Fields in TEGRA_SPDIF_CH_STA_TX_F */
442
443/*
444 * The 6-word transmit channel data page buffer holds a block (192 frames) of
445 * channel status information. The order of transmission is from LSB to MSB
446 * bit, and from CH_STA_TX_A to CH_STA_TX_F then back to CH_STA_TX_A.
447 */
448
449/* Fields in TEGRA_SPDIF_USR_STA_RX_A */
450
451/*
452 * This 4-word deep FIFO receives user FIFO field information. The order of
453 * receive is from LSB to MSB bit.
454 */
455
456/* Fields in TEGRA_SPDIF_USR_DAT_TX_A */
457
458/*
459 * This 4-word deep FIFO transmits user FIFO field information. The order of
460 * transmission is from LSB to MSB bit.
461 */
462
463struct tegra_spdif {
464 struct clk *clk_spdif_out;
465 int clk_refs;
466 struct tegra_pcm_dma_params capture_dma_data;
467 struct tegra_pcm_dma_params playback_dma_data;
468 void __iomem *regs;
469 struct dentry *debug;
470 u32 reg_ctrl;
471};
472
473#endif
diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c
new file mode 100644
index 000000000000..4e77026807a2
--- /dev/null
+++ b/sound/soc/tegra/tegra_wm8753.c
@@ -0,0 +1,224 @@
1/*
2 * tegra_wm8753.c - Tegra machine ASoC driver for boards using WM8753 codec.
3 *
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010-2012 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd.
10 *
11 * Copyright 2007 Wolfson Microelectronics PLC.
12 * Author: Graeme Gregory
13 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#include <asm/mach-types.h>
32
33#include <linux/module.h>
34#include <linux/platform_device.h>
35#include <linux/slab.h>
36#include <linux/gpio.h>
37#include <linux/of_gpio.h>
38
39#include <sound/core.h>
40#include <sound/jack.h>
41#include <sound/pcm.h>
42#include <sound/pcm_params.h>
43#include <sound/soc.h>
44
45#include "../codecs/wm8753.h"
46
47#include "tegra_asoc_utils.h"
48
49#define DRV_NAME "tegra-snd-wm8753"
50
51struct tegra_wm8753 {
52 struct tegra_asoc_utils_data util_data;
53};
54
55static int tegra_wm8753_hw_params(struct snd_pcm_substream *substream,
56 struct snd_pcm_hw_params *params)
57{
58 struct snd_soc_pcm_runtime *rtd = substream->private_data;
59 struct snd_soc_dai *codec_dai = rtd->codec_dai;
60 struct snd_soc_codec *codec = rtd->codec;
61 struct snd_soc_card *card = codec->card;
62 struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card);
63 int srate, mclk;
64 int err;
65
66 srate = params_rate(params);
67 switch (srate) {
68 case 11025:
69 case 22050:
70 case 44100:
71 case 88200:
72 mclk = 11289600;
73 break;
74 default:
75 mclk = 12288000;
76 break;
77 }
78
79 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
80 if (err < 0) {
81 dev_err(card->dev, "Can't configure clocks\n");
82 return err;
83 }
84
85 err = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, mclk,
86 SND_SOC_CLOCK_IN);
87 if (err < 0) {
88 dev_err(card->dev, "codec_dai clock not set\n");
89 return err;
90 }
91
92 return 0;
93}
94
95static struct snd_soc_ops tegra_wm8753_ops = {
96 .hw_params = tegra_wm8753_hw_params,
97};
98
99static const struct snd_soc_dapm_widget tegra_wm8753_dapm_widgets[] = {
100 SND_SOC_DAPM_HP("Headphone Jack", NULL),
101 SND_SOC_DAPM_MIC("Mic Jack", NULL),
102};
103
104static struct snd_soc_dai_link tegra_wm8753_dai = {
105 .name = "WM8753",
106 .stream_name = "WM8753 PCM",
107 .codec_dai_name = "wm8753-hifi",
108 .ops = &tegra_wm8753_ops,
109 .dai_fmt = SND_SOC_DAIFMT_I2S |
110 SND_SOC_DAIFMT_NB_NF |
111 SND_SOC_DAIFMT_CBS_CFS,
112};
113
114static struct snd_soc_card snd_soc_tegra_wm8753 = {
115 .name = "tegra-wm8753",
116 .owner = THIS_MODULE,
117 .dai_link = &tegra_wm8753_dai,
118 .num_links = 1,
119
120 .dapm_widgets = tegra_wm8753_dapm_widgets,
121 .num_dapm_widgets = ARRAY_SIZE(tegra_wm8753_dapm_widgets),
122 .fully_routed = true,
123};
124
125static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev)
126{
127 struct snd_soc_card *card = &snd_soc_tegra_wm8753;
128 struct tegra_wm8753 *machine;
129 int ret;
130
131 machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8753),
132 GFP_KERNEL);
133 if (!machine) {
134 dev_err(&pdev->dev, "Can't allocate tegra_wm8753 struct\n");
135 ret = -ENOMEM;
136 goto err;
137 }
138
139 card->dev = &pdev->dev;
140 platform_set_drvdata(pdev, card);
141 snd_soc_card_set_drvdata(card, machine);
142
143 ret = snd_soc_of_parse_card_name(card, "nvidia,model");
144 if (ret)
145 goto err;
146
147 ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
148 if (ret)
149 goto err;
150
151 tegra_wm8753_dai.codec_of_node = of_parse_phandle(
152 pdev->dev.of_node, "nvidia,audio-codec", 0);
153 if (!tegra_wm8753_dai.codec_of_node) {
154 dev_err(&pdev->dev,
155 "Property 'nvidia,audio-codec' missing or invalid\n");
156 ret = -EINVAL;
157 goto err;
158 }
159
160 tegra_wm8753_dai.cpu_dai_of_node = of_parse_phandle(
161 pdev->dev.of_node, "nvidia,i2s-controller", 0);
162 if (!tegra_wm8753_dai.cpu_dai_of_node) {
163 dev_err(&pdev->dev,
164 "Property 'nvidia,i2s-controller' missing or invalid\n");
165 ret = -EINVAL;
166 goto err;
167 }
168
169 tegra_wm8753_dai.platform_of_node =
170 tegra_wm8753_dai.cpu_dai_of_node;
171
172 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
173 if (ret)
174 goto err;
175
176 ret = snd_soc_register_card(card);
177 if (ret) {
178 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
179 ret);
180 goto err_fini_utils;
181 }
182
183 return 0;
184
185err_fini_utils:
186 tegra_asoc_utils_fini(&machine->util_data);
187err:
188 return ret;
189}
190
191static int __devexit tegra_wm8753_driver_remove(struct platform_device *pdev)
192{
193 struct snd_soc_card *card = platform_get_drvdata(pdev);
194 struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card);
195
196 snd_soc_unregister_card(card);
197
198 tegra_asoc_utils_fini(&machine->util_data);
199
200 return 0;
201}
202
203static const struct of_device_id tegra_wm8753_of_match[] __devinitconst = {
204 { .compatible = "nvidia,tegra-audio-wm8753", },
205 {},
206};
207
208static struct platform_driver tegra_wm8753_driver = {
209 .driver = {
210 .name = DRV_NAME,
211 .owner = THIS_MODULE,
212 .pm = &snd_soc_pm_ops,
213 .of_match_table = tegra_wm8753_of_match,
214 },
215 .probe = tegra_wm8753_driver_probe,
216 .remove = __devexit_p(tegra_wm8753_driver_remove),
217};
218module_platform_driver(tegra_wm8753_driver);
219
220MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
221MODULE_DESCRIPTION("Tegra+WM8753 machine ASoC driver");
222MODULE_LICENSE("GPL");
223MODULE_ALIAS("platform:" DRV_NAME);
224MODULE_DEVICE_TABLE(of, tegra_wm8753_of_match);
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index 566655e23b7d..0b0df49d9d33 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -2,7 +2,7 @@
2 * tegra_wm8903.c - Tegra machine ASoC driver for boards using WM8903 codec. 2 * tegra_wm8903.c - Tegra machine ASoC driver for boards using WM8903 codec.
3 * 3 *
4 * Author: Stephen Warren <swarren@nvidia.com> 4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010-2011 - NVIDIA, Inc. 5 * Copyright (C) 2010-2012 - NVIDIA, Inc.
6 * 6 *
7 * Based on code copyright/by: 7 * Based on code copyright/by:
8 * 8 *
@@ -46,9 +46,6 @@
46 46
47#include "../codecs/wm8903.h" 47#include "../codecs/wm8903.h"
48 48
49#include "tegra_das.h"
50#include "tegra_i2s.h"
51#include "tegra_pcm.h"
52#include "tegra_asoc_utils.h" 49#include "tegra_asoc_utils.h"
53 50
54#define DRV_NAME "tegra-snd-wm8903" 51#define DRV_NAME "tegra-snd-wm8903"
@@ -61,7 +58,6 @@
61 58
62struct tegra_wm8903 { 59struct tegra_wm8903 {
63 struct tegra_wm8903_platform_data pdata; 60 struct tegra_wm8903_platform_data pdata;
64 struct platform_device *pcm_dev;
65 struct tegra_asoc_utils_data util_data; 61 struct tegra_asoc_utils_data util_data;
66 int gpio_requested; 62 int gpio_requested;
67}; 63};
@@ -354,8 +350,8 @@ static struct snd_soc_dai_link tegra_wm8903_dai = {
354 .name = "WM8903", 350 .name = "WM8903",
355 .stream_name = "WM8903 PCM", 351 .stream_name = "WM8903 PCM",
356 .codec_name = "wm8903.0-001a", 352 .codec_name = "wm8903.0-001a",
357 .platform_name = "tegra-pcm-audio", 353 .platform_name = "tegra20-i2s.0",
358 .cpu_dai_name = "tegra-i2s.0", 354 .cpu_dai_name = "tegra20-i2s.0",
359 .codec_dai_name = "wm8903-hifi", 355 .codec_dai_name = "wm8903-hifi",
360 .init = tegra_wm8903_init, 356 .init = tegra_wm8903_init,
361 .ops = &tegra_wm8903_ops, 357 .ops = &tegra_wm8903_ops,
@@ -392,7 +388,6 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
392 ret = -ENOMEM; 388 ret = -ENOMEM;
393 goto err; 389 goto err;
394 } 390 }
395 machine->pcm_dev = ERR_PTR(-EINVAL);
396 391
397 card->dev = &pdev->dev; 392 card->dev = &pdev->dev;
398 platform_set_drvdata(pdev, card); 393 platform_set_drvdata(pdev, card);
@@ -428,14 +423,9 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
428 goto err; 423 goto err;
429 } 424 }
430 425
431 machine->pcm_dev = platform_device_register_simple( 426 tegra_wm8903_dai.platform_name = NULL;
432 "tegra-pcm-audio", -1, NULL, 0); 427 tegra_wm8903_dai.platform_of_node =
433 if (IS_ERR(machine->pcm_dev)) { 428 tegra_wm8903_dai.cpu_dai_of_node;
434 dev_err(&pdev->dev,
435 "Can't instantiate tegra-pcm-audio\n");
436 ret = PTR_ERR(machine->pcm_dev);
437 goto err;
438 }
439 } else { 429 } else {
440 if (machine_is_harmony()) { 430 if (machine_is_harmony()) {
441 card->dapm_routes = harmony_audio_map; 431 card->dapm_routes = harmony_audio_map;
@@ -454,7 +444,7 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
454 444
455 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); 445 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
456 if (ret) 446 if (ret)
457 goto err_unregister; 447 goto err;
458 448
459 ret = snd_soc_register_card(card); 449 ret = snd_soc_register_card(card);
460 if (ret) { 450 if (ret) {
@@ -467,9 +457,6 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
467 457
468err_fini_utils: 458err_fini_utils:
469 tegra_asoc_utils_fini(&machine->util_data); 459 tegra_asoc_utils_fini(&machine->util_data);
470err_unregister:
471 if (!IS_ERR(machine->pcm_dev))
472 platform_device_unregister(machine->pcm_dev);
473err: 460err:
474 return ret; 461 return ret;
475} 462}
@@ -497,8 +484,6 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev)
497 snd_soc_unregister_card(card); 484 snd_soc_unregister_card(card);
498 485
499 tegra_asoc_utils_fini(&machine->util_data); 486 tegra_asoc_utils_fini(&machine->util_data);
500 if (!IS_ERR(machine->pcm_dev))
501 platform_device_unregister(machine->pcm_dev);
502 487
503 return 0; 488 return 0;
504} 489}
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
index 2bdfc550cff8..4a8d5b672c9f 100644
--- a/sound/soc/tegra/trimslice.c
+++ b/sound/soc/tegra/trimslice.c
@@ -27,6 +27,7 @@
27#include <asm/mach-types.h> 27#include <asm/mach-types.h>
28 28
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/of.h>
30#include <linux/platform_device.h> 31#include <linux/platform_device.h>
31#include <linux/slab.h> 32#include <linux/slab.h>
32 33
@@ -38,9 +39,6 @@
38 39
39#include "../codecs/tlv320aic23.h" 40#include "../codecs/tlv320aic23.h"
40 41
41#include "tegra_das.h"
42#include "tegra_i2s.h"
43#include "tegra_pcm.h"
44#include "tegra_asoc_utils.h" 42#include "tegra_asoc_utils.h"
45 43
46#define DRV_NAME "tegra-snd-trimslice" 44#define DRV_NAME "tegra-snd-trimslice"
@@ -119,8 +117,8 @@ static struct snd_soc_dai_link trimslice_tlv320aic23_dai = {
119 .name = "TLV320AIC23", 117 .name = "TLV320AIC23",
120 .stream_name = "AIC23", 118 .stream_name = "AIC23",
121 .codec_name = "tlv320aic23-codec.2-001a", 119 .codec_name = "tlv320aic23-codec.2-001a",
122 .platform_name = "tegra-pcm-audio", 120 .platform_name = "tegra20-i2s.0",
123 .cpu_dai_name = "tegra-i2s.0", 121 .cpu_dai_name = "tegra20-i2s.0",
124 .codec_dai_name = "tlv320aic23-hifi", 122 .codec_dai_name = "tlv320aic23-hifi",
125 .ops = &trimslice_asoc_ops, 123 .ops = &trimslice_asoc_ops,
126}; 124};
@@ -152,6 +150,32 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
152 goto err; 150 goto err;
153 } 151 }
154 152
153 if (pdev->dev.of_node) {
154 trimslice_tlv320aic23_dai.codec_name = NULL;
155 trimslice_tlv320aic23_dai.codec_of_node = of_parse_phandle(
156 pdev->dev.of_node, "nvidia,audio-codec", 0);
157 if (!trimslice_tlv320aic23_dai.codec_of_node) {
158 dev_err(&pdev->dev,
159 "Property 'nvidia,audio-codec' missing or invalid\n");
160 ret = -EINVAL;
161 goto err;
162 }
163
164 trimslice_tlv320aic23_dai.cpu_dai_name = NULL;
165 trimslice_tlv320aic23_dai.cpu_dai_of_node = of_parse_phandle(
166 pdev->dev.of_node, "nvidia,i2s-controller", 0);
167 if (!trimslice_tlv320aic23_dai.cpu_dai_of_node) {
168 dev_err(&pdev->dev,
169 "Property 'nvidia,i2s-controller' missing or invalid\n");
170 ret = -EINVAL;
171 goto err;
172 }
173
174 trimslice_tlv320aic23_dai.platform_name = NULL;
175 trimslice_tlv320aic23_dai.platform_of_node =
176 trimslice_tlv320aic23_dai.cpu_dai_of_node;
177 }
178
155 ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev); 179 ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev);
156 if (ret) 180 if (ret)
157 goto err; 181 goto err;
@@ -187,10 +211,17 @@ static int __devexit tegra_snd_trimslice_remove(struct platform_device *pdev)
187 return 0; 211 return 0;
188} 212}
189 213
214static const struct of_device_id trimslice_of_match[] __devinitconst = {
215 { .compatible = "nvidia,tegra-audio-trimslice", },
216 {},
217};
218MODULE_DEVICE_TABLE(of, trimslice_of_match);
219
190static struct platform_driver tegra_snd_trimslice_driver = { 220static struct platform_driver tegra_snd_trimslice_driver = {
191 .driver = { 221 .driver = {
192 .name = DRV_NAME, 222 .name = DRV_NAME,
193 .owner = THIS_MODULE, 223 .owner = THIS_MODULE,
224 .of_match_table = trimslice_of_match,
194 }, 225 },
195 .probe = tegra_snd_trimslice_probe, 226 .probe = tegra_snd_trimslice_probe,
196 .remove = __devexit_p(tegra_snd_trimslice_remove), 227 .remove = __devexit_p(tegra_snd_trimslice_remove),
diff --git a/sound/soc/ux500/Kconfig b/sound/soc/ux500/Kconfig
new file mode 100644
index 000000000000..44cf43404cd9
--- /dev/null
+++ b/sound/soc/ux500/Kconfig
@@ -0,0 +1,14 @@
1#
2# Ux500 SoC audio configuration
3#
4menuconfig SND_SOC_UX500
5 tristate "SoC Audio support for Ux500 platform"
6 depends on SND_SOC
7 depends on MFD_DB8500_PRCMU
8 help
9 Say Y if you want to enable ASoC-support for
10 any of the Ux500 platforms (e.g. U8500).
11
12config SND_SOC_UX500_PLAT_MSP_I2S
13 tristate
14 depends on SND_SOC_UX500
diff --git a/sound/soc/ux500/Makefile b/sound/soc/ux500/Makefile
new file mode 100644
index 000000000000..19974c5a2ea1
--- /dev/null
+++ b/sound/soc/ux500/Makefile
@@ -0,0 +1,4 @@
1# Ux500 Platform Support
2
3snd-soc-ux500-plat-msp-i2s-objs := ux500_msp_dai.o ux500_msp_i2s.o
4obj-$(CONFIG_SND_SOC_UX500_PLAT_MSP_I2S) += snd-soc-ux500-plat-msp-i2s.o
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
new file mode 100644
index 000000000000..93c6c40e724c
--- /dev/null
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -0,0 +1,843 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
5 * Roger Nilsson <roger.xr.nilsson@stericsson.com>
6 * for ST-Ericsson.
7 *
8 * License terms:
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/slab.h>
17#include <linux/bitops.h>
18#include <linux/platform_device.h>
19#include <linux/clk.h>
20#include <linux/regulator/consumer.h>
21#include <linux/mfd/dbx500-prcmu.h>
22
23#include <mach/hardware.h>
24#include <mach/board-mop500-msp.h>
25
26#include <sound/soc.h>
27#include <sound/soc-dai.h>
28
29#include "ux500_msp_i2s.h"
30#include "ux500_msp_dai.h"
31
32static int setup_pcm_multichan(struct snd_soc_dai *dai,
33 struct ux500_msp_config *msp_config)
34{
35 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
36 struct msp_multichannel_config *multi =
37 &msp_config->multichannel_config;
38
39 if (drvdata->slots > 1) {
40 msp_config->multichannel_configured = 1;
41
42 multi->tx_multichannel_enable = true;
43 multi->rx_multichannel_enable = true;
44 multi->rx_comparison_enable_mode = MSP_COMPARISON_DISABLED;
45
46 multi->tx_channel_0_enable = drvdata->tx_mask;
47 multi->tx_channel_1_enable = 0;
48 multi->tx_channel_2_enable = 0;
49 multi->tx_channel_3_enable = 0;
50
51 multi->rx_channel_0_enable = drvdata->rx_mask;
52 multi->rx_channel_1_enable = 0;
53 multi->rx_channel_2_enable = 0;
54 multi->rx_channel_3_enable = 0;
55
56 dev_dbg(dai->dev,
57 "%s: Multichannel enabled. Slots: %d, TX: %u, RX: %u\n",
58 __func__, drvdata->slots, multi->tx_channel_0_enable,
59 multi->rx_channel_0_enable);
60 }
61
62 return 0;
63}
64
65static int setup_frameper(struct snd_soc_dai *dai, unsigned int rate,
66 struct msp_protdesc *prot_desc)
67{
68 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
69
70 switch (drvdata->slots) {
71 case 1:
72 switch (rate) {
73 case 8000:
74 prot_desc->frame_period =
75 FRAME_PER_SINGLE_SLOT_8_KHZ;
76 break;
77
78 case 16000:
79 prot_desc->frame_period =
80 FRAME_PER_SINGLE_SLOT_16_KHZ;
81 break;
82
83 case 44100:
84 prot_desc->frame_period =
85 FRAME_PER_SINGLE_SLOT_44_1_KHZ;
86 break;
87
88 case 48000:
89 prot_desc->frame_period =
90 FRAME_PER_SINGLE_SLOT_48_KHZ;
91 break;
92
93 default:
94 dev_err(dai->dev,
95 "%s: Error: Unsupported sample-rate (freq = %d)!\n",
96 __func__, rate);
97 return -EINVAL;
98 }
99 break;
100
101 case 2:
102 prot_desc->frame_period = FRAME_PER_2_SLOTS;
103 break;
104
105 case 8:
106 prot_desc->frame_period = FRAME_PER_8_SLOTS;
107 break;
108
109 case 16:
110 prot_desc->frame_period = FRAME_PER_16_SLOTS;
111 break;
112 default:
113 dev_err(dai->dev,
114 "%s: Error: Unsupported slot-count (slots = %d)!\n",
115 __func__, drvdata->slots);
116 return -EINVAL;
117 }
118
119 prot_desc->clocks_per_frame =
120 prot_desc->frame_period+1;
121
122 dev_dbg(dai->dev, "%s: Clocks per frame: %u\n",
123 __func__,
124 prot_desc->clocks_per_frame);
125
126 return 0;
127}
128
129static int setup_pcm_framing(struct snd_soc_dai *dai, unsigned int rate,
130 struct msp_protdesc *prot_desc)
131{
132 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
133
134 u32 frame_length = MSP_FRAME_LEN_1;
135 prot_desc->frame_width = 0;
136
137 switch (drvdata->slots) {
138 case 1:
139 frame_length = MSP_FRAME_LEN_1;
140 break;
141
142 case 2:
143 frame_length = MSP_FRAME_LEN_2;
144 break;
145
146 case 8:
147 frame_length = MSP_FRAME_LEN_8;
148 break;
149
150 case 16:
151 frame_length = MSP_FRAME_LEN_16;
152 break;
153 default:
154 dev_err(dai->dev,
155 "%s: Error: Unsupported slot-count (slots = %d)!\n",
156 __func__, drvdata->slots);
157 return -EINVAL;
158 }
159
160 prot_desc->tx_frame_len_1 = frame_length;
161 prot_desc->rx_frame_len_1 = frame_length;
162 prot_desc->tx_frame_len_2 = frame_length;
163 prot_desc->rx_frame_len_2 = frame_length;
164
165 prot_desc->tx_elem_len_1 = MSP_ELEM_LEN_16;
166 prot_desc->rx_elem_len_1 = MSP_ELEM_LEN_16;
167 prot_desc->tx_elem_len_2 = MSP_ELEM_LEN_16;
168 prot_desc->rx_elem_len_2 = MSP_ELEM_LEN_16;
169
170 return setup_frameper(dai, rate, prot_desc);
171}
172
173static int setup_clocking(struct snd_soc_dai *dai,
174 unsigned int fmt,
175 struct ux500_msp_config *msp_config)
176{
177 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
178 case SND_SOC_DAIFMT_NB_NF:
179 break;
180
181 case SND_SOC_DAIFMT_NB_IF:
182 msp_config->tx_fsync_pol ^= 1 << TFSPOL_SHIFT;
183 msp_config->rx_fsync_pol ^= 1 << RFSPOL_SHIFT;
184
185 break;
186
187 default:
188 dev_err(dai->dev,
189 "%s: Error: Unsopported inversion (fmt = 0x%x)!\n",
190 __func__, fmt);
191
192 return -EINVAL;
193 }
194
195 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
196 case SND_SOC_DAIFMT_CBM_CFM:
197 dev_dbg(dai->dev, "%s: Codec is master.\n", __func__);
198
199 msp_config->iodelay = 0x20;
200 msp_config->rx_fsync_sel = 0;
201 msp_config->tx_fsync_sel = 1 << TFSSEL_SHIFT;
202 msp_config->tx_clk_sel = 0;
203 msp_config->rx_clk_sel = 0;
204 msp_config->srg_clk_sel = 0x2 << SCKSEL_SHIFT;
205
206 break;
207
208 case SND_SOC_DAIFMT_CBS_CFS:
209 dev_dbg(dai->dev, "%s: Codec is slave.\n", __func__);
210
211 msp_config->tx_clk_sel = TX_CLK_SEL_SRG;
212 msp_config->tx_fsync_sel = TX_SYNC_SRG_PROG;
213 msp_config->rx_clk_sel = RX_CLK_SEL_SRG;
214 msp_config->rx_fsync_sel = RX_SYNC_SRG;
215 msp_config->srg_clk_sel = 1 << SCKSEL_SHIFT;
216
217 break;
218
219 default:
220 dev_err(dai->dev, "%s: Error: Unsopported master (fmt = 0x%x)!\n",
221 __func__, fmt);
222
223 return -EINVAL;
224 }
225
226 return 0;
227}
228
229static int setup_pcm_protdesc(struct snd_soc_dai *dai,
230 unsigned int fmt,
231 struct msp_protdesc *prot_desc)
232{
233 prot_desc->rx_phase_mode = MSP_SINGLE_PHASE;
234 prot_desc->tx_phase_mode = MSP_SINGLE_PHASE;
235 prot_desc->rx_phase2_start_mode = MSP_PHASE2_START_MODE_IMEDIATE;
236 prot_desc->tx_phase2_start_mode = MSP_PHASE2_START_MODE_IMEDIATE;
237 prot_desc->rx_byte_order = MSP_BTF_MS_BIT_FIRST;
238 prot_desc->tx_byte_order = MSP_BTF_MS_BIT_FIRST;
239 prot_desc->tx_fsync_pol = MSP_FSYNC_POL(MSP_FSYNC_POL_ACT_HI);
240 prot_desc->rx_fsync_pol = MSP_FSYNC_POL_ACT_HI << RFSPOL_SHIFT;
241
242 if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_DSP_A) {
243 dev_dbg(dai->dev, "%s: DSP_A.\n", __func__);
244 prot_desc->rx_clk_pol = MSP_RISING_EDGE;
245 prot_desc->tx_clk_pol = MSP_FALLING_EDGE;
246
247 prot_desc->rx_data_delay = MSP_DELAY_1;
248 prot_desc->tx_data_delay = MSP_DELAY_1;
249 } else {
250 dev_dbg(dai->dev, "%s: DSP_B.\n", __func__);
251 prot_desc->rx_clk_pol = MSP_FALLING_EDGE;
252 prot_desc->tx_clk_pol = MSP_RISING_EDGE;
253
254 prot_desc->rx_data_delay = MSP_DELAY_0;
255 prot_desc->tx_data_delay = MSP_DELAY_0;
256 }
257
258 prot_desc->rx_half_word_swap = MSP_SWAP_NONE;
259 prot_desc->tx_half_word_swap = MSP_SWAP_NONE;
260 prot_desc->compression_mode = MSP_COMPRESS_MODE_LINEAR;
261 prot_desc->expansion_mode = MSP_EXPAND_MODE_LINEAR;
262 prot_desc->frame_sync_ignore = MSP_FSYNC_IGNORE;
263
264 return 0;
265}
266
267static int setup_i2s_protdesc(struct msp_protdesc *prot_desc)
268{
269 prot_desc->rx_phase_mode = MSP_DUAL_PHASE;
270 prot_desc->tx_phase_mode = MSP_DUAL_PHASE;
271 prot_desc->rx_phase2_start_mode = MSP_PHASE2_START_MODE_FSYNC;
272 prot_desc->tx_phase2_start_mode = MSP_PHASE2_START_MODE_FSYNC;
273 prot_desc->rx_byte_order = MSP_BTF_MS_BIT_FIRST;
274 prot_desc->tx_byte_order = MSP_BTF_MS_BIT_FIRST;
275 prot_desc->tx_fsync_pol = MSP_FSYNC_POL(MSP_FSYNC_POL_ACT_LO);
276 prot_desc->rx_fsync_pol = MSP_FSYNC_POL_ACT_LO << RFSPOL_SHIFT;
277
278 prot_desc->rx_frame_len_1 = MSP_FRAME_LEN_1;
279 prot_desc->rx_frame_len_2 = MSP_FRAME_LEN_1;
280 prot_desc->tx_frame_len_1 = MSP_FRAME_LEN_1;
281 prot_desc->tx_frame_len_2 = MSP_FRAME_LEN_1;
282 prot_desc->rx_elem_len_1 = MSP_ELEM_LEN_16;
283 prot_desc->rx_elem_len_2 = MSP_ELEM_LEN_16;
284 prot_desc->tx_elem_len_1 = MSP_ELEM_LEN_16;
285 prot_desc->tx_elem_len_2 = MSP_ELEM_LEN_16;
286
287 prot_desc->rx_clk_pol = MSP_RISING_EDGE;
288 prot_desc->tx_clk_pol = MSP_FALLING_EDGE;
289
290 prot_desc->rx_data_delay = MSP_DELAY_0;
291 prot_desc->tx_data_delay = MSP_DELAY_0;
292
293 prot_desc->tx_half_word_swap = MSP_SWAP_NONE;
294 prot_desc->rx_half_word_swap = MSP_SWAP_NONE;
295 prot_desc->compression_mode = MSP_COMPRESS_MODE_LINEAR;
296 prot_desc->expansion_mode = MSP_EXPAND_MODE_LINEAR;
297 prot_desc->frame_sync_ignore = MSP_FSYNC_IGNORE;
298
299 return 0;
300}
301
302static int setup_msp_config(struct snd_pcm_substream *substream,
303 struct snd_soc_dai *dai,
304 struct ux500_msp_config *msp_config)
305{
306 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
307 struct msp_protdesc *prot_desc = &msp_config->protdesc;
308 struct snd_pcm_runtime *runtime = substream->runtime;
309 unsigned int fmt = drvdata->fmt;
310 int ret;
311
312 memset(msp_config, 0, sizeof(*msp_config));
313
314 msp_config->f_inputclk = drvdata->master_clk;
315
316 msp_config->tx_fifo_config = TX_FIFO_ENABLE;
317 msp_config->rx_fifo_config = RX_FIFO_ENABLE;
318 msp_config->def_elem_len = 1;
319 msp_config->direction = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
320 MSP_DIR_TX : MSP_DIR_RX;
321 msp_config->data_size = MSP_DATA_BITS_32;
322 msp_config->frame_freq = runtime->rate;
323
324 dev_dbg(dai->dev, "%s: f_inputclk = %u, frame_freq = %u.\n",
325 __func__, msp_config->f_inputclk, msp_config->frame_freq);
326 /* To avoid division by zero */
327 prot_desc->clocks_per_frame = 1;
328
329 dev_dbg(dai->dev, "%s: rate: %u, channels: %d.\n", __func__,
330 runtime->rate, runtime->channels);
331 switch (fmt &
332 (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
333 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
334 dev_dbg(dai->dev, "%s: SND_SOC_DAIFMT_I2S.\n", __func__);
335
336 msp_config->default_protdesc = 1;
337 msp_config->protocol = MSP_I2S_PROTOCOL;
338 break;
339
340 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
341 dev_dbg(dai->dev, "%s: SND_SOC_DAIFMT_I2S.\n", __func__);
342
343 msp_config->data_size = MSP_DATA_BITS_16;
344 msp_config->protocol = MSP_I2S_PROTOCOL;
345
346 ret = setup_i2s_protdesc(prot_desc);
347 if (ret < 0)
348 return ret;
349
350 break;
351
352 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
353 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
354 case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBS_CFS:
355 case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM:
356 dev_dbg(dai->dev, "%s: PCM format.\n", __func__);
357
358 msp_config->data_size = MSP_DATA_BITS_16;
359 msp_config->protocol = MSP_PCM_PROTOCOL;
360
361 ret = setup_pcm_protdesc(dai, fmt, prot_desc);
362 if (ret < 0)
363 return ret;
364
365 ret = setup_pcm_multichan(dai, msp_config);
366 if (ret < 0)
367 return ret;
368
369 ret = setup_pcm_framing(dai, runtime->rate, prot_desc);
370 if (ret < 0)
371 return ret;
372
373 break;
374
375 default:
376 dev_err(dai->dev, "%s: Error: Unsopported format (%d)!\n",
377 __func__, fmt);
378 return -EINVAL;
379 }
380
381 return setup_clocking(dai, fmt, msp_config);
382}
383
384static int ux500_msp_dai_startup(struct snd_pcm_substream *substream,
385 struct snd_soc_dai *dai)
386{
387 int ret = 0;
388 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
389
390 dev_dbg(dai->dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id,
391 snd_pcm_stream_str(substream));
392
393 /* Enable regulator */
394 ret = regulator_enable(drvdata->reg_vape);
395 if (ret != 0) {
396 dev_err(drvdata->msp->dev,
397 "%s: Failed to enable regulator!\n", __func__);
398 return ret;
399 }
400
401 /* Enable clock */
402 dev_dbg(dai->dev, "%s: Enabling MSP-clock.\n", __func__);
403 clk_enable(drvdata->clk);
404
405 return 0;
406}
407
408static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream,
409 struct snd_soc_dai *dai)
410{
411 int ret;
412 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
413 bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
414
415 dev_dbg(dai->dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id,
416 snd_pcm_stream_str(substream));
417
418 if (drvdata->vape_opp_constraint == 1) {
419 prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP,
420 "ux500_msp_i2s", 50);
421 drvdata->vape_opp_constraint = 0;
422 }
423
424 if (ux500_msp_i2s_close(drvdata->msp,
425 is_playback ? MSP_DIR_TX : MSP_DIR_RX)) {
426 dev_err(dai->dev,
427 "%s: Error: MSP %d (%s): Unable to close i2s.\n",
428 __func__, dai->id, snd_pcm_stream_str(substream));
429 }
430
431 /* Disable clock */
432 clk_disable(drvdata->clk);
433
434 /* Disable regulator */
435 ret = regulator_disable(drvdata->reg_vape);
436 if (ret < 0)
437 dev_err(dai->dev,
438 "%s: ERROR: Failed to disable regulator (%d)!\n",
439 __func__, ret);
440}
441
442static int ux500_msp_dai_prepare(struct snd_pcm_substream *substream,
443 struct snd_soc_dai *dai)
444{
445 int ret = 0;
446 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
447 struct snd_pcm_runtime *runtime = substream->runtime;
448 struct ux500_msp_config msp_config;
449
450 dev_dbg(dai->dev, "%s: MSP %d (%s): Enter (rate = %d).\n", __func__,
451 dai->id, snd_pcm_stream_str(substream), runtime->rate);
452
453 setup_msp_config(substream, dai, &msp_config);
454
455 ret = ux500_msp_i2s_open(drvdata->msp, &msp_config);
456 if (ret < 0) {
457 dev_err(dai->dev, "%s: Error: msp_setup failed (ret = %d)!\n",
458 __func__, ret);
459 return ret;
460 }
461
462 /* Set OPP-level */
463 if ((drvdata->fmt & SND_SOC_DAIFMT_MASTER_MASK) &&
464 (drvdata->msp->f_bitclk > 19200000)) {
465 /* If the bit-clock is higher than 19.2MHz, Vape should be
466 * run in 100% OPP. Only when bit-clock is used (MSP master) */
467 prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP,
468 "ux500-msp-i2s", 100);
469 drvdata->vape_opp_constraint = 1;
470 } else {
471 prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP,
472 "ux500-msp-i2s", 50);
473 drvdata->vape_opp_constraint = 0;
474 }
475
476 return ret;
477}
478
479static int ux500_msp_dai_hw_params(struct snd_pcm_substream *substream,
480 struct snd_pcm_hw_params *params,
481 struct snd_soc_dai *dai)
482{
483 unsigned int mask, slots_active;
484 struct snd_pcm_runtime *runtime = substream->runtime;
485 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
486
487 dev_dbg(dai->dev, "%s: MSP %d (%s): Enter.\n",
488 __func__, dai->id, snd_pcm_stream_str(substream));
489
490 switch (drvdata->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
491 case SND_SOC_DAIFMT_I2S:
492 snd_pcm_hw_constraint_minmax(runtime,
493 SNDRV_PCM_HW_PARAM_CHANNELS,
494 1, 2);
495 break;
496
497 case SND_SOC_DAIFMT_DSP_B:
498 case SND_SOC_DAIFMT_DSP_A:
499 mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
500 drvdata->tx_mask :
501 drvdata->rx_mask;
502
503 slots_active = hweight32(mask);
504 dev_dbg(dai->dev, "TDM-slots active: %d", slots_active);
505
506 snd_pcm_hw_constraint_minmax(runtime,
507 SNDRV_PCM_HW_PARAM_CHANNELS,
508 slots_active, slots_active);
509 break;
510
511 default:
512 dev_err(dai->dev,
513 "%s: Error: Unsupported protocol (fmt = 0x%x)!\n",
514 __func__, drvdata->fmt);
515 return -EINVAL;
516 }
517
518 return 0;
519}
520
521static int ux500_msp_dai_set_dai_fmt(struct snd_soc_dai *dai,
522 unsigned int fmt)
523{
524 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
525
526 dev_dbg(dai->dev, "%s: MSP %d: Enter.\n", __func__, dai->id);
527
528 switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK |
529 SND_SOC_DAIFMT_MASTER_MASK)) {
530 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
531 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
532 case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBS_CFS:
533 case SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM:
534 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
535 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
536 break;
537
538 default:
539 dev_err(dai->dev,
540 "%s: Error: Unsupported protocol/master (fmt = 0x%x)!\n",
541 __func__, drvdata->fmt);
542 return -EINVAL;
543 }
544
545 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
546 case SND_SOC_DAIFMT_NB_NF:
547 case SND_SOC_DAIFMT_NB_IF:
548 case SND_SOC_DAIFMT_IB_IF:
549 break;
550
551 default:
552 dev_err(dai->dev,
553 "%s: Error: Unsupported inversion (fmt = 0x%x)!\n",
554 __func__, drvdata->fmt);
555 return -EINVAL;
556 }
557
558 drvdata->fmt = fmt;
559 return 0;
560}
561
562static int ux500_msp_dai_set_tdm_slot(struct snd_soc_dai *dai,
563 unsigned int tx_mask,
564 unsigned int rx_mask,
565 int slots, int slot_width)
566{
567 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
568 unsigned int cap;
569
570 switch (slots) {
571 case 1:
572 cap = 0x01;
573 break;
574 case 2:
575 cap = 0x03;
576 break;
577 case 8:
578 cap = 0xFF;
579 break;
580 case 16:
581 cap = 0xFFFF;
582 break;
583 default:
584 dev_err(dai->dev, "%s: Error: Unsupported slot-count (%d)!\n",
585 __func__, slots);
586 return -EINVAL;
587 }
588 drvdata->slots = slots;
589
590 if (!(slot_width == 16)) {
591 dev_err(dai->dev, "%s: Error: Unsupported slot-width (%d)!\n",
592 __func__, slot_width);
593 return -EINVAL;
594 }
595 drvdata->slot_width = slot_width;
596
597 drvdata->tx_mask = tx_mask & cap;
598 drvdata->rx_mask = rx_mask & cap;
599
600 return 0;
601}
602
603static int ux500_msp_dai_set_dai_sysclk(struct snd_soc_dai *dai,
604 int clk_id, unsigned int freq, int dir)
605{
606 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
607
608 dev_dbg(dai->dev, "%s: MSP %d: Enter. clk-id: %d, freq: %u.\n",
609 __func__, dai->id, clk_id, freq);
610
611 switch (clk_id) {
612 case UX500_MSP_MASTER_CLOCK:
613 drvdata->master_clk = freq;
614 break;
615
616 default:
617 dev_err(dai->dev, "%s: MSP %d: Invalid clk-id (%d)!\n",
618 __func__, dai->id, clk_id);
619 return -EINVAL;
620 }
621
622 return 0;
623}
624
625static int ux500_msp_dai_trigger(struct snd_pcm_substream *substream,
626 int cmd, struct snd_soc_dai *dai)
627{
628 int ret = 0;
629 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
630
631 dev_dbg(dai->dev, "%s: MSP %d (%s): Enter (msp->id = %d, cmd = %d).\n",
632 __func__, dai->id, snd_pcm_stream_str(substream),
633 (int)drvdata->msp->id, cmd);
634
635 ret = ux500_msp_i2s_trigger(drvdata->msp, cmd, substream->stream);
636
637 return ret;
638}
639
640static int ux500_msp_dai_probe(struct snd_soc_dai *dai)
641{
642 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
643
644 drvdata->playback_dma_data.dma_cfg = drvdata->msp->dma_cfg_tx;
645 drvdata->capture_dma_data.dma_cfg = drvdata->msp->dma_cfg_rx;
646
647 dai->playback_dma_data = &drvdata->playback_dma_data;
648 dai->capture_dma_data = &drvdata->capture_dma_data;
649
650 drvdata->playback_dma_data.data_size = drvdata->slot_width;
651 drvdata->capture_dma_data.data_size = drvdata->slot_width;
652
653 return 0;
654}
655
656static struct snd_soc_dai_ops ux500_msp_dai_ops[] = {
657 {
658 .set_sysclk = ux500_msp_dai_set_dai_sysclk,
659 .set_fmt = ux500_msp_dai_set_dai_fmt,
660 .set_tdm_slot = ux500_msp_dai_set_tdm_slot,
661 .startup = ux500_msp_dai_startup,
662 .shutdown = ux500_msp_dai_shutdown,
663 .prepare = ux500_msp_dai_prepare,
664 .trigger = ux500_msp_dai_trigger,
665 .hw_params = ux500_msp_dai_hw_params,
666 }
667};
668
669static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = {
670 {
671 .name = "ux500-msp-i2s.0",
672 .probe = ux500_msp_dai_probe,
673 .id = 0,
674 .suspend = NULL,
675 .resume = NULL,
676 .playback = {
677 .channels_min = UX500_MSP_MIN_CHANNELS,
678 .channels_max = UX500_MSP_MAX_CHANNELS,
679 .rates = UX500_I2S_RATES,
680 .formats = UX500_I2S_FORMATS,
681 },
682 .capture = {
683 .channels_min = UX500_MSP_MIN_CHANNELS,
684 .channels_max = UX500_MSP_MAX_CHANNELS,
685 .rates = UX500_I2S_RATES,
686 .formats = UX500_I2S_FORMATS,
687 },
688 .ops = ux500_msp_dai_ops,
689 },
690 {
691 .name = "ux500-msp-i2s.1",
692 .probe = ux500_msp_dai_probe,
693 .id = 1,
694 .suspend = NULL,
695 .resume = NULL,
696 .playback = {
697 .channels_min = UX500_MSP_MIN_CHANNELS,
698 .channels_max = UX500_MSP_MAX_CHANNELS,
699 .rates = UX500_I2S_RATES,
700 .formats = UX500_I2S_FORMATS,
701 },
702 .capture = {
703 .channels_min = UX500_MSP_MIN_CHANNELS,
704 .channels_max = UX500_MSP_MAX_CHANNELS,
705 .rates = UX500_I2S_RATES,
706 .formats = UX500_I2S_FORMATS,
707 },
708 .ops = ux500_msp_dai_ops,
709 },
710 {
711 .name = "ux500-msp-i2s.2",
712 .id = 2,
713 .probe = ux500_msp_dai_probe,
714 .suspend = NULL,
715 .resume = NULL,
716 .playback = {
717 .channels_min = UX500_MSP_MIN_CHANNELS,
718 .channels_max = UX500_MSP_MAX_CHANNELS,
719 .rates = UX500_I2S_RATES,
720 .formats = UX500_I2S_FORMATS,
721 },
722 .capture = {
723 .channels_min = UX500_MSP_MIN_CHANNELS,
724 .channels_max = UX500_MSP_MAX_CHANNELS,
725 .rates = UX500_I2S_RATES,
726 .formats = UX500_I2S_FORMATS,
727 },
728 .ops = ux500_msp_dai_ops,
729 },
730 {
731 .name = "ux500-msp-i2s.3",
732 .probe = ux500_msp_dai_probe,
733 .id = 3,
734 .suspend = NULL,
735 .resume = NULL,
736 .playback = {
737 .channels_min = UX500_MSP_MIN_CHANNELS,
738 .channels_max = UX500_MSP_MAX_CHANNELS,
739 .rates = UX500_I2S_RATES,
740 .formats = UX500_I2S_FORMATS,
741 },
742 .capture = {
743 .channels_min = UX500_MSP_MIN_CHANNELS,
744 .channels_max = UX500_MSP_MAX_CHANNELS,
745 .rates = UX500_I2S_RATES,
746 .formats = UX500_I2S_FORMATS,
747 },
748 .ops = ux500_msp_dai_ops,
749 },
750};
751
752static int __devinit ux500_msp_drv_probe(struct platform_device *pdev)
753{
754 struct ux500_msp_i2s_drvdata *drvdata;
755 int ret = 0;
756
757 dev_dbg(&pdev->dev, "%s: Enter (pdev->name = %s).\n", __func__,
758 pdev->name);
759
760 drvdata = devm_kzalloc(&pdev->dev,
761 sizeof(struct ux500_msp_i2s_drvdata),
762 GFP_KERNEL);
763 drvdata->fmt = 0;
764 drvdata->slots = 1;
765 drvdata->tx_mask = 0x01;
766 drvdata->rx_mask = 0x01;
767 drvdata->slot_width = 16;
768 drvdata->master_clk = MSP_INPUT_FREQ_APB;
769
770 drvdata->reg_vape = devm_regulator_get(&pdev->dev, "v-ape");
771 if (IS_ERR(drvdata->reg_vape)) {
772 ret = (int)PTR_ERR(drvdata->reg_vape);
773 dev_err(&pdev->dev,
774 "%s: ERROR: Failed to get Vape supply (%d)!\n",
775 __func__, ret);
776 return ret;
777 }
778 prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, (char *)pdev->name, 50);
779
780 drvdata->clk = clk_get(&pdev->dev, NULL);
781 if (IS_ERR(drvdata->clk)) {
782 ret = (int)PTR_ERR(drvdata->clk);
783 dev_err(&pdev->dev, "%s: ERROR: clk_get failed (%d)!\n",
784 __func__, ret);
785 goto err_clk;
786 }
787
788 ret = ux500_msp_i2s_init_msp(pdev, &drvdata->msp,
789 pdev->dev.platform_data);
790 if (!drvdata->msp) {
791 dev_err(&pdev->dev,
792 "%s: ERROR: Failed to init MSP-struct (%d)!",
793 __func__, ret);
794 goto err_init_msp;
795 }
796 dev_set_drvdata(&pdev->dev, drvdata);
797
798 ret = snd_soc_register_dai(&pdev->dev,
799 &ux500_msp_dai_drv[drvdata->msp->id]);
800 if (ret < 0) {
801 dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n",
802 __func__, drvdata->msp->id);
803 goto err_init_msp;
804 }
805
806 return 0;
807
808err_init_msp:
809 clk_put(drvdata->clk);
810
811err_clk:
812 devm_regulator_put(drvdata->reg_vape);
813
814 return ret;
815}
816
817static int __devexit ux500_msp_drv_remove(struct platform_device *pdev)
818{
819 struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
820
821 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(ux500_msp_dai_drv));
822
823 devm_regulator_put(drvdata->reg_vape);
824 prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s");
825
826 clk_put(drvdata->clk);
827
828 ux500_msp_i2s_cleanup_msp(pdev, drvdata->msp);
829
830 return 0;
831}
832
833static struct platform_driver msp_i2s_driver = {
834 .driver = {
835 .name = "ux500-msp-i2s",
836 .owner = THIS_MODULE,
837 },
838 .probe = ux500_msp_drv_probe,
839 .remove = ux500_msp_drv_remove,
840};
841module_platform_driver(msp_i2s_driver);
842
843MODULE_LICENSE("GPLv2");
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h
new file mode 100644
index 000000000000..98202a34a5dd
--- /dev/null
+++ b/sound/soc/ux500/ux500_msp_dai.h
@@ -0,0 +1,79 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
5 * Roger Nilsson <roger.xr.nilsson@stericsson.com>
6 * for ST-Ericsson.
7 *
8 * License terms:
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation.
13 */
14
15#ifndef UX500_msp_dai_H
16#define UX500_msp_dai_H
17
18#include <linux/types.h>
19#include <linux/spinlock.h>
20
21#include "ux500_msp_i2s.h"
22
23#define UX500_NBR_OF_DAI 4
24
25#define UX500_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | \
26 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
27
28#define UX500_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
29
30#define FRAME_PER_SINGLE_SLOT_8_KHZ 31
31#define FRAME_PER_SINGLE_SLOT_16_KHZ 124
32#define FRAME_PER_SINGLE_SLOT_44_1_KHZ 63
33#define FRAME_PER_SINGLE_SLOT_48_KHZ 49
34#define FRAME_PER_2_SLOTS 31
35#define FRAME_PER_8_SLOTS 138
36#define FRAME_PER_16_SLOTS 277
37
38#ifndef CONFIG_SND_SOC_UX500_AB5500
39#define UX500_MSP_INTERNAL_CLOCK_FREQ 40000000
40#define UX500_MSP1_INTERNAL_CLOCK_FREQ UX500_MSP_INTERNAL_CLOCK_FREQ
41#else
42#define UX500_MSP_INTERNAL_CLOCK_FREQ 13000000
43#define UX500_MSP1_INTERNAL_CLOCK_FREQ (UX500_MSP_INTERNAL_CLOCK_FREQ * 2)
44#endif
45
46#define UX500_MSP_MIN_CHANNELS 1
47#define UX500_MSP_MAX_CHANNELS 8
48
49#define PLAYBACK_CONFIGURED 1
50#define CAPTURE_CONFIGURED 2
51
52enum ux500_msp_clock_id {
53 UX500_MSP_MASTER_CLOCK,
54};
55
56struct ux500_msp_i2s_drvdata {
57 struct ux500_msp *msp;
58 struct regulator *reg_vape;
59 struct ux500_msp_dma_params playback_dma_data;
60 struct ux500_msp_dma_params capture_dma_data;
61 unsigned int fmt;
62 unsigned int tx_mask;
63 unsigned int rx_mask;
64 int slots;
65 int slot_width;
66 u8 configured;
67 int data_delay;
68
69 /* Clocks */
70 unsigned int master_clk;
71 struct clk *clk;
72
73 /* Regulators */
74 int vape_opp_constraint;
75};
76
77int ux500_msp_dai_set_data_delay(struct snd_soc_dai *dai, int delay);
78
79#endif
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
new file mode 100644
index 000000000000..496dec10c96e
--- /dev/null
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -0,0 +1,742 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
5 * Roger Nilsson <roger.xr.nilsson@stericsson.com>,
6 * Sandeep Kaushik <sandeep.kaushik@st.com>
7 * for ST-Ericsson.
8 *
9 * License terms:
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as published
13 * by the Free Software Foundation.
14 */
15
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/delay.h>
19#include <linux/slab.h>
20
21#include <mach/hardware.h>
22#include <mach/board-mop500-msp.h>
23
24#include <sound/soc.h>
25
26#include "ux500_msp_i2s.h"
27
28 /* Protocol desciptors */
29static const struct msp_protdesc prot_descs[] = {
30 { /* I2S */
31 MSP_SINGLE_PHASE,
32 MSP_SINGLE_PHASE,
33 MSP_PHASE2_START_MODE_IMEDIATE,
34 MSP_PHASE2_START_MODE_IMEDIATE,
35 MSP_BTF_MS_BIT_FIRST,
36 MSP_BTF_MS_BIT_FIRST,
37 MSP_FRAME_LEN_1,
38 MSP_FRAME_LEN_1,
39 MSP_FRAME_LEN_1,
40 MSP_FRAME_LEN_1,
41 MSP_ELEM_LEN_32,
42 MSP_ELEM_LEN_32,
43 MSP_ELEM_LEN_32,
44 MSP_ELEM_LEN_32,
45 MSP_DELAY_1,
46 MSP_DELAY_1,
47 MSP_RISING_EDGE,
48 MSP_FALLING_EDGE,
49 MSP_FSYNC_POL_ACT_LO,
50 MSP_FSYNC_POL_ACT_LO,
51 MSP_SWAP_NONE,
52 MSP_SWAP_NONE,
53 MSP_COMPRESS_MODE_LINEAR,
54 MSP_EXPAND_MODE_LINEAR,
55 MSP_FSYNC_IGNORE,
56 31,
57 15,
58 32,
59 }, { /* PCM */
60 MSP_DUAL_PHASE,
61 MSP_DUAL_PHASE,
62 MSP_PHASE2_START_MODE_FSYNC,
63 MSP_PHASE2_START_MODE_FSYNC,
64 MSP_BTF_MS_BIT_FIRST,
65 MSP_BTF_MS_BIT_FIRST,
66 MSP_FRAME_LEN_1,
67 MSP_FRAME_LEN_1,
68 MSP_FRAME_LEN_1,
69 MSP_FRAME_LEN_1,
70 MSP_ELEM_LEN_16,
71 MSP_ELEM_LEN_16,
72 MSP_ELEM_LEN_16,
73 MSP_ELEM_LEN_16,
74 MSP_DELAY_0,
75 MSP_DELAY_0,
76 MSP_RISING_EDGE,
77 MSP_FALLING_EDGE,
78 MSP_FSYNC_POL_ACT_HI,
79 MSP_FSYNC_POL_ACT_HI,
80 MSP_SWAP_NONE,
81 MSP_SWAP_NONE,
82 MSP_COMPRESS_MODE_LINEAR,
83 MSP_EXPAND_MODE_LINEAR,
84 MSP_FSYNC_IGNORE,
85 255,
86 0,
87 256,
88 }, { /* Companded PCM */
89 MSP_SINGLE_PHASE,
90 MSP_SINGLE_PHASE,
91 MSP_PHASE2_START_MODE_FSYNC,
92 MSP_PHASE2_START_MODE_FSYNC,
93 MSP_BTF_MS_BIT_FIRST,
94 MSP_BTF_MS_BIT_FIRST,
95 MSP_FRAME_LEN_1,
96 MSP_FRAME_LEN_1,
97 MSP_FRAME_LEN_1,
98 MSP_FRAME_LEN_1,
99 MSP_ELEM_LEN_8,
100 MSP_ELEM_LEN_8,
101 MSP_ELEM_LEN_8,
102 MSP_ELEM_LEN_8,
103 MSP_DELAY_0,
104 MSP_DELAY_0,
105 MSP_RISING_EDGE,
106 MSP_RISING_EDGE,
107 MSP_FSYNC_POL_ACT_HI,
108 MSP_FSYNC_POL_ACT_HI,
109 MSP_SWAP_NONE,
110 MSP_SWAP_NONE,
111 MSP_COMPRESS_MODE_LINEAR,
112 MSP_EXPAND_MODE_LINEAR,
113 MSP_FSYNC_IGNORE,
114 255,
115 0,
116 256,
117 },
118};
119
120static void set_prot_desc_tx(struct ux500_msp *msp,
121 struct msp_protdesc *protdesc,
122 enum msp_data_size data_size)
123{
124 u32 temp_reg = 0;
125
126 temp_reg |= MSP_P2_ENABLE_BIT(protdesc->tx_phase_mode);
127 temp_reg |= MSP_P2_START_MODE_BIT(protdesc->tx_phase2_start_mode);
128 temp_reg |= MSP_P1_FRAME_LEN_BITS(protdesc->tx_frame_len_1);
129 temp_reg |= MSP_P2_FRAME_LEN_BITS(protdesc->tx_frame_len_2);
130 if (msp->def_elem_len) {
131 temp_reg |= MSP_P1_ELEM_LEN_BITS(protdesc->tx_elem_len_1);
132 temp_reg |= MSP_P2_ELEM_LEN_BITS(protdesc->tx_elem_len_2);
133 } else {
134 temp_reg |= MSP_P1_ELEM_LEN_BITS(data_size);
135 temp_reg |= MSP_P2_ELEM_LEN_BITS(data_size);
136 }
137 temp_reg |= MSP_DATA_DELAY_BITS(protdesc->tx_data_delay);
138 temp_reg |= MSP_SET_ENDIANNES_BIT(protdesc->tx_byte_order);
139 temp_reg |= MSP_FSYNC_POL(protdesc->tx_fsync_pol);
140 temp_reg |= MSP_DATA_WORD_SWAP(protdesc->tx_half_word_swap);
141 temp_reg |= MSP_SET_COMPANDING_MODE(protdesc->compression_mode);
142 temp_reg |= MSP_SET_FSYNC_IGNORE(protdesc->frame_sync_ignore);
143
144 writel(temp_reg, msp->registers + MSP_TCF);
145}
146
147static void set_prot_desc_rx(struct ux500_msp *msp,
148 struct msp_protdesc *protdesc,
149 enum msp_data_size data_size)
150{
151 u32 temp_reg = 0;
152
153 temp_reg |= MSP_P2_ENABLE_BIT(protdesc->rx_phase_mode);
154 temp_reg |= MSP_P2_START_MODE_BIT(protdesc->rx_phase2_start_mode);
155 temp_reg |= MSP_P1_FRAME_LEN_BITS(protdesc->rx_frame_len_1);
156 temp_reg |= MSP_P2_FRAME_LEN_BITS(protdesc->rx_frame_len_2);
157 if (msp->def_elem_len) {
158 temp_reg |= MSP_P1_ELEM_LEN_BITS(protdesc->rx_elem_len_1);
159 temp_reg |= MSP_P2_ELEM_LEN_BITS(protdesc->rx_elem_len_2);
160 } else {
161 temp_reg |= MSP_P1_ELEM_LEN_BITS(data_size);
162 temp_reg |= MSP_P2_ELEM_LEN_BITS(data_size);
163 }
164
165 temp_reg |= MSP_DATA_DELAY_BITS(protdesc->rx_data_delay);
166 temp_reg |= MSP_SET_ENDIANNES_BIT(protdesc->rx_byte_order);
167 temp_reg |= MSP_FSYNC_POL(protdesc->rx_fsync_pol);
168 temp_reg |= MSP_DATA_WORD_SWAP(protdesc->rx_half_word_swap);
169 temp_reg |= MSP_SET_COMPANDING_MODE(protdesc->expansion_mode);
170 temp_reg |= MSP_SET_FSYNC_IGNORE(protdesc->frame_sync_ignore);
171
172 writel(temp_reg, msp->registers + MSP_RCF);
173}
174
175static int configure_protocol(struct ux500_msp *msp,
176 struct ux500_msp_config *config)
177{
178 struct msp_protdesc *protdesc;
179 enum msp_data_size data_size;
180 u32 temp_reg = 0;
181
182 data_size = config->data_size;
183 msp->def_elem_len = config->def_elem_len;
184 if (config->default_protdesc == 1) {
185 if (config->protocol >= MSP_INVALID_PROTOCOL) {
186 dev_err(msp->dev, "%s: ERROR: Invalid protocol!\n",
187 __func__);
188 return -EINVAL;
189 }
190 protdesc =
191 (struct msp_protdesc *)&prot_descs[config->protocol];
192 } else {
193 protdesc = (struct msp_protdesc *)&config->protdesc;
194 }
195
196 if (data_size < MSP_DATA_BITS_DEFAULT || data_size > MSP_DATA_BITS_32) {
197 dev_err(msp->dev,
198 "%s: ERROR: Invalid data-size requested (data_size = %d)!\n",
199 __func__, data_size);
200 return -EINVAL;
201 }
202
203 if (config->direction & MSP_DIR_TX)
204 set_prot_desc_tx(msp, protdesc, data_size);
205 if (config->direction & MSP_DIR_RX)
206 set_prot_desc_rx(msp, protdesc, data_size);
207
208 /* The code below should not be separated. */
209 temp_reg = readl(msp->registers + MSP_GCR) & ~TX_CLK_POL_RISING;
210 temp_reg |= MSP_TX_CLKPOL_BIT(~protdesc->tx_clk_pol);
211 writel(temp_reg, msp->registers + MSP_GCR);
212 temp_reg = readl(msp->registers + MSP_GCR) & ~RX_CLK_POL_RISING;
213 temp_reg |= MSP_RX_CLKPOL_BIT(protdesc->rx_clk_pol);
214 writel(temp_reg, msp->registers + MSP_GCR);
215
216 return 0;
217}
218
219static int setup_bitclk(struct ux500_msp *msp, struct ux500_msp_config *config)
220{
221 u32 reg_val_GCR;
222 u32 frame_per = 0;
223 u32 sck_div = 0;
224 u32 frame_width = 0;
225 u32 temp_reg = 0;
226 struct msp_protdesc *protdesc = NULL;
227
228 reg_val_GCR = readl(msp->registers + MSP_GCR);
229 writel(reg_val_GCR & ~SRG_ENABLE, msp->registers + MSP_GCR);
230
231 if (config->default_protdesc)
232 protdesc =
233 (struct msp_protdesc *)&prot_descs[config->protocol];
234 else
235 protdesc = (struct msp_protdesc *)&config->protdesc;
236
237 switch (config->protocol) {
238 case MSP_PCM_PROTOCOL:
239 case MSP_PCM_COMPAND_PROTOCOL:
240 frame_width = protdesc->frame_width;
241 sck_div = config->f_inputclk / (config->frame_freq *
242 (protdesc->clocks_per_frame));
243 frame_per = protdesc->frame_period;
244 break;
245 case MSP_I2S_PROTOCOL:
246 frame_width = protdesc->frame_width;
247 sck_div = config->f_inputclk / (config->frame_freq *
248 (protdesc->clocks_per_frame));
249 frame_per = protdesc->frame_period;
250 break;
251 default:
252 dev_err(msp->dev, "%s: ERROR: Unknown protocol (%d)!\n",
253 __func__,
254 config->protocol);
255 return -EINVAL;
256 }
257
258 temp_reg = (sck_div - 1) & SCK_DIV_MASK;
259 temp_reg |= FRAME_WIDTH_BITS(frame_width);
260 temp_reg |= FRAME_PERIOD_BITS(frame_per);
261 writel(temp_reg, msp->registers + MSP_SRG);
262
263 msp->f_bitclk = (config->f_inputclk)/(sck_div + 1);
264
265 /* Enable bit-clock */
266 udelay(100);
267 reg_val_GCR = readl(msp->registers + MSP_GCR);
268 writel(reg_val_GCR | SRG_ENABLE, msp->registers + MSP_GCR);
269 udelay(100);
270
271 return 0;
272}
273
274static int configure_multichannel(struct ux500_msp *msp,
275 struct ux500_msp_config *config)
276{
277 struct msp_protdesc *protdesc;
278 struct msp_multichannel_config *mcfg;
279 u32 reg_val_MCR;
280
281 if (config->default_protdesc == 1) {
282 if (config->protocol >= MSP_INVALID_PROTOCOL) {
283 dev_err(msp->dev,
284 "%s: ERROR: Invalid protocol (%d)!\n",
285 __func__, config->protocol);
286 return -EINVAL;
287 }
288 protdesc = (struct msp_protdesc *)
289 &prot_descs[config->protocol];
290 } else {
291 protdesc = (struct msp_protdesc *)&config->protdesc;
292 }
293
294 mcfg = &config->multichannel_config;
295 if (mcfg->tx_multichannel_enable) {
296 if (protdesc->tx_phase_mode == MSP_SINGLE_PHASE) {
297 reg_val_MCR = readl(msp->registers + MSP_MCR);
298 writel(reg_val_MCR | (mcfg->tx_multichannel_enable ?
299 1 << TMCEN_BIT : 0),
300 msp->registers + MSP_MCR);
301 writel(mcfg->tx_channel_0_enable,
302 msp->registers + MSP_TCE0);
303 writel(mcfg->tx_channel_1_enable,
304 msp->registers + MSP_TCE1);
305 writel(mcfg->tx_channel_2_enable,
306 msp->registers + MSP_TCE2);
307 writel(mcfg->tx_channel_3_enable,
308 msp->registers + MSP_TCE3);
309 } else {
310 dev_err(msp->dev,
311 "%s: ERROR: Only single-phase supported (TX-mode: %d)!\n",
312 __func__, protdesc->tx_phase_mode);
313 return -EINVAL;
314 }
315 }
316 if (mcfg->rx_multichannel_enable) {
317 if (protdesc->rx_phase_mode == MSP_SINGLE_PHASE) {
318 reg_val_MCR = readl(msp->registers + MSP_MCR);
319 writel(reg_val_MCR | (mcfg->rx_multichannel_enable ?
320 1 << RMCEN_BIT : 0),
321 msp->registers + MSP_MCR);
322 writel(mcfg->rx_channel_0_enable,
323 msp->registers + MSP_RCE0);
324 writel(mcfg->rx_channel_1_enable,
325 msp->registers + MSP_RCE1);
326 writel(mcfg->rx_channel_2_enable,
327 msp->registers + MSP_RCE2);
328 writel(mcfg->rx_channel_3_enable,
329 msp->registers + MSP_RCE3);
330 } else {
331 dev_err(msp->dev,
332 "%s: ERROR: Only single-phase supported (RX-mode: %d)!\n",
333 __func__, protdesc->rx_phase_mode);
334 return -EINVAL;
335 }
336 if (mcfg->rx_comparison_enable_mode) {
337 reg_val_MCR = readl(msp->registers + MSP_MCR);
338 writel(reg_val_MCR |
339 (mcfg->rx_comparison_enable_mode << RCMPM_BIT),
340 msp->registers + MSP_MCR);
341
342 writel(mcfg->comparison_mask,
343 msp->registers + MSP_RCM);
344 writel(mcfg->comparison_value,
345 msp->registers + MSP_RCV);
346
347 }
348 }
349
350 return 0;
351}
352
353static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
354{
355 int status = 0;
356 u32 reg_val_DMACR, reg_val_GCR;
357
358 /* Check msp state whether in RUN or CONFIGURED Mode */
359 if ((msp->msp_state == MSP_STATE_IDLE) && (msp->plat_init)) {
360 status = msp->plat_init();
361 if (status) {
362 dev_err(msp->dev, "%s: ERROR: Failed to init MSP (%d)!\n",
363 __func__, status);
364 return status;
365 }
366 }
367
368 /* Configure msp with protocol dependent settings */
369 configure_protocol(msp, config);
370 setup_bitclk(msp, config);
371 if (config->multichannel_configured == 1) {
372 status = configure_multichannel(msp, config);
373 if (status)
374 dev_warn(msp->dev,
375 "%s: WARN: configure_multichannel failed (%d)!\n",
376 __func__, status);
377 }
378
379 /* Make sure the correct DMA-directions are configured */
380 if ((config->direction & MSP_DIR_RX) && (!msp->dma_cfg_rx)) {
381 dev_err(msp->dev, "%s: ERROR: MSP RX-mode is not configured!",
382 __func__);
383 return -EINVAL;
384 }
385 if ((config->direction == MSP_DIR_TX) && (!msp->dma_cfg_tx)) {
386 dev_err(msp->dev, "%s: ERROR: MSP TX-mode is not configured!",
387 __func__);
388 return -EINVAL;
389 }
390
391 reg_val_DMACR = readl(msp->registers + MSP_DMACR);
392 if (config->direction & MSP_DIR_RX)
393 reg_val_DMACR |= RX_DMA_ENABLE;
394 if (config->direction & MSP_DIR_TX)
395 reg_val_DMACR |= TX_DMA_ENABLE;
396 writel(reg_val_DMACR, msp->registers + MSP_DMACR);
397
398 writel(config->iodelay, msp->registers + MSP_IODLY);
399
400 /* Enable frame generation logic */
401 reg_val_GCR = readl(msp->registers + MSP_GCR);
402 writel(reg_val_GCR | FRAME_GEN_ENABLE, msp->registers + MSP_GCR);
403
404 return status;
405}
406
407static void flush_fifo_rx(struct ux500_msp *msp)
408{
409 u32 reg_val_DR, reg_val_GCR, reg_val_FLR;
410 u32 limit = 32;
411
412 reg_val_GCR = readl(msp->registers + MSP_GCR);
413 writel(reg_val_GCR | RX_ENABLE, msp->registers + MSP_GCR);
414
415 reg_val_FLR = readl(msp->registers + MSP_FLR);
416 while (!(reg_val_FLR & RX_FIFO_EMPTY) && limit--) {
417 reg_val_DR = readl(msp->registers + MSP_DR);
418 reg_val_FLR = readl(msp->registers + MSP_FLR);
419 }
420
421 writel(reg_val_GCR, msp->registers + MSP_GCR);
422}
423
424static void flush_fifo_tx(struct ux500_msp *msp)
425{
426 u32 reg_val_TSTDR, reg_val_GCR, reg_val_FLR;
427 u32 limit = 32;
428
429 reg_val_GCR = readl(msp->registers + MSP_GCR);
430 writel(reg_val_GCR | TX_ENABLE, msp->registers + MSP_GCR);
431 writel(MSP_ITCR_ITEN | MSP_ITCR_TESTFIFO, msp->registers + MSP_ITCR);
432
433 reg_val_FLR = readl(msp->registers + MSP_FLR);
434 while (!(reg_val_FLR & TX_FIFO_EMPTY) && limit--) {
435 reg_val_TSTDR = readl(msp->registers + MSP_TSTDR);
436 reg_val_FLR = readl(msp->registers + MSP_FLR);
437 }
438 writel(0x0, msp->registers + MSP_ITCR);
439 writel(reg_val_GCR, msp->registers + MSP_GCR);
440}
441
442int ux500_msp_i2s_open(struct ux500_msp *msp,
443 struct ux500_msp_config *config)
444{
445 u32 old_reg, new_reg, mask;
446 int res;
447 unsigned int tx_sel, rx_sel, tx_busy, rx_busy;
448
449 if (in_interrupt()) {
450 dev_err(msp->dev,
451 "%s: ERROR: Open called in interrupt context!\n",
452 __func__);
453 return -1;
454 }
455
456 tx_sel = (config->direction & MSP_DIR_TX) > 0;
457 rx_sel = (config->direction & MSP_DIR_RX) > 0;
458 if (!tx_sel && !rx_sel) {
459 dev_err(msp->dev, "%s: Error: No direction selected!\n",
460 __func__);
461 return -EINVAL;
462 }
463
464 tx_busy = (msp->dir_busy & MSP_DIR_TX) > 0;
465 rx_busy = (msp->dir_busy & MSP_DIR_RX) > 0;
466 if (tx_busy && tx_sel) {
467 dev_err(msp->dev, "%s: Error: TX is in use!\n", __func__);
468 return -EBUSY;
469 }
470 if (rx_busy && rx_sel) {
471 dev_err(msp->dev, "%s: Error: RX is in use!\n", __func__);
472 return -EBUSY;
473 }
474
475 msp->dir_busy |= (tx_sel ? MSP_DIR_TX : 0) | (rx_sel ? MSP_DIR_RX : 0);
476
477 /* First do the global config register */
478 mask = RX_CLK_SEL_MASK | TX_CLK_SEL_MASK | RX_FSYNC_MASK |
479 TX_FSYNC_MASK | RX_SYNC_SEL_MASK | TX_SYNC_SEL_MASK |
480 RX_FIFO_ENABLE_MASK | TX_FIFO_ENABLE_MASK | SRG_CLK_SEL_MASK |
481 LOOPBACK_MASK | TX_EXTRA_DELAY_MASK;
482
483 new_reg = (config->tx_clk_sel | config->rx_clk_sel |
484 config->rx_fsync_pol | config->tx_fsync_pol |
485 config->rx_fsync_sel | config->tx_fsync_sel |
486 config->rx_fifo_config | config->tx_fifo_config |
487 config->srg_clk_sel | config->loopback_enable |
488 config->tx_data_enable);
489
490 old_reg = readl(msp->registers + MSP_GCR);
491 old_reg &= ~mask;
492 new_reg |= old_reg;
493 writel(new_reg, msp->registers + MSP_GCR);
494
495 res = enable_msp(msp, config);
496 if (res < 0) {
497 dev_err(msp->dev, "%s: ERROR: enable_msp failed (%d)!\n",
498 __func__, res);
499 return -EBUSY;
500 }
501 if (config->loopback_enable & 0x80)
502 msp->loopback_enable = 1;
503
504 /* Flush FIFOs */
505 flush_fifo_tx(msp);
506 flush_fifo_rx(msp);
507
508 msp->msp_state = MSP_STATE_CONFIGURED;
509 return 0;
510}
511
512static void disable_msp_rx(struct ux500_msp *msp)
513{
514 u32 reg_val_GCR, reg_val_DMACR, reg_val_IMSC;
515
516 reg_val_GCR = readl(msp->registers + MSP_GCR);
517 writel(reg_val_GCR & ~RX_ENABLE, msp->registers + MSP_GCR);
518 reg_val_DMACR = readl(msp->registers + MSP_DMACR);
519 writel(reg_val_DMACR & ~RX_DMA_ENABLE, msp->registers + MSP_DMACR);
520 reg_val_IMSC = readl(msp->registers + MSP_IMSC);
521 writel(reg_val_IMSC &
522 ~(RX_SERVICE_INT | RX_OVERRUN_ERROR_INT),
523 msp->registers + MSP_IMSC);
524
525 msp->dir_busy &= ~MSP_DIR_RX;
526}
527
528static void disable_msp_tx(struct ux500_msp *msp)
529{
530 u32 reg_val_GCR, reg_val_DMACR, reg_val_IMSC;
531
532 reg_val_GCR = readl(msp->registers + MSP_GCR);
533 writel(reg_val_GCR & ~TX_ENABLE, msp->registers + MSP_GCR);
534 reg_val_DMACR = readl(msp->registers + MSP_DMACR);
535 writel(reg_val_DMACR & ~TX_DMA_ENABLE, msp->registers + MSP_DMACR);
536 reg_val_IMSC = readl(msp->registers + MSP_IMSC);
537 writel(reg_val_IMSC &
538 ~(TX_SERVICE_INT | TX_UNDERRUN_ERR_INT),
539 msp->registers + MSP_IMSC);
540
541 msp->dir_busy &= ~MSP_DIR_TX;
542}
543
544static int disable_msp(struct ux500_msp *msp, unsigned int dir)
545{
546 u32 reg_val_GCR;
547 int status = 0;
548 unsigned int disable_tx, disable_rx;
549
550 reg_val_GCR = readl(msp->registers + MSP_GCR);
551 disable_tx = dir & MSP_DIR_TX;
552 disable_rx = dir & MSP_DIR_TX;
553 if (disable_tx && disable_rx) {
554 reg_val_GCR = readl(msp->registers + MSP_GCR);
555 writel(reg_val_GCR | LOOPBACK_MASK,
556 msp->registers + MSP_GCR);
557
558 /* Flush TX-FIFO */
559 flush_fifo_tx(msp);
560
561 /* Disable TX-channel */
562 writel((readl(msp->registers + MSP_GCR) &
563 (~TX_ENABLE)), msp->registers + MSP_GCR);
564
565 /* Flush RX-FIFO */
566 flush_fifo_rx(msp);
567
568 /* Disable Loopback and Receive channel */
569 writel((readl(msp->registers + MSP_GCR) &
570 (~(RX_ENABLE | LOOPBACK_MASK))),
571 msp->registers + MSP_GCR);
572
573 disable_msp_tx(msp);
574 disable_msp_rx(msp);
575 } else if (disable_tx)
576 disable_msp_tx(msp);
577 else if (disable_rx)
578 disable_msp_rx(msp);
579
580 return status;
581}
582
583int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
584{
585 u32 reg_val_GCR, enable_bit;
586
587 if (msp->msp_state == MSP_STATE_IDLE) {
588 dev_err(msp->dev, "%s: ERROR: MSP is not configured!\n",
589 __func__);
590 return -EINVAL;
591 }
592
593 switch (cmd) {
594 case SNDRV_PCM_TRIGGER_START:
595 case SNDRV_PCM_TRIGGER_RESUME:
596 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
597 if (direction == SNDRV_PCM_STREAM_PLAYBACK)
598 enable_bit = TX_ENABLE;
599 else
600 enable_bit = RX_ENABLE;
601 reg_val_GCR = readl(msp->registers + MSP_GCR);
602 writel(reg_val_GCR | enable_bit, msp->registers + MSP_GCR);
603 break;
604
605 case SNDRV_PCM_TRIGGER_STOP:
606 case SNDRV_PCM_TRIGGER_SUSPEND:
607 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
608 if (direction == SNDRV_PCM_STREAM_PLAYBACK)
609 disable_msp_tx(msp);
610 else
611 disable_msp_rx(msp);
612 break;
613 default:
614 return -EINVAL;
615 break;
616 }
617
618 return 0;
619}
620
621int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
622{
623 int status = 0;
624
625 dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir);
626
627 status = disable_msp(msp, dir);
628 if (msp->dir_busy == 0) {
629 /* disable sample rate and frame generators */
630 msp->msp_state = MSP_STATE_IDLE;
631 writel((readl(msp->registers + MSP_GCR) &
632 (~(FRAME_GEN_ENABLE | SRG_ENABLE))),
633 msp->registers + MSP_GCR);
634 if (msp->plat_exit)
635 status = msp->plat_exit();
636 if (status)
637 dev_warn(msp->dev,
638 "%s: WARN: ux500_msp_i2s_exit failed (%d)!\n",
639 __func__, status);
640 writel(0, msp->registers + MSP_GCR);
641 writel(0, msp->registers + MSP_TCF);
642 writel(0, msp->registers + MSP_RCF);
643 writel(0, msp->registers + MSP_DMACR);
644 writel(0, msp->registers + MSP_SRG);
645 writel(0, msp->registers + MSP_MCR);
646 writel(0, msp->registers + MSP_RCM);
647 writel(0, msp->registers + MSP_RCV);
648 writel(0, msp->registers + MSP_TCE0);
649 writel(0, msp->registers + MSP_TCE1);
650 writel(0, msp->registers + MSP_TCE2);
651 writel(0, msp->registers + MSP_TCE3);
652 writel(0, msp->registers + MSP_RCE0);
653 writel(0, msp->registers + MSP_RCE1);
654 writel(0, msp->registers + MSP_RCE2);
655 writel(0, msp->registers + MSP_RCE3);
656 }
657
658 return status;
659
660}
661
662int ux500_msp_i2s_init_msp(struct platform_device *pdev,
663 struct ux500_msp **msp_p,
664 struct msp_i2s_platform_data *platform_data)
665{
666 int ret = 0;
667 struct resource *res = NULL;
668 struct i2s_controller *i2s_cont;
669 struct ux500_msp *msp;
670
671 dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__,
672 pdev->name, platform_data->id);
673
674 *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL);
675 msp = *msp_p;
676
677 msp->id = platform_data->id;
678 msp->dev = &pdev->dev;
679 msp->plat_init = platform_data->msp_i2s_init;
680 msp->plat_exit = platform_data->msp_i2s_exit;
681 msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx;
682 msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx;
683
684 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
685 if (res == NULL) {
686 dev_err(&pdev->dev, "%s: ERROR: Unable to get resource!\n",
687 __func__);
688 ret = -ENOMEM;
689 goto err_res;
690 }
691
692 msp->registers = ioremap(res->start, (res->end - res->start + 1));
693 if (msp->registers == NULL) {
694 dev_err(&pdev->dev, "%s: ERROR: ioremap failed!\n", __func__);
695 ret = -ENOMEM;
696 goto err_res;
697 }
698
699 msp->msp_state = MSP_STATE_IDLE;
700 msp->loopback_enable = 0;
701
702 /* I2S-controller is allocated and added in I2S controller class. */
703 i2s_cont = devm_kzalloc(&pdev->dev, sizeof(*i2s_cont), GFP_KERNEL);
704 if (!i2s_cont) {
705 dev_err(&pdev->dev,
706 "%s: ERROR: Failed to allocate I2S-controller!\n",
707 __func__);
708 goto err_i2s_cont;
709 }
710 i2s_cont->dev.parent = &pdev->dev;
711 i2s_cont->data = (void *)msp;
712 i2s_cont->id = (s16)msp->id;
713 snprintf(i2s_cont->name, sizeof(i2s_cont->name), "ux500-msp-i2s.%04x",
714 msp->id);
715 dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name);
716 msp->i2s_cont = i2s_cont;
717
718 return 0;
719
720err_i2s_cont:
721 iounmap(msp->registers);
722
723err_res:
724 devm_kfree(&pdev->dev, msp);
725
726 return ret;
727}
728
729void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
730 struct ux500_msp *msp)
731{
732 dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id);
733
734 device_unregister(&msp->i2s_cont->dev);
735 devm_kfree(&pdev->dev, msp->i2s_cont);
736
737 iounmap(msp->registers);
738
739 devm_kfree(&pdev->dev, msp);
740}
741
742MODULE_LICENSE("GPLv2");
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h
new file mode 100644
index 000000000000..7f71b4a0d4bc
--- /dev/null
+++ b/sound/soc/ux500/ux500_msp_i2s.h
@@ -0,0 +1,553 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
5 * for ST-Ericsson.
6 *
7 * License terms:
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as published
11 * by the Free Software Foundation.
12 */
13
14
15#ifndef UX500_MSP_I2S_H
16#define UX500_MSP_I2S_H
17
18#include <linux/platform_device.h>
19
20#include <mach/board-mop500-msp.h>
21
22#define MSP_INPUT_FREQ_APB 48000000
23
24/*** Stereo mode. Used for APB data accesses as 16 bits accesses (mono),
25 * 32 bits accesses (stereo).
26 ***/
27enum msp_stereo_mode {
28 MSP_MONO,
29 MSP_STEREO
30};
31
32/* Direction (Transmit/Receive mode) */
33enum msp_direction {
34 MSP_TX = 1,
35 MSP_RX = 2
36};
37
38/* Transmit and receive configuration register */
39#define MSP_BIG_ENDIAN 0x00000000
40#define MSP_LITTLE_ENDIAN 0x00001000
41#define MSP_UNEXPECTED_FS_ABORT 0x00000000
42#define MSP_UNEXPECTED_FS_IGNORE 0x00008000
43#define MSP_NON_MODE_BIT_MASK 0x00009000
44
45/* Global configuration register */
46#define RX_ENABLE 0x00000001
47#define RX_FIFO_ENABLE 0x00000002
48#define RX_SYNC_SRG 0x00000010
49#define RX_CLK_POL_RISING 0x00000020
50#define RX_CLK_SEL_SRG 0x00000040
51#define TX_ENABLE 0x00000100
52#define TX_FIFO_ENABLE 0x00000200
53#define TX_SYNC_SRG_PROG 0x00001800
54#define TX_SYNC_SRG_AUTO 0x00001000
55#define TX_CLK_POL_RISING 0x00002000
56#define TX_CLK_SEL_SRG 0x00004000
57#define TX_EXTRA_DELAY_ENABLE 0x00008000
58#define SRG_ENABLE 0x00010000
59#define FRAME_GEN_ENABLE 0x00100000
60#define SRG_CLK_SEL_APB 0x00000000
61#define RX_FIFO_SYNC_HI 0x00000000
62#define TX_FIFO_SYNC_HI 0x00000000
63#define SPI_CLK_MODE_NORMAL 0x00000000
64
65#define MSP_FRAME_SIZE_AUTO -1
66
67#define MSP_DR 0x00
68#define MSP_GCR 0x04
69#define MSP_TCF 0x08
70#define MSP_RCF 0x0c
71#define MSP_SRG 0x10
72#define MSP_FLR 0x14
73#define MSP_DMACR 0x18
74
75#define MSP_IMSC 0x20
76#define MSP_RIS 0x24
77#define MSP_MIS 0x28
78#define MSP_ICR 0x2c
79#define MSP_MCR 0x30
80#define MSP_RCV 0x34
81#define MSP_RCM 0x38
82
83#define MSP_TCE0 0x40
84#define MSP_TCE1 0x44
85#define MSP_TCE2 0x48
86#define MSP_TCE3 0x4c
87
88#define MSP_RCE0 0x60
89#define MSP_RCE1 0x64
90#define MSP_RCE2 0x68
91#define MSP_RCE3 0x6c
92#define MSP_IODLY 0x70
93
94#define MSP_ITCR 0x80
95#define MSP_ITIP 0x84
96#define MSP_ITOP 0x88
97#define MSP_TSTDR 0x8c
98
99#define MSP_PID0 0xfe0
100#define MSP_PID1 0xfe4
101#define MSP_PID2 0xfe8
102#define MSP_PID3 0xfec
103
104#define MSP_CID0 0xff0
105#define MSP_CID1 0xff4
106#define MSP_CID2 0xff8
107#define MSP_CID3 0xffc
108
109/* Protocol dependant parameters list */
110#define RX_ENABLE_MASK BIT(0)
111#define RX_FIFO_ENABLE_MASK BIT(1)
112#define RX_FSYNC_MASK BIT(2)
113#define DIRECT_COMPANDING_MASK BIT(3)
114#define RX_SYNC_SEL_MASK BIT(4)
115#define RX_CLK_POL_MASK BIT(5)
116#define RX_CLK_SEL_MASK BIT(6)
117#define LOOPBACK_MASK BIT(7)
118#define TX_ENABLE_MASK BIT(8)
119#define TX_FIFO_ENABLE_MASK BIT(9)
120#define TX_FSYNC_MASK BIT(10)
121#define TX_MSP_TDR_TSR BIT(11)
122#define TX_SYNC_SEL_MASK (BIT(12) | BIT(11))
123#define TX_CLK_POL_MASK BIT(13)
124#define TX_CLK_SEL_MASK BIT(14)
125#define TX_EXTRA_DELAY_MASK BIT(15)
126#define SRG_ENABLE_MASK BIT(16)
127#define SRG_CLK_POL_MASK BIT(17)
128#define SRG_CLK_SEL_MASK (BIT(19) | BIT(18))
129#define FRAME_GEN_EN_MASK BIT(20)
130#define SPI_CLK_MODE_MASK (BIT(22) | BIT(21))
131#define SPI_BURST_MODE_MASK BIT(23)
132
133#define RXEN_SHIFT 0
134#define RFFEN_SHIFT 1
135#define RFSPOL_SHIFT 2
136#define DCM_SHIFT 3
137#define RFSSEL_SHIFT 4
138#define RCKPOL_SHIFT 5
139#define RCKSEL_SHIFT 6
140#define LBM_SHIFT 7
141#define TXEN_SHIFT 8
142#define TFFEN_SHIFT 9
143#define TFSPOL_SHIFT 10
144#define TFSSEL_SHIFT 11
145#define TCKPOL_SHIFT 13
146#define TCKSEL_SHIFT 14
147#define TXDDL_SHIFT 15
148#define SGEN_SHIFT 16
149#define SCKPOL_SHIFT 17
150#define SCKSEL_SHIFT 18
151#define FGEN_SHIFT 20
152#define SPICKM_SHIFT 21
153#define TBSWAP_SHIFT 28
154
155#define RCKPOL_MASK BIT(0)
156#define TCKPOL_MASK BIT(0)
157#define SPICKM_MASK (BIT(1) | BIT(0))
158#define MSP_RX_CLKPOL_BIT(n) ((n & RCKPOL_MASK) << RCKPOL_SHIFT)
159#define MSP_TX_CLKPOL_BIT(n) ((n & TCKPOL_MASK) << TCKPOL_SHIFT)
160
161#define P1ELEN_SHIFT 0
162#define P1FLEN_SHIFT 3
163#define DTYP_SHIFT 10
164#define ENDN_SHIFT 12
165#define DDLY_SHIFT 13
166#define FSIG_SHIFT 15
167#define P2ELEN_SHIFT 16
168#define P2FLEN_SHIFT 19
169#define P2SM_SHIFT 26
170#define P2EN_SHIFT 27
171#define FSYNC_SHIFT 15
172
173#define P1ELEN_MASK 0x00000007
174#define P2ELEN_MASK 0x00070000
175#define P1FLEN_MASK 0x00000378
176#define P2FLEN_MASK 0x03780000
177#define DDLY_MASK 0x00003000
178#define DTYP_MASK 0x00000600
179#define P2SM_MASK 0x04000000
180#define P2EN_MASK 0x08000000
181#define ENDN_MASK 0x00001000
182#define TFSPOL_MASK 0x00000400
183#define TBSWAP_MASK 0x30000000
184#define COMPANDING_MODE_MASK 0x00000c00
185#define FSYNC_MASK 0x00008000
186
187#define MSP_P1_ELEM_LEN_BITS(n) (n & P1ELEN_MASK)
188#define MSP_P2_ELEM_LEN_BITS(n) (((n) << P2ELEN_SHIFT) & P2ELEN_MASK)
189#define MSP_P1_FRAME_LEN_BITS(n) (((n) << P1FLEN_SHIFT) & P1FLEN_MASK)
190#define MSP_P2_FRAME_LEN_BITS(n) (((n) << P2FLEN_SHIFT) & P2FLEN_MASK)
191#define MSP_DATA_DELAY_BITS(n) (((n) << DDLY_SHIFT) & DDLY_MASK)
192#define MSP_DATA_TYPE_BITS(n) (((n) << DTYP_SHIFT) & DTYP_MASK)
193#define MSP_P2_START_MODE_BIT(n) ((n << P2SM_SHIFT) & P2SM_MASK)
194#define MSP_P2_ENABLE_BIT(n) ((n << P2EN_SHIFT) & P2EN_MASK)
195#define MSP_SET_ENDIANNES_BIT(n) ((n << ENDN_SHIFT) & ENDN_MASK)
196#define MSP_FSYNC_POL(n) ((n << TFSPOL_SHIFT) & TFSPOL_MASK)
197#define MSP_DATA_WORD_SWAP(n) ((n << TBSWAP_SHIFT) & TBSWAP_MASK)
198#define MSP_SET_COMPANDING_MODE(n) ((n << DTYP_SHIFT) & \
199 COMPANDING_MODE_MASK)
200#define MSP_SET_FSYNC_IGNORE(n) ((n << FSYNC_SHIFT) & FSYNC_MASK)
201
202/* Flag register */
203#define RX_BUSY BIT(0)
204#define RX_FIFO_EMPTY BIT(1)
205#define RX_FIFO_FULL BIT(2)
206#define TX_BUSY BIT(3)
207#define TX_FIFO_EMPTY BIT(4)
208#define TX_FIFO_FULL BIT(5)
209
210#define RBUSY_SHIFT 0
211#define RFE_SHIFT 1
212#define RFU_SHIFT 2
213#define TBUSY_SHIFT 3
214#define TFE_SHIFT 4
215#define TFU_SHIFT 5
216
217/* Multichannel control register */
218#define RMCEN_SHIFT 0
219#define RMCSF_SHIFT 1
220#define RCMPM_SHIFT 3
221#define TMCEN_SHIFT 5
222#define TNCSF_SHIFT 6
223
224/* Sample rate generator register */
225#define SCKDIV_SHIFT 0
226#define FRWID_SHIFT 10
227#define FRPER_SHIFT 16
228
229#define SCK_DIV_MASK 0x0000003FF
230#define FRAME_WIDTH_BITS(n) (((n) << FRWID_SHIFT) & 0x0000FC00)
231#define FRAME_PERIOD_BITS(n) (((n) << FRPER_SHIFT) & 0x1FFF0000)
232
233/* DMA controller register */
234#define RX_DMA_ENABLE BIT(0)
235#define TX_DMA_ENABLE BIT(1)
236
237#define RDMAE_SHIFT 0
238#define TDMAE_SHIFT 1
239
240/* Interrupt Register */
241#define RX_SERVICE_INT BIT(0)
242#define RX_OVERRUN_ERROR_INT BIT(1)
243#define RX_FSYNC_ERR_INT BIT(2)
244#define RX_FSYNC_INT BIT(3)
245#define TX_SERVICE_INT BIT(4)
246#define TX_UNDERRUN_ERR_INT BIT(5)
247#define TX_FSYNC_ERR_INT BIT(6)
248#define TX_FSYNC_INT BIT(7)
249#define ALL_INT 0x000000ff
250
251/* MSP test control register */
252#define MSP_ITCR_ITEN BIT(0)
253#define MSP_ITCR_TESTFIFO BIT(1)
254
255#define RMCEN_BIT 0
256#define RMCSF_BIT 1
257#define RCMPM_BIT 3
258#define TMCEN_BIT 5
259#define TNCSF_BIT 6
260
261/* Single or dual phase mode */
262enum msp_phase_mode {
263 MSP_SINGLE_PHASE,
264 MSP_DUAL_PHASE
265};
266
267/* Frame length */
268enum msp_frame_length {
269 MSP_FRAME_LEN_1 = 0,
270 MSP_FRAME_LEN_2 = 1,
271 MSP_FRAME_LEN_4 = 3,
272 MSP_FRAME_LEN_8 = 7,
273 MSP_FRAME_LEN_12 = 11,
274 MSP_FRAME_LEN_16 = 15,
275 MSP_FRAME_LEN_20 = 19,
276 MSP_FRAME_LEN_32 = 31,
277 MSP_FRAME_LEN_48 = 47,
278 MSP_FRAME_LEN_64 = 63
279};
280
281/* Element length */
282enum msp_elem_length {
283 MSP_ELEM_LEN_8 = 0,
284 MSP_ELEM_LEN_10 = 1,
285 MSP_ELEM_LEN_12 = 2,
286 MSP_ELEM_LEN_14 = 3,
287 MSP_ELEM_LEN_16 = 4,
288 MSP_ELEM_LEN_20 = 5,
289 MSP_ELEM_LEN_24 = 6,
290 MSP_ELEM_LEN_32 = 7
291};
292
293enum msp_data_xfer_width {
294 MSP_DATA_TRANSFER_WIDTH_BYTE,
295 MSP_DATA_TRANSFER_WIDTH_HALFWORD,
296 MSP_DATA_TRANSFER_WIDTH_WORD
297};
298
299enum msp_frame_sync {
300 MSP_FSYNC_UNIGNORE = 0,
301 MSP_FSYNC_IGNORE = 1,
302};
303
304enum msp_phase2_start_mode {
305 MSP_PHASE2_START_MODE_IMEDIATE,
306 MSP_PHASE2_START_MODE_FSYNC
307};
308
309enum msp_btf {
310 MSP_BTF_MS_BIT_FIRST = 0,
311 MSP_BTF_LS_BIT_FIRST = 1
312};
313
314enum msp_fsync_pol {
315 MSP_FSYNC_POL_ACT_HI = 0,
316 MSP_FSYNC_POL_ACT_LO = 1
317};
318
319/* Data delay (in bit clock cycles) */
320enum msp_delay {
321 MSP_DELAY_0 = 0,
322 MSP_DELAY_1 = 1,
323 MSP_DELAY_2 = 2,
324 MSP_DELAY_3 = 3
325};
326
327/* Configurations of clocks (transmit, receive or sample rate generator) */
328enum msp_edge {
329 MSP_FALLING_EDGE = 0,
330 MSP_RISING_EDGE = 1,
331};
332
333enum msp_hws {
334 MSP_SWAP_NONE = 0,
335 MSP_SWAP_BYTE_PER_WORD = 1,
336 MSP_SWAP_BYTE_PER_HALF_WORD = 2,
337 MSP_SWAP_HALF_WORD_PER_WORD = 3
338};
339
340enum msp_compress_mode {
341 MSP_COMPRESS_MODE_LINEAR = 0,
342 MSP_COMPRESS_MODE_MU_LAW = 2,
343 MSP_COMPRESS_MODE_A_LAW = 3
344};
345
346enum msp_spi_burst_mode {
347 MSP_SPI_BURST_MODE_DISABLE = 0,
348 MSP_SPI_BURST_MODE_ENABLE = 1
349};
350
351enum msp_expand_mode {
352 MSP_EXPAND_MODE_LINEAR = 0,
353 MSP_EXPAND_MODE_LINEAR_SIGNED = 1,
354 MSP_EXPAND_MODE_MU_LAW = 2,
355 MSP_EXPAND_MODE_A_LAW = 3
356};
357
358#define MSP_FRAME_PERIOD_IN_MONO_MODE 256
359#define MSP_FRAME_PERIOD_IN_STEREO_MODE 32
360#define MSP_FRAME_WIDTH_IN_STEREO_MODE 16
361
362enum msp_protocol {
363 MSP_I2S_PROTOCOL,
364 MSP_PCM_PROTOCOL,
365 MSP_PCM_COMPAND_PROTOCOL,
366 MSP_INVALID_PROTOCOL
367};
368
369/*
370 * No of registers to backup during
371 * suspend resume
372 */
373#define MAX_MSP_BACKUP_REGS 36
374
375enum enum_i2s_controller {
376 MSP_0_I2S_CONTROLLER = 0,
377 MSP_1_I2S_CONTROLLER,
378 MSP_2_I2S_CONTROLLER,
379 MSP_3_I2S_CONTROLLER,
380};
381
382enum i2s_direction_t {
383 MSP_DIR_TX = 0x01,
384 MSP_DIR_RX = 0x02,
385};
386
387enum msp_data_size {
388 MSP_DATA_BITS_DEFAULT = -1,
389 MSP_DATA_BITS_8 = 0x00,
390 MSP_DATA_BITS_10,
391 MSP_DATA_BITS_12,
392 MSP_DATA_BITS_14,
393 MSP_DATA_BITS_16,
394 MSP_DATA_BITS_20,
395 MSP_DATA_BITS_24,
396 MSP_DATA_BITS_32,
397};
398
399enum msp_state {
400 MSP_STATE_IDLE = 0,
401 MSP_STATE_CONFIGURED = 1,
402 MSP_STATE_RUNNING = 2,
403};
404
405enum msp_rx_comparison_enable_mode {
406 MSP_COMPARISON_DISABLED = 0,
407 MSP_COMPARISON_NONEQUAL_ENABLED = 2,
408 MSP_COMPARISON_EQUAL_ENABLED = 3
409};
410
411struct msp_multichannel_config {
412 bool rx_multichannel_enable;
413 bool tx_multichannel_enable;
414 enum msp_rx_comparison_enable_mode rx_comparison_enable_mode;
415 u8 padding;
416 u32 comparison_value;
417 u32 comparison_mask;
418 u32 rx_channel_0_enable;
419 u32 rx_channel_1_enable;
420 u32 rx_channel_2_enable;
421 u32 rx_channel_3_enable;
422 u32 tx_channel_0_enable;
423 u32 tx_channel_1_enable;
424 u32 tx_channel_2_enable;
425 u32 tx_channel_3_enable;
426};
427
428struct msp_protdesc {
429 u32 rx_phase_mode;
430 u32 tx_phase_mode;
431 u32 rx_phase2_start_mode;
432 u32 tx_phase2_start_mode;
433 u32 rx_byte_order;
434 u32 tx_byte_order;
435 u32 rx_frame_len_1;
436 u32 rx_frame_len_2;
437 u32 tx_frame_len_1;
438 u32 tx_frame_len_2;
439 u32 rx_elem_len_1;
440 u32 rx_elem_len_2;
441 u32 tx_elem_len_1;
442 u32 tx_elem_len_2;
443 u32 rx_data_delay;
444 u32 tx_data_delay;
445 u32 rx_clk_pol;
446 u32 tx_clk_pol;
447 u32 rx_fsync_pol;
448 u32 tx_fsync_pol;
449 u32 rx_half_word_swap;
450 u32 tx_half_word_swap;
451 u32 compression_mode;
452 u32 expansion_mode;
453 u32 frame_sync_ignore;
454 u32 frame_period;
455 u32 frame_width;
456 u32 clocks_per_frame;
457};
458
459struct i2s_message {
460 enum i2s_direction_t i2s_direction;
461 void *txdata;
462 void *rxdata;
463 size_t txbytes;
464 size_t rxbytes;
465 int dma_flag;
466 int tx_offset;
467 int rx_offset;
468 bool cyclic_dma;
469 dma_addr_t buf_addr;
470 size_t buf_len;
471 size_t period_len;
472};
473
474struct i2s_controller {
475 struct module *owner;
476 unsigned int id;
477 unsigned int class;
478 const struct i2s_algorithm *algo; /* the algorithm to access the bus */
479 void *data;
480 struct mutex bus_lock;
481 struct device dev; /* the controller device */
482 char name[48];
483};
484
485struct ux500_msp_config {
486 unsigned int f_inputclk;
487 unsigned int rx_clk_sel;
488 unsigned int tx_clk_sel;
489 unsigned int srg_clk_sel;
490 unsigned int rx_fsync_pol;
491 unsigned int tx_fsync_pol;
492 unsigned int rx_fsync_sel;
493 unsigned int tx_fsync_sel;
494 unsigned int rx_fifo_config;
495 unsigned int tx_fifo_config;
496 unsigned int spi_clk_mode;
497 unsigned int spi_burst_mode;
498 unsigned int loopback_enable;
499 unsigned int tx_data_enable;
500 unsigned int default_protdesc;
501 struct msp_protdesc protdesc;
502 int multichannel_configured;
503 struct msp_multichannel_config multichannel_config;
504 unsigned int direction;
505 unsigned int protocol;
506 unsigned int frame_freq;
507 unsigned int frame_size;
508 enum msp_data_size data_size;
509 unsigned int def_elem_len;
510 unsigned int iodelay;
511 void (*handler) (void *data);
512 void *tx_callback_data;
513 void *rx_callback_data;
514};
515
516struct ux500_msp {
517 enum enum_i2s_controller id;
518 void __iomem *registers;
519 struct device *dev;
520 struct i2s_controller *i2s_cont;
521 struct stedma40_chan_cfg *dma_cfg_rx;
522 struct stedma40_chan_cfg *dma_cfg_tx;
523 struct dma_chan *tx_pipeid;
524 struct dma_chan *rx_pipeid;
525 enum msp_state msp_state;
526 int (*transfer) (struct ux500_msp *msp, struct i2s_message *message);
527 int (*plat_init) (void);
528 int (*plat_exit) (void);
529 struct timer_list notify_timer;
530 int def_elem_len;
531 unsigned int dir_busy;
532 int loopback_enable;
533 u32 backup_regs[MAX_MSP_BACKUP_REGS];
534 unsigned int f_bitclk;
535};
536
537struct ux500_msp_dma_params {
538 unsigned int data_size;
539 struct stedma40_chan_cfg *dma_cfg;
540};
541
542int ux500_msp_i2s_init_msp(struct platform_device *pdev,
543 struct ux500_msp **msp_p,
544 struct msp_i2s_platform_data *platform_data);
545void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
546 struct ux500_msp *msp);
547int ux500_msp_i2s_open(struct ux500_msp *msp, struct ux500_msp_config *config);
548int ux500_msp_i2s_close(struct ux500_msp *msp,
549 unsigned int dir);
550int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd,
551 int direction);
552
553#endif