aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2015-11-10 14:01:58 -0500
committerMark Brown <broonie@kernel.org>2015-11-10 14:01:58 -0500
commit2a148b6f2726ced30f796435f61d6e915c979784 (patch)
tree48d233fa5639677b16b10a3442029f3a2e40ef92 /sound
parent021c5d9469960b8c68aa1d1825f7bfd8d61e157d (diff)
parentbb9a13a0209c56cdf27d125a1f2f6f34378c64f4 (diff)
Merge tag 'asoc-v4.3-rc6' into asoc-fix-rcar
ASoC: Updates for v4.4 Not much core work here, a few small tweaks to interfaces but mainly the changes here are driver ones. Highlights include: - Updates to the topology userspace interface - Big updates to the Renesas support from Morimoto-san - Most of the support for Intel Sky Lake systems. - New drivers for Asahi Kasei Microdevices AK4613, Allwinnner A10, Cirrus Logic WM8998, Dialog DA7219, Nuvoton NAU8825 and Rockchip S/PDIF.
Diffstat (limited to 'sound')
-rw-r--r--sound/arm/Kconfig15
-rw-r--r--sound/arm/pxa2xx-ac97.c13
-rw-r--r--sound/arm/pxa2xx-pcm-lib.c201
-rw-r--r--sound/arm/pxa2xx-pcm.c12
-rw-r--r--sound/arm/pxa2xx-pcm.h2
-rw-r--r--sound/hda/ext/hdac_ext_bus.c1
-rw-r--r--sound/pci/hda/hda_codec.c4
-rw-r--r--sound/pci/hda/hda_tegra.c30
-rw-r--r--sound/pci/hda/patch_cirrus.c1
-rw-r--r--sound/pci/hda/patch_conexant.c1
-rw-r--r--sound/pci/hda/patch_realtek.c32
-rw-r--r--sound/pci/hda/patch_sigmatel.c6
-rw-r--r--sound/soc/Kconfig6
-rw-r--r--sound/soc/Makefile4
-rw-r--r--sound/soc/atmel/Kconfig9
-rw-r--r--sound/soc/atmel/Makefile2
-rw-r--r--sound/soc/atmel/atmel-classd.c679
-rw-r--r--sound/soc/atmel/atmel-classd.h120
-rw-r--r--sound/soc/atmel/atmel_wm8904.c1
-rw-r--r--sound/soc/au1x/db1000.c10
-rw-r--r--sound/soc/au1x/db1200.c14
-rw-r--r--sound/soc/au1x/psc-i2s.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c11
-rw-r--r--sound/soc/blackfin/bfin-eval-adau1373.c12
-rw-r--r--sound/soc/blackfin/bfin-eval-adau1701.c12
-rw-r--r--sound/soc/blackfin/bfin-eval-adav80x.c12
-rw-r--r--sound/soc/codecs/Kconfig23
-rw-r--r--sound/soc/codecs/Makefile10
-rw-r--r--sound/soc/codecs/ad193x-i2c.c8
-rw-r--r--sound/soc/codecs/ad193x-spi.c16
-rw-r--r--sound/soc/codecs/ad193x.c128
-rw-r--r--sound/soc/codecs/ad193x.h9
-rw-r--r--sound/soc/codecs/ak4613.c497
-rw-r--r--sound/soc/codecs/ak4642.c153
-rw-r--r--sound/soc/codecs/arizona.c49
-rw-r--r--sound/soc/codecs/arizona.h14
-rw-r--r--sound/soc/codecs/da7213.c190
-rw-r--r--sound/soc/codecs/da7213.h8
-rw-r--r--sound/soc/codecs/da7219-aad.c823
-rw-r--r--sound/soc/codecs/da7219-aad.h212
-rw-r--r--sound/soc/codecs/da7219.c1955
-rw-r--r--sound/soc/codecs/da7219.h820
-rw-r--r--sound/soc/codecs/es8328.c2
-rw-r--r--sound/soc/codecs/hdmi.c109
-rw-r--r--sound/soc/codecs/nau8825.c1309
-rw-r--r--sound/soc/codecs/nau8825.h341
-rw-r--r--sound/soc/codecs/rl6347a.c19
-rw-r--r--sound/soc/codecs/rl6347a.h2
-rw-r--r--sound/soc/codecs/rt286.c9
-rw-r--r--sound/soc/codecs/rt298.c37
-rw-r--r--sound/soc/codecs/rt5640.c22
-rw-r--r--sound/soc/codecs/rt5645.c200
-rw-r--r--sound/soc/codecs/rt5645.h46
-rw-r--r--sound/soc/codecs/sgtl5000.c6
-rw-r--r--sound/soc/codecs/ssm2518.c6
-rw-r--r--sound/soc/codecs/tas2552.c2
-rw-r--r--sound/soc/codecs/tlv320aic3x.c49
-rw-r--r--sound/soc/codecs/wm0010.c23
-rw-r--r--sound/soc/codecs/wm2000.c4
-rw-r--r--sound/soc/codecs/wm5110.c187
-rw-r--r--sound/soc/codecs/wm8731.c2
-rw-r--r--sound/soc/codecs/wm8903.c2
-rw-r--r--sound/soc/codecs/wm8904.c2
-rw-r--r--sound/soc/codecs/wm8955.c2
-rw-r--r--sound/soc/codecs/wm8960.c28
-rw-r--r--sound/soc/codecs/wm8962.c10
-rw-r--r--sound/soc/codecs/wm8998.c1430
-rw-r--r--sound/soc/codecs/wm8998.h23
-rw-r--r--sound/soc/davinci/davinci-mcasp.c319
-rw-r--r--sound/soc/dwc/designware_i2s.c142
-rw-r--r--sound/soc/fsl/fsl-asoc-card.c144
-rw-r--r--sound/soc/fsl/fsl_esai.c88
-rw-r--r--sound/soc/fsl/fsl_sai.c38
-rw-r--r--sound/soc/fsl/fsl_spdif.c73
-rw-r--r--sound/soc/fsl/fsl_ssi.c107
-rw-r--r--sound/soc/fsl/imx-spdif.c1
-rw-r--r--sound/soc/fsl/imx-ssi.c19
-rw-r--r--sound/soc/generic/simple-card.c8
-rw-r--r--sound/soc/intel/Kconfig15
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform-pcm.c19
-rw-r--r--sound/soc/intel/boards/Makefile2
-rw-r--r--sound/soc/intel/boards/broadwell.c9
-rw-r--r--sound/soc/intel/boards/skl_rt286.c259
-rw-r--r--sound/soc/intel/common/Makefile6
-rw-r--r--sound/soc/intel/common/sst-dsp-priv.h1
-rw-r--r--sound/soc/intel/common/sst-dsp.c2
-rw-r--r--sound/soc/intel/common/sst-dsp.h2
-rw-r--r--sound/soc/intel/common/sst-firmware.c10
-rw-r--r--sound/soc/intel/haswell/sst-haswell-ipc.c20
-rw-r--r--sound/soc/intel/skylake/Makefile3
-rw-r--r--sound/soc/intel/skylake/skl-messages.c44
-rw-r--r--sound/soc/intel/skylake/skl-nhlt.c10
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c176
-rw-r--r--sound/soc/intel/skylake/skl-sst-dsp.c7
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c12
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.h1
-rw-r--r--sound/soc/intel/skylake/skl-sst.c56
-rw-r--r--sound/soc/intel/skylake/skl-topology.c1252
-rw-r--r--sound/soc/intel/skylake/skl-topology.h36
-rw-r--r--sound/soc/intel/skylake/skl-tplg-interface.h83
-rw-r--r--sound/soc/intel/skylake/skl.c32
-rw-r--r--sound/soc/intel/skylake/skl.h17
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c1
-rw-r--r--sound/soc/kirkwood/armada-370-db.c1
-rw-r--r--sound/soc/mediatek/mt8173-max98090.c11
-rw-r--r--sound/soc/mediatek/mt8173-rt5650-rt5676.c11
-rw-r--r--sound/soc/mediatek/mtk-afe-pcm.c17
-rw-r--r--sound/soc/mxs/mxs-sgtl5000.c6
-rw-r--r--sound/soc/omap/rx51.c2
-rw-r--r--sound/soc/pxa/Kconfig2
-rw-r--r--sound/soc/pxa/brownstone.c9
-rw-r--r--sound/soc/pxa/corgi.c11
-rw-r--r--sound/soc/pxa/e740_wm9705.c5
-rw-r--r--sound/soc/pxa/e750_wm9705.c5
-rw-r--r--sound/soc/pxa/e800_wm9712.c5
-rw-r--r--sound/soc/pxa/hx4700.c4
-rw-r--r--sound/soc/pxa/imote2.c11
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c11
-rw-r--r--sound/soc/pxa/palm27x.c9
-rw-r--r--sound/soc/pxa/poodle.c11
-rw-r--r--sound/soc/pxa/pxa-ssp.c1
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c49
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c3
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c33
-rw-r--r--sound/soc/pxa/spitz.c5
-rw-r--r--sound/soc/pxa/tosa.c5
-rw-r--r--sound/soc/pxa/ttc-dkb.c12
-rw-r--r--sound/soc/qcom/lpass-cpu.c3
-rw-r--r--sound/soc/rockchip/Kconfig12
-rw-r--r--sound/soc/rockchip/Makefile6
-rw-r--r--sound/soc/rockchip/rockchip_i2s.c48
-rw-r--r--sound/soc/rockchip/rockchip_i2s.h16
-rw-r--r--sound/soc/rockchip/rockchip_spdif.c405
-rw-r--r--sound/soc/rockchip/rockchip_spdif.h63
-rw-r--r--sound/soc/samsung/h1940_uda1380.c5
-rw-r--r--sound/soc/samsung/rx1950_uda1380.c5
-rw-r--r--sound/soc/sh/Kconfig3
-rw-r--r--sound/soc/sh/rcar/adg.c306
-rw-r--r--sound/soc/sh/rcar/core.c66
-rw-r--r--sound/soc/sh/rcar/ctu.c16
-rw-r--r--sound/soc/sh/rcar/dma.c2
-rw-r--r--sound/soc/sh/rcar/dvc.c16
-rw-r--r--sound/soc/sh/rcar/gen.c14
-rw-r--r--sound/soc/sh/rcar/mix.c16
-rw-r--r--sound/soc/sh/rcar/rcar_snd.h117
-rw-r--r--sound/soc/sh/rcar/rsnd.h29
-rw-r--r--sound/soc/sh/rcar/src.c27
-rw-r--r--sound/soc/sh/rcar/ssi.c113
-rw-r--r--sound/soc/sh/siu_dai.c85
-rw-r--r--sound/soc/soc-compress.c12
-rw-r--r--sound/soc/soc-core.c29
-rw-r--r--sound/soc/soc-dapm.c61
-rw-r--r--sound/soc/soc-ops.c36
-rw-r--r--sound/soc/soc-pcm.c49
-rw-r--r--sound/soc/soc-topology.c4
-rw-r--r--sound/soc/soc-utils.c9
-rw-r--r--sound/soc/spear/Kconfig2
-rw-r--r--sound/soc/sti/uniperif_player.c14
-rw-r--r--sound/soc/sti/uniperif_reader.c6
-rw-r--r--sound/soc/sunxi/Kconfig11
-rw-r--r--sound/soc/sunxi/Makefile2
-rw-r--r--sound/soc/sunxi/sun4i-codec.c712
-rw-r--r--sound/soc/ux500/mop500.c1
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c1
-rw-r--r--sound/synth/emux/emux_oss.c3
165 files changed, 14087 insertions, 1489 deletions
diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig
index 885683a3b0bd..e0406211716b 100644
--- a/sound/arm/Kconfig
+++ b/sound/arm/Kconfig
@@ -9,6 +9,14 @@ menuconfig SND_ARM
9 Drivers that are implemented on ASoC can be found in 9 Drivers that are implemented on ASoC can be found in
10 "ALSA for SoC audio support" section. 10 "ALSA for SoC audio support" section.
11 11
12config SND_PXA2XX_LIB
13 tristate
14 select SND_AC97_CODEC if SND_PXA2XX_LIB_AC97
15 select SND_DMAENGINE_PCM
16
17config SND_PXA2XX_LIB_AC97
18 bool
19
12if SND_ARM 20if SND_ARM
13 21
14config SND_ARMAACI 22config SND_ARMAACI
@@ -21,13 +29,6 @@ config SND_PXA2XX_PCM
21 tristate 29 tristate
22 select SND_PCM 30 select SND_PCM
23 31
24config SND_PXA2XX_LIB
25 tristate
26 select SND_AC97_CODEC if SND_PXA2XX_LIB_AC97
27
28config SND_PXA2XX_LIB_AC97
29 bool
30
31config SND_PXA2XX_AC97 32config SND_PXA2XX_AC97
32 tristate "AC97 driver for the Intel PXA2xx chip" 33 tristate "AC97 driver for the Intel PXA2xx chip"
33 depends on ARCH_PXA 34 depends on ARCH_PXA
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index 38590b322c54..fbd5dad0c484 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/dmaengine.h> 17#include <linux/dmaengine.h>
18#include <linux/dma/pxa-dma.h>
18 19
19#include <sound/core.h> 20#include <sound/core.h>
20#include <sound/pcm.h> 21#include <sound/pcm.h>
@@ -43,7 +44,11 @@ static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
43 .reset = pxa2xx_ac97_reset, 44 .reset = pxa2xx_ac97_reset,
44}; 45};
45 46
46static unsigned long pxa2xx_ac97_pcm_out_req = 12; 47static struct pxad_param pxa2xx_ac97_pcm_out_req = {
48 .prio = PXAD_PRIO_LOWEST,
49 .drcmr = 12,
50};
51
47static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_out = { 52static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_out = {
48 .addr = __PREG(PCDR), 53 .addr = __PREG(PCDR),
49 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 54 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
@@ -51,7 +56,11 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_out = {
51 .filter_data = &pxa2xx_ac97_pcm_out_req, 56 .filter_data = &pxa2xx_ac97_pcm_out_req,
52}; 57};
53 58
54static unsigned long pxa2xx_ac97_pcm_in_req = 11; 59static struct pxad_param pxa2xx_ac97_pcm_in_req = {
60 .prio = PXAD_PRIO_LOWEST,
61 .drcmr = 11,
62};
63
55static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_in = { 64static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_in = {
56 .addr = __PREG(PCDR), 65 .addr = __PREG(PCDR),
57 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 66 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c
index 01f8fdc42b1b..e9b98af6b52c 100644
--- a/sound/arm/pxa2xx-pcm-lib.c
+++ b/sound/arm/pxa2xx-pcm-lib.c
@@ -8,6 +8,7 @@
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/dma-mapping.h> 9#include <linux/dma-mapping.h>
10#include <linux/dmaengine.h> 10#include <linux/dmaengine.h>
11#include <linux/dma/pxa-dma.h>
11 12
12#include <sound/core.h> 13#include <sound/core.h>
13#include <sound/pcm.h> 14#include <sound/pcm.h>
@@ -15,8 +16,6 @@
15#include <sound/pxa2xx-lib.h> 16#include <sound/pxa2xx-lib.h>
16#include <sound/dmaengine_pcm.h> 17#include <sound/dmaengine_pcm.h>
17 18
18#include <mach/dma.h>
19
20#include "pxa2xx-pcm.h" 19#include "pxa2xx-pcm.h"
21 20
22static const struct snd_pcm_hardware pxa2xx_pcm_hardware = { 21static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
@@ -31,7 +30,7 @@ static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
31 .period_bytes_min = 32, 30 .period_bytes_min = 32,
32 .period_bytes_max = 8192 - 32, 31 .period_bytes_max = 8192 - 32,
33 .periods_min = 1, 32 .periods_min = 1,
34 .periods_max = PAGE_SIZE/sizeof(pxa_dma_desc), 33 .periods_max = 256,
35 .buffer_bytes_max = 128 * 1024, 34 .buffer_bytes_max = 128 * 1024,
36 .fifo_size = 32, 35 .fifo_size = 32,
37}; 36};
@@ -39,65 +38,29 @@ static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
39int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, 38int __pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
40 struct snd_pcm_hw_params *params) 39 struct snd_pcm_hw_params *params)
41{ 40{
42 struct snd_pcm_runtime *runtime = substream->runtime; 41 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
43 struct pxa2xx_runtime_data *rtd = runtime->private_data; 42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
44 size_t totsize = params_buffer_bytes(params); 43 struct snd_dmaengine_dai_dma_data *dma_params;
45 size_t period = params_period_bytes(params); 44 struct dma_slave_config config;
46 pxa_dma_desc *dma_desc; 45 int ret;
47 dma_addr_t dma_buff_phys, next_desc_phys;
48 u32 dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG;
49 46
50 /* temporary transition hack */ 47 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
51 switch (rtd->params->addr_width) { 48 if (!dma_params)
52 case DMA_SLAVE_BUSWIDTH_1_BYTE: 49 return 0;
53 dcmd |= DCMD_WIDTH1;
54 break;
55 case DMA_SLAVE_BUSWIDTH_2_BYTES:
56 dcmd |= DCMD_WIDTH2;
57 break;
58 case DMA_SLAVE_BUSWIDTH_4_BYTES:
59 dcmd |= DCMD_WIDTH4;
60 break;
61 default:
62 /* can't happen */
63 break;
64 }
65 50
66 switch (rtd->params->maxburst) { 51 ret = snd_hwparams_to_dma_slave_config(substream, params, &config);
67 case 8: 52 if (ret)
68 dcmd |= DCMD_BURST8; 53 return ret;
69 break;
70 case 16:
71 dcmd |= DCMD_BURST16;
72 break;
73 case 32:
74 dcmd |= DCMD_BURST32;
75 break;
76 }
77 54
78 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 55 snd_dmaengine_pcm_set_config_from_dai_data(substream,
79 runtime->dma_bytes = totsize; 56 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream),
57 &config);
80 58
81 dma_desc = rtd->dma_desc_array; 59 ret = dmaengine_slave_config(chan, &config);
82 next_desc_phys = rtd->dma_desc_array_phys; 60 if (ret)
83 dma_buff_phys = runtime->dma_addr; 61 return ret;
84 do { 62
85 next_desc_phys += sizeof(pxa_dma_desc); 63 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
86 dma_desc->ddadr = next_desc_phys;
87 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
88 dma_desc->dsadr = dma_buff_phys;
89 dma_desc->dtadr = rtd->params->addr;
90 } else {
91 dma_desc->dsadr = rtd->params->addr;
92 dma_desc->dtadr = dma_buff_phys;
93 }
94 if (period > totsize)
95 period = totsize;
96 dma_desc->dcmd = dcmd | period | DCMD_ENDIRQEN;
97 dma_desc++;
98 dma_buff_phys += period;
99 } while (totsize -= period);
100 dma_desc[-1].ddadr = rtd->dma_desc_array_phys;
101 64
102 return 0; 65 return 0;
103} 66}
@@ -105,13 +68,6 @@ EXPORT_SYMBOL(__pxa2xx_pcm_hw_params);
105 68
106int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) 69int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
107{ 70{
108 struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
109
110 if (rtd && rtd->params && rtd->params->filter_data) {
111 unsigned long req = *(unsigned long *) rtd->params->filter_data;
112 DRCMR(req) = 0;
113 }
114
115 snd_pcm_set_runtime_buffer(substream, NULL); 71 snd_pcm_set_runtime_buffer(substream, NULL);
116 return 0; 72 return 0;
117} 73}
@@ -119,100 +75,36 @@ EXPORT_SYMBOL(__pxa2xx_pcm_hw_free);
119 75
120int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 76int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
121{ 77{
122 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; 78 return snd_dmaengine_pcm_trigger(substream, cmd);
123 int ret = 0;
124
125 switch (cmd) {
126 case SNDRV_PCM_TRIGGER_START:
127 DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
128 DCSR(prtd->dma_ch) = DCSR_RUN;
129 break;
130
131 case SNDRV_PCM_TRIGGER_STOP:
132 case SNDRV_PCM_TRIGGER_SUSPEND:
133 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
134 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
135 break;
136
137 case SNDRV_PCM_TRIGGER_RESUME:
138 DCSR(prtd->dma_ch) |= DCSR_RUN;
139 break;
140 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
141 DDADR(prtd->dma_ch) = prtd->dma_desc_array_phys;
142 DCSR(prtd->dma_ch) |= DCSR_RUN;
143 break;
144
145 default:
146 ret = -EINVAL;
147 }
148
149 return ret;
150} 79}
151EXPORT_SYMBOL(pxa2xx_pcm_trigger); 80EXPORT_SYMBOL(pxa2xx_pcm_trigger);
152 81
153snd_pcm_uframes_t 82snd_pcm_uframes_t
154pxa2xx_pcm_pointer(struct snd_pcm_substream *substream) 83pxa2xx_pcm_pointer(struct snd_pcm_substream *substream)
155{ 84{
156 struct snd_pcm_runtime *runtime = substream->runtime; 85 return snd_dmaengine_pcm_pointer(substream);
157 struct pxa2xx_runtime_data *prtd = runtime->private_data;
158
159 dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
160 DSADR(prtd->dma_ch) : DTADR(prtd->dma_ch);
161 snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr);
162
163 if (x == runtime->buffer_size)
164 x = 0;
165 return x;
166} 86}
167EXPORT_SYMBOL(pxa2xx_pcm_pointer); 87EXPORT_SYMBOL(pxa2xx_pcm_pointer);
168 88
169int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream) 89int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
170{ 90{
171 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
172 unsigned long req;
173
174 if (!prtd || !prtd->params)
175 return 0;
176
177 if (prtd->dma_ch == -1)
178 return -EINVAL;
179
180 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
181 DCSR(prtd->dma_ch) = 0;
182 DCMD(prtd->dma_ch) = 0;
183 req = *(unsigned long *) prtd->params->filter_data;
184 DRCMR(req) = prtd->dma_ch | DRCMR_MAPVLD;
185
186 return 0; 91 return 0;
187} 92}
188EXPORT_SYMBOL(__pxa2xx_pcm_prepare); 93EXPORT_SYMBOL(__pxa2xx_pcm_prepare);
189 94
190void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
191{
192 struct snd_pcm_substream *substream = dev_id;
193 int dcsr;
194
195 dcsr = DCSR(dma_ch);
196 DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN;
197
198 if (dcsr & DCSR_ENDINTR) {
199 snd_pcm_period_elapsed(substream);
200 } else {
201 printk(KERN_ERR "DMA error on channel %d (DCSR=%#x)\n",
202 dma_ch, dcsr);
203 snd_pcm_stop_xrun(substream);
204 }
205}
206EXPORT_SYMBOL(pxa2xx_pcm_dma_irq);
207
208int __pxa2xx_pcm_open(struct snd_pcm_substream *substream) 95int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
209{ 96{
97 struct snd_soc_pcm_runtime *rtd = substream->private_data;
210 struct snd_pcm_runtime *runtime = substream->runtime; 98 struct snd_pcm_runtime *runtime = substream->runtime;
211 struct pxa2xx_runtime_data *rtd; 99 struct snd_dmaengine_dai_dma_data *dma_params;
212 int ret; 100 int ret;
213 101
214 runtime->hw = pxa2xx_pcm_hardware; 102 runtime->hw = pxa2xx_pcm_hardware;
215 103
104 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
105 if (!dma_params)
106 return 0;
107
216 /* 108 /*
217 * For mysterious reasons (and despite what the manual says) 109 * For mysterious reasons (and despite what the manual says)
218 * playback samples are lost if the DMA count is not a multiple 110 * playback samples are lost if the DMA count is not a multiple
@@ -221,48 +113,27 @@ int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
221 ret = snd_pcm_hw_constraint_step(runtime, 0, 113 ret = snd_pcm_hw_constraint_step(runtime, 0,
222 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); 114 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
223 if (ret) 115 if (ret)
224 goto out; 116 return ret;
225 117
226 ret = snd_pcm_hw_constraint_step(runtime, 0, 118 ret = snd_pcm_hw_constraint_step(runtime, 0,
227 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32); 119 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
228 if (ret) 120 if (ret)
229 goto out; 121 return ret;
230 122
231 ret = snd_pcm_hw_constraint_integer(runtime, 123 ret = snd_pcm_hw_constraint_integer(runtime,
232 SNDRV_PCM_HW_PARAM_PERIODS); 124 SNDRV_PCM_HW_PARAM_PERIODS);
233 if (ret < 0) 125 if (ret < 0)
234 goto out; 126 return ret;
235
236 ret = -ENOMEM;
237 rtd = kzalloc(sizeof(*rtd), GFP_KERNEL);
238 if (!rtd)
239 goto out;
240 rtd->dma_desc_array =
241 dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE,
242 &rtd->dma_desc_array_phys, GFP_KERNEL);
243 if (!rtd->dma_desc_array)
244 goto err1;
245 127
246 rtd->dma_ch = -1; 128 return snd_dmaengine_pcm_open_request_chan(substream,
247 runtime->private_data = rtd; 129 pxad_filter_fn,
248 return 0; 130 dma_params->filter_data);
249
250 err1:
251 kfree(rtd);
252 out:
253 return ret;
254} 131}
255EXPORT_SYMBOL(__pxa2xx_pcm_open); 132EXPORT_SYMBOL(__pxa2xx_pcm_open);
256 133
257int __pxa2xx_pcm_close(struct snd_pcm_substream *substream) 134int __pxa2xx_pcm_close(struct snd_pcm_substream *substream)
258{ 135{
259 struct snd_pcm_runtime *runtime = substream->runtime; 136 return snd_dmaengine_pcm_close_release_chan(substream);
260 struct pxa2xx_runtime_data *rtd = runtime->private_data;
261
262 dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE,
263 rtd->dma_desc_array, rtd->dma_desc_array_phys);
264 kfree(rtd);
265 return 0;
266} 137}
267EXPORT_SYMBOL(__pxa2xx_pcm_close); 138EXPORT_SYMBOL(__pxa2xx_pcm_close);
268 139
diff --git a/sound/arm/pxa2xx-pcm.c b/sound/arm/pxa2xx-pcm.c
index 83be8e3f095e..83fcfac97739 100644
--- a/sound/arm/pxa2xx-pcm.c
+++ b/sound/arm/pxa2xx-pcm.c
@@ -46,17 +46,13 @@ static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
46 46
47 rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 47 rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
48 client->playback_params : client->capture_params; 48 client->playback_params : client->capture_params;
49 ret = pxa_request_dma("dma", DMA_PRIO_LOW,
50 pxa2xx_pcm_dma_irq, substream);
51 if (ret < 0)
52 goto err2;
53 rtd->dma_ch = ret;
54 49
55 ret = client->startup(substream); 50 ret = client->startup(substream);
56 if (!ret) 51 if (!ret)
57 goto out; 52 goto err2;
53
54 return 0;
58 55
59 pxa_free_dma(rtd->dma_ch);
60 err2: 56 err2:
61 __pxa2xx_pcm_close(substream); 57 __pxa2xx_pcm_close(substream);
62 out: 58 out:
@@ -66,9 +62,7 @@ static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
66static int pxa2xx_pcm_close(struct snd_pcm_substream *substream) 62static int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
67{ 63{
68 struct pxa2xx_pcm_client *client = substream->private_data; 64 struct pxa2xx_pcm_client *client = substream->private_data;
69 struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
70 65
71 pxa_free_dma(rtd->dma_ch);
72 client->shutdown(substream); 66 client->shutdown(substream);
73 67
74 return __pxa2xx_pcm_close(substream); 68 return __pxa2xx_pcm_close(substream);
diff --git a/sound/arm/pxa2xx-pcm.h b/sound/arm/pxa2xx-pcm.h
index 00330985beec..8fa2b7c9e6b8 100644
--- a/sound/arm/pxa2xx-pcm.h
+++ b/sound/arm/pxa2xx-pcm.h
@@ -13,8 +13,6 @@
13struct pxa2xx_runtime_data { 13struct pxa2xx_runtime_data {
14 int dma_ch; 14 int dma_ch;
15 struct snd_dmaengine_dai_dma_data *params; 15 struct snd_dmaengine_dai_dma_data *params;
16 struct pxa_dma_desc *dma_desc_array;
17 dma_addr_t dma_desc_array_phys;
18}; 16};
19 17
20struct pxa2xx_pcm_client { 18struct pxa2xx_pcm_client {
diff --git a/sound/hda/ext/hdac_ext_bus.c b/sound/hda/ext/hdac_ext_bus.c
index 4449d1a99089..2433f7c81472 100644
--- a/sound/hda/ext/hdac_ext_bus.c
+++ b/sound/hda/ext/hdac_ext_bus.c
@@ -19,6 +19,7 @@
19 19
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/io.h>
22#include <sound/hdaudio_ext.h> 23#include <sound/hdaudio_ext.h>
23 24
24MODULE_DESCRIPTION("HDA extended core"); 25MODULE_DESCRIPTION("HDA extended core");
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 37f43a1b34ef..a249d5486889 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -3367,10 +3367,8 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
3367 int dev, err; 3367 int dev, err;
3368 3368
3369 err = snd_hda_codec_parse_pcms(codec); 3369 err = snd_hda_codec_parse_pcms(codec);
3370 if (err < 0) { 3370 if (err < 0)
3371 snd_hda_codec_reset(codec);
3372 return err; 3371 return err;
3373 }
3374 3372
3375 /* attach a new PCM streams */ 3373 /* attach a new PCM streams */
3376 list_for_each_entry(cpcm, &codec->pcm_list_head, list) { 3374 list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c
index 477742cb70a2..58c0aad37284 100644
--- a/sound/pci/hda/hda_tegra.c
+++ b/sound/pci/hda/hda_tegra.c
@@ -73,6 +73,7 @@ struct hda_tegra {
73 struct clk *hda2codec_2x_clk; 73 struct clk *hda2codec_2x_clk;
74 struct clk *hda2hdmi_clk; 74 struct clk *hda2hdmi_clk;
75 void __iomem *regs; 75 void __iomem *regs;
76 struct work_struct probe_work;
76}; 77};
77 78
78#ifdef CONFIG_PM 79#ifdef CONFIG_PM
@@ -294,7 +295,9 @@ static int hda_tegra_dev_disconnect(struct snd_device *device)
294static int hda_tegra_dev_free(struct snd_device *device) 295static int hda_tegra_dev_free(struct snd_device *device)
295{ 296{
296 struct azx *chip = device->device_data; 297 struct azx *chip = device->device_data;
298 struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip);
297 299
300 cancel_work_sync(&hda->probe_work);
298 if (azx_bus(chip)->chip_init) { 301 if (azx_bus(chip)->chip_init) {
299 azx_stop_all_streams(chip); 302 azx_stop_all_streams(chip);
300 azx_stop_chip(chip); 303 azx_stop_chip(chip);
@@ -426,6 +429,9 @@ static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev)
426/* 429/*
427 * constructor 430 * constructor
428 */ 431 */
432
433static void hda_tegra_probe_work(struct work_struct *work);
434
429static int hda_tegra_create(struct snd_card *card, 435static int hda_tegra_create(struct snd_card *card,
430 unsigned int driver_caps, 436 unsigned int driver_caps,
431 struct hda_tegra *hda) 437 struct hda_tegra *hda)
@@ -452,6 +458,8 @@ static int hda_tegra_create(struct snd_card *card,
452 chip->single_cmd = false; 458 chip->single_cmd = false;
453 chip->snoop = true; 459 chip->snoop = true;
454 460
461 INIT_WORK(&hda->probe_work, hda_tegra_probe_work);
462
455 err = azx_bus_init(chip, NULL, &hda_tegra_io_ops); 463 err = azx_bus_init(chip, NULL, &hda_tegra_io_ops);
456 if (err < 0) 464 if (err < 0)
457 return err; 465 return err;
@@ -499,6 +507,21 @@ static int hda_tegra_probe(struct platform_device *pdev)
499 card->private_data = chip; 507 card->private_data = chip;
500 508
501 dev_set_drvdata(&pdev->dev, card); 509 dev_set_drvdata(&pdev->dev, card);
510 schedule_work(&hda->probe_work);
511
512 return 0;
513
514out_free:
515 snd_card_free(card);
516 return err;
517}
518
519static void hda_tegra_probe_work(struct work_struct *work)
520{
521 struct hda_tegra *hda = container_of(work, struct hda_tegra, probe_work);
522 struct azx *chip = &hda->chip;
523 struct platform_device *pdev = to_platform_device(hda->dev);
524 int err;
502 525
503 err = hda_tegra_first_init(chip, pdev); 526 err = hda_tegra_first_init(chip, pdev);
504 if (err < 0) 527 if (err < 0)
@@ -520,11 +543,8 @@ static int hda_tegra_probe(struct platform_device *pdev)
520 chip->running = 1; 543 chip->running = 1;
521 snd_hda_set_power_save(&chip->bus, power_save * 1000); 544 snd_hda_set_power_save(&chip->bus, power_save * 1000);
522 545
523 return 0; 546 out_free:
524 547 return; /* no error return from async probe */
525out_free:
526 snd_card_free(card);
527 return err;
528} 548}
529 549
530static int hda_tegra_remove(struct platform_device *pdev) 550static int hda_tegra_remove(struct platform_device *pdev)
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 584a0343ab0c..85813de26da8 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -633,6 +633,7 @@ static const struct snd_pci_quirk cs4208_mac_fixup_tbl[] = {
633 SND_PCI_QUIRK(0x106b, 0x5e00, "MacBookPro 11,2", CS4208_MBP11), 633 SND_PCI_QUIRK(0x106b, 0x5e00, "MacBookPro 11,2", CS4208_MBP11),
634 SND_PCI_QUIRK(0x106b, 0x7100, "MacBookAir 6,1", CS4208_MBA6), 634 SND_PCI_QUIRK(0x106b, 0x7100, "MacBookAir 6,1", CS4208_MBA6),
635 SND_PCI_QUIRK(0x106b, 0x7200, "MacBookAir 6,2", CS4208_MBA6), 635 SND_PCI_QUIRK(0x106b, 0x7200, "MacBookAir 6,2", CS4208_MBA6),
636 SND_PCI_QUIRK(0x106b, 0x7b00, "MacBookPro 12,1", CS4208_MBP11),
636 {} /* terminator */ 637 {} /* terminator */
637}; 638};
638 639
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index ca03c40609fc..2f0ec7c45fc7 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -819,6 +819,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
819 SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT_PINCFG_LENOVO_TP410), 819 SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT_PINCFG_LENOVO_TP410),
820 SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT_PINCFG_LENOVO_TP410), 820 SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT_PINCFG_LENOVO_TP410),
821 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo IdeaPad Z560", CXT_FIXUP_MUTE_LED_EAPD), 821 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo IdeaPad Z560", CXT_FIXUP_MUTE_LED_EAPD),
822 SND_PCI_QUIRK(0x17aa, 0x390b, "Lenovo G50-80", CXT_FIXUP_STEREO_DMIC),
822 SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), 823 SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
823 SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC), 824 SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
824 SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC), 825 SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index a75b5611d1e4..16b8dcba5c12 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4188,6 +4188,24 @@ static void alc_fixup_disable_aamix(struct hda_codec *codec,
4188 } 4188 }
4189} 4189}
4190 4190
4191/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
4192static void alc_fixup_tpt440_dock(struct hda_codec *codec,
4193 const struct hda_fixup *fix, int action)
4194{
4195 static const struct hda_pintbl pincfgs[] = {
4196 { 0x16, 0x21211010 }, /* dock headphone */
4197 { 0x19, 0x21a11010 }, /* dock mic */
4198 { }
4199 };
4200 struct alc_spec *spec = codec->spec;
4201
4202 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4203 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
4204 codec->power_save_node = 0; /* avoid click noises */
4205 snd_hda_apply_pincfgs(codec, pincfgs);
4206 }
4207}
4208
4191static void alc_shutup_dell_xps13(struct hda_codec *codec) 4209static void alc_shutup_dell_xps13(struct hda_codec *codec)
4192{ 4210{
4193 struct alc_spec *spec = codec->spec; 4211 struct alc_spec *spec = codec->spec;
@@ -4562,7 +4580,6 @@ enum {
4562 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC, 4580 ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
4563 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, 4581 ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
4564 ALC292_FIXUP_TPT440_DOCK, 4582 ALC292_FIXUP_TPT440_DOCK,
4565 ALC292_FIXUP_TPT440_DOCK2,
4566 ALC283_FIXUP_BXBT2807_MIC, 4583 ALC283_FIXUP_BXBT2807_MIC,
4567 ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED, 4584 ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
4568 ALC282_FIXUP_ASPIRE_V5_PINS, 4585 ALC282_FIXUP_ASPIRE_V5_PINS,
@@ -5029,17 +5046,7 @@ static const struct hda_fixup alc269_fixups[] = {
5029 }, 5046 },
5030 [ALC292_FIXUP_TPT440_DOCK] = { 5047 [ALC292_FIXUP_TPT440_DOCK] = {
5031 .type = HDA_FIXUP_FUNC, 5048 .type = HDA_FIXUP_FUNC,
5032 .v.func = alc269_fixup_pincfg_no_hp_to_lineout, 5049 .v.func = alc_fixup_tpt440_dock,
5033 .chained = true,
5034 .chain_id = ALC292_FIXUP_TPT440_DOCK2
5035 },
5036 [ALC292_FIXUP_TPT440_DOCK2] = {
5037 .type = HDA_FIXUP_PINS,
5038 .v.pins = (const struct hda_pintbl[]) {
5039 { 0x16, 0x21211010 }, /* dock headphone */
5040 { 0x19, 0x21a11010 }, /* dock mic */
5041 { }
5042 },
5043 .chained = true, 5050 .chained = true,
5044 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST 5051 .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
5045 }, 5052 },
@@ -5299,6 +5306,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5299 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK), 5306 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
5300 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK), 5307 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
5301 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5308 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5309 SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
5302 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK), 5310 SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
5303 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), 5311 SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
5304 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), 5312 SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 9d947aef2c8b..def5cc8dff02 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -4520,7 +4520,11 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
4520 return err; 4520 return err;
4521 4521
4522 spec = codec->spec; 4522 spec = codec->spec;
4523 codec->power_save_node = 1; 4523 /* enable power_save_node only for new 92HD89xx chips, as it causes
4524 * click noises on old 92HD73xx chips.
4525 */
4526 if ((codec->core.vendor_id & 0xfffffff0) != 0x111d7670)
4527 codec->power_save_node = 1;
4524 spec->linear_tone_beep = 0; 4528 spec->linear_tone_beep = 0;
4525 spec->gen.mixer_nid = 0x1d; 4529 spec->gen.mixer_nid = 0x1d;
4526 spec->have_spdif_mux = 1; 4530 spec->have_spdif_mux = 1;
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 225bfda414e9..7ff7d88e46dd 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -9,7 +9,6 @@ menuconfig SND_SOC
9 select SND_JACK if INPUT=y || INPUT=SND 9 select SND_JACK if INPUT=y || INPUT=SND
10 select REGMAP_I2C if I2C 10 select REGMAP_I2C if I2C
11 select REGMAP_SPI if SPI_MASTER 11 select REGMAP_SPI if SPI_MASTER
12 select SND_COMPRESS_OFFLOAD
13 ---help--- 12 ---help---
14 13
15 If you want ASoC support, you should say Y here and also to the 14 If you want ASoC support, you should say Y here and also to the
@@ -30,6 +29,10 @@ config SND_SOC_GENERIC_DMAENGINE_PCM
30 bool 29 bool
31 select SND_DMAENGINE_PCM 30 select SND_DMAENGINE_PCM
32 31
32config SND_SOC_COMPRESS
33 bool
34 select SND_COMPRESS_OFFLOAD
35
33config SND_SOC_TOPOLOGY 36config SND_SOC_TOPOLOGY
34 bool 37 bool
35 38
@@ -58,6 +61,7 @@ source "sound/soc/sh/Kconfig"
58source "sound/soc/sirf/Kconfig" 61source "sound/soc/sirf/Kconfig"
59source "sound/soc/spear/Kconfig" 62source "sound/soc/spear/Kconfig"
60source "sound/soc/sti/Kconfig" 63source "sound/soc/sti/Kconfig"
64source "sound/soc/sunxi/Kconfig"
61source "sound/soc/tegra/Kconfig" 65source "sound/soc/tegra/Kconfig"
62source "sound/soc/txx9/Kconfig" 66source "sound/soc/txx9/Kconfig"
63source "sound/soc/ux500/Kconfig" 67source "sound/soc/ux500/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 134aca150a50..8eb06db32fa0 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,5 +1,6 @@
1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o 1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
2snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o soc-devres.o soc-ops.o 2snd-soc-core-objs += soc-pcm.o soc-io.o soc-devres.o soc-ops.o
3snd-soc-core-$(CONFIG_SND_SOC_COMPRESS) += soc-compress.o
3 4
4ifneq ($(CONFIG_SND_SOC_TOPOLOGY),) 5ifneq ($(CONFIG_SND_SOC_TOPOLOGY),)
5snd-soc-core-objs += soc-topology.o 6snd-soc-core-objs += soc-topology.o
@@ -40,6 +41,7 @@ obj-$(CONFIG_SND_SOC) += sh/
40obj-$(CONFIG_SND_SOC) += sirf/ 41obj-$(CONFIG_SND_SOC) += sirf/
41obj-$(CONFIG_SND_SOC) += spear/ 42obj-$(CONFIG_SND_SOC) += spear/
42obj-$(CONFIG_SND_SOC) += sti/ 43obj-$(CONFIG_SND_SOC) += sti/
44obj-$(CONFIG_SND_SOC) += sunxi/
43obj-$(CONFIG_SND_SOC) += tegra/ 45obj-$(CONFIG_SND_SOC) += tegra/
44obj-$(CONFIG_SND_SOC) += txx9/ 46obj-$(CONFIG_SND_SOC) += txx9/
45obj-$(CONFIG_SND_SOC) += ux500/ 47obj-$(CONFIG_SND_SOC) += ux500/
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index 1489cd461aec..2d30464b81ce 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -59,4 +59,13 @@ config SND_AT91_SOC_SAM9X5_WM8731
59 help 59 help
60 Say Y if you want to add support for audio SoC on an 60 Say Y if you want to add support for audio SoC on an
61 at91sam9x5 based board that is using WM8731 codec. 61 at91sam9x5 based board that is using WM8731 codec.
62
63config SND_ATMEL_SOC_CLASSD
64 tristate "Atmel ASoC driver for boards using CLASSD"
65 depends on ARCH_AT91 || COMPILE_TEST
66 select SND_ATMEL_SOC_DMA
67 select REGMAP_MMIO
68 help
69 Say Y if you want to add support for Atmel ASoC driver for boards using
70 CLASSD.
62endif 71endif
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
index b327e5cc8de3..f6f7db428216 100644
--- a/sound/soc/atmel/Makefile
+++ b/sound/soc/atmel/Makefile
@@ -11,7 +11,9 @@ obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
11snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o 11snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o
12snd-atmel-soc-wm8904-objs := atmel_wm8904.o 12snd-atmel-soc-wm8904-objs := atmel_wm8904.o
13snd-soc-sam9x5-wm8731-objs := sam9x5_wm8731.o 13snd-soc-sam9x5-wm8731-objs := sam9x5_wm8731.o
14snd-atmel-soc-classd-objs := atmel-classd.o
14 15
15obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o 16obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o
16obj-$(CONFIG_SND_ATMEL_SOC_WM8904) += snd-atmel-soc-wm8904.o 17obj-$(CONFIG_SND_ATMEL_SOC_WM8904) += snd-atmel-soc-wm8904.o
17obj-$(CONFIG_SND_AT91_SOC_SAM9X5_WM8731) += snd-soc-sam9x5-wm8731.o 18obj-$(CONFIG_SND_AT91_SOC_SAM9X5_WM8731) += snd-soc-sam9x5-wm8731.o
19obj-$(CONFIG_SND_ATMEL_SOC_CLASSD) += snd-atmel-soc-classd.o
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c
new file mode 100644
index 000000000000..8276675730ef
--- /dev/null
+++ b/sound/soc/atmel/atmel-classd.c
@@ -0,0 +1,679 @@
1/* Atmel ALSA SoC Audio Class D Amplifier (CLASSD) driver
2 *
3 * Copyright (C) 2015 Atmel
4 *
5 * Author: Songjun Wu <songjun.wu@atmel.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 or later
9 * as published by the Free Software Foundation.
10 */
11
12#include <linux/of.h>
13#include <linux/clk.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/regmap.h>
17#include <sound/core.h>
18#include <sound/dmaengine_pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/tlv.h>
21#include "atmel-classd.h"
22
23struct atmel_classd_pdata {
24 bool non_overlap_enable;
25 int non_overlap_time;
26 int pwm_type;
27 const char *card_name;
28};
29
30struct atmel_classd {
31 dma_addr_t phy_base;
32 struct regmap *regmap;
33 struct clk *pclk;
34 struct clk *gclk;
35 struct clk *aclk;
36 int irq;
37 const struct atmel_classd_pdata *pdata;
38};
39
40#ifdef CONFIG_OF
41static const struct of_device_id atmel_classd_of_match[] = {
42 {
43 .compatible = "atmel,sama5d2-classd",
44 }, {
45 /* sentinel */
46 }
47};
48MODULE_DEVICE_TABLE(of, atmel_classd_of_match);
49
50static struct atmel_classd_pdata *atmel_classd_dt_init(struct device *dev)
51{
52 struct device_node *np = dev->of_node;
53 struct atmel_classd_pdata *pdata;
54 const char *pwm_type;
55 int ret;
56
57 if (!np) {
58 dev_err(dev, "device node not found\n");
59 return ERR_PTR(-EINVAL);
60 }
61
62 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
63 if (!pdata)
64 return ERR_PTR(-ENOMEM);
65
66 ret = of_property_read_string(np, "atmel,pwm-type", &pwm_type);
67 if ((ret == 0) && (strcmp(pwm_type, "diff") == 0))
68 pdata->pwm_type = CLASSD_MR_PWMTYP_DIFF;
69 else
70 pdata->pwm_type = CLASSD_MR_PWMTYP_SINGLE;
71
72 ret = of_property_read_u32(np,
73 "atmel,non-overlap-time", &pdata->non_overlap_time);
74 if (ret)
75 pdata->non_overlap_enable = false;
76 else
77 pdata->non_overlap_enable = true;
78
79 ret = of_property_read_string(np, "atmel,model", &pdata->card_name);
80 if (ret)
81 pdata->card_name = "CLASSD";
82
83 return pdata;
84}
85#else
86static inline struct atmel_classd_pdata *
87atmel_classd_dt_init(struct device *dev)
88{
89 return ERR_PTR(-EINVAL);
90}
91#endif
92
93#define ATMEL_CLASSD_RATES (SNDRV_PCM_RATE_8000 \
94 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 \
95 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 \
96 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 \
97 | SNDRV_PCM_RATE_96000)
98
99static const struct snd_pcm_hardware atmel_classd_hw = {
100 .info = SNDRV_PCM_INFO_MMAP
101 | SNDRV_PCM_INFO_MMAP_VALID
102 | SNDRV_PCM_INFO_INTERLEAVED
103 | SNDRV_PCM_INFO_RESUME
104 | SNDRV_PCM_INFO_PAUSE,
105 .formats = (SNDRV_PCM_FMTBIT_S16_LE),
106 .rates = ATMEL_CLASSD_RATES,
107 .rate_min = 8000,
108 .rate_max = 96000,
109 .channels_min = 2,
110 .channels_max = 2,
111 .buffer_bytes_max = 64 * 1024,
112 .period_bytes_min = 256,
113 .period_bytes_max = 32 * 1024,
114 .periods_min = 2,
115 .periods_max = 256,
116};
117
118#define ATMEL_CLASSD_PREALLOC_BUF_SIZE (64 * 1024)
119
120/* cpu dai component */
121static int atmel_classd_cpu_dai_startup(struct snd_pcm_substream *substream,
122 struct snd_soc_dai *cpu_dai)
123{
124 struct snd_soc_pcm_runtime *rtd = substream->private_data;
125 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
126
127 regmap_write(dd->regmap, CLASSD_THR, 0x0);
128
129 return clk_prepare_enable(dd->pclk);
130}
131
132static void atmel_classd_cpu_dai_shutdown(struct snd_pcm_substream *substream,
133 struct snd_soc_dai *cpu_dai)
134{
135 struct snd_soc_pcm_runtime *rtd = substream->private_data;
136 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
137
138 clk_disable_unprepare(dd->pclk);
139}
140
141static const struct snd_soc_dai_ops atmel_classd_cpu_dai_ops = {
142 .startup = atmel_classd_cpu_dai_startup,
143 .shutdown = atmel_classd_cpu_dai_shutdown,
144};
145
146static struct snd_soc_dai_driver atmel_classd_cpu_dai = {
147 .playback = {
148 .channels_min = 2,
149 .channels_max = 2,
150 .rates = ATMEL_CLASSD_RATES,
151 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
152 .ops = &atmel_classd_cpu_dai_ops,
153};
154
155static const struct snd_soc_component_driver atmel_classd_cpu_dai_component = {
156 .name = "atmel-classd",
157};
158
159/* platform */
160static int
161atmel_classd_platform_configure_dma(struct snd_pcm_substream *substream,
162 struct snd_pcm_hw_params *params,
163 struct dma_slave_config *slave_config)
164{
165 struct snd_soc_pcm_runtime *rtd = substream->private_data;
166 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
167
168 if (params_physical_width(params) != 16) {
169 dev_err(rtd->platform->dev,
170 "only supports 16-bit audio data\n");
171 return -EINVAL;
172 }
173
174 slave_config->direction = DMA_MEM_TO_DEV;
175 slave_config->dst_addr = dd->phy_base + CLASSD_THR;
176 slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
177 slave_config->dst_maxburst = 1;
178 slave_config->src_maxburst = 1;
179 slave_config->device_fc = false;
180
181 return 0;
182}
183
184static const struct snd_dmaengine_pcm_config
185atmel_classd_dmaengine_pcm_config = {
186 .prepare_slave_config = atmel_classd_platform_configure_dma,
187 .pcm_hardware = &atmel_classd_hw,
188 .prealloc_buffer_size = ATMEL_CLASSD_PREALLOC_BUF_SIZE,
189};
190
191/* codec */
192static const char * const mono_mode_text[] = {
193 "mix", "sat", "left", "right"
194};
195
196static SOC_ENUM_SINGLE_DECL(classd_mono_mode_enum,
197 CLASSD_INTPMR, CLASSD_INTPMR_MONO_MODE_SHIFT,
198 mono_mode_text);
199
200static const char * const eqcfg_text[] = {
201 "Treble-12dB", "Treble-6dB",
202 "Medium-8dB", "Medium-3dB",
203 "Bass-12dB", "Bass-6dB",
204 "0 dB",
205 "Bass+6dB", "Bass+12dB",
206 "Medium+3dB", "Medium+8dB",
207 "Treble+6dB", "Treble+12dB",
208};
209
210static const unsigned int eqcfg_value[] = {
211 CLASSD_INTPMR_EQCFG_T_CUT_12, CLASSD_INTPMR_EQCFG_T_CUT_6,
212 CLASSD_INTPMR_EQCFG_M_CUT_8, CLASSD_INTPMR_EQCFG_M_CUT_3,
213 CLASSD_INTPMR_EQCFG_B_CUT_12, CLASSD_INTPMR_EQCFG_B_CUT_6,
214 CLASSD_INTPMR_EQCFG_FLAT,
215 CLASSD_INTPMR_EQCFG_B_BOOST_6, CLASSD_INTPMR_EQCFG_B_BOOST_12,
216 CLASSD_INTPMR_EQCFG_M_BOOST_3, CLASSD_INTPMR_EQCFG_M_BOOST_8,
217 CLASSD_INTPMR_EQCFG_T_BOOST_6, CLASSD_INTPMR_EQCFG_T_BOOST_12,
218};
219
220static SOC_VALUE_ENUM_SINGLE_DECL(classd_eqcfg_enum,
221 CLASSD_INTPMR, CLASSD_INTPMR_EQCFG_SHIFT, 0xf,
222 eqcfg_text, eqcfg_value);
223
224static const DECLARE_TLV_DB_SCALE(classd_digital_tlv, -7800, 100, 1);
225
226static const struct snd_kcontrol_new atmel_classd_snd_controls[] = {
227SOC_DOUBLE_TLV("Playback Volume", CLASSD_INTPMR,
228 CLASSD_INTPMR_ATTL_SHIFT, CLASSD_INTPMR_ATTR_SHIFT,
229 78, 1, classd_digital_tlv),
230
231SOC_SINGLE("Deemphasis Switch", CLASSD_INTPMR,
232 CLASSD_INTPMR_DEEMP_SHIFT, 1, 0),
233
234SOC_SINGLE("Mono Switch", CLASSD_INTPMR, CLASSD_INTPMR_MONO_SHIFT, 1, 0),
235
236SOC_SINGLE("Swap Switch", CLASSD_INTPMR, CLASSD_INTPMR_SWAP_SHIFT, 1, 0),
237
238SOC_ENUM("Mono Mode", classd_mono_mode_enum),
239
240SOC_ENUM("EQ", classd_eqcfg_enum),
241};
242
243static const char * const pwm_type[] = {
244 "Single ended", "Differential"
245};
246
247static int atmel_classd_codec_probe(struct snd_soc_codec *codec)
248{
249 struct snd_soc_card *card = snd_soc_codec_get_drvdata(codec);
250 struct atmel_classd *dd = snd_soc_card_get_drvdata(card);
251 const struct atmel_classd_pdata *pdata = dd->pdata;
252 u32 mask, val;
253
254 mask = CLASSD_MR_PWMTYP_MASK;
255 val = pdata->pwm_type << CLASSD_MR_PWMTYP_SHIFT;
256
257 mask |= CLASSD_MR_NON_OVERLAP_MASK;
258 if (pdata->non_overlap_enable) {
259 val |= (CLASSD_MR_NON_OVERLAP_EN
260 << CLASSD_MR_NON_OVERLAP_SHIFT);
261
262 mask |= CLASSD_MR_NOVR_VAL_MASK;
263 switch (pdata->non_overlap_time) {
264 case 5:
265 val |= (CLASSD_MR_NOVR_VAL_5NS
266 << CLASSD_MR_NOVR_VAL_SHIFT);
267 break;
268 case 10:
269 val |= (CLASSD_MR_NOVR_VAL_10NS
270 << CLASSD_MR_NOVR_VAL_SHIFT);
271 break;
272 case 15:
273 val |= (CLASSD_MR_NOVR_VAL_15NS
274 << CLASSD_MR_NOVR_VAL_SHIFT);
275 break;
276 case 20:
277 val |= (CLASSD_MR_NOVR_VAL_20NS
278 << CLASSD_MR_NOVR_VAL_SHIFT);
279 break;
280 default:
281 val |= (CLASSD_MR_NOVR_VAL_10NS
282 << CLASSD_MR_NOVR_VAL_SHIFT);
283 dev_warn(codec->dev,
284 "non-overlapping value %d is invalid, the default value 10 is specified\n",
285 pdata->non_overlap_time);
286 break;
287 }
288 }
289
290 snd_soc_update_bits(codec, CLASSD_MR, mask, val);
291
292 dev_info(codec->dev,
293 "PWM modulation type is %s, non-overlapping is %s\n",
294 pwm_type[pdata->pwm_type],
295 pdata->non_overlap_enable?"enabled":"disabled");
296
297 return 0;
298}
299
300static struct regmap *atmel_classd_codec_get_remap(struct device *dev)
301{
302 return dev_get_regmap(dev, NULL);
303}
304
305static struct snd_soc_codec_driver soc_codec_dev_classd = {
306 .probe = atmel_classd_codec_probe,
307 .controls = atmel_classd_snd_controls,
308 .num_controls = ARRAY_SIZE(atmel_classd_snd_controls),
309 .get_regmap = atmel_classd_codec_get_remap,
310};
311
312/* codec dai component */
313static int atmel_classd_codec_dai_startup(struct snd_pcm_substream *substream,
314 struct snd_soc_dai *codec_dai)
315{
316 struct snd_soc_pcm_runtime *rtd = substream->private_data;
317 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
318 int ret;
319
320 ret = clk_prepare_enable(dd->aclk);
321 if (ret)
322 return ret;
323
324 return clk_prepare_enable(dd->gclk);
325}
326
327static int atmel_classd_codec_dai_digital_mute(struct snd_soc_dai *codec_dai,
328 int mute)
329{
330 struct snd_soc_codec *codec = codec_dai->codec;
331 u32 mask, val;
332
333 mask = CLASSD_MR_LMUTE_MASK | CLASSD_MR_RMUTE_MASK;
334
335 if (mute)
336 val = mask;
337 else
338 val = 0;
339
340 snd_soc_update_bits(codec, CLASSD_MR, mask, val);
341
342 return 0;
343}
344
345#define CLASSD_ACLK_RATE_11M2896_MPY_8 (112896 * 100 * 8)
346#define CLASSD_ACLK_RATE_12M288_MPY_8 (12228 * 1000 * 8)
347
348static struct {
349 int rate;
350 int sample_rate;
351 int dsp_clk;
352 unsigned long aclk_rate;
353} const sample_rates[] = {
354 { 8000, CLASSD_INTPMR_FRAME_8K,
355 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 },
356 { 16000, CLASSD_INTPMR_FRAME_16K,
357 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 },
358 { 32000, CLASSD_INTPMR_FRAME_32K,
359 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 },
360 { 48000, CLASSD_INTPMR_FRAME_48K,
361 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 },
362 { 96000, CLASSD_INTPMR_FRAME_96K,
363 CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 },
364 { 22050, CLASSD_INTPMR_FRAME_22K,
365 CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 },
366 { 44100, CLASSD_INTPMR_FRAME_44K,
367 CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 },
368 { 88200, CLASSD_INTPMR_FRAME_88K,
369 CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 },
370};
371
372static int
373atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream,
374 struct snd_pcm_hw_params *params,
375 struct snd_soc_dai *codec_dai)
376{
377 struct snd_soc_pcm_runtime *rtd = substream->private_data;
378 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
379 struct snd_soc_codec *codec = codec_dai->codec;
380 int fs;
381 int i, best, best_val, cur_val, ret;
382 u32 mask, val;
383
384 fs = params_rate(params);
385
386 best = 0;
387 best_val = abs(fs - sample_rates[0].rate);
388 for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
389 /* Closest match */
390 cur_val = abs(fs - sample_rates[i].rate);
391 if (cur_val < best_val) {
392 best = i;
393 best_val = cur_val;
394 }
395 }
396
397 dev_dbg(codec->dev,
398 "Selected SAMPLE_RATE of %dHz, ACLK_RATE of %ldHz\n",
399 sample_rates[best].rate, sample_rates[best].aclk_rate);
400
401 clk_disable_unprepare(dd->gclk);
402 clk_disable_unprepare(dd->aclk);
403
404 ret = clk_set_rate(dd->aclk, sample_rates[best].aclk_rate);
405 if (ret)
406 return ret;
407
408 mask = CLASSD_INTPMR_DSP_CLK_FREQ_MASK | CLASSD_INTPMR_FRAME_MASK;
409 val = (sample_rates[best].dsp_clk << CLASSD_INTPMR_DSP_CLK_FREQ_SHIFT)
410 | (sample_rates[best].sample_rate << CLASSD_INTPMR_FRAME_SHIFT);
411
412 snd_soc_update_bits(codec, CLASSD_INTPMR, mask, val);
413
414 ret = clk_prepare_enable(dd->aclk);
415 if (ret)
416 return ret;
417
418 return clk_prepare_enable(dd->gclk);
419}
420
421static void
422atmel_classd_codec_dai_shutdown(struct snd_pcm_substream *substream,
423 struct snd_soc_dai *codec_dai)
424{
425 struct snd_soc_pcm_runtime *rtd = substream->private_data;
426 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card);
427
428 clk_disable_unprepare(dd->gclk);
429 clk_disable_unprepare(dd->aclk);
430}
431
432static int atmel_classd_codec_dai_prepare(struct snd_pcm_substream *substream,
433 struct snd_soc_dai *codec_dai)
434{
435 struct snd_soc_codec *codec = codec_dai->codec;
436
437 snd_soc_update_bits(codec, CLASSD_MR,
438 CLASSD_MR_LEN_MASK | CLASSD_MR_REN_MASK,
439 (CLASSD_MR_LEN_DIS << CLASSD_MR_LEN_SHIFT)
440 |(CLASSD_MR_REN_DIS << CLASSD_MR_REN_SHIFT));
441
442 return 0;
443}
444
445static int atmel_classd_codec_dai_trigger(struct snd_pcm_substream *substream,
446 int cmd, struct snd_soc_dai *codec_dai)
447{
448 struct snd_soc_codec *codec = codec_dai->codec;
449 u32 mask, val;
450
451 mask = CLASSD_MR_LEN_MASK | CLASSD_MR_REN_MASK;
452
453 switch (cmd) {
454 case SNDRV_PCM_TRIGGER_START:
455 case SNDRV_PCM_TRIGGER_RESUME:
456 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
457 val = mask;
458 break;
459 case SNDRV_PCM_TRIGGER_STOP:
460 case SNDRV_PCM_TRIGGER_SUSPEND:
461 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
462 val = (CLASSD_MR_LEN_DIS << CLASSD_MR_LEN_SHIFT)
463 | (CLASSD_MR_REN_DIS << CLASSD_MR_REN_SHIFT);
464 break;
465 default:
466 return -EINVAL;
467 }
468
469 snd_soc_update_bits(codec, CLASSD_MR, mask, val);
470
471 return 0;
472}
473
474static const struct snd_soc_dai_ops atmel_classd_codec_dai_ops = {
475 .digital_mute = atmel_classd_codec_dai_digital_mute,
476 .startup = atmel_classd_codec_dai_startup,
477 .shutdown = atmel_classd_codec_dai_shutdown,
478 .hw_params = atmel_classd_codec_dai_hw_params,
479 .prepare = atmel_classd_codec_dai_prepare,
480 .trigger = atmel_classd_codec_dai_trigger,
481};
482
483#define ATMEL_CLASSD_CODEC_DAI_NAME "atmel-classd-hifi"
484
485static struct snd_soc_dai_driver atmel_classd_codec_dai = {
486 .name = ATMEL_CLASSD_CODEC_DAI_NAME,
487 .playback = {
488 .stream_name = "Playback",
489 .channels_min = 2,
490 .channels_max = 2,
491 .rates = ATMEL_CLASSD_RATES,
492 .formats = SNDRV_PCM_FMTBIT_S16_LE,
493 },
494 .ops = &atmel_classd_codec_dai_ops,
495};
496
497/* ASoC sound card */
498static int atmel_classd_asoc_card_init(struct device *dev,
499 struct snd_soc_card *card)
500{
501 struct snd_soc_dai_link *dai_link;
502 struct atmel_classd *dd = snd_soc_card_get_drvdata(card);
503
504 dai_link = devm_kzalloc(dev, sizeof(*dai_link), GFP_KERNEL);
505 if (!dai_link)
506 return -ENOMEM;
507
508 dai_link->name = "CLASSD";
509 dai_link->stream_name = "CLASSD PCM";
510 dai_link->codec_dai_name = ATMEL_CLASSD_CODEC_DAI_NAME;
511 dai_link->cpu_dai_name = dev_name(dev);
512 dai_link->codec_name = dev_name(dev);
513 dai_link->platform_name = dev_name(dev);
514
515 card->dai_link = dai_link;
516 card->num_links = 1;
517 card->name = dd->pdata->card_name;
518 card->dev = dev;
519
520 return 0;
521};
522
523/* regmap configuration */
524static const struct reg_default atmel_classd_reg_defaults[] = {
525 { CLASSD_INTPMR, 0x00301212 },
526};
527
528#define ATMEL_CLASSD_REG_MAX 0xE4
529static const struct regmap_config atmel_classd_regmap_config = {
530 .reg_bits = 32,
531 .reg_stride = 4,
532 .val_bits = 32,
533 .max_register = ATMEL_CLASSD_REG_MAX,
534
535 .cache_type = REGCACHE_FLAT,
536 .reg_defaults = atmel_classd_reg_defaults,
537 .num_reg_defaults = ARRAY_SIZE(atmel_classd_reg_defaults),
538};
539
540static int atmel_classd_probe(struct platform_device *pdev)
541{
542 struct device *dev = &pdev->dev;
543 struct atmel_classd *dd;
544 struct resource *res;
545 void __iomem *io_base;
546 const struct atmel_classd_pdata *pdata;
547 struct snd_soc_card *card;
548 int ret;
549
550 pdata = dev_get_platdata(dev);
551 if (!pdata) {
552 pdata = atmel_classd_dt_init(dev);
553 if (IS_ERR(pdata))
554 return PTR_ERR(pdata);
555 }
556
557 dd = devm_kzalloc(dev, sizeof(*dd), GFP_KERNEL);
558 if (!dd)
559 return -ENOMEM;
560
561 dd->pdata = pdata;
562
563 dd->irq = platform_get_irq(pdev, 0);
564 if (dd->irq < 0) {
565 ret = dd->irq;
566 dev_err(dev, "failed to could not get irq: %d\n", ret);
567 return ret;
568 }
569
570 dd->pclk = devm_clk_get(dev, "pclk");
571 if (IS_ERR(dd->pclk)) {
572 ret = PTR_ERR(dd->pclk);
573 dev_err(dev, "failed to get peripheral clock: %d\n", ret);
574 return ret;
575 }
576
577 dd->gclk = devm_clk_get(dev, "gclk");
578 if (IS_ERR(dd->gclk)) {
579 ret = PTR_ERR(dd->gclk);
580 dev_err(dev, "failed to get GCK clock: %d\n", ret);
581 return ret;
582 }
583
584 dd->aclk = devm_clk_get(dev, "aclk");
585 if (IS_ERR(dd->aclk)) {
586 ret = PTR_ERR(dd->aclk);
587 dev_err(dev, "failed to get audio clock: %d\n", ret);
588 return ret;
589 }
590
591 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
592 if (!res) {
593 dev_err(dev, "no memory resource\n");
594 return -ENXIO;
595 }
596
597 io_base = devm_ioremap_resource(dev, res);
598 if (IS_ERR(io_base)) {
599 ret = PTR_ERR(io_base);
600 dev_err(dev, "failed to remap register memory: %d\n", ret);
601 return ret;
602 }
603
604 dd->phy_base = res->start;
605
606 dd->regmap = devm_regmap_init_mmio(dev, io_base,
607 &atmel_classd_regmap_config);
608 if (IS_ERR(dd->regmap)) {
609 ret = PTR_ERR(dd->regmap);
610 dev_err(dev, "failed to init register map: %d\n", ret);
611 return ret;
612 }
613
614 ret = devm_snd_soc_register_component(dev,
615 &atmel_classd_cpu_dai_component,
616 &atmel_classd_cpu_dai, 1);
617 if (ret) {
618 dev_err(dev, "could not register CPU DAI: %d\n", ret);
619 return ret;
620 }
621
622 ret = devm_snd_dmaengine_pcm_register(dev,
623 &atmel_classd_dmaengine_pcm_config,
624 0);
625 if (ret) {
626 dev_err(dev, "could not register platform: %d\n", ret);
627 return ret;
628 }
629
630 ret = snd_soc_register_codec(dev, &soc_codec_dev_classd,
631 &atmel_classd_codec_dai, 1);
632 if (ret) {
633 dev_err(dev, "could not register codec: %d\n", ret);
634 return ret;
635 }
636
637 /* register sound card */
638 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
639 if (!card)
640 return -ENOMEM;
641
642 snd_soc_card_set_drvdata(card, dd);
643 platform_set_drvdata(pdev, card);
644
645 ret = atmel_classd_asoc_card_init(dev, card);
646 if (ret) {
647 dev_err(dev, "failed to init sound card\n");
648 return ret;
649 }
650
651 ret = devm_snd_soc_register_card(dev, card);
652 if (ret) {
653 dev_err(dev, "failed to register sound card: %d\n", ret);
654 return ret;
655 }
656
657 return 0;
658}
659
660static int atmel_classd_remove(struct platform_device *pdev)
661{
662 snd_soc_unregister_codec(&pdev->dev);
663 return 0;
664}
665
666static struct platform_driver atmel_classd_driver = {
667 .driver = {
668 .name = "atmel-classd",
669 .of_match_table = of_match_ptr(atmel_classd_of_match),
670 .pm = &snd_soc_pm_ops,
671 },
672 .probe = atmel_classd_probe,
673 .remove = atmel_classd_remove,
674};
675module_platform_driver(atmel_classd_driver);
676
677MODULE_DESCRIPTION("Atmel ClassD driver under ALSA SoC architecture");
678MODULE_AUTHOR("Songjun Wu <songjun.wu@atmel.com>");
679MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel-classd.h b/sound/soc/atmel/atmel-classd.h
new file mode 100644
index 000000000000..73f8fdd1ca83
--- /dev/null
+++ b/sound/soc/atmel/atmel-classd.h
@@ -0,0 +1,120 @@
1#ifndef __ATMEL_CLASSD_H_
2#define __ATMEL_CLASSD_H_
3
4#define CLASSD_CR 0x00000000
5#define CLASSD_CR_RESET 0x1
6
7#define CLASSD_MR 0x00000004
8
9#define CLASSD_MR_LEN_DIS 0x0
10#define CLASSD_MR_LEN_EN 0x1
11#define CLASSD_MR_LEN_MASK (0x1 << 0)
12#define CLASSD_MR_LEN_SHIFT (0)
13
14#define CLASSD_MR_LMUTE_DIS 0x0
15#define CLASSD_MR_LMUTE_EN 0x1
16#define CLASSD_MR_LMUTE_SHIFT (0x1)
17#define CLASSD_MR_LMUTE_MASK (0x1 << 1)
18
19#define CLASSD_MR_REN_DIS 0x0
20#define CLASSD_MR_REN_EN 0x1
21#define CLASSD_MR_REN_MASK (0x1 << 4)
22#define CLASSD_MR_REN_SHIFT (4)
23
24#define CLASSD_MR_RMUTE_DIS 0x0
25#define CLASSD_MR_RMUTE_EN 0x1
26#define CLASSD_MR_RMUTE_SHIFT (0x5)
27#define CLASSD_MR_RMUTE_MASK (0x1 << 5)
28
29#define CLASSD_MR_PWMTYP_SINGLE 0x0
30#define CLASSD_MR_PWMTYP_DIFF 0x1
31#define CLASSD_MR_PWMTYP_MASK (0x1 << 8)
32#define CLASSD_MR_PWMTYP_SHIFT (8)
33
34#define CLASSD_MR_NON_OVERLAP_DIS 0x0
35#define CLASSD_MR_NON_OVERLAP_EN 0x1
36#define CLASSD_MR_NON_OVERLAP_MASK (0x1 << 16)
37#define CLASSD_MR_NON_OVERLAP_SHIFT (16)
38
39#define CLASSD_MR_NOVR_VAL_5NS 0x0
40#define CLASSD_MR_NOVR_VAL_10NS 0x1
41#define CLASSD_MR_NOVR_VAL_15NS 0x2
42#define CLASSD_MR_NOVR_VAL_20NS 0x3
43#define CLASSD_MR_NOVR_VAL_MASK (0x3 << 20)
44#define CLASSD_MR_NOVR_VAL_SHIFT (20)
45
46#define CLASSD_INTPMR 0x00000008
47
48#define CLASSD_INTPMR_ATTL_MASK (0x3f << 0)
49#define CLASSD_INTPMR_ATTL_SHIFT (0)
50#define CLASSD_INTPMR_ATTR_MASK (0x3f << 8)
51#define CLASSD_INTPMR_ATTR_SHIFT (8)
52
53#define CLASSD_INTPMR_DSP_CLK_FREQ_12M288 0x0
54#define CLASSD_INTPMR_DSP_CLK_FREQ_11M2896 0x1
55#define CLASSD_INTPMR_DSP_CLK_FREQ_MASK (0x1 << 16)
56#define CLASSD_INTPMR_DSP_CLK_FREQ_SHIFT (16)
57
58#define CLASSD_INTPMR_DEEMP_DIS 0x0
59#define CLASSD_INTPMR_DEEMP_EN 0x1
60#define CLASSD_INTPMR_DEEMP_MASK (0x1 << 18)
61#define CLASSD_INTPMR_DEEMP_SHIFT (18)
62
63#define CLASSD_INTPMR_SWAP_LEFT_ON_LSB 0x0
64#define CLASSD_INTPMR_SWAP_RIGHT_ON_LSB 0x1
65#define CLASSD_INTPMR_SWAP_MASK (0x1 << 19)
66#define CLASSD_INTPMR_SWAP_SHIFT (19)
67
68#define CLASSD_INTPMR_FRAME_8K 0x0
69#define CLASSD_INTPMR_FRAME_16K 0x1
70#define CLASSD_INTPMR_FRAME_32K 0x2
71#define CLASSD_INTPMR_FRAME_48K 0x3
72#define CLASSD_INTPMR_FRAME_96K 0x4
73#define CLASSD_INTPMR_FRAME_22K 0x5
74#define CLASSD_INTPMR_FRAME_44K 0x6
75#define CLASSD_INTPMR_FRAME_88K 0x7
76#define CLASSD_INTPMR_FRAME_MASK (0x7 << 20)
77#define CLASSD_INTPMR_FRAME_SHIFT (20)
78
79#define CLASSD_INTPMR_EQCFG_FLAT 0x0
80#define CLASSD_INTPMR_EQCFG_B_BOOST_12 0x1
81#define CLASSD_INTPMR_EQCFG_B_BOOST_6 0x2
82#define CLASSD_INTPMR_EQCFG_B_CUT_12 0x3
83#define CLASSD_INTPMR_EQCFG_B_CUT_6 0x4
84#define CLASSD_INTPMR_EQCFG_M_BOOST_3 0x5
85#define CLASSD_INTPMR_EQCFG_M_BOOST_8 0x6
86#define CLASSD_INTPMR_EQCFG_M_CUT_3 0x7
87#define CLASSD_INTPMR_EQCFG_M_CUT_8 0x8
88#define CLASSD_INTPMR_EQCFG_T_BOOST_12 0x9
89#define CLASSD_INTPMR_EQCFG_T_BOOST_6 0xa
90#define CLASSD_INTPMR_EQCFG_T_CUT_12 0xb
91#define CLASSD_INTPMR_EQCFG_T_CUT_6 0xc
92#define CLASSD_INTPMR_EQCFG_SHIFT (24)
93
94#define CLASSD_INTPMR_MONO_DIS 0x0
95#define CLASSD_INTPMR_MONO_EN 0x1
96#define CLASSD_INTPMR_MONO_MASK (0x1 << 28)
97#define CLASSD_INTPMR_MONO_SHIFT (28)
98
99#define CLASSD_INTPMR_MONO_MODE_MIX 0x0
100#define CLASSD_INTPMR_MONO_MODE_SAT 0x1
101#define CLASSD_INTPMR_MONO_MODE_LEFT 0x2
102#define CLASSD_INTPMR_MONO_MODE_RIGHT 0x3
103#define CLASSD_INTPMR_MONO_MODE_MASK (0x3 << 29)
104#define CLASSD_INTPMR_MONO_MODE_SHIFT (29)
105
106#define CLASSD_INTSR 0x0000000c
107
108#define CLASSD_THR 0x00000010
109
110#define CLASSD_IER 0x00000014
111
112#define CLASSD_IDR 0x00000018
113
114#define CLASSD_IMR 0x0000001c
115
116#define CLASSD_ISR 0x00000020
117
118#define CLASSD_WPMR 0x000000e4
119
120#endif
diff --git a/sound/soc/atmel/atmel_wm8904.c b/sound/soc/atmel/atmel_wm8904.c
index aa354e1c6ff7..1933bcd46cca 100644
--- a/sound/soc/atmel/atmel_wm8904.c
+++ b/sound/soc/atmel/atmel_wm8904.c
@@ -176,6 +176,7 @@ static const struct of_device_id atmel_asoc_wm8904_dt_ids[] = {
176 { .compatible = "atmel,asoc-wm8904", }, 176 { .compatible = "atmel,asoc-wm8904", },
177 { } 177 { }
178}; 178};
179MODULE_DEVICE_TABLE(of, atmel_asoc_wm8904_dt_ids);
179#endif 180#endif
180 181
181static struct platform_driver atmel_asoc_wm8904_driver = { 182static struct platform_driver atmel_asoc_wm8904_driver = {
diff --git a/sound/soc/au1x/db1000.c b/sound/soc/au1x/db1000.c
index 452f404abfd2..e97c32798e98 100644
--- a/sound/soc/au1x/db1000.c
+++ b/sound/soc/au1x/db1000.c
@@ -38,14 +38,7 @@ static int db1000_audio_probe(struct platform_device *pdev)
38{ 38{
39 struct snd_soc_card *card = &db1000_ac97; 39 struct snd_soc_card *card = &db1000_ac97;
40 card->dev = &pdev->dev; 40 card->dev = &pdev->dev;
41 return snd_soc_register_card(card); 41 return devm_snd_soc_register_card(&pdev->dev, card);
42}
43
44static int db1000_audio_remove(struct platform_device *pdev)
45{
46 struct snd_soc_card *card = platform_get_drvdata(pdev);
47 snd_soc_unregister_card(card);
48 return 0;
49} 42}
50 43
51static struct platform_driver db1000_audio_driver = { 44static struct platform_driver db1000_audio_driver = {
@@ -54,7 +47,6 @@ static struct platform_driver db1000_audio_driver = {
54 .pm = &snd_soc_pm_ops, 47 .pm = &snd_soc_pm_ops,
55 }, 48 },
56 .probe = db1000_audio_probe, 49 .probe = db1000_audio_probe,
57 .remove = db1000_audio_remove,
58}; 50};
59 51
60module_platform_driver(db1000_audio_driver); 52module_platform_driver(db1000_audio_driver);
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index 58c3164802b8..5c73061d912a 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -129,6 +129,8 @@ static struct snd_soc_dai_link db1300_i2s_dai = {
129 .cpu_dai_name = "au1xpsc_i2s.2", 129 .cpu_dai_name = "au1xpsc_i2s.2",
130 .platform_name = "au1xpsc-pcm.2", 130 .platform_name = "au1xpsc-pcm.2",
131 .codec_name = "wm8731.0-001b", 131 .codec_name = "wm8731.0-001b",
132 .dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
133 SND_SOC_DAIFMT_CBM_CFM,
132 .ops = &db1200_i2s_wm8731_ops, 134 .ops = &db1200_i2s_wm8731_ops,
133}; 135};
134 136
@@ -146,6 +148,8 @@ static struct snd_soc_dai_link db1550_i2s_dai = {
146 .cpu_dai_name = "au1xpsc_i2s.3", 148 .cpu_dai_name = "au1xpsc_i2s.3",
147 .platform_name = "au1xpsc-pcm.3", 149 .platform_name = "au1xpsc-pcm.3",
148 .codec_name = "wm8731.0-001b", 150 .codec_name = "wm8731.0-001b",
151 .dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
152 SND_SOC_DAIFMT_CBM_CFM,
149 .ops = &db1200_i2s_wm8731_ops, 153 .ops = &db1200_i2s_wm8731_ops,
150}; 154};
151 155
@@ -174,14 +178,7 @@ static int db1200_audio_probe(struct platform_device *pdev)
174 178
175 card = db1200_cards[pid->driver_data]; 179 card = db1200_cards[pid->driver_data];
176 card->dev = &pdev->dev; 180 card->dev = &pdev->dev;
177 return snd_soc_register_card(card); 181 return devm_snd_soc_register_card(&pdev->dev, card);
178}
179
180static int db1200_audio_remove(struct platform_device *pdev)
181{
182 struct snd_soc_card *card = platform_get_drvdata(pdev);
183 snd_soc_unregister_card(card);
184 return 0;
185} 182}
186 183
187static struct platform_driver db1200_audio_driver = { 184static struct platform_driver db1200_audio_driver = {
@@ -191,7 +188,6 @@ static struct platform_driver db1200_audio_driver = {
191 }, 188 },
192 .id_table = db1200_pids, 189 .id_table = db1200_pids,
193 .probe = db1200_audio_probe, 190 .probe = db1200_audio_probe,
194 .remove = db1200_audio_remove,
195}; 191};
196 192
197module_platform_driver(db1200_audio_driver); 193module_platform_driver(db1200_audio_driver);
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index 38e853add96e..0bf9d62b91a0 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -296,7 +296,6 @@ static int au1xpsc_i2s_drvprobe(struct platform_device *pdev)
296{ 296{
297 struct resource *iores, *dmares; 297 struct resource *iores, *dmares;
298 unsigned long sel; 298 unsigned long sel;
299 int ret;
300 struct au1xpsc_audio_data *wd; 299 struct au1xpsc_audio_data *wd;
301 300
302 wd = devm_kzalloc(&pdev->dev, sizeof(struct au1xpsc_audio_data), 301 wd = devm_kzalloc(&pdev->dev, sizeof(struct au1xpsc_audio_data),
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index 5bf1501e5e3c..864df2616e10 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -87,27 +87,18 @@ static int bf5xx_ad1836_driver_probe(struct platform_device *pdev)
87 card->dev = &pdev->dev; 87 card->dev = &pdev->dev;
88 platform_set_drvdata(pdev, card); 88 platform_set_drvdata(pdev, card);
89 89
90 ret = snd_soc_register_card(card); 90 ret = devm_snd_soc_register_card(&pdev->dev, card);
91 if (ret) 91 if (ret)
92 dev_err(&pdev->dev, "Failed to register card\n"); 92 dev_err(&pdev->dev, "Failed to register card\n");
93 return ret; 93 return ret;
94} 94}
95 95
96static int bf5xx_ad1836_driver_remove(struct platform_device *pdev)
97{
98 struct snd_soc_card *card = platform_get_drvdata(pdev);
99
100 snd_soc_unregister_card(card);
101 return 0;
102}
103
104static struct platform_driver bf5xx_ad1836_driver = { 96static struct platform_driver bf5xx_ad1836_driver = {
105 .driver = { 97 .driver = {
106 .name = "bfin-snd-ad1836", 98 .name = "bfin-snd-ad1836",
107 .pm = &snd_soc_pm_ops, 99 .pm = &snd_soc_pm_ops,
108 }, 100 },
109 .probe = bf5xx_ad1836_driver_probe, 101 .probe = bf5xx_ad1836_driver_probe,
110 .remove = bf5xx_ad1836_driver_remove,
111}; 102};
112module_platform_driver(bf5xx_ad1836_driver); 103module_platform_driver(bf5xx_ad1836_driver);
113 104
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c
index 523baf5820d7..72ac78988426 100644
--- a/sound/soc/blackfin/bfin-eval-adau1373.c
+++ b/sound/soc/blackfin/bfin-eval-adau1373.c
@@ -154,16 +154,7 @@ static int bfin_eval_adau1373_probe(struct platform_device *pdev)
154 154
155 card->dev = &pdev->dev; 155 card->dev = &pdev->dev;
156 156
157 return snd_soc_register_card(&bfin_eval_adau1373); 157 return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adau1373);
158}
159
160static int bfin_eval_adau1373_remove(struct platform_device *pdev)
161{
162 struct snd_soc_card *card = platform_get_drvdata(pdev);
163
164 snd_soc_unregister_card(card);
165
166 return 0;
167} 158}
168 159
169static struct platform_driver bfin_eval_adau1373_driver = { 160static struct platform_driver bfin_eval_adau1373_driver = {
@@ -172,7 +163,6 @@ static struct platform_driver bfin_eval_adau1373_driver = {
172 .pm = &snd_soc_pm_ops, 163 .pm = &snd_soc_pm_ops,
173 }, 164 },
174 .probe = bfin_eval_adau1373_probe, 165 .probe = bfin_eval_adau1373_probe,
175 .remove = bfin_eval_adau1373_remove,
176}; 166};
177 167
178module_platform_driver(bfin_eval_adau1373_driver); 168module_platform_driver(bfin_eval_adau1373_driver);
diff --git a/sound/soc/blackfin/bfin-eval-adau1701.c b/sound/soc/blackfin/bfin-eval-adau1701.c
index f9e926dfd4ef..5c67f72cf9a9 100644
--- a/sound/soc/blackfin/bfin-eval-adau1701.c
+++ b/sound/soc/blackfin/bfin-eval-adau1701.c
@@ -94,16 +94,7 @@ static int bfin_eval_adau1701_probe(struct platform_device *pdev)
94 94
95 card->dev = &pdev->dev; 95 card->dev = &pdev->dev;
96 96
97 return snd_soc_register_card(&bfin_eval_adau1701); 97 return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adau1701);
98}
99
100static int bfin_eval_adau1701_remove(struct platform_device *pdev)
101{
102 struct snd_soc_card *card = platform_get_drvdata(pdev);
103
104 snd_soc_unregister_card(card);
105
106 return 0;
107} 98}
108 99
109static struct platform_driver bfin_eval_adau1701_driver = { 100static struct platform_driver bfin_eval_adau1701_driver = {
@@ -112,7 +103,6 @@ static struct platform_driver bfin_eval_adau1701_driver = {
112 .pm = &snd_soc_pm_ops, 103 .pm = &snd_soc_pm_ops,
113 }, 104 },
114 .probe = bfin_eval_adau1701_probe, 105 .probe = bfin_eval_adau1701_probe,
115 .remove = bfin_eval_adau1701_remove,
116}; 106};
117 107
118module_platform_driver(bfin_eval_adau1701_driver); 108module_platform_driver(bfin_eval_adau1701_driver);
diff --git a/sound/soc/blackfin/bfin-eval-adav80x.c b/sound/soc/blackfin/bfin-eval-adav80x.c
index 27eee66afdb2..1037477d10b2 100644
--- a/sound/soc/blackfin/bfin-eval-adav80x.c
+++ b/sound/soc/blackfin/bfin-eval-adav80x.c
@@ -119,16 +119,7 @@ static int bfin_eval_adav80x_probe(struct platform_device *pdev)
119 119
120 card->dev = &pdev->dev; 120 card->dev = &pdev->dev;
121 121
122 return snd_soc_register_card(&bfin_eval_adav80x); 122 return devm_snd_soc_register_card(&pdev->dev, &bfin_eval_adav80x);
123}
124
125static int bfin_eval_adav80x_remove(struct platform_device *pdev)
126{
127 struct snd_soc_card *card = platform_get_drvdata(pdev);
128
129 snd_soc_unregister_card(card);
130
131 return 0;
132} 123}
133 124
134static const struct platform_device_id bfin_eval_adav80x_ids[] = { 125static const struct platform_device_id bfin_eval_adav80x_ids[] = {
@@ -144,7 +135,6 @@ static struct platform_driver bfin_eval_adav80x_driver = {
144 .pm = &snd_soc_pm_ops, 135 .pm = &snd_soc_pm_ops,
145 }, 136 },
146 .probe = bfin_eval_adav80x_probe, 137 .probe = bfin_eval_adav80x_probe,
147 .remove = bfin_eval_adav80x_remove,
148 .id_table = bfin_eval_adav80x_ids, 138 .id_table = bfin_eval_adav80x_ids,
149}; 139};
150 140
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0c9733ecd17f..cfdafc4c11ea 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -36,6 +36,7 @@ config SND_SOC_ALL_CODECS
36 select SND_SOC_AK4104 if SPI_MASTER 36 select SND_SOC_AK4104 if SPI_MASTER
37 select SND_SOC_AK4535 if I2C 37 select SND_SOC_AK4535 if I2C
38 select SND_SOC_AK4554 38 select SND_SOC_AK4554
39 select SND_SOC_AK4613 if I2C
39 select SND_SOC_AK4641 if I2C 40 select SND_SOC_AK4641 if I2C
40 select SND_SOC_AK4642 if I2C 41 select SND_SOC_AK4642 if I2C
41 select SND_SOC_AK4671 if I2C 42 select SND_SOC_AK4671 if I2C
@@ -57,6 +58,7 @@ config SND_SOC_ALL_CODECS
57 select SND_SOC_CX20442 if TTY 58 select SND_SOC_CX20442 if TTY
58 select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI 59 select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
59 select SND_SOC_DA7213 if I2C 60 select SND_SOC_DA7213 if I2C
61 select SND_SOC_DA7219 if I2C
60 select SND_SOC_DA732X if I2C 62 select SND_SOC_DA732X if I2C
61 select SND_SOC_DA9055 if I2C 63 select SND_SOC_DA9055 if I2C
62 select SND_SOC_DMIC 64 select SND_SOC_DMIC
@@ -79,7 +81,7 @@ config SND_SOC_ALL_CODECS
79 select SND_SOC_MAX9877 if I2C 81 select SND_SOC_MAX9877 if I2C
80 select SND_SOC_MC13783 if MFD_MC13XXX 82 select SND_SOC_MC13783 if MFD_MC13XXX
81 select SND_SOC_ML26124 if I2C 83 select SND_SOC_ML26124 if I2C
82 select SND_SOC_HDMI_CODEC 84 select SND_SOC_NAU8825 if I2C
83 select SND_SOC_PCM1681 if I2C 85 select SND_SOC_PCM1681 if I2C
84 select SND_SOC_PCM1792A if SPI_MASTER 86 select SND_SOC_PCM1792A if SPI_MASTER
85 select SND_SOC_PCM3008 87 select SND_SOC_PCM3008
@@ -171,6 +173,7 @@ config SND_SOC_ALL_CODECS
171 select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI 173 select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI
172 select SND_SOC_WM8996 if I2C 174 select SND_SOC_WM8996 if I2C
173 select SND_SOC_WM8997 if MFD_WM8997 175 select SND_SOC_WM8997 if MFD_WM8997
176 select SND_SOC_WM8998 if MFD_WM8998
174 select SND_SOC_WM9081 if I2C 177 select SND_SOC_WM9081 if I2C
175 select SND_SOC_WM9090 if I2C 178 select SND_SOC_WM9090 if I2C
176 select SND_SOC_WM9705 if SND_SOC_AC97_BUS 179 select SND_SOC_WM9705 if SND_SOC_AC97_BUS
@@ -195,9 +198,11 @@ config SND_SOC_ARIZONA
195 default y if SND_SOC_WM5102=y 198 default y if SND_SOC_WM5102=y
196 default y if SND_SOC_WM5110=y 199 default y if SND_SOC_WM5110=y
197 default y if SND_SOC_WM8997=y 200 default y if SND_SOC_WM8997=y
201 default y if SND_SOC_WM8998=y
198 default m if SND_SOC_WM5102=m 202 default m if SND_SOC_WM5102=m
199 default m if SND_SOC_WM5110=m 203 default m if SND_SOC_WM5110=m
200 default m if SND_SOC_WM8997=m 204 default m if SND_SOC_WM8997=m
205 default m if SND_SOC_WM8998=m
201 206
202config SND_SOC_WM_HUBS 207config SND_SOC_WM_HUBS
203 tristate 208 tristate
@@ -319,6 +324,10 @@ config SND_SOC_AK4535
319config SND_SOC_AK4554 324config SND_SOC_AK4554
320 tristate "AKM AK4554 CODEC" 325 tristate "AKM AK4554 CODEC"
321 326
327config SND_SOC_AK4613
328 tristate "AKM AK4613 CODEC"
329 depends on I2C
330
322config SND_SOC_AK4641 331config SND_SOC_AK4641
323 tristate 332 tristate
324 333
@@ -430,6 +439,9 @@ config SND_SOC_DA7210
430config SND_SOC_DA7213 439config SND_SOC_DA7213
431 tristate 440 tristate
432 441
442config SND_SOC_DA7219
443 tristate
444
433config SND_SOC_DA732X 445config SND_SOC_DA732X
434 tristate 446 tristate
435 447
@@ -442,9 +454,6 @@ config SND_SOC_BT_SCO
442config SND_SOC_DMIC 454config SND_SOC_DMIC
443 tristate 455 tristate
444 456
445config SND_SOC_HDMI_CODEC
446 tristate "HDMI stub CODEC"
447
448config SND_SOC_ES8328 457config SND_SOC_ES8328
449 tristate "Everest Semi ES8328 CODEC" 458 tristate "Everest Semi ES8328 CODEC"
450 459
@@ -865,6 +874,9 @@ config SND_SOC_WM8996
865config SND_SOC_WM8997 874config SND_SOC_WM8997
866 tristate 875 tristate
867 876
877config SND_SOC_WM8998
878 tristate
879
868config SND_SOC_WM9081 880config SND_SOC_WM9081
869 tristate 881 tristate
870 882
@@ -896,6 +908,9 @@ config SND_SOC_MC13783
896config SND_SOC_ML26124 908config SND_SOC_ML26124
897 tristate 909 tristate
898 910
911config SND_SOC_NAU8825
912 tristate
913
899config SND_SOC_TPA6130A2 914config SND_SOC_TPA6130A2
900 tristate "Texas Instruments TPA6130A2 headphone amplifier" 915 tristate "Texas Instruments TPA6130A2 headphone amplifier"
901 depends on I2C 916 depends on I2C
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 4a32077954ae..f632fc42f59f 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -26,6 +26,7 @@ snd-soc-ads117x-objs := ads117x.o
26snd-soc-ak4104-objs := ak4104.o 26snd-soc-ak4104-objs := ak4104.o
27snd-soc-ak4535-objs := ak4535.o 27snd-soc-ak4535-objs := ak4535.o
28snd-soc-ak4554-objs := ak4554.o 28snd-soc-ak4554-objs := ak4554.o
29snd-soc-ak4613-objs := ak4613.o
29snd-soc-ak4641-objs := ak4641.o 30snd-soc-ak4641-objs := ak4641.o
30snd-soc-ak4642-objs := ak4642.o 31snd-soc-ak4642-objs := ak4642.o
31snd-soc-ak4671-objs := ak4671.o 32snd-soc-ak4671-objs := ak4671.o
@@ -49,6 +50,7 @@ snd-soc-cs4349-objs := cs4349.o
49snd-soc-cx20442-objs := cx20442.o 50snd-soc-cx20442-objs := cx20442.o
50snd-soc-da7210-objs := da7210.o 51snd-soc-da7210-objs := da7210.o
51snd-soc-da7213-objs := da7213.o 52snd-soc-da7213-objs := da7213.o
53snd-soc-da7219-objs := da7219.o da7219-aad.o
52snd-soc-da732x-objs := da732x.o 54snd-soc-da732x-objs := da732x.o
53snd-soc-da9055-objs := da9055.o 55snd-soc-da9055-objs := da9055.o
54snd-soc-bt-sco-objs := bt-sco.o 56snd-soc-bt-sco-objs := bt-sco.o
@@ -72,7 +74,7 @@ snd-soc-max98925-objs := max98925.o
72snd-soc-max9850-objs := max9850.o 74snd-soc-max9850-objs := max9850.o
73snd-soc-mc13783-objs := mc13783.o 75snd-soc-mc13783-objs := mc13783.o
74snd-soc-ml26124-objs := ml26124.o 76snd-soc-ml26124-objs := ml26124.o
75snd-soc-hdmi-codec-objs := hdmi.o 77snd-soc-nau8825-objs := nau8825.o
76snd-soc-pcm1681-objs := pcm1681.o 78snd-soc-pcm1681-objs := pcm1681.o
77snd-soc-pcm1792a-codec-objs := pcm1792a.o 79snd-soc-pcm1792a-codec-objs := pcm1792a.o
78snd-soc-pcm3008-objs := pcm3008.o 80snd-soc-pcm3008-objs := pcm3008.o
@@ -176,6 +178,7 @@ snd-soc-wm8993-objs := wm8993.o
176snd-soc-wm8994-objs := wm8994.o wm8958-dsp2.o 178snd-soc-wm8994-objs := wm8994.o wm8958-dsp2.o
177snd-soc-wm8995-objs := wm8995.o 179snd-soc-wm8995-objs := wm8995.o
178snd-soc-wm8997-objs := wm8997.o 180snd-soc-wm8997-objs := wm8997.o
181snd-soc-wm8998-objs := wm8998.o
179snd-soc-wm9081-objs := wm9081.o 182snd-soc-wm9081-objs := wm9081.o
180snd-soc-wm9090-objs := wm9090.o 183snd-soc-wm9090-objs := wm9090.o
181snd-soc-wm9705-objs := wm9705.o 184snd-soc-wm9705-objs := wm9705.o
@@ -216,6 +219,7 @@ obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
216obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o 219obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
217obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 220obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
218obj-$(CONFIG_SND_SOC_AK4554) += snd-soc-ak4554.o 221obj-$(CONFIG_SND_SOC_AK4554) += snd-soc-ak4554.o
222obj-$(CONFIG_SND_SOC_AK4613) += snd-soc-ak4613.o
219obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o 223obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o
220obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 224obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
221obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 225obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
@@ -241,6 +245,7 @@ obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o
241obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 245obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
242obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 246obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
243obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o 247obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o
248obj-$(CONFIG_SND_SOC_DA7219) += snd-soc-da7219.o
244obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o 249obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o
245obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o 250obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o
246obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o 251obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o
@@ -264,7 +269,7 @@ obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
264obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 269obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
265obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o 270obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
266obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o 271obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
267obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o 272obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o
268obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o 273obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o
269obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o 274obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o
270obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 275obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
@@ -364,6 +369,7 @@ obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
364obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o 369obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o
365obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o 370obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o
366obj-$(CONFIG_SND_SOC_WM8997) += snd-soc-wm8997.o 371obj-$(CONFIG_SND_SOC_WM8997) += snd-soc-wm8997.o
372obj-$(CONFIG_SND_SOC_WM8998) += snd-soc-wm8998.o
367obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o 373obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
368obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o 374obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o
369obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o 375obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
diff --git a/sound/soc/codecs/ad193x-i2c.c b/sound/soc/codecs/ad193x-i2c.c
index df3a1a415825..171313664bc8 100644
--- a/sound/soc/codecs/ad193x-i2c.c
+++ b/sound/soc/codecs/ad193x-i2c.c
@@ -15,8 +15,8 @@
15#include "ad193x.h" 15#include "ad193x.h"
16 16
17static const struct i2c_device_id ad193x_id[] = { 17static const struct i2c_device_id ad193x_id[] = {
18 { "ad1936", 0 }, 18 { "ad1936", AD193X },
19 { "ad1937", 0 }, 19 { "ad1937", AD193X },
20 { } 20 { }
21}; 21};
22MODULE_DEVICE_TABLE(i2c, ad193x_id); 22MODULE_DEVICE_TABLE(i2c, ad193x_id);
@@ -30,7 +30,9 @@ static int ad193x_i2c_probe(struct i2c_client *client,
30 config.val_bits = 8; 30 config.val_bits = 8;
31 config.reg_bits = 8; 31 config.reg_bits = 8;
32 32
33 return ad193x_probe(&client->dev, devm_regmap_init_i2c(client, &config)); 33 return ad193x_probe(&client->dev,
34 devm_regmap_init_i2c(client, &config),
35 (enum ad193x_type)id->driver_data);
34} 36}
35 37
36static int ad193x_i2c_remove(struct i2c_client *client) 38static int ad193x_i2c_remove(struct i2c_client *client)
diff --git a/sound/soc/codecs/ad193x-spi.c b/sound/soc/codecs/ad193x-spi.c
index 390cef9b9dc2..431f95da1de1 100644
--- a/sound/soc/codecs/ad193x-spi.c
+++ b/sound/soc/codecs/ad193x-spi.c
@@ -16,6 +16,7 @@
16 16
17static int ad193x_spi_probe(struct spi_device *spi) 17static int ad193x_spi_probe(struct spi_device *spi)
18{ 18{
19 const struct spi_device_id *id = spi_get_device_id(spi);
19 struct regmap_config config; 20 struct regmap_config config;
20 21
21 config = ad193x_regmap_config; 22 config = ad193x_regmap_config;
@@ -24,7 +25,8 @@ static int ad193x_spi_probe(struct spi_device *spi)
24 config.read_flag_mask = 0x09; 25 config.read_flag_mask = 0x09;
25 config.write_flag_mask = 0x08; 26 config.write_flag_mask = 0x08;
26 27
27 return ad193x_probe(&spi->dev, devm_regmap_init_spi(spi, &config)); 28 return ad193x_probe(&spi->dev, devm_regmap_init_spi(spi, &config),
29 (enum ad193x_type)id->driver_data);
28} 30}
29 31
30static int ad193x_spi_remove(struct spi_device *spi) 32static int ad193x_spi_remove(struct spi_device *spi)
@@ -33,6 +35,17 @@ static int ad193x_spi_remove(struct spi_device *spi)
33 return 0; 35 return 0;
34} 36}
35 37
38static const struct spi_device_id ad193x_spi_id[] = {
39 { "ad193x", AD193X },
40 { "ad1933", AD1933 },
41 { "ad1934", AD1934 },
42 { "ad1938", AD193X },
43 { "ad1939", AD193X },
44 { "adau1328", AD193X },
45 { }
46};
47MODULE_DEVICE_TABLE(spi, ad193x_spi_id);
48
36static struct spi_driver ad193x_spi_driver = { 49static struct spi_driver ad193x_spi_driver = {
37 .driver = { 50 .driver = {
38 .name = "ad193x", 51 .name = "ad193x",
@@ -40,6 +53,7 @@ static struct spi_driver ad193x_spi_driver = {
40 }, 53 },
41 .probe = ad193x_spi_probe, 54 .probe = ad193x_spi_probe,
42 .remove = ad193x_spi_remove, 55 .remove = ad193x_spi_remove,
56 .id_table = ad193x_spi_id,
43}; 57};
44module_spi_driver(ad193x_spi_driver); 58module_spi_driver(ad193x_spi_driver);
45 59
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 17c953595660..3a3f3f2343d7 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -23,6 +23,7 @@
23/* codec private data */ 23/* codec private data */
24struct ad193x_priv { 24struct ad193x_priv {
25 struct regmap *regmap; 25 struct regmap *regmap;
26 enum ad193x_type type;
26 int sysclk; 27 int sysclk;
27}; 28};
28 29
@@ -47,12 +48,6 @@ static const struct snd_kcontrol_new ad193x_snd_controls[] = {
47 SOC_DOUBLE_R_TLV("DAC4 Volume", AD193X_DAC_L4_VOL, 48 SOC_DOUBLE_R_TLV("DAC4 Volume", AD193X_DAC_L4_VOL,
48 AD193X_DAC_R4_VOL, 0, 0xFF, 1, adau193x_tlv), 49 AD193X_DAC_R4_VOL, 0, 0xFF, 1, adau193x_tlv),
49 50
50 /* ADC switch control */
51 SOC_DOUBLE("ADC1 Switch", AD193X_ADC_CTRL0, AD193X_ADCL1_MUTE,
52 AD193X_ADCR1_MUTE, 1, 1),
53 SOC_DOUBLE("ADC2 Switch", AD193X_ADC_CTRL0, AD193X_ADCL2_MUTE,
54 AD193X_ADCR2_MUTE, 1, 1),
55
56 /* DAC switch control */ 51 /* DAC switch control */
57 SOC_DOUBLE("DAC1 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL1_MUTE, 52 SOC_DOUBLE("DAC1 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL1_MUTE,
58 AD193X_DACR1_MUTE, 1, 1), 53 AD193X_DACR1_MUTE, 1, 1),
@@ -63,26 +58,37 @@ static const struct snd_kcontrol_new ad193x_snd_controls[] = {
63 SOC_DOUBLE("DAC4 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL4_MUTE, 58 SOC_DOUBLE("DAC4 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL4_MUTE,
64 AD193X_DACR4_MUTE, 1, 1), 59 AD193X_DACR4_MUTE, 1, 1),
65 60
61 /* DAC de-emphasis */
62 SOC_ENUM("Playback Deemphasis", ad193x_deemp_enum),
63};
64
65static const struct snd_kcontrol_new ad193x_adc_snd_controls[] = {
66 /* ADC switch control */
67 SOC_DOUBLE("ADC1 Switch", AD193X_ADC_CTRL0, AD193X_ADCL1_MUTE,
68 AD193X_ADCR1_MUTE, 1, 1),
69 SOC_DOUBLE("ADC2 Switch", AD193X_ADC_CTRL0, AD193X_ADCL2_MUTE,
70 AD193X_ADCR2_MUTE, 1, 1),
71
66 /* ADC high-pass filter */ 72 /* ADC high-pass filter */
67 SOC_SINGLE("ADC High Pass Filter Switch", AD193X_ADC_CTRL0, 73 SOC_SINGLE("ADC High Pass Filter Switch", AD193X_ADC_CTRL0,
68 AD193X_ADC_HIGHPASS_FILTER, 1, 0), 74 AD193X_ADC_HIGHPASS_FILTER, 1, 0),
69
70 /* DAC de-emphasis */
71 SOC_ENUM("Playback Deemphasis", ad193x_deemp_enum),
72}; 75};
73 76
74static const struct snd_soc_dapm_widget ad193x_dapm_widgets[] = { 77static const struct snd_soc_dapm_widget ad193x_dapm_widgets[] = {
75 SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0), 78 SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
76 SND_SOC_DAPM_PGA("DAC Output", AD193X_DAC_CTRL0, 0, 1, NULL, 0), 79 SND_SOC_DAPM_PGA("DAC Output", AD193X_DAC_CTRL0, 0, 1, NULL, 0),
77 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
78 SND_SOC_DAPM_SUPPLY("PLL_PWR", AD193X_PLL_CLK_CTRL0, 0, 1, NULL, 0), 80 SND_SOC_DAPM_SUPPLY("PLL_PWR", AD193X_PLL_CLK_CTRL0, 0, 1, NULL, 0),
79 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD193X_ADC_CTRL0, 0, 1, NULL, 0),
80 SND_SOC_DAPM_SUPPLY("SYSCLK", AD193X_PLL_CLK_CTRL0, 7, 0, NULL, 0), 81 SND_SOC_DAPM_SUPPLY("SYSCLK", AD193X_PLL_CLK_CTRL0, 7, 0, NULL, 0),
81 SND_SOC_DAPM_VMID("VMID"), 82 SND_SOC_DAPM_VMID("VMID"),
82 SND_SOC_DAPM_OUTPUT("DAC1OUT"), 83 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
83 SND_SOC_DAPM_OUTPUT("DAC2OUT"), 84 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
84 SND_SOC_DAPM_OUTPUT("DAC3OUT"), 85 SND_SOC_DAPM_OUTPUT("DAC3OUT"),
85 SND_SOC_DAPM_OUTPUT("DAC4OUT"), 86 SND_SOC_DAPM_OUTPUT("DAC4OUT"),
87};
88
89static const struct snd_soc_dapm_widget ad193x_adc_widgets[] = {
90 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
91 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD193X_ADC_CTRL0, 0, 1, NULL, 0),
86 SND_SOC_DAPM_INPUT("ADC1IN"), 92 SND_SOC_DAPM_INPUT("ADC1IN"),
87 SND_SOC_DAPM_INPUT("ADC2IN"), 93 SND_SOC_DAPM_INPUT("ADC2IN"),
88}; 94};
@@ -91,18 +97,33 @@ static const struct snd_soc_dapm_route audio_paths[] = {
91 { "DAC", NULL, "SYSCLK" }, 97 { "DAC", NULL, "SYSCLK" },
92 { "DAC Output", NULL, "DAC" }, 98 { "DAC Output", NULL, "DAC" },
93 { "DAC Output", NULL, "VMID" }, 99 { "DAC Output", NULL, "VMID" },
94 { "ADC", NULL, "SYSCLK" },
95 { "DAC", NULL, "ADC_PWR" },
96 { "ADC", NULL, "ADC_PWR" },
97 { "DAC1OUT", NULL, "DAC Output" }, 100 { "DAC1OUT", NULL, "DAC Output" },
98 { "DAC2OUT", NULL, "DAC Output" }, 101 { "DAC2OUT", NULL, "DAC Output" },
99 { "DAC3OUT", NULL, "DAC Output" }, 102 { "DAC3OUT", NULL, "DAC Output" },
100 { "DAC4OUT", NULL, "DAC Output" }, 103 { "DAC4OUT", NULL, "DAC Output" },
104 { "SYSCLK", NULL, "PLL_PWR" },
105};
106
107static const struct snd_soc_dapm_route ad193x_adc_audio_paths[] = {
108 { "ADC", NULL, "SYSCLK" },
109 { "ADC", NULL, "ADC_PWR" },
101 { "ADC", NULL, "ADC1IN" }, 110 { "ADC", NULL, "ADC1IN" },
102 { "ADC", NULL, "ADC2IN" }, 111 { "ADC", NULL, "ADC2IN" },
103 { "SYSCLK", NULL, "PLL_PWR" },
104}; 112};
105 113
114static inline bool ad193x_has_adc(const struct ad193x_priv *ad193x)
115{
116 switch (ad193x->type) {
117 case AD1933:
118 case AD1934:
119 return false;
120 default:
121 break;
122 }
123
124 return true;
125}
126
106/* 127/*
107 * DAI ops entries 128 * DAI ops entries
108 */ 129 */
@@ -147,8 +168,10 @@ static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
147 168
148 regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1, 169 regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
149 AD193X_DAC_CHAN_MASK, channels << AD193X_DAC_CHAN_SHFT); 170 AD193X_DAC_CHAN_MASK, channels << AD193X_DAC_CHAN_SHFT);
150 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2, 171 if (ad193x_has_adc(ad193x))
151 AD193X_ADC_CHAN_MASK, channels << AD193X_ADC_CHAN_SHFT); 172 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
173 AD193X_ADC_CHAN_MASK,
174 channels << AD193X_ADC_CHAN_SHFT);
152 175
153 return 0; 176 return 0;
154} 177}
@@ -172,7 +195,9 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
172 adc_serfmt |= AD193X_ADC_SERFMT_AUX; 195 adc_serfmt |= AD193X_ADC_SERFMT_AUX;
173 break; 196 break;
174 default: 197 default:
175 return -EINVAL; 198 if (ad193x_has_adc(ad193x))
199 return -EINVAL;
200 break;
176 } 201 }
177 202
178 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 203 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@@ -217,10 +242,12 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai,
217 return -EINVAL; 242 return -EINVAL;
218 } 243 }
219 244
220 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1, 245 if (ad193x_has_adc(ad193x)) {
221 AD193X_ADC_SERFMT_MASK, adc_serfmt); 246 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1,
222 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2, 247 AD193X_ADC_SERFMT_MASK, adc_serfmt);
223 AD193X_ADC_FMT_MASK, adc_fmt); 248 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2,
249 AD193X_ADC_FMT_MASK, adc_fmt);
250 }
224 regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1, 251 regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1,
225 AD193X_DAC_FMT_MASK, dac_fmt); 252 AD193X_DAC_FMT_MASK, dac_fmt);
226 253
@@ -287,8 +314,9 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
287 AD193X_DAC_WORD_LEN_MASK, 314 AD193X_DAC_WORD_LEN_MASK,
288 word_len << AD193X_DAC_WORD_LEN_SHFT); 315 word_len << AD193X_DAC_WORD_LEN_SHFT);
289 316
290 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1, 317 if (ad193x_has_adc(ad193x))
291 AD193X_ADC_WORD_LEN_MASK, word_len); 318 regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1,
319 AD193X_ADC_WORD_LEN_MASK, word_len);
292 320
293 return 0; 321 return 0;
294} 322}
@@ -326,6 +354,8 @@ static struct snd_soc_dai_driver ad193x_dai = {
326static int ad193x_codec_probe(struct snd_soc_codec *codec) 354static int ad193x_codec_probe(struct snd_soc_codec *codec)
327{ 355{
328 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); 356 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
357 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
358 int num, ret;
329 359
330 /* default setting for ad193x */ 360 /* default setting for ad193x */
331 361
@@ -335,14 +365,46 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec)
335 regmap_write(ad193x->regmap, AD193X_DAC_CTRL2, 0x1A); 365 regmap_write(ad193x->regmap, AD193X_DAC_CTRL2, 0x1A);
336 /* dac in tdm mode */ 366 /* dac in tdm mode */
337 regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x40); 367 regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x40);
338 /* high-pass filter enable */ 368
339 regmap_write(ad193x->regmap, AD193X_ADC_CTRL0, 0x3); 369 /* adc only */
340 /* sata delay=1, adc aux mode */ 370 if (ad193x_has_adc(ad193x)) {
341 regmap_write(ad193x->regmap, AD193X_ADC_CTRL1, 0x43); 371 /* high-pass filter enable */
372 regmap_write(ad193x->regmap, AD193X_ADC_CTRL0, 0x3);
373 /* sata delay=1, adc aux mode */
374 regmap_write(ad193x->regmap, AD193X_ADC_CTRL1, 0x43);
375 }
376
342 /* pll input: mclki/xi */ 377 /* pll input: mclki/xi */
343 regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */ 378 regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
344 regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL1, 0x04); 379 regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL1, 0x04);
345 380
381 /* adc only */
382 if (ad193x_has_adc(ad193x)) {
383 /* add adc controls */
384 num = ARRAY_SIZE(ad193x_adc_snd_controls);
385 ret = snd_soc_add_codec_controls(codec,
386 ad193x_adc_snd_controls,
387 num);
388 if (ret)
389 return ret;
390
391 /* add adc widgets */
392 num = ARRAY_SIZE(ad193x_adc_widgets);
393 ret = snd_soc_dapm_new_controls(dapm,
394 ad193x_adc_widgets,
395 num);
396 if (ret)
397 return ret;
398
399 /* add adc routes */
400 num = ARRAY_SIZE(ad193x_adc_audio_paths);
401 ret = snd_soc_dapm_add_routes(dapm,
402 ad193x_adc_audio_paths,
403 num);
404 if (ret)
405 return ret;
406 }
407
346 return 0; 408 return 0;
347} 409}
348 410
@@ -356,18 +418,13 @@ static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
356 .num_dapm_routes = ARRAY_SIZE(audio_paths), 418 .num_dapm_routes = ARRAY_SIZE(audio_paths),
357}; 419};
358 420
359static bool adau193x_reg_volatile(struct device *dev, unsigned int reg)
360{
361 return false;
362}
363
364const struct regmap_config ad193x_regmap_config = { 421const struct regmap_config ad193x_regmap_config = {
365 .max_register = AD193X_NUM_REGS - 1, 422 .max_register = AD193X_NUM_REGS - 1,
366 .volatile_reg = adau193x_reg_volatile,
367}; 423};
368EXPORT_SYMBOL_GPL(ad193x_regmap_config); 424EXPORT_SYMBOL_GPL(ad193x_regmap_config);
369 425
370int ad193x_probe(struct device *dev, struct regmap *regmap) 426int ad193x_probe(struct device *dev, struct regmap *regmap,
427 enum ad193x_type type)
371{ 428{
372 struct ad193x_priv *ad193x; 429 struct ad193x_priv *ad193x;
373 430
@@ -379,6 +436,7 @@ int ad193x_probe(struct device *dev, struct regmap *regmap)
379 return -ENOMEM; 436 return -ENOMEM;
380 437
381 ad193x->regmap = regmap; 438 ad193x->regmap = regmap;
439 ad193x->type = type;
382 440
383 dev_set_drvdata(dev, ad193x); 441 dev_set_drvdata(dev, ad193x);
384 442
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h
index ab9a998f15be..8b1e65f928d2 100644
--- a/sound/soc/codecs/ad193x.h
+++ b/sound/soc/codecs/ad193x.h
@@ -13,8 +13,15 @@
13 13
14struct device; 14struct device;
15 15
16enum ad193x_type {
17 AD193X,
18 AD1933,
19 AD1934,
20};
21
16extern const struct regmap_config ad193x_regmap_config; 22extern const struct regmap_config ad193x_regmap_config;
17int ad193x_probe(struct device *dev, struct regmap *regmap); 23int ad193x_probe(struct device *dev, struct regmap *regmap,
24 enum ad193x_type type);
18 25
19#define AD193X_PLL_CLK_CTRL0 0x00 26#define AD193X_PLL_CLK_CTRL0 0x00
20#define AD193X_PLL_POWERDOWN 0x01 27#define AD193X_PLL_POWERDOWN 0x01
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c
new file mode 100644
index 000000000000..07a266460ec3
--- /dev/null
+++ b/sound/soc/codecs/ak4613.c
@@ -0,0 +1,497 @@
1/*
2 * ak4613.c -- Asahi Kasei ALSA Soc Audio driver
3 *
4 * Copyright (C) 2015 Renesas Electronics Corporation
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * Based on ak4642.c by Kuninori Morimoto
8 * Based on wm8731.c by Richard Purdie
9 * Based on ak4535.c by Richard Purdie
10 * Based on wm8753.c by Liam Girdwood
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/clk.h>
18#include <linux/i2c.h>
19#include <linux/slab.h>
20#include <linux/of_device.h>
21#include <linux/module.h>
22#include <linux/regmap.h>
23#include <sound/soc.h>
24#include <sound/pcm_params.h>
25#include <sound/tlv.h>
26
27#define PW_MGMT1 0x00 /* Power Management 1 */
28#define PW_MGMT2 0x01 /* Power Management 2 */
29#define PW_MGMT3 0x02 /* Power Management 3 */
30#define CTRL1 0x03 /* Control 1 */
31#define CTRL2 0x04 /* Control 2 */
32#define DEMP1 0x05 /* De-emphasis1 */
33#define DEMP2 0x06 /* De-emphasis2 */
34#define OFD 0x07 /* Overflow Detect */
35#define ZRD 0x08 /* Zero Detect */
36#define ICTRL 0x09 /* Input Control */
37#define OCTRL 0x0a /* Output Control */
38#define LOUT1 0x0b /* LOUT1 Volume Control */
39#define ROUT1 0x0c /* ROUT1 Volume Control */
40#define LOUT2 0x0d /* LOUT2 Volume Control */
41#define ROUT2 0x0e /* ROUT2 Volume Control */
42#define LOUT3 0x0f /* LOUT3 Volume Control */
43#define ROUT3 0x10 /* ROUT3 Volume Control */
44#define LOUT4 0x11 /* LOUT4 Volume Control */
45#define ROUT4 0x12 /* ROUT4 Volume Control */
46#define LOUT5 0x13 /* LOUT5 Volume Control */
47#define ROUT5 0x14 /* ROUT5 Volume Control */
48#define LOUT6 0x15 /* LOUT6 Volume Control */
49#define ROUT6 0x16 /* ROUT6 Volume Control */
50
51/* PW_MGMT1 */
52#define RSTN BIT(0)
53#define PMDAC BIT(1)
54#define PMADC BIT(2)
55#define PMVR BIT(3)
56
57/* PW_MGMT2 */
58#define PMAD_ALL 0x7
59
60/* PW_MGMT3 */
61#define PMDA_ALL 0x3f
62
63/* CTRL1 */
64#define DIF0 BIT(3)
65#define DIF1 BIT(4)
66#define DIF2 BIT(5)
67#define TDM0 BIT(6)
68#define TDM1 BIT(7)
69#define NO_FMT (0xff)
70#define FMT_MASK (0xf8)
71
72/* CTRL2 */
73#define DFS_NORMAL_SPEED (0 << 2)
74#define DFS_DOUBLE_SPEED (1 << 2)
75#define DFS_QUAD_SPEED (2 << 2)
76
77struct ak4613_priv {
78 struct mutex lock;
79
80 unsigned int fmt;
81 u8 fmt_ctrl;
82 int cnt;
83};
84
85struct ak4613_formats {
86 unsigned int width;
87 unsigned int fmt;
88};
89
90struct ak4613_interface {
91 struct ak4613_formats capture;
92 struct ak4613_formats playback;
93};
94
95/*
96 * Playback Volume
97 *
98 * max : 0x00 : 0 dB
99 * ( 0.5 dB step )
100 * min : 0xFE : -127.0 dB
101 * mute: 0xFF
102 */
103static const DECLARE_TLV_DB_SCALE(out_tlv, -12750, 50, 1);
104
105static const struct snd_kcontrol_new ak4613_snd_controls[] = {
106 SOC_DOUBLE_R_TLV("Digital Playback Volume1", LOUT1, ROUT1,
107 0, 0xFF, 1, out_tlv),
108 SOC_DOUBLE_R_TLV("Digital Playback Volume2", LOUT2, ROUT2,
109 0, 0xFF, 1, out_tlv),
110 SOC_DOUBLE_R_TLV("Digital Playback Volume3", LOUT3, ROUT3,
111 0, 0xFF, 1, out_tlv),
112 SOC_DOUBLE_R_TLV("Digital Playback Volume4", LOUT4, ROUT4,
113 0, 0xFF, 1, out_tlv),
114 SOC_DOUBLE_R_TLV("Digital Playback Volume5", LOUT5, ROUT5,
115 0, 0xFF, 1, out_tlv),
116 SOC_DOUBLE_R_TLV("Digital Playback Volume6", LOUT6, ROUT6,
117 0, 0xFF, 1, out_tlv),
118};
119
120static const struct reg_default ak4613_reg[] = {
121 { 0x0, 0x0f }, { 0x1, 0x07 }, { 0x2, 0x3f }, { 0x3, 0x20 },
122 { 0x4, 0x20 }, { 0x5, 0x55 }, { 0x6, 0x05 }, { 0x7, 0x07 },
123 { 0x8, 0x0f }, { 0x9, 0x07 }, { 0xa, 0x3f }, { 0xb, 0x00 },
124 { 0xc, 0x00 }, { 0xd, 0x00 }, { 0xe, 0x00 }, { 0xf, 0x00 },
125 { 0x10, 0x00 }, { 0x11, 0x00 }, { 0x12, 0x00 }, { 0x13, 0x00 },
126 { 0x14, 0x00 }, { 0x15, 0x00 }, { 0x16, 0x00 },
127};
128
129#define AUDIO_IFACE_IDX_TO_VAL(i) (i << 3)
130#define AUDIO_IFACE(b, fmt) { b, SND_SOC_DAIFMT_##fmt }
131static const struct ak4613_interface ak4613_iface[] = {
132 /* capture */ /* playback */
133 [0] = { AUDIO_IFACE(24, LEFT_J), AUDIO_IFACE(16, RIGHT_J) },
134 [1] = { AUDIO_IFACE(24, LEFT_J), AUDIO_IFACE(20, RIGHT_J) },
135 [2] = { AUDIO_IFACE(24, LEFT_J), AUDIO_IFACE(24, RIGHT_J) },
136 [3] = { AUDIO_IFACE(24, LEFT_J), AUDIO_IFACE(24, LEFT_J) },
137 [4] = { AUDIO_IFACE(24, I2S), AUDIO_IFACE(24, I2S) },
138};
139
140static const struct regmap_config ak4613_regmap_cfg = {
141 .reg_bits = 8,
142 .val_bits = 8,
143 .max_register = 0x16,
144 .reg_defaults = ak4613_reg,
145 .num_reg_defaults = ARRAY_SIZE(ak4613_reg),
146};
147
148static const struct of_device_id ak4613_of_match[] = {
149 { .compatible = "asahi-kasei,ak4613", .data = &ak4613_regmap_cfg },
150 {},
151};
152MODULE_DEVICE_TABLE(of, ak4613_of_match);
153
154static const struct i2c_device_id ak4613_i2c_id[] = {
155 { "ak4613", (kernel_ulong_t)&ak4613_regmap_cfg },
156 { }
157};
158MODULE_DEVICE_TABLE(i2c, ak4613_i2c_id);
159
160static const struct snd_soc_dapm_widget ak4613_dapm_widgets[] = {
161
162 /* Outputs */
163 SND_SOC_DAPM_OUTPUT("LOUT1"),
164 SND_SOC_DAPM_OUTPUT("LOUT2"),
165 SND_SOC_DAPM_OUTPUT("LOUT3"),
166 SND_SOC_DAPM_OUTPUT("LOUT4"),
167 SND_SOC_DAPM_OUTPUT("LOUT5"),
168 SND_SOC_DAPM_OUTPUT("LOUT6"),
169
170 SND_SOC_DAPM_OUTPUT("ROUT1"),
171 SND_SOC_DAPM_OUTPUT("ROUT2"),
172 SND_SOC_DAPM_OUTPUT("ROUT3"),
173 SND_SOC_DAPM_OUTPUT("ROUT4"),
174 SND_SOC_DAPM_OUTPUT("ROUT5"),
175 SND_SOC_DAPM_OUTPUT("ROUT6"),
176
177 /* Inputs */
178 SND_SOC_DAPM_INPUT("LIN1"),
179 SND_SOC_DAPM_INPUT("LIN2"),
180
181 SND_SOC_DAPM_INPUT("RIN1"),
182 SND_SOC_DAPM_INPUT("RIN2"),
183
184 /* DAC */
185 SND_SOC_DAPM_DAC("DAC1", NULL, PW_MGMT3, 0, 0),
186 SND_SOC_DAPM_DAC("DAC2", NULL, PW_MGMT3, 1, 0),
187 SND_SOC_DAPM_DAC("DAC3", NULL, PW_MGMT3, 2, 0),
188 SND_SOC_DAPM_DAC("DAC4", NULL, PW_MGMT3, 3, 0),
189 SND_SOC_DAPM_DAC("DAC5", NULL, PW_MGMT3, 4, 0),
190 SND_SOC_DAPM_DAC("DAC6", NULL, PW_MGMT3, 5, 0),
191
192 /* ADC */
193 SND_SOC_DAPM_ADC("ADC1", NULL, PW_MGMT2, 0, 0),
194 SND_SOC_DAPM_ADC("ADC2", NULL, PW_MGMT2, 1, 0),
195};
196
197static const struct snd_soc_dapm_route ak4613_intercon[] = {
198 {"LOUT1", NULL, "DAC1"},
199 {"LOUT2", NULL, "DAC2"},
200 {"LOUT3", NULL, "DAC3"},
201 {"LOUT4", NULL, "DAC4"},
202 {"LOUT5", NULL, "DAC5"},
203 {"LOUT6", NULL, "DAC6"},
204
205 {"ROUT1", NULL, "DAC1"},
206 {"ROUT2", NULL, "DAC2"},
207 {"ROUT3", NULL, "DAC3"},
208 {"ROUT4", NULL, "DAC4"},
209 {"ROUT5", NULL, "DAC5"},
210 {"ROUT6", NULL, "DAC6"},
211
212 {"DAC1", NULL, "Playback"},
213 {"DAC2", NULL, "Playback"},
214 {"DAC3", NULL, "Playback"},
215 {"DAC4", NULL, "Playback"},
216 {"DAC5", NULL, "Playback"},
217 {"DAC6", NULL, "Playback"},
218
219 {"Capture", NULL, "ADC1"},
220 {"Capture", NULL, "ADC2"},
221
222 {"ADC1", NULL, "LIN1"},
223 {"ADC2", NULL, "LIN2"},
224
225 {"ADC1", NULL, "RIN1"},
226 {"ADC2", NULL, "RIN2"},
227};
228
229static void ak4613_dai_shutdown(struct snd_pcm_substream *substream,
230 struct snd_soc_dai *dai)
231{
232 struct snd_soc_codec *codec = dai->codec;
233 struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
234 struct device *dev = codec->dev;
235
236 mutex_lock(&priv->lock);
237 priv->cnt--;
238 if (priv->cnt < 0) {
239 dev_err(dev, "unexpected counter error\n");
240 priv->cnt = 0;
241 }
242 if (!priv->cnt)
243 priv->fmt_ctrl = NO_FMT;
244 mutex_unlock(&priv->lock);
245}
246
247static int ak4613_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
248{
249 struct snd_soc_codec *codec = dai->codec;
250 struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
251
252 fmt &= SND_SOC_DAIFMT_FORMAT_MASK;
253
254 switch (fmt) {
255 case SND_SOC_DAIFMT_RIGHT_J:
256 case SND_SOC_DAIFMT_LEFT_J:
257 case SND_SOC_DAIFMT_I2S:
258 priv->fmt = fmt;
259
260 break;
261 default:
262 return -EINVAL;
263 }
264
265 return 0;
266}
267
268static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
269 struct snd_pcm_hw_params *params,
270 struct snd_soc_dai *dai)
271{
272 struct snd_soc_codec *codec = dai->codec;
273 struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
274 const struct ak4613_formats *fmts;
275 struct device *dev = codec->dev;
276 unsigned int width = params_width(params);
277 unsigned int fmt = priv->fmt;
278 unsigned int rate;
279 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
280 int i, ret;
281 u8 fmt_ctrl, ctrl2;
282
283 rate = params_rate(params);
284 switch (rate) {
285 case 32000:
286 case 44100:
287 case 48000:
288 ctrl2 = DFS_NORMAL_SPEED;
289 break;
290 case 88200:
291 case 96000:
292 ctrl2 = DFS_DOUBLE_SPEED;
293 break;
294 case 176400:
295 case 192000:
296 ctrl2 = DFS_QUAD_SPEED;
297 break;
298 default:
299 return -EINVAL;
300 }
301
302 /*
303 * FIXME
304 *
305 * It doesn't support TDM at this point
306 */
307 fmt_ctrl = NO_FMT;
308 for (i = 0; i < ARRAY_SIZE(ak4613_iface); i++) {
309 fmts = (is_play) ? &ak4613_iface[i].playback :
310 &ak4613_iface[i].capture;
311
312 if (fmts->fmt != fmt)
313 continue;
314
315 if (fmt == SND_SOC_DAIFMT_RIGHT_J) {
316 if (fmts->width != width)
317 continue;
318 } else {
319 if (fmts->width < width)
320 continue;
321 }
322
323 fmt_ctrl = AUDIO_IFACE_IDX_TO_VAL(i);
324 break;
325 }
326
327 ret = -EINVAL;
328 if (fmt_ctrl == NO_FMT)
329 goto hw_params_end;
330
331 mutex_lock(&priv->lock);
332 if ((priv->fmt_ctrl == NO_FMT) ||
333 (priv->fmt_ctrl == fmt_ctrl)) {
334 priv->fmt_ctrl = fmt_ctrl;
335 priv->cnt++;
336 ret = 0;
337 }
338 mutex_unlock(&priv->lock);
339
340 if (ret < 0)
341 goto hw_params_end;
342
343 snd_soc_update_bits(codec, CTRL1, FMT_MASK, fmt_ctrl);
344 snd_soc_write(codec, CTRL2, ctrl2);
345
346hw_params_end:
347 if (ret < 0)
348 dev_warn(dev, "unsupported data width/format combination\n");
349
350 return ret;
351}
352
353static int ak4613_set_bias_level(struct snd_soc_codec *codec,
354 enum snd_soc_bias_level level)
355{
356 u8 mgmt1 = 0;
357
358 switch (level) {
359 case SND_SOC_BIAS_ON:
360 mgmt1 |= RSTN;
361 /* fall through */
362 case SND_SOC_BIAS_PREPARE:
363 mgmt1 |= PMADC | PMDAC;
364 /* fall through */
365 case SND_SOC_BIAS_STANDBY:
366 mgmt1 |= PMVR;
367 /* fall through */
368 case SND_SOC_BIAS_OFF:
369 default:
370 break;
371 }
372
373 snd_soc_write(codec, PW_MGMT1, mgmt1);
374
375 return 0;
376}
377
378static const struct snd_soc_dai_ops ak4613_dai_ops = {
379 .shutdown = ak4613_dai_shutdown,
380 .set_fmt = ak4613_dai_set_fmt,
381 .hw_params = ak4613_dai_hw_params,
382};
383
384#define AK4613_PCM_RATE (SNDRV_PCM_RATE_32000 |\
385 SNDRV_PCM_RATE_44100 |\
386 SNDRV_PCM_RATE_48000 |\
387 SNDRV_PCM_RATE_64000 |\
388 SNDRV_PCM_RATE_88200 |\
389 SNDRV_PCM_RATE_96000 |\
390 SNDRV_PCM_RATE_176400 |\
391 SNDRV_PCM_RATE_192000)
392#define AK4613_PCM_FMTBIT (SNDRV_PCM_FMTBIT_S16_LE |\
393 SNDRV_PCM_FMTBIT_S24_LE)
394
395static struct snd_soc_dai_driver ak4613_dai = {
396 .name = "ak4613-hifi",
397 .playback = {
398 .stream_name = "Playback",
399 .channels_min = 2,
400 .channels_max = 2,
401 .rates = AK4613_PCM_RATE,
402 .formats = AK4613_PCM_FMTBIT,
403 },
404 .capture = {
405 .stream_name = "Capture",
406 .channels_min = 2,
407 .channels_max = 2,
408 .rates = AK4613_PCM_RATE,
409 .formats = AK4613_PCM_FMTBIT,
410 },
411 .ops = &ak4613_dai_ops,
412 .symmetric_rates = 1,
413};
414
415static int ak4613_resume(struct snd_soc_codec *codec)
416{
417 struct regmap *regmap = dev_get_regmap(codec->dev, NULL);
418
419 regcache_mark_dirty(regmap);
420 return regcache_sync(regmap);
421}
422
423static struct snd_soc_codec_driver soc_codec_dev_ak4613 = {
424 .resume = ak4613_resume,
425 .set_bias_level = ak4613_set_bias_level,
426 .controls = ak4613_snd_controls,
427 .num_controls = ARRAY_SIZE(ak4613_snd_controls),
428 .dapm_widgets = ak4613_dapm_widgets,
429 .num_dapm_widgets = ARRAY_SIZE(ak4613_dapm_widgets),
430 .dapm_routes = ak4613_intercon,
431 .num_dapm_routes = ARRAY_SIZE(ak4613_intercon),
432};
433
434static int ak4613_i2c_probe(struct i2c_client *i2c,
435 const struct i2c_device_id *id)
436{
437 struct device *dev = &i2c->dev;
438 struct device_node *np = dev->of_node;
439 const struct regmap_config *regmap_cfg;
440 struct regmap *regmap;
441 struct ak4613_priv *priv;
442
443 regmap_cfg = NULL;
444 if (np) {
445 const struct of_device_id *of_id;
446
447 of_id = of_match_device(ak4613_of_match, dev);
448 if (of_id)
449 regmap_cfg = of_id->data;
450 } else {
451 regmap_cfg = (const struct regmap_config *)id->driver_data;
452 }
453
454 if (!regmap_cfg)
455 return -EINVAL;
456
457 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
458 if (!priv)
459 return -ENOMEM;
460
461 priv->fmt_ctrl = NO_FMT;
462 priv->cnt = 0;
463
464 mutex_init(&priv->lock);
465
466 i2c_set_clientdata(i2c, priv);
467
468 regmap = devm_regmap_init_i2c(i2c, regmap_cfg);
469 if (IS_ERR(regmap))
470 return PTR_ERR(regmap);
471
472 return snd_soc_register_codec(dev, &soc_codec_dev_ak4613,
473 &ak4613_dai, 1);
474}
475
476static int ak4613_i2c_remove(struct i2c_client *client)
477{
478 snd_soc_unregister_codec(&client->dev);
479 return 0;
480}
481
482static struct i2c_driver ak4613_i2c_driver = {
483 .driver = {
484 .name = "ak4613-codec",
485 .owner = THIS_MODULE,
486 .of_match_table = ak4613_of_match,
487 },
488 .probe = ak4613_i2c_probe,
489 .remove = ak4613_i2c_remove,
490 .id_table = ak4613_i2c_id,
491};
492
493module_i2c_driver(ak4613_i2c_driver);
494
495MODULE_DESCRIPTION("Soc AK4613 driver");
496MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
497MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 4a90143d0e90..cda27c22812a 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -23,6 +23,8 @@
23 * AK4648 is tested. 23 * AK4648 is tested.
24 */ 24 */
25 25
26#include <linux/clk.h>
27#include <linux/clk-provider.h>
26#include <linux/delay.h> 28#include <linux/delay.h>
27#include <linux/i2c.h> 29#include <linux/i2c.h>
28#include <linux/slab.h> 30#include <linux/slab.h>
@@ -128,11 +130,8 @@
128#define I2S (3 << 0) 130#define I2S (3 << 0)
129 131
130/* MD_CTL2 */ 132/* MD_CTL2 */
131#define FS0 (1 << 0) 133#define FSs(val) (((val & 0x7) << 0) | ((val & 0x8) << 2))
132#define FS1 (1 << 1) 134#define PSs(val) ((val & 0x3) << 6)
133#define FS2 (1 << 2)
134#define FS3 (1 << 5)
135#define FS_MASK (FS0 | FS1 | FS2 | FS3)
136 135
137/* MD_CTL3 */ 136/* MD_CTL3 */
138#define BST1 (1 << 3) 137#define BST1 (1 << 3)
@@ -147,6 +146,7 @@ struct ak4642_drvdata {
147 146
148struct ak4642_priv { 147struct ak4642_priv {
149 const struct ak4642_drvdata *drvdata; 148 const struct ak4642_drvdata *drvdata;
149 struct clk *mcko;
150}; 150};
151 151
152/* 152/*
@@ -430,56 +430,56 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
430 return 0; 430 return 0;
431} 431}
432 432
433static int ak4642_set_mcko(struct snd_soc_codec *codec,
434 u32 frequency)
435{
436 u32 fs_list[] = {
437 [0] = 8000,
438 [1] = 12000,
439 [2] = 16000,
440 [3] = 24000,
441 [4] = 7350,
442 [5] = 11025,
443 [6] = 14700,
444 [7] = 22050,
445 [10] = 32000,
446 [11] = 48000,
447 [14] = 29400,
448 [15] = 44100,
449 };
450 u32 ps_list[] = {
451 [0] = 256,
452 [1] = 128,
453 [2] = 64,
454 [3] = 32
455 };
456 int ps, fs;
457
458 for (ps = 0; ps < ARRAY_SIZE(ps_list); ps++) {
459 for (fs = 0; fs < ARRAY_SIZE(fs_list); fs++) {
460 if (frequency == ps_list[ps] * fs_list[fs]) {
461 snd_soc_write(codec, MD_CTL2,
462 PSs(ps) | FSs(fs));
463 return 0;
464 }
465 }
466 }
467
468 return 0;
469}
470
433static int ak4642_dai_hw_params(struct snd_pcm_substream *substream, 471static int ak4642_dai_hw_params(struct snd_pcm_substream *substream,
434 struct snd_pcm_hw_params *params, 472 struct snd_pcm_hw_params *params,
435 struct snd_soc_dai *dai) 473 struct snd_soc_dai *dai)
436{ 474{
437 struct snd_soc_codec *codec = dai->codec; 475 struct snd_soc_codec *codec = dai->codec;
438 u8 rate; 476 struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec);
477 u32 rate = clk_get_rate(priv->mcko);
439 478
440 switch (params_rate(params)) { 479 if (!rate)
441 case 7350: 480 rate = params_rate(params) * 256;
442 rate = FS2;
443 break;
444 case 8000:
445 rate = 0;
446 break;
447 case 11025:
448 rate = FS2 | FS0;
449 break;
450 case 12000:
451 rate = FS0;
452 break;
453 case 14700:
454 rate = FS2 | FS1;
455 break;
456 case 16000:
457 rate = FS1;
458 break;
459 case 22050:
460 rate = FS2 | FS1 | FS0;
461 break;
462 case 24000:
463 rate = FS1 | FS0;
464 break;
465 case 29400:
466 rate = FS3 | FS2 | FS1;
467 break;
468 case 32000:
469 rate = FS3 | FS1;
470 break;
471 case 44100:
472 rate = FS3 | FS2 | FS1 | FS0;
473 break;
474 case 48000:
475 rate = FS3 | FS1 | FS0;
476 break;
477 default:
478 return -EINVAL;
479 }
480 snd_soc_update_bits(codec, MD_CTL2, FS_MASK, rate);
481 481
482 return 0; 482 return ak4642_set_mcko(codec, rate);
483} 483}
484 484
485static int ak4642_set_bias_level(struct snd_soc_codec *codec, 485static int ak4642_set_bias_level(struct snd_soc_codec *codec,
@@ -532,7 +532,18 @@ static int ak4642_resume(struct snd_soc_codec *codec)
532 return 0; 532 return 0;
533} 533}
534 534
535static int ak4642_probe(struct snd_soc_codec *codec)
536{
537 struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec);
538
539 if (priv->mcko)
540 ak4642_set_mcko(codec, clk_get_rate(priv->mcko));
541
542 return 0;
543}
544
535static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { 545static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
546 .probe = ak4642_probe,
536 .resume = ak4642_resume, 547 .resume = ak4642_resume,
537 .set_bias_level = ak4642_set_bias_level, 548 .set_bias_level = ak4642_set_bias_level,
538 .controls = ak4642_snd_controls, 549 .controls = ak4642_snd_controls,
@@ -580,19 +591,54 @@ static const struct ak4642_drvdata ak4648_drvdata = {
580 .extended_frequencies = 1, 591 .extended_frequencies = 1,
581}; 592};
582 593
594#ifdef CONFIG_COMMON_CLK
595static struct clk *ak4642_of_parse_mcko(struct device *dev)
596{
597 struct device_node *np = dev->of_node;
598 struct clk *clk;
599 const char *clk_name = np->name;
600 const char *parent_clk_name = NULL;
601 u32 rate;
602
603 if (of_property_read_u32(np, "clock-frequency", &rate))
604 return NULL;
605
606 if (of_property_read_bool(np, "clocks"))
607 parent_clk_name = of_clk_get_parent_name(np, 0);
608
609 of_property_read_string(np, "clock-output-names", &clk_name);
610
611 clk = clk_register_fixed_rate(dev, clk_name, parent_clk_name,
612 (parent_clk_name) ? 0 : CLK_IS_ROOT,
613 rate);
614 if (!IS_ERR(clk))
615 of_clk_add_provider(np, of_clk_src_simple_get, clk);
616
617 return clk;
618}
619#else
620#define ak4642_of_parse_mcko(d) 0
621#endif
622
583static const struct of_device_id ak4642_of_match[]; 623static const struct of_device_id ak4642_of_match[];
584static int ak4642_i2c_probe(struct i2c_client *i2c, 624static int ak4642_i2c_probe(struct i2c_client *i2c,
585 const struct i2c_device_id *id) 625 const struct i2c_device_id *id)
586{ 626{
587 struct device_node *np = i2c->dev.of_node; 627 struct device *dev = &i2c->dev;
628 struct device_node *np = dev->of_node;
588 const struct ak4642_drvdata *drvdata = NULL; 629 const struct ak4642_drvdata *drvdata = NULL;
589 struct regmap *regmap; 630 struct regmap *regmap;
590 struct ak4642_priv *priv; 631 struct ak4642_priv *priv;
632 struct clk *mcko = NULL;
591 633
592 if (np) { 634 if (np) {
593 const struct of_device_id *of_id; 635 const struct of_device_id *of_id;
594 636
595 of_id = of_match_device(ak4642_of_match, &i2c->dev); 637 mcko = ak4642_of_parse_mcko(dev);
638 if (IS_ERR(mcko))
639 mcko = NULL;
640
641 of_id = of_match_device(ak4642_of_match, dev);
596 if (of_id) 642 if (of_id)
597 drvdata = of_id->data; 643 drvdata = of_id->data;
598 } else { 644 } else {
@@ -600,15 +646,16 @@ static int ak4642_i2c_probe(struct i2c_client *i2c,
600 } 646 }
601 647
602 if (!drvdata) { 648 if (!drvdata) {
603 dev_err(&i2c->dev, "Unknown device type\n"); 649 dev_err(dev, "Unknown device type\n");
604 return -EINVAL; 650 return -EINVAL;
605 } 651 }
606 652
607 priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL); 653 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
608 if (!priv) 654 if (!priv)
609 return -ENOMEM; 655 return -ENOMEM;
610 656
611 priv->drvdata = drvdata; 657 priv->drvdata = drvdata;
658 priv->mcko = mcko;
612 659
613 i2c_set_clientdata(i2c, priv); 660 i2c_set_clientdata(i2c, priv);
614 661
@@ -616,7 +663,7 @@ static int ak4642_i2c_probe(struct i2c_client *i2c,
616 if (IS_ERR(regmap)) 663 if (IS_ERR(regmap))
617 return PTR_ERR(regmap); 664 return PTR_ERR(regmap);
618 665
619 return snd_soc_register_codec(&i2c->dev, 666 return snd_soc_register_codec(dev,
620 &soc_codec_dev_ak4642, &ak4642_dai, 1); 667 &soc_codec_dev_ak4642, &ak4642_dai, 1);
621} 668}
622 669
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 8a2221ab3d10..9929efc6b9aa 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -147,6 +147,8 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
147 0x4f5, 0x0da); 147 0x4f5, 0x0da);
148 } 148 }
149 break; 149 break;
150 default:
151 break;
150 } 152 }
151 153
152 return 0; 154 return 0;
@@ -314,6 +316,7 @@ const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
314 "Tone Generator 2", 316 "Tone Generator 2",
315 "Haptics", 317 "Haptics",
316 "AEC", 318 "AEC",
319 "AEC2",
317 "Mic Mute Mixer", 320 "Mic Mute Mixer",
318 "Noise Generator", 321 "Noise Generator",
319 "IN1L", 322 "IN1L",
@@ -421,6 +424,7 @@ int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
421 0x05, 424 0x05,
422 0x06, /* Haptics */ 425 0x06, /* Haptics */
423 0x08, /* AEC */ 426 0x08, /* AEC */
427 0x09, /* AEC2 */
424 0x0c, /* Noise mixer */ 428 0x0c, /* Noise mixer */
425 0x0d, /* Comfort noise */ 429 0x0d, /* Comfort noise */
426 0x10, /* IN1L */ 430 0x10, /* IN1L */
@@ -525,6 +529,32 @@ EXPORT_SYMBOL_GPL(arizona_mixer_values);
525const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0); 529const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
526EXPORT_SYMBOL_GPL(arizona_mixer_tlv); 530EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
527 531
532const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = {
533 "12kHz", "24kHz", "48kHz", "96kHz", "192kHz",
534 "11.025kHz", "22.05kHz", "44.1kHz", "88.2kHz", "176.4kHz",
535 "4kHz", "8kHz", "16kHz", "32kHz",
536};
537EXPORT_SYMBOL_GPL(arizona_sample_rate_text);
538
539const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE] = {
540 0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
541 0x10, 0x11, 0x12, 0x13,
542};
543EXPORT_SYMBOL_GPL(arizona_sample_rate_val);
544
545const char *arizona_sample_rate_val_to_name(unsigned int rate_val)
546{
547 int i;
548
549 for (i = 0; i < ARRAY_SIZE(arizona_sample_rate_val); ++i) {
550 if (arizona_sample_rate_val[i] == rate_val)
551 return arizona_sample_rate_text[i];
552 }
553
554 return "Illegal";
555}
556EXPORT_SYMBOL_GPL(arizona_sample_rate_val_to_name);
557
528const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = { 558const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE] = {
529 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate", 559 "SYNCCLK rate", "8kHz", "16kHz", "ASYNCCLK rate",
530}; 560};
@@ -689,6 +719,15 @@ static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
689 ARIZONA_IN_VU, val); 719 ARIZONA_IN_VU, val);
690} 720}
691 721
722bool arizona_input_analog(struct snd_soc_codec *codec, int shift)
723{
724 unsigned int reg = ARIZONA_IN1L_CONTROL + ((shift / 2) * 8);
725 unsigned int val = snd_soc_read(codec, reg);
726
727 return !(val & ARIZONA_IN1_MODE_MASK);
728}
729EXPORT_SYMBOL_GPL(arizona_input_analog);
730
692int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, 731int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
693 int event) 732 int event)
694{ 733{
@@ -725,6 +764,9 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
725 reg = snd_soc_read(codec, ARIZONA_INPUT_ENABLES); 764 reg = snd_soc_read(codec, ARIZONA_INPUT_ENABLES);
726 if (reg == 0) 765 if (reg == 0)
727 arizona_in_set_vu(codec, 0); 766 arizona_in_set_vu(codec, 0);
767 break;
768 default:
769 break;
728 } 770 }
729 771
730 return 0; 772 return 0;
@@ -806,6 +848,8 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
806 break; 848 break;
807 } 849 }
808 break; 850 break;
851 default:
852 break;
809 } 853 }
810 854
811 return 0; 855 return 0;
@@ -1868,6 +1912,11 @@ static int arizona_calc_fratio(struct arizona_fll *fll,
1868 if (fll->arizona->rev < 3 || sync) 1912 if (fll->arizona->rev < 3 || sync)
1869 return init_ratio; 1913 return init_ratio;
1870 break; 1914 break;
1915 case WM8998:
1916 case WM1814:
1917 if (sync)
1918 return init_ratio;
1919 break;
1871 default: 1920 default:
1872 return init_ratio; 1921 return init_ratio;
1873 } 1922 }
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index ada0a418ff4b..fea8b8ae8e1a 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -93,12 +93,17 @@ struct arizona_priv {
93 bool dvfs_cached; 93 bool dvfs_cached;
94}; 94};
95 95
96#define ARIZONA_NUM_MIXER_INPUTS 103 96#define ARIZONA_NUM_MIXER_INPUTS 104
97 97
98extern const unsigned int arizona_mixer_tlv[]; 98extern const unsigned int arizona_mixer_tlv[];
99extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS]; 99extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS];
100extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; 100extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
101 101
102#define ARIZONA_GAINMUX_CONTROLS(name, base) \
103 SOC_SINGLE_RANGE_TLV(name " Input Volume", base + 1, \
104 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
105 arizona_mixer_tlv)
106
102#define ARIZONA_MIXER_CONTROLS(name, base) \ 107#define ARIZONA_MIXER_CONTROLS(name, base) \
103 SOC_SINGLE_RANGE_TLV(name " Input 1 Volume", base + 1, \ 108 SOC_SINGLE_RANGE_TLV(name " Input 1 Volume", base + 1, \
104 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \ 109 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
@@ -209,8 +214,12 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
209 .num_regs = 1 }) } 214 .num_regs = 1 }) }
210 215
211#define ARIZONA_RATE_ENUM_SIZE 4 216#define ARIZONA_RATE_ENUM_SIZE 4
217#define ARIZONA_SAMPLE_RATE_ENUM_SIZE 14
218
212extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE]; 219extern const char *arizona_rate_text[ARIZONA_RATE_ENUM_SIZE];
213extern const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE]; 220extern const int arizona_rate_val[ARIZONA_RATE_ENUM_SIZE];
221extern const char * const arizona_sample_rate_text[ARIZONA_SAMPLE_RATE_ENUM_SIZE];
222extern const unsigned int arizona_sample_rate_val[ARIZONA_SAMPLE_RATE_ENUM_SIZE];
214 223
215extern const struct soc_enum arizona_isrc_fsl[]; 224extern const struct soc_enum arizona_isrc_fsl[];
216extern const struct soc_enum arizona_isrc_fsh[]; 225extern const struct soc_enum arizona_isrc_fsh[];
@@ -294,4 +303,7 @@ extern int arizona_init_dai(struct arizona_priv *priv, int dai);
294int arizona_set_output_mode(struct snd_soc_codec *codec, int output, 303int arizona_set_output_mode(struct snd_soc_codec *codec, int output,
295 bool diff); 304 bool diff);
296 305
306extern bool arizona_input_analog(struct snd_soc_codec *codec, int shift);
307
308extern const char *arizona_sample_rate_val_to_name(unsigned int rate_val);
297#endif 309#endif
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index a9c86efb3187..7278f93460c1 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -12,6 +12,7 @@
12 * option) any later version. 12 * option) any later version.
13 */ 13 */
14 14
15#include <linux/clk.h>
15#include <linux/delay.h> 16#include <linux/delay.h>
16#include <linux/i2c.h> 17#include <linux/i2c.h>
17#include <linux/regmap.h> 18#include <linux/regmap.h>
@@ -1222,23 +1223,44 @@ static int da7213_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1222{ 1223{
1223 struct snd_soc_codec *codec = codec_dai->codec; 1224 struct snd_soc_codec *codec = codec_dai->codec;
1224 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); 1225 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
1226 int ret = 0;
1227
1228 if ((da7213->clk_src == clk_id) && (da7213->mclk_rate == freq))
1229 return 0;
1230
1231 if (((freq < 5000000) && (freq != 32768)) || (freq > 54000000)) {
1232 dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
1233 freq);
1234 return -EINVAL;
1235 }
1225 1236
1226 switch (clk_id) { 1237 switch (clk_id) {
1227 case DA7213_CLKSRC_MCLK: 1238 case DA7213_CLKSRC_MCLK:
1228 if ((freq == 32768) || 1239 da7213->mclk_squarer_en = false;
1229 ((freq >= 5000000) && (freq <= 54000000))) { 1240 break;
1230 da7213->mclk_rate = freq; 1241 case DA7213_CLKSRC_MCLK_SQR:
1231 return 0; 1242 da7213->mclk_squarer_en = true;
1232 } else {
1233 dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
1234 freq);
1235 return -EINVAL;
1236 }
1237 break; 1243 break;
1238 default: 1244 default:
1239 dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id); 1245 dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
1240 return -EINVAL; 1246 return -EINVAL;
1241 } 1247 }
1248
1249 da7213->clk_src = clk_id;
1250
1251 if (da7213->mclk) {
1252 freq = clk_round_rate(da7213->mclk, freq);
1253 ret = clk_set_rate(da7213->mclk, freq);
1254 if (ret) {
1255 dev_err(codec_dai->dev, "Failed to set clock rate %d\n",
1256 freq);
1257 return ret;
1258 }
1259 }
1260
1261 da7213->mclk_rate = freq;
1262
1263 return 0;
1242} 1264}
1243 1265
1244/* Supported PLL input frequencies are 5MHz - 54MHz. */ 1266/* Supported PLL input frequencies are 5MHz - 54MHz. */
@@ -1366,12 +1388,25 @@ static struct snd_soc_dai_driver da7213_dai = {
1366static int da7213_set_bias_level(struct snd_soc_codec *codec, 1388static int da7213_set_bias_level(struct snd_soc_codec *codec,
1367 enum snd_soc_bias_level level) 1389 enum snd_soc_bias_level level)
1368{ 1390{
1391 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
1392 int ret;
1393
1369 switch (level) { 1394 switch (level) {
1370 case SND_SOC_BIAS_ON: 1395 case SND_SOC_BIAS_ON:
1371 case SND_SOC_BIAS_PREPARE: 1396 case SND_SOC_BIAS_PREPARE:
1372 break; 1397 break;
1373 case SND_SOC_BIAS_STANDBY: 1398 case SND_SOC_BIAS_STANDBY:
1374 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { 1399 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
1400 /* MCLK */
1401 if (da7213->mclk) {
1402 ret = clk_prepare_enable(da7213->mclk);
1403 if (ret) {
1404 dev_err(codec->dev,
1405 "Failed to enable mclk\n");
1406 return ret;
1407 }
1408 }
1409
1375 /* Enable VMID reference & master bias */ 1410 /* Enable VMID reference & master bias */
1376 snd_soc_update_bits(codec, DA7213_REFERENCES, 1411 snd_soc_update_bits(codec, DA7213_REFERENCES,
1377 DA7213_VMID_EN | DA7213_BIAS_EN, 1412 DA7213_VMID_EN | DA7213_BIAS_EN,
@@ -1382,15 +1417,127 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
1382 /* Disable VMID reference & master bias */ 1417 /* Disable VMID reference & master bias */
1383 snd_soc_update_bits(codec, DA7213_REFERENCES, 1418 snd_soc_update_bits(codec, DA7213_REFERENCES,
1384 DA7213_VMID_EN | DA7213_BIAS_EN, 0); 1419 DA7213_VMID_EN | DA7213_BIAS_EN, 0);
1420
1421 /* MCLK */
1422 if (da7213->mclk)
1423 clk_disable_unprepare(da7213->mclk);
1385 break; 1424 break;
1386 } 1425 }
1387 return 0; 1426 return 0;
1388} 1427}
1389 1428
1429/* DT */
1430static const struct of_device_id da7213_of_match[] = {
1431 { .compatible = "dlg,da7213", },
1432 { }
1433};
1434MODULE_DEVICE_TABLE(of, da7213_of_match);
1435
1436static enum da7213_micbias_voltage
1437 da7213_of_micbias_lvl(struct snd_soc_codec *codec, u32 val)
1438{
1439 switch (val) {
1440 case 1600:
1441 return DA7213_MICBIAS_1_6V;
1442 case 2200:
1443 return DA7213_MICBIAS_2_2V;
1444 case 2500:
1445 return DA7213_MICBIAS_2_5V;
1446 case 3000:
1447 return DA7213_MICBIAS_3_0V;
1448 default:
1449 dev_warn(codec->dev, "Invalid micbias level\n");
1450 return DA7213_MICBIAS_2_2V;
1451 }
1452}
1453
1454static enum da7213_dmic_data_sel
1455 da7213_of_dmic_data_sel(struct snd_soc_codec *codec, const char *str)
1456{
1457 if (!strcmp(str, "lrise_rfall")) {
1458 return DA7213_DMIC_DATA_LRISE_RFALL;
1459 } else if (!strcmp(str, "lfall_rrise")) {
1460 return DA7213_DMIC_DATA_LFALL_RRISE;
1461 } else {
1462 dev_warn(codec->dev, "Invalid DMIC data select type\n");
1463 return DA7213_DMIC_DATA_LRISE_RFALL;
1464 }
1465}
1466
1467static enum da7213_dmic_samplephase
1468 da7213_of_dmic_samplephase(struct snd_soc_codec *codec, const char *str)
1469{
1470 if (!strcmp(str, "on_clkedge")) {
1471 return DA7213_DMIC_SAMPLE_ON_CLKEDGE;
1472 } else if (!strcmp(str, "between_clkedge")) {
1473 return DA7213_DMIC_SAMPLE_BETWEEN_CLKEDGE;
1474 } else {
1475 dev_warn(codec->dev, "Invalid DMIC sample phase\n");
1476 return DA7213_DMIC_SAMPLE_ON_CLKEDGE;
1477 }
1478}
1479
1480static enum da7213_dmic_clk_rate
1481 da7213_of_dmic_clkrate(struct snd_soc_codec *codec, u32 val)
1482{
1483 switch (val) {
1484 case 1500000:
1485 return DA7213_DMIC_CLK_1_5MHZ;
1486 case 3000000:
1487 return DA7213_DMIC_CLK_3_0MHZ;
1488 default:
1489 dev_warn(codec->dev, "Invalid DMIC clock rate\n");
1490 return DA7213_DMIC_CLK_1_5MHZ;
1491 }
1492}
1493
1494static struct da7213_platform_data
1495 *da7213_of_to_pdata(struct snd_soc_codec *codec)
1496{
1497 struct device_node *np = codec->dev->of_node;
1498 struct da7213_platform_data *pdata;
1499 const char *of_str;
1500 u32 of_val32;
1501
1502 pdata = devm_kzalloc(codec->dev, sizeof(*pdata), GFP_KERNEL);
1503 if (!pdata) {
1504 dev_warn(codec->dev, "Failed to allocate memory for pdata\n");
1505 return NULL;
1506 }
1507
1508 if (of_property_read_u32(np, "dlg,micbias1-lvl", &of_val32) >= 0)
1509 pdata->micbias1_lvl = da7213_of_micbias_lvl(codec, of_val32);
1510 else
1511 pdata->micbias1_lvl = DA7213_MICBIAS_2_2V;
1512
1513 if (of_property_read_u32(np, "dlg,micbias2-lvl", &of_val32) >= 0)
1514 pdata->micbias2_lvl = da7213_of_micbias_lvl(codec, of_val32);
1515 else
1516 pdata->micbias2_lvl = DA7213_MICBIAS_2_2V;
1517
1518 if (!of_property_read_string(np, "dlg,dmic-data-sel", &of_str))
1519 pdata->dmic_data_sel = da7213_of_dmic_data_sel(codec, of_str);
1520 else
1521 pdata->dmic_data_sel = DA7213_DMIC_DATA_LRISE_RFALL;
1522
1523 if (!of_property_read_string(np, "dlg,dmic-samplephase", &of_str))
1524 pdata->dmic_samplephase =
1525 da7213_of_dmic_samplephase(codec, of_str);
1526 else
1527 pdata->dmic_samplephase = DA7213_DMIC_SAMPLE_ON_CLKEDGE;
1528
1529 if (of_property_read_u32(np, "dlg,dmic-clkrate", &of_val32) >= 0)
1530 pdata->dmic_clk_rate = da7213_of_dmic_clkrate(codec, of_val32);
1531 else
1532 pdata->dmic_clk_rate = DA7213_DMIC_CLK_3_0MHZ;
1533
1534 return pdata;
1535}
1536
1537
1390static int da7213_probe(struct snd_soc_codec *codec) 1538static int da7213_probe(struct snd_soc_codec *codec)
1391{ 1539{
1392 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); 1540 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
1393 struct da7213_platform_data *pdata = da7213->pdata;
1394 1541
1395 /* Default to using ALC auto offset calibration mode. */ 1542 /* Default to using ALC auto offset calibration mode. */
1396 snd_soc_update_bits(codec, DA7213_ALC_CTRL1, 1543 snd_soc_update_bits(codec, DA7213_ALC_CTRL1,
@@ -1450,8 +1597,15 @@ static int da7213_probe(struct snd_soc_codec *codec)
1450 snd_soc_update_bits(codec, DA7213_LINE_CTRL, 1597 snd_soc_update_bits(codec, DA7213_LINE_CTRL,
1451 DA7213_LINE_AMP_OE, DA7213_LINE_AMP_OE); 1598 DA7213_LINE_AMP_OE, DA7213_LINE_AMP_OE);
1452 1599
1600 /* Handle DT/Platform data */
1601 if (codec->dev->of_node)
1602 da7213->pdata = da7213_of_to_pdata(codec);
1603 else
1604 da7213->pdata = dev_get_platdata(codec->dev);
1605
1453 /* Set platform data values */ 1606 /* Set platform data values */
1454 if (da7213->pdata) { 1607 if (da7213->pdata) {
1608 struct da7213_platform_data *pdata = da7213->pdata;
1455 u8 micbias_lvl = 0, dmic_cfg = 0; 1609 u8 micbias_lvl = 0, dmic_cfg = 0;
1456 1610
1457 /* Set Mic Bias voltages */ 1611 /* Set Mic Bias voltages */
@@ -1503,10 +1657,17 @@ static int da7213_probe(struct snd_soc_codec *codec)
1503 DA7213_DMIC_DATA_SEL_MASK | 1657 DA7213_DMIC_DATA_SEL_MASK |
1504 DA7213_DMIC_SAMPLEPHASE_MASK | 1658 DA7213_DMIC_SAMPLEPHASE_MASK |
1505 DA7213_DMIC_CLK_RATE_MASK, dmic_cfg); 1659 DA7213_DMIC_CLK_RATE_MASK, dmic_cfg);
1660 }
1506 1661
1507 /* Set MCLK squaring */ 1662 /* Check if MCLK provided */
1508 da7213->mclk_squarer_en = pdata->mclk_squaring; 1663 da7213->mclk = devm_clk_get(codec->dev, "mclk");
1664 if (IS_ERR(da7213->mclk)) {
1665 if (PTR_ERR(da7213->mclk) != -ENOENT)
1666 return PTR_ERR(da7213->mclk);
1667 else
1668 da7213->mclk = NULL;
1509 } 1669 }
1670
1510 return 0; 1671 return 0;
1511} 1672}
1512 1673
@@ -1537,7 +1698,6 @@ static int da7213_i2c_probe(struct i2c_client *i2c,
1537 const struct i2c_device_id *id) 1698 const struct i2c_device_id *id)
1538{ 1699{
1539 struct da7213_priv *da7213; 1700 struct da7213_priv *da7213;
1540 struct da7213_platform_data *pdata = dev_get_platdata(&i2c->dev);
1541 int ret; 1701 int ret;
1542 1702
1543 da7213 = devm_kzalloc(&i2c->dev, sizeof(struct da7213_priv), 1703 da7213 = devm_kzalloc(&i2c->dev, sizeof(struct da7213_priv),
@@ -1545,9 +1705,6 @@ static int da7213_i2c_probe(struct i2c_client *i2c,
1545 if (!da7213) 1705 if (!da7213)
1546 return -ENOMEM; 1706 return -ENOMEM;
1547 1707
1548 if (pdata)
1549 da7213->pdata = pdata;
1550
1551 i2c_set_clientdata(i2c, da7213); 1708 i2c_set_clientdata(i2c, da7213);
1552 1709
1553 da7213->regmap = devm_regmap_init_i2c(i2c, &da7213_regmap_config); 1710 da7213->regmap = devm_regmap_init_i2c(i2c, &da7213_regmap_config);
@@ -1582,6 +1739,7 @@ MODULE_DEVICE_TABLE(i2c, da7213_i2c_id);
1582static struct i2c_driver da7213_i2c_driver = { 1739static struct i2c_driver da7213_i2c_driver = {
1583 .driver = { 1740 .driver = {
1584 .name = "da7213", 1741 .name = "da7213",
1742 .of_match_table = of_match_ptr(da7213_of_match),
1585 }, 1743 },
1586 .probe = da7213_i2c_probe, 1744 .probe = da7213_i2c_probe,
1587 .remove = da7213_remove, 1745 .remove = da7213_remove,
diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h
index 9cb9ddd01282..030fd691b076 100644
--- a/sound/soc/codecs/da7213.h
+++ b/sound/soc/codecs/da7213.h
@@ -13,6 +13,7 @@
13#ifndef _DA7213_H 13#ifndef _DA7213_H
14#define _DA7213_H 14#define _DA7213_H
15 15
16#include <linux/clk.h>
16#include <linux/regmap.h> 17#include <linux/regmap.h>
17#include <sound/da7213.h> 18#include <sound/da7213.h>
18 19
@@ -504,14 +505,17 @@
504#define DA7213_PLL_INDIV_20_40_MHZ_VAL 8 505#define DA7213_PLL_INDIV_20_40_MHZ_VAL 8
505#define DA7213_PLL_INDIV_40_54_MHZ_VAL 16 506#define DA7213_PLL_INDIV_40_54_MHZ_VAL 16
506 507
507enum clk_src { 508enum da7213_clk_src {
508 DA7213_CLKSRC_MCLK 509 DA7213_CLKSRC_MCLK = 0,
510 DA7213_CLKSRC_MCLK_SQR,
509}; 511};
510 512
511/* Codec private data */ 513/* Codec private data */
512struct da7213_priv { 514struct da7213_priv {
513 struct regmap *regmap; 515 struct regmap *regmap;
516 struct clk *mclk;
514 unsigned int mclk_rate; 517 unsigned int mclk_rate;
518 int clk_src;
515 bool master; 519 bool master;
516 bool mclk_squarer_en; 520 bool mclk_squarer_en;
517 bool srm_en; 521 bool srm_en;
diff --git a/sound/soc/codecs/da7219-aad.c b/sound/soc/codecs/da7219-aad.c
new file mode 100644
index 000000000000..9459593eef13
--- /dev/null
+++ b/sound/soc/codecs/da7219-aad.c
@@ -0,0 +1,823 @@
1/*
2 * da7219-aad.c - Dialog DA7219 ALSA SoC AAD Driver
3 *
4 * Copyright (c) 2015 Dialog Semiconductor Ltd.
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/of_device.h>
17#include <linux/of_irq.h>
18#include <linux/pm_wakeirq.h>
19#include <linux/slab.h>
20#include <linux/delay.h>
21#include <linux/workqueue.h>
22#include <sound/soc.h>
23#include <sound/jack.h>
24#include <sound/da7219.h>
25
26#include "da7219.h"
27#include "da7219-aad.h"
28
29
30/*
31 * Detection control
32 */
33
34void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
35{
36 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
37
38 da7219->aad->jack = jack;
39 da7219->aad->jack_inserted = false;
40
41 /* Send an initial empty report */
42 snd_soc_jack_report(jack, 0, DA7219_AAD_REPORT_ALL_MASK);
43
44 /* Enable/Disable jack detection */
45 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
46 DA7219_ACCDET_EN_MASK,
47 (jack ? DA7219_ACCDET_EN_MASK : 0));
48}
49EXPORT_SYMBOL_GPL(da7219_aad_jack_det);
50
51/*
52 * Button/HPTest work
53 */
54
55static void da7219_aad_btn_det_work(struct work_struct *work)
56{
57 struct da7219_aad_priv *da7219_aad =
58 container_of(work, struct da7219_aad_priv, btn_det_work);
59 struct snd_soc_codec *codec = da7219_aad->codec;
60 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
61 u8 statusa, micbias_ctrl;
62 bool micbias_up = false;
63 int retries = 0;
64
65 /* Drive headphones/lineout */
66 snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
67 DA7219_HP_L_AMP_OE_MASK,
68 DA7219_HP_L_AMP_OE_MASK);
69 snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
70 DA7219_HP_R_AMP_OE_MASK,
71 DA7219_HP_R_AMP_OE_MASK);
72
73 /* Make sure mic bias is up */
74 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
75 snd_soc_dapm_sync(dapm);
76
77 do {
78 statusa = snd_soc_read(codec, DA7219_ACCDET_STATUS_A);
79 if (statusa & DA7219_MICBIAS_UP_STS_MASK)
80 micbias_up = true;
81 else if (retries++ < DA7219_AAD_MICBIAS_CHK_RETRIES)
82 msleep(DA7219_AAD_MICBIAS_CHK_DELAY);
83 } while ((!micbias_up) && (retries < DA7219_AAD_MICBIAS_CHK_RETRIES));
84
85 if (retries >= DA7219_AAD_MICBIAS_CHK_RETRIES)
86 dev_warn(codec->dev, "Mic bias status check timed out");
87
88 /*
89 * Mic bias pulse required to enable mic, must be done before enabling
90 * button detection to prevent erroneous button readings.
91 */
92 if (da7219_aad->micbias_pulse_lvl && da7219_aad->micbias_pulse_time) {
93 /* Pulse higher level voltage */
94 micbias_ctrl = snd_soc_read(codec, DA7219_MICBIAS_CTRL);
95 snd_soc_update_bits(codec, DA7219_MICBIAS_CTRL,
96 DA7219_MICBIAS1_LEVEL_MASK,
97 da7219_aad->micbias_pulse_lvl);
98 msleep(da7219_aad->micbias_pulse_time);
99 snd_soc_write(codec, DA7219_MICBIAS_CTRL, micbias_ctrl);
100
101 }
102
103 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
104 DA7219_BUTTON_CONFIG_MASK,
105 da7219_aad->btn_cfg);
106}
107
108static void da7219_aad_hptest_work(struct work_struct *work)
109{
110 struct da7219_aad_priv *da7219_aad =
111 container_of(work, struct da7219_aad_priv, hptest_work);
112 struct snd_soc_codec *codec = da7219_aad->codec;
113 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
114 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
115
116 u16 tonegen_freq_hptest;
117 u8 accdet_cfg8;
118 int report = 0;
119
120 /* Lock DAPM and any Kcontrols that are affected by this test */
121 snd_soc_dapm_mutex_lock(dapm);
122 mutex_lock(&da7219->lock);
123
124 /* Bypass cache so it saves current settings */
125 regcache_cache_bypass(da7219->regmap, true);
126
127 /* Make sure Tone Generator is disabled */
128 snd_soc_write(codec, DA7219_TONE_GEN_CFG1, 0);
129
130 /* Enable HPTest block, 1KOhms check */
131 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8,
132 DA7219_HPTEST_EN_MASK | DA7219_HPTEST_RES_SEL_MASK,
133 DA7219_HPTEST_EN_MASK |
134 DA7219_HPTEST_RES_SEL_1KOHMS);
135
136 /* Set gains to 0db */
137 snd_soc_write(codec, DA7219_DAC_L_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
138 snd_soc_write(codec, DA7219_DAC_R_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
139 snd_soc_write(codec, DA7219_HP_L_GAIN, DA7219_HP_AMP_GAIN_0DB);
140 snd_soc_write(codec, DA7219_HP_R_GAIN, DA7219_HP_AMP_GAIN_0DB);
141
142 /* Disable DAC filters, EQs and soft mute */
143 snd_soc_update_bits(codec, DA7219_DAC_FILTERS1, DA7219_HPF_MODE_MASK,
144 0);
145 snd_soc_update_bits(codec, DA7219_DAC_FILTERS4, DA7219_DAC_EQ_EN_MASK,
146 0);
147 snd_soc_update_bits(codec, DA7219_DAC_FILTERS5,
148 DA7219_DAC_SOFTMUTE_EN_MASK, 0);
149
150 /* Enable HP left & right paths */
151 snd_soc_update_bits(codec, DA7219_CP_CTRL, DA7219_CP_EN_MASK,
152 DA7219_CP_EN_MASK);
153 snd_soc_update_bits(codec, DA7219_DIG_ROUTING_DAC,
154 DA7219_DAC_L_SRC_MASK | DA7219_DAC_R_SRC_MASK,
155 DA7219_DAC_L_SRC_TONEGEN |
156 DA7219_DAC_R_SRC_TONEGEN);
157 snd_soc_update_bits(codec, DA7219_DAC_L_CTRL,
158 DA7219_DAC_L_EN_MASK | DA7219_DAC_L_MUTE_EN_MASK,
159 DA7219_DAC_L_EN_MASK);
160 snd_soc_update_bits(codec, DA7219_DAC_R_CTRL,
161 DA7219_DAC_R_EN_MASK | DA7219_DAC_R_MUTE_EN_MASK,
162 DA7219_DAC_R_EN_MASK);
163 snd_soc_update_bits(codec, DA7219_MIXOUT_L_SELECT,
164 DA7219_MIXOUT_L_MIX_SELECT_MASK,
165 DA7219_MIXOUT_L_MIX_SELECT_MASK);
166 snd_soc_update_bits(codec, DA7219_MIXOUT_R_SELECT,
167 DA7219_MIXOUT_R_MIX_SELECT_MASK,
168 DA7219_MIXOUT_R_MIX_SELECT_MASK);
169 snd_soc_update_bits(codec, DA7219_DROUTING_ST_OUTFILT_1L,
170 DA7219_OUTFILT_ST_1L_SRC_MASK,
171 DA7219_DMIX_ST_SRC_OUTFILT1L);
172 snd_soc_update_bits(codec, DA7219_DROUTING_ST_OUTFILT_1R,
173 DA7219_OUTFILT_ST_1R_SRC_MASK,
174 DA7219_DMIX_ST_SRC_OUTFILT1R);
175 snd_soc_update_bits(codec, DA7219_MIXOUT_L_CTRL,
176 DA7219_MIXOUT_L_AMP_EN_MASK,
177 DA7219_MIXOUT_L_AMP_EN_MASK);
178 snd_soc_update_bits(codec, DA7219_MIXOUT_R_CTRL,
179 DA7219_MIXOUT_R_AMP_EN_MASK,
180 DA7219_MIXOUT_R_AMP_EN_MASK);
181 snd_soc_write(codec, DA7219_HP_L_CTRL,
182 DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK);
183 snd_soc_write(codec, DA7219_HP_R_CTRL,
184 DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK);
185
186 /* Configure & start Tone Generator */
187 snd_soc_write(codec, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK);
188 tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ);
189 regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L,
190 &tonegen_freq_hptest, sizeof(tonegen_freq_hptest));
191 snd_soc_update_bits(codec, DA7219_TONE_GEN_CFG2,
192 DA7219_SWG_SEL_MASK | DA7219_TONE_GEN_GAIN_MASK,
193 DA7219_SWG_SEL_SRAMP |
194 DA7219_TONE_GEN_GAIN_MINUS_15DB);
195 snd_soc_write(codec, DA7219_TONE_GEN_CFG1, DA7219_START_STOPN_MASK);
196
197 msleep(DA7219_AAD_HPTEST_PERIOD);
198
199 /* Grab comparator reading */
200 accdet_cfg8 = snd_soc_read(codec, DA7219_ACCDET_CONFIG_8);
201 if (accdet_cfg8 & DA7219_HPTEST_COMP_MASK)
202 report |= SND_JACK_HEADPHONE;
203 else
204 report |= SND_JACK_LINEOUT;
205
206 /* Stop tone generator */
207 snd_soc_write(codec, DA7219_TONE_GEN_CFG1, 0);
208
209 msleep(DA7219_AAD_HPTEST_PERIOD);
210
211 /* Restore original settings from cache */
212 regcache_mark_dirty(da7219->regmap);
213 regcache_sync_region(da7219->regmap, DA7219_HP_L_CTRL,
214 DA7219_HP_R_CTRL);
215 regcache_sync_region(da7219->regmap, DA7219_MIXOUT_L_CTRL,
216 DA7219_MIXOUT_R_CTRL);
217 regcache_sync_region(da7219->regmap, DA7219_DROUTING_ST_OUTFILT_1L,
218 DA7219_DROUTING_ST_OUTFILT_1R);
219 regcache_sync_region(da7219->regmap, DA7219_MIXOUT_L_SELECT,
220 DA7219_MIXOUT_R_SELECT);
221 regcache_sync_region(da7219->regmap, DA7219_DAC_L_CTRL,
222 DA7219_DAC_R_CTRL);
223 regcache_sync_region(da7219->regmap, DA7219_DIG_ROUTING_DAC,
224 DA7219_DIG_ROUTING_DAC);
225 regcache_sync_region(da7219->regmap, DA7219_CP_CTRL, DA7219_CP_CTRL);
226 regcache_sync_region(da7219->regmap, DA7219_DAC_FILTERS5,
227 DA7219_DAC_FILTERS5);
228 regcache_sync_region(da7219->regmap, DA7219_DAC_FILTERS4,
229 DA7219_DAC_FILTERS1);
230 regcache_sync_region(da7219->regmap, DA7219_HP_L_GAIN,
231 DA7219_HP_R_GAIN);
232 regcache_sync_region(da7219->regmap, DA7219_DAC_L_GAIN,
233 DA7219_DAC_R_GAIN);
234 regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_ON_PER,
235 DA7219_TONE_GEN_ON_PER);
236 regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_FREQ1_L,
237 DA7219_TONE_GEN_FREQ1_U);
238 regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_CFG1,
239 DA7219_TONE_GEN_CFG2);
240
241 regcache_cache_bypass(da7219->regmap, false);
242
243 /* Disable HPTest block */
244 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8,
245 DA7219_HPTEST_EN_MASK, 0);
246
247 /* Drive Headphones/lineout */
248 snd_soc_update_bits(codec, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK,
249 DA7219_HP_L_AMP_OE_MASK);
250 snd_soc_update_bits(codec, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK,
251 DA7219_HP_R_AMP_OE_MASK);
252
253 mutex_unlock(&da7219->lock);
254 snd_soc_dapm_mutex_unlock(dapm);
255
256 /*
257 * Only send report if jack hasn't been removed during process,
258 * otherwise it's invalid and we drop it.
259 */
260 if (da7219_aad->jack_inserted)
261 snd_soc_jack_report(da7219_aad->jack, report,
262 SND_JACK_HEADSET | SND_JACK_LINEOUT);
263}
264
265
266/*
267 * IRQ
268 */
269
270static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
271{
272 struct da7219_aad_priv *da7219_aad = data;
273 struct snd_soc_codec *codec = da7219_aad->codec;
274 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
275 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
276 u8 events[DA7219_AAD_IRQ_REG_MAX];
277 u8 statusa;
278 int i, report = 0, mask = 0;
279
280 /* Read current IRQ events */
281 regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
282 events, DA7219_AAD_IRQ_REG_MAX);
283
284 if (!events[DA7219_AAD_IRQ_REG_A] && !events[DA7219_AAD_IRQ_REG_B])
285 return IRQ_NONE;
286
287 /* Read status register for jack insertion & type status */
288 statusa = snd_soc_read(codec, DA7219_ACCDET_STATUS_A);
289
290 /* Clear events */
291 regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
292 events, DA7219_AAD_IRQ_REG_MAX);
293
294 dev_dbg(codec->dev, "IRQ events = 0x%x|0x%x, status = 0x%x\n",
295 events[DA7219_AAD_IRQ_REG_A], events[DA7219_AAD_IRQ_REG_B],
296 statusa);
297
298 if (statusa & DA7219_JACK_INSERTION_STS_MASK) {
299 /* Jack Insertion */
300 if (events[DA7219_AAD_IRQ_REG_A] &
301 DA7219_E_JACK_INSERTED_MASK) {
302 report |= SND_JACK_MECHANICAL;
303 mask |= SND_JACK_MECHANICAL;
304 da7219_aad->jack_inserted = true;
305 }
306
307 /* Jack type detection */
308 if (events[DA7219_AAD_IRQ_REG_A] &
309 DA7219_E_JACK_DETECT_COMPLETE_MASK) {
310 /*
311 * If 4-pole, then enable button detection, else perform
312 * HP impedance test to determine output type to report.
313 *
314 * We schedule work here as the tasks themselves can
315 * take time to complete, and in particular for hptest
316 * we want to be able to check if the jack was removed
317 * during the procedure as this will invalidate the
318 * result. By doing this as work, the IRQ thread can
319 * handle a removal, and we can check at the end of
320 * hptest if we have a valid result or not.
321 */
322 if (statusa & DA7219_JACK_TYPE_STS_MASK) {
323 report |= SND_JACK_HEADSET;
324 mask |= SND_JACK_HEADSET | SND_JACK_LINEOUT;
325 schedule_work(&da7219_aad->btn_det_work);
326 } else {
327 schedule_work(&da7219_aad->hptest_work);
328 }
329 }
330
331 /* Button support for 4-pole jack */
332 if (statusa & DA7219_JACK_TYPE_STS_MASK) {
333 for (i = 0; i < DA7219_AAD_MAX_BUTTONS; ++i) {
334 /* Button Press */
335 if (events[DA7219_AAD_IRQ_REG_B] &
336 (DA7219_E_BUTTON_A_PRESSED_MASK << i)) {
337 report |= SND_JACK_BTN_0 >> i;
338 mask |= SND_JACK_BTN_0 >> i;
339 }
340 }
341 snd_soc_jack_report(da7219_aad->jack, report, mask);
342
343 for (i = 0; i < DA7219_AAD_MAX_BUTTONS; ++i) {
344 /* Button Release */
345 if (events[DA7219_AAD_IRQ_REG_B] &
346 (DA7219_E_BUTTON_A_RELEASED_MASK >> i)) {
347 report &= ~(SND_JACK_BTN_0 >> i);
348 mask |= SND_JACK_BTN_0 >> i;
349 }
350 }
351 }
352 } else {
353 /* Jack removal */
354 if (events[DA7219_AAD_IRQ_REG_A] & DA7219_E_JACK_REMOVED_MASK) {
355 report = 0;
356 mask |= DA7219_AAD_REPORT_ALL_MASK;
357 da7219_aad->jack_inserted = false;
358
359 /* Un-drive headphones/lineout */
360 snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
361 DA7219_HP_R_AMP_OE_MASK, 0);
362 snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
363 DA7219_HP_L_AMP_OE_MASK, 0);
364
365 /* Ensure button detection disabled */
366 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
367 DA7219_BUTTON_CONFIG_MASK, 0);
368
369 /* Disable mic bias */
370 snd_soc_dapm_disable_pin(dapm, "Mic Bias");
371 snd_soc_dapm_sync(dapm);
372
373 /* Cancel any pending work */
374 cancel_work_sync(&da7219_aad->btn_det_work);
375 cancel_work_sync(&da7219_aad->hptest_work);
376 }
377 }
378
379 snd_soc_jack_report(da7219_aad->jack, report, mask);
380
381 return IRQ_HANDLED;
382}
383
384/*
385 * DT to pdata conversion
386 */
387
388static enum da7219_aad_micbias_pulse_lvl
389 da7219_aad_of_micbias_pulse_lvl(struct snd_soc_codec *codec, u32 val)
390{
391 switch (val) {
392 case 2800:
393 return DA7219_AAD_MICBIAS_PULSE_LVL_2_8V;
394 case 2900:
395 return DA7219_AAD_MICBIAS_PULSE_LVL_2_9V;
396 default:
397 dev_warn(codec->dev, "Invalid micbias pulse level");
398 return DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
399 }
400}
401
402static enum da7219_aad_btn_cfg
403 da7219_aad_of_btn_cfg(struct snd_soc_codec *codec, u32 val)
404{
405 switch (val) {
406 case 2:
407 return DA7219_AAD_BTN_CFG_2MS;
408 case 5:
409 return DA7219_AAD_BTN_CFG_5MS;
410 case 10:
411 return DA7219_AAD_BTN_CFG_10MS;
412 case 50:
413 return DA7219_AAD_BTN_CFG_50MS;
414 case 100:
415 return DA7219_AAD_BTN_CFG_100MS;
416 case 200:
417 return DA7219_AAD_BTN_CFG_200MS;
418 case 500:
419 return DA7219_AAD_BTN_CFG_500MS;
420 default:
421 dev_warn(codec->dev, "Invalid button config");
422 return DA7219_AAD_BTN_CFG_10MS;
423 }
424}
425
426static enum da7219_aad_mic_det_thr
427 da7219_aad_of_mic_det_thr(struct snd_soc_codec *codec, u32 val)
428{
429 switch (val) {
430 case 200:
431 return DA7219_AAD_MIC_DET_THR_200_OHMS;
432 case 500:
433 return DA7219_AAD_MIC_DET_THR_500_OHMS;
434 case 750:
435 return DA7219_AAD_MIC_DET_THR_750_OHMS;
436 case 1000:
437 return DA7219_AAD_MIC_DET_THR_1000_OHMS;
438 default:
439 dev_warn(codec->dev, "Invalid mic detect threshold");
440 return DA7219_AAD_MIC_DET_THR_500_OHMS;
441 }
442}
443
444static enum da7219_aad_jack_ins_deb
445 da7219_aad_of_jack_ins_deb(struct snd_soc_codec *codec, u32 val)
446{
447 switch (val) {
448 case 5:
449 return DA7219_AAD_JACK_INS_DEB_5MS;
450 case 10:
451 return DA7219_AAD_JACK_INS_DEB_10MS;
452 case 20:
453 return DA7219_AAD_JACK_INS_DEB_20MS;
454 case 50:
455 return DA7219_AAD_JACK_INS_DEB_50MS;
456 case 100:
457 return DA7219_AAD_JACK_INS_DEB_100MS;
458 case 200:
459 return DA7219_AAD_JACK_INS_DEB_200MS;
460 case 500:
461 return DA7219_AAD_JACK_INS_DEB_500MS;
462 case 1000:
463 return DA7219_AAD_JACK_INS_DEB_1S;
464 default:
465 dev_warn(codec->dev, "Invalid jack insert debounce");
466 return DA7219_AAD_JACK_INS_DEB_20MS;
467 }
468}
469
470static enum da7219_aad_jack_det_rate
471 da7219_aad_of_jack_det_rate(struct snd_soc_codec *codec, const char *str)
472{
473 if (!strcmp(str, "32ms_64ms")) {
474 return DA7219_AAD_JACK_DET_RATE_32_64MS;
475 } else if (!strcmp(str, "64ms_128ms")) {
476 return DA7219_AAD_JACK_DET_RATE_64_128MS;
477 } else if (!strcmp(str, "128ms_256ms")) {
478 return DA7219_AAD_JACK_DET_RATE_128_256MS;
479 } else if (!strcmp(str, "256ms_512ms")) {
480 return DA7219_AAD_JACK_DET_RATE_256_512MS;
481 } else {
482 dev_warn(codec->dev, "Invalid jack detect rate");
483 return DA7219_AAD_JACK_DET_RATE_256_512MS;
484 }
485}
486
487static enum da7219_aad_jack_rem_deb
488 da7219_aad_of_jack_rem_deb(struct snd_soc_codec *codec, u32 val)
489{
490 switch (val) {
491 case 1:
492 return DA7219_AAD_JACK_REM_DEB_1MS;
493 case 5:
494 return DA7219_AAD_JACK_REM_DEB_5MS;
495 case 10:
496 return DA7219_AAD_JACK_REM_DEB_10MS;
497 case 20:
498 return DA7219_AAD_JACK_REM_DEB_20MS;
499 default:
500 dev_warn(codec->dev, "Invalid jack removal debounce");
501 return DA7219_AAD_JACK_REM_DEB_1MS;
502 }
503}
504
505static enum da7219_aad_btn_avg
506 da7219_aad_of_btn_avg(struct snd_soc_codec *codec, u32 val)
507{
508 switch (val) {
509 case 1:
510 return DA7219_AAD_BTN_AVG_1;
511 case 2:
512 return DA7219_AAD_BTN_AVG_2;
513 case 4:
514 return DA7219_AAD_BTN_AVG_4;
515 case 8:
516 return DA7219_AAD_BTN_AVG_8;
517 default:
518 dev_warn(codec->dev, "Invalid button average value");
519 return DA7219_AAD_BTN_AVG_2;
520 }
521}
522
523static enum da7219_aad_adc_1bit_rpt
524 da7219_aad_of_adc_1bit_rpt(struct snd_soc_codec *codec, u32 val)
525{
526 switch (val) {
527 case 1:
528 return DA7219_AAD_ADC_1BIT_RPT_1;
529 case 2:
530 return DA7219_AAD_ADC_1BIT_RPT_2;
531 case 4:
532 return DA7219_AAD_ADC_1BIT_RPT_4;
533 case 8:
534 return DA7219_AAD_ADC_1BIT_RPT_8;
535 default:
536 dev_warn(codec->dev, "Invalid ADC 1-bit repeat value");
537 return DA7219_AAD_ADC_1BIT_RPT_1;
538 }
539}
540
541static struct da7219_aad_pdata *da7219_aad_of_to_pdata(struct snd_soc_codec *codec)
542{
543 struct device_node *np = codec->dev->of_node;
544 struct device_node *aad_np = of_find_node_by_name(np, "da7219_aad");
545 struct da7219_aad_pdata *aad_pdata;
546 const char *of_str;
547 u32 of_val32;
548
549 if (!aad_np)
550 return NULL;
551
552 aad_pdata = devm_kzalloc(codec->dev, sizeof(*aad_pdata), GFP_KERNEL);
553 if (!aad_pdata)
554 goto out;
555
556 aad_pdata->irq = irq_of_parse_and_map(np, 0);
557
558 if (of_property_read_u32(aad_np, "dlg,micbias-pulse-lvl",
559 &of_val32) >= 0)
560 aad_pdata->micbias_pulse_lvl =
561 da7219_aad_of_micbias_pulse_lvl(codec, of_val32);
562 else
563 aad_pdata->micbias_pulse_lvl = DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
564
565 if (of_property_read_u32(aad_np, "dlg,micbias-pulse-time",
566 &of_val32) >= 0)
567 aad_pdata->micbias_pulse_time = of_val32;
568
569 if (of_property_read_u32(aad_np, "dlg,btn-cfg", &of_val32) >= 0)
570 aad_pdata->btn_cfg = da7219_aad_of_btn_cfg(codec, of_val32);
571 else
572 aad_pdata->btn_cfg = DA7219_AAD_BTN_CFG_10MS;
573
574 if (of_property_read_u32(aad_np, "dlg,mic-det-thr", &of_val32) >= 0)
575 aad_pdata->mic_det_thr =
576 da7219_aad_of_mic_det_thr(codec, of_val32);
577 else
578 aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_500_OHMS;
579
580 if (of_property_read_u32(aad_np, "dlg,jack-ins-deb", &of_val32) >= 0)
581 aad_pdata->jack_ins_deb =
582 da7219_aad_of_jack_ins_deb(codec, of_val32);
583 else
584 aad_pdata->jack_ins_deb = DA7219_AAD_JACK_INS_DEB_20MS;
585
586 if (!of_property_read_string(aad_np, "dlg,jack-det-rate", &of_str))
587 aad_pdata->jack_det_rate =
588 da7219_aad_of_jack_det_rate(codec, of_str);
589 else
590 aad_pdata->jack_det_rate = DA7219_AAD_JACK_DET_RATE_256_512MS;
591
592 if (of_property_read_u32(aad_np, "dlg,jack-rem-deb", &of_val32) >= 0)
593 aad_pdata->jack_rem_deb =
594 da7219_aad_of_jack_rem_deb(codec, of_val32);
595 else
596 aad_pdata->jack_rem_deb = DA7219_AAD_JACK_REM_DEB_1MS;
597
598 if (of_property_read_u32(aad_np, "dlg,a-d-btn-thr", &of_val32) >= 0)
599 aad_pdata->a_d_btn_thr = (u8) of_val32;
600 else
601 aad_pdata->a_d_btn_thr = 0xA;
602
603 if (of_property_read_u32(aad_np, "dlg,d-b-btn-thr", &of_val32) >= 0)
604 aad_pdata->d_b_btn_thr = (u8) of_val32;
605 else
606 aad_pdata->d_b_btn_thr = 0x16;
607
608 if (of_property_read_u32(aad_np, "dlg,b-c-btn-thr", &of_val32) >= 0)
609 aad_pdata->b_c_btn_thr = (u8) of_val32;
610 else
611 aad_pdata->b_c_btn_thr = 0x21;
612
613 if (of_property_read_u32(aad_np, "dlg,c-mic-btn-thr", &of_val32) >= 0)
614 aad_pdata->c_mic_btn_thr = (u8) of_val32;
615 else
616 aad_pdata->c_mic_btn_thr = 0x3E;
617
618 if (of_property_read_u32(aad_np, "dlg,btn-avg", &of_val32) >= 0)
619 aad_pdata->btn_avg = da7219_aad_of_btn_avg(codec, of_val32);
620 else
621 aad_pdata->btn_avg = DA7219_AAD_BTN_AVG_2;
622
623 if (of_property_read_u32(aad_np, "dlg,adc-1bit-rpt", &of_val32) >= 0)
624 aad_pdata->adc_1bit_rpt =
625 da7219_aad_of_adc_1bit_rpt(codec, of_val32);
626 else
627 aad_pdata->adc_1bit_rpt = DA7219_AAD_ADC_1BIT_RPT_1;
628
629out:
630 of_node_put(aad_np);
631
632 return aad_pdata;
633}
634
635static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
636{
637 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
638 struct da7219_aad_priv *da7219_aad = da7219->aad;
639 struct da7219_pdata *pdata = da7219->pdata;
640
641 if ((pdata) && (pdata->aad_pdata)) {
642 struct da7219_aad_pdata *aad_pdata = pdata->aad_pdata;
643 u8 cfg, mask;
644
645 da7219_aad->irq = aad_pdata->irq;
646
647 switch (aad_pdata->micbias_pulse_lvl) {
648 case DA7219_AAD_MICBIAS_PULSE_LVL_2_8V:
649 case DA7219_AAD_MICBIAS_PULSE_LVL_2_9V:
650 da7219_aad->micbias_pulse_lvl =
651 (aad_pdata->micbias_pulse_lvl <<
652 DA7219_MICBIAS1_LEVEL_SHIFT);
653 break;
654 default:
655 break;
656 }
657
658 da7219_aad->micbias_pulse_time = aad_pdata->micbias_pulse_time;
659
660 switch (aad_pdata->btn_cfg) {
661 case DA7219_AAD_BTN_CFG_2MS:
662 case DA7219_AAD_BTN_CFG_5MS:
663 case DA7219_AAD_BTN_CFG_10MS:
664 case DA7219_AAD_BTN_CFG_50MS:
665 case DA7219_AAD_BTN_CFG_100MS:
666 case DA7219_AAD_BTN_CFG_200MS:
667 case DA7219_AAD_BTN_CFG_500MS:
668 da7219_aad->btn_cfg = (aad_pdata->btn_cfg <<
669 DA7219_BUTTON_CONFIG_SHIFT);
670 }
671
672 cfg = 0;
673 mask = 0;
674 switch (aad_pdata->mic_det_thr) {
675 case DA7219_AAD_MIC_DET_THR_200_OHMS:
676 case DA7219_AAD_MIC_DET_THR_500_OHMS:
677 case DA7219_AAD_MIC_DET_THR_750_OHMS:
678 case DA7219_AAD_MIC_DET_THR_1000_OHMS:
679 cfg |= (aad_pdata->mic_det_thr <<
680 DA7219_MIC_DET_THRESH_SHIFT);
681 mask |= DA7219_MIC_DET_THRESH_MASK;
682 }
683 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1, mask, cfg);
684
685 cfg = 0;
686 mask = 0;
687 switch (aad_pdata->jack_ins_deb) {
688 case DA7219_AAD_JACK_INS_DEB_5MS:
689 case DA7219_AAD_JACK_INS_DEB_10MS:
690 case DA7219_AAD_JACK_INS_DEB_20MS:
691 case DA7219_AAD_JACK_INS_DEB_50MS:
692 case DA7219_AAD_JACK_INS_DEB_100MS:
693 case DA7219_AAD_JACK_INS_DEB_200MS:
694 case DA7219_AAD_JACK_INS_DEB_500MS:
695 case DA7219_AAD_JACK_INS_DEB_1S:
696 cfg |= (aad_pdata->jack_ins_deb <<
697 DA7219_JACKDET_DEBOUNCE_SHIFT);
698 mask |= DA7219_JACKDET_DEBOUNCE_MASK;
699 }
700 switch (aad_pdata->jack_det_rate) {
701 case DA7219_AAD_JACK_DET_RATE_32_64MS:
702 case DA7219_AAD_JACK_DET_RATE_64_128MS:
703 case DA7219_AAD_JACK_DET_RATE_128_256MS:
704 case DA7219_AAD_JACK_DET_RATE_256_512MS:
705 cfg |= (aad_pdata->jack_det_rate <<
706 DA7219_JACK_DETECT_RATE_SHIFT);
707 mask |= DA7219_JACK_DETECT_RATE_MASK;
708 }
709 switch (aad_pdata->jack_rem_deb) {
710 case DA7219_AAD_JACK_REM_DEB_1MS:
711 case DA7219_AAD_JACK_REM_DEB_5MS:
712 case DA7219_AAD_JACK_REM_DEB_10MS:
713 case DA7219_AAD_JACK_REM_DEB_20MS:
714 cfg |= (aad_pdata->jack_rem_deb <<
715 DA7219_JACKDET_REM_DEB_SHIFT);
716 mask |= DA7219_JACKDET_REM_DEB_MASK;
717 }
718 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_2, mask, cfg);
719
720 snd_soc_write(codec, DA7219_ACCDET_CONFIG_3,
721 aad_pdata->a_d_btn_thr);
722 snd_soc_write(codec, DA7219_ACCDET_CONFIG_4,
723 aad_pdata->d_b_btn_thr);
724 snd_soc_write(codec, DA7219_ACCDET_CONFIG_5,
725 aad_pdata->b_c_btn_thr);
726 snd_soc_write(codec, DA7219_ACCDET_CONFIG_6,
727 aad_pdata->c_mic_btn_thr);
728
729 cfg = 0;
730 mask = 0;
731 switch (aad_pdata->btn_avg) {
732 case DA7219_AAD_BTN_AVG_1:
733 case DA7219_AAD_BTN_AVG_2:
734 case DA7219_AAD_BTN_AVG_4:
735 case DA7219_AAD_BTN_AVG_8:
736 cfg |= (aad_pdata->btn_avg <<
737 DA7219_BUTTON_AVERAGE_SHIFT);
738 mask |= DA7219_BUTTON_AVERAGE_MASK;
739 }
740 switch (aad_pdata->adc_1bit_rpt) {
741 case DA7219_AAD_ADC_1BIT_RPT_1:
742 case DA7219_AAD_ADC_1BIT_RPT_2:
743 case DA7219_AAD_ADC_1BIT_RPT_4:
744 case DA7219_AAD_ADC_1BIT_RPT_8:
745 cfg |= (aad_pdata->adc_1bit_rpt <<
746 DA7219_ADC_1_BIT_REPEAT_SHIFT);
747 mask |= DA7219_ADC_1_BIT_REPEAT_MASK;
748 }
749 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_7, mask, cfg);
750 }
751}
752
753
754/*
755 * Init/Exit
756 */
757
758int da7219_aad_init(struct snd_soc_codec *codec)
759{
760 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
761 struct da7219_aad_priv *da7219_aad;
762 u8 mask[DA7219_AAD_IRQ_REG_MAX];
763 int ret;
764
765 da7219_aad = devm_kzalloc(codec->dev, sizeof(*da7219_aad), GFP_KERNEL);
766 if (!da7219_aad)
767 return -ENOMEM;
768
769 da7219->aad = da7219_aad;
770 da7219_aad->codec = codec;
771
772 /* Handle any DT/platform data */
773 if ((codec->dev->of_node) && (da7219->pdata))
774 da7219->pdata->aad_pdata = da7219_aad_of_to_pdata(codec);
775
776 da7219_aad_handle_pdata(codec);
777
778 /* Disable button detection */
779 snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
780 DA7219_BUTTON_CONFIG_MASK, 0);
781
782 INIT_WORK(&da7219_aad->btn_det_work, da7219_aad_btn_det_work);
783 INIT_WORK(&da7219_aad->hptest_work, da7219_aad_hptest_work);
784
785 ret = request_threaded_irq(da7219_aad->irq, NULL,
786 da7219_aad_irq_thread,
787 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
788 "da7219-aad", da7219_aad);
789 if (ret) {
790 dev_err(codec->dev, "Failed to request IRQ: %d\n", ret);
791 return ret;
792 }
793
794 /* Unmask AAD IRQs */
795 memset(mask, 0, DA7219_AAD_IRQ_REG_MAX);
796 regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_MASK_A,
797 &mask, DA7219_AAD_IRQ_REG_MAX);
798
799 return 0;
800}
801EXPORT_SYMBOL_GPL(da7219_aad_init);
802
803void da7219_aad_exit(struct snd_soc_codec *codec)
804{
805 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
806 struct da7219_aad_priv *da7219_aad = da7219->aad;
807 u8 mask[DA7219_AAD_IRQ_REG_MAX];
808
809 /* Mask off AAD IRQs */
810 memset(mask, DA7219_BYTE_MASK, DA7219_AAD_IRQ_REG_MAX);
811 regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_MASK_A,
812 mask, DA7219_AAD_IRQ_REG_MAX);
813
814 free_irq(da7219_aad->irq, da7219_aad);
815
816 cancel_work_sync(&da7219_aad->btn_det_work);
817 cancel_work_sync(&da7219_aad->hptest_work);
818}
819EXPORT_SYMBOL_GPL(da7219_aad_exit);
820
821MODULE_DESCRIPTION("ASoC DA7219 AAD Driver");
822MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
823MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/da7219-aad.h b/sound/soc/codecs/da7219-aad.h
new file mode 100644
index 000000000000..4fccf677cd06
--- /dev/null
+++ b/sound/soc/codecs/da7219-aad.h
@@ -0,0 +1,212 @@
1/*
2 * da7219-aad.h - DA7322 ASoC AAD Driver
3 *
4 * Copyright (c) 2015 Dialog Semiconductor Ltd.
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#ifndef __DA7219_AAD_H
15#define __DA7219_AAD_H
16
17#include <linux/timer.h>
18#include <sound/soc.h>
19#include <sound/jack.h>
20#include <sound/da7219-aad.h>
21
22/*
23 * Registers
24 */
25
26#define DA7219_ACCDET_STATUS_A 0xC0
27#define DA7219_ACCDET_STATUS_B 0xC1
28#define DA7219_ACCDET_IRQ_EVENT_A 0xC2
29#define DA7219_ACCDET_IRQ_EVENT_B 0xC3
30#define DA7219_ACCDET_IRQ_MASK_A 0xC4
31#define DA7219_ACCDET_IRQ_MASK_B 0xC5
32#define DA7219_ACCDET_CONFIG_1 0xC6
33#define DA7219_ACCDET_CONFIG_2 0xC7
34#define DA7219_ACCDET_CONFIG_3 0xC8
35#define DA7219_ACCDET_CONFIG_4 0xC9
36#define DA7219_ACCDET_CONFIG_5 0xCA
37#define DA7219_ACCDET_CONFIG_6 0xCB
38#define DA7219_ACCDET_CONFIG_7 0xCC
39#define DA7219_ACCDET_CONFIG_8 0xCD
40
41
42/*
43 * Bit Fields
44 */
45
46/* DA7219_ACCDET_STATUS_A = 0xC0 */
47#define DA7219_JACK_INSERTION_STS_SHIFT 0
48#define DA7219_JACK_INSERTION_STS_MASK (0x1 << 0)
49#define DA7219_JACK_TYPE_STS_SHIFT 1
50#define DA7219_JACK_TYPE_STS_MASK (0x1 << 1)
51#define DA7219_JACK_PIN_ORDER_STS_SHIFT 2
52#define DA7219_JACK_PIN_ORDER_STS_MASK (0x1 << 2)
53#define DA7219_MICBIAS_UP_STS_SHIFT 3
54#define DA7219_MICBIAS_UP_STS_MASK (0x1 << 3)
55
56/* DA7219_ACCDET_STATUS_B = 0xC1 */
57#define DA7219_BUTTON_TYPE_STS_SHIFT 0
58#define DA7219_BUTTON_TYPE_STS_MASK (0xFF << 0)
59
60/* DA7219_ACCDET_IRQ_EVENT_A = 0xC2 */
61#define DA7219_E_JACK_INSERTED_SHIFT 0
62#define DA7219_E_JACK_INSERTED_MASK (0x1 << 0)
63#define DA7219_E_JACK_REMOVED_SHIFT 1
64#define DA7219_E_JACK_REMOVED_MASK (0x1 << 1)
65#define DA7219_E_JACK_DETECT_COMPLETE_SHIFT 2
66#define DA7219_E_JACK_DETECT_COMPLETE_MASK (0x1 << 2)
67
68/* DA7219_ACCDET_IRQ_EVENT_B = 0xC3 */
69#define DA7219_E_BUTTON_A_PRESSED_SHIFT 0
70#define DA7219_E_BUTTON_A_PRESSED_MASK (0x1 << 0)
71#define DA7219_E_BUTTON_B_PRESSED_SHIFT 1
72#define DA7219_E_BUTTON_B_PRESSED_MASK (0x1 << 1)
73#define DA7219_E_BUTTON_C_PRESSED_SHIFT 2
74#define DA7219_E_BUTTON_C_PRESSED_MASK (0x1 << 2)
75#define DA7219_E_BUTTON_D_PRESSED_SHIFT 3
76#define DA7219_E_BUTTON_D_PRESSED_MASK (0x1 << 3)
77#define DA7219_E_BUTTON_D_RELEASED_SHIFT 4
78#define DA7219_E_BUTTON_D_RELEASED_MASK (0x1 << 4)
79#define DA7219_E_BUTTON_C_RELEASED_SHIFT 5
80#define DA7219_E_BUTTON_C_RELEASED_MASK (0x1 << 5)
81#define DA7219_E_BUTTON_B_RELEASED_SHIFT 6
82#define DA7219_E_BUTTON_B_RELEASED_MASK (0x1 << 6)
83#define DA7219_E_BUTTON_A_RELEASED_SHIFT 7
84#define DA7219_E_BUTTON_A_RELEASED_MASK (0x1 << 7)
85
86/* DA7219_ACCDET_IRQ_MASK_A = 0xC4 */
87#define DA7219_M_JACK_INSERTED_SHIFT 0
88#define DA7219_M_JACK_INSERTED_MASK (0x1 << 0)
89#define DA7219_M_JACK_REMOVED_SHIFT 1
90#define DA7219_M_JACK_REMOVED_MASK (0x1 << 1)
91#define DA7219_M_JACK_DETECT_COMPLETE_SHIFT 2
92#define DA7219_M_JACK_DETECT_COMPLETE_MASK (0x1 << 2)
93
94/* DA7219_ACCDET_IRQ_MASK_B = 0xC5 */
95#define DA7219_M_BUTTON_A_PRESSED_SHIFT 0
96#define DA7219_M_BUTTON_A_PRESSED_MASK (0x1 << 0)
97#define DA7219_M_BUTTON_B_PRESSED_SHIFT 1
98#define DA7219_M_BUTTON_B_PRESSED_MASK (0x1 << 1)
99#define DA7219_M_BUTTON_C_PRESSED_SHIFT 2
100#define DA7219_M_BUTTON_C_PRESSED_MASK (0x1 << 2)
101#define DA7219_M_BUTTON_D_PRESSED_SHIFT 3
102#define DA7219_M_BUTTON_D_PRESSED_MASK (0x1 << 3)
103#define DA7219_M_BUTTON_D_RELEASED_SHIFT 4
104#define DA7219_M_BUTTON_D_RELEASED_MASK (0x1 << 4)
105#define DA7219_M_BUTTON_C_RELEASED_SHIFT 5
106#define DA7219_M_BUTTON_C_RELEASED_MASK (0x1 << 5)
107#define DA7219_M_BUTTON_B_RELEASED_SHIFT 6
108#define DA7219_M_BUTTON_B_RELEASED_MASK (0x1 << 6)
109#define DA7219_M_BUTTON_A_RELEASED_SHIFT 7
110#define DA7219_M_BUTTON_A_RELEASED_MASK (0x1 << 7)
111
112/* DA7219_ACCDET_CONFIG_1 = 0xC6 */
113#define DA7219_ACCDET_EN_SHIFT 0
114#define DA7219_ACCDET_EN_MASK (0x1 << 0)
115#define DA7219_BUTTON_CONFIG_SHIFT 1
116#define DA7219_BUTTON_CONFIG_MASK (0x7 << 1)
117#define DA7219_MIC_DET_THRESH_SHIFT 4
118#define DA7219_MIC_DET_THRESH_MASK (0x3 << 4)
119#define DA7219_JACK_TYPE_DET_EN_SHIFT 6
120#define DA7219_JACK_TYPE_DET_EN_MASK (0x1 << 6)
121#define DA7219_PIN_ORDER_DET_EN_SHIFT 7
122#define DA7219_PIN_ORDER_DET_EN_MASK (0x1 << 7)
123
124/* DA7219_ACCDET_CONFIG_2 = 0xC7 */
125#define DA7219_ACCDET_PAUSE_SHIFT 0
126#define DA7219_ACCDET_PAUSE_MASK (0x1 << 0)
127#define DA7219_JACKDET_DEBOUNCE_SHIFT 1
128#define DA7219_JACKDET_DEBOUNCE_MASK (0x7 << 1)
129#define DA7219_JACK_DETECT_RATE_SHIFT 4
130#define DA7219_JACK_DETECT_RATE_MASK (0x3 << 4)
131#define DA7219_JACKDET_REM_DEB_SHIFT 6
132#define DA7219_JACKDET_REM_DEB_MASK (0x3 << 6)
133
134/* DA7219_ACCDET_CONFIG_3 = 0xC8 */
135#define DA7219_A_D_BUTTON_THRESH_SHIFT 0
136#define DA7219_A_D_BUTTON_THRESH_MASK (0xFF << 0)
137
138/* DA7219_ACCDET_CONFIG_4 = 0xC9 */
139#define DA7219_D_B_BUTTON_THRESH_SHIFT 0
140#define DA7219_D_B_BUTTON_THRESH_MASK (0xFF << 0)
141
142/* DA7219_ACCDET_CONFIG_5 = 0xCA */
143#define DA7219_B_C_BUTTON_THRESH_SHIFT 0
144#define DA7219_B_C_BUTTON_THRESH_MASK (0xFF << 0)
145
146/* DA7219_ACCDET_CONFIG_6 = 0xCB */
147#define DA7219_C_MIC_BUTTON_THRESH_SHIFT 0
148#define DA7219_C_MIC_BUTTON_THRESH_MASK (0xFF << 0)
149
150/* DA7219_ACCDET_CONFIG_7 = 0xCC */
151#define DA7219_BUTTON_AVERAGE_SHIFT 0
152#define DA7219_BUTTON_AVERAGE_MASK (0x3 << 0)
153#define DA7219_ADC_1_BIT_REPEAT_SHIFT 2
154#define DA7219_ADC_1_BIT_REPEAT_MASK (0x3 << 2)
155#define DA7219_PIN_ORDER_FORCE_SHIFT 4
156#define DA7219_PIN_ORDER_FORCE_MASK (0x1 << 4)
157#define DA7219_JACK_TYPE_FORCE_SHIFT 5
158#define DA7219_JACK_TYPE_FORCE_MASK (0x1 << 5)
159
160/* DA7219_ACCDET_CONFIG_8 = 0xCD */
161#define DA7219_HPTEST_EN_SHIFT 0
162#define DA7219_HPTEST_EN_MASK (0x1 << 0)
163#define DA7219_HPTEST_RES_SEL_SHIFT 1
164#define DA7219_HPTEST_RES_SEL_MASK (0x3 << 1)
165#define DA7219_HPTEST_RES_SEL_1KOHMS (0x0 << 1)
166#define DA7219_HPTEST_COMP_SHIFT 4
167#define DA7219_HPTEST_COMP_MASK (0x1 << 4)
168
169
170#define DA7219_AAD_MAX_BUTTONS 4
171#define DA7219_AAD_REPORT_ALL_MASK (SND_JACK_MECHANICAL | \
172 SND_JACK_HEADSET | SND_JACK_LINEOUT | \
173 SND_JACK_BTN_0 | SND_JACK_BTN_1 | \
174 SND_JACK_BTN_2 | SND_JACK_BTN_3)
175
176#define DA7219_AAD_MICBIAS_CHK_DELAY 10
177#define DA7219_AAD_MICBIAS_CHK_RETRIES 5
178
179#define DA7219_AAD_HPTEST_RAMP_FREQ 0x28
180#define DA7219_AAD_HPTEST_PERIOD 65
181
182enum da7219_aad_event_regs {
183 DA7219_AAD_IRQ_REG_A = 0,
184 DA7219_AAD_IRQ_REG_B,
185 DA7219_AAD_IRQ_REG_MAX,
186};
187
188/* Private data */
189struct da7219_aad_priv {
190 struct snd_soc_codec *codec;
191 int irq;
192
193 u8 micbias_pulse_lvl;
194 u32 micbias_pulse_time;
195
196 u8 btn_cfg;
197
198 struct work_struct btn_det_work;
199 struct work_struct hptest_work;
200
201 struct snd_soc_jack *jack;
202 bool jack_inserted;
203};
204
205/* AAD control */
206void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
207
208/* Init/Exit */
209int da7219_aad_init(struct snd_soc_codec *codec);
210void da7219_aad_exit(struct snd_soc_codec *codec);
211
212#endif /* __DA7219_AAD_H */
diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c
new file mode 100644
index 000000000000..f238c1e8a69c
--- /dev/null
+++ b/sound/soc/codecs/da7219.c
@@ -0,0 +1,1955 @@
1/*
2 * da7219.c - DA7219 ALSA SoC Codec Driver
3 *
4 * Copyright (c) 2015 Dialog Semiconductor
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/clk.h>
15#include <linux/i2c.h>
16#include <linux/of_device.h>
17#include <linux/regmap.h>
18#include <linux/slab.h>
19#include <linux/pm.h>
20#include <linux/module.h>
21#include <linux/delay.h>
22#include <linux/regulator/consumer.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/tlv.h>
29#include <asm/div64.h>
30
31#include <sound/da7219.h>
32#include "da7219.h"
33#include "da7219-aad.h"
34
35
36/*
37 * TLVs and Enums
38 */
39
40/* Input TLVs */
41static const DECLARE_TLV_DB_SCALE(da7219_mic_gain_tlv, -600, 600, 0);
42static const DECLARE_TLV_DB_SCALE(da7219_mixin_gain_tlv, -450, 150, 0);
43static const DECLARE_TLV_DB_SCALE(da7219_adc_dig_gain_tlv, -8325, 75, 0);
44static const DECLARE_TLV_DB_SCALE(da7219_alc_threshold_tlv, -9450, 150, 0);
45static const DECLARE_TLV_DB_SCALE(da7219_alc_gain_tlv, 0, 600, 0);
46static const DECLARE_TLV_DB_SCALE(da7219_alc_ana_gain_tlv, 0, 600, 0);
47static const DECLARE_TLV_DB_SCALE(da7219_sidetone_gain_tlv, -4200, 300, 0);
48static const DECLARE_TLV_DB_SCALE(da7219_tonegen_gain_tlv, -4500, 300, 0);
49
50/* Output TLVs */
51static const DECLARE_TLV_DB_SCALE(da7219_dac_eq_band_tlv, -1050, 150, 0);
52
53static const DECLARE_TLV_DB_RANGE(da7219_dac_dig_gain_tlv,
54 0x0, 0x07, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
55 /* -77.25dB to 12dB */
56 0x08, 0x7f, TLV_DB_SCALE_ITEM(-7725, 75, 0)
57);
58
59static const DECLARE_TLV_DB_SCALE(da7219_dac_ng_threshold_tlv, -10200, 600, 0);
60static const DECLARE_TLV_DB_SCALE(da7219_hp_gain_tlv, -5700, 100, 0);
61
62/* Input Enums */
63static const char * const da7219_alc_attack_rate_txt[] = {
64 "7.33/fs", "14.66/fs", "29.32/fs", "58.64/fs", "117.3/fs", "234.6/fs",
65 "469.1/fs", "938.2/fs", "1876/fs", "3753/fs", "7506/fs", "15012/fs",
66 "30024/fs"
67};
68
69static const struct soc_enum da7219_alc_attack_rate =
70 SOC_ENUM_SINGLE(DA7219_ALC_CTRL2, DA7219_ALC_ATTACK_SHIFT,
71 DA7219_ALC_ATTACK_MAX, da7219_alc_attack_rate_txt);
72
73static const char * const da7219_alc_release_rate_txt[] = {
74 "28.66/fs", "57.33/fs", "114.6/fs", "229.3/fs", "458.6/fs", "917.1/fs",
75 "1834/fs", "3668/fs", "7337/fs", "14674/fs", "29348/fs"
76};
77
78static const struct soc_enum da7219_alc_release_rate =
79 SOC_ENUM_SINGLE(DA7219_ALC_CTRL2, DA7219_ALC_RELEASE_SHIFT,
80 DA7219_ALC_RELEASE_MAX, da7219_alc_release_rate_txt);
81
82static const char * const da7219_alc_hold_time_txt[] = {
83 "62/fs", "124/fs", "248/fs", "496/fs", "992/fs", "1984/fs", "3968/fs",
84 "7936/fs", "15872/fs", "31744/fs", "63488/fs", "126976/fs",
85 "253952/fs", "507904/fs", "1015808/fs", "2031616/fs"
86};
87
88static const struct soc_enum da7219_alc_hold_time =
89 SOC_ENUM_SINGLE(DA7219_ALC_CTRL3, DA7219_ALC_HOLD_SHIFT,
90 DA7219_ALC_HOLD_MAX, da7219_alc_hold_time_txt);
91
92static const char * const da7219_alc_env_rate_txt[] = {
93 "1/4", "1/16", "1/256", "1/65536"
94};
95
96static const struct soc_enum da7219_alc_env_attack_rate =
97 SOC_ENUM_SINGLE(DA7219_ALC_CTRL3, DA7219_ALC_INTEG_ATTACK_SHIFT,
98 DA7219_ALC_INTEG_MAX, da7219_alc_env_rate_txt);
99
100static const struct soc_enum da7219_alc_env_release_rate =
101 SOC_ENUM_SINGLE(DA7219_ALC_CTRL3, DA7219_ALC_INTEG_RELEASE_SHIFT,
102 DA7219_ALC_INTEG_MAX, da7219_alc_env_rate_txt);
103
104static const char * const da7219_alc_anticlip_step_txt[] = {
105 "0.034dB/fs", "0.068dB/fs", "0.136dB/fs", "0.272dB/fs"
106};
107
108static const struct soc_enum da7219_alc_anticlip_step =
109 SOC_ENUM_SINGLE(DA7219_ALC_ANTICLIP_CTRL,
110 DA7219_ALC_ANTICLIP_STEP_SHIFT,
111 DA7219_ALC_ANTICLIP_STEP_MAX,
112 da7219_alc_anticlip_step_txt);
113
114/* Input/Output Enums */
115static const char * const da7219_gain_ramp_rate_txt[] = {
116 "Nominal Rate * 8", "Nominal Rate", "Nominal Rate / 8",
117 "Nominal Rate / 16"
118};
119
120static const struct soc_enum da7219_gain_ramp_rate =
121 SOC_ENUM_SINGLE(DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_SHIFT,
122 DA7219_GAIN_RAMP_RATE_MAX, da7219_gain_ramp_rate_txt);
123
124static const char * const da7219_hpf_mode_txt[] = {
125 "Disabled", "Audio", "Voice"
126};
127
128static const unsigned int da7219_hpf_mode_val[] = {
129 DA7219_HPF_DISABLED, DA7219_HPF_AUDIO_EN, DA7219_HPF_VOICE_EN,
130};
131
132static const struct soc_enum da7219_adc_hpf_mode =
133 SOC_VALUE_ENUM_SINGLE(DA7219_ADC_FILTERS1, DA7219_HPF_MODE_SHIFT,
134 DA7219_HPF_MODE_MASK, DA7219_HPF_MODE_MAX,
135 da7219_hpf_mode_txt, da7219_hpf_mode_val);
136
137static const struct soc_enum da7219_dac_hpf_mode =
138 SOC_VALUE_ENUM_SINGLE(DA7219_DAC_FILTERS1, DA7219_HPF_MODE_SHIFT,
139 DA7219_HPF_MODE_MASK, DA7219_HPF_MODE_MAX,
140 da7219_hpf_mode_txt, da7219_hpf_mode_val);
141
142static const char * const da7219_audio_hpf_corner_txt[] = {
143 "2Hz", "4Hz", "8Hz", "16Hz"
144};
145
146static const struct soc_enum da7219_adc_audio_hpf_corner =
147 SOC_ENUM_SINGLE(DA7219_ADC_FILTERS1,
148 DA7219_ADC_AUDIO_HPF_CORNER_SHIFT,
149 DA7219_AUDIO_HPF_CORNER_MAX,
150 da7219_audio_hpf_corner_txt);
151
152static const struct soc_enum da7219_dac_audio_hpf_corner =
153 SOC_ENUM_SINGLE(DA7219_DAC_FILTERS1,
154 DA7219_DAC_AUDIO_HPF_CORNER_SHIFT,
155 DA7219_AUDIO_HPF_CORNER_MAX,
156 da7219_audio_hpf_corner_txt);
157
158static const char * const da7219_voice_hpf_corner_txt[] = {
159 "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
160};
161
162static const struct soc_enum da7219_adc_voice_hpf_corner =
163 SOC_ENUM_SINGLE(DA7219_ADC_FILTERS1,
164 DA7219_ADC_VOICE_HPF_CORNER_SHIFT,
165 DA7219_VOICE_HPF_CORNER_MAX,
166 da7219_voice_hpf_corner_txt);
167
168static const struct soc_enum da7219_dac_voice_hpf_corner =
169 SOC_ENUM_SINGLE(DA7219_DAC_FILTERS1,
170 DA7219_DAC_VOICE_HPF_CORNER_SHIFT,
171 DA7219_VOICE_HPF_CORNER_MAX,
172 da7219_voice_hpf_corner_txt);
173
174static const char * const da7219_tonegen_dtmf_key_txt[] = {
175 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D",
176 "*", "#"
177};
178
179static const struct soc_enum da7219_tonegen_dtmf_key =
180 SOC_ENUM_SINGLE(DA7219_TONE_GEN_CFG1, DA7219_DTMF_REG_SHIFT,
181 DA7219_DTMF_REG_MAX, da7219_tonegen_dtmf_key_txt);
182
183static const char * const da7219_tonegen_swg_sel_txt[] = {
184 "Sum", "SWG1", "SWG2", "SWG1_1-Cos"
185};
186
187static const struct soc_enum da7219_tonegen_swg_sel =
188 SOC_ENUM_SINGLE(DA7219_TONE_GEN_CFG2, DA7219_SWG_SEL_SHIFT,
189 DA7219_SWG_SEL_MAX, da7219_tonegen_swg_sel_txt);
190
191/* Output Enums */
192static const char * const da7219_dac_softmute_rate_txt[] = {
193 "1 Sample", "2 Samples", "4 Samples", "8 Samples", "16 Samples",
194 "32 Samples", "64 Samples"
195};
196
197static const struct soc_enum da7219_dac_softmute_rate =
198 SOC_ENUM_SINGLE(DA7219_DAC_FILTERS5, DA7219_DAC_SOFTMUTE_RATE_SHIFT,
199 DA7219_DAC_SOFTMUTE_RATE_MAX,
200 da7219_dac_softmute_rate_txt);
201
202static const char * const da7219_dac_ng_setup_time_txt[] = {
203 "256 Samples", "512 Samples", "1024 Samples", "2048 Samples"
204};
205
206static const struct soc_enum da7219_dac_ng_setup_time =
207 SOC_ENUM_SINGLE(DA7219_DAC_NG_SETUP_TIME,
208 DA7219_DAC_NG_SETUP_TIME_SHIFT,
209 DA7219_DAC_NG_SETUP_TIME_MAX,
210 da7219_dac_ng_setup_time_txt);
211
212static const char * const da7219_dac_ng_rampup_txt[] = {
213 "0.22ms/dB", "0.0138ms/dB"
214};
215
216static const struct soc_enum da7219_dac_ng_rampup_rate =
217 SOC_ENUM_SINGLE(DA7219_DAC_NG_SETUP_TIME,
218 DA7219_DAC_NG_RAMPUP_RATE_SHIFT,
219 DA7219_DAC_NG_RAMP_RATE_MAX,
220 da7219_dac_ng_rampup_txt);
221
222static const char * const da7219_dac_ng_rampdown_txt[] = {
223 "0.88ms/dB", "14.08ms/dB"
224};
225
226static const struct soc_enum da7219_dac_ng_rampdown_rate =
227 SOC_ENUM_SINGLE(DA7219_DAC_NG_SETUP_TIME,
228 DA7219_DAC_NG_RAMPDN_RATE_SHIFT,
229 DA7219_DAC_NG_RAMP_RATE_MAX,
230 da7219_dac_ng_rampdown_txt);
231
232
233static const char * const da7219_cp_track_mode_txt[] = {
234 "Largest Volume", "DAC Volume", "Signal Magnitude"
235};
236
237static const unsigned int da7219_cp_track_mode_val[] = {
238 DA7219_CP_MCHANGE_LARGEST_VOL, DA7219_CP_MCHANGE_DAC_VOL,
239 DA7219_CP_MCHANGE_SIG_MAG
240};
241
242static const struct soc_enum da7219_cp_track_mode =
243 SOC_VALUE_ENUM_SINGLE(DA7219_CP_CTRL, DA7219_CP_MCHANGE_SHIFT,
244 DA7219_CP_MCHANGE_REL_MASK, DA7219_CP_MCHANGE_MAX,
245 da7219_cp_track_mode_txt,
246 da7219_cp_track_mode_val);
247
248
249/*
250 * Control Functions
251 */
252
253/* Locked Kcontrol calls */
254static int da7219_volsw_locked_get(struct snd_kcontrol *kcontrol,
255 struct snd_ctl_elem_value *ucontrol)
256{
257 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
258 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
259 int ret;
260
261 mutex_lock(&da7219->lock);
262 ret = snd_soc_get_volsw(kcontrol, ucontrol);
263 mutex_unlock(&da7219->lock);
264
265 return ret;
266}
267
268static int da7219_volsw_locked_put(struct snd_kcontrol *kcontrol,
269 struct snd_ctl_elem_value *ucontrol)
270{
271 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
272 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
273 int ret;
274
275 mutex_lock(&da7219->lock);
276 ret = snd_soc_put_volsw(kcontrol, ucontrol);
277 mutex_unlock(&da7219->lock);
278
279 return ret;
280}
281
282static int da7219_enum_locked_get(struct snd_kcontrol *kcontrol,
283 struct snd_ctl_elem_value *ucontrol)
284{
285 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
286 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
287 int ret;
288
289 mutex_lock(&da7219->lock);
290 ret = snd_soc_get_enum_double(kcontrol, ucontrol);
291 mutex_unlock(&da7219->lock);
292
293 return ret;
294}
295
296static int da7219_enum_locked_put(struct snd_kcontrol *kcontrol,
297 struct snd_ctl_elem_value *ucontrol)
298{
299 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
300 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
301 int ret;
302
303 mutex_lock(&da7219->lock);
304 ret = snd_soc_put_enum_double(kcontrol, ucontrol);
305 mutex_unlock(&da7219->lock);
306
307 return ret;
308}
309
310/* ALC */
311static void da7219_alc_calib(struct snd_soc_codec *codec)
312{
313 u8 mic_ctrl, mixin_ctrl, adc_ctrl, calib_ctrl;
314
315 /* Save current state of mic control register */
316 mic_ctrl = snd_soc_read(codec, DA7219_MIC_1_CTRL);
317
318 /* Save current state of input mixer control register */
319 mixin_ctrl = snd_soc_read(codec, DA7219_MIXIN_L_CTRL);
320
321 /* Save current state of input ADC control register */
322 adc_ctrl = snd_soc_read(codec, DA7219_ADC_L_CTRL);
323
324 /* Enable then Mute MIC PGAs */
325 snd_soc_update_bits(codec, DA7219_MIC_1_CTRL, DA7219_MIC_1_AMP_EN_MASK,
326 DA7219_MIC_1_AMP_EN_MASK);
327 snd_soc_update_bits(codec, DA7219_MIC_1_CTRL,
328 DA7219_MIC_1_AMP_MUTE_EN_MASK,
329 DA7219_MIC_1_AMP_MUTE_EN_MASK);
330
331 /* Enable input mixers unmuted */
332 snd_soc_update_bits(codec, DA7219_MIXIN_L_CTRL,
333 DA7219_MIXIN_L_AMP_EN_MASK |
334 DA7219_MIXIN_L_AMP_MUTE_EN_MASK,
335 DA7219_MIXIN_L_AMP_EN_MASK);
336
337 /* Enable input filters unmuted */
338 snd_soc_update_bits(codec, DA7219_ADC_L_CTRL,
339 DA7219_ADC_L_MUTE_EN_MASK | DA7219_ADC_L_EN_MASK,
340 DA7219_ADC_L_EN_MASK);
341
342 /* Perform auto calibration */
343 snd_soc_update_bits(codec, DA7219_ALC_CTRL1,
344 DA7219_ALC_AUTO_CALIB_EN_MASK,
345 DA7219_ALC_AUTO_CALIB_EN_MASK);
346 do {
347 calib_ctrl = snd_soc_read(codec, DA7219_ALC_CTRL1);
348 } while (calib_ctrl & DA7219_ALC_AUTO_CALIB_EN_MASK);
349
350 /* If auto calibration fails, disable DC offset, hybrid ALC */
351 if (calib_ctrl & DA7219_ALC_CALIB_OVERFLOW_MASK) {
352 dev_warn(codec->dev,
353 "ALC auto calibration failed with overflow\n");
354 snd_soc_update_bits(codec, DA7219_ALC_CTRL1,
355 DA7219_ALC_OFFSET_EN_MASK |
356 DA7219_ALC_SYNC_MODE_MASK, 0);
357 } else {
358 /* Enable DC offset cancellation, hybrid mode */
359 snd_soc_update_bits(codec, DA7219_ALC_CTRL1,
360 DA7219_ALC_OFFSET_EN_MASK |
361 DA7219_ALC_SYNC_MODE_MASK,
362 DA7219_ALC_OFFSET_EN_MASK |
363 DA7219_ALC_SYNC_MODE_MASK);
364 }
365
366 /* Restore input filter control register to original state */
367 snd_soc_write(codec, DA7219_ADC_L_CTRL, adc_ctrl);
368
369 /* Restore input mixer control registers to original state */
370 snd_soc_write(codec, DA7219_MIXIN_L_CTRL, mixin_ctrl);
371
372 /* Restore MIC control registers to original states */
373 snd_soc_write(codec, DA7219_MIC_1_CTRL, mic_ctrl);
374}
375
376static int da7219_mixin_gain_put(struct snd_kcontrol *kcontrol,
377 struct snd_ctl_elem_value *ucontrol)
378{
379 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
380 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
381 int ret;
382
383 ret = snd_soc_put_volsw(kcontrol, ucontrol);
384
385 /*
386 * If ALC in operation and value of control has been updated,
387 * make sure calibrated offsets are updated.
388 */
389 if ((ret == 1) && (da7219->alc_en))
390 da7219_alc_calib(codec);
391
392 return ret;
393}
394
395static int da7219_alc_sw_put(struct snd_kcontrol *kcontrol,
396 struct snd_ctl_elem_value *ucontrol)
397{
398 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
399 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
400
401
402 /* Force ALC offset calibration if enabling ALC */
403 if ((ucontrol->value.integer.value[0]) && (!da7219->alc_en)) {
404 da7219_alc_calib(codec);
405 da7219->alc_en = true;
406 } else {
407 da7219->alc_en = false;
408 }
409
410 return snd_soc_put_volsw(kcontrol, ucontrol);
411}
412
413/* ToneGen */
414static int da7219_tonegen_freq_get(struct snd_kcontrol *kcontrol,
415 struct snd_ctl_elem_value *ucontrol)
416{
417 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
418 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
419 struct soc_mixer_control *mixer_ctrl =
420 (struct soc_mixer_control *) kcontrol->private_value;
421 unsigned int reg = mixer_ctrl->reg;
422 u16 val;
423 int ret;
424
425 mutex_lock(&da7219->lock);
426 ret = regmap_raw_read(da7219->regmap, reg, &val, sizeof(val));
427 mutex_unlock(&da7219->lock);
428
429 if (ret)
430 return ret;
431
432 /*
433 * Frequency value spans two 8-bit registers, lower then upper byte.
434 * Therefore we need to convert to host endianness here.
435 */
436 ucontrol->value.integer.value[0] = le16_to_cpu(val);
437
438 return 0;
439}
440
441static int da7219_tonegen_freq_put(struct snd_kcontrol *kcontrol,
442 struct snd_ctl_elem_value *ucontrol)
443{
444 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
445 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
446 struct soc_mixer_control *mixer_ctrl =
447 (struct soc_mixer_control *) kcontrol->private_value;
448 unsigned int reg = mixer_ctrl->reg;
449 u16 val;
450 int ret;
451
452 /*
453 * Frequency value spans two 8-bit registers, lower then upper byte.
454 * Therefore we need to convert to little endian here to align with
455 * HW registers.
456 */
457 val = cpu_to_le16(ucontrol->value.integer.value[0]);
458
459 mutex_lock(&da7219->lock);
460 ret = regmap_raw_write(da7219->regmap, reg, &val, sizeof(val));
461 mutex_unlock(&da7219->lock);
462
463 return ret;
464}
465
466
467/*
468 * KControls
469 */
470
471static const struct snd_kcontrol_new da7219_snd_controls[] = {
472 /* Mics */
473 SOC_SINGLE_TLV("Mic Volume", DA7219_MIC_1_GAIN,
474 DA7219_MIC_1_AMP_GAIN_SHIFT, DA7219_MIC_1_AMP_GAIN_MAX,
475 DA7219_NO_INVERT, da7219_mic_gain_tlv),
476 SOC_SINGLE("Mic Switch", DA7219_MIC_1_CTRL,
477 DA7219_MIC_1_AMP_MUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX,
478 DA7219_INVERT),
479
480 /* Mixer Input */
481 SOC_SINGLE_EXT_TLV("Mixin Volume", DA7219_MIXIN_L_GAIN,
482 DA7219_MIXIN_L_AMP_GAIN_SHIFT,
483 DA7219_MIXIN_L_AMP_GAIN_MAX, DA7219_NO_INVERT,
484 snd_soc_get_volsw, da7219_mixin_gain_put,
485 da7219_mixin_gain_tlv),
486 SOC_SINGLE("Mixin Switch", DA7219_MIXIN_L_CTRL,
487 DA7219_MIXIN_L_AMP_MUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX,
488 DA7219_INVERT),
489 SOC_SINGLE("Mixin Gain Ramp Switch", DA7219_MIXIN_L_CTRL,
490 DA7219_MIXIN_L_AMP_RAMP_EN_SHIFT, DA7219_SWITCH_EN_MAX,
491 DA7219_NO_INVERT),
492 SOC_SINGLE("Mixin ZC Gain Switch", DA7219_MIXIN_L_CTRL,
493 DA7219_MIXIN_L_AMP_ZC_EN_SHIFT, DA7219_SWITCH_EN_MAX,
494 DA7219_NO_INVERT),
495
496 /* ADC */
497 SOC_SINGLE_TLV("Capture Digital Volume", DA7219_ADC_L_GAIN,
498 DA7219_ADC_L_DIGITAL_GAIN_SHIFT,
499 DA7219_ADC_L_DIGITAL_GAIN_MAX, DA7219_NO_INVERT,
500 da7219_adc_dig_gain_tlv),
501 SOC_SINGLE("Capture Digital Switch", DA7219_ADC_L_CTRL,
502 DA7219_ADC_L_MUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX,
503 DA7219_INVERT),
504 SOC_SINGLE("Capture Digital Gain Ramp Switch", DA7219_ADC_L_CTRL,
505 DA7219_ADC_L_RAMP_EN_SHIFT, DA7219_SWITCH_EN_MAX,
506 DA7219_NO_INVERT),
507
508 /* ALC */
509 SOC_ENUM("ALC Attack Rate", da7219_alc_attack_rate),
510 SOC_ENUM("ALC Release Rate", da7219_alc_release_rate),
511 SOC_ENUM("ALC Hold Time", da7219_alc_hold_time),
512 SOC_ENUM("ALC Envelope Attack Rate", da7219_alc_env_attack_rate),
513 SOC_ENUM("ALC Envelope Release Rate", da7219_alc_env_release_rate),
514 SOC_SINGLE_TLV("ALC Noise Threshold", DA7219_ALC_NOISE,
515 DA7219_ALC_NOISE_SHIFT, DA7219_ALC_THRESHOLD_MAX,
516 DA7219_INVERT, da7219_alc_threshold_tlv),
517 SOC_SINGLE_TLV("ALC Min Threshold", DA7219_ALC_TARGET_MIN,
518 DA7219_ALC_THRESHOLD_MIN_SHIFT, DA7219_ALC_THRESHOLD_MAX,
519 DA7219_INVERT, da7219_alc_threshold_tlv),
520 SOC_SINGLE_TLV("ALC Max Threshold", DA7219_ALC_TARGET_MAX,
521 DA7219_ALC_THRESHOLD_MAX_SHIFT, DA7219_ALC_THRESHOLD_MAX,
522 DA7219_INVERT, da7219_alc_threshold_tlv),
523 SOC_SINGLE_TLV("ALC Max Attenuation", DA7219_ALC_GAIN_LIMITS,
524 DA7219_ALC_ATTEN_MAX_SHIFT, DA7219_ALC_ATTEN_GAIN_MAX,
525 DA7219_NO_INVERT, da7219_alc_gain_tlv),
526 SOC_SINGLE_TLV("ALC Max Volume", DA7219_ALC_GAIN_LIMITS,
527 DA7219_ALC_GAIN_MAX_SHIFT, DA7219_ALC_ATTEN_GAIN_MAX,
528 DA7219_NO_INVERT, da7219_alc_gain_tlv),
529 SOC_SINGLE_RANGE_TLV("ALC Min Analog Volume", DA7219_ALC_ANA_GAIN_LIMITS,
530 DA7219_ALC_ANA_GAIN_MIN_SHIFT,
531 DA7219_ALC_ANA_GAIN_MIN, DA7219_ALC_ANA_GAIN_MAX,
532 DA7219_NO_INVERT, da7219_alc_ana_gain_tlv),
533 SOC_SINGLE_RANGE_TLV("ALC Max Analog Volume", DA7219_ALC_ANA_GAIN_LIMITS,
534 DA7219_ALC_ANA_GAIN_MAX_SHIFT,
535 DA7219_ALC_ANA_GAIN_MIN, DA7219_ALC_ANA_GAIN_MAX,
536 DA7219_NO_INVERT, da7219_alc_ana_gain_tlv),
537 SOC_ENUM("ALC Anticlip Step", da7219_alc_anticlip_step),
538 SOC_SINGLE("ALC Anticlip Switch", DA7219_ALC_ANTICLIP_CTRL,
539 DA7219_ALC_ANTIPCLIP_EN_SHIFT, DA7219_SWITCH_EN_MAX,
540 DA7219_NO_INVERT),
541 SOC_SINGLE_EXT("ALC Switch", DA7219_ALC_CTRL1, DA7219_ALC_EN_SHIFT,
542 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT,
543 snd_soc_get_volsw, da7219_alc_sw_put),
544
545 /* Input High-Pass Filters */
546 SOC_ENUM("ADC HPF Mode", da7219_adc_hpf_mode),
547 SOC_ENUM("ADC HPF Corner Audio", da7219_adc_audio_hpf_corner),
548 SOC_ENUM("ADC HPF Corner Voice", da7219_adc_voice_hpf_corner),
549
550 /* Sidetone Filter */
551 SOC_SINGLE_TLV("Sidetone Volume", DA7219_SIDETONE_GAIN,
552 DA7219_SIDETONE_GAIN_SHIFT, DA7219_SIDETONE_GAIN_MAX,
553 DA7219_NO_INVERT, da7219_sidetone_gain_tlv),
554 SOC_SINGLE("Sidetone Switch", DA7219_SIDETONE_CTRL,
555 DA7219_SIDETONE_MUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX,
556 DA7219_INVERT),
557
558 /* Tone Generator */
559 SOC_SINGLE_EXT_TLV("ToneGen Volume", DA7219_TONE_GEN_CFG2,
560 DA7219_TONE_GEN_GAIN_SHIFT, DA7219_TONE_GEN_GAIN_MAX,
561 DA7219_NO_INVERT, da7219_volsw_locked_get,
562 da7219_volsw_locked_put, da7219_tonegen_gain_tlv),
563 SOC_ENUM_EXT("ToneGen DTMF Key", da7219_tonegen_dtmf_key,
564 da7219_enum_locked_get, da7219_enum_locked_put),
565 SOC_SINGLE_EXT("ToneGen DTMF Switch", DA7219_TONE_GEN_CFG1,
566 DA7219_DTMF_EN_SHIFT, DA7219_SWITCH_EN_MAX,
567 DA7219_NO_INVERT, da7219_volsw_locked_get,
568 da7219_volsw_locked_put),
569 SOC_ENUM_EXT("ToneGen Sinewave Gen Type", da7219_tonegen_swg_sel,
570 da7219_enum_locked_get, da7219_enum_locked_put),
571 SOC_SINGLE_EXT("ToneGen Sinewave1 Freq", DA7219_TONE_GEN_FREQ1_L,
572 DA7219_FREQ1_L_SHIFT, DA7219_FREQ_MAX, DA7219_NO_INVERT,
573 da7219_tonegen_freq_get, da7219_tonegen_freq_put),
574 SOC_SINGLE_EXT("ToneGen Sinewave2 Freq", DA7219_TONE_GEN_FREQ2_L,
575 DA7219_FREQ2_L_SHIFT, DA7219_FREQ_MAX, DA7219_NO_INVERT,
576 da7219_tonegen_freq_get, da7219_tonegen_freq_put),
577 SOC_SINGLE_EXT("ToneGen On Time", DA7219_TONE_GEN_ON_PER,
578 DA7219_BEEP_ON_PER_SHIFT, DA7219_BEEP_ON_OFF_MAX,
579 DA7219_NO_INVERT, da7219_volsw_locked_get,
580 da7219_volsw_locked_put),
581 SOC_SINGLE("ToneGen Off Time", DA7219_TONE_GEN_OFF_PER,
582 DA7219_BEEP_OFF_PER_SHIFT, DA7219_BEEP_ON_OFF_MAX,
583 DA7219_NO_INVERT),
584
585 /* Gain ramping */
586 SOC_ENUM("Gain Ramp Rate", da7219_gain_ramp_rate),
587
588 /* DAC High-Pass Filter */
589 SOC_ENUM_EXT("DAC HPF Mode", da7219_dac_hpf_mode,
590 da7219_enum_locked_get, da7219_enum_locked_put),
591 SOC_ENUM("DAC HPF Corner Audio", da7219_dac_audio_hpf_corner),
592 SOC_ENUM("DAC HPF Corner Voice", da7219_dac_voice_hpf_corner),
593
594 /* DAC 5-Band Equaliser */
595 SOC_SINGLE_TLV("DAC EQ Band1 Volume", DA7219_DAC_FILTERS2,
596 DA7219_DAC_EQ_BAND1_SHIFT, DA7219_DAC_EQ_BAND_MAX,
597 DA7219_NO_INVERT, da7219_dac_eq_band_tlv),
598 SOC_SINGLE_TLV("DAC EQ Band2 Volume", DA7219_DAC_FILTERS2,
599 DA7219_DAC_EQ_BAND2_SHIFT, DA7219_DAC_EQ_BAND_MAX,
600 DA7219_NO_INVERT, da7219_dac_eq_band_tlv),
601 SOC_SINGLE_TLV("DAC EQ Band3 Volume", DA7219_DAC_FILTERS3,
602 DA7219_DAC_EQ_BAND3_SHIFT, DA7219_DAC_EQ_BAND_MAX,
603 DA7219_NO_INVERT, da7219_dac_eq_band_tlv),
604 SOC_SINGLE_TLV("DAC EQ Band4 Volume", DA7219_DAC_FILTERS3,
605 DA7219_DAC_EQ_BAND4_SHIFT, DA7219_DAC_EQ_BAND_MAX,
606 DA7219_NO_INVERT, da7219_dac_eq_band_tlv),
607 SOC_SINGLE_TLV("DAC EQ Band5 Volume", DA7219_DAC_FILTERS4,
608 DA7219_DAC_EQ_BAND5_SHIFT, DA7219_DAC_EQ_BAND_MAX,
609 DA7219_NO_INVERT, da7219_dac_eq_band_tlv),
610 SOC_SINGLE_EXT("DAC EQ Switch", DA7219_DAC_FILTERS4,
611 DA7219_DAC_EQ_EN_SHIFT, DA7219_SWITCH_EN_MAX,
612 DA7219_NO_INVERT, da7219_volsw_locked_get,
613 da7219_volsw_locked_put),
614
615 /* DAC Softmute */
616 SOC_ENUM("DAC Soft Mute Rate", da7219_dac_softmute_rate),
617 SOC_SINGLE_EXT("DAC Soft Mute Switch", DA7219_DAC_FILTERS5,
618 DA7219_DAC_SOFTMUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX,
619 DA7219_NO_INVERT, da7219_volsw_locked_get,
620 da7219_volsw_locked_put),
621
622 /* DAC Noise Gate */
623 SOC_ENUM("DAC NG Setup Time", da7219_dac_ng_setup_time),
624 SOC_ENUM("DAC NG Rampup Rate", da7219_dac_ng_rampup_rate),
625 SOC_ENUM("DAC NG Rampdown Rate", da7219_dac_ng_rampdown_rate),
626 SOC_SINGLE_TLV("DAC NG Off Threshold", DA7219_DAC_NG_OFF_THRESH,
627 DA7219_DAC_NG_OFF_THRESHOLD_SHIFT,
628 DA7219_DAC_NG_THRESHOLD_MAX, DA7219_NO_INVERT,
629 da7219_dac_ng_threshold_tlv),
630 SOC_SINGLE_TLV("DAC NG On Threshold", DA7219_DAC_NG_ON_THRESH,
631 DA7219_DAC_NG_ON_THRESHOLD_SHIFT,
632 DA7219_DAC_NG_THRESHOLD_MAX, DA7219_NO_INVERT,
633 da7219_dac_ng_threshold_tlv),
634 SOC_SINGLE("DAC NG Switch", DA7219_DAC_NG_CTRL, DA7219_DAC_NG_EN_SHIFT,
635 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT),
636
637 /* DACs */
638 SOC_DOUBLE_R_EXT_TLV("Playback Digital Volume", DA7219_DAC_L_GAIN,
639 DA7219_DAC_R_GAIN, DA7219_DAC_L_DIGITAL_GAIN_SHIFT,
640 DA7219_DAC_DIGITAL_GAIN_MAX, DA7219_NO_INVERT,
641 da7219_volsw_locked_get, da7219_volsw_locked_put,
642 da7219_dac_dig_gain_tlv),
643 SOC_DOUBLE_R_EXT("Playback Digital Switch", DA7219_DAC_L_CTRL,
644 DA7219_DAC_R_CTRL, DA7219_DAC_L_MUTE_EN_SHIFT,
645 DA7219_SWITCH_EN_MAX, DA7219_INVERT,
646 da7219_volsw_locked_get, da7219_volsw_locked_put),
647 SOC_DOUBLE_R("Playback Digital Gain Ramp Switch", DA7219_DAC_L_CTRL,
648 DA7219_DAC_R_CTRL, DA7219_DAC_L_RAMP_EN_SHIFT,
649 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT),
650
651 /* CP */
652 SOC_ENUM("Charge Pump Track Mode", da7219_cp_track_mode),
653 SOC_SINGLE("Charge Pump Threshold", DA7219_CP_VOL_THRESHOLD1,
654 DA7219_CP_THRESH_VDD2_SHIFT, DA7219_CP_THRESH_VDD2_MAX,
655 DA7219_NO_INVERT),
656
657 /* Headphones */
658 SOC_DOUBLE_R_EXT_TLV("Headphone Volume", DA7219_HP_L_GAIN,
659 DA7219_HP_R_GAIN, DA7219_HP_L_AMP_GAIN_SHIFT,
660 DA7219_HP_AMP_GAIN_MAX, DA7219_NO_INVERT,
661 da7219_volsw_locked_get, da7219_volsw_locked_put,
662 da7219_hp_gain_tlv),
663 SOC_DOUBLE_R_EXT("Headphone Switch", DA7219_HP_L_CTRL, DA7219_HP_R_CTRL,
664 DA7219_HP_L_AMP_MUTE_EN_SHIFT, DA7219_SWITCH_EN_MAX,
665 DA7219_INVERT, da7219_volsw_locked_get,
666 da7219_volsw_locked_put),
667 SOC_DOUBLE_R("Headphone Gain Ramp Switch", DA7219_HP_L_CTRL,
668 DA7219_HP_R_CTRL, DA7219_HP_L_AMP_RAMP_EN_SHIFT,
669 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT),
670 SOC_DOUBLE_R("Headphone ZC Gain Switch", DA7219_HP_L_CTRL,
671 DA7219_HP_R_CTRL, DA7219_HP_L_AMP_ZC_EN_SHIFT,
672 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT),
673};
674
675
676/*
677 * DAPM Mux Controls
678 */
679
680static const char * const da7219_out_sel_txt[] = {
681 "ADC", "Tone Generator", "DAIL", "DAIR"
682};
683
684static const struct soc_enum da7219_out_dail_sel =
685 SOC_ENUM_SINGLE(DA7219_DIG_ROUTING_DAI,
686 DA7219_DAI_L_SRC_SHIFT,
687 DA7219_OUT_SRC_MAX,
688 da7219_out_sel_txt);
689
690static const struct snd_kcontrol_new da7219_out_dail_sel_mux =
691 SOC_DAPM_ENUM("Out DAIL Mux", da7219_out_dail_sel);
692
693static const struct soc_enum da7219_out_dair_sel =
694 SOC_ENUM_SINGLE(DA7219_DIG_ROUTING_DAI,
695 DA7219_DAI_R_SRC_SHIFT,
696 DA7219_OUT_SRC_MAX,
697 da7219_out_sel_txt);
698
699static const struct snd_kcontrol_new da7219_out_dair_sel_mux =
700 SOC_DAPM_ENUM("Out DAIR Mux", da7219_out_dair_sel);
701
702static const struct soc_enum da7219_out_dacl_sel =
703 SOC_ENUM_SINGLE(DA7219_DIG_ROUTING_DAC,
704 DA7219_DAC_L_SRC_SHIFT,
705 DA7219_OUT_SRC_MAX,
706 da7219_out_sel_txt);
707
708static const struct snd_kcontrol_new da7219_out_dacl_sel_mux =
709 SOC_DAPM_ENUM("Out DACL Mux", da7219_out_dacl_sel);
710
711static const struct soc_enum da7219_out_dacr_sel =
712 SOC_ENUM_SINGLE(DA7219_DIG_ROUTING_DAC,
713 DA7219_DAC_R_SRC_SHIFT,
714 DA7219_OUT_SRC_MAX,
715 da7219_out_sel_txt);
716
717static const struct snd_kcontrol_new da7219_out_dacr_sel_mux =
718 SOC_DAPM_ENUM("Out DACR Mux", da7219_out_dacr_sel);
719
720
721/*
722 * DAPM Mixer Controls
723 */
724
725static const struct snd_kcontrol_new da7219_mixin_controls[] = {
726 SOC_DAPM_SINGLE("Mic Switch", DA7219_MIXIN_L_SELECT,
727 DA7219_MIXIN_L_MIX_SELECT_SHIFT,
728 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT),
729};
730
731static const struct snd_kcontrol_new da7219_mixout_l_controls[] = {
732 SOC_DAPM_SINGLE("DACL Switch", DA7219_MIXOUT_L_SELECT,
733 DA7219_MIXOUT_L_MIX_SELECT_SHIFT,
734 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT),
735};
736
737static const struct snd_kcontrol_new da7219_mixout_r_controls[] = {
738 SOC_DAPM_SINGLE("DACR Switch", DA7219_MIXOUT_R_SELECT,
739 DA7219_MIXOUT_R_MIX_SELECT_SHIFT,
740 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT),
741};
742
743#define DA7219_DMIX_ST_CTRLS(reg) \
744 SOC_DAPM_SINGLE("Out FilterL Switch", reg, \
745 DA7219_DMIX_ST_SRC_OUTFILT1L_SHIFT, \
746 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT), \
747 SOC_DAPM_SINGLE("Out FilterR Switch", reg, \
748 DA7219_DMIX_ST_SRC_OUTFILT1R_SHIFT, \
749 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT), \
750 SOC_DAPM_SINGLE("Sidetone Switch", reg, \
751 DA7219_DMIX_ST_SRC_SIDETONE_SHIFT, \
752 DA7219_SWITCH_EN_MAX, DA7219_NO_INVERT) \
753
754static const struct snd_kcontrol_new da7219_st_out_filtl_mix_controls[] = {
755 DA7219_DMIX_ST_CTRLS(DA7219_DROUTING_ST_OUTFILT_1L),
756};
757
758static const struct snd_kcontrol_new da7219_st_out_filtr_mix_controls[] = {
759 DA7219_DMIX_ST_CTRLS(DA7219_DROUTING_ST_OUTFILT_1R),
760};
761
762
763/*
764 * DAPM Events
765 */
766
767static int da7219_dai_event(struct snd_soc_dapm_widget *w,
768 struct snd_kcontrol *kcontrol, int event)
769{
770 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
771 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
772 u8 pll_ctrl, pll_status;
773 int i = 0;
774 bool srm_lock = false;
775
776 switch (event) {
777 case SND_SOC_DAPM_PRE_PMU:
778 if (da7219->master)
779 /* Enable DAI clks for master mode */
780 snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
781 DA7219_DAI_CLK_EN_MASK,
782 DA7219_DAI_CLK_EN_MASK);
783
784 /* PC synchronised to DAI */
785 snd_soc_update_bits(codec, DA7219_PC_COUNT,
786 DA7219_PC_FREERUN_MASK, 0);
787
788 /* Slave mode, if SRM not enabled no need for status checks */
789 pll_ctrl = snd_soc_read(codec, DA7219_PLL_CTRL);
790 if ((pll_ctrl & DA7219_PLL_MODE_MASK) != DA7219_PLL_MODE_SRM)
791 return 0;
792
793 /* Check SRM has locked */
794 do {
795 pll_status = snd_soc_read(codec, DA7219_PLL_SRM_STS);
796 if (pll_status & DA7219_PLL_SRM_STS_SRM_LOCK) {
797 srm_lock = true;
798 } else {
799 ++i;
800 msleep(50);
801 }
802 } while ((i < DA7219_SRM_CHECK_RETRIES) & (!srm_lock));
803
804 if (!srm_lock)
805 dev_warn(codec->dev, "SRM failed to lock\n");
806
807 return 0;
808 case SND_SOC_DAPM_POST_PMD:
809 /* PC free-running */
810 snd_soc_update_bits(codec, DA7219_PC_COUNT,
811 DA7219_PC_FREERUN_MASK,
812 DA7219_PC_FREERUN_MASK);
813
814 /* Disable DAI clks if in master mode */
815 if (da7219->master)
816 snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
817 DA7219_DAI_CLK_EN_MASK, 0);
818 return 0;
819 default:
820 return -EINVAL;
821 }
822}
823
824
825/*
826 * DAPM Widgets
827 */
828
829static const struct snd_soc_dapm_widget da7219_dapm_widgets[] = {
830 /* Input Supplies */
831 SND_SOC_DAPM_SUPPLY("Mic Bias", DA7219_MICBIAS_CTRL,
832 DA7219_MICBIAS1_EN_SHIFT, DA7219_NO_INVERT,
833 NULL, 0),
834
835 /* Inputs */
836 SND_SOC_DAPM_INPUT("MIC"),
837
838 /* Input PGAs */
839 SND_SOC_DAPM_PGA("Mic PGA", DA7219_MIC_1_CTRL,
840 DA7219_MIC_1_AMP_EN_SHIFT, DA7219_NO_INVERT,
841 NULL, 0),
842 SND_SOC_DAPM_PGA("Mixin PGA", DA7219_MIXIN_L_CTRL,
843 DA7219_MIXIN_L_AMP_EN_SHIFT, DA7219_NO_INVERT,
844 NULL, 0),
845
846 /* Input Filters */
847 SND_SOC_DAPM_ADC("ADC", NULL, DA7219_ADC_L_CTRL, DA7219_ADC_L_EN_SHIFT,
848 DA7219_NO_INVERT),
849
850 /* Tone Generator */
851 SND_SOC_DAPM_SIGGEN("TONE"),
852 SND_SOC_DAPM_PGA("Tone Generator", DA7219_TONE_GEN_CFG1,
853 DA7219_START_STOPN_SHIFT, DA7219_NO_INVERT, NULL, 0),
854
855 /* Sidetone Input */
856 SND_SOC_DAPM_ADC("Sidetone Filter", NULL, DA7219_SIDETONE_CTRL,
857 DA7219_SIDETONE_EN_SHIFT, DA7219_NO_INVERT),
858
859 /* Input Mixer Supply */
860 SND_SOC_DAPM_SUPPLY("Mixer In Supply", DA7219_MIXIN_L_CTRL,
861 DA7219_MIXIN_L_MIX_EN_SHIFT, DA7219_NO_INVERT,
862 NULL, 0),
863
864 /* Input Mixer */
865 SND_SOC_DAPM_MIXER("Mixer In", SND_SOC_NOPM, 0, 0,
866 da7219_mixin_controls,
867 ARRAY_SIZE(da7219_mixin_controls)),
868
869 /* Input Muxes */
870 SND_SOC_DAPM_MUX("Out DAIL Mux", SND_SOC_NOPM, 0, 0,
871 &da7219_out_dail_sel_mux),
872 SND_SOC_DAPM_MUX("Out DAIR Mux", SND_SOC_NOPM, 0, 0,
873 &da7219_out_dair_sel_mux),
874
875 /* DAI Supply */
876 SND_SOC_DAPM_SUPPLY("DAI", DA7219_DAI_CTRL, DA7219_DAI_EN_SHIFT,
877 DA7219_NO_INVERT, da7219_dai_event,
878 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
879
880 /* DAI */
881 SND_SOC_DAPM_AIF_OUT("DAIOUT", "Capture", 0, SND_SOC_NOPM, 0, 0),
882 SND_SOC_DAPM_AIF_IN("DAIIN", "Playback", 0, SND_SOC_NOPM, 0, 0),
883
884 /* Output Muxes */
885 SND_SOC_DAPM_MUX("Out DACL Mux", SND_SOC_NOPM, 0, 0,
886 &da7219_out_dacl_sel_mux),
887 SND_SOC_DAPM_MUX("Out DACR Mux", SND_SOC_NOPM, 0, 0,
888 &da7219_out_dacr_sel_mux),
889
890 /* Output Mixers */
891 SND_SOC_DAPM_MIXER("Mixer Out FilterL", SND_SOC_NOPM, 0, 0,
892 da7219_mixout_l_controls,
893 ARRAY_SIZE(da7219_mixout_l_controls)),
894 SND_SOC_DAPM_MIXER("Mixer Out FilterR", SND_SOC_NOPM, 0, 0,
895 da7219_mixout_r_controls,
896 ARRAY_SIZE(da7219_mixout_r_controls)),
897
898 /* Sidetone Mixers */
899 SND_SOC_DAPM_MIXER("ST Mixer Out FilterL", SND_SOC_NOPM, 0, 0,
900 da7219_st_out_filtl_mix_controls,
901 ARRAY_SIZE(da7219_st_out_filtl_mix_controls)),
902 SND_SOC_DAPM_MIXER("ST Mixer Out FilterR", SND_SOC_NOPM, 0,
903 0, da7219_st_out_filtr_mix_controls,
904 ARRAY_SIZE(da7219_st_out_filtr_mix_controls)),
905
906 /* DACs */
907 SND_SOC_DAPM_DAC("DACL", NULL, DA7219_DAC_L_CTRL, DA7219_DAC_L_EN_SHIFT,
908 DA7219_NO_INVERT),
909 SND_SOC_DAPM_DAC("DACR", NULL, DA7219_DAC_R_CTRL, DA7219_DAC_R_EN_SHIFT,
910 DA7219_NO_INVERT),
911
912 /* Output PGAs */
913 SND_SOC_DAPM_PGA("Mixout Left PGA", DA7219_MIXOUT_L_CTRL,
914 DA7219_MIXOUT_L_AMP_EN_SHIFT, DA7219_NO_INVERT,
915 NULL, 0),
916 SND_SOC_DAPM_PGA("Mixout Right PGA", DA7219_MIXOUT_R_CTRL,
917 DA7219_MIXOUT_R_AMP_EN_SHIFT, DA7219_NO_INVERT,
918 NULL, 0),
919 SND_SOC_DAPM_PGA("Headphone Left PGA", DA7219_HP_L_CTRL,
920 DA7219_HP_L_AMP_EN_SHIFT, DA7219_NO_INVERT, NULL, 0),
921 SND_SOC_DAPM_PGA("Headphone Right PGA", DA7219_HP_R_CTRL,
922 DA7219_HP_R_AMP_EN_SHIFT, DA7219_NO_INVERT, NULL, 0),
923
924 /* Output Supplies */
925 SND_SOC_DAPM_SUPPLY("Charge Pump", DA7219_CP_CTRL, DA7219_CP_EN_SHIFT,
926 DA7219_NO_INVERT, NULL, 0),
927
928 /* Outputs */
929 SND_SOC_DAPM_OUTPUT("HPL"),
930 SND_SOC_DAPM_OUTPUT("HPR"),
931};
932
933
934/*
935 * DAPM Mux Routes
936 */
937
938#define DA7219_OUT_DAI_MUX_ROUTES(name) \
939 {name, "ADC", "Mixer In"}, \
940 {name, "Tone Generator", "Tone Generator"}, \
941 {name, "DAIL", "DAIOUT"}, \
942 {name, "DAIR", "DAIOUT"}
943
944#define DA7219_OUT_DAC_MUX_ROUTES(name) \
945 {name, "ADC", "Mixer In"}, \
946 {name, "Tone Generator", "Tone Generator"}, \
947 {name, "DAIL", "DAIIN"}, \
948 {name, "DAIR", "DAIIN"}
949
950/*
951 * DAPM Mixer Routes
952 */
953
954#define DA7219_DMIX_ST_ROUTES(name) \
955 {name, "Out FilterL Switch", "Mixer Out FilterL"}, \
956 {name, "Out FilterR Switch", "Mixer Out FilterR"}, \
957 {name, "Sidetone Switch", "Sidetone Filter"}
958
959
960/*
961 * DAPM audio route definition
962 */
963
964static const struct snd_soc_dapm_route da7219_audio_map[] = {
965 /* Input paths */
966 {"MIC", NULL, "Mic Bias"},
967 {"Mic PGA", NULL, "MIC"},
968 {"Mixin PGA", NULL, "Mic PGA"},
969 {"ADC", NULL, "Mixin PGA"},
970
971 {"Sidetone Filter", NULL, "ADC"},
972 {"Mixer In", NULL, "Mixer In Supply"},
973 {"Mixer In", "Mic Switch", "ADC"},
974
975 {"Tone Generator", NULL, "TONE"},
976
977 DA7219_OUT_DAI_MUX_ROUTES("Out DAIL Mux"),
978 DA7219_OUT_DAI_MUX_ROUTES("Out DAIR Mux"),
979
980 {"DAIOUT", NULL, "Out DAIL Mux"},
981 {"DAIOUT", NULL, "Out DAIR Mux"},
982 {"DAIOUT", NULL, "DAI"},
983
984 /* Output paths */
985 {"DAIIN", NULL, "DAI"},
986
987 DA7219_OUT_DAC_MUX_ROUTES("Out DACL Mux"),
988 DA7219_OUT_DAC_MUX_ROUTES("Out DACR Mux"),
989
990 {"Mixer Out FilterL", "DACL Switch", "Out DACL Mux"},
991 {"Mixer Out FilterR", "DACR Switch", "Out DACR Mux"},
992
993 DA7219_DMIX_ST_ROUTES("ST Mixer Out FilterL"),
994 DA7219_DMIX_ST_ROUTES("ST Mixer Out FilterR"),
995
996 {"DACL", NULL, "ST Mixer Out FilterL"},
997 {"DACR", NULL, "ST Mixer Out FilterR"},
998
999 {"Mixout Left PGA", NULL, "DACL"},
1000 {"Mixout Right PGA", NULL, "DACR"},
1001
1002 {"Headphone Left PGA", NULL, "Mixout Left PGA"},
1003 {"Headphone Right PGA", NULL, "Mixout Right PGA"},
1004
1005 {"HPL", NULL, "Headphone Left PGA"},
1006 {"HPR", NULL, "Headphone Right PGA"},
1007
1008 {"HPL", NULL, "Charge Pump"},
1009 {"HPR", NULL, "Charge Pump"},
1010};
1011
1012
1013/*
1014 * DAI operations
1015 */
1016
1017static int da7219_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1018 int clk_id, unsigned int freq, int dir)
1019{
1020 struct snd_soc_codec *codec = codec_dai->codec;
1021 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1022 int ret = 0;
1023
1024 if ((da7219->clk_src == clk_id) && (da7219->mclk_rate == freq))
1025 return 0;
1026
1027 if (((freq < 2000000) && (freq != 32768)) || (freq > 54000000)) {
1028 dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
1029 freq);
1030 return -EINVAL;
1031 }
1032
1033 switch (clk_id) {
1034 case DA7219_CLKSRC_MCLK_SQR:
1035 snd_soc_update_bits(codec, DA7219_PLL_CTRL,
1036 DA7219_PLL_MCLK_SQR_EN_MASK,
1037 DA7219_PLL_MCLK_SQR_EN_MASK);
1038 break;
1039 case DA7219_CLKSRC_MCLK:
1040 snd_soc_update_bits(codec, DA7219_PLL_CTRL,
1041 DA7219_PLL_MCLK_SQR_EN_MASK, 0);
1042 break;
1043 default:
1044 dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
1045 return -EINVAL;
1046 }
1047
1048 da7219->clk_src = clk_id;
1049
1050 if (da7219->mclk) {
1051 freq = clk_round_rate(da7219->mclk, freq);
1052 ret = clk_set_rate(da7219->mclk, freq);
1053 if (ret) {
1054 dev_err(codec_dai->dev, "Failed to set clock rate %d\n",
1055 freq);
1056 return ret;
1057 }
1058 }
1059
1060 da7219->mclk_rate = freq;
1061
1062 return 0;
1063}
1064
1065static int da7219_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1066 int source, unsigned int fref, unsigned int fout)
1067{
1068 struct snd_soc_codec *codec = codec_dai->codec;
1069 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1070
1071 u8 pll_ctrl, indiv_bits, indiv;
1072 u8 pll_frac_top, pll_frac_bot, pll_integer;
1073 u32 freq_ref;
1074 u64 frac_div;
1075
1076 /* Verify 32KHz, 2MHz - 54MHz MCLK provided, and set input divider */
1077 if (da7219->mclk_rate == 32768) {
1078 indiv_bits = DA7219_PLL_INDIV_2_5_MHZ;
1079 indiv = DA7219_PLL_INDIV_2_5_MHZ_VAL;
1080 } else if (da7219->mclk_rate < 2000000) {
1081 dev_err(codec->dev, "PLL input clock %d below valid range\n",
1082 da7219->mclk_rate);
1083 return -EINVAL;
1084 } else if (da7219->mclk_rate <= 5000000) {
1085 indiv_bits = DA7219_PLL_INDIV_2_5_MHZ;
1086 indiv = DA7219_PLL_INDIV_2_5_MHZ_VAL;
1087 } else if (da7219->mclk_rate <= 10000000) {
1088 indiv_bits = DA7219_PLL_INDIV_5_10_MHZ;
1089 indiv = DA7219_PLL_INDIV_5_10_MHZ_VAL;
1090 } else if (da7219->mclk_rate <= 20000000) {
1091 indiv_bits = DA7219_PLL_INDIV_10_20_MHZ;
1092 indiv = DA7219_PLL_INDIV_10_20_MHZ_VAL;
1093 } else if (da7219->mclk_rate <= 40000000) {
1094 indiv_bits = DA7219_PLL_INDIV_20_40_MHZ;
1095 indiv = DA7219_PLL_INDIV_20_40_MHZ_VAL;
1096 } else if (da7219->mclk_rate <= 54000000) {
1097 indiv_bits = DA7219_PLL_INDIV_40_54_MHZ;
1098 indiv = DA7219_PLL_INDIV_40_54_MHZ_VAL;
1099 } else {
1100 dev_err(codec->dev, "PLL input clock %d above valid range\n",
1101 da7219->mclk_rate);
1102 return -EINVAL;
1103 }
1104 freq_ref = (da7219->mclk_rate / indiv);
1105 pll_ctrl = indiv_bits;
1106
1107 /* Configure PLL */
1108 switch (source) {
1109 case DA7219_SYSCLK_MCLK:
1110 pll_ctrl |= DA7219_PLL_MODE_BYPASS;
1111 snd_soc_update_bits(codec, DA7219_PLL_CTRL,
1112 DA7219_PLL_INDIV_MASK |
1113 DA7219_PLL_MODE_MASK, pll_ctrl);
1114 return 0;
1115 case DA7219_SYSCLK_PLL:
1116 pll_ctrl |= DA7219_PLL_MODE_NORMAL;
1117 break;
1118 case DA7219_SYSCLK_PLL_SRM:
1119 pll_ctrl |= DA7219_PLL_MODE_SRM;
1120 break;
1121 case DA7219_SYSCLK_PLL_32KHZ:
1122 pll_ctrl |= DA7219_PLL_MODE_32KHZ;
1123 break;
1124 default:
1125 dev_err(codec->dev, "Invalid PLL config\n");
1126 return -EINVAL;
1127 }
1128
1129 /* Calculate dividers for PLL */
1130 pll_integer = fout / freq_ref;
1131 frac_div = (u64)(fout % freq_ref) * 8192ULL;
1132 do_div(frac_div, freq_ref);
1133 pll_frac_top = (frac_div >> DA7219_BYTE_SHIFT) & DA7219_BYTE_MASK;
1134 pll_frac_bot = (frac_div) & DA7219_BYTE_MASK;
1135
1136 /* Write PLL config & dividers */
1137 snd_soc_write(codec, DA7219_PLL_FRAC_TOP, pll_frac_top);
1138 snd_soc_write(codec, DA7219_PLL_FRAC_BOT, pll_frac_bot);
1139 snd_soc_write(codec, DA7219_PLL_INTEGER, pll_integer);
1140 snd_soc_update_bits(codec, DA7219_PLL_CTRL,
1141 DA7219_PLL_INDIV_MASK | DA7219_PLL_MODE_MASK,
1142 pll_ctrl);
1143
1144 return 0;
1145}
1146
1147static int da7219_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1148{
1149 struct snd_soc_codec *codec = codec_dai->codec;
1150 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1151 u8 dai_clk_mode = 0, dai_ctrl = 0;
1152
1153 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1154 case SND_SOC_DAIFMT_CBM_CFM:
1155 da7219->master = true;
1156 break;
1157 case SND_SOC_DAIFMT_CBS_CFS:
1158 da7219->master = false;
1159 break;
1160 default:
1161 return -EINVAL;
1162 }
1163
1164 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1165 case SND_SOC_DAIFMT_NB_NF:
1166 break;
1167 case SND_SOC_DAIFMT_NB_IF:
1168 dai_clk_mode |= DA7219_DAI_WCLK_POL_INV;
1169 break;
1170 case SND_SOC_DAIFMT_IB_NF:
1171 dai_clk_mode |= DA7219_DAI_CLK_POL_INV;
1172 break;
1173 case SND_SOC_DAIFMT_IB_IF:
1174 dai_clk_mode |= DA7219_DAI_WCLK_POL_INV |
1175 DA7219_DAI_CLK_POL_INV;
1176 break;
1177 default:
1178 return -EINVAL;
1179 }
1180
1181 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1182 case SND_SOC_DAIFMT_I2S:
1183 dai_ctrl |= DA7219_DAI_FORMAT_I2S;
1184 break;
1185 case SND_SOC_DAIFMT_LEFT_J:
1186 dai_ctrl |= DA7219_DAI_FORMAT_LEFT_J;
1187 break;
1188 case SND_SOC_DAIFMT_RIGHT_J:
1189 dai_ctrl |= DA7219_DAI_FORMAT_RIGHT_J;
1190 break;
1191 case SND_SOC_DAIFMT_DSP_B:
1192 dai_ctrl |= DA7219_DAI_FORMAT_DSP;
1193 break;
1194 default:
1195 return -EINVAL;
1196 }
1197
1198 /* By default 64 BCLKs per WCLK is supported */
1199 dai_clk_mode |= DA7219_DAI_BCLKS_PER_WCLK_64;
1200
1201 snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
1202 DA7219_DAI_BCLKS_PER_WCLK_MASK |
1203 DA7219_DAI_CLK_POL_MASK | DA7219_DAI_WCLK_POL_MASK,
1204 dai_clk_mode);
1205 snd_soc_update_bits(codec, DA7219_DAI_CTRL, DA7219_DAI_FORMAT_MASK,
1206 dai_ctrl);
1207
1208 return 0;
1209}
1210
1211static int da7219_set_dai_tdm_slot(struct snd_soc_dai *dai,
1212 unsigned int tx_mask, unsigned int rx_mask,
1213 int slots, int slot_width)
1214{
1215 struct snd_soc_codec *codec = dai->codec;
1216 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1217 u8 dai_bclks_per_wclk;
1218 u16 offset;
1219 u32 frame_size;
1220
1221 /* No channels enabled so disable TDM, revert to 64-bit frames */
1222 if (!tx_mask) {
1223 snd_soc_update_bits(codec, DA7219_DAI_TDM_CTRL,
1224 DA7219_DAI_TDM_CH_EN_MASK |
1225 DA7219_DAI_TDM_MODE_EN_MASK, 0);
1226 snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
1227 DA7219_DAI_BCLKS_PER_WCLK_MASK,
1228 DA7219_DAI_BCLKS_PER_WCLK_64);
1229 return 0;
1230 }
1231
1232 /* Check we have valid slots */
1233 if (fls(tx_mask) > DA7219_DAI_TDM_MAX_SLOTS) {
1234 dev_err(codec->dev, "Invalid number of slots, max = %d\n",
1235 DA7219_DAI_TDM_MAX_SLOTS);
1236 return -EINVAL;
1237 }
1238
1239 /* Check we have a valid offset given */
1240 if (rx_mask > DA7219_DAI_OFFSET_MAX) {
1241 dev_err(codec->dev, "Invalid slot offset, max = %d\n",
1242 DA7219_DAI_OFFSET_MAX);
1243 return -EINVAL;
1244 }
1245
1246 /* Calculate & validate frame size based on slot info provided. */
1247 frame_size = slots * slot_width;
1248 switch (frame_size) {
1249 case 32:
1250 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_32;
1251 break;
1252 case 64:
1253 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_64;
1254 break;
1255 case 128:
1256 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_128;
1257 break;
1258 case 256:
1259 dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_256;
1260 break;
1261 default:
1262 dev_err(codec->dev, "Invalid frame size %d\n", frame_size);
1263 return -EINVAL;
1264 }
1265
1266 snd_soc_update_bits(codec, DA7219_DAI_CLK_MODE,
1267 DA7219_DAI_BCLKS_PER_WCLK_MASK,
1268 dai_bclks_per_wclk);
1269
1270 offset = cpu_to_le16(rx_mask);
1271 regmap_bulk_write(da7219->regmap, DA7219_DAI_OFFSET_LOWER,
1272 &offset, sizeof(offset));
1273
1274 snd_soc_update_bits(codec, DA7219_DAI_TDM_CTRL,
1275 DA7219_DAI_TDM_CH_EN_MASK |
1276 DA7219_DAI_TDM_MODE_EN_MASK,
1277 (tx_mask << DA7219_DAI_TDM_CH_EN_SHIFT) |
1278 DA7219_DAI_TDM_MODE_EN_MASK);
1279
1280 return 0;
1281}
1282
1283static int da7219_hw_params(struct snd_pcm_substream *substream,
1284 struct snd_pcm_hw_params *params,
1285 struct snd_soc_dai *dai)
1286{
1287 struct snd_soc_codec *codec = dai->codec;
1288 u8 dai_ctrl = 0, fs;
1289 unsigned int channels;
1290
1291 switch (params_width(params)) {
1292 case 16:
1293 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S16_LE;
1294 break;
1295 case 20:
1296 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S20_LE;
1297 break;
1298 case 24:
1299 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S24_LE;
1300 break;
1301 case 32:
1302 dai_ctrl |= DA7219_DAI_WORD_LENGTH_S32_LE;
1303 break;
1304 default:
1305 return -EINVAL;
1306 }
1307
1308 channels = params_channels(params);
1309 if ((channels < 1) | (channels > DA7219_DAI_CH_NUM_MAX)) {
1310 dev_err(codec->dev,
1311 "Invalid number of channels, only 1 to %d supported\n",
1312 DA7219_DAI_CH_NUM_MAX);
1313 return -EINVAL;
1314 }
1315 dai_ctrl |= channels << DA7219_DAI_CH_NUM_SHIFT;
1316
1317 switch (params_rate(params)) {
1318 case 8000:
1319 fs = DA7219_SR_8000;
1320 break;
1321 case 11025:
1322 fs = DA7219_SR_11025;
1323 break;
1324 case 12000:
1325 fs = DA7219_SR_12000;
1326 break;
1327 case 16000:
1328 fs = DA7219_SR_16000;
1329 break;
1330 case 22050:
1331 fs = DA7219_SR_22050;
1332 break;
1333 case 24000:
1334 fs = DA7219_SR_24000;
1335 break;
1336 case 32000:
1337 fs = DA7219_SR_32000;
1338 break;
1339 case 44100:
1340 fs = DA7219_SR_44100;
1341 break;
1342 case 48000:
1343 fs = DA7219_SR_48000;
1344 break;
1345 case 88200:
1346 fs = DA7219_SR_88200;
1347 break;
1348 case 96000:
1349 fs = DA7219_SR_96000;
1350 break;
1351 default:
1352 return -EINVAL;
1353 }
1354
1355 snd_soc_update_bits(codec, DA7219_DAI_CTRL,
1356 DA7219_DAI_WORD_LENGTH_MASK |
1357 DA7219_DAI_CH_NUM_MASK,
1358 dai_ctrl);
1359 snd_soc_write(codec, DA7219_SR, fs);
1360
1361 return 0;
1362}
1363
1364static const struct snd_soc_dai_ops da7219_dai_ops = {
1365 .hw_params = da7219_hw_params,
1366 .set_sysclk = da7219_set_dai_sysclk,
1367 .set_pll = da7219_set_dai_pll,
1368 .set_fmt = da7219_set_dai_fmt,
1369 .set_tdm_slot = da7219_set_dai_tdm_slot,
1370};
1371
1372#define DA7219_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1373 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1374
1375static struct snd_soc_dai_driver da7219_dai = {
1376 .name = "da7219-hifi",
1377 .playback = {
1378 .stream_name = "Playback",
1379 .channels_min = 1,
1380 .channels_max = DA7219_DAI_CH_NUM_MAX,
1381 .rates = SNDRV_PCM_RATE_8000_96000,
1382 .formats = DA7219_FORMATS,
1383 },
1384 .capture = {
1385 .stream_name = "Capture",
1386 .channels_min = 1,
1387 .channels_max = DA7219_DAI_CH_NUM_MAX,
1388 .rates = SNDRV_PCM_RATE_8000_96000,
1389 .formats = DA7219_FORMATS,
1390 },
1391 .ops = &da7219_dai_ops,
1392 .symmetric_rates = 1,
1393 .symmetric_channels = 1,
1394 .symmetric_samplebits = 1,
1395};
1396
1397
1398/*
1399 * DT
1400 */
1401
1402static const struct of_device_id da7219_of_match[] = {
1403 { .compatible = "dlg,da7219", },
1404 { }
1405};
1406MODULE_DEVICE_TABLE(of, da7219_of_match);
1407
1408static enum da7219_ldo_lvl_sel da7219_of_ldo_lvl(struct snd_soc_codec *codec,
1409 u32 val)
1410{
1411 switch (val) {
1412 case 1050:
1413 return DA7219_LDO_LVL_SEL_1_05V;
1414 case 1100:
1415 return DA7219_LDO_LVL_SEL_1_10V;
1416 case 1200:
1417 return DA7219_LDO_LVL_SEL_1_20V;
1418 case 1400:
1419 return DA7219_LDO_LVL_SEL_1_40V;
1420 default:
1421 dev_warn(codec->dev, "Invalid LDO level");
1422 return DA7219_LDO_LVL_SEL_1_05V;
1423 }
1424}
1425
1426static enum da7219_micbias_voltage
1427 da7219_of_micbias_lvl(struct snd_soc_codec *codec, u32 val)
1428{
1429 switch (val) {
1430 case 1800:
1431 return DA7219_MICBIAS_1_8V;
1432 case 2000:
1433 return DA7219_MICBIAS_2_0V;
1434 case 2200:
1435 return DA7219_MICBIAS_2_2V;
1436 case 2400:
1437 return DA7219_MICBIAS_2_4V;
1438 case 2600:
1439 return DA7219_MICBIAS_2_6V;
1440 default:
1441 dev_warn(codec->dev, "Invalid micbias level");
1442 return DA7219_MICBIAS_2_2V;
1443 }
1444}
1445
1446static enum da7219_mic_amp_in_sel
1447 da7219_of_mic_amp_in_sel(struct snd_soc_codec *codec, const char *str)
1448{
1449 if (!strcmp(str, "diff")) {
1450 return DA7219_MIC_AMP_IN_SEL_DIFF;
1451 } else if (!strcmp(str, "se_p")) {
1452 return DA7219_MIC_AMP_IN_SEL_SE_P;
1453 } else if (!strcmp(str, "se_n")) {
1454 return DA7219_MIC_AMP_IN_SEL_SE_N;
1455 } else {
1456 dev_warn(codec->dev, "Invalid mic input type selection");
1457 return DA7219_MIC_AMP_IN_SEL_DIFF;
1458 }
1459}
1460
1461static struct da7219_pdata *da7219_of_to_pdata(struct snd_soc_codec *codec)
1462{
1463 struct device_node *np = codec->dev->of_node;
1464 struct da7219_pdata *pdata;
1465 const char *of_str;
1466 u32 of_val32;
1467
1468 pdata = devm_kzalloc(codec->dev, sizeof(*pdata), GFP_KERNEL);
1469 if (!pdata)
1470 return NULL;
1471
1472 if (of_property_read_u32(np, "dlg,ldo-lvl", &of_val32) >= 0)
1473 pdata->ldo_lvl_sel = da7219_of_ldo_lvl(codec, of_val32);
1474
1475 if (of_property_read_u32(np, "dlg,micbias-lvl", &of_val32) >= 0)
1476 pdata->micbias_lvl = da7219_of_micbias_lvl(codec, of_val32);
1477 else
1478 pdata->micbias_lvl = DA7219_MICBIAS_2_2V;
1479
1480 if (!of_property_read_string(np, "dlg,mic-amp-in-sel", &of_str))
1481 pdata->mic_amp_in_sel = da7219_of_mic_amp_in_sel(codec, of_str);
1482 else
1483 pdata->mic_amp_in_sel = DA7219_MIC_AMP_IN_SEL_DIFF;
1484
1485 return pdata;
1486}
1487
1488
1489/*
1490 * Codec driver functions
1491 */
1492
1493static int da7219_set_bias_level(struct snd_soc_codec *codec,
1494 enum snd_soc_bias_level level)
1495{
1496 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1497 int ret;
1498
1499 switch (level) {
1500 case SND_SOC_BIAS_ON:
1501 case SND_SOC_BIAS_PREPARE:
1502 break;
1503 case SND_SOC_BIAS_STANDBY:
1504 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
1505 /* MCLK */
1506 if (da7219->mclk) {
1507 ret = clk_prepare_enable(da7219->mclk);
1508 if (ret) {
1509 dev_err(codec->dev,
1510 "Failed to enable mclk\n");
1511 return ret;
1512 }
1513 }
1514
1515 /* Master bias */
1516 snd_soc_update_bits(codec, DA7219_REFERENCES,
1517 DA7219_BIAS_EN_MASK,
1518 DA7219_BIAS_EN_MASK);
1519
1520 /* Enable Internal Digital LDO */
1521 snd_soc_update_bits(codec, DA7219_LDO_CTRL,
1522 DA7219_LDO_EN_MASK,
1523 DA7219_LDO_EN_MASK);
1524 }
1525 break;
1526 case SND_SOC_BIAS_OFF:
1527 /* Only disable if jack detection not active */
1528 if (!da7219->aad->jack) {
1529 /* Bypass Internal Digital LDO */
1530 snd_soc_update_bits(codec, DA7219_LDO_CTRL,
1531 DA7219_LDO_EN_MASK, 0);
1532
1533 /* Master bias */
1534 snd_soc_update_bits(codec, DA7219_REFERENCES,
1535 DA7219_BIAS_EN_MASK, 0);
1536 }
1537
1538 /* MCLK */
1539 if (da7219->mclk)
1540 clk_disable_unprepare(da7219->mclk);
1541 break;
1542 }
1543
1544 return 0;
1545}
1546
1547static const char *da7219_supply_names[DA7219_NUM_SUPPLIES] = {
1548 [DA7219_SUPPLY_VDD] = "VDD",
1549 [DA7219_SUPPLY_VDDMIC] = "VDDMIC",
1550 [DA7219_SUPPLY_VDDIO] = "VDDIO",
1551};
1552
1553static int da7219_handle_supplies(struct snd_soc_codec *codec)
1554{
1555 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1556 struct regulator *vddio;
1557 u8 io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_2_5V_3_6V;
1558 int i, ret;
1559
1560 /* Get required supplies */
1561 for (i = 0; i < DA7219_NUM_SUPPLIES; ++i)
1562 da7219->supplies[i].supply = da7219_supply_names[i];
1563
1564 ret = devm_regulator_bulk_get(codec->dev, DA7219_NUM_SUPPLIES,
1565 da7219->supplies);
1566 if (ret) {
1567 dev_err(codec->dev, "Failed to get supplies");
1568 return ret;
1569 }
1570
1571 /* Determine VDDIO voltage provided */
1572 vddio = da7219->supplies[DA7219_SUPPLY_VDDIO].consumer;
1573 ret = regulator_get_voltage(vddio);
1574 if (ret < 1200000)
1575 dev_warn(codec->dev, "Invalid VDDIO voltage\n");
1576 else if (ret < 2800000)
1577 io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_1_2V_2_8V;
1578
1579 /* Enable main supplies */
1580 ret = regulator_bulk_enable(DA7219_NUM_SUPPLIES, da7219->supplies);
1581 if (ret) {
1582 dev_err(codec->dev, "Failed to enable supplies");
1583 return ret;
1584 }
1585
1586 /* Ensure device in active mode */
1587 snd_soc_write(codec, DA7219_SYSTEM_ACTIVE, DA7219_SYSTEM_ACTIVE_MASK);
1588
1589 /* Update IO voltage level range */
1590 snd_soc_write(codec, DA7219_IO_CTRL, io_voltage_lvl);
1591
1592 return 0;
1593}
1594
1595static void da7219_handle_pdata(struct snd_soc_codec *codec)
1596{
1597 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1598 struct da7219_pdata *pdata = da7219->pdata;
1599
1600 if (pdata) {
1601 u8 micbias_lvl = 0;
1602
1603 /* Internal LDO */
1604 switch (pdata->ldo_lvl_sel) {
1605 case DA7219_LDO_LVL_SEL_1_05V:
1606 case DA7219_LDO_LVL_SEL_1_10V:
1607 case DA7219_LDO_LVL_SEL_1_20V:
1608 case DA7219_LDO_LVL_SEL_1_40V:
1609 snd_soc_update_bits(codec, DA7219_LDO_CTRL,
1610 DA7219_LDO_LEVEL_SELECT_MASK,
1611 (pdata->ldo_lvl_sel <<
1612 DA7219_LDO_LEVEL_SELECT_SHIFT));
1613 break;
1614 }
1615
1616 /* Mic Bias voltages */
1617 switch (pdata->micbias_lvl) {
1618 case DA7219_MICBIAS_1_8V:
1619 case DA7219_MICBIAS_2_0V:
1620 case DA7219_MICBIAS_2_2V:
1621 case DA7219_MICBIAS_2_4V:
1622 case DA7219_MICBIAS_2_6V:
1623 micbias_lvl |= (pdata->micbias_lvl <<
1624 DA7219_MICBIAS1_LEVEL_SHIFT);
1625 break;
1626 }
1627
1628 snd_soc_write(codec, DA7219_MICBIAS_CTRL, micbias_lvl);
1629
1630 /* Mic */
1631 switch (pdata->mic_amp_in_sel) {
1632 case DA7219_MIC_AMP_IN_SEL_DIFF:
1633 case DA7219_MIC_AMP_IN_SEL_SE_P:
1634 case DA7219_MIC_AMP_IN_SEL_SE_N:
1635 snd_soc_write(codec, DA7219_MIC_1_SELECT,
1636 pdata->mic_amp_in_sel);
1637 break;
1638 }
1639 }
1640}
1641
1642static int da7219_probe(struct snd_soc_codec *codec)
1643{
1644 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1645 int ret;
1646
1647 mutex_init(&da7219->lock);
1648
1649 /* Regulator configuration */
1650 ret = da7219_handle_supplies(codec);
1651 if (ret)
1652 return ret;
1653
1654 /* Handle DT/Platform data */
1655 if (codec->dev->of_node)
1656 da7219->pdata = da7219_of_to_pdata(codec);
1657 else
1658 da7219->pdata = dev_get_platdata(codec->dev);
1659
1660 da7219_handle_pdata(codec);
1661
1662 /* Check if MCLK provided */
1663 da7219->mclk = devm_clk_get(codec->dev, "mclk");
1664 if (IS_ERR(da7219->mclk)) {
1665 if (PTR_ERR(da7219->mclk) != -ENOENT)
1666 return PTR_ERR(da7219->mclk);
1667 else
1668 da7219->mclk = NULL;
1669 }
1670
1671 /* Default PC counter to free-running */
1672 snd_soc_update_bits(codec, DA7219_PC_COUNT, DA7219_PC_FREERUN_MASK,
1673 DA7219_PC_FREERUN_MASK);
1674
1675 /* Default gain ramping */
1676 snd_soc_update_bits(codec, DA7219_MIXIN_L_CTRL,
1677 DA7219_MIXIN_L_AMP_RAMP_EN_MASK,
1678 DA7219_MIXIN_L_AMP_RAMP_EN_MASK);
1679 snd_soc_update_bits(codec, DA7219_ADC_L_CTRL, DA7219_ADC_L_RAMP_EN_MASK,
1680 DA7219_ADC_L_RAMP_EN_MASK);
1681 snd_soc_update_bits(codec, DA7219_DAC_L_CTRL, DA7219_DAC_L_RAMP_EN_MASK,
1682 DA7219_DAC_L_RAMP_EN_MASK);
1683 snd_soc_update_bits(codec, DA7219_DAC_R_CTRL, DA7219_DAC_R_RAMP_EN_MASK,
1684 DA7219_DAC_R_RAMP_EN_MASK);
1685 snd_soc_update_bits(codec, DA7219_HP_L_CTRL,
1686 DA7219_HP_L_AMP_RAMP_EN_MASK,
1687 DA7219_HP_L_AMP_RAMP_EN_MASK);
1688 snd_soc_update_bits(codec, DA7219_HP_R_CTRL,
1689 DA7219_HP_R_AMP_RAMP_EN_MASK,
1690 DA7219_HP_R_AMP_RAMP_EN_MASK);
1691
1692 /* Default infinite tone gen, start/stop by Kcontrol */
1693 snd_soc_write(codec, DA7219_TONE_GEN_CYCLES, DA7219_BEEP_CYCLES_MASK);
1694
1695 /* Initialise AAD block */
1696 return da7219_aad_init(codec);
1697}
1698
1699static int da7219_remove(struct snd_soc_codec *codec)
1700{
1701 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1702
1703 da7219_aad_exit(codec);
1704
1705 /* Supplies */
1706 return regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies);
1707}
1708
1709#ifdef CONFIG_PM
1710static int da7219_suspend(struct snd_soc_codec *codec)
1711{
1712 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1713
1714 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
1715
1716 /* Put device into standby mode if jack detection disabled */
1717 if (!da7219->aad->jack)
1718 snd_soc_write(codec, DA7219_SYSTEM_ACTIVE, 0);
1719
1720 return 0;
1721}
1722
1723static int da7219_resume(struct snd_soc_codec *codec)
1724{
1725 struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
1726
1727 /* Put device into active mode if previously pushed to standby */
1728 if (!da7219->aad->jack)
1729 snd_soc_write(codec, DA7219_SYSTEM_ACTIVE,
1730 DA7219_SYSTEM_ACTIVE_MASK);
1731
1732 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
1733
1734 return 0;
1735}
1736#else
1737#define da7219_suspend NULL
1738#define da7219_resume NULL
1739#endif
1740
1741static struct snd_soc_codec_driver soc_codec_dev_da7219 = {
1742 .probe = da7219_probe,
1743 .remove = da7219_remove,
1744 .suspend = da7219_suspend,
1745 .resume = da7219_resume,
1746 .set_bias_level = da7219_set_bias_level,
1747
1748 .controls = da7219_snd_controls,
1749 .num_controls = ARRAY_SIZE(da7219_snd_controls),
1750
1751 .dapm_widgets = da7219_dapm_widgets,
1752 .num_dapm_widgets = ARRAY_SIZE(da7219_dapm_widgets),
1753 .dapm_routes = da7219_audio_map,
1754 .num_dapm_routes = ARRAY_SIZE(da7219_audio_map),
1755};
1756
1757
1758/*
1759 * Regmap configs
1760 */
1761
1762static struct reg_default da7219_reg_defaults[] = {
1763 { DA7219_MIC_1_SELECT, 0x00 },
1764 { DA7219_CIF_TIMEOUT_CTRL, 0x01 },
1765 { DA7219_SR_24_48, 0x00 },
1766 { DA7219_SR, 0x0A },
1767 { DA7219_CIF_I2C_ADDR_CFG, 0x02 },
1768 { DA7219_PLL_CTRL, 0x10 },
1769 { DA7219_PLL_FRAC_TOP, 0x00 },
1770 { DA7219_PLL_FRAC_BOT, 0x00 },
1771 { DA7219_PLL_INTEGER, 0x20 },
1772 { DA7219_DIG_ROUTING_DAI, 0x10 },
1773 { DA7219_DAI_CLK_MODE, 0x01 },
1774 { DA7219_DAI_CTRL, 0x28 },
1775 { DA7219_DAI_TDM_CTRL, 0x40 },
1776 { DA7219_DIG_ROUTING_DAC, 0x32 },
1777 { DA7219_DAI_OFFSET_LOWER, 0x00 },
1778 { DA7219_DAI_OFFSET_UPPER, 0x00 },
1779 { DA7219_REFERENCES, 0x00 },
1780 { DA7219_MIXIN_L_SELECT, 0x00 },
1781 { DA7219_MIXIN_L_GAIN, 0x03 },
1782 { DA7219_ADC_L_GAIN, 0x6F },
1783 { DA7219_ADC_FILTERS1, 0x80 },
1784 { DA7219_MIC_1_GAIN, 0x01 },
1785 { DA7219_SIDETONE_CTRL, 0x40 },
1786 { DA7219_SIDETONE_GAIN, 0x0E },
1787 { DA7219_DROUTING_ST_OUTFILT_1L, 0x01 },
1788 { DA7219_DROUTING_ST_OUTFILT_1R, 0x02 },
1789 { DA7219_DAC_FILTERS5, 0x00 },
1790 { DA7219_DAC_FILTERS2, 0x88 },
1791 { DA7219_DAC_FILTERS3, 0x88 },
1792 { DA7219_DAC_FILTERS4, 0x08 },
1793 { DA7219_DAC_FILTERS1, 0x80 },
1794 { DA7219_DAC_L_GAIN, 0x6F },
1795 { DA7219_DAC_R_GAIN, 0x6F },
1796 { DA7219_CP_CTRL, 0x20 },
1797 { DA7219_HP_L_GAIN, 0x39 },
1798 { DA7219_HP_R_GAIN, 0x39 },
1799 { DA7219_MIXOUT_L_SELECT, 0x00 },
1800 { DA7219_MIXOUT_R_SELECT, 0x00 },
1801 { DA7219_MICBIAS_CTRL, 0x03 },
1802 { DA7219_MIC_1_CTRL, 0x40 },
1803 { DA7219_MIXIN_L_CTRL, 0x40 },
1804 { DA7219_ADC_L_CTRL, 0x40 },
1805 { DA7219_DAC_L_CTRL, 0x40 },
1806 { DA7219_DAC_R_CTRL, 0x40 },
1807 { DA7219_HP_L_CTRL, 0x40 },
1808 { DA7219_HP_R_CTRL, 0x40 },
1809 { DA7219_MIXOUT_L_CTRL, 0x10 },
1810 { DA7219_MIXOUT_R_CTRL, 0x10 },
1811 { DA7219_CHIP_ID1, 0x23 },
1812 { DA7219_CHIP_ID2, 0x93 },
1813 { DA7219_CHIP_REVISION, 0x00 },
1814 { DA7219_LDO_CTRL, 0x00 },
1815 { DA7219_IO_CTRL, 0x00 },
1816 { DA7219_GAIN_RAMP_CTRL, 0x00 },
1817 { DA7219_PC_COUNT, 0x02 },
1818 { DA7219_CP_VOL_THRESHOLD1, 0x0E },
1819 { DA7219_DIG_CTRL, 0x00 },
1820 { DA7219_ALC_CTRL2, 0x00 },
1821 { DA7219_ALC_CTRL3, 0x00 },
1822 { DA7219_ALC_NOISE, 0x3F },
1823 { DA7219_ALC_TARGET_MIN, 0x3F },
1824 { DA7219_ALC_TARGET_MAX, 0x00 },
1825 { DA7219_ALC_GAIN_LIMITS, 0xFF },
1826 { DA7219_ALC_ANA_GAIN_LIMITS, 0x71 },
1827 { DA7219_ALC_ANTICLIP_CTRL, 0x00 },
1828 { DA7219_ALC_ANTICLIP_LEVEL, 0x00 },
1829 { DA7219_DAC_NG_SETUP_TIME, 0x00 },
1830 { DA7219_DAC_NG_OFF_THRESH, 0x00 },
1831 { DA7219_DAC_NG_ON_THRESH, 0x00 },
1832 { DA7219_DAC_NG_CTRL, 0x00 },
1833 { DA7219_TONE_GEN_CFG1, 0x00 },
1834 { DA7219_TONE_GEN_CFG2, 0x00 },
1835 { DA7219_TONE_GEN_CYCLES, 0x00 },
1836 { DA7219_TONE_GEN_FREQ1_L, 0x55 },
1837 { DA7219_TONE_GEN_FREQ1_U, 0x15 },
1838 { DA7219_TONE_GEN_FREQ2_L, 0x00 },
1839 { DA7219_TONE_GEN_FREQ2_U, 0x40 },
1840 { DA7219_TONE_GEN_ON_PER, 0x02 },
1841 { DA7219_TONE_GEN_OFF_PER, 0x01 },
1842 { DA7219_ACCDET_IRQ_MASK_A, 0x00 },
1843 { DA7219_ACCDET_IRQ_MASK_B, 0x00 },
1844 { DA7219_ACCDET_CONFIG_1, 0xD6 },
1845 { DA7219_ACCDET_CONFIG_2, 0x34 },
1846 { DA7219_ACCDET_CONFIG_3, 0x0A },
1847 { DA7219_ACCDET_CONFIG_4, 0x16 },
1848 { DA7219_ACCDET_CONFIG_5, 0x21 },
1849 { DA7219_ACCDET_CONFIG_6, 0x3E },
1850 { DA7219_ACCDET_CONFIG_7, 0x01 },
1851 { DA7219_SYSTEM_ACTIVE, 0x00 },
1852};
1853
1854static bool da7219_volatile_register(struct device *dev, unsigned int reg)
1855{
1856 switch (reg) {
1857 case DA7219_MIC_1_GAIN_STATUS:
1858 case DA7219_MIXIN_L_GAIN_STATUS:
1859 case DA7219_ADC_L_GAIN_STATUS:
1860 case DA7219_DAC_L_GAIN_STATUS:
1861 case DA7219_DAC_R_GAIN_STATUS:
1862 case DA7219_HP_L_GAIN_STATUS:
1863 case DA7219_HP_R_GAIN_STATUS:
1864 case DA7219_CIF_CTRL:
1865 case DA7219_PLL_SRM_STS:
1866 case DA7219_ALC_CTRL1:
1867 case DA7219_SYSTEM_MODES_INPUT:
1868 case DA7219_SYSTEM_MODES_OUTPUT:
1869 case DA7219_ALC_OFFSET_AUTO_M_L:
1870 case DA7219_ALC_OFFSET_AUTO_U_L:
1871 case DA7219_TONE_GEN_CFG1:
1872 case DA7219_ACCDET_STATUS_A:
1873 case DA7219_ACCDET_STATUS_B:
1874 case DA7219_ACCDET_IRQ_EVENT_A:
1875 case DA7219_ACCDET_IRQ_EVENT_B:
1876 case DA7219_ACCDET_CONFIG_8:
1877 case DA7219_SYSTEM_STATUS:
1878 return 1;
1879 default:
1880 return 0;
1881 }
1882}
1883
1884static const struct regmap_config da7219_regmap_config = {
1885 .reg_bits = 8,
1886 .val_bits = 8,
1887
1888 .max_register = DA7219_SYSTEM_ACTIVE,
1889 .reg_defaults = da7219_reg_defaults,
1890 .num_reg_defaults = ARRAY_SIZE(da7219_reg_defaults),
1891 .volatile_reg = da7219_volatile_register,
1892 .cache_type = REGCACHE_RBTREE,
1893};
1894
1895
1896/*
1897 * I2C layer
1898 */
1899
1900static int da7219_i2c_probe(struct i2c_client *i2c,
1901 const struct i2c_device_id *id)
1902{
1903 struct da7219_priv *da7219;
1904 int ret;
1905
1906 da7219 = devm_kzalloc(&i2c->dev, sizeof(struct da7219_priv),
1907 GFP_KERNEL);
1908 if (!da7219)
1909 return -ENOMEM;
1910
1911 i2c_set_clientdata(i2c, da7219);
1912
1913 da7219->regmap = devm_regmap_init_i2c(i2c, &da7219_regmap_config);
1914 if (IS_ERR(da7219->regmap)) {
1915 ret = PTR_ERR(da7219->regmap);
1916 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
1917 return ret;
1918 }
1919
1920 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7219,
1921 &da7219_dai, 1);
1922 if (ret < 0) {
1923 dev_err(&i2c->dev, "Failed to register da7219 codec: %d\n",
1924 ret);
1925 }
1926 return ret;
1927}
1928
1929static int da7219_i2c_remove(struct i2c_client *client)
1930{
1931 snd_soc_unregister_codec(&client->dev);
1932 return 0;
1933}
1934
1935static const struct i2c_device_id da7219_i2c_id[] = {
1936 { "da7219", },
1937 { }
1938};
1939MODULE_DEVICE_TABLE(i2c, da7219_i2c_id);
1940
1941static struct i2c_driver da7219_i2c_driver = {
1942 .driver = {
1943 .name = "da7219",
1944 .of_match_table = of_match_ptr(da7219_of_match),
1945 },
1946 .probe = da7219_i2c_probe,
1947 .remove = da7219_i2c_remove,
1948 .id_table = da7219_i2c_id,
1949};
1950
1951module_i2c_driver(da7219_i2c_driver);
1952
1953MODULE_DESCRIPTION("ASoC DA7219 Codec Driver");
1954MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
1955MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/da7219.h b/sound/soc/codecs/da7219.h
new file mode 100644
index 000000000000..b514268c6c56
--- /dev/null
+++ b/sound/soc/codecs/da7219.h
@@ -0,0 +1,820 @@
1/*
2 * da7219.h - DA7219 ALSA SoC Codec Driver
3 *
4 * Copyright (c) 2015 Dialog Semiconductor
5 *
6 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#ifndef __DA7219_H
15#define __DA7219_H
16
17#include <linux/regmap.h>
18#include <linux/regulator/consumer.h>
19#include <sound/da7219.h>
20
21/*
22 * Registers
23 */
24
25#define DA7219_MIC_1_GAIN_STATUS 0x6
26#define DA7219_MIXIN_L_GAIN_STATUS 0x8
27#define DA7219_ADC_L_GAIN_STATUS 0xA
28#define DA7219_DAC_L_GAIN_STATUS 0xC
29#define DA7219_DAC_R_GAIN_STATUS 0xD
30#define DA7219_HP_L_GAIN_STATUS 0xE
31#define DA7219_HP_R_GAIN_STATUS 0xF
32#define DA7219_MIC_1_SELECT 0x10
33#define DA7219_CIF_TIMEOUT_CTRL 0x12
34#define DA7219_CIF_CTRL 0x13
35#define DA7219_SR_24_48 0x16
36#define DA7219_SR 0x17
37#define DA7219_CIF_I2C_ADDR_CFG 0x1B
38#define DA7219_PLL_CTRL 0x20
39#define DA7219_PLL_FRAC_TOP 0x22
40#define DA7219_PLL_FRAC_BOT 0x23
41#define DA7219_PLL_INTEGER 0x24
42#define DA7219_PLL_SRM_STS 0x25
43#define DA7219_DIG_ROUTING_DAI 0x2A
44#define DA7219_DAI_CLK_MODE 0x2B
45#define DA7219_DAI_CTRL 0x2C
46#define DA7219_DAI_TDM_CTRL 0x2D
47#define DA7219_DIG_ROUTING_DAC 0x2E
48#define DA7219_ALC_CTRL1 0x2F
49#define DA7219_DAI_OFFSET_LOWER 0x30
50#define DA7219_DAI_OFFSET_UPPER 0x31
51#define DA7219_REFERENCES 0x32
52#define DA7219_MIXIN_L_SELECT 0x33
53#define DA7219_MIXIN_L_GAIN 0x34
54#define DA7219_ADC_L_GAIN 0x36
55#define DA7219_ADC_FILTERS1 0x38
56#define DA7219_MIC_1_GAIN 0x39
57#define DA7219_SIDETONE_CTRL 0x3A
58#define DA7219_SIDETONE_GAIN 0x3B
59#define DA7219_DROUTING_ST_OUTFILT_1L 0x3C
60#define DA7219_DROUTING_ST_OUTFILT_1R 0x3D
61#define DA7219_DAC_FILTERS5 0x40
62#define DA7219_DAC_FILTERS2 0x41
63#define DA7219_DAC_FILTERS3 0x42
64#define DA7219_DAC_FILTERS4 0x43
65#define DA7219_DAC_FILTERS1 0x44
66#define DA7219_DAC_L_GAIN 0x45
67#define DA7219_DAC_R_GAIN 0x46
68#define DA7219_CP_CTRL 0x47
69#define DA7219_HP_L_GAIN 0x48
70#define DA7219_HP_R_GAIN 0x49
71#define DA7219_MIXOUT_L_SELECT 0x4B
72#define DA7219_MIXOUT_R_SELECT 0x4C
73#define DA7219_SYSTEM_MODES_INPUT 0x50
74#define DA7219_SYSTEM_MODES_OUTPUT 0x51
75#define DA7219_MICBIAS_CTRL 0x62
76#define DA7219_MIC_1_CTRL 0x63
77#define DA7219_MIXIN_L_CTRL 0x65
78#define DA7219_ADC_L_CTRL 0x67
79#define DA7219_DAC_L_CTRL 0x69
80#define DA7219_DAC_R_CTRL 0x6A
81#define DA7219_HP_L_CTRL 0x6B
82#define DA7219_HP_R_CTRL 0x6C
83#define DA7219_MIXOUT_L_CTRL 0x6E
84#define DA7219_MIXOUT_R_CTRL 0x6F
85#define DA7219_CHIP_ID1 0x81
86#define DA7219_CHIP_ID2 0x82
87#define DA7219_CHIP_REVISION 0x83
88#define DA7219_LDO_CTRL 0x90
89#define DA7219_IO_CTRL 0x91
90#define DA7219_GAIN_RAMP_CTRL 0x92
91#define DA7219_PC_COUNT 0x94
92#define DA7219_CP_VOL_THRESHOLD1 0x95
93#define DA7219_CP_DELAY 0x96
94#define DA7219_DIG_CTRL 0x99
95#define DA7219_ALC_CTRL2 0x9A
96#define DA7219_ALC_CTRL3 0x9B
97#define DA7219_ALC_NOISE 0x9C
98#define DA7219_ALC_TARGET_MIN 0x9D
99#define DA7219_ALC_TARGET_MAX 0x9E
100#define DA7219_ALC_GAIN_LIMITS 0x9F
101#define DA7219_ALC_ANA_GAIN_LIMITS 0xA0
102#define DA7219_ALC_ANTICLIP_CTRL 0xA1
103#define DA7219_ALC_ANTICLIP_LEVEL 0xA2
104#define DA7219_ALC_OFFSET_AUTO_M_L 0xA3
105#define DA7219_ALC_OFFSET_AUTO_U_L 0xA4
106#define DA7219_DAC_NG_SETUP_TIME 0xAF
107#define DA7219_DAC_NG_OFF_THRESH 0xB0
108#define DA7219_DAC_NG_ON_THRESH 0xB1
109#define DA7219_DAC_NG_CTRL 0xB2
110#define DA7219_TONE_GEN_CFG1 0xB4
111#define DA7219_TONE_GEN_CFG2 0xB5
112#define DA7219_TONE_GEN_CYCLES 0xB6
113#define DA7219_TONE_GEN_FREQ1_L 0xB7
114#define DA7219_TONE_GEN_FREQ1_U 0xB8
115#define DA7219_TONE_GEN_FREQ2_L 0xB9
116#define DA7219_TONE_GEN_FREQ2_U 0xBA
117#define DA7219_TONE_GEN_ON_PER 0xBB
118#define DA7219_TONE_GEN_OFF_PER 0xBC
119#define DA7219_SYSTEM_STATUS 0xE0
120#define DA7219_SYSTEM_ACTIVE 0xFD
121
122
123/*
124 * Bit Fields
125 */
126
127#define DA7219_SWITCH_EN_MAX 0x1
128
129/* DA7219_MIC_1_GAIN_STATUS = 0x6 */
130#define DA7219_MIC_1_AMP_GAIN_STATUS_SHIFT 0
131#define DA7219_MIC_1_AMP_GAIN_STATUS_MASK (0x7 << 0)
132#define DA7219_MIC_1_AMP_GAIN_MAX 0x7
133
134/* DA7219_MIXIN_L_GAIN_STATUS = 0x8 */
135#define DA7219_MIXIN_L_AMP_GAIN_STATUS_SHIFT 0
136#define DA7219_MIXIN_L_AMP_GAIN_STATUS_MASK (0xF << 0)
137
138/* DA7219_ADC_L_GAIN_STATUS = 0xA */
139#define DA7219_ADC_L_DIGITAL_GAIN_STATUS_SHIFT 0
140#define DA7219_ADC_L_DIGITAL_GAIN_STATUS_MASK (0x7F << 0)
141
142/* DA7219_DAC_L_GAIN_STATUS = 0xC */
143#define DA7219_DAC_L_DIGITAL_GAIN_STATUS_SHIFT 0
144#define DA7219_DAC_L_DIGITAL_GAIN_STATUS_MASK (0x7F << 0)
145
146/* DA7219_DAC_R_GAIN_STATUS = 0xD */
147#define DA7219_DAC_R_DIGITAL_GAIN_STATUS_SHIFT 0
148#define DA7219_DAC_R_DIGITAL_GAIN_STATUS_MASK (0x7F << 0)
149
150/* DA7219_HP_L_GAIN_STATUS = 0xE */
151#define DA7219_HP_L_AMP_GAIN_STATUS_SHIFT 0
152#define DA7219_HP_L_AMP_GAIN_STATUS_MASK (0x3F << 0)
153
154/* DA7219_HP_R_GAIN_STATUS = 0xF */
155#define DA7219_HP_R_AMP_GAIN_STATUS_SHIFT 0
156#define DA7219_HP_R_AMP_GAIN_STATUS_MASK (0x3F << 0)
157
158/* DA7219_MIC_1_SELECT = 0x10 */
159#define DA7219_MIC_1_AMP_IN_SEL_SHIFT 0
160#define DA7219_MIC_1_AMP_IN_SEL_MASK (0x3 << 0)
161
162/* DA7219_CIF_TIMEOUT_CTRL = 0x12 */
163#define DA7219_I2C_TIMEOUT_EN_SHIFT 0
164#define DA7219_I2C_TIMEOUT_EN_MASK (0x1 << 0)
165
166/* DA7219_CIF_CTRL = 0x13 */
167#define DA7219_CIF_I2C_WRITE_MODE_SHIFT 0
168#define DA7219_CIF_I2C_WRITE_MODE_MASK (0x1 << 0)
169#define DA7219_CIF_REG_SOFT_RESET_SHIFT 7
170#define DA7219_CIF_REG_SOFT_RESET_MASK (0x1 << 7)
171
172/* DA7219_SR_24_48 = 0x16 */
173#define DA7219_SR_24_48_SHIFT 0
174#define DA7219_SR_24_48_MASK (0x1 << 0)
175
176/* DA7219_SR = 0x17 */
177#define DA7219_SR_SHIFT 0
178#define DA7219_SR_MASK (0xF << 0)
179#define DA7219_SR_8000 (0x01 << 0)
180#define DA7219_SR_11025 (0x02 << 0)
181#define DA7219_SR_12000 (0x03 << 0)
182#define DA7219_SR_16000 (0x05 << 0)
183#define DA7219_SR_22050 (0x06 << 0)
184#define DA7219_SR_24000 (0x07 << 0)
185#define DA7219_SR_32000 (0x09 << 0)
186#define DA7219_SR_44100 (0x0A << 0)
187#define DA7219_SR_48000 (0x0B << 0)
188#define DA7219_SR_88200 (0x0E << 0)
189#define DA7219_SR_96000 (0x0F << 0)
190
191/* DA7219_CIF_I2C_ADDR_CFG = 0x1B */
192#define DA7219_CIF_I2C_ADDR_CFG_SHIFT 0
193#define DA7219_CIF_I2C_ADDR_CFG_MASK (0x3 << 0)
194
195/* DA7219_PLL_CTRL = 0x20 */
196#define DA7219_PLL_INDIV_SHIFT 2
197#define DA7219_PLL_INDIV_MASK (0x7 << 2)
198#define DA7219_PLL_INDIV_2_5_MHZ (0x0 << 2)
199#define DA7219_PLL_INDIV_5_10_MHZ (0x1 << 2)
200#define DA7219_PLL_INDIV_10_20_MHZ (0x2 << 2)
201#define DA7219_PLL_INDIV_20_40_MHZ (0x3 << 2)
202#define DA7219_PLL_INDIV_40_54_MHZ (0x4 << 2)
203#define DA7219_PLL_MCLK_SQR_EN_SHIFT 5
204#define DA7219_PLL_MCLK_SQR_EN_MASK (0x1 << 5)
205#define DA7219_PLL_MODE_SHIFT 6
206#define DA7219_PLL_MODE_MASK (0x3 << 6)
207#define DA7219_PLL_MODE_BYPASS (0x0 << 6)
208#define DA7219_PLL_MODE_NORMAL (0x1 << 6)
209#define DA7219_PLL_MODE_SRM (0x2 << 6)
210#define DA7219_PLL_MODE_32KHZ (0x3 << 6)
211
212/* DA7219_PLL_FRAC_TOP = 0x22 */
213#define DA7219_PLL_FBDIV_FRAC_TOP_SHIFT 0
214#define DA7219_PLL_FBDIV_FRAC_TOP_MASK (0x1F << 0)
215
216/* DA7219_PLL_FRAC_BOT = 0x23 */
217#define DA7219_PLL_FBDIV_FRAC_BOT_SHIFT 0
218#define DA7219_PLL_FBDIV_FRAC_BOT_MASK (0xFF << 0)
219
220/* DA7219_PLL_INTEGER = 0x24 */
221#define DA7219_PLL_FBDIV_INTEGER_SHIFT 0
222#define DA7219_PLL_FBDIV_INTEGER_MASK (0x7F << 0)
223
224/* DA7219_PLL_SRM_STS = 0x25 */
225#define DA7219_PLL_SRM_STATE_SHIFT 0
226#define DA7219_PLL_SRM_STATE_MASK (0xF << 0)
227#define DA7219_PLL_SRM_STATUS_SHIFT 4
228#define DA7219_PLL_SRM_STATUS_MASK (0xF << 4)
229#define DA7219_PLL_SRM_STS_SRM_LOCK (0x1 << 7)
230
231/* DA7219_DIG_ROUTING_DAI = 0x2A */
232#define DA7219_DAI_L_SRC_SHIFT 0
233#define DA7219_DAI_L_SRC_MASK (0x3 << 0)
234#define DA7219_DAI_R_SRC_SHIFT 4
235#define DA7219_DAI_R_SRC_MASK (0x3 << 4)
236#define DA7219_OUT_SRC_MAX 4
237
238/* DA7219_DAI_CLK_MODE = 0x2B */
239#define DA7219_DAI_BCLKS_PER_WCLK_SHIFT 0
240#define DA7219_DAI_BCLKS_PER_WCLK_MASK (0x3 << 0)
241#define DA7219_DAI_BCLKS_PER_WCLK_32 (0x0 << 0)
242#define DA7219_DAI_BCLKS_PER_WCLK_64 (0x1 << 0)
243#define DA7219_DAI_BCLKS_PER_WCLK_128 (0x2 << 0)
244#define DA7219_DAI_BCLKS_PER_WCLK_256 (0x3 << 0)
245#define DA7219_DAI_CLK_POL_SHIFT 2
246#define DA7219_DAI_CLK_POL_MASK (0x1 << 2)
247#define DA7219_DAI_CLK_POL_INV (0x1 << 2)
248#define DA7219_DAI_WCLK_POL_SHIFT 3
249#define DA7219_DAI_WCLK_POL_MASK (0x1 << 3)
250#define DA7219_DAI_WCLK_POL_INV (0x1 << 3)
251#define DA7219_DAI_WCLK_TRI_STATE_SHIFT 4
252#define DA7219_DAI_WCLK_TRI_STATE_MASK (0x1 << 4)
253#define DA7219_DAI_CLK_EN_SHIFT 7
254#define DA7219_DAI_CLK_EN_MASK (0x1 << 7)
255
256/* DA7219_DAI_CTRL = 0x2C */
257#define DA7219_DAI_FORMAT_SHIFT 0
258#define DA7219_DAI_FORMAT_MASK (0x3 << 0)
259#define DA7219_DAI_FORMAT_I2S (0x0 << 0)
260#define DA7219_DAI_FORMAT_LEFT_J (0x1 << 0)
261#define DA7219_DAI_FORMAT_RIGHT_J (0x2 << 0)
262#define DA7219_DAI_FORMAT_DSP (0x3 << 0)
263#define DA7219_DAI_WORD_LENGTH_SHIFT 2
264#define DA7219_DAI_WORD_LENGTH_MASK (0x3 << 2)
265#define DA7219_DAI_WORD_LENGTH_S16_LE (0x0 << 2)
266#define DA7219_DAI_WORD_LENGTH_S20_LE (0x1 << 2)
267#define DA7219_DAI_WORD_LENGTH_S24_LE (0x2 << 2)
268#define DA7219_DAI_WORD_LENGTH_S32_LE (0x3 << 2)
269#define DA7219_DAI_CH_NUM_SHIFT 4
270#define DA7219_DAI_CH_NUM_MASK (0x3 << 4)
271#define DA7219_DAI_CH_NUM_MAX 2
272#define DA7219_DAI_EN_SHIFT 7
273#define DA7219_DAI_EN_MASK (0x1 << 7)
274
275/* DA7219_DAI_TDM_CTRL = 0x2D */
276#define DA7219_DAI_TDM_CH_EN_SHIFT 0
277#define DA7219_DAI_TDM_CH_EN_MASK (0x3 << 0)
278#define DA7219_DAI_OE_SHIFT 6
279#define DA7219_DAI_OE_MASK (0x1 << 6)
280#define DA7219_DAI_TDM_MODE_EN_SHIFT 7
281#define DA7219_DAI_TDM_MODE_EN_MASK (0x1 << 7)
282#define DA7219_DAI_TDM_MAX_SLOTS 2
283
284/* DA7219_DIG_ROUTING_DAC = 0x2E */
285#define DA7219_DAC_L_SRC_SHIFT 0
286#define DA7219_DAC_L_SRC_MASK (0x3 << 0)
287#define DA7219_DAC_L_SRC_TONEGEN (0x1 << 0)
288#define DA7219_DAC_L_MONO_SHIFT 3
289#define DA7219_DAC_L_MONO_MASK (0x1 << 3)
290#define DA7219_DAC_R_SRC_SHIFT 4
291#define DA7219_DAC_R_SRC_MASK (0x3 << 4)
292#define DA7219_DAC_R_SRC_TONEGEN (0x1 << 4)
293#define DA7219_DAC_R_MONO_SHIFT 7
294#define DA7219_DAC_R_MONO_MASK (0x1 << 7)
295
296/* DA7219_ALC_CTRL1 = 0x2F */
297#define DA7219_ALC_OFFSET_EN_SHIFT 0
298#define DA7219_ALC_OFFSET_EN_MASK (0x1 << 0)
299#define DA7219_ALC_SYNC_MODE_SHIFT 1
300#define DA7219_ALC_SYNC_MODE_MASK (0x1 << 1)
301#define DA7219_ALC_EN_SHIFT 3
302#define DA7219_ALC_EN_MASK (0x1 << 3)
303#define DA7219_ALC_AUTO_CALIB_EN_SHIFT 4
304#define DA7219_ALC_AUTO_CALIB_EN_MASK (0x1 << 4)
305#define DA7219_ALC_CALIB_OVERFLOW_SHIFT 5
306#define DA7219_ALC_CALIB_OVERFLOW_MASK (0x1 << 5)
307
308/* DA7219_DAI_OFFSET_LOWER = 0x30 */
309#define DA7219_DAI_OFFSET_LOWER_SHIFT 0
310#define DA7219_DAI_OFFSET_LOWER_MASK (0xFF << 0)
311
312/* DA7219_DAI_OFFSET_UPPER = 0x31 */
313#define DA7219_DAI_OFFSET_UPPER_SHIFT 0
314#define DA7219_DAI_OFFSET_UPPER_MASK (0x7 << 0)
315#define DA7219_DAI_OFFSET_MAX 0x2FF
316
317/* DA7219_REFERENCES = 0x32 */
318#define DA7219_BIAS_EN_SHIFT 3
319#define DA7219_BIAS_EN_MASK (0x1 << 3)
320#define DA7219_VMID_FAST_CHARGE_SHIFT 4
321#define DA7219_VMID_FAST_CHARGE_MASK (0x1 << 4)
322
323/* DA7219_MIXIN_L_SELECT = 0x33 */
324#define DA7219_MIXIN_L_MIX_SELECT_SHIFT 0
325#define DA7219_MIXIN_L_MIX_SELECT_MASK (0x1 << 0)
326
327/* DA7219_MIXIN_L_GAIN = 0x34 */
328#define DA7219_MIXIN_L_AMP_GAIN_SHIFT 0
329#define DA7219_MIXIN_L_AMP_GAIN_MASK (0xF << 0)
330#define DA7219_MIXIN_L_AMP_GAIN_MAX 0xF
331
332/* DA7219_ADC_L_GAIN = 0x36 */
333#define DA7219_ADC_L_DIGITAL_GAIN_SHIFT 0
334#define DA7219_ADC_L_DIGITAL_GAIN_MASK (0x7F << 0)
335#define DA7219_ADC_L_DIGITAL_GAIN_MAX 0x7F
336
337/* DA7219_ADC_FILTERS1 = 0x38 */
338#define DA7219_ADC_VOICE_HPF_CORNER_SHIFT 0
339#define DA7219_ADC_VOICE_HPF_CORNER_MASK (0x7 << 0)
340#define DA7219_VOICE_HPF_CORNER_MAX 8
341#define DA7219_ADC_VOICE_EN_SHIFT 3
342#define DA7219_ADC_VOICE_EN_MASK (0x1 << 3)
343#define DA7219_ADC_AUDIO_HPF_CORNER_SHIFT 4
344#define DA7219_ADC_AUDIO_HPF_CORNER_MASK (0x3 << 4)
345#define DA7219_AUDIO_HPF_CORNER_MAX 4
346#define DA7219_ADC_HPF_EN_SHIFT 7
347#define DA7219_ADC_HPF_EN_MASK (0x1 << 7)
348#define DA7219_HPF_MODE_SHIFT 0
349#define DA7219_HPF_DISABLED ((0x0 << 3) | (0x0 << 7))
350#define DA7219_HPF_AUDIO_EN ((0x0 << 3) | (0x1 << 7))
351#define DA7219_HPF_VOICE_EN ((0x1 << 3) | (0x1 << 7))
352#define DA7219_HPF_MODE_MASK ((0x1 << 3) | (0x1 << 7))
353#define DA7219_HPF_MODE_MAX 3
354
355/* DA7219_MIC_1_GAIN = 0x39 */
356#define DA7219_MIC_1_AMP_GAIN_SHIFT 0
357#define DA7219_MIC_1_AMP_GAIN_MASK (0x7 << 0)
358
359/* DA7219_SIDETONE_CTRL = 0x3A */
360#define DA7219_SIDETONE_MUTE_EN_SHIFT 6
361#define DA7219_SIDETONE_MUTE_EN_MASK (0x1 << 6)
362#define DA7219_SIDETONE_EN_SHIFT 7
363#define DA7219_SIDETONE_EN_MASK (0x1 << 7)
364
365/* DA7219_SIDETONE_GAIN = 0x3B */
366#define DA7219_SIDETONE_GAIN_SHIFT 0
367#define DA7219_SIDETONE_GAIN_MASK (0xF << 0)
368#define DA7219_SIDETONE_GAIN_MAX 0xE
369
370/* DA7219_DROUTING_ST_OUTFILT_1L = 0x3C */
371#define DA7219_OUTFILT_ST_1L_SRC_SHIFT 0
372#define DA7219_OUTFILT_ST_1L_SRC_MASK (0x7 << 0)
373#define DA7219_DMIX_ST_SRC_OUTFILT1L_SHIFT 0
374#define DA7219_DMIX_ST_SRC_OUTFILT1R_SHIFT 1
375#define DA7219_DMIX_ST_SRC_SIDETONE_SHIFT 2
376#define DA7219_DMIX_ST_SRC_OUTFILT1L (0x1 << 0)
377#define DA7219_DMIX_ST_SRC_OUTFILT1R (0x1 << 1)
378
379/* DA7219_DROUTING_ST_OUTFILT_1R = 0x3D */
380#define DA7219_OUTFILT_ST_1R_SRC_SHIFT 0
381#define DA7219_OUTFILT_ST_1R_SRC_MASK (0x7 << 0)
382
383/* DA7219_DAC_FILTERS5 = 0x40 */
384#define DA7219_DAC_SOFTMUTE_RATE_SHIFT 4
385#define DA7219_DAC_SOFTMUTE_RATE_MASK (0x7 << 4)
386#define DA7219_DAC_SOFTMUTE_RATE_MAX 7
387#define DA7219_DAC_SOFTMUTE_EN_SHIFT 7
388#define DA7219_DAC_SOFTMUTE_EN_MASK (0x1 << 7)
389
390/* DA7219_DAC_FILTERS2 = 0x41 */
391#define DA7219_DAC_EQ_BAND1_SHIFT 0
392#define DA7219_DAC_EQ_BAND1_MASK (0xF << 0)
393#define DA7219_DAC_EQ_BAND2_SHIFT 4
394#define DA7219_DAC_EQ_BAND2_MASK (0xF << 4)
395#define DA7219_DAC_EQ_BAND_MAX 0xF
396
397/* DA7219_DAC_FILTERS3 = 0x42 */
398#define DA7219_DAC_EQ_BAND3_SHIFT 0
399#define DA7219_DAC_EQ_BAND3_MASK (0xF << 0)
400#define DA7219_DAC_EQ_BAND4_SHIFT 4
401#define DA7219_DAC_EQ_BAND4_MASK (0xF << 4)
402
403/* DA7219_DAC_FILTERS4 = 0x43 */
404#define DA7219_DAC_EQ_BAND5_SHIFT 0
405#define DA7219_DAC_EQ_BAND5_MASK (0xF << 0)
406#define DA7219_DAC_EQ_EN_SHIFT 7
407#define DA7219_DAC_EQ_EN_MASK (0x1 << 7)
408
409/* DA7219_DAC_FILTERS1 = 0x44 */
410#define DA7219_DAC_VOICE_HPF_CORNER_SHIFT 0
411#define DA7219_DAC_VOICE_HPF_CORNER_MASK (0x7 << 0)
412#define DA7219_DAC_VOICE_EN_SHIFT 3
413#define DA7219_DAC_VOICE_EN_MASK (0x1 << 3)
414#define DA7219_DAC_AUDIO_HPF_CORNER_SHIFT 4
415#define DA7219_DAC_AUDIO_HPF_CORNER_MASK (0x3 << 4)
416#define DA7219_DAC_HPF_EN_SHIFT 7
417#define DA7219_DAC_HPF_EN_MASK (0x1 << 7)
418
419/* DA7219_DAC_L_GAIN = 0x45 */
420#define DA7219_DAC_L_DIGITAL_GAIN_SHIFT 0
421#define DA7219_DAC_L_DIGITAL_GAIN_MASK (0x7F << 0)
422#define DA7219_DAC_DIGITAL_GAIN_MAX 0x7F
423#define DA7219_DAC_DIGITAL_GAIN_0DB (0x6F << 0)
424
425/* DA7219_DAC_R_GAIN = 0x46 */
426#define DA7219_DAC_R_DIGITAL_GAIN_SHIFT 0
427#define DA7219_DAC_R_DIGITAL_GAIN_MASK (0x7F << 0)
428
429/* DA7219_CP_CTRL = 0x47 */
430#define DA7219_CP_MCHANGE_SHIFT 4
431#define DA7219_CP_MCHANGE_MASK (0x3 << 4)
432#define DA7219_CP_MCHANGE_REL_MASK 0x3
433#define DA7219_CP_MCHANGE_MAX 3
434#define DA7219_CP_MCHANGE_LARGEST_VOL 0x1
435#define DA7219_CP_MCHANGE_DAC_VOL 0x2
436#define DA7219_CP_MCHANGE_SIG_MAG 0x3
437#define DA7219_CP_EN_SHIFT 7
438#define DA7219_CP_EN_MASK (0x1 << 7)
439
440/* DA7219_HP_L_GAIN = 0x48 */
441#define DA7219_HP_L_AMP_GAIN_SHIFT 0
442#define DA7219_HP_L_AMP_GAIN_MASK (0x3F << 0)
443#define DA7219_HP_AMP_GAIN_MAX 0x3F
444#define DA7219_HP_AMP_GAIN_0DB (0x39 << 0)
445
446/* DA7219_HP_R_GAIN = 0x49 */
447#define DA7219_HP_R_AMP_GAIN_SHIFT 0
448#define DA7219_HP_R_AMP_GAIN_MASK (0x3F << 0)
449
450/* DA7219_MIXOUT_L_SELECT = 0x4B */
451#define DA7219_MIXOUT_L_MIX_SELECT_SHIFT 0
452#define DA7219_MIXOUT_L_MIX_SELECT_MASK (0x1 << 0)
453
454/* DA7219_MIXOUT_R_SELECT = 0x4C */
455#define DA7219_MIXOUT_R_MIX_SELECT_SHIFT 0
456#define DA7219_MIXOUT_R_MIX_SELECT_MASK (0x1 << 0)
457
458/* DA7219_SYSTEM_MODES_INPUT = 0x50 */
459#define DA7219_MODE_SUBMIT_SHIFT 0
460#define DA7219_MODE_SUBMIT_MASK (0x1 << 0)
461#define DA7219_ADC_MODE_SHIFT 1
462#define DA7219_ADC_MODE_MASK (0x7F << 1)
463
464/* DA7219_SYSTEM_MODES_OUTPUT = 0x51 */
465#define DA7219_MODE_SUBMIT_SHIFT 0
466#define DA7219_MODE_SUBMIT_MASK (0x1 << 0)
467#define DA7219_DAC_MODE_SHIFT 1
468#define DA7219_DAC_MODE_MASK (0x7F << 1)
469
470/* DA7219_MICBIAS_CTRL = 0x62 */
471#define DA7219_MICBIAS1_LEVEL_SHIFT 0
472#define DA7219_MICBIAS1_LEVEL_MASK (0x7 << 0)
473#define DA7219_MICBIAS1_EN_SHIFT 3
474#define DA7219_MICBIAS1_EN_MASK (0x1 << 3)
475
476/* DA7219_MIC_1_CTRL = 0x63 */
477#define DA7219_MIC_1_AMP_RAMP_EN_SHIFT 5
478#define DA7219_MIC_1_AMP_RAMP_EN_MASK (0x1 << 5)
479#define DA7219_MIC_1_AMP_MUTE_EN_SHIFT 6
480#define DA7219_MIC_1_AMP_MUTE_EN_MASK (0x1 << 6)
481#define DA7219_MIC_1_AMP_EN_SHIFT 7
482#define DA7219_MIC_1_AMP_EN_MASK (0x1 << 7)
483
484/* DA7219_MIXIN_L_CTRL = 0x65 */
485#define DA7219_MIXIN_L_MIX_EN_SHIFT 3
486#define DA7219_MIXIN_L_MIX_EN_MASK (0x1 << 3)
487#define DA7219_MIXIN_L_AMP_ZC_EN_SHIFT 4
488#define DA7219_MIXIN_L_AMP_ZC_EN_MASK (0x1 << 4)
489#define DA7219_MIXIN_L_AMP_RAMP_EN_SHIFT 5
490#define DA7219_MIXIN_L_AMP_RAMP_EN_MASK (0x1 << 5)
491#define DA7219_MIXIN_L_AMP_MUTE_EN_SHIFT 6
492#define DA7219_MIXIN_L_AMP_MUTE_EN_MASK (0x1 << 6)
493#define DA7219_MIXIN_L_AMP_EN_SHIFT 7
494#define DA7219_MIXIN_L_AMP_EN_MASK (0x1 << 7)
495
496/* DA7219_ADC_L_CTRL = 0x67 */
497#define DA7219_ADC_L_BIAS_SHIFT 0
498#define DA7219_ADC_L_BIAS_MASK (0x3 << 0)
499#define DA7219_ADC_L_RAMP_EN_SHIFT 5
500#define DA7219_ADC_L_RAMP_EN_MASK (0x1 << 5)
501#define DA7219_ADC_L_MUTE_EN_SHIFT 6
502#define DA7219_ADC_L_MUTE_EN_MASK (0x1 << 6)
503#define DA7219_ADC_L_EN_SHIFT 7
504#define DA7219_ADC_L_EN_MASK (0x1 << 7)
505
506/* DA7219_DAC_L_CTRL = 0x69 */
507#define DA7219_DAC_L_RAMP_EN_SHIFT 5
508#define DA7219_DAC_L_RAMP_EN_MASK (0x1 << 5)
509#define DA7219_DAC_L_MUTE_EN_SHIFT 6
510#define DA7219_DAC_L_MUTE_EN_MASK (0x1 << 6)
511#define DA7219_DAC_L_EN_SHIFT 7
512#define DA7219_DAC_L_EN_MASK (0x1 << 7)
513
514/* DA7219_DAC_R_CTRL = 0x6A */
515#define DA7219_DAC_R_RAMP_EN_SHIFT 5
516#define DA7219_DAC_R_RAMP_EN_MASK (0x1 << 5)
517#define DA7219_DAC_R_MUTE_EN_SHIFT 6
518#define DA7219_DAC_R_MUTE_EN_MASK (0x1 << 6)
519#define DA7219_DAC_R_EN_SHIFT 7
520#define DA7219_DAC_R_EN_MASK (0x1 << 7)
521
522/* DA7219_HP_L_CTRL = 0x6B */
523#define DA7219_HP_L_AMP_MIN_GAIN_EN_SHIFT 2
524#define DA7219_HP_L_AMP_MIN_GAIN_EN_MASK (0x1 << 2)
525#define DA7219_HP_L_AMP_OE_SHIFT 3
526#define DA7219_HP_L_AMP_OE_MASK (0x1 << 3)
527#define DA7219_HP_L_AMP_ZC_EN_SHIFT 4
528#define DA7219_HP_L_AMP_ZC_EN_MASK (0x1 << 4)
529#define DA7219_HP_L_AMP_RAMP_EN_SHIFT 5
530#define DA7219_HP_L_AMP_RAMP_EN_MASK (0x1 << 5)
531#define DA7219_HP_L_AMP_MUTE_EN_SHIFT 6
532#define DA7219_HP_L_AMP_MUTE_EN_MASK (0x1 << 6)
533#define DA7219_HP_L_AMP_EN_SHIFT 7
534#define DA7219_HP_L_AMP_EN_MASK (0x1 << 7)
535
536/* DA7219_HP_R_CTRL = 0x6C */
537#define DA7219_HP_R_AMP_MIN_GAIN_EN_SHIFT 2
538#define DA7219_HP_R_AMP_MIN_GAIN_EN_MASK (0x1 << 2)
539#define DA7219_HP_R_AMP_OE_SHIFT 3
540#define DA7219_HP_R_AMP_OE_MASK (0x1 << 3)
541#define DA7219_HP_R_AMP_ZC_EN_SHIFT 4
542#define DA7219_HP_R_AMP_ZC_EN_MASK (0x1 << 4)
543#define DA7219_HP_R_AMP_RAMP_EN_SHIFT 5
544#define DA7219_HP_R_AMP_RAMP_EN_MASK (0x1 << 5)
545#define DA7219_HP_R_AMP_MUTE_EN_SHIFT 6
546#define DA7219_HP_R_AMP_MUTE_EN_MASK (0x1 << 6)
547#define DA7219_HP_R_AMP_EN_SHIFT 7
548#define DA7219_HP_R_AMP_EN_MASK (0x1 << 7)
549
550/* DA7219_MIXOUT_L_CTRL = 0x6E */
551#define DA7219_MIXOUT_L_AMP_EN_SHIFT 7
552#define DA7219_MIXOUT_L_AMP_EN_MASK (0x1 << 7)
553
554/* DA7219_MIXOUT_R_CTRL = 0x6F */
555#define DA7219_MIXOUT_R_AMP_EN_SHIFT 7
556#define DA7219_MIXOUT_R_AMP_EN_MASK (0x1 << 7)
557
558/* DA7219_CHIP_ID1 = 0x81 */
559#define DA7219_CHIP_ID1_SHIFT 0
560#define DA7219_CHIP_ID1_MASK (0xFF << 0)
561
562/* DA7219_CHIP_ID2 = 0x82 */
563#define DA7219_CHIP_ID2_SHIFT 0
564#define DA7219_CHIP_ID2_MASK (0xFF << 0)
565
566/* DA7219_CHIP_REVISION = 0x83 */
567#define DA7219_CHIP_MINOR_SHIFT 0
568#define DA7219_CHIP_MINOR_MASK (0xF << 0)
569#define DA7219_CHIP_MAJOR_SHIFT 4
570#define DA7219_CHIP_MAJOR_MASK (0xF << 4)
571
572/* DA7219_LDO_CTRL = 0x90 */
573#define DA7219_LDO_LEVEL_SELECT_SHIFT 4
574#define DA7219_LDO_LEVEL_SELECT_MASK (0x3 << 4)
575#define DA7219_LDO_EN_SHIFT 7
576#define DA7219_LDO_EN_MASK (0x1 << 7)
577
578/* DA7219_IO_CTRL = 0x91 */
579#define DA7219_IO_VOLTAGE_LEVEL_SHIFT 0
580#define DA7219_IO_VOLTAGE_LEVEL_MASK (0x1 << 0)
581#define DA7219_IO_VOLTAGE_LEVEL_2_5V_3_6V 0
582#define DA7219_IO_VOLTAGE_LEVEL_1_2V_2_8V 1
583
584/* DA7219_GAIN_RAMP_CTRL = 0x92 */
585#define DA7219_GAIN_RAMP_RATE_SHIFT 0
586#define DA7219_GAIN_RAMP_RATE_MASK (0x3 << 0)
587#define DA7219_GAIN_RAMP_RATE_MAX 4
588
589/* DA7219_PC_COUNT = 0x94 */
590#define DA7219_PC_FREERUN_SHIFT 0
591#define DA7219_PC_FREERUN_MASK (0x1 << 0)
592#define DA7219_PC_RESYNC_AUTO_SHIFT 1
593#define DA7219_PC_RESYNC_AUTO_MASK (0x1 << 1)
594
595/* DA7219_CP_VOL_THRESHOLD1 = 0x95 */
596#define DA7219_CP_THRESH_VDD2_SHIFT 0
597#define DA7219_CP_THRESH_VDD2_MASK (0x3F << 0)
598#define DA7219_CP_THRESH_VDD2_MAX 0x3F
599
600/* DA7219_DIG_CTRL = 0x99 */
601#define DA7219_DAC_L_INV_SHIFT 3
602#define DA7219_DAC_L_INV_MASK (0x1 << 3)
603#define DA7219_DAC_R_INV_SHIFT 7
604#define DA7219_DAC_R_INV_MASK (0x1 << 7)
605
606/* DA7219_ALC_CTRL2 = 0x9A */
607#define DA7219_ALC_ATTACK_SHIFT 0
608#define DA7219_ALC_ATTACK_MASK (0xF << 0)
609#define DA7219_ALC_ATTACK_MAX 13
610#define DA7219_ALC_RELEASE_SHIFT 4
611#define DA7219_ALC_RELEASE_MASK (0xF << 4)
612#define DA7219_ALC_RELEASE_MAX 11
613
614/* DA7219_ALC_CTRL3 = 0x9B */
615#define DA7219_ALC_HOLD_SHIFT 0
616#define DA7219_ALC_HOLD_MASK (0xF << 0)
617#define DA7219_ALC_HOLD_MAX 16
618#define DA7219_ALC_INTEG_ATTACK_SHIFT 4
619#define DA7219_ALC_INTEG_ATTACK_MASK (0x3 << 4)
620#define DA7219_ALC_INTEG_RELEASE_SHIFT 6
621#define DA7219_ALC_INTEG_RELEASE_MASK (0x3 << 6)
622#define DA7219_ALC_INTEG_MAX 4
623
624/* DA7219_ALC_NOISE = 0x9C */
625#define DA7219_ALC_NOISE_SHIFT 0
626#define DA7219_ALC_NOISE_MASK (0x3F << 0)
627#define DA7219_ALC_THRESHOLD_MAX 0x3F
628
629/* DA7219_ALC_TARGET_MIN = 0x9D */
630#define DA7219_ALC_THRESHOLD_MIN_SHIFT 0
631#define DA7219_ALC_THRESHOLD_MIN_MASK (0x3F << 0)
632
633/* DA7219_ALC_TARGET_MAX = 0x9E */
634#define DA7219_ALC_THRESHOLD_MAX_SHIFT 0
635#define DA7219_ALC_THRESHOLD_MAX_MASK (0x3F << 0)
636
637/* DA7219_ALC_GAIN_LIMITS = 0x9F */
638#define DA7219_ALC_ATTEN_MAX_SHIFT 0
639#define DA7219_ALC_ATTEN_MAX_MASK (0xF << 0)
640#define DA7219_ALC_GAIN_MAX_SHIFT 4
641#define DA7219_ALC_GAIN_MAX_MASK (0xF << 4)
642#define DA7219_ALC_ATTEN_GAIN_MAX 0xF
643
644/* DA7219_ALC_ANA_GAIN_LIMITS = 0xA0 */
645#define DA7219_ALC_ANA_GAIN_MIN_SHIFT 0
646#define DA7219_ALC_ANA_GAIN_MIN_MASK (0x7 << 0)
647#define DA7219_ALC_ANA_GAIN_MIN 0x1
648#define DA7219_ALC_ANA_GAIN_MAX_SHIFT 4
649#define DA7219_ALC_ANA_GAIN_MAX_MASK (0x7 << 4)
650#define DA7219_ALC_ANA_GAIN_MAX 0x7
651
652/* DA7219_ALC_ANTICLIP_CTRL = 0xA1 */
653#define DA7219_ALC_ANTICLIP_STEP_SHIFT 0
654#define DA7219_ALC_ANTICLIP_STEP_MASK (0x3 << 0)
655#define DA7219_ALC_ANTICLIP_STEP_MAX 4
656#define DA7219_ALC_ANTIPCLIP_EN_SHIFT 7
657#define DA7219_ALC_ANTIPCLIP_EN_MASK (0x1 << 7)
658
659/* DA7219_ALC_ANTICLIP_LEVEL = 0xA2 */
660#define DA7219_ALC_ANTICLIP_LEVEL_SHIFT 0
661#define DA7219_ALC_ANTICLIP_LEVEL_MASK (0x7F << 0)
662
663/* DA7219_ALC_OFFSET_AUTO_M_L = 0xA3 */
664#define DA7219_ALC_OFFSET_AUTO_M_L_SHIFT 0
665#define DA7219_ALC_OFFSET_AUTO_M_L_MASK (0xFF << 0)
666
667/* DA7219_ALC_OFFSET_AUTO_U_L = 0xA4 */
668#define DA7219_ALC_OFFSET_AUTO_U_L_SHIFT 0
669#define DA7219_ALC_OFFSET_AUTO_U_L_MASK (0xF << 0)
670
671/* DA7219_DAC_NG_SETUP_TIME = 0xAF */
672#define DA7219_DAC_NG_SETUP_TIME_SHIFT 0
673#define DA7219_DAC_NG_SETUP_TIME_MASK (0x3 << 0)
674#define DA7219_DAC_NG_SETUP_TIME_MAX 4
675#define DA7219_DAC_NG_RAMPUP_RATE_SHIFT 2
676#define DA7219_DAC_NG_RAMPUP_RATE_MASK (0x1 << 2)
677#define DA7219_DAC_NG_RAMPDN_RATE_SHIFT 3
678#define DA7219_DAC_NG_RAMPDN_RATE_MASK (0x1 << 3)
679#define DA7219_DAC_NG_RAMP_RATE_MAX 2
680
681/* DA7219_DAC_NG_OFF_THRESH = 0xB0 */
682#define DA7219_DAC_NG_OFF_THRESHOLD_SHIFT 0
683#define DA7219_DAC_NG_OFF_THRESHOLD_MASK (0x7 << 0)
684#define DA7219_DAC_NG_THRESHOLD_MAX 0x7
685
686/* DA7219_DAC_NG_ON_THRESH = 0xB1 */
687#define DA7219_DAC_NG_ON_THRESHOLD_SHIFT 0
688#define DA7219_DAC_NG_ON_THRESHOLD_MASK (0x7 << 0)
689
690/* DA7219_DAC_NG_CTRL = 0xB2 */
691#define DA7219_DAC_NG_EN_SHIFT 7
692#define DA7219_DAC_NG_EN_MASK (0x1 << 7)
693
694/* DA7219_TONE_GEN_CFG1 = 0xB4 */
695#define DA7219_DTMF_REG_SHIFT 0
696#define DA7219_DTMF_REG_MASK (0xF << 0)
697#define DA7219_DTMF_REG_MAX 16
698#define DA7219_DTMF_EN_SHIFT 4
699#define DA7219_DTMF_EN_MASK (0x1 << 4)
700#define DA7219_START_STOPN_SHIFT 7
701#define DA7219_START_STOPN_MASK (0x1 << 7)
702
703/* DA7219_TONE_GEN_CFG2 = 0xB5 */
704#define DA7219_SWG_SEL_SHIFT 0
705#define DA7219_SWG_SEL_MASK (0x3 << 0)
706#define DA7219_SWG_SEL_MAX 4
707#define DA7219_SWG_SEL_SRAMP (0x3 << 0)
708#define DA7219_TONE_GEN_GAIN_SHIFT 4
709#define DA7219_TONE_GEN_GAIN_MASK (0xF << 4)
710#define DA7219_TONE_GEN_GAIN_MAX 0xF
711#define DA7219_TONE_GEN_GAIN_MINUS_9DB (0x3 << 4)
712#define DA7219_TONE_GEN_GAIN_MINUS_15DB (0x5 << 4)
713
714/* DA7219_TONE_GEN_CYCLES = 0xB6 */
715#define DA7219_BEEP_CYCLES_SHIFT 0
716#define DA7219_BEEP_CYCLES_MASK (0x7 << 0)
717
718/* DA7219_TONE_GEN_FREQ1_L = 0xB7 */
719#define DA7219_FREQ1_L_SHIFT 0
720#define DA7219_FREQ1_L_MASK (0xFF << 0)
721#define DA7219_FREQ_MAX 0xFFFF
722
723/* DA7219_TONE_GEN_FREQ1_U = 0xB8 */
724#define DA7219_FREQ1_U_SHIFT 0
725#define DA7219_FREQ1_U_MASK (0xFF << 0)
726
727/* DA7219_TONE_GEN_FREQ2_L = 0xB9 */
728#define DA7219_FREQ2_L_SHIFT 0
729#define DA7219_FREQ2_L_MASK (0xFF << 0)
730
731/* DA7219_TONE_GEN_FREQ2_U = 0xBA */
732#define DA7219_FREQ2_U_SHIFT 0
733#define DA7219_FREQ2_U_MASK (0xFF << 0)
734
735/* DA7219_TONE_GEN_ON_PER = 0xBB */
736#define DA7219_BEEP_ON_PER_SHIFT 0
737#define DA7219_BEEP_ON_PER_MASK (0x3F << 0)
738#define DA7219_BEEP_ON_OFF_MAX 0x3F
739
740/* DA7219_TONE_GEN_OFF_PER = 0xBC */
741#define DA7219_BEEP_OFF_PER_SHIFT 0
742#define DA7219_BEEP_OFF_PER_MASK (0x3F << 0)
743
744/* DA7219_SYSTEM_STATUS = 0xE0 */
745#define DA7219_SC1_BUSY_SHIFT 0
746#define DA7219_SC1_BUSY_MASK (0x1 << 0)
747#define DA7219_SC2_BUSY_SHIFT 1
748#define DA7219_SC2_BUSY_MASK (0x1 << 1)
749
750/* DA7219_SYSTEM_ACTIVE = 0xFD */
751#define DA7219_SYSTEM_ACTIVE_SHIFT 0
752#define DA7219_SYSTEM_ACTIVE_MASK (0x1 << 0)
753
754
755/*
756 * General defines & data
757 */
758
759/* Register inversion */
760#define DA7219_NO_INVERT 0
761#define DA7219_INVERT 1
762
763/* Byte related defines */
764#define DA7219_BYTE_SHIFT 8
765#define DA7219_BYTE_MASK 0xFF
766
767/* PLL Output Frequencies */
768#define DA7219_PLL_FREQ_OUT_90316 90316800
769#define DA7219_PLL_FREQ_OUT_98304 98304000
770
771/* PLL Frequency Dividers */
772#define DA7219_PLL_INDIV_2_5_MHZ_VAL 1
773#define DA7219_PLL_INDIV_5_10_MHZ_VAL 2
774#define DA7219_PLL_INDIV_10_20_MHZ_VAL 4
775#define DA7219_PLL_INDIV_20_40_MHZ_VAL 8
776#define DA7219_PLL_INDIV_40_54_MHZ_VAL 16
777
778/* SRM */
779#define DA7219_SRM_CHECK_RETRIES 8
780
781enum da7219_clk_src {
782 DA7219_CLKSRC_MCLK = 0,
783 DA7219_CLKSRC_MCLK_SQR,
784};
785
786enum da7219_sys_clk {
787 DA7219_SYSCLK_MCLK = 0,
788 DA7219_SYSCLK_PLL,
789 DA7219_SYSCLK_PLL_SRM,
790 DA7219_SYSCLK_PLL_32KHZ
791};
792
793/* Regulators */
794enum da7219_supplies {
795 DA7219_SUPPLY_VDD = 0,
796 DA7219_SUPPLY_VDDMIC,
797 DA7219_SUPPLY_VDDIO,
798 DA7219_NUM_SUPPLIES,
799};
800
801struct da7219_aad_priv;
802
803/* Private data */
804struct da7219_priv {
805 struct da7219_aad_priv *aad;
806 struct da7219_pdata *pdata;
807
808 struct regulator_bulk_data supplies[DA7219_NUM_SUPPLIES];
809 struct regmap *regmap;
810 struct mutex lock;
811
812 struct clk *mclk;
813 unsigned int mclk_rate;
814 int clk_src;
815
816 bool master;
817 bool alc_en;
818};
819
820#endif /* __DA7219_H */
diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c
index 6a091016e0fc..969e337dc17c 100644
--- a/sound/soc/codecs/es8328.c
+++ b/sound/soc/codecs/es8328.c
@@ -129,7 +129,7 @@ static int es8328_put_deemph(struct snd_kcontrol *kcontrol,
129{ 129{
130 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 130 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
131 struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); 131 struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec);
132 int deemph = ucontrol->value.integer.value[0]; 132 unsigned int deemph = ucontrol->value.integer.value[0];
133 int ret; 133 int ret;
134 134
135 if (deemph > 1) 135 if (deemph > 1)
diff --git a/sound/soc/codecs/hdmi.c b/sound/soc/codecs/hdmi.c
deleted file mode 100644
index bd42ad34e004..000000000000
--- a/sound/soc/codecs/hdmi.c
+++ /dev/null
@@ -1,109 +0,0 @@
1/*
2 * ALSA SoC codec driver for HDMI audio codecs.
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#include <linux/of.h>
24#include <linux/of_device.h>
25
26#define DRV_NAME "hdmi-audio-codec"
27
28static const struct snd_soc_dapm_widget hdmi_widgets[] = {
29 SND_SOC_DAPM_INPUT("RX"),
30 SND_SOC_DAPM_OUTPUT("TX"),
31};
32
33static const struct snd_soc_dapm_route hdmi_routes[] = {
34 { "Capture", NULL, "RX" },
35 { "TX", NULL, "Playback" },
36};
37
38static struct snd_soc_dai_driver hdmi_codec_dai = {
39 .name = "hdmi-hifi",
40 .playback = {
41 .stream_name = "Playback",
42 .channels_min = 2,
43 .channels_max = 8,
44 .rates = SNDRV_PCM_RATE_32000 |
45 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
46 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
47 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
48 .formats = SNDRV_PCM_FMTBIT_S16_LE |
49 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
50 .sig_bits = 24,
51 },
52 .capture = {
53 .stream_name = "Capture",
54 .channels_min = 2,
55 .channels_max = 2,
56 .rates = SNDRV_PCM_RATE_32000 |
57 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
58 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
59 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
60 .formats = SNDRV_PCM_FMTBIT_S16_LE |
61 SNDRV_PCM_FMTBIT_S24_LE,
62 },
63
64};
65
66#ifdef CONFIG_OF
67static const struct of_device_id hdmi_audio_codec_ids[] = {
68 { .compatible = "linux,hdmi-audio", },
69 { }
70};
71MODULE_DEVICE_TABLE(of, hdmi_audio_codec_ids);
72#endif
73
74static struct snd_soc_codec_driver hdmi_codec = {
75 .dapm_widgets = hdmi_widgets,
76 .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
77 .dapm_routes = hdmi_routes,
78 .num_dapm_routes = ARRAY_SIZE(hdmi_routes),
79 .ignore_pmdown_time = true,
80};
81
82static int hdmi_codec_probe(struct platform_device *pdev)
83{
84 return snd_soc_register_codec(&pdev->dev, &hdmi_codec,
85 &hdmi_codec_dai, 1);
86}
87
88static int hdmi_codec_remove(struct platform_device *pdev)
89{
90 snd_soc_unregister_codec(&pdev->dev);
91 return 0;
92}
93
94static struct platform_driver hdmi_codec_driver = {
95 .driver = {
96 .name = DRV_NAME,
97 .of_match_table = of_match_ptr(hdmi_audio_codec_ids),
98 },
99
100 .probe = hdmi_codec_probe,
101 .remove = hdmi_codec_remove,
102};
103
104module_platform_driver(hdmi_codec_driver);
105
106MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
107MODULE_DESCRIPTION("ASoC generic HDMI codec driver");
108MODULE_LICENSE("GPL");
109MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c
new file mode 100644
index 000000000000..7fc7b4e3f444
--- /dev/null
+++ b/sound/soc/codecs/nau8825.c
@@ -0,0 +1,1309 @@
1/*
2 * Nuvoton NAU8825 audio codec driver
3 *
4 * Copyright 2015 Google Chromium project.
5 * Author: Anatol Pomozov <anatol@chromium.org>
6 * Copyright 2015 Nuvoton Technology Corp.
7 * Co-author: Meng-Huang Kuo <mhkuo@nuvoton.com>
8 *
9 * Licensed under the GPL-2.
10 */
11
12#include <linux/module.h>
13#include <linux/delay.h>
14#include <linux/init.h>
15#include <linux/i2c.h>
16#include <linux/regmap.h>
17#include <linux/slab.h>
18#include <linux/clk.h>
19#include <linux/acpi.h>
20#include <linux/math64.h>
21
22#include <sound/initval.h>
23#include <sound/tlv.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/jack.h>
29
30
31#include "nau8825.h"
32
33#define NAU_FREF_MAX 13500000
34#define NAU_FVCO_MAX 100000000
35#define NAU_FVCO_MIN 90000000
36
37struct nau8825_fll {
38 int mclk_src;
39 int ratio;
40 int fll_frac;
41 int fll_int;
42 int clk_ref_div;
43};
44
45struct nau8825_fll_attr {
46 unsigned int param;
47 unsigned int val;
48};
49
50/* scaling for mclk from sysclk_src output */
51static const struct nau8825_fll_attr mclk_src_scaling[] = {
52 { 1, 0x0 },
53 { 2, 0x2 },
54 { 4, 0x3 },
55 { 8, 0x4 },
56 { 16, 0x5 },
57 { 32, 0x6 },
58 { 3, 0x7 },
59 { 6, 0xa },
60 { 12, 0xb },
61 { 24, 0xc },
62 { 48, 0xd },
63 { 96, 0xe },
64 { 5, 0xf },
65};
66
67/* ratio for input clk freq */
68static const struct nau8825_fll_attr fll_ratio[] = {
69 { 512000, 0x01 },
70 { 256000, 0x02 },
71 { 128000, 0x04 },
72 { 64000, 0x08 },
73 { 32000, 0x10 },
74 { 8000, 0x20 },
75 { 4000, 0x40 },
76};
77
78static const struct nau8825_fll_attr fll_pre_scalar[] = {
79 { 1, 0x0 },
80 { 2, 0x1 },
81 { 4, 0x2 },
82 { 8, 0x3 },
83};
84
85static const struct reg_default nau8825_reg_defaults[] = {
86 { NAU8825_REG_ENA_CTRL, 0x00ff },
87 { NAU8825_REG_CLK_DIVIDER, 0x0050 },
88 { NAU8825_REG_FLL1, 0x0 },
89 { NAU8825_REG_FLL2, 0x3126 },
90 { NAU8825_REG_FLL3, 0x0008 },
91 { NAU8825_REG_FLL4, 0x0010 },
92 { NAU8825_REG_FLL5, 0x0 },
93 { NAU8825_REG_FLL6, 0x6000 },
94 { NAU8825_REG_FLL_VCO_RSV, 0xf13c },
95 { NAU8825_REG_HSD_CTRL, 0x000c },
96 { NAU8825_REG_JACK_DET_CTRL, 0x0 },
97 { NAU8825_REG_INTERRUPT_MASK, 0x0 },
98 { NAU8825_REG_INTERRUPT_DIS_CTRL, 0xffff },
99 { NAU8825_REG_SAR_CTRL, 0x0015 },
100 { NAU8825_REG_KEYDET_CTRL, 0x0110 },
101 { NAU8825_REG_VDET_THRESHOLD_1, 0x0 },
102 { NAU8825_REG_VDET_THRESHOLD_2, 0x0 },
103 { NAU8825_REG_VDET_THRESHOLD_3, 0x0 },
104 { NAU8825_REG_VDET_THRESHOLD_4, 0x0 },
105 { NAU8825_REG_GPIO34_CTRL, 0x0 },
106 { NAU8825_REG_GPIO12_CTRL, 0x0 },
107 { NAU8825_REG_TDM_CTRL, 0x0 },
108 { NAU8825_REG_I2S_PCM_CTRL1, 0x000b },
109 { NAU8825_REG_I2S_PCM_CTRL2, 0x8010 },
110 { NAU8825_REG_LEFT_TIME_SLOT, 0x0 },
111 { NAU8825_REG_RIGHT_TIME_SLOT, 0x0 },
112 { NAU8825_REG_BIQ_CTRL, 0x0 },
113 { NAU8825_REG_BIQ_COF1, 0x0 },
114 { NAU8825_REG_BIQ_COF2, 0x0 },
115 { NAU8825_REG_BIQ_COF3, 0x0 },
116 { NAU8825_REG_BIQ_COF4, 0x0 },
117 { NAU8825_REG_BIQ_COF5, 0x0 },
118 { NAU8825_REG_BIQ_COF6, 0x0 },
119 { NAU8825_REG_BIQ_COF7, 0x0 },
120 { NAU8825_REG_BIQ_COF8, 0x0 },
121 { NAU8825_REG_BIQ_COF9, 0x0 },
122 { NAU8825_REG_BIQ_COF10, 0x0 },
123 { NAU8825_REG_ADC_RATE, 0x0010 },
124 { NAU8825_REG_DAC_CTRL1, 0x0001 },
125 { NAU8825_REG_DAC_CTRL2, 0x0 },
126 { NAU8825_REG_DAC_DGAIN_CTRL, 0x0 },
127 { NAU8825_REG_ADC_DGAIN_CTRL, 0x00cf },
128 { NAU8825_REG_MUTE_CTRL, 0x0 },
129 { NAU8825_REG_HSVOL_CTRL, 0x0 },
130 { NAU8825_REG_DACL_CTRL, 0x02cf },
131 { NAU8825_REG_DACR_CTRL, 0x00cf },
132 { NAU8825_REG_ADC_DRC_KNEE_IP12, 0x1486 },
133 { NAU8825_REG_ADC_DRC_KNEE_IP34, 0x0f12 },
134 { NAU8825_REG_ADC_DRC_SLOPES, 0x25ff },
135 { NAU8825_REG_ADC_DRC_ATKDCY, 0x3457 },
136 { NAU8825_REG_DAC_DRC_KNEE_IP12, 0x1486 },
137 { NAU8825_REG_DAC_DRC_KNEE_IP34, 0x0f12 },
138 { NAU8825_REG_DAC_DRC_SLOPES, 0x25f9 },
139 { NAU8825_REG_DAC_DRC_ATKDCY, 0x3457 },
140 { NAU8825_REG_IMM_MODE_CTRL, 0x0 },
141 { NAU8825_REG_CLASSG_CTRL, 0x0 },
142 { NAU8825_REG_OPT_EFUSE_CTRL, 0x0 },
143 { NAU8825_REG_MISC_CTRL, 0x0 },
144 { NAU8825_REG_BIAS_ADJ, 0x0 },
145 { NAU8825_REG_TRIM_SETTINGS, 0x0 },
146 { NAU8825_REG_ANALOG_CONTROL_1, 0x0 },
147 { NAU8825_REG_ANALOG_CONTROL_2, 0x0 },
148 { NAU8825_REG_ANALOG_ADC_1, 0x0011 },
149 { NAU8825_REG_ANALOG_ADC_2, 0x0020 },
150 { NAU8825_REG_RDAC, 0x0008 },
151 { NAU8825_REG_MIC_BIAS, 0x0006 },
152 { NAU8825_REG_BOOST, 0x0 },
153 { NAU8825_REG_FEPGA, 0x0 },
154 { NAU8825_REG_POWER_UP_CONTROL, 0x0 },
155 { NAU8825_REG_CHARGE_PUMP, 0x0 },
156};
157
158static bool nau8825_readable_reg(struct device *dev, unsigned int reg)
159{
160 switch (reg) {
161 case NAU8825_REG_ENA_CTRL:
162 case NAU8825_REG_CLK_DIVIDER ... NAU8825_REG_FLL_VCO_RSV:
163 case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL:
164 case NAU8825_REG_INTERRUPT_MASK ... NAU8825_REG_KEYDET_CTRL:
165 case NAU8825_REG_VDET_THRESHOLD_1 ... NAU8825_REG_DACR_CTRL:
166 case NAU8825_REG_ADC_DRC_KNEE_IP12 ... NAU8825_REG_ADC_DRC_ATKDCY:
167 case NAU8825_REG_DAC_DRC_KNEE_IP12 ... NAU8825_REG_DAC_DRC_ATKDCY:
168 case NAU8825_REG_IMM_MODE_CTRL ... NAU8825_REG_IMM_RMS_R:
169 case NAU8825_REG_CLASSG_CTRL ... NAU8825_REG_OPT_EFUSE_CTRL:
170 case NAU8825_REG_MISC_CTRL:
171 case NAU8825_REG_I2C_DEVICE_ID ... NAU8825_REG_SARDOUT_RAM_STATUS:
172 case NAU8825_REG_BIAS_ADJ:
173 case NAU8825_REG_TRIM_SETTINGS ... NAU8825_REG_ANALOG_CONTROL_2:
174 case NAU8825_REG_ANALOG_ADC_1 ... NAU8825_REG_MIC_BIAS:
175 case NAU8825_REG_BOOST ... NAU8825_REG_FEPGA:
176 case NAU8825_REG_POWER_UP_CONTROL ... NAU8825_REG_GENERAL_STATUS:
177 return true;
178 default:
179 return false;
180 }
181
182}
183
184static bool nau8825_writeable_reg(struct device *dev, unsigned int reg)
185{
186 switch (reg) {
187 case NAU8825_REG_RESET ... NAU8825_REG_ENA_CTRL:
188 case NAU8825_REG_CLK_DIVIDER ... NAU8825_REG_FLL_VCO_RSV:
189 case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL:
190 case NAU8825_REG_INTERRUPT_MASK:
191 case NAU8825_REG_INT_CLR_KEY_STATUS ... NAU8825_REG_KEYDET_CTRL:
192 case NAU8825_REG_VDET_THRESHOLD_1 ... NAU8825_REG_DACR_CTRL:
193 case NAU8825_REG_ADC_DRC_KNEE_IP12 ... NAU8825_REG_ADC_DRC_ATKDCY:
194 case NAU8825_REG_DAC_DRC_KNEE_IP12 ... NAU8825_REG_DAC_DRC_ATKDCY:
195 case NAU8825_REG_IMM_MODE_CTRL:
196 case NAU8825_REG_CLASSG_CTRL ... NAU8825_REG_OPT_EFUSE_CTRL:
197 case NAU8825_REG_MISC_CTRL:
198 case NAU8825_REG_BIAS_ADJ:
199 case NAU8825_REG_TRIM_SETTINGS ... NAU8825_REG_ANALOG_CONTROL_2:
200 case NAU8825_REG_ANALOG_ADC_1 ... NAU8825_REG_MIC_BIAS:
201 case NAU8825_REG_BOOST ... NAU8825_REG_FEPGA:
202 case NAU8825_REG_POWER_UP_CONTROL ... NAU8825_REG_CHARGE_PUMP:
203 return true;
204 default:
205 return false;
206 }
207}
208
209static bool nau8825_volatile_reg(struct device *dev, unsigned int reg)
210{
211 switch (reg) {
212 case NAU8825_REG_RESET:
213 case NAU8825_REG_IRQ_STATUS:
214 case NAU8825_REG_INT_CLR_KEY_STATUS:
215 case NAU8825_REG_IMM_RMS_L:
216 case NAU8825_REG_IMM_RMS_R:
217 case NAU8825_REG_I2C_DEVICE_ID:
218 case NAU8825_REG_SARDOUT_RAM_STATUS:
219 case NAU8825_REG_CHARGE_PUMP_INPUT_READ:
220 case NAU8825_REG_GENERAL_STATUS:
221 return true;
222 default:
223 return false;
224 }
225}
226
227static int nau8825_pump_event(struct snd_soc_dapm_widget *w,
228 struct snd_kcontrol *kcontrol, int event)
229{
230 switch (event) {
231 case SND_SOC_DAPM_POST_PMU:
232 /* Prevent startup click by letting charge pump to ramp up */
233 msleep(10);
234 break;
235 default:
236 return -EINVAL;
237 }
238
239 return 0;
240}
241
242static const char * const nau8825_adc_decimation[] = {
243 "32", "64", "128", "256"
244};
245
246static const struct soc_enum nau8825_adc_decimation_enum =
247 SOC_ENUM_SINGLE(NAU8825_REG_ADC_RATE, NAU8825_ADC_SYNC_DOWN_SFT,
248 ARRAY_SIZE(nau8825_adc_decimation), nau8825_adc_decimation);
249
250static const char * const nau8825_dac_oversampl[] = {
251 "64", "256", "128", "", "32"
252};
253
254static const struct soc_enum nau8825_dac_oversampl_enum =
255 SOC_ENUM_SINGLE(NAU8825_REG_DAC_CTRL1, NAU8825_DAC_OVERSAMPLE_SFT,
256 ARRAY_SIZE(nau8825_dac_oversampl), nau8825_dac_oversampl);
257
258static const DECLARE_TLV_DB_MINMAX_MUTE(adc_vol_tlv, -10300, 2400);
259static const DECLARE_TLV_DB_MINMAX_MUTE(sidetone_vol_tlv, -4200, 0);
260static const DECLARE_TLV_DB_MINMAX(dac_vol_tlv, -5400, 0);
261static const DECLARE_TLV_DB_MINMAX(fepga_gain_tlv, -100, 3600);
262static const DECLARE_TLV_DB_MINMAX_MUTE(crosstalk_vol_tlv, -9600, 2400);
263
264static const struct snd_kcontrol_new nau8825_controls[] = {
265 SOC_SINGLE_TLV("Mic Volume", NAU8825_REG_ADC_DGAIN_CTRL,
266 0, 0xff, 0, adc_vol_tlv),
267 SOC_DOUBLE_TLV("Headphone Bypass Volume", NAU8825_REG_ADC_DGAIN_CTRL,
268 12, 8, 0x0f, 0, sidetone_vol_tlv),
269 SOC_DOUBLE_TLV("Headphone Volume", NAU8825_REG_HSVOL_CTRL,
270 6, 0, 0x3f, 1, dac_vol_tlv),
271 SOC_SINGLE_TLV("Frontend PGA Volume", NAU8825_REG_POWER_UP_CONTROL,
272 8, 37, 0, fepga_gain_tlv),
273 SOC_DOUBLE_TLV("Headphone Crosstalk Volume", NAU8825_REG_DAC_DGAIN_CTRL,
274 0, 8, 0xff, 0, crosstalk_vol_tlv),
275
276 SOC_ENUM("ADC Decimation Rate", nau8825_adc_decimation_enum),
277 SOC_ENUM("DAC Oversampling Rate", nau8825_dac_oversampl_enum),
278};
279
280/* DAC Mux 0x33[9] and 0x34[9] */
281static const char * const nau8825_dac_src[] = {
282 "DACL", "DACR",
283};
284
285static SOC_ENUM_SINGLE_DECL(
286 nau8825_dacl_enum, NAU8825_REG_DACL_CTRL,
287 NAU8825_DACL_CH_SEL_SFT, nau8825_dac_src);
288
289static SOC_ENUM_SINGLE_DECL(
290 nau8825_dacr_enum, NAU8825_REG_DACR_CTRL,
291 NAU8825_DACR_CH_SEL_SFT, nau8825_dac_src);
292
293static const struct snd_kcontrol_new nau8825_dacl_mux =
294 SOC_DAPM_ENUM("DACL Source", nau8825_dacl_enum);
295
296static const struct snd_kcontrol_new nau8825_dacr_mux =
297 SOC_DAPM_ENUM("DACR Source", nau8825_dacr_enum);
298
299
300static const struct snd_soc_dapm_widget nau8825_dapm_widgets[] = {
301 SND_SOC_DAPM_AIF_OUT("AIFTX", "Capture", 0, NAU8825_REG_I2S_PCM_CTRL2,
302 15, 1),
303
304 SND_SOC_DAPM_INPUT("MIC"),
305 SND_SOC_DAPM_MICBIAS("MICBIAS", NAU8825_REG_MIC_BIAS, 8, 0),
306
307 SND_SOC_DAPM_PGA("Frontend PGA", NAU8825_REG_POWER_UP_CONTROL, 14, 0,
308 NULL, 0),
309
310 SND_SOC_DAPM_ADC("ADC", NULL, NAU8825_REG_ENA_CTRL, 8, 0),
311 SND_SOC_DAPM_SUPPLY("ADC Clock", NAU8825_REG_ENA_CTRL, 7, 0, NULL, 0),
312 SND_SOC_DAPM_SUPPLY("ADC Power", NAU8825_REG_ANALOG_ADC_2, 6, 0, NULL,
313 0),
314
315 /* ADC for button press detection */
316 SND_SOC_DAPM_ADC("SAR", NULL, NAU8825_REG_SAR_CTRL,
317 NAU8825_SAR_ADC_EN_SFT, 0),
318
319 SND_SOC_DAPM_DAC("ADACL", NULL, NAU8825_REG_RDAC, 12, 0),
320 SND_SOC_DAPM_DAC("ADACR", NULL, NAU8825_REG_RDAC, 13, 0),
321 SND_SOC_DAPM_SUPPLY("ADACL Clock", NAU8825_REG_RDAC, 8, 0, NULL, 0),
322 SND_SOC_DAPM_SUPPLY("ADACR Clock", NAU8825_REG_RDAC, 9, 0, NULL, 0),
323
324 SND_SOC_DAPM_DAC("DDACR", NULL, NAU8825_REG_ENA_CTRL,
325 NAU8825_ENABLE_DACR_SFT, 0),
326 SND_SOC_DAPM_DAC("DDACL", NULL, NAU8825_REG_ENA_CTRL,
327 NAU8825_ENABLE_DACL_SFT, 0),
328 SND_SOC_DAPM_SUPPLY("DDAC Clock", NAU8825_REG_ENA_CTRL, 6, 0, NULL, 0),
329
330 SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &nau8825_dacl_mux),
331 SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &nau8825_dacr_mux),
332
333 SND_SOC_DAPM_PGA("HP amp L", NAU8825_REG_CLASSG_CTRL, 1, 0, NULL, 0),
334 SND_SOC_DAPM_PGA("HP amp R", NAU8825_REG_CLASSG_CTRL, 2, 0, NULL, 0),
335 SND_SOC_DAPM_SUPPLY("HP amp power", NAU8825_REG_CLASSG_CTRL, 0, 0, NULL,
336 0),
337
338 SND_SOC_DAPM_SUPPLY("Charge Pump", NAU8825_REG_CHARGE_PUMP, 5, 0,
339 nau8825_pump_event, SND_SOC_DAPM_POST_PMU),
340
341 SND_SOC_DAPM_PGA("Output Driver R Stage 1",
342 NAU8825_REG_POWER_UP_CONTROL, 5, 0, NULL, 0),
343 SND_SOC_DAPM_PGA("Output Driver L Stage 1",
344 NAU8825_REG_POWER_UP_CONTROL, 4, 0, NULL, 0),
345 SND_SOC_DAPM_PGA("Output Driver R Stage 2",
346 NAU8825_REG_POWER_UP_CONTROL, 3, 0, NULL, 0),
347 SND_SOC_DAPM_PGA("Output Driver L Stage 2",
348 NAU8825_REG_POWER_UP_CONTROL, 2, 0, NULL, 0),
349 SND_SOC_DAPM_PGA_S("Output Driver R Stage 3", 1,
350 NAU8825_REG_POWER_UP_CONTROL, 1, 0, NULL, 0),
351 SND_SOC_DAPM_PGA_S("Output Driver L Stage 3", 1,
352 NAU8825_REG_POWER_UP_CONTROL, 0, 0, NULL, 0),
353
354 SND_SOC_DAPM_PGA_S("Output DACL", 2, NAU8825_REG_CHARGE_PUMP, 8, 1, NULL, 0),
355 SND_SOC_DAPM_PGA_S("Output DACR", 2, NAU8825_REG_CHARGE_PUMP, 9, 1, NULL, 0),
356
357 SND_SOC_DAPM_OUTPUT("HPOL"),
358 SND_SOC_DAPM_OUTPUT("HPOR"),
359};
360
361static const struct snd_soc_dapm_route nau8825_dapm_routes[] = {
362 {"Frontend PGA", NULL, "MIC"},
363 {"ADC", NULL, "Frontend PGA"},
364 {"ADC", NULL, "ADC Clock"},
365 {"ADC", NULL, "ADC Power"},
366 {"AIFTX", NULL, "ADC"},
367
368 {"DDACL", NULL, "Playback"},
369 {"DDACR", NULL, "Playback"},
370 {"DDACL", NULL, "DDAC Clock"},
371 {"DDACR", NULL, "DDAC Clock"},
372 {"DACL Mux", "DACL", "DDACL"},
373 {"DACL Mux", "DACR", "DDACR"},
374 {"DACR Mux", "DACL", "DDACL"},
375 {"DACR Mux", "DACR", "DDACR"},
376 {"HP amp L", NULL, "DACL Mux"},
377 {"HP amp R", NULL, "DACR Mux"},
378 {"HP amp L", NULL, "HP amp power"},
379 {"HP amp R", NULL, "HP amp power"},
380 {"ADACL", NULL, "HP amp L"},
381 {"ADACR", NULL, "HP amp R"},
382 {"ADACL", NULL, "ADACL Clock"},
383 {"ADACR", NULL, "ADACR Clock"},
384 {"Output Driver L Stage 1", NULL, "ADACL"},
385 {"Output Driver R Stage 1", NULL, "ADACR"},
386 {"Output Driver L Stage 2", NULL, "Output Driver L Stage 1"},
387 {"Output Driver R Stage 2", NULL, "Output Driver R Stage 1"},
388 {"Output Driver L Stage 3", NULL, "Output Driver L Stage 2"},
389 {"Output Driver R Stage 3", NULL, "Output Driver R Stage 2"},
390 {"Output DACL", NULL, "Output Driver L Stage 3"},
391 {"Output DACR", NULL, "Output Driver R Stage 3"},
392 {"HPOL", NULL, "Output DACL"},
393 {"HPOR", NULL, "Output DACR"},
394 {"HPOL", NULL, "Charge Pump"},
395 {"HPOR", NULL, "Charge Pump"},
396};
397
398static int nau8825_hw_params(struct snd_pcm_substream *substream,
399 struct snd_pcm_hw_params *params,
400 struct snd_soc_dai *dai)
401{
402 struct snd_soc_codec *codec = dai->codec;
403 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
404 unsigned int val_len = 0;
405
406 switch (params_width(params)) {
407 case 16:
408 val_len |= NAU8825_I2S_DL_16;
409 break;
410 case 20:
411 val_len |= NAU8825_I2S_DL_20;
412 break;
413 case 24:
414 val_len |= NAU8825_I2S_DL_24;
415 break;
416 case 32:
417 val_len |= NAU8825_I2S_DL_32;
418 break;
419 default:
420 return -EINVAL;
421 }
422
423 regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL1,
424 NAU8825_I2S_DL_MASK, val_len);
425
426 return 0;
427}
428
429static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
430{
431 struct snd_soc_codec *codec = codec_dai->codec;
432 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
433 unsigned int ctrl1_val = 0, ctrl2_val = 0;
434
435 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
436 case SND_SOC_DAIFMT_CBM_CFM:
437 ctrl2_val |= NAU8825_I2S_MS_MASTER;
438 break;
439 case SND_SOC_DAIFMT_CBS_CFS:
440 break;
441 default:
442 return -EINVAL;
443 }
444
445 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
446 case SND_SOC_DAIFMT_NB_NF:
447 break;
448 case SND_SOC_DAIFMT_IB_NF:
449 ctrl1_val |= NAU8825_I2S_BP_INV;
450 break;
451 default:
452 return -EINVAL;
453 }
454
455 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
456 case SND_SOC_DAIFMT_I2S:
457 ctrl1_val |= NAU8825_I2S_DF_I2S;
458 break;
459 case SND_SOC_DAIFMT_LEFT_J:
460 ctrl1_val |= NAU8825_I2S_DF_LEFT;
461 break;
462 case SND_SOC_DAIFMT_RIGHT_J:
463 ctrl1_val |= NAU8825_I2S_DF_RIGTH;
464 break;
465 case SND_SOC_DAIFMT_DSP_A:
466 ctrl1_val |= NAU8825_I2S_DF_PCM_AB;
467 break;
468 case SND_SOC_DAIFMT_DSP_B:
469 ctrl1_val |= NAU8825_I2S_DF_PCM_AB;
470 ctrl1_val |= NAU8825_I2S_PCMB_EN;
471 break;
472 default:
473 return -EINVAL;
474 }
475
476 regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL1,
477 NAU8825_I2S_DL_MASK | NAU8825_I2S_DF_MASK |
478 NAU8825_I2S_BP_MASK | NAU8825_I2S_PCMB_MASK,
479 ctrl1_val);
480 regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2,
481 NAU8825_I2S_MS_MASK, ctrl2_val);
482
483 return 0;
484}
485
486static const struct snd_soc_dai_ops nau8825_dai_ops = {
487 .hw_params = nau8825_hw_params,
488 .set_fmt = nau8825_set_dai_fmt,
489};
490
491#define NAU8825_RATES SNDRV_PCM_RATE_8000_192000
492#define NAU8825_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
493 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
494
495static struct snd_soc_dai_driver nau8825_dai = {
496 .name = "nau8825-hifi",
497 .playback = {
498 .stream_name = "Playback",
499 .channels_min = 1,
500 .channels_max = 2,
501 .rates = NAU8825_RATES,
502 .formats = NAU8825_FORMATS,
503 },
504 .capture = {
505 .stream_name = "Capture",
506 .channels_min = 1,
507 .channels_max = 1,
508 .rates = NAU8825_RATES,
509 .formats = NAU8825_FORMATS,
510 },
511 .ops = &nau8825_dai_ops,
512};
513
514/**
515 * nau8825_enable_jack_detect - Specify a jack for event reporting
516 *
517 * @component: component to register the jack with
518 * @jack: jack to use to report headset and button events on
519 *
520 * After this function has been called the headset insert/remove and button
521 * events will be routed to the given jack. Jack can be null to stop
522 * reporting.
523 */
524int nau8825_enable_jack_detect(struct snd_soc_codec *codec,
525 struct snd_soc_jack *jack)
526{
527 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
528 struct regmap *regmap = nau8825->regmap;
529
530 nau8825->jack = jack;
531
532 /* Ground HP Outputs[1:0], needed for headset auto detection
533 * Enable Automatic Mic/Gnd switching reading on insert interrupt[6]
534 */
535 regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL,
536 NAU8825_HSD_AUTO_MODE | NAU8825_SPKR_DWN1R | NAU8825_SPKR_DWN1L,
537 NAU8825_HSD_AUTO_MODE | NAU8825_SPKR_DWN1R | NAU8825_SPKR_DWN1L);
538
539 regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK,
540 NAU8825_IRQ_HEADSET_COMPLETE_EN | NAU8825_IRQ_EJECT_EN, 0);
541
542 return 0;
543}
544EXPORT_SYMBOL_GPL(nau8825_enable_jack_detect);
545
546
547static bool nau8825_is_jack_inserted(struct regmap *regmap)
548{
549 int status;
550
551 regmap_read(regmap, NAU8825_REG_I2C_DEVICE_ID, &status);
552 return !(status & NAU8825_GPIO2JD1);
553}
554
555static void nau8825_restart_jack_detection(struct regmap *regmap)
556{
557 /* this will restart the entire jack detection process including MIC/GND
558 * switching and create interrupts. We have to go from 0 to 1 and back
559 * to 0 to restart.
560 */
561 regmap_update_bits(regmap, NAU8825_REG_JACK_DET_CTRL,
562 NAU8825_JACK_DET_RESTART, NAU8825_JACK_DET_RESTART);
563 regmap_update_bits(regmap, NAU8825_REG_JACK_DET_CTRL,
564 NAU8825_JACK_DET_RESTART, 0);
565}
566
567static void nau8825_eject_jack(struct nau8825 *nau8825)
568{
569 struct snd_soc_dapm_context *dapm = nau8825->dapm;
570 struct regmap *regmap = nau8825->regmap;
571
572 snd_soc_dapm_disable_pin(dapm, "SAR");
573 snd_soc_dapm_disable_pin(dapm, "MICBIAS");
574 /* Detach 2kOhm Resistors from MICBIAS to MICGND1/2 */
575 regmap_update_bits(regmap, NAU8825_REG_MIC_BIAS,
576 NAU8825_MICBIAS_JKSLV | NAU8825_MICBIAS_JKR2, 0);
577 /* ground HPL/HPR, MICGRND1/2 */
578 regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL, 0xf, 0xf);
579
580 snd_soc_dapm_sync(dapm);
581}
582
583static int nau8825_button_decode(int value)
584{
585 int buttons = 0;
586
587 /* The chip supports up to 8 buttons, but ALSA defines only 6 buttons */
588 if (value & BIT(0))
589 buttons |= SND_JACK_BTN_0;
590 if (value & BIT(1))
591 buttons |= SND_JACK_BTN_1;
592 if (value & BIT(2))
593 buttons |= SND_JACK_BTN_2;
594 if (value & BIT(3))
595 buttons |= SND_JACK_BTN_3;
596 if (value & BIT(4))
597 buttons |= SND_JACK_BTN_4;
598 if (value & BIT(5))
599 buttons |= SND_JACK_BTN_5;
600
601 return buttons;
602}
603
604static int nau8825_jack_insert(struct nau8825 *nau8825)
605{
606 struct regmap *regmap = nau8825->regmap;
607 struct snd_soc_dapm_context *dapm = nau8825->dapm;
608 int jack_status_reg, mic_detected;
609 int type = 0;
610
611 regmap_read(regmap, NAU8825_REG_GENERAL_STATUS, &jack_status_reg);
612 mic_detected = (jack_status_reg >> 10) & 3;
613
614 switch (mic_detected) {
615 case 0:
616 /* no mic */
617 type = SND_JACK_HEADPHONE;
618 break;
619 case 1:
620 dev_dbg(nau8825->dev, "OMTP (micgnd1) mic connected\n");
621 type = SND_JACK_HEADSET;
622
623 /* Unground MICGND1 */
624 regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL, 3 << 2,
625 1 << 2);
626 /* Attach 2kOhm Resistor from MICBIAS to MICGND1 */
627 regmap_update_bits(regmap, NAU8825_REG_MIC_BIAS,
628 NAU8825_MICBIAS_JKSLV | NAU8825_MICBIAS_JKR2,
629 NAU8825_MICBIAS_JKR2);
630 /* Attach SARADC to MICGND1 */
631 regmap_update_bits(regmap, NAU8825_REG_SAR_CTRL,
632 NAU8825_SAR_INPUT_MASK,
633 NAU8825_SAR_INPUT_JKR2);
634
635 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
636 snd_soc_dapm_force_enable_pin(dapm, "SAR");
637 snd_soc_dapm_sync(dapm);
638 break;
639 case 2:
640 case 3:
641 dev_dbg(nau8825->dev, "CTIA (micgnd2) mic connected\n");
642 type = SND_JACK_HEADSET;
643
644 /* Unground MICGND2 */
645 regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL, 3 << 2,
646 2 << 2);
647 /* Attach 2kOhm Resistor from MICBIAS to MICGND2 */
648 regmap_update_bits(regmap, NAU8825_REG_MIC_BIAS,
649 NAU8825_MICBIAS_JKSLV | NAU8825_MICBIAS_JKR2,
650 NAU8825_MICBIAS_JKSLV);
651 /* Attach SARADC to MICGND2 */
652 regmap_update_bits(regmap, NAU8825_REG_SAR_CTRL,
653 NAU8825_SAR_INPUT_MASK,
654 NAU8825_SAR_INPUT_JKSLV);
655
656 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
657 snd_soc_dapm_force_enable_pin(dapm, "SAR");
658 snd_soc_dapm_sync(dapm);
659 break;
660 }
661
662 if (type & SND_JACK_HEADPHONE) {
663 /* Unground HPL/R */
664 regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL, 0x3, 0);
665 }
666
667 return type;
668}
669
670#define NAU8825_BUTTONS (SND_JACK_BTN_0 | SND_JACK_BTN_1 | \
671 SND_JACK_BTN_2 | SND_JACK_BTN_3)
672
673static irqreturn_t nau8825_interrupt(int irq, void *data)
674{
675 struct nau8825 *nau8825 = (struct nau8825 *)data;
676 struct regmap *regmap = nau8825->regmap;
677 int active_irq, clear_irq = 0, event = 0, event_mask = 0;
678
679 regmap_read(regmap, NAU8825_REG_IRQ_STATUS, &active_irq);
680
681 if ((active_irq & NAU8825_JACK_EJECTION_IRQ_MASK) ==
682 NAU8825_JACK_EJECTION_DETECTED) {
683
684 nau8825_eject_jack(nau8825);
685 event_mask |= SND_JACK_HEADSET;
686 clear_irq = NAU8825_JACK_EJECTION_IRQ_MASK;
687 } else if (active_irq & NAU8825_KEY_SHORT_PRESS_IRQ) {
688 int key_status;
689
690 regmap_read(regmap, NAU8825_REG_INT_CLR_KEY_STATUS,
691 &key_status);
692
693 /* upper 8 bits of the register are for short pressed keys,
694 * lower 8 bits - for long pressed buttons
695 */
696 nau8825->button_pressed = nau8825_button_decode(
697 key_status >> 8);
698
699 event |= nau8825->button_pressed;
700 event_mask |= NAU8825_BUTTONS;
701 clear_irq = NAU8825_KEY_SHORT_PRESS_IRQ;
702 } else if (active_irq & NAU8825_KEY_RELEASE_IRQ) {
703 event_mask = NAU8825_BUTTONS;
704 clear_irq = NAU8825_KEY_RELEASE_IRQ;
705 } else if (active_irq & NAU8825_HEADSET_COMPLETION_IRQ) {
706 if (nau8825_is_jack_inserted(regmap)) {
707 event |= nau8825_jack_insert(nau8825);
708 } else {
709 dev_warn(nau8825->dev, "Headset completion IRQ fired but no headset connected\n");
710 nau8825_eject_jack(nau8825);
711 }
712
713 event_mask |= SND_JACK_HEADSET;
714 clear_irq = NAU8825_HEADSET_COMPLETION_IRQ;
715 }
716
717 if (!clear_irq)
718 clear_irq = active_irq;
719 /* clears the rightmost interruption */
720 regmap_write(regmap, NAU8825_REG_INT_CLR_KEY_STATUS, clear_irq);
721
722 if (event_mask)
723 snd_soc_jack_report(nau8825->jack, event, event_mask);
724
725 return IRQ_HANDLED;
726}
727
728static void nau8825_setup_buttons(struct nau8825 *nau8825)
729{
730 struct regmap *regmap = nau8825->regmap;
731
732 regmap_update_bits(regmap, NAU8825_REG_SAR_CTRL,
733 NAU8825_SAR_TRACKING_GAIN_MASK,
734 nau8825->sar_voltage << NAU8825_SAR_TRACKING_GAIN_SFT);
735 regmap_update_bits(regmap, NAU8825_REG_SAR_CTRL,
736 NAU8825_SAR_COMPARE_TIME_MASK,
737 nau8825->sar_compare_time << NAU8825_SAR_COMPARE_TIME_SFT);
738 regmap_update_bits(regmap, NAU8825_REG_SAR_CTRL,
739 NAU8825_SAR_SAMPLING_TIME_MASK,
740 nau8825->sar_sampling_time << NAU8825_SAR_SAMPLING_TIME_SFT);
741
742 regmap_update_bits(regmap, NAU8825_REG_KEYDET_CTRL,
743 NAU8825_KEYDET_LEVELS_NR_MASK,
744 (nau8825->sar_threshold_num - 1) << NAU8825_KEYDET_LEVELS_NR_SFT);
745 regmap_update_bits(regmap, NAU8825_REG_KEYDET_CTRL,
746 NAU8825_KEYDET_HYSTERESIS_MASK,
747 nau8825->sar_hysteresis << NAU8825_KEYDET_HYSTERESIS_SFT);
748 regmap_update_bits(regmap, NAU8825_REG_KEYDET_CTRL,
749 NAU8825_KEYDET_SHORTKEY_DEBOUNCE_MASK,
750 nau8825->key_debounce << NAU8825_KEYDET_SHORTKEY_DEBOUNCE_SFT);
751
752 regmap_write(regmap, NAU8825_REG_VDET_THRESHOLD_1,
753 (nau8825->sar_threshold[0] << 8) | nau8825->sar_threshold[1]);
754 regmap_write(regmap, NAU8825_REG_VDET_THRESHOLD_2,
755 (nau8825->sar_threshold[2] << 8) | nau8825->sar_threshold[3]);
756 regmap_write(regmap, NAU8825_REG_VDET_THRESHOLD_3,
757 (nau8825->sar_threshold[4] << 8) | nau8825->sar_threshold[5]);
758 regmap_write(regmap, NAU8825_REG_VDET_THRESHOLD_4,
759 (nau8825->sar_threshold[6] << 8) | nau8825->sar_threshold[7]);
760
761 /* Enable short press and release interruptions */
762 regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK,
763 NAU8825_IRQ_KEY_SHORT_PRESS_EN | NAU8825_IRQ_KEY_RELEASE_EN,
764 0);
765}
766
767static void nau8825_init_regs(struct nau8825 *nau8825)
768{
769 struct regmap *regmap = nau8825->regmap;
770
771 /* Enable Bias/Vmid */
772 regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
773 NAU8825_BIAS_VMID, NAU8825_BIAS_VMID);
774 regmap_update_bits(nau8825->regmap, NAU8825_REG_BOOST,
775 NAU8825_GLOBAL_BIAS_EN, NAU8825_GLOBAL_BIAS_EN);
776
777 /* VMID Tieoff */
778 regmap_update_bits(regmap, NAU8825_REG_BIAS_ADJ,
779 NAU8825_BIAS_VMID_SEL_MASK,
780 nau8825->vref_impedance << NAU8825_BIAS_VMID_SEL_SFT);
781 /* Disable Boost Driver, Automatic Short circuit protection enable */
782 regmap_update_bits(regmap, NAU8825_REG_BOOST,
783 NAU8825_PRECHARGE_DIS | NAU8825_HP_BOOST_G_DIS |
784 NAU8825_SHORT_SHUTDOWN_EN,
785 NAU8825_PRECHARGE_DIS | NAU8825_HP_BOOST_G_DIS |
786 NAU8825_SHORT_SHUTDOWN_EN);
787
788 regmap_update_bits(regmap, NAU8825_REG_GPIO12_CTRL,
789 NAU8825_JKDET_OUTPUT_EN,
790 nau8825->jkdet_enable ? 0 : NAU8825_JKDET_OUTPUT_EN);
791 regmap_update_bits(regmap, NAU8825_REG_GPIO12_CTRL,
792 NAU8825_JKDET_PULL_EN,
793 nau8825->jkdet_pull_enable ? 0 : NAU8825_JKDET_PULL_EN);
794 regmap_update_bits(regmap, NAU8825_REG_GPIO12_CTRL,
795 NAU8825_JKDET_PULL_UP,
796 nau8825->jkdet_pull_up ? NAU8825_JKDET_PULL_UP : 0);
797 regmap_update_bits(regmap, NAU8825_REG_JACK_DET_CTRL,
798 NAU8825_JACK_POLARITY,
799 /* jkdet_polarity - 1 is for active-low */
800 nau8825->jkdet_polarity ? 0 : NAU8825_JACK_POLARITY);
801
802 regmap_update_bits(regmap, NAU8825_REG_JACK_DET_CTRL,
803 NAU8825_JACK_INSERT_DEBOUNCE_MASK,
804 nau8825->jack_insert_debounce << NAU8825_JACK_INSERT_DEBOUNCE_SFT);
805 regmap_update_bits(regmap, NAU8825_REG_JACK_DET_CTRL,
806 NAU8825_JACK_EJECT_DEBOUNCE_MASK,
807 nau8825->jack_eject_debounce << NAU8825_JACK_EJECT_DEBOUNCE_SFT);
808
809 /* Mask unneeded IRQs: 1 - disable, 0 - enable */
810 regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK, 0x7ff, 0x7ff);
811
812 regmap_update_bits(regmap, NAU8825_REG_MIC_BIAS,
813 NAU8825_MICBIAS_VOLTAGE_MASK, nau8825->micbias_voltage);
814
815 if (nau8825->sar_threshold_num)
816 nau8825_setup_buttons(nau8825);
817
818 /* Default oversampling/decimations settings are unusable
819 * (audible hiss). Set it to something better.
820 */
821 regmap_update_bits(regmap, NAU8825_REG_ADC_RATE,
822 NAU8825_ADC_SYNC_DOWN_MASK, NAU8825_ADC_SYNC_DOWN_128);
823 regmap_update_bits(regmap, NAU8825_REG_DAC_CTRL1,
824 NAU8825_DAC_OVERSAMPLE_MASK, NAU8825_DAC_OVERSAMPLE_128);
825}
826
827static const struct regmap_config nau8825_regmap_config = {
828 .val_bits = 16,
829 .reg_bits = 16,
830
831 .max_register = NAU8825_REG_MAX,
832 .readable_reg = nau8825_readable_reg,
833 .writeable_reg = nau8825_writeable_reg,
834 .volatile_reg = nau8825_volatile_reg,
835
836 .cache_type = REGCACHE_RBTREE,
837 .reg_defaults = nau8825_reg_defaults,
838 .num_reg_defaults = ARRAY_SIZE(nau8825_reg_defaults),
839};
840
841static int nau8825_codec_probe(struct snd_soc_codec *codec)
842{
843 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
844 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
845
846 nau8825->dapm = dapm;
847
848 /* The interrupt clock is gated by x1[10:8],
849 * one of them needs to be enabled all the time for
850 * interrupts to happen.
851 */
852 snd_soc_dapm_force_enable_pin(dapm, "DDACR");
853 snd_soc_dapm_sync(dapm);
854
855 /* Unmask interruptions. Handler uses dapm object so we can enable
856 * interruptions only after dapm is fully initialized.
857 */
858 regmap_write(nau8825->regmap, NAU8825_REG_INTERRUPT_DIS_CTRL, 0);
859 nau8825_restart_jack_detection(nau8825->regmap);
860
861 return 0;
862}
863
864/**
865 * nau8825_calc_fll_param - Calculate FLL parameters.
866 * @fll_in: external clock provided to codec.
867 * @fs: sampling rate.
868 * @fll_param: Pointer to structure of FLL parameters.
869 *
870 * Calculate FLL parameters to configure codec.
871 *
872 * Returns 0 for success or negative error code.
873 */
874static int nau8825_calc_fll_param(unsigned int fll_in, unsigned int fs,
875 struct nau8825_fll *fll_param)
876{
877 u64 fvco;
878 unsigned int fref, i;
879
880 /* Ensure the reference clock frequency (FREF) is <= 13.5MHz by dividing
881 * freq_in by 1, 2, 4, or 8 using FLL pre-scalar.
882 * FREF = freq_in / NAU8825_FLL_REF_DIV_MASK
883 */
884 for (i = 0; i < ARRAY_SIZE(fll_pre_scalar); i++) {
885 fref = fll_in / fll_pre_scalar[i].param;
886 if (fref <= NAU_FREF_MAX)
887 break;
888 }
889 if (i == ARRAY_SIZE(fll_pre_scalar))
890 return -EINVAL;
891 fll_param->clk_ref_div = fll_pre_scalar[i].val;
892
893 /* Choose the FLL ratio based on FREF */
894 for (i = 0; i < ARRAY_SIZE(fll_ratio); i++) {
895 if (fref >= fll_ratio[i].param)
896 break;
897 }
898 if (i == ARRAY_SIZE(fll_ratio))
899 return -EINVAL;
900 fll_param->ratio = fll_ratio[i].val;
901
902 /* Calculate the frequency of DCO (FDCO) given freq_out = 256 * Fs.
903 * FDCO must be within the 90MHz - 100MHz or the FFL cannot be
904 * guaranteed across the full range of operation.
905 * FDCO = freq_out * 2 * mclk_src_scaling
906 */
907 for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) {
908 fvco = 256 * fs * 2 * mclk_src_scaling[i].param;
909 if (NAU_FVCO_MIN < fvco && fvco < NAU_FVCO_MAX)
910 break;
911 }
912 if (i == ARRAY_SIZE(mclk_src_scaling))
913 return -EINVAL;
914 fll_param->mclk_src = mclk_src_scaling[i].val;
915
916 /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional
917 * input based on FDCO, FREF and FLL ratio.
918 */
919 fvco = div_u64(fvco << 16, fref * fll_param->ratio);
920 fll_param->fll_int = (fvco >> 16) & 0x3FF;
921 fll_param->fll_frac = fvco & 0xFFFF;
922 return 0;
923}
924
925static void nau8825_fll_apply(struct nau8825 *nau8825,
926 struct nau8825_fll *fll_param)
927{
928 regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER,
929 NAU8825_CLK_MCLK_SRC_MASK, fll_param->mclk_src);
930 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL1,
931 NAU8825_FLL_RATIO_MASK, fll_param->ratio);
932 /* FLL 16-bit fractional input */
933 regmap_write(nau8825->regmap, NAU8825_REG_FLL2, fll_param->fll_frac);
934 /* FLL 10-bit integer input */
935 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL3,
936 NAU8825_FLL_INTEGER_MASK, fll_param->fll_int);
937 /* FLL pre-scaler */
938 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL4,
939 NAU8825_FLL_REF_DIV_MASK, fll_param->clk_ref_div);
940 /* select divided VCO input */
941 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL5,
942 NAU8825_FLL_FILTER_SW_MASK, 0x0000);
943 /* FLL sigma delta modulator enable */
944 regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL6,
945 NAU8825_SDM_EN_MASK, NAU8825_SDM_EN);
946}
947
948/* freq_out must be 256*Fs in order to achieve the best performance */
949static int nau8825_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
950 unsigned int freq_in, unsigned int freq_out)
951{
952 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
953 struct nau8825_fll fll_param;
954 int ret, fs;
955
956 fs = freq_out / 256;
957 ret = nau8825_calc_fll_param(freq_in, fs, &fll_param);
958 if (ret < 0) {
959 dev_err(codec->dev, "Unsupported input clock %d\n", freq_in);
960 return ret;
961 }
962 dev_dbg(codec->dev, "mclk_src=%x ratio=%x fll_frac=%x fll_int=%x clk_ref_div=%x\n",
963 fll_param.mclk_src, fll_param.ratio, fll_param.fll_frac,
964 fll_param.fll_int, fll_param.clk_ref_div);
965
966 nau8825_fll_apply(nau8825, &fll_param);
967 mdelay(2);
968 regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER,
969 NAU8825_CLK_SRC_MASK, NAU8825_CLK_SRC_VCO);
970 return 0;
971}
972
973static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id,
974 unsigned int freq)
975{
976 struct regmap *regmap = nau8825->regmap;
977 int ret;
978
979 switch (clk_id) {
980 case NAU8825_CLK_MCLK:
981 regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER,
982 NAU8825_CLK_SRC_MASK, NAU8825_CLK_SRC_MCLK);
983 regmap_update_bits(regmap, NAU8825_REG_FLL6, NAU8825_DCO_EN, 0);
984
985 /* We selected MCLK source but the clock itself managed externally */
986 if (!nau8825->mclk)
987 break;
988
989 if (!nau8825->mclk_freq) {
990 ret = clk_prepare_enable(nau8825->mclk);
991 if (ret) {
992 dev_err(nau8825->dev, "Unable to prepare codec mclk\n");
993 return ret;
994 }
995 }
996
997 if (nau8825->mclk_freq != freq) {
998 nau8825->mclk_freq = freq;
999
1000 freq = clk_round_rate(nau8825->mclk, freq);
1001 ret = clk_set_rate(nau8825->mclk, freq);
1002 if (ret) {
1003 dev_err(nau8825->dev, "Unable to set mclk rate\n");
1004 return ret;
1005 }
1006 }
1007
1008 break;
1009 case NAU8825_CLK_INTERNAL:
1010 regmap_update_bits(regmap, NAU8825_REG_FLL6, NAU8825_DCO_EN,
1011 NAU8825_DCO_EN);
1012 regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER,
1013 NAU8825_CLK_SRC_MASK, NAU8825_CLK_SRC_VCO);
1014
1015 if (nau8825->mclk_freq) {
1016 clk_disable_unprepare(nau8825->mclk);
1017 nau8825->mclk_freq = 0;
1018 }
1019
1020 break;
1021 default:
1022 dev_err(nau8825->dev, "Invalid clock id (%d)\n", clk_id);
1023 return -EINVAL;
1024 }
1025
1026 dev_dbg(nau8825->dev, "Sysclk is %dHz and clock id is %d\n", freq,
1027 clk_id);
1028 return 0;
1029}
1030
1031static int nau8825_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1032 int source, unsigned int freq, int dir)
1033{
1034 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
1035
1036 return nau8825_configure_sysclk(nau8825, clk_id, freq);
1037}
1038
1039static int nau8825_set_bias_level(struct snd_soc_codec *codec,
1040 enum snd_soc_bias_level level)
1041{
1042 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
1043 int ret;
1044
1045 switch (level) {
1046 case SND_SOC_BIAS_ON:
1047 break;
1048
1049 case SND_SOC_BIAS_PREPARE:
1050 break;
1051
1052 case SND_SOC_BIAS_STANDBY:
1053 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
1054 if (nau8825->mclk_freq) {
1055 ret = clk_prepare_enable(nau8825->mclk);
1056 if (ret) {
1057 dev_err(nau8825->dev, "Unable to prepare codec mclk\n");
1058 return ret;
1059 }
1060 }
1061
1062 ret = regcache_sync(nau8825->regmap);
1063 if (ret) {
1064 dev_err(codec->dev,
1065 "Failed to sync cache: %d\n", ret);
1066 return ret;
1067 }
1068 }
1069
1070 break;
1071
1072 case SND_SOC_BIAS_OFF:
1073 if (nau8825->mclk_freq)
1074 clk_disable_unprepare(nau8825->mclk);
1075
1076 regcache_mark_dirty(nau8825->regmap);
1077 break;
1078 }
1079 return 0;
1080}
1081
1082static struct snd_soc_codec_driver nau8825_codec_driver = {
1083 .probe = nau8825_codec_probe,
1084 .set_sysclk = nau8825_set_sysclk,
1085 .set_pll = nau8825_set_pll,
1086 .set_bias_level = nau8825_set_bias_level,
1087 .suspend_bias_off = true,
1088
1089 .controls = nau8825_controls,
1090 .num_controls = ARRAY_SIZE(nau8825_controls),
1091 .dapm_widgets = nau8825_dapm_widgets,
1092 .num_dapm_widgets = ARRAY_SIZE(nau8825_dapm_widgets),
1093 .dapm_routes = nau8825_dapm_routes,
1094 .num_dapm_routes = ARRAY_SIZE(nau8825_dapm_routes),
1095};
1096
1097static void nau8825_reset_chip(struct regmap *regmap)
1098{
1099 regmap_write(regmap, NAU8825_REG_RESET, 0x00);
1100 regmap_write(regmap, NAU8825_REG_RESET, 0x00);
1101}
1102
1103static void nau8825_print_device_properties(struct nau8825 *nau8825)
1104{
1105 int i;
1106 struct device *dev = nau8825->dev;
1107
1108 dev_dbg(dev, "jkdet-enable: %d\n", nau8825->jkdet_enable);
1109 dev_dbg(dev, "jkdet-pull-enable: %d\n", nau8825->jkdet_pull_enable);
1110 dev_dbg(dev, "jkdet-pull-up: %d\n", nau8825->jkdet_pull_up);
1111 dev_dbg(dev, "jkdet-polarity: %d\n", nau8825->jkdet_polarity);
1112 dev_dbg(dev, "micbias-voltage: %d\n", nau8825->micbias_voltage);
1113 dev_dbg(dev, "vref-impedance: %d\n", nau8825->vref_impedance);
1114
1115 dev_dbg(dev, "sar-threshold-num: %d\n", nau8825->sar_threshold_num);
1116 for (i = 0; i < nau8825->sar_threshold_num; i++)
1117 dev_dbg(dev, "sar-threshold[%d]=%d\n", i,
1118 nau8825->sar_threshold[i]);
1119
1120 dev_dbg(dev, "sar-hysteresis: %d\n", nau8825->sar_hysteresis);
1121 dev_dbg(dev, "sar-voltage: %d\n", nau8825->sar_voltage);
1122 dev_dbg(dev, "sar-compare-time: %d\n", nau8825->sar_compare_time);
1123 dev_dbg(dev, "sar-sampling-time: %d\n", nau8825->sar_sampling_time);
1124 dev_dbg(dev, "short-key-debounce: %d\n", nau8825->key_debounce);
1125 dev_dbg(dev, "jack-insert-debounce: %d\n",
1126 nau8825->jack_insert_debounce);
1127 dev_dbg(dev, "jack-eject-debounce: %d\n",
1128 nau8825->jack_eject_debounce);
1129}
1130
1131static int nau8825_read_device_properties(struct device *dev,
1132 struct nau8825 *nau8825) {
1133
1134 nau8825->jkdet_enable = device_property_read_bool(dev,
1135 "nuvoton,jkdet-enable");
1136 nau8825->jkdet_pull_enable = device_property_read_bool(dev,
1137 "nuvoton,jkdet-pull-enable");
1138 nau8825->jkdet_pull_up = device_property_read_bool(dev,
1139 "nuvoton,jkdet-pull-up");
1140 device_property_read_u32(dev, "nuvoton,jkdet-polarity",
1141 &nau8825->jkdet_polarity);
1142 device_property_read_u32(dev, "nuvoton,micbias-voltage",
1143 &nau8825->micbias_voltage);
1144 device_property_read_u32(dev, "nuvoton,vref-impedance",
1145 &nau8825->vref_impedance);
1146 device_property_read_u32(dev, "nuvoton,sar-threshold-num",
1147 &nau8825->sar_threshold_num);
1148 device_property_read_u32_array(dev, "nuvoton,sar-threshold",
1149 nau8825->sar_threshold, nau8825->sar_threshold_num);
1150 device_property_read_u32(dev, "nuvoton,sar-hysteresis",
1151 &nau8825->sar_hysteresis);
1152 device_property_read_u32(dev, "nuvoton,sar-voltage",
1153 &nau8825->sar_voltage);
1154 device_property_read_u32(dev, "nuvoton,sar-compare-time",
1155 &nau8825->sar_compare_time);
1156 device_property_read_u32(dev, "nuvoton,sar-sampling-time",
1157 &nau8825->sar_sampling_time);
1158 device_property_read_u32(dev, "nuvoton,short-key-debounce",
1159 &nau8825->key_debounce);
1160 device_property_read_u32(dev, "nuvoton,jack-insert-debounce",
1161 &nau8825->jack_insert_debounce);
1162 device_property_read_u32(dev, "nuvoton,jack-eject-debounce",
1163 &nau8825->jack_eject_debounce);
1164
1165 nau8825->mclk = devm_clk_get(dev, "mclk");
1166 if (PTR_ERR(nau8825->mclk) == -EPROBE_DEFER) {
1167 return -EPROBE_DEFER;
1168 } else if (PTR_ERR(nau8825->mclk) == -ENOENT) {
1169 /* The MCLK is managed externally or not used at all */
1170 nau8825->mclk = NULL;
1171 dev_info(dev, "No 'mclk' clock found, assume MCLK is managed externally");
1172 } else if (IS_ERR(nau8825->mclk)) {
1173 return -EINVAL;
1174 }
1175
1176 return 0;
1177}
1178
1179static int nau8825_setup_irq(struct nau8825 *nau8825)
1180{
1181 struct regmap *regmap = nau8825->regmap;
1182 int ret;
1183
1184 /* IRQ Output Enable */
1185 regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK,
1186 NAU8825_IRQ_OUTPUT_EN, NAU8825_IRQ_OUTPUT_EN);
1187
1188 /* Enable internal VCO needed for interruptions */
1189 nau8825_configure_sysclk(nau8825, NAU8825_CLK_INTERNAL, 0);
1190
1191 /* Enable DDACR needed for interrupts
1192 * It is the same as force_enable_pin("DDACR") we do later
1193 */
1194 regmap_update_bits(regmap, NAU8825_REG_ENA_CTRL,
1195 NAU8825_ENABLE_DACR, NAU8825_ENABLE_DACR);
1196
1197 /* Chip needs one FSCLK cycle in order to generate interrupts,
1198 * as we cannot guarantee one will be provided by the system. Turning
1199 * master mode on then off enables us to generate that FSCLK cycle
1200 * with a minimum of contention on the clock bus.
1201 */
1202 regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2,
1203 NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_MASTER);
1204 regmap_update_bits(regmap, NAU8825_REG_I2S_PCM_CTRL2,
1205 NAU8825_I2S_MS_MASK, NAU8825_I2S_MS_SLAVE);
1206
1207 ret = devm_request_threaded_irq(nau8825->dev, nau8825->irq, NULL,
1208 nau8825_interrupt, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
1209 "nau8825", nau8825);
1210
1211 if (ret) {
1212 dev_err(nau8825->dev, "Cannot request irq %d (%d)\n",
1213 nau8825->irq, ret);
1214 return ret;
1215 }
1216
1217 return 0;
1218}
1219
1220static int nau8825_i2c_probe(struct i2c_client *i2c,
1221 const struct i2c_device_id *id)
1222{
1223 struct device *dev = &i2c->dev;
1224 struct nau8825 *nau8825 = dev_get_platdata(&i2c->dev);
1225 int ret, value;
1226
1227 if (!nau8825) {
1228 nau8825 = devm_kzalloc(dev, sizeof(*nau8825), GFP_KERNEL);
1229 if (!nau8825)
1230 return -ENOMEM;
1231 ret = nau8825_read_device_properties(dev, nau8825);
1232 if (ret)
1233 return ret;
1234 }
1235
1236 i2c_set_clientdata(i2c, nau8825);
1237
1238 nau8825->regmap = devm_regmap_init_i2c(i2c, &nau8825_regmap_config);
1239 if (IS_ERR(nau8825->regmap))
1240 return PTR_ERR(nau8825->regmap);
1241 nau8825->dev = dev;
1242 nau8825->irq = i2c->irq;
1243
1244 nau8825_print_device_properties(nau8825);
1245
1246 nau8825_reset_chip(nau8825->regmap);
1247 ret = regmap_read(nau8825->regmap, NAU8825_REG_I2C_DEVICE_ID, &value);
1248 if (ret < 0) {
1249 dev_err(dev, "Failed to read device id from the NAU8825: %d\n",
1250 ret);
1251 return ret;
1252 }
1253 if ((value & NAU8825_SOFTWARE_ID_MASK) !=
1254 NAU8825_SOFTWARE_ID_NAU8825) {
1255 dev_err(dev, "Not a NAU8825 chip\n");
1256 return -ENODEV;
1257 }
1258
1259 nau8825_init_regs(nau8825);
1260
1261 if (i2c->irq)
1262 nau8825_setup_irq(nau8825);
1263
1264 return snd_soc_register_codec(&i2c->dev, &nau8825_codec_driver,
1265 &nau8825_dai, 1);
1266}
1267
1268static int nau8825_i2c_remove(struct i2c_client *client)
1269{
1270 snd_soc_unregister_codec(&client->dev);
1271 return 0;
1272}
1273
1274static const struct i2c_device_id nau8825_i2c_ids[] = {
1275 { "nau8825", 0 },
1276 { }
1277};
1278
1279#ifdef CONFIG_OF
1280static const struct of_device_id nau8825_of_ids[] = {
1281 { .compatible = "nuvoton,nau8825", },
1282 {}
1283};
1284MODULE_DEVICE_TABLE(of, nau8825_of_ids);
1285#endif
1286
1287#ifdef CONFIG_ACPI
1288static const struct acpi_device_id nau8825_acpi_match[] = {
1289 { "10508825", 0 },
1290 {},
1291};
1292MODULE_DEVICE_TABLE(acpi, nau8825_acpi_match);
1293#endif
1294
1295static struct i2c_driver nau8825_driver = {
1296 .driver = {
1297 .name = "nau8825",
1298 .of_match_table = of_match_ptr(nau8825_of_ids),
1299 .acpi_match_table = ACPI_PTR(nau8825_acpi_match),
1300 },
1301 .probe = nau8825_i2c_probe,
1302 .remove = nau8825_i2c_remove,
1303 .id_table = nau8825_i2c_ids,
1304};
1305module_i2c_driver(nau8825_driver);
1306
1307MODULE_DESCRIPTION("ASoC nau8825 driver");
1308MODULE_AUTHOR("Anatol Pomozov <anatol@chromium.org>");
1309MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/nau8825.h b/sound/soc/codecs/nau8825.h
new file mode 100644
index 000000000000..dff8edb83bfd
--- /dev/null
+++ b/sound/soc/codecs/nau8825.h
@@ -0,0 +1,341 @@
1/*
2 * NAU8825 ALSA SoC audio driver
3 *
4 * Copyright 2015 Google Inc.
5 * Author: Anatol Pomozov <anatol.pomozov@chrominium.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __NAU8825_H__
13#define __NAU8825_H__
14
15#define NAU8825_REG_RESET 0x00
16#define NAU8825_REG_ENA_CTRL 0x01
17#define NAU8825_REG_CLK_DIVIDER 0x03
18#define NAU8825_REG_FLL1 0x04
19#define NAU8825_REG_FLL2 0x05
20#define NAU8825_REG_FLL3 0x06
21#define NAU8825_REG_FLL4 0x07
22#define NAU8825_REG_FLL5 0x08
23#define NAU8825_REG_FLL6 0x09
24#define NAU8825_REG_FLL_VCO_RSV 0x0a
25#define NAU8825_REG_HSD_CTRL 0x0c
26#define NAU8825_REG_JACK_DET_CTRL 0x0d
27#define NAU8825_REG_INTERRUPT_MASK 0x0f
28#define NAU8825_REG_IRQ_STATUS 0x10
29#define NAU8825_REG_INT_CLR_KEY_STATUS 0x11
30#define NAU8825_REG_INTERRUPT_DIS_CTRL 0x12
31#define NAU8825_REG_SAR_CTRL 0x13
32#define NAU8825_REG_KEYDET_CTRL 0x14
33#define NAU8825_REG_VDET_THRESHOLD_1 0x15
34#define NAU8825_REG_VDET_THRESHOLD_2 0x16
35#define NAU8825_REG_VDET_THRESHOLD_3 0x17
36#define NAU8825_REG_VDET_THRESHOLD_4 0x18
37#define NAU8825_REG_GPIO34_CTRL 0x19
38#define NAU8825_REG_GPIO12_CTRL 0x1a
39#define NAU8825_REG_TDM_CTRL 0x1b
40#define NAU8825_REG_I2S_PCM_CTRL1 0x1c
41#define NAU8825_REG_I2S_PCM_CTRL2 0x1d
42#define NAU8825_REG_LEFT_TIME_SLOT 0x1e
43#define NAU8825_REG_RIGHT_TIME_SLOT 0x1f
44#define NAU8825_REG_BIQ_CTRL 0x20
45#define NAU8825_REG_BIQ_COF1 0x21
46#define NAU8825_REG_BIQ_COF2 0x22
47#define NAU8825_REG_BIQ_COF3 0x23
48#define NAU8825_REG_BIQ_COF4 0x24
49#define NAU8825_REG_BIQ_COF5 0x25
50#define NAU8825_REG_BIQ_COF6 0x26
51#define NAU8825_REG_BIQ_COF7 0x27
52#define NAU8825_REG_BIQ_COF8 0x28
53#define NAU8825_REG_BIQ_COF9 0x29
54#define NAU8825_REG_BIQ_COF10 0x2a
55#define NAU8825_REG_ADC_RATE 0x2b
56#define NAU8825_REG_DAC_CTRL1 0x2c
57#define NAU8825_REG_DAC_CTRL2 0x2d
58#define NAU8825_REG_DAC_DGAIN_CTRL 0x2f
59#define NAU8825_REG_ADC_DGAIN_CTRL 0x30
60#define NAU8825_REG_MUTE_CTRL 0x31
61#define NAU8825_REG_HSVOL_CTRL 0x32
62#define NAU8825_REG_DACL_CTRL 0x33
63#define NAU8825_REG_DACR_CTRL 0x34
64#define NAU8825_REG_ADC_DRC_KNEE_IP12 0x38
65#define NAU8825_REG_ADC_DRC_KNEE_IP34 0x39
66#define NAU8825_REG_ADC_DRC_SLOPES 0x3a
67#define NAU8825_REG_ADC_DRC_ATKDCY 0x3b
68#define NAU8825_REG_DAC_DRC_KNEE_IP12 0x45
69#define NAU8825_REG_DAC_DRC_KNEE_IP34 0x46
70#define NAU8825_REG_DAC_DRC_SLOPES 0x47
71#define NAU8825_REG_DAC_DRC_ATKDCY 0x48
72#define NAU8825_REG_IMM_MODE_CTRL 0x4c
73#define NAU8825_REG_IMM_RMS_L 0x4d
74#define NAU8825_REG_IMM_RMS_R 0x4e
75#define NAU8825_REG_CLASSG_CTRL 0x50
76#define NAU8825_REG_OPT_EFUSE_CTRL 0x51
77#define NAU8825_REG_MISC_CTRL 0x55
78#define NAU8825_REG_I2C_DEVICE_ID 0x58
79#define NAU8825_REG_SARDOUT_RAM_STATUS 0x59
80#define NAU8825_REG_BIAS_ADJ 0x66
81#define NAU8825_REG_TRIM_SETTINGS 0x68
82#define NAU8825_REG_ANALOG_CONTROL_1 0x69
83#define NAU8825_REG_ANALOG_CONTROL_2 0x6a
84#define NAU8825_REG_ANALOG_ADC_1 0x71
85#define NAU8825_REG_ANALOG_ADC_2 0x72
86#define NAU8825_REG_RDAC 0x73
87#define NAU8825_REG_MIC_BIAS 0x74
88#define NAU8825_REG_BOOST 0x76
89#define NAU8825_REG_FEPGA 0x77
90#define NAU8825_REG_POWER_UP_CONTROL 0x7f
91#define NAU8825_REG_CHARGE_PUMP 0x80
92#define NAU8825_REG_CHARGE_PUMP_INPUT_READ 0x81
93#define NAU8825_REG_GENERAL_STATUS 0x82
94#define NAU8825_REG_MAX NAU8825_REG_GENERAL_STATUS
95
96/* ENA_CTRL (0x1) */
97#define NAU8825_ENABLE_DACR_SFT 10
98#define NAU8825_ENABLE_DACR (1 << NAU8825_ENABLE_DACR_SFT)
99#define NAU8825_ENABLE_DACL_SFT 9
100#define NAU8825_ENABLE_ADC_SFT 8
101#define NAU8825_ENABLE_SAR_SFT 1
102
103/* CLK_DIVIDER (0x3) */
104#define NAU8825_CLK_SRC_SFT 15
105#define NAU8825_CLK_SRC_MASK (1 << NAU8825_CLK_SRC_SFT)
106#define NAU8825_CLK_SRC_VCO (1 << NAU8825_CLK_SRC_SFT)
107#define NAU8825_CLK_SRC_MCLK (0 << NAU8825_CLK_SRC_SFT)
108#define NAU8825_CLK_MCLK_SRC_MASK (0xf << 0)
109
110/* FLL1 (0x04) */
111#define NAU8825_FLL_RATIO_MASK (0x7f << 0)
112
113/* FLL3 (0x06) */
114#define NAU8825_FLL_INTEGER_MASK (0x3ff << 0)
115
116/* FLL4 (0x07) */
117#define NAU8825_FLL_REF_DIV_MASK (0x3 << 10)
118
119/* FLL5 (0x08) */
120#define NAU8825_FLL_FILTER_SW_MASK (0x1 << 14)
121
122/* FLL6 (0x9) */
123#define NAU8825_DCO_EN_MASK (0x1 << 15)
124#define NAU8825_DCO_EN (0x1 << 15)
125#define NAU8825_DCO_DIS (0x0 << 15)
126#define NAU8825_SDM_EN_MASK (0x1 << 14)
127#define NAU8825_SDM_EN (0x1 << 14)
128#define NAU8825_SDM_DIS (0x0 << 14)
129
130/* HSD_CTRL (0xc) */
131#define NAU8825_HSD_AUTO_MODE (1 << 6)
132/* 0 - short to GND, 1 - open */
133#define NAU8825_SPKR_DWN1R (1 << 1)
134#define NAU8825_SPKR_DWN1L (1 << 0)
135
136/* JACK_DET_CTRL (0xd) */
137#define NAU8825_JACK_DET_RESTART (1 << 9)
138#define NAU8825_JACK_INSERT_DEBOUNCE_SFT 5
139#define NAU8825_JACK_INSERT_DEBOUNCE_MASK (0x7 << NAU8825_JACK_INSERT_DEBOUNCE_SFT)
140#define NAU8825_JACK_EJECT_DEBOUNCE_SFT 2
141#define NAU8825_JACK_EJECT_DEBOUNCE_MASK (0x7 << NAU8825_JACK_EJECT_DEBOUNCE_SFT)
142#define NAU8825_JACK_POLARITY (1 << 1) /* 0 - active low, 1 - active high */
143
144/* INTERRUPT_MASK (0xf) */
145#define NAU8825_IRQ_OUTPUT_EN (1 << 11)
146#define NAU8825_IRQ_HEADSET_COMPLETE_EN (1 << 10)
147#define NAU8825_IRQ_KEY_RELEASE_EN (1 << 7)
148#define NAU8825_IRQ_KEY_SHORT_PRESS_EN (1 << 5)
149#define NAU8825_IRQ_EJECT_EN (1 << 2)
150
151/* IRQ_STATUS (0x10) */
152#define NAU8825_HEADSET_COMPLETION_IRQ (1 << 10)
153#define NAU8825_SHORT_CIRCUIT_IRQ (1 << 9)
154#define NAU8825_IMPEDANCE_MEAS_IRQ (1 << 8)
155#define NAU8825_KEY_IRQ_MASK (0x7 << 5)
156#define NAU8825_KEY_RELEASE_IRQ (1 << 7)
157#define NAU8825_KEY_LONG_PRESS_IRQ (1 << 6)
158#define NAU8825_KEY_SHORT_PRESS_IRQ (1 << 5)
159#define NAU8825_MIC_DETECTION_IRQ (1 << 4)
160#define NAU8825_JACK_EJECTION_IRQ_MASK (3 << 2)
161#define NAU8825_JACK_EJECTION_DETECTED (1 << 2)
162#define NAU8825_JACK_INSERTION_IRQ_MASK (3 << 0)
163#define NAU8825_JACK_INSERTION_DETECTED (1 << 0)
164
165/* INTERRUPT_DIS_CTRL (0x12) */
166#define NAU8825_IRQ_HEADSET_COMPLETE_DIS (1 << 10)
167#define NAU8825_IRQ_KEY_RELEASE_DIS (1 << 7)
168#define NAU8825_IRQ_KEY_SHORT_PRESS_DIS (1 << 5)
169#define NAU8825_IRQ_EJECT_DIS (1 << 2)
170
171/* SAR_CTRL (0x13) */
172#define NAU8825_SAR_ADC_EN_SFT 12
173#define NAU8825_SAR_ADC_EN (1 << NAU8825_SAR_ADC_EN_SFT)
174#define NAU8825_SAR_INPUT_MASK (1 << 11)
175#define NAU8825_SAR_INPUT_JKSLV (1 << 11)
176#define NAU8825_SAR_INPUT_JKR2 (0 << 11)
177#define NAU8825_SAR_TRACKING_GAIN_SFT 8
178#define NAU8825_SAR_TRACKING_GAIN_MASK (0x7 << NAU8825_SAR_TRACKING_GAIN_SFT)
179#define NAU8825_SAR_COMPARE_TIME_SFT 2
180#define NAU8825_SAR_COMPARE_TIME_MASK (3 << 2)
181#define NAU8825_SAR_SAMPLING_TIME_SFT 0
182#define NAU8825_SAR_SAMPLING_TIME_MASK (3 << 0)
183
184/* KEYDET_CTRL (0x14) */
185#define NAU8825_KEYDET_SHORTKEY_DEBOUNCE_SFT 12
186#define NAU8825_KEYDET_SHORTKEY_DEBOUNCE_MASK (0x3 << NAU8825_KEYDET_SHORTKEY_DEBOUNCE_SFT)
187#define NAU8825_KEYDET_LEVELS_NR_SFT 8
188#define NAU8825_KEYDET_LEVELS_NR_MASK (0x7 << 8)
189#define NAU8825_KEYDET_HYSTERESIS_SFT 0
190#define NAU8825_KEYDET_HYSTERESIS_MASK 0xf
191
192/* GPIO12_CTRL (0x1a) */
193#define NAU8825_JKDET_PULL_UP (1 << 11) /* 0 - pull down, 1 - pull up */
194#define NAU8825_JKDET_PULL_EN (1 << 9) /* 0 - enable pull, 1 - disable */
195#define NAU8825_JKDET_OUTPUT_EN (1 << 8) /* 0 - enable input, 1 - enable output */
196
197/* I2S_PCM_CTRL1 (0x1c) */
198#define NAU8825_I2S_BP_SFT 7
199#define NAU8825_I2S_BP_MASK (1 << NAU8825_I2S_BP_SFT)
200#define NAU8825_I2S_BP_INV (1 << NAU8825_I2S_BP_SFT)
201#define NAU8825_I2S_PCMB_SFT 6
202#define NAU8825_I2S_PCMB_MASK (1 << NAU8825_I2S_PCMB_SFT)
203#define NAU8825_I2S_PCMB_EN (1 << NAU8825_I2S_PCMB_SFT)
204#define NAU8825_I2S_DL_SFT 2
205#define NAU8825_I2S_DL_MASK (0x3 << NAU8825_I2S_DL_SFT)
206#define NAU8825_I2S_DL_16 (0 << NAU8825_I2S_DL_SFT)
207#define NAU8825_I2S_DL_20 (1 << NAU8825_I2S_DL_SFT)
208#define NAU8825_I2S_DL_24 (2 << NAU8825_I2S_DL_SFT)
209#define NAU8825_I2S_DL_32 (3 << NAU8825_I2S_DL_SFT)
210#define NAU8825_I2S_DF_SFT 0
211#define NAU8825_I2S_DF_MASK (0x3 << NAU8825_I2S_DF_SFT)
212#define NAU8825_I2S_DF_RIGTH (0 << NAU8825_I2S_DF_SFT)
213#define NAU8825_I2S_DF_LEFT (1 << NAU8825_I2S_DF_SFT)
214#define NAU8825_I2S_DF_I2S (2 << NAU8825_I2S_DF_SFT)
215#define NAU8825_I2S_DF_PCM_AB (3 << NAU8825_I2S_DF_SFT)
216
217/* I2S_PCM_CTRL2 (0x1d) */
218#define NAU8825_I2S_TRISTATE (1 << 15) /* 0 - normal mode, 1 - Hi-Z output */
219#define NAU8825_I2S_MS_SFT 3
220#define NAU8825_I2S_MS_MASK (1 << NAU8825_I2S_MS_SFT)
221#define NAU8825_I2S_MS_MASTER (1 << NAU8825_I2S_MS_SFT)
222#define NAU8825_I2S_MS_SLAVE (0 << NAU8825_I2S_MS_SFT)
223
224/* ADC_RATE (0x2b) */
225#define NAU8825_ADC_SYNC_DOWN_SFT 0
226#define NAU8825_ADC_SYNC_DOWN_MASK 0x3
227#define NAU8825_ADC_SYNC_DOWN_32 0
228#define NAU8825_ADC_SYNC_DOWN_64 1
229#define NAU8825_ADC_SYNC_DOWN_128 2
230#define NAU8825_ADC_SYNC_DOWN_256 3
231
232/* DAC_CTRL1 (0x2c) */
233#define NAU8825_DAC_CLIP_OFF (1 << 7)
234#define NAU8825_DAC_OVERSAMPLE_SFT 0
235#define NAU8825_DAC_OVERSAMPLE_MASK 0x7
236#define NAU8825_DAC_OVERSAMPLE_64 0
237#define NAU8825_DAC_OVERSAMPLE_256 1
238#define NAU8825_DAC_OVERSAMPLE_128 2
239#define NAU8825_DAC_OVERSAMPLE_32 4
240
241/* MUTE_CTRL (0x31) */
242#define NAU8825_DAC_ZERO_CROSSING_EN (1 << 9)
243#define NAU8825_DAC_SOFT_MUTE (1 << 9)
244
245/* HSVOL_CTRL (0x32) */
246#define NAU8825_HP_MUTE (1 << 15)
247
248/* DACL_CTRL (0x33) */
249#define NAU8825_DACL_CH_SEL_SFT 9
250
251/* DACR_CTRL (0x34) */
252#define NAU8825_DACR_CH_SEL_SFT 9
253
254/* I2C_DEVICE_ID (0x58) */
255#define NAU8825_GPIO2JD1 (1 << 7)
256#define NAU8825_SOFTWARE_ID_MASK 0x3
257#define NAU8825_SOFTWARE_ID_NAU8825 0x0
258
259/* BIAS_ADJ (0x66) */
260#define NAU8825_BIAS_VMID (1 << 6)
261#define NAU8825_BIAS_VMID_SEL_SFT 4
262#define NAU8825_BIAS_VMID_SEL_MASK (3 << NAU8825_BIAS_VMID_SEL_SFT)
263
264/* ANALOG_CONTROL_2 (0x6a) */
265#define NAU8825_HP_NON_CLASSG_CURRENT_2xADJ (1 << 12)
266#define NAU8825_DAC_CAPACITOR_MSB (1 << 1)
267#define NAU8825_DAC_CAPACITOR_LSB (1 << 0)
268
269/* ANALOG_ADC_2 (0x72) */
270#define NAU8825_ADC_VREFSEL_MASK (0x3 << 8)
271#define NAU8825_ADC_VREFSEL_ANALOG (0 << 8)
272#define NAU8825_ADC_VREFSEL_VMID (1 << 8)
273#define NAU8825_ADC_VREFSEL_VMID_PLUS_0_5DB (2 << 8)
274#define NAU8825_ADC_VREFSEL_VMID_PLUS_1DB (3 << 8)
275#define NAU8825_POWERUP_ADCL (1 << 6)
276
277/* MIC_BIAS (0x74) */
278#define NAU8825_MICBIAS_JKSLV (1 << 14)
279#define NAU8825_MICBIAS_JKR2 (1 << 12)
280#define NAU8825_MICBIAS_POWERUP_SFT 8
281#define NAU8825_MICBIAS_VOLTAGE_SFT 0
282#define NAU8825_MICBIAS_VOLTAGE_MASK 0x7
283
284/* BOOST (0x76) */
285#define NAU8825_PRECHARGE_DIS (1 << 13)
286#define NAU8825_GLOBAL_BIAS_EN (1 << 12)
287#define NAU8825_HP_BOOST_G_DIS (1 << 8)
288#define NAU8825_SHORT_SHUTDOWN_EN (1 << 6)
289
290/* POWER_UP_CONTROL (0x7f) */
291#define NAU8825_POWERUP_INTEGR_R (1 << 5)
292#define NAU8825_POWERUP_INTEGR_L (1 << 4)
293#define NAU8825_POWERUP_DRV_IN_R (1 << 3)
294#define NAU8825_POWERUP_DRV_IN_L (1 << 2)
295#define NAU8825_POWERUP_HP_DRV_R (1 << 1)
296#define NAU8825_POWERUP_HP_DRV_L (1 << 0)
297
298/* CHARGE_PUMP (0x80) */
299#define NAU8825_JAMNODCLOW (1 << 10)
300#define NAU8825_POWER_DOWN_DACR (1 << 9)
301#define NAU8825_POWER_DOWN_DACL (1 << 8)
302#define NAU8825_CHANRGE_PUMP_EN (1 << 5)
303
304
305/* System Clock Source */
306enum {
307 NAU8825_CLK_MCLK = 0,
308 NAU8825_CLK_INTERNAL,
309};
310
311struct nau8825 {
312 struct device *dev;
313 struct regmap *regmap;
314 struct snd_soc_dapm_context *dapm;
315 struct snd_soc_jack *jack;
316 struct clk *mclk;
317 int irq;
318 int mclk_freq; /* 0 - mclk is disabled */
319 int button_pressed;
320 int micbias_voltage;
321 int vref_impedance;
322 bool jkdet_enable;
323 bool jkdet_pull_enable;
324 bool jkdet_pull_up;
325 int jkdet_polarity;
326 int sar_threshold_num;
327 int sar_threshold[8];
328 int sar_hysteresis;
329 int sar_voltage;
330 int sar_compare_time;
331 int sar_sampling_time;
332 int key_debounce;
333 int jack_insert_debounce;
334 int jack_eject_debounce;
335};
336
337int nau8825_enable_jack_detect(struct snd_soc_codec *codec,
338 struct snd_soc_jack *jack);
339
340
341#endif /* __NAU8825_H__ */
diff --git a/sound/soc/codecs/rl6347a.c b/sound/soc/codecs/rl6347a.c
index 91d5166bd3a1..a4b910efbd45 100644
--- a/sound/soc/codecs/rl6347a.c
+++ b/sound/soc/codecs/rl6347a.c
@@ -11,25 +11,8 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h> 14#include <linux/i2c.h>
19#include <linux/platform_device.h> 15#include <linux/regmap.h>
20#include <linux/spi/spi.h>
21#include <linux/dmi.h>
22#include <linux/acpi.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30#include <sound/jack.h>
31#include <linux/workqueue.h>
32#include <sound/hda_verbs.h>
33 16
34#include "rl6347a.h" 17#include "rl6347a.h"
35 18
diff --git a/sound/soc/codecs/rl6347a.h b/sound/soc/codecs/rl6347a.h
index 1cb56e50b7f3..e127919cb36b 100644
--- a/sound/soc/codecs/rl6347a.h
+++ b/sound/soc/codecs/rl6347a.h
@@ -12,6 +12,8 @@
12#ifndef __RL6347A_H__ 12#ifndef __RL6347A_H__
13#define __RL6347A_H__ 13#define __RL6347A_H__
14 14
15#include <sound/hda_verbs.h>
16
15#define VERB_CMD(V, N, D) ((N << 20) | (V << 8) | D) 17#define VERB_CMD(V, N, D) ((N << 20) | (V << 8) | D)
16 18
17#define RL6347A_VENDOR_REGISTERS 0x20 19#define RL6347A_VENDOR_REGISTERS 0x20
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index bd9365885f73..af2ed774b552 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -29,7 +29,6 @@
29#include <sound/jack.h> 29#include <sound/jack.h>
30#include <linux/workqueue.h> 30#include <linux/workqueue.h>
31#include <sound/rt286.h> 31#include <sound/rt286.h>
32#include <sound/hda_verbs.h>
33 32
34#include "rl6347a.h" 33#include "rl6347a.h"
35#include "rt286.h" 34#include "rt286.h"
@@ -38,7 +37,7 @@
38#define RT288_VENDOR_ID 0x10ec0288 37#define RT288_VENDOR_ID 0x10ec0288
39 38
40struct rt286_priv { 39struct rt286_priv {
41 const struct reg_default *index_cache; 40 struct reg_default *index_cache;
42 int index_cache_size; 41 int index_cache_size;
43 struct regmap *regmap; 42 struct regmap *regmap;
44 struct snd_soc_codec *codec; 43 struct snd_soc_codec *codec;
@@ -1161,7 +1160,11 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1161 return -ENODEV; 1160 return -ENODEV;
1162 } 1161 }
1163 1162
1164 rt286->index_cache = rt286_index_def; 1163 rt286->index_cache = devm_kmemdup(&i2c->dev, rt286_index_def,
1164 sizeof(rt286_index_def), GFP_KERNEL);
1165 if (!rt286->index_cache)
1166 return -ENOMEM;
1167
1165 rt286->index_cache_size = INDEX_CACHE_SIZE; 1168 rt286->index_cache_size = INDEX_CACHE_SIZE;
1166 rt286->i2c = i2c; 1169 rt286->i2c = i2c;
1167 i2c_set_clientdata(i2c, rt286); 1170 i2c_set_clientdata(i2c, rt286);
diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c
index 3c2f0f8d6266..b3f795c60749 100644
--- a/sound/soc/codecs/rt298.c
+++ b/sound/soc/codecs/rt298.c
@@ -28,7 +28,6 @@
28#include <sound/jack.h> 28#include <sound/jack.h>
29#include <linux/workqueue.h> 29#include <linux/workqueue.h>
30#include <sound/rt298.h> 30#include <sound/rt298.h>
31#include <sound/hda_verbs.h>
32 31
33#include "rl6347a.h" 32#include "rl6347a.h"
34#include "rt298.h" 33#include "rt298.h"
@@ -49,25 +48,25 @@ struct rt298_priv {
49 int is_hp_in; 48 int is_hp_in;
50}; 49};
51 50
52static struct reg_default rt298_index_def[] = { 51static const struct reg_default rt298_index_def[] = {
53 { 0x01, 0xaaaa }, 52 { 0x01, 0xa5a8 },
54 { 0x02, 0x8aaa }, 53 { 0x02, 0x8e95 },
55 { 0x03, 0x0002 }, 54 { 0x03, 0x0002 },
56 { 0x04, 0xaf01 }, 55 { 0x04, 0xaf67 },
57 { 0x08, 0x000d }, 56 { 0x08, 0x200f },
58 { 0x09, 0xd810 }, 57 { 0x09, 0xd010 },
59 { 0x0a, 0x0120 }, 58 { 0x0a, 0x0100 },
60 { 0x0b, 0x0000 }, 59 { 0x0b, 0x0000 },
61 { 0x0d, 0x2800 }, 60 { 0x0d, 0x2800 },
62 { 0x0f, 0x0000 }, 61 { 0x0f, 0x0022 },
63 { 0x19, 0x0a17 }, 62 { 0x19, 0x0217 },
64 { 0x20, 0x0020 }, 63 { 0x20, 0x0020 },
65 { 0x33, 0x0208 }, 64 { 0x33, 0x0208 },
66 { 0x46, 0x0300 }, 65 { 0x46, 0x0300 },
67 { 0x49, 0x0004 }, 66 { 0x49, 0x4004 },
68 { 0x4f, 0x50e9 }, 67 { 0x4f, 0x50c9 },
69 { 0x50, 0x2000 }, 68 { 0x50, 0x3000 },
70 { 0x63, 0x2902 }, 69 { 0x63, 0x1b02 },
71 { 0x67, 0x1111 }, 70 { 0x67, 0x1111 },
72 { 0x68, 0x1016 }, 71 { 0x68, 0x1016 },
73 { 0x69, 0x273f }, 72 { 0x69, 0x273f },
@@ -129,7 +128,7 @@ static bool rt298_volatile_register(struct device *dev, unsigned int reg)
129 case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT298_HP_OUT, 0): 128 case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT298_HP_OUT, 0):
130 return true; 129 return true;
131 default: 130 default:
132 return true; 131 return false;
133 } 132 }
134 133
135 134
@@ -1165,7 +1164,11 @@ static int rt298_i2c_probe(struct i2c_client *i2c,
1165 return -ENODEV; 1164 return -ENODEV;
1166 } 1165 }
1167 1166
1168 rt298->index_cache = rt298_index_def; 1167 rt298->index_cache = devm_kmemdup(&i2c->dev, rt298_index_def,
1168 sizeof(rt298_index_def), GFP_KERNEL);
1169 if (!rt298->index_cache)
1170 return -ENOMEM;
1171
1169 rt298->index_cache_size = INDEX_CACHE_SIZE; 1172 rt298->index_cache_size = INDEX_CACHE_SIZE;
1170 rt298->i2c = i2c; 1173 rt298->i2c = i2c;
1171 i2c_set_clientdata(i2c, rt298); 1174 i2c_set_clientdata(i2c, rt298);
@@ -1214,7 +1217,7 @@ static int rt298_i2c_probe(struct i2c_client *i2c,
1214 mdelay(10); 1217 mdelay(10);
1215 1218
1216 if (!rt298->pdata.gpio2_en) 1219 if (!rt298->pdata.gpio2_en)
1217 regmap_write(rt298->regmap, RT298_SET_DMIC2_DEFAULT, 0x4000); 1220 regmap_write(rt298->regmap, RT298_SET_DMIC2_DEFAULT, 0x40);
1218 else 1221 else
1219 regmap_write(rt298->regmap, RT298_SET_DMIC2_DEFAULT, 0); 1222 regmap_write(rt298->regmap, RT298_SET_DMIC2_DEFAULT, 0);
1220 1223
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index e1ceeb885f7d..f2beb1aa5763 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -405,11 +405,14 @@ static const struct snd_kcontrol_new rt5640_snd_controls[] = {
405 SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5640_DAC1_DIG_VOL, 405 SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5640_DAC1_DIG_VOL,
406 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 406 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT,
407 175, 0, dac_vol_tlv), 407 175, 0, dac_vol_tlv),
408 /* IN1/IN2 Control */ 408 /* IN1/IN2/IN3 Control */
409 SOC_SINGLE_TLV("IN1 Boost", RT5640_IN1_IN2, 409 SOC_SINGLE_TLV("IN1 Boost", RT5640_IN1_IN2,
410 RT5640_BST_SFT1, 8, 0, bst_tlv), 410 RT5640_BST_SFT1, 8, 0, bst_tlv),
411 SOC_SINGLE_TLV("IN2 Boost", RT5640_IN3_IN4, 411 SOC_SINGLE_TLV("IN2 Boost", RT5640_IN3_IN4,
412 RT5640_BST_SFT2, 8, 0, bst_tlv), 412 RT5640_BST_SFT2, 8, 0, bst_tlv),
413 SOC_SINGLE_TLV("IN3 Boost", RT5640_IN1_IN2,
414 RT5640_BST_SFT2, 8, 0, bst_tlv),
415
413 /* INL/INR Volume Control */ 416 /* INL/INR Volume Control */
414 SOC_DOUBLE_TLV("IN Capture Volume", RT5640_INL_INR_VOL, 417 SOC_DOUBLE_TLV("IN Capture Volume", RT5640_INL_INR_VOL,
415 RT5640_INL_VOL_SFT, RT5640_INR_VOL_SFT, 418 RT5640_INL_VOL_SFT, RT5640_INR_VOL_SFT,
@@ -598,6 +601,8 @@ static const struct snd_kcontrol_new rt5640_rec_l_mix[] = {
598 RT5640_M_HP_L_RM_L_SFT, 1, 1), 601 RT5640_M_HP_L_RM_L_SFT, 1, 1),
599 SOC_DAPM_SINGLE("INL Switch", RT5640_REC_L2_MIXER, 602 SOC_DAPM_SINGLE("INL Switch", RT5640_REC_L2_MIXER,
600 RT5640_M_IN_L_RM_L_SFT, 1, 1), 603 RT5640_M_IN_L_RM_L_SFT, 1, 1),
604 SOC_DAPM_SINGLE("BST3 Switch", RT5640_REC_L2_MIXER,
605 RT5640_M_BST2_RM_L_SFT, 1, 1),
601 SOC_DAPM_SINGLE("BST2 Switch", RT5640_REC_L2_MIXER, 606 SOC_DAPM_SINGLE("BST2 Switch", RT5640_REC_L2_MIXER,
602 RT5640_M_BST4_RM_L_SFT, 1, 1), 607 RT5640_M_BST4_RM_L_SFT, 1, 1),
603 SOC_DAPM_SINGLE("BST1 Switch", RT5640_REC_L2_MIXER, 608 SOC_DAPM_SINGLE("BST1 Switch", RT5640_REC_L2_MIXER,
@@ -611,6 +616,8 @@ static const struct snd_kcontrol_new rt5640_rec_r_mix[] = {
611 RT5640_M_HP_R_RM_R_SFT, 1, 1), 616 RT5640_M_HP_R_RM_R_SFT, 1, 1),
612 SOC_DAPM_SINGLE("INR Switch", RT5640_REC_R2_MIXER, 617 SOC_DAPM_SINGLE("INR Switch", RT5640_REC_R2_MIXER,
613 RT5640_M_IN_R_RM_R_SFT, 1, 1), 618 RT5640_M_IN_R_RM_R_SFT, 1, 1),
619 SOC_DAPM_SINGLE("BST3 Switch", RT5640_REC_R2_MIXER,
620 RT5640_M_BST2_RM_R_SFT, 1, 1),
614 SOC_DAPM_SINGLE("BST2 Switch", RT5640_REC_R2_MIXER, 621 SOC_DAPM_SINGLE("BST2 Switch", RT5640_REC_R2_MIXER,
615 RT5640_M_BST4_RM_R_SFT, 1, 1), 622 RT5640_M_BST4_RM_R_SFT, 1, 1),
616 SOC_DAPM_SINGLE("BST1 Switch", RT5640_REC_R2_MIXER, 623 SOC_DAPM_SINGLE("BST1 Switch", RT5640_REC_R2_MIXER,
@@ -1065,6 +1072,8 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
1065 SND_SOC_DAPM_INPUT("IN1N"), 1072 SND_SOC_DAPM_INPUT("IN1N"),
1066 SND_SOC_DAPM_INPUT("IN2P"), 1073 SND_SOC_DAPM_INPUT("IN2P"),
1067 SND_SOC_DAPM_INPUT("IN2N"), 1074 SND_SOC_DAPM_INPUT("IN2N"),
1075 SND_SOC_DAPM_INPUT("IN3P"),
1076 SND_SOC_DAPM_INPUT("IN3N"),
1068 SND_SOC_DAPM_PGA("DMIC L1", SND_SOC_NOPM, 0, 0, NULL, 0), 1077 SND_SOC_DAPM_PGA("DMIC L1", SND_SOC_NOPM, 0, 0, NULL, 0),
1069 SND_SOC_DAPM_PGA("DMIC R1", SND_SOC_NOPM, 0, 0, NULL, 0), 1078 SND_SOC_DAPM_PGA("DMIC R1", SND_SOC_NOPM, 0, 0, NULL, 0),
1070 SND_SOC_DAPM_PGA("DMIC L2", SND_SOC_NOPM, 0, 0, NULL, 0), 1079 SND_SOC_DAPM_PGA("DMIC L2", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -1081,6 +1090,8 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
1081 RT5640_PWR_BST1_BIT, 0, NULL, 0), 1090 RT5640_PWR_BST1_BIT, 0, NULL, 0),
1082 SND_SOC_DAPM_PGA("BST2", RT5640_PWR_ANLG2, 1091 SND_SOC_DAPM_PGA("BST2", RT5640_PWR_ANLG2,
1083 RT5640_PWR_BST4_BIT, 0, NULL, 0), 1092 RT5640_PWR_BST4_BIT, 0, NULL, 0),
1093 SND_SOC_DAPM_PGA("BST3", RT5640_PWR_ANLG2,
1094 RT5640_PWR_BST2_BIT, 0, NULL, 0),
1084 /* Input Volume */ 1095 /* Input Volume */
1085 SND_SOC_DAPM_PGA("INL VOL", RT5640_PWR_VOL, 1096 SND_SOC_DAPM_PGA("INL VOL", RT5640_PWR_VOL,
1086 RT5640_PWR_IN_L_BIT, 0, NULL, 0), 1097 RT5640_PWR_IN_L_BIT, 0, NULL, 0),
@@ -1310,6 +1321,7 @@ static const struct snd_soc_dapm_widget rt5639_specific_dapm_widgets[] = {
1310static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { 1321static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
1311 {"IN1P", NULL, "LDO2"}, 1322 {"IN1P", NULL, "LDO2"},
1312 {"IN2P", NULL, "LDO2"}, 1323 {"IN2P", NULL, "LDO2"},
1324 {"IN3P", NULL, "LDO2"},
1313 1325
1314 {"DMIC L1", NULL, "DMIC1"}, 1326 {"DMIC L1", NULL, "DMIC1"},
1315 {"DMIC R1", NULL, "DMIC1"}, 1327 {"DMIC R1", NULL, "DMIC1"},
@@ -1320,18 +1332,22 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
1320 {"BST1", NULL, "IN1N"}, 1332 {"BST1", NULL, "IN1N"},
1321 {"BST2", NULL, "IN2P"}, 1333 {"BST2", NULL, "IN2P"},
1322 {"BST2", NULL, "IN2N"}, 1334 {"BST2", NULL, "IN2N"},
1335 {"BST3", NULL, "IN3P"},
1336 {"BST3", NULL, "IN3N"},
1323 1337
1324 {"INL VOL", NULL, "IN2P"}, 1338 {"INL VOL", NULL, "IN2P"},
1325 {"INR VOL", NULL, "IN2N"}, 1339 {"INR VOL", NULL, "IN2N"},
1326 1340
1327 {"RECMIXL", "HPOL Switch", "HPOL"}, 1341 {"RECMIXL", "HPOL Switch", "HPOL"},
1328 {"RECMIXL", "INL Switch", "INL VOL"}, 1342 {"RECMIXL", "INL Switch", "INL VOL"},
1343 {"RECMIXL", "BST3 Switch", "BST3"},
1329 {"RECMIXL", "BST2 Switch", "BST2"}, 1344 {"RECMIXL", "BST2 Switch", "BST2"},
1330 {"RECMIXL", "BST1 Switch", "BST1"}, 1345 {"RECMIXL", "BST1 Switch", "BST1"},
1331 {"RECMIXL", "OUT MIXL Switch", "OUT MIXL"}, 1346 {"RECMIXL", "OUT MIXL Switch", "OUT MIXL"},
1332 1347
1333 {"RECMIXR", "HPOR Switch", "HPOR"}, 1348 {"RECMIXR", "HPOR Switch", "HPOR"},
1334 {"RECMIXR", "INR Switch", "INR VOL"}, 1349 {"RECMIXR", "INR Switch", "INR VOL"},
1350 {"RECMIXR", "BST3 Switch", "BST3"},
1335 {"RECMIXR", "BST2 Switch", "BST2"}, 1351 {"RECMIXR", "BST2 Switch", "BST2"},
1336 {"RECMIXR", "BST1 Switch", "BST1"}, 1352 {"RECMIXR", "BST1 Switch", "BST1"},
1337 {"RECMIXR", "OUT MIXR Switch", "OUT MIXR"}, 1353 {"RECMIXR", "OUT MIXR Switch", "OUT MIXR"},
@@ -2260,6 +2276,10 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
2260 regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4, 2276 regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4,
2261 RT5640_IN_DF2, RT5640_IN_DF2); 2277 RT5640_IN_DF2, RT5640_IN_DF2);
2262 2278
2279 if (rt5640->pdata.in3_diff)
2280 regmap_update_bits(rt5640->regmap, RT5640_IN1_IN2,
2281 RT5640_IN_DF2, RT5640_IN_DF2);
2282
2263 rt5640->hp_mute = 1; 2283 rt5640->hp_mute = 1;
2264 2284
2265 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640, 2285 return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640,
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index 4972bf3efa91..28132375e427 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -42,6 +42,8 @@
42 42
43#define RT5645_PR_BASE (RT5645_PR_RANGE_BASE + (0 * RT5645_PR_SPACING)) 43#define RT5645_PR_BASE (RT5645_PR_RANGE_BASE + (0 * RT5645_PR_SPACING))
44 44
45#define RT5645_HWEQ_NUM 57
46
45static const struct regmap_range_cfg rt5645_ranges[] = { 47static const struct regmap_range_cfg rt5645_ranges[] = {
46 { 48 {
47 .name = "PR", 49 .name = "PR",
@@ -224,6 +226,11 @@ static const struct reg_default rt5645_reg[] = {
224 { 0xff, 0x6308 }, 226 { 0xff, 0x6308 },
225}; 227};
226 228
229struct rt5645_eq_param_s {
230 unsigned short reg;
231 unsigned short val;
232};
233
227static const char *const rt5645_supply_names[] = { 234static const char *const rt5645_supply_names[] = {
228 "avdd", 235 "avdd",
229 "cpvdd", 236 "cpvdd",
@@ -240,6 +247,7 @@ struct rt5645_priv {
240 struct snd_soc_jack *btn_jack; 247 struct snd_soc_jack *btn_jack;
241 struct delayed_work jack_detect_work; 248 struct delayed_work jack_detect_work;
242 struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)]; 249 struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)];
250 struct rt5645_eq_param_s *eq_param;
243 251
244 int codec_type; 252 int codec_type;
245 int sysclk; 253 int sysclk;
@@ -469,6 +477,94 @@ static const DECLARE_TLV_DB_RANGE(bst_tlv,
469 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0) 477 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0)
470); 478);
471 479
480/* {-6, -4.5, -3, -1.5, 0, 0.82, 1.58, 2.28} dB */
481static const DECLARE_TLV_DB_RANGE(spk_clsd_tlv,
482 0, 4, TLV_DB_SCALE_ITEM(-600, 150, 0),
483 5, 5, TLV_DB_SCALE_ITEM(82, 0, 0),
484 6, 6, TLV_DB_SCALE_ITEM(158, 0, 0),
485 7, 7, TLV_DB_SCALE_ITEM(228, 0, 0)
486);
487
488static int rt5645_hweq_info(struct snd_kcontrol *kcontrol,
489 struct snd_ctl_elem_info *uinfo)
490{
491 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
492 uinfo->count = RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s);
493
494 return 0;
495}
496
497static int rt5645_hweq_get(struct snd_kcontrol *kcontrol,
498 struct snd_ctl_elem_value *ucontrol)
499{
500 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
501 struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
502 struct rt5645_eq_param_s *eq_param =
503 (struct rt5645_eq_param_s *)ucontrol->value.bytes.data;
504 int i;
505
506 for (i = 0; i < RT5645_HWEQ_NUM; i++) {
507 eq_param[i].reg = cpu_to_be16(rt5645->eq_param[i].reg);
508 eq_param[i].val = cpu_to_be16(rt5645->eq_param[i].val);
509 }
510
511 return 0;
512}
513
514static bool rt5645_validate_hweq(unsigned short reg)
515{
516 if ((reg >= 0x1a4 && reg <= 0x1cd) | (reg >= 0x1e5 && reg <= 0x1f8) |
517 (reg == RT5645_EQ_CTRL2))
518 return true;
519
520 return false;
521}
522
523static int rt5645_hweq_put(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_value *ucontrol)
525{
526 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
527 struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
528 struct rt5645_eq_param_s *eq_param =
529 (struct rt5645_eq_param_s *)ucontrol->value.bytes.data;
530 int i;
531
532 for (i = 0; i < RT5645_HWEQ_NUM; i++) {
533 eq_param[i].reg = be16_to_cpu(eq_param[i].reg);
534 eq_param[i].val = be16_to_cpu(eq_param[i].val);
535 }
536
537 /* The final setting of the table should be RT5645_EQ_CTRL2 */
538 for (i = RT5645_HWEQ_NUM - 1; i >= 0; i--) {
539 if (eq_param[i].reg == 0)
540 continue;
541 else if (eq_param[i].reg != RT5645_EQ_CTRL2)
542 return 0;
543 else
544 break;
545 }
546
547 for (i = 0; i < RT5645_HWEQ_NUM; i++) {
548 if (!rt5645_validate_hweq(eq_param[i].reg) &&
549 eq_param[i].reg != 0)
550 return 0;
551 else if (eq_param[i].reg == 0)
552 break;
553 }
554
555 memcpy(rt5645->eq_param, eq_param,
556 RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s));
557
558 return 0;
559}
560
561#define RT5645_HWEQ(xname) \
562{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
563 .info = rt5645_hweq_info, \
564 .get = rt5645_hweq_get, \
565 .put = rt5645_hweq_put \
566}
567
472static const struct snd_kcontrol_new rt5645_snd_controls[] = { 568static const struct snd_kcontrol_new rt5645_snd_controls[] = {
473 /* Speaker Output Volume */ 569 /* Speaker Output Volume */
474 SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL, 570 SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL,
@@ -476,6 +572,10 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
476 SOC_DOUBLE_TLV("Speaker Playback Volume", RT5645_SPK_VOL, 572 SOC_DOUBLE_TLV("Speaker Playback Volume", RT5645_SPK_VOL,
477 RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv), 573 RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv),
478 574
575 /* ClassD modulator Speaker Gain Ratio */
576 SOC_SINGLE_TLV("Speaker ClassD Playback Volume", RT5645_SPO_CLSD_RATIO,
577 RT5645_SPK_G_CLSD_SFT, 7, 0, spk_clsd_tlv),
578
479 /* Headphone Output Volume */ 579 /* Headphone Output Volume */
480 SOC_DOUBLE("Headphone Channel Switch", RT5645_HP_VOL, 580 SOC_DOUBLE("Headphone Channel Switch", RT5645_HP_VOL,
481 RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1), 581 RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1),
@@ -519,16 +619,17 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
519 RT5645_L_VOL_SFT + 1, RT5645_R_VOL_SFT + 1, 63, 0, adc_vol_tlv), 619 RT5645_L_VOL_SFT + 1, RT5645_R_VOL_SFT + 1, 63, 0, adc_vol_tlv),
520 620
521 /* ADC Boost Volume Control */ 621 /* ADC Boost Volume Control */
522 SOC_DOUBLE_TLV("STO1 ADC Boost Gain", RT5645_ADC_BST_VOL1, 622 SOC_DOUBLE_TLV("ADC Boost Capture Volume", RT5645_ADC_BST_VOL1,
523 RT5645_STO1_ADC_L_BST_SFT, RT5645_STO1_ADC_R_BST_SFT, 3, 0, 623 RT5645_STO1_ADC_L_BST_SFT, RT5645_STO1_ADC_R_BST_SFT, 3, 0,
524 adc_bst_tlv), 624 adc_bst_tlv),
525 SOC_DOUBLE_TLV("STO2 ADC Boost Gain", RT5645_ADC_BST_VOL1, 625 SOC_DOUBLE_TLV("Mono ADC Boost Capture Volume", RT5645_ADC_BST_VOL2,
526 RT5645_STO2_ADC_L_BST_SFT, RT5645_STO2_ADC_R_BST_SFT, 3, 0, 626 RT5645_MONO_ADC_L_BST_SFT, RT5645_MONO_ADC_R_BST_SFT, 3, 0,
527 adc_bst_tlv), 627 adc_bst_tlv),
528 628
529 /* I2S2 function select */ 629 /* I2S2 function select */
530 SOC_SINGLE("I2S2 Func Switch", RT5645_GPIO_CTRL1, RT5645_I2S2_SEL_SFT, 630 SOC_SINGLE("I2S2 Func Switch", RT5645_GPIO_CTRL1, RT5645_I2S2_SEL_SFT,
531 1, 1), 631 1, 1),
632 RT5645_HWEQ("Speaker HWEQ"),
532}; 633};
533 634
534/** 635/**
@@ -619,6 +720,22 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
619 720
620} 721}
621 722
723static int rt5645_enable_hweq(struct snd_soc_codec *codec)
724{
725 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
726 int i;
727
728 for (i = 0; i < RT5645_HWEQ_NUM; i++) {
729 if (rt5645_validate_hweq(rt5645->eq_param[i].reg))
730 regmap_write(rt5645->regmap, rt5645->eq_param[i].reg,
731 rt5645->eq_param[i].val);
732 else
733 break;
734 }
735
736 return 0;
737}
738
622/** 739/**
623 * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters 740 * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters
624 * @codec: SoC audio codec device. 741 * @codec: SoC audio codec device.
@@ -732,14 +849,14 @@ static const struct snd_kcontrol_new rt5645_mono_adc_r_mix[] = {
732static const struct snd_kcontrol_new rt5645_dac_l_mix[] = { 849static const struct snd_kcontrol_new rt5645_dac_l_mix[] = {
733 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5645_AD_DA_MIXER, 850 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5645_AD_DA_MIXER,
734 RT5645_M_ADCMIX_L_SFT, 1, 1), 851 RT5645_M_ADCMIX_L_SFT, 1, 1),
735 SOC_DAPM_SINGLE("DAC1 Switch", RT5645_AD_DA_MIXER, 852 SOC_DAPM_SINGLE_AUTODISABLE("DAC1 Switch", RT5645_AD_DA_MIXER,
736 RT5645_M_DAC1_L_SFT, 1, 1), 853 RT5645_M_DAC1_L_SFT, 1, 1),
737}; 854};
738 855
739static const struct snd_kcontrol_new rt5645_dac_r_mix[] = { 856static const struct snd_kcontrol_new rt5645_dac_r_mix[] = {
740 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5645_AD_DA_MIXER, 857 SOC_DAPM_SINGLE("Stereo ADC Switch", RT5645_AD_DA_MIXER,
741 RT5645_M_ADCMIX_R_SFT, 1, 1), 858 RT5645_M_ADCMIX_R_SFT, 1, 1),
742 SOC_DAPM_SINGLE("DAC1 Switch", RT5645_AD_DA_MIXER, 859 SOC_DAPM_SINGLE_AUTODISABLE("DAC1 Switch", RT5645_AD_DA_MIXER,
743 RT5645_M_DAC1_R_SFT, 1, 1), 860 RT5645_M_DAC1_R_SFT, 1, 1),
744}; 861};
745 862
@@ -1381,7 +1498,7 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on)
1381 regmap_write(rt5645->regmap, RT5645_PR_BASE + 1498 regmap_write(rt5645->regmap, RT5645_PR_BASE +
1382 RT5645_MAMP_INT_REG2, 0xfc00); 1499 RT5645_MAMP_INT_REG2, 0xfc00);
1383 snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140); 1500 snd_soc_write(codec, RT5645_DEPOP_M2, 0x1140);
1384 mdelay(5); 1501 msleep(40);
1385 rt5645->hp_on = true; 1502 rt5645->hp_on = true;
1386 } else { 1503 } else {
1387 /* depop parameters */ 1504 /* depop parameters */
@@ -1523,6 +1640,7 @@ static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
1523 1640
1524 switch (event) { 1641 switch (event) {
1525 case SND_SOC_DAPM_POST_PMU: 1642 case SND_SOC_DAPM_POST_PMU:
1643 rt5645_enable_hweq(codec);
1526 snd_soc_update_bits(codec, RT5645_PWR_DIG1, 1644 snd_soc_update_bits(codec, RT5645_PWR_DIG1,
1527 RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | 1645 RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
1528 RT5645_PWR_CLS_D_L, 1646 RT5645_PWR_CLS_D_L,
@@ -1531,6 +1649,7 @@ static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
1531 break; 1649 break;
1532 1650
1533 case SND_SOC_DAPM_PRE_PMD: 1651 case SND_SOC_DAPM_PRE_PMD:
1652 snd_soc_write(codec, RT5645_EQ_CTRL2, 0);
1534 snd_soc_update_bits(codec, RT5645_PWR_DIG1, 1653 snd_soc_update_bits(codec, RT5645_PWR_DIG1,
1535 RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | 1654 RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
1536 RT5645_PWR_CLS_D_L, 0); 1655 RT5645_PWR_CLS_D_L, 0);
@@ -2733,6 +2852,10 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec,
2733 snd_soc_update_bits(codec, RT5645_PWR_ANLG1, 2852 snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
2734 RT5645_PWR_FV1 | RT5645_PWR_FV2, 2853 RT5645_PWR_FV1 | RT5645_PWR_FV2,
2735 RT5645_PWR_FV1 | RT5645_PWR_FV2); 2854 RT5645_PWR_FV1 | RT5645_PWR_FV2);
2855 if (rt5645->en_button_func &&
2856 snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
2857 queue_delayed_work(system_power_efficient_wq,
2858 &rt5645->jack_detect_work, msecs_to_jiffies(0));
2736 break; 2859 break;
2737 2860
2738 case SND_SOC_BIAS_OFF: 2861 case SND_SOC_BIAS_OFF:
@@ -2829,13 +2952,15 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
2829 snd_soc_dapm_sync(dapm); 2952 snd_soc_dapm_sync(dapm);
2830 rt5645->jack_type = SND_JACK_HEADPHONE; 2953 rt5645->jack_type = SND_JACK_HEADPHONE;
2831 } 2954 }
2832 2955 if (rt5645->pdata.jd_invert)
2833 snd_soc_update_bits(codec, RT5645_CHARGE_PUMP, 0x0300, 0x0200); 2956 regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
2834 snd_soc_write(codec, RT5645_DEPOP_M1, 0x001d); 2957 RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
2835 snd_soc_write(codec, RT5645_DEPOP_M1, 0x0001);
2836 } else { /* jack out */ 2958 } else { /* jack out */
2837 rt5645->jack_type = 0; 2959 rt5645->jack_type = 0;
2838 2960
2961 regmap_update_bits(rt5645->regmap, RT5645_HP_VOL,
2962 RT5645_L_MUTE | RT5645_R_MUTE,
2963 RT5645_L_MUTE | RT5645_R_MUTE);
2839 regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL2, 2964 regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL2,
2840 RT5645_CBJ_MN_JD, RT5645_CBJ_MN_JD); 2965 RT5645_CBJ_MN_JD, RT5645_CBJ_MN_JD);
2841 regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1, 2966 regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1,
@@ -2848,6 +2973,9 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
2848 snd_soc_dapm_disable_pin(dapm, "LDO2"); 2973 snd_soc_dapm_disable_pin(dapm, "LDO2");
2849 snd_soc_dapm_disable_pin(dapm, "Mic Det Power"); 2974 snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
2850 snd_soc_dapm_sync(dapm); 2975 snd_soc_dapm_sync(dapm);
2976 if (rt5645->pdata.jd_invert)
2977 regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
2978 RT5645_JD_1_1_MASK, RT5645_JD_1_1_NOR);
2851 } 2979 }
2852 2980
2853 return rt5645->jack_type; 2981 return rt5645->jack_type;
@@ -2880,8 +3008,6 @@ int rt5645_set_jack_detect(struct snd_soc_codec *codec,
2880 rt5645->en_button_func = true; 3008 rt5645->en_button_func = true;
2881 regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, 3009 regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1,
2882 RT5645_GP1_PIN_IRQ, RT5645_GP1_PIN_IRQ); 3010 RT5645_GP1_PIN_IRQ, RT5645_GP1_PIN_IRQ);
2883 regmap_update_bits(rt5645->regmap, RT5645_DEPOP_M1,
2884 RT5645_HP_CB_MASK, RT5645_HP_CB_PU);
2885 regmap_update_bits(rt5645->regmap, RT5645_GEN_CTRL1, 3011 regmap_update_bits(rt5645->regmap, RT5645_GEN_CTRL1,
2886 RT5645_DIG_GATE_CTRL, RT5645_DIG_GATE_CTRL); 3012 RT5645_DIG_GATE_CTRL, RT5645_DIG_GATE_CTRL);
2887 } 3013 }
@@ -3041,6 +3167,9 @@ static int rt5645_probe(struct snd_soc_codec *codec)
3041 snd_soc_dapm_sync(dapm); 3167 snd_soc_dapm_sync(dapm);
3042 } 3168 }
3043 3169
3170 rt5645->eq_param = devm_kzalloc(codec->dev,
3171 RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s), GFP_KERNEL);
3172
3044 return 0; 3173 return 0;
3045} 3174}
3046 3175
@@ -3101,7 +3230,7 @@ static struct snd_soc_dai_driver rt5645_dai[] = {
3101 .capture = { 3230 .capture = {
3102 .stream_name = "AIF1 Capture", 3231 .stream_name = "AIF1 Capture",
3103 .channels_min = 1, 3232 .channels_min = 1,
3104 .channels_max = 2, 3233 .channels_max = 4,
3105 .rates = RT5645_STEREO_RATES, 3234 .rates = RT5645_STEREO_RATES,
3106 .formats = RT5645_FORMATS, 3235 .formats = RT5645_FORMATS,
3107 }, 3236 },
@@ -3205,9 +3334,49 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = {
3205 DMI_MATCH(DMI_PRODUCT_NAME, "Celes"), 3334 DMI_MATCH(DMI_PRODUCT_NAME, "Celes"),
3206 }, 3335 },
3207 }, 3336 },
3337 {
3338 .ident = "Google Ultima",
3339 .callback = strago_quirk_cb,
3340 .matches = {
3341 DMI_MATCH(DMI_PRODUCT_NAME, "Ultima"),
3342 },
3343 },
3344 {
3345 .ident = "Google Reks",
3346 .callback = strago_quirk_cb,
3347 .matches = {
3348 DMI_MATCH(DMI_PRODUCT_NAME, "Reks"),
3349 },
3350 },
3208 { } 3351 { }
3209}; 3352};
3210 3353
3354static struct rt5645_platform_data buddy_platform_data = {
3355 .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5,
3356 .dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
3357 .jd_mode = 3,
3358 .jd_invert = true,
3359};
3360
3361static int buddy_quirk_cb(const struct dmi_system_id *id)
3362{
3363 rt5645_pdata = &buddy_platform_data;
3364
3365 return 1;
3366}
3367
3368static struct dmi_system_id dmi_platform_intel_broadwell[] = {
3369 {
3370 .ident = "Chrome Buddy",
3371 .callback = buddy_quirk_cb,
3372 .matches = {
3373 DMI_MATCH(DMI_PRODUCT_NAME, "Buddy"),
3374 },
3375 },
3376 { }
3377};
3378
3379
3211static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev) 3380static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev)
3212{ 3381{
3213 rt5645->pdata.in2_diff = device_property_read_bool(dev, 3382 rt5645->pdata.in2_diff = device_property_read_bool(dev,
@@ -3240,7 +3409,8 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3240 3409
3241 if (pdata) 3410 if (pdata)
3242 rt5645->pdata = *pdata; 3411 rt5645->pdata = *pdata;
3243 else if (dmi_check_system(dmi_platform_intel_braswell)) 3412 else if (dmi_check_system(dmi_platform_intel_braswell) ||
3413 dmi_check_system(dmi_platform_intel_broadwell))
3244 rt5645->pdata = *rt5645_pdata; 3414 rt5645->pdata = *rt5645_pdata;
3245 else 3415 else
3246 rt5645_parse_dt(rt5645, &i2c->dev); 3416 rt5645_parse_dt(rt5645, &i2c->dev);
@@ -3468,6 +3638,8 @@ static void rt5645_i2c_shutdown(struct i2c_client *i2c)
3468 RT5645_CBJ_MN_JD); 3638 RT5645_CBJ_MN_JD);
3469 regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1, RT5645_CBJ_BST1_EN, 3639 regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1, RT5645_CBJ_BST1_EN,
3470 0); 3640 0);
3641 msleep(20);
3642 regmap_write(rt5645->regmap, RT5645_RESET, 0);
3471} 3643}
3472 3644
3473static struct i2c_driver rt5645_i2c_driver = { 3645static struct i2c_driver rt5645_i2c_driver = {
diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h
index 0e4cfc6ac649..093e46d559fb 100644
--- a/sound/soc/codecs/rt5645.h
+++ b/sound/soc/codecs/rt5645.h
@@ -39,8 +39,8 @@
39#define RT5645_STO1_ADC_DIG_VOL 0x1c 39#define RT5645_STO1_ADC_DIG_VOL 0x1c
40#define RT5645_MONO_ADC_DIG_VOL 0x1d 40#define RT5645_MONO_ADC_DIG_VOL 0x1d
41#define RT5645_ADC_BST_VOL1 0x1e 41#define RT5645_ADC_BST_VOL1 0x1e
42/* Mixer - D-D */
43#define RT5645_ADC_BST_VOL2 0x20 42#define RT5645_ADC_BST_VOL2 0x20
43/* Mixer - D-D */
44#define RT5645_STO1_ADC_MIXER 0x27 44#define RT5645_STO1_ADC_MIXER 0x27
45#define RT5645_MONO_ADC_MIXER 0x28 45#define RT5645_MONO_ADC_MIXER 0x28
46#define RT5645_AD_DA_MIXER 0x29 46#define RT5645_AD_DA_MIXER 0x29
@@ -315,12 +315,14 @@
315#define RT5645_STO1_ADC_R_BST_SFT 12 315#define RT5645_STO1_ADC_R_BST_SFT 12
316#define RT5645_STO1_ADC_COMP_MASK (0x3 << 10) 316#define RT5645_STO1_ADC_COMP_MASK (0x3 << 10)
317#define RT5645_STO1_ADC_COMP_SFT 10 317#define RT5645_STO1_ADC_COMP_SFT 10
318#define RT5645_STO2_ADC_L_BST_MASK (0x3 << 8) 318
319#define RT5645_STO2_ADC_L_BST_SFT 8 319/* ADC Boost Volume Control (0x20) */
320#define RT5645_STO2_ADC_R_BST_MASK (0x3 << 6) 320#define RT5645_MONO_ADC_L_BST_MASK (0x3 << 14)
321#define RT5645_STO2_ADC_R_BST_SFT 6 321#define RT5645_MONO_ADC_L_BST_SFT 14
322#define RT5645_STO2_ADC_COMP_MASK (0x3 << 4) 322#define RT5645_MONO_ADC_R_BST_MASK (0x3 << 12)
323#define RT5645_STO2_ADC_COMP_SFT 4 323#define RT5645_MONO_ADC_R_BST_SFT 12
324#define RT5645_MONO_ADC_COMP_MASK (0x3 << 10)
325#define RT5645_MONO_ADC_COMP_SFT 10
324 326
325/* Stereo2 ADC Mixer Control (0x26) */ 327/* Stereo2 ADC Mixer Control (0x26) */
326#define RT5645_STO2_ADC_SRC_MASK (0x1 << 15) 328#define RT5645_STO2_ADC_SRC_MASK (0x1 << 15)
@@ -619,14 +621,14 @@
619#define RT5645_G_OM_L_SM_L_SFT 6 621#define RT5645_G_OM_L_SM_L_SFT 6
620#define RT5645_M_BST1_L_SM_L (0x1 << 5) 622#define RT5645_M_BST1_L_SM_L (0x1 << 5)
621#define RT5645_M_BST1_L_SM_L_SFT 5 623#define RT5645_M_BST1_L_SM_L_SFT 5
624#define RT5645_M_BST3_L_SM_L (0x1 << 4)
625#define RT5645_M_BST3_L_SM_L_SFT 4
622#define RT5645_M_IN_L_SM_L (0x1 << 3) 626#define RT5645_M_IN_L_SM_L (0x1 << 3)
623#define RT5645_M_IN_L_SM_L_SFT 3 627#define RT5645_M_IN_L_SM_L_SFT 3
624#define RT5645_M_DAC_L1_SM_L (0x1 << 1)
625#define RT5645_M_DAC_L1_SM_L_SFT 1
626#define RT5645_M_DAC_L2_SM_L (0x1 << 2) 628#define RT5645_M_DAC_L2_SM_L (0x1 << 2)
627#define RT5645_M_DAC_L2_SM_L_SFT 2 629#define RT5645_M_DAC_L2_SM_L_SFT 2
628#define RT5645_M_BST3_L_SM_L (0x1 << 4) 630#define RT5645_M_DAC_L1_SM_L (0x1 << 1)
629#define RT5645_M_BST3_L_SM_L_SFT 4 631#define RT5645_M_DAC_L1_SM_L_SFT 1
630 632
631/* SPK Right Mixer Control (0x47) */ 633/* SPK Right Mixer Control (0x47) */
632#define RT5645_G_RM_R_SM_R_MASK (0x3 << 14) 634#define RT5645_G_RM_R_SM_R_MASK (0x3 << 14)
@@ -641,14 +643,14 @@
641#define RT5645_G_OM_R_SM_R_SFT 6 643#define RT5645_G_OM_R_SM_R_SFT 6
642#define RT5645_M_BST2_R_SM_R (0x1 << 5) 644#define RT5645_M_BST2_R_SM_R (0x1 << 5)
643#define RT5645_M_BST2_R_SM_R_SFT 5 645#define RT5645_M_BST2_R_SM_R_SFT 5
646#define RT5645_M_BST3_R_SM_R (0x1 << 4)
647#define RT5645_M_BST3_R_SM_R_SFT 4
644#define RT5645_M_IN_R_SM_R (0x1 << 3) 648#define RT5645_M_IN_R_SM_R (0x1 << 3)
645#define RT5645_M_IN_R_SM_R_SFT 3 649#define RT5645_M_IN_R_SM_R_SFT 3
646#define RT5645_M_DAC_R1_SM_R (0x1 << 1)
647#define RT5645_M_DAC_R1_SM_R_SFT 1
648#define RT5645_M_DAC_R2_SM_R (0x1 << 2) 650#define RT5645_M_DAC_R2_SM_R (0x1 << 2)
649#define RT5645_M_DAC_R2_SM_R_SFT 2 651#define RT5645_M_DAC_R2_SM_R_SFT 2
650#define RT5645_M_BST3_R_SM_R (0x1 << 4) 652#define RT5645_M_DAC_R1_SM_R (0x1 << 1)
651#define RT5645_M_BST3_R_SM_R_SFT 4 653#define RT5645_M_DAC_R1_SM_R_SFT 1
652 654
653/* SPOLMIX Control (0x48) */ 655/* SPOLMIX Control (0x48) */
654#define RT5645_M_DAC_L1_SPM_L (0x1 << 15) 656#define RT5645_M_DAC_L1_SPM_L (0x1 << 15)
@@ -668,13 +670,17 @@
668#define RT5645_M_SV_R_SPM_R (0x1 << 0) 670#define RT5645_M_SV_R_SPM_R (0x1 << 0)
669#define RT5645_M_SV_R_SPM_R_SFT 0 671#define RT5645_M_SV_R_SPM_R_SFT 0
670 672
673/* SPOMIX Ratio Control (0x4a) */
674#define RT5645_SPK_G_CLSD_MASK (0x7 << 0)
675#define RT5645_SPK_G_CLSD_SFT 0
676
671/* Mono Output Mixer Control (0x4c) */ 677/* Mono Output Mixer Control (0x4c) */
678#define RT5645_G_MONOMIX_MASK (0x1 << 10)
679#define RT5645_G_MONOMIX_SFT 10
672#define RT5645_M_OV_L_MM (0x1 << 9) 680#define RT5645_M_OV_L_MM (0x1 << 9)
673#define RT5645_M_OV_L_MM_SFT 9 681#define RT5645_M_OV_L_MM_SFT 9
674#define RT5645_M_DAC_L2_MA (0x1 << 8) 682#define RT5645_M_DAC_L2_MA (0x1 << 8)
675#define RT5645_M_DAC_L2_MA_SFT 8 683#define RT5645_M_DAC_L2_MA_SFT 8
676#define RT5645_G_MONOMIX_MASK (0x1 << 10)
677#define RT5645_G_MONOMIX_SFT 10
678#define RT5645_M_BST2_MM (0x1 << 4) 684#define RT5645_M_BST2_MM (0x1 << 4)
679#define RT5645_M_BST2_MM_SFT 4 685#define RT5645_M_BST2_MM_SFT 4
680#define RT5645_M_DAC_R1_MM (0x1 << 3) 686#define RT5645_M_DAC_R1_MM (0x1 << 3)
@@ -777,8 +783,6 @@
777#define RT5645_PWR_CLS_D_R_BIT 9 783#define RT5645_PWR_CLS_D_R_BIT 9
778#define RT5645_PWR_CLS_D_L (0x1 << 8) 784#define RT5645_PWR_CLS_D_L (0x1 << 8)
779#define RT5645_PWR_CLS_D_L_BIT 8 785#define RT5645_PWR_CLS_D_L_BIT 8
780#define RT5645_PWR_ADC_R (0x1 << 1)
781#define RT5645_PWR_ADC_R_BIT 1
782#define RT5645_PWR_DAC_L2 (0x1 << 7) 786#define RT5645_PWR_DAC_L2 (0x1 << 7)
783#define RT5645_PWR_DAC_L2_BIT 7 787#define RT5645_PWR_DAC_L2_BIT 7
784#define RT5645_PWR_DAC_R2 (0x1 << 6) 788#define RT5645_PWR_DAC_R2 (0x1 << 6)
@@ -1626,6 +1630,10 @@
1626#define RT5645_OT_P_NOR (0x0 << 10) 1630#define RT5645_OT_P_NOR (0x0 << 10)
1627#define RT5645_OT_P_INV (0x1 << 10) 1631#define RT5645_OT_P_INV (0x1 << 10)
1628#define RT5645_IRQ_JD_1_1_EN (0x1 << 9) 1632#define RT5645_IRQ_JD_1_1_EN (0x1 << 9)
1633#define RT5645_JD_1_1_MASK (0x1 << 7)
1634#define RT5645_JD_1_1_SFT 7
1635#define RT5645_JD_1_1_NOR (0x0 << 7)
1636#define RT5645_JD_1_1_INV (0x1 << 7)
1629 1637
1630/* IRQ Control 2 (0xbe) */ 1638/* IRQ Control 2 (0xbe) */
1631#define RT5645_IRQ_MB1_OC_MASK (0x1 << 15) 1639#define RT5645_IRQ_MB1_OC_MASK (0x1 << 15)
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index bfda25ef0dd4..f540f82b1f27 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -1376,8 +1376,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
1376 sgtl5000->micbias_resistor << SGTL5000_BIAS_R_SHIFT); 1376 sgtl5000->micbias_resistor << SGTL5000_BIAS_R_SHIFT);
1377 1377
1378 snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL, 1378 snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL,
1379 SGTL5000_BIAS_R_MASK, 1379 SGTL5000_BIAS_VOLT_MASK,
1380 sgtl5000->micbias_voltage << SGTL5000_BIAS_R_SHIFT); 1380 sgtl5000->micbias_voltage << SGTL5000_BIAS_VOLT_SHIFT);
1381 /* 1381 /*
1382 * disable DAP 1382 * disable DAP
1383 * TODO: 1383 * TODO:
@@ -1549,7 +1549,7 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
1549 else { 1549 else {
1550 sgtl5000->micbias_voltage = 0; 1550 sgtl5000->micbias_voltage = 0;
1551 dev_err(&client->dev, 1551 dev_err(&client->dev,
1552 "Unsuitable MicBias resistor\n"); 1552 "Unsuitable MicBias voltage\n");
1553 } 1553 }
1554 } else { 1554 } else {
1555 sgtl5000->micbias_voltage = 0; 1555 sgtl5000->micbias_voltage = 0;
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c
index ddb0203fc649..86b81a60ac52 100644
--- a/sound/soc/codecs/ssm2518.c
+++ b/sound/soc/codecs/ssm2518.c
@@ -723,17 +723,11 @@ static struct snd_soc_codec_driver ssm2518_codec_driver = {
723 .num_dapm_routes = ARRAY_SIZE(ssm2518_routes), 723 .num_dapm_routes = ARRAY_SIZE(ssm2518_routes),
724}; 724};
725 725
726static bool ssm2518_register_volatile(struct device *dev, unsigned int reg)
727{
728 return false;
729}
730
731static const struct regmap_config ssm2518_regmap_config = { 726static const struct regmap_config ssm2518_regmap_config = {
732 .val_bits = 8, 727 .val_bits = 8,
733 .reg_bits = 8, 728 .reg_bits = 8,
734 729
735 .max_register = SSM2518_REG_DRC_9, 730 .max_register = SSM2518_REG_DRC_9,
736 .volatile_reg = ssm2518_register_volatile,
737 731
738 .cache_type = REGCACHE_RBTREE, 732 .cache_type = REGCACHE_RBTREE,
739 .reg_defaults = ssm2518_reg_defaults, 733 .reg_defaults = ssm2518_reg_defaults,
diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c
index e3a0bca28bcf..cc1d3981fa4b 100644
--- a/sound/soc/codecs/tas2552.c
+++ b/sound/soc/codecs/tas2552.c
@@ -549,7 +549,7 @@ static struct snd_soc_dai_driver tas2552_dai[] = {
549/* 549/*
550 * DAC digital volumes. From -7 to 24 dB in 1 dB steps 550 * DAC digital volumes. From -7 to 24 dB in 1 dB steps
551 */ 551 */
552static DECLARE_TLV_DB_SCALE(dac_tlv, -7, 100, 0); 552static DECLARE_TLV_DB_SCALE(dac_tlv, -700, 100, 0);
553 553
554static const char * const tas2552_din_source_select[] = { 554static const char * const tas2552_din_source_select[] = {
555 "Muted", 555 "Muted",
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 1a82b19b2644..a564759845f9 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -80,6 +80,7 @@ struct aic3x_priv {
80 unsigned int sysclk; 80 unsigned int sysclk;
81 unsigned int dai_fmt; 81 unsigned int dai_fmt;
82 unsigned int tdm_delay; 82 unsigned int tdm_delay;
83 unsigned int slot_width;
83 struct list_head list; 84 struct list_head list;
84 int master; 85 int master;
85 int gpio_reset; 86 int gpio_reset;
@@ -1025,10 +1026,14 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
1025 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; 1026 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
1026 u16 d, pll_d = 1; 1027 u16 d, pll_d = 1;
1027 int clk; 1028 int clk;
1029 int width = aic3x->slot_width;
1030
1031 if (!width)
1032 width = params_width(params);
1028 1033
1029 /* select data word length */ 1034 /* select data word length */
1030 data = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4)); 1035 data = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
1031 switch (params_width(params)) { 1036 switch (width) {
1032 case 16: 1037 case 16:
1033 break; 1038 break;
1034 case 20: 1039 case 20:
@@ -1170,12 +1175,16 @@ static int aic3x_prepare(struct snd_pcm_substream *substream,
1170 struct snd_soc_codec *codec = dai->codec; 1175 struct snd_soc_codec *codec = dai->codec;
1171 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 1176 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1172 int delay = 0; 1177 int delay = 0;
1178 int width = aic3x->slot_width;
1179
1180 if (!width)
1181 width = substream->runtime->sample_bits;
1173 1182
1174 /* TDM slot selection only valid in DSP_A/_B mode */ 1183 /* TDM slot selection only valid in DSP_A/_B mode */
1175 if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_A) 1184 if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_A)
1176 delay += (aic3x->tdm_delay + 1); 1185 delay += (aic3x->tdm_delay*width + 1);
1177 else if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_B) 1186 else if (aic3x->dai_fmt == SND_SOC_DAIFMT_DSP_B)
1178 delay += aic3x->tdm_delay; 1187 delay += aic3x->tdm_delay*width;
1179 1188
1180 /* Configure data delay */ 1189 /* Configure data delay */
1181 snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay); 1190 snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay);
@@ -1296,7 +1305,20 @@ static int aic3x_set_dai_tdm_slot(struct snd_soc_dai *codec_dai,
1296 return -EINVAL; 1305 return -EINVAL;
1297 } 1306 }
1298 1307
1299 aic3x->tdm_delay = lsb * slot_width; 1308 switch (slot_width) {
1309 case 16:
1310 case 20:
1311 case 24:
1312 case 32:
1313 break;
1314 default:
1315 dev_err(codec->dev, "Unsupported slot width %d\n", slot_width);
1316 return -EINVAL;
1317 }
1318
1319
1320 aic3x->tdm_delay = lsb;
1321 aic3x->slot_width = slot_width;
1300 1322
1301 /* DOUT in high-impedance on inactive bit clocks */ 1323 /* DOUT in high-impedance on inactive bit clocks */
1302 snd_soc_update_bits(codec, AIC3X_ASD_INTF_CTRLA, 1324 snd_soc_update_bits(codec, AIC3X_ASD_INTF_CTRLA,
@@ -1509,14 +1531,17 @@ static int aic3x_init(struct snd_soc_codec *codec)
1509 snd_soc_write(codec, PGAL_2_LLOPM_VOL, DEFAULT_VOL); 1531 snd_soc_write(codec, PGAL_2_LLOPM_VOL, DEFAULT_VOL);
1510 snd_soc_write(codec, PGAR_2_RLOPM_VOL, DEFAULT_VOL); 1532 snd_soc_write(codec, PGAR_2_RLOPM_VOL, DEFAULT_VOL);
1511 1533
1512 /* Line2 to HP Bypass default volume, disconnect from Output Mixer */ 1534 /* On tlv320aic3104, these registers are reserved and must not be written */
1513 snd_soc_write(codec, LINE2L_2_HPLOUT_VOL, DEFAULT_VOL); 1535 if (aic3x->model != AIC3X_MODEL_3104) {
1514 snd_soc_write(codec, LINE2R_2_HPROUT_VOL, DEFAULT_VOL); 1536 /* Line2 to HP Bypass default volume, disconnect from Output Mixer */
1515 snd_soc_write(codec, LINE2L_2_HPLCOM_VOL, DEFAULT_VOL); 1537 snd_soc_write(codec, LINE2L_2_HPLOUT_VOL, DEFAULT_VOL);
1516 snd_soc_write(codec, LINE2R_2_HPRCOM_VOL, DEFAULT_VOL); 1538 snd_soc_write(codec, LINE2R_2_HPROUT_VOL, DEFAULT_VOL);
1517 /* Line2 Line Out default volume, disconnect from Output Mixer */ 1539 snd_soc_write(codec, LINE2L_2_HPLCOM_VOL, DEFAULT_VOL);
1518 snd_soc_write(codec, LINE2L_2_LLOPM_VOL, DEFAULT_VOL); 1540 snd_soc_write(codec, LINE2R_2_HPRCOM_VOL, DEFAULT_VOL);
1519 snd_soc_write(codec, LINE2R_2_RLOPM_VOL, DEFAULT_VOL); 1541 /* Line2 Line Out default volume, disconnect from Output Mixer */
1542 snd_soc_write(codec, LINE2L_2_LLOPM_VOL, DEFAULT_VOL);
1543 snd_soc_write(codec, LINE2R_2_RLOPM_VOL, DEFAULT_VOL);
1544 }
1520 1545
1521 switch (aic3x->model) { 1546 switch (aic3x->model) {
1522 case AIC3X_MODEL_3X: 1547 case AIC3X_MODEL_3X:
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c
index f2c6ad4b8fde..581ec1502228 100644
--- a/sound/soc/codecs/wm0010.c
+++ b/sound/soc/codecs/wm0010.c
@@ -577,7 +577,6 @@ static int wm0010_boot(struct snd_soc_codec *codec)
577 struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); 577 struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
578 unsigned long flags; 578 unsigned long flags;
579 int ret; 579 int ret;
580 const struct firmware *fw;
581 struct spi_message m; 580 struct spi_message m;
582 struct spi_transfer t; 581 struct spi_transfer t;
583 struct dfw_pllrec pll_rec; 582 struct dfw_pllrec pll_rec;
@@ -623,14 +622,6 @@ static int wm0010_boot(struct snd_soc_codec *codec)
623 wm0010->state = WM0010_OUT_OF_RESET; 622 wm0010->state = WM0010_OUT_OF_RESET;
624 spin_unlock_irqrestore(&wm0010->irq_lock, flags); 623 spin_unlock_irqrestore(&wm0010->irq_lock, flags);
625 624
626 /* First the bootloader */
627 ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev);
628 if (ret != 0) {
629 dev_err(codec->dev, "Failed to request stage2 loader: %d\n",
630 ret);
631 goto abort;
632 }
633
634 if (!wait_for_completion_timeout(&wm0010->boot_completion, 625 if (!wait_for_completion_timeout(&wm0010->boot_completion,
635 msecs_to_jiffies(20))) 626 msecs_to_jiffies(20)))
636 dev_err(codec->dev, "Failed to get interrupt from DSP\n"); 627 dev_err(codec->dev, "Failed to get interrupt from DSP\n");
@@ -673,7 +664,7 @@ static int wm0010_boot(struct snd_soc_codec *codec)
673 664
674 img_swap = kzalloc(len, GFP_KERNEL | GFP_DMA); 665 img_swap = kzalloc(len, GFP_KERNEL | GFP_DMA);
675 if (!img_swap) 666 if (!img_swap)
676 goto abort; 667 goto abort_out;
677 668
678 /* We need to re-order for 0010 */ 669 /* We need to re-order for 0010 */
679 byte_swap_64((u64 *)&pll_rec, img_swap, len); 670 byte_swap_64((u64 *)&pll_rec, img_swap, len);
@@ -688,16 +679,16 @@ static int wm0010_boot(struct snd_soc_codec *codec)
688 spi_message_add_tail(&t, &m); 679 spi_message_add_tail(&t, &m);
689 680
690 ret = spi_sync(spi, &m); 681 ret = spi_sync(spi, &m);
691 if (ret != 0) { 682 if (ret) {
692 dev_err(codec->dev, "First PLL write failed: %d\n", ret); 683 dev_err(codec->dev, "First PLL write failed: %d\n", ret);
693 goto abort; 684 goto abort_swap;
694 } 685 }
695 686
696 /* Use a second send of the message to get the return status */ 687 /* Use a second send of the message to get the return status */
697 ret = spi_sync(spi, &m); 688 ret = spi_sync(spi, &m);
698 if (ret != 0) { 689 if (ret) {
699 dev_err(codec->dev, "Second PLL write failed: %d\n", ret); 690 dev_err(codec->dev, "Second PLL write failed: %d\n", ret);
700 goto abort; 691 goto abort_swap;
701 } 692 }
702 693
703 p = (u32 *)out; 694 p = (u32 *)out;
@@ -730,6 +721,10 @@ static int wm0010_boot(struct snd_soc_codec *codec)
730 721
731 return 0; 722 return 0;
732 723
724abort_swap:
725 kfree(img_swap);
726abort_out:
727 kfree(out);
733abort: 728abort:
734 /* Put the chip back into reset */ 729 /* Put the chip back into reset */
735 wm0010_halt(codec); 730 wm0010_halt(codec);
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 786abd02b140..a67ea10f41a1 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -620,7 +620,7 @@ static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,
620{ 620{
621 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 621 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
622 struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); 622 struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
623 int anc_active = ucontrol->value.integer.value[0]; 623 unsigned int anc_active = ucontrol->value.integer.value[0];
624 int ret; 624 int ret;
625 625
626 if (anc_active > 1) 626 if (anc_active > 1)
@@ -653,7 +653,7 @@ static int wm2000_speaker_put(struct snd_kcontrol *kcontrol,
653{ 653{
654 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 654 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
655 struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); 655 struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
656 int val = ucontrol->value.integer.value[0]; 656 unsigned int val = ucontrol->value.integer.value[0];
657 int ret; 657 int ret;
658 658
659 if (val > 1) 659 if (val > 1)
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 9756578fc752..c04c0bc6f58a 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -38,6 +38,12 @@
38struct wm5110_priv { 38struct wm5110_priv {
39 struct arizona_priv core; 39 struct arizona_priv core;
40 struct arizona_fll fll[2]; 40 struct arizona_fll fll[2];
41
42 unsigned int in_value;
43 int in_pre_pending;
44 int in_post_pending;
45
46 unsigned int in_pga_cache[6];
41}; 47};
42 48
43static const struct wm_adsp_region wm5110_dsp1_regions[] = { 49static const struct wm_adsp_region wm5110_dsp1_regions[] = {
@@ -428,6 +434,127 @@ err:
428 return ret; 434 return ret;
429} 435}
430 436
437static int wm5110_in_pga_get(struct snd_kcontrol *kcontrol,
438 struct snd_ctl_elem_value *ucontrol)
439{
440 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
441 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
442 struct snd_soc_card *card = dapm->card;
443 int ret;
444
445 /*
446 * PGA Volume is also used as part of the enable sequence, so
447 * usage of it should be avoided whilst that is running.
448 */
449 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
450
451 ret = snd_soc_get_volsw_range(kcontrol, ucontrol);
452
453 mutex_unlock(&card->dapm_mutex);
454
455 return ret;
456}
457
458static int wm5110_in_pga_put(struct snd_kcontrol *kcontrol,
459 struct snd_ctl_elem_value *ucontrol)
460{
461 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
462 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
463 struct snd_soc_card *card = dapm->card;
464 int ret;
465
466 /*
467 * PGA Volume is also used as part of the enable sequence, so
468 * usage of it should be avoided whilst that is running.
469 */
470 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
471
472 ret = snd_soc_put_volsw_range(kcontrol, ucontrol);
473
474 mutex_unlock(&card->dapm_mutex);
475
476 return ret;
477}
478
479static int wm5110_in_analog_ev(struct snd_soc_dapm_widget *w,
480 struct snd_kcontrol *kcontrol, int event)
481{
482 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
483 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
484 struct wm5110_priv *wm5110 = snd_soc_codec_get_drvdata(codec);
485 struct arizona *arizona = priv->arizona;
486 unsigned int reg, mask;
487 struct reg_sequence analog_seq[] = {
488 { 0x80, 0x3 },
489 { 0x35d, 0 },
490 { 0x80, 0x0 },
491 };
492
493 reg = ARIZONA_IN1L_CONTROL + ((w->shift ^ 0x1) * 4);
494 mask = ARIZONA_IN1L_PGA_VOL_MASK;
495
496 switch (event) {
497 case SND_SOC_DAPM_WILL_PMU:
498 wm5110->in_value |= 0x3 << ((w->shift ^ 0x1) * 2);
499 wm5110->in_pre_pending++;
500 wm5110->in_post_pending++;
501 return 0;
502 case SND_SOC_DAPM_PRE_PMU:
503 wm5110->in_pga_cache[w->shift] = snd_soc_read(codec, reg);
504
505 snd_soc_update_bits(codec, reg, mask,
506 0x40 << ARIZONA_IN1L_PGA_VOL_SHIFT);
507
508 wm5110->in_pre_pending--;
509 if (wm5110->in_pre_pending == 0) {
510 analog_seq[1].def = wm5110->in_value;
511 regmap_multi_reg_write_bypassed(arizona->regmap,
512 analog_seq,
513 ARRAY_SIZE(analog_seq));
514
515 msleep(55);
516
517 wm5110->in_value = 0;
518 }
519
520 break;
521 case SND_SOC_DAPM_POST_PMU:
522 snd_soc_update_bits(codec, reg, mask,
523 wm5110->in_pga_cache[w->shift]);
524
525 wm5110->in_post_pending--;
526 if (wm5110->in_post_pending == 0)
527 regmap_multi_reg_write_bypassed(arizona->regmap,
528 analog_seq,
529 ARRAY_SIZE(analog_seq));
530 break;
531 default:
532 break;
533 }
534
535 return 0;
536}
537
538static int wm5110_in_ev(struct snd_soc_dapm_widget *w,
539 struct snd_kcontrol *kcontrol, int event)
540{
541 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
542 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
543 struct arizona *arizona = priv->arizona;
544
545 switch (arizona->rev) {
546 case 0 ... 4:
547 if (arizona_input_analog(codec, w->shift))
548 wm5110_in_analog_ev(w, kcontrol, event);
549
550 break;
551 default:
552 break;
553 }
554
555 return arizona_in_ev(w, kcontrol, event);
556}
557
431static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0); 558static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
432static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); 559static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
433static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); 560static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
@@ -454,18 +581,24 @@ SOC_ENUM("IN2 OSR", arizona_in_dmic_osr[1]),
454SOC_ENUM("IN3 OSR", arizona_in_dmic_osr[2]), 581SOC_ENUM("IN3 OSR", arizona_in_dmic_osr[2]),
455SOC_ENUM("IN4 OSR", arizona_in_dmic_osr[3]), 582SOC_ENUM("IN4 OSR", arizona_in_dmic_osr[3]),
456 583
457SOC_SINGLE_RANGE_TLV("IN1L Volume", ARIZONA_IN1L_CONTROL, 584SOC_SINGLE_RANGE_EXT_TLV("IN1L Volume", ARIZONA_IN1L_CONTROL,
458 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 585 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
459SOC_SINGLE_RANGE_TLV("IN1R Volume", ARIZONA_IN1R_CONTROL, 586 wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
460 ARIZONA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 587SOC_SINGLE_RANGE_EXT_TLV("IN1R Volume", ARIZONA_IN1R_CONTROL,
461SOC_SINGLE_RANGE_TLV("IN2L Volume", ARIZONA_IN2L_CONTROL, 588 ARIZONA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
462 ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 589 wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
463SOC_SINGLE_RANGE_TLV("IN2R Volume", ARIZONA_IN2R_CONTROL, 590SOC_SINGLE_RANGE_EXT_TLV("IN2L Volume", ARIZONA_IN2L_CONTROL,
464 ARIZONA_IN2R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 591 ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
465SOC_SINGLE_RANGE_TLV("IN3L Volume", ARIZONA_IN3L_CONTROL, 592 wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
466 ARIZONA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 593SOC_SINGLE_RANGE_EXT_TLV("IN2R Volume", ARIZONA_IN2R_CONTROL,
467SOC_SINGLE_RANGE_TLV("IN3R Volume", ARIZONA_IN3R_CONTROL, 594 ARIZONA_IN2R_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
468 ARIZONA_IN3R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv), 595 wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
596SOC_SINGLE_RANGE_EXT_TLV("IN3L Volume", ARIZONA_IN3L_CONTROL,
597 ARIZONA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
598 wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
599SOC_SINGLE_RANGE_EXT_TLV("IN3R Volume", ARIZONA_IN3R_CONTROL,
600 ARIZONA_IN3R_PGA_VOL_SHIFT, 0x40, 0x5f, 0,
601 wm5110_in_pga_get, wm5110_in_pga_put, ana_tlv),
469 602
470SOC_ENUM("IN HPF Cutoff Frequency", arizona_in_hpf_cut_enum), 603SOC_ENUM("IN HPF Cutoff Frequency", arizona_in_hpf_cut_enum),
471 604
@@ -896,29 +1029,35 @@ SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
896SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"), 1029SND_SOC_DAPM_OUTPUT("DRC2 Signal Activity"),
897 1030
898SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT, 1031SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
899 0, NULL, 0, arizona_in_ev, 1032 0, NULL, 0, wm5110_in_ev,
900 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 1033 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
901 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 1034 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1035 SND_SOC_DAPM_WILL_PMU),
902SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT, 1036SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
903 0, NULL, 0, arizona_in_ev, 1037 0, NULL, 0, wm5110_in_ev,
904 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 1038 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
905 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 1039 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1040 SND_SOC_DAPM_WILL_PMU),
906SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT, 1041SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
907 0, NULL, 0, arizona_in_ev, 1042 0, NULL, 0, wm5110_in_ev,
908 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 1043 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
909 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 1044 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1045 SND_SOC_DAPM_WILL_PMU),
910SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT, 1046SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
911 0, NULL, 0, arizona_in_ev, 1047 0, NULL, 0, wm5110_in_ev,
912 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 1048 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
913 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 1049 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1050 SND_SOC_DAPM_WILL_PMU),
914SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT, 1051SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT,
915 0, NULL, 0, arizona_in_ev, 1052 0, NULL, 0, wm5110_in_ev,
916 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 1053 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
917 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 1054 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1055 SND_SOC_DAPM_WILL_PMU),
918SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT, 1056SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
919 0, NULL, 0, arizona_in_ev, 1057 0, NULL, 0, wm5110_in_ev,
920 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 1058 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
921 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 1059 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1060 SND_SOC_DAPM_WILL_PMU),
922SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT, 1061SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT,
923 0, NULL, 0, arizona_in_ev, 1062 0, NULL, 0, arizona_in_ev,
924 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD | 1063 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index ace8645245a0..07cf1bd7913a 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -132,7 +132,7 @@ static int wm8731_put_deemph(struct snd_kcontrol *kcontrol,
132{ 132{
133 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 133 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
134 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 134 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
135 int deemph = ucontrol->value.integer.value[0]; 135 unsigned int deemph = ucontrol->value.integer.value[0];
136 int ret = 0; 136 int ret = 0;
137 137
138 if (deemph > 1) 138 if (deemph > 1)
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index b011253459af..e4cc41e6c23e 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -452,7 +452,7 @@ static int wm8903_put_deemph(struct snd_kcontrol *kcontrol,
452{ 452{
453 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 453 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
454 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 454 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
455 int deemph = ucontrol->value.integer.value[0]; 455 unsigned int deemph = ucontrol->value.integer.value[0];
456 int ret = 0; 456 int ret = 0;
457 457
458 if (deemph > 1) 458 if (deemph > 1)
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index b783743dc97e..2aa23f1b9e3c 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -534,7 +534,7 @@ static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
534{ 534{
535 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 535 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
536 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 536 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
537 int deemph = ucontrol->value.integer.value[0]; 537 unsigned int deemph = ucontrol->value.integer.value[0];
538 538
539 if (deemph > 1) 539 if (deemph > 1)
540 return -EINVAL; 540 return -EINVAL;
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 12e4435f00f8..9db00d53abe7 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -402,7 +402,7 @@ static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
402{ 402{
403 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 403 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
404 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); 404 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
405 int deemph = ucontrol->value.integer.value[0]; 405 unsigned int deemph = ucontrol->value.integer.value[0];
406 406
407 if (deemph > 1) 407 if (deemph > 1)
408 return -EINVAL; 408 return -EINVAL;
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index e3b7d0c57411..056375339ea3 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -201,7 +201,7 @@ static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
201{ 201{
202 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 202 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
203 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 203 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
204 int deemph = ucontrol->value.integer.value[0]; 204 unsigned int deemph = ucontrol->value.integer.value[0];
205 205
206 if (deemph > 1) 206 if (deemph > 1)
207 return -EINVAL; 207 return -EINVAL;
@@ -211,28 +211,38 @@ static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
211 return wm8960_set_deemph(codec); 211 return wm8960_set_deemph(codec);
212} 212}
213 213
214static const DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 50, 0); 214static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
215static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1); 215static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1725, 75, 0);
216static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
216static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0); 217static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0);
217static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); 218static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
218static const DECLARE_TLV_DB_SCALE(boost_tlv, -1200, 300, 1); 219static const DECLARE_TLV_DB_SCALE(lineinboost_tlv, -1500, 300, 1);
220static const unsigned int micboost_tlv[] = {
221 TLV_DB_RANGE_HEAD(2),
222 0, 1, TLV_DB_SCALE_ITEM(0, 1300, 0),
223 2, 3, TLV_DB_SCALE_ITEM(2000, 900, 0),
224};
219 225
220static const struct snd_kcontrol_new wm8960_snd_controls[] = { 226static const struct snd_kcontrol_new wm8960_snd_controls[] = {
221SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL, 227SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL,
222 0, 63, 0, adc_tlv), 228 0, 63, 0, inpga_tlv),
223SOC_DOUBLE_R("Capture Volume ZC Switch", WM8960_LINVOL, WM8960_RINVOL, 229SOC_DOUBLE_R("Capture Volume ZC Switch", WM8960_LINVOL, WM8960_RINVOL,
224 6, 1, 0), 230 6, 1, 0),
225SOC_DOUBLE_R("Capture Switch", WM8960_LINVOL, WM8960_RINVOL, 231SOC_DOUBLE_R("Capture Switch", WM8960_LINVOL, WM8960_RINVOL,
226 7, 1, 0), 232 7, 1, 0),
227 233
228SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT3 Volume", 234SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT3 Volume",
229 WM8960_INBMIX1, 4, 7, 0, boost_tlv), 235 WM8960_INBMIX1, 4, 7, 0, lineinboost_tlv),
230SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT2 Volume", 236SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT2 Volume",
231 WM8960_INBMIX1, 1, 7, 0, boost_tlv), 237 WM8960_INBMIX1, 1, 7, 0, lineinboost_tlv),
232SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT3 Volume", 238SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT3 Volume",
233 WM8960_INBMIX2, 4, 7, 0, boost_tlv), 239 WM8960_INBMIX2, 4, 7, 0, lineinboost_tlv),
234SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT2 Volume", 240SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT2 Volume",
235 WM8960_INBMIX2, 1, 7, 0, boost_tlv), 241 WM8960_INBMIX2, 1, 7, 0, lineinboost_tlv),
242SOC_SINGLE_TLV("Right Input Boost Mixer RINPUT1 Volume",
243 WM8960_RINPATH, 4, 3, 0, micboost_tlv),
244SOC_SINGLE_TLV("Left Input Boost Mixer LINPUT1 Volume",
245 WM8960_LINPATH, 4, 3, 0, micboost_tlv),
236 246
237SOC_DOUBLE_R_TLV("Playback Volume", WM8960_LDAC, WM8960_RDAC, 247SOC_DOUBLE_R_TLV("Playback Volume", WM8960_LDAC, WM8960_RDAC,
238 0, 255, 0, dac_tlv), 248 0, 255, 0, dac_tlv),
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index b4eb975da981..39ebd7bf4f53 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -2944,7 +2944,8 @@ static int wm8962_mute(struct snd_soc_dai *dai, int mute)
2944 WM8962_DAC_MUTE, val); 2944 WM8962_DAC_MUTE, val);
2945} 2945}
2946 2946
2947#define WM8962_RATES SNDRV_PCM_RATE_8000_96000 2947#define WM8962_RATES (SNDRV_PCM_RATE_8000_48000 |\
2948 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
2948 2949
2949#define WM8962_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 2950#define WM8962_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2950 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 2951 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
@@ -3759,7 +3760,7 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
3759 ret = snd_soc_register_codec(&i2c->dev, 3760 ret = snd_soc_register_codec(&i2c->dev,
3760 &soc_codec_dev_wm8962, &wm8962_dai, 1); 3761 &soc_codec_dev_wm8962, &wm8962_dai, 1);
3761 if (ret < 0) 3762 if (ret < 0)
3762 goto err_enable; 3763 goto err_pm_runtime;
3763 3764
3764 regcache_cache_only(wm8962->regmap, true); 3765 regcache_cache_only(wm8962->regmap, true);
3765 3766
@@ -3768,6 +3769,8 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
3768 3769
3769 return 0; 3770 return 0;
3770 3771
3772err_pm_runtime:
3773 pm_runtime_disable(&i2c->dev);
3771err_enable: 3774err_enable:
3772 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); 3775 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
3773err: 3776err:
@@ -3777,6 +3780,7 @@ err:
3777static int wm8962_i2c_remove(struct i2c_client *client) 3780static int wm8962_i2c_remove(struct i2c_client *client)
3778{ 3781{
3779 snd_soc_unregister_codec(&client->dev); 3782 snd_soc_unregister_codec(&client->dev);
3783 pm_runtime_disable(&client->dev);
3780 return 0; 3784 return 0;
3781} 3785}
3782 3786
@@ -3804,6 +3808,8 @@ static int wm8962_runtime_resume(struct device *dev)
3804 3808
3805 wm8962_reset(wm8962); 3809 wm8962_reset(wm8962);
3806 3810
3811 regcache_mark_dirty(wm8962->regmap);
3812
3807 /* SYSCLK defaults to on; make sure it is off so we can safely 3813 /* SYSCLK defaults to on; make sure it is off so we can safely
3808 * write to registers if the device is declocked. 3814 * write to registers if the device is declocked.
3809 */ 3815 */
diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c
new file mode 100644
index 000000000000..8782dfb628ab
--- /dev/null
+++ b/sound/soc/codecs/wm8998.c
@@ -0,0 +1,1430 @@
1/*
2 * wm8998.c -- ALSA SoC Audio driver for WM8998 codecs
3 *
4 * Copyright 2015 Cirrus Logic, Inc.
5 *
6 * Author: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/pm_runtime.h>
19#include <linux/regmap.h>
20#include <linux/slab.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/jack.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28
29#include <linux/mfd/arizona/core.h>
30#include <linux/mfd/arizona/registers.h>
31
32#include "arizona.h"
33#include "wm8998.h"
34
35struct wm8998_priv {
36 struct arizona_priv core;
37 struct arizona_fll fll[2];
38};
39
40static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w,
41 struct snd_kcontrol *kcontrol,
42 int event)
43{
44 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
45 unsigned int val;
46
47 switch (event) {
48 case SND_SOC_DAPM_PRE_PMU:
49 val = snd_soc_read(codec, ARIZONA_ASRC_RATE1);
50 val &= ARIZONA_ASRC_RATE1_MASK;
51 val >>= ARIZONA_ASRC_RATE1_SHIFT;
52
53 switch (val) {
54 case 0:
55 case 1:
56 case 2:
57 val = snd_soc_read(codec,
58 ARIZONA_SAMPLE_RATE_1 + val);
59 if (val >= 0x11) {
60 dev_warn(codec->dev,
61 "Unsupported ASRC rate1 (%s)\n",
62 arizona_sample_rate_val_to_name(val));
63 return -EINVAL;
64 }
65 break;
66 default:
67 dev_err(codec->dev,
68 "Illegal ASRC rate1 selector (0x%x)\n",
69 val);
70 return -EINVAL;
71 }
72
73 val = snd_soc_read(codec, ARIZONA_ASRC_RATE2);
74 val &= ARIZONA_ASRC_RATE2_MASK;
75 val >>= ARIZONA_ASRC_RATE2_SHIFT;
76
77 switch (val) {
78 case 8:
79 case 9:
80 val -= 0x8;
81 val = snd_soc_read(codec,
82 ARIZONA_ASYNC_SAMPLE_RATE_1 + val);
83 if (val >= 0x11) {
84 dev_warn(codec->dev,
85 "Unsupported ASRC rate2 (%s)\n",
86 arizona_sample_rate_val_to_name(val));
87 return -EINVAL;
88 }
89 break;
90 default:
91 dev_err(codec->dev,
92 "Illegal ASRC rate2 selector (0x%x)\n",
93 val);
94 return -EINVAL;
95 }
96 break;
97 default:
98 return -EINVAL;
99 }
100
101 return 0;
102}
103
104static int wm8998_in1mux_put(struct snd_kcontrol *kcontrol,
105 struct snd_ctl_elem_value *ucontrol)
106{
107 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
108 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
109 struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
110 struct arizona *arizona = wm8998->core.arizona;
111 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
112 unsigned int mux, inmode;
113 unsigned int mode_val, src_val;
114
115 mux = ucontrol->value.enumerated.item[0];
116 if (mux > 1)
117 return -EINVAL;
118
119 /* L and R registers have same shift and mask */
120 inmode = arizona->pdata.inmode[2 * mux];
121 src_val = mux << ARIZONA_IN1L_SRC_SHIFT;
122 if (inmode & ARIZONA_INMODE_SE)
123 src_val |= 1 << ARIZONA_IN1L_SRC_SE_SHIFT;
124
125 switch (arizona->pdata.inmode[0]) {
126 case ARIZONA_INMODE_DMIC:
127 if (mux)
128 mode_val = 0; /* B always analogue */
129 else
130 mode_val = 1 << ARIZONA_IN1_MODE_SHIFT;
131
132 snd_soc_update_bits(codec, ARIZONA_IN1L_CONTROL,
133 ARIZONA_IN1_MODE_MASK, mode_val);
134
135 /* IN1A is digital so L and R must change together */
136 /* src_val setting same for both registers */
137 snd_soc_update_bits(codec,
138 ARIZONA_ADC_DIGITAL_VOLUME_1L,
139 ARIZONA_IN1L_SRC_MASK |
140 ARIZONA_IN1L_SRC_SE_MASK, src_val);
141 snd_soc_update_bits(codec,
142 ARIZONA_ADC_DIGITAL_VOLUME_1R,
143 ARIZONA_IN1R_SRC_MASK |
144 ARIZONA_IN1R_SRC_SE_MASK, src_val);
145 break;
146 default:
147 /* both analogue */
148 snd_soc_update_bits(codec,
149 e->reg,
150 ARIZONA_IN1L_SRC_MASK |
151 ARIZONA_IN1L_SRC_SE_MASK,
152 src_val);
153 break;
154 }
155
156 return snd_soc_dapm_mux_update_power(dapm, kcontrol,
157 ucontrol->value.enumerated.item[0],
158 e, NULL);
159}
160
161static int wm8998_in2mux_put(struct snd_kcontrol *kcontrol,
162 struct snd_ctl_elem_value *ucontrol)
163{
164 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
165 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
166 struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
167 struct arizona *arizona = wm8998->core.arizona;
168 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
169 unsigned int mux, inmode, src_val, mode_val;
170
171 mux = ucontrol->value.enumerated.item[0];
172 if (mux > 1)
173 return -EINVAL;
174
175 inmode = arizona->pdata.inmode[1 + (2 * mux)];
176 if (inmode & ARIZONA_INMODE_DMIC)
177 mode_val = 1 << ARIZONA_IN2_MODE_SHIFT;
178 else
179 mode_val = 0;
180
181 src_val = mux << ARIZONA_IN2L_SRC_SHIFT;
182 if (inmode & ARIZONA_INMODE_SE)
183 src_val |= 1 << ARIZONA_IN2L_SRC_SE_SHIFT;
184
185 snd_soc_update_bits(codec, ARIZONA_IN2L_CONTROL,
186 ARIZONA_IN2_MODE_MASK, mode_val);
187
188 snd_soc_update_bits(codec, ARIZONA_ADC_DIGITAL_VOLUME_2L,
189 ARIZONA_IN2L_SRC_MASK | ARIZONA_IN2L_SRC_SE_MASK,
190 src_val);
191
192 return snd_soc_dapm_mux_update_power(dapm, kcontrol,
193 ucontrol->value.enumerated.item[0],
194 e, NULL);
195}
196
197static const char * const wm8998_inmux_texts[] = {
198 "A",
199 "B",
200};
201
202static const SOC_ENUM_SINGLE_DECL(wm8998_in1muxl_enum,
203 ARIZONA_ADC_DIGITAL_VOLUME_1L,
204 ARIZONA_IN1L_SRC_SHIFT,
205 wm8998_inmux_texts);
206
207static const SOC_ENUM_SINGLE_DECL(wm8998_in1muxr_enum,
208 ARIZONA_ADC_DIGITAL_VOLUME_1R,
209 ARIZONA_IN1R_SRC_SHIFT,
210 wm8998_inmux_texts);
211
212static const SOC_ENUM_SINGLE_DECL(wm8998_in2mux_enum,
213 ARIZONA_ADC_DIGITAL_VOLUME_2L,
214 ARIZONA_IN2L_SRC_SHIFT,
215 wm8998_inmux_texts);
216
217static const struct snd_kcontrol_new wm8998_in1mux[2] = {
218 SOC_DAPM_ENUM_EXT("IN1L Mux", wm8998_in1muxl_enum,
219 snd_soc_dapm_get_enum_double, wm8998_in1mux_put),
220 SOC_DAPM_ENUM_EXT("IN1R Mux", wm8998_in1muxr_enum,
221 snd_soc_dapm_get_enum_double, wm8998_in1mux_put),
222};
223
224static const struct snd_kcontrol_new wm8998_in2mux =
225 SOC_DAPM_ENUM_EXT("IN2 Mux", wm8998_in2mux_enum,
226 snd_soc_dapm_get_enum_double, wm8998_in2mux_put);
227
228static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
229static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
230static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
231static DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
232
233#define WM8998_NG_SRC(name, base) \
234 SOC_SINGLE(name " NG HPOUTL Switch", base, 0, 1, 0), \
235 SOC_SINGLE(name " NG HPOUTR Switch", base, 1, 1, 0), \
236 SOC_SINGLE(name " NG LINEOUTL Switch", base, 2, 1, 0), \
237 SOC_SINGLE(name " NG LINEOUTR Switch", base, 3, 1, 0), \
238 SOC_SINGLE(name " NG EPOUT Switch", base, 4, 1, 0), \
239 SOC_SINGLE(name " NG SPKOUTL Switch", base, 6, 1, 0), \
240 SOC_SINGLE(name " NG SPKOUTR Switch", base, 7, 1, 0)
241
242static const struct snd_kcontrol_new wm8998_snd_controls[] = {
243SOC_ENUM("IN1 OSR", arizona_in_dmic_osr[0]),
244SOC_ENUM("IN2 OSR", arizona_in_dmic_osr[1]),
245
246SOC_SINGLE_RANGE_TLV("IN1L Volume", ARIZONA_IN1L_CONTROL,
247 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
248SOC_SINGLE_RANGE_TLV("IN1R Volume", ARIZONA_IN1R_CONTROL,
249 ARIZONA_IN1R_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
250SOC_SINGLE_RANGE_TLV("IN2 Volume", ARIZONA_IN2L_CONTROL,
251 ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
252
253SOC_ENUM("IN HPF Cutoff Frequency", arizona_in_hpf_cut_enum),
254
255SOC_SINGLE("IN1L HPF Switch", ARIZONA_IN1L_CONTROL,
256 ARIZONA_IN1L_HPF_SHIFT, 1, 0),
257SOC_SINGLE("IN1R HPF Switch", ARIZONA_IN1R_CONTROL,
258 ARIZONA_IN1R_HPF_SHIFT, 1, 0),
259SOC_SINGLE("IN2 HPF Switch", ARIZONA_IN2L_CONTROL,
260 ARIZONA_IN2L_HPF_SHIFT, 1, 0),
261
262SOC_SINGLE_TLV("IN1L Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L,
263 ARIZONA_IN1L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
264SOC_SINGLE_TLV("IN1R Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1R,
265 ARIZONA_IN1R_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
266SOC_SINGLE_TLV("IN2 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2L,
267 ARIZONA_IN2L_DIG_VOL_SHIFT, 0xbf, 0, digital_tlv),
268
269SOC_ENUM("Input Ramp Up", arizona_in_vi_ramp),
270SOC_ENUM("Input Ramp Down", arizona_in_vd_ramp),
271
272ARIZONA_GAINMUX_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE),
273ARIZONA_GAINMUX_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
274ARIZONA_GAINMUX_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
275ARIZONA_GAINMUX_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
276
277SND_SOC_BYTES("EQ1 Coefficients", ARIZONA_EQ1_3, 19),
278SOC_SINGLE("EQ1 Mode Switch", ARIZONA_EQ1_2, ARIZONA_EQ1_B1_MODE_SHIFT, 1, 0),
279SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
280 24, 0, eq_tlv),
281SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
282 24, 0, eq_tlv),
283SOC_SINGLE_TLV("EQ1 B3 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B3_GAIN_SHIFT,
284 24, 0, eq_tlv),
285SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT,
286 24, 0, eq_tlv),
287SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT,
288 24, 0, eq_tlv),
289
290SND_SOC_BYTES("EQ2 Coefficients", ARIZONA_EQ2_3, 19),
291SOC_SINGLE("EQ2 Mode Switch", ARIZONA_EQ2_2, ARIZONA_EQ2_B1_MODE_SHIFT, 1, 0),
292SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT,
293 24, 0, eq_tlv),
294SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT,
295 24, 0, eq_tlv),
296SOC_SINGLE_TLV("EQ2 B3 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B3_GAIN_SHIFT,
297 24, 0, eq_tlv),
298SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT,
299 24, 0, eq_tlv),
300SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT,
301 24, 0, eq_tlv),
302
303SND_SOC_BYTES("EQ3 Coefficients", ARIZONA_EQ3_3, 19),
304SOC_SINGLE("EQ3 Mode Switch", ARIZONA_EQ3_2, ARIZONA_EQ3_B1_MODE_SHIFT, 1, 0),
305SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT,
306 24, 0, eq_tlv),
307SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT,
308 24, 0, eq_tlv),
309SOC_SINGLE_TLV("EQ3 B3 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B3_GAIN_SHIFT,
310 24, 0, eq_tlv),
311SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT,
312 24, 0, eq_tlv),
313SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT,
314 24, 0, eq_tlv),
315
316SND_SOC_BYTES("EQ4 Coefficients", ARIZONA_EQ4_3, 19),
317SOC_SINGLE("EQ4 Mode Switch", ARIZONA_EQ4_2, ARIZONA_EQ4_B1_MODE_SHIFT, 1, 0),
318SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT,
319 24, 0, eq_tlv),
320SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT,
321 24, 0, eq_tlv),
322SOC_SINGLE_TLV("EQ4 B3 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B3_GAIN_SHIFT,
323 24, 0, eq_tlv),
324SOC_SINGLE_TLV("EQ4 B4 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B4_GAIN_SHIFT,
325 24, 0, eq_tlv),
326SOC_SINGLE_TLV("EQ4 B5 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B5_GAIN_SHIFT,
327 24, 0, eq_tlv),
328
329ARIZONA_GAINMUX_CONTROLS("DRC1L", ARIZONA_DRC1LMIX_INPUT_1_SOURCE),
330ARIZONA_GAINMUX_CONTROLS("DRC1R", ARIZONA_DRC1RMIX_INPUT_1_SOURCE),
331
332SND_SOC_BYTES_MASK("DRC1", ARIZONA_DRC1_CTRL1, 5,
333 ARIZONA_DRC1R_ENA | ARIZONA_DRC1L_ENA),
334
335ARIZONA_MIXER_CONTROLS("LHPF1", ARIZONA_HPLP1MIX_INPUT_1_SOURCE),
336ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE),
337ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE),
338ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE),
339
340SND_SOC_BYTES("LHPF1 Coefficients", ARIZONA_HPLPF1_2, 1),
341SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1),
342SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1),
343SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1),
344
345SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode),
346SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
347SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
348SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
349
350SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]),
351SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]),
352SOC_ENUM("ISRC1 FSH", arizona_isrc_fsh[0]),
353SOC_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]),
354SOC_ENUM("ASRC RATE 1", arizona_asrc_rate1),
355
356ARIZONA_MIXER_CONTROLS("HPOUTL", ARIZONA_OUT1LMIX_INPUT_1_SOURCE),
357ARIZONA_MIXER_CONTROLS("HPOUTR", ARIZONA_OUT1RMIX_INPUT_1_SOURCE),
358ARIZONA_MIXER_CONTROLS("LINEOUTL", ARIZONA_OUT2LMIX_INPUT_1_SOURCE),
359ARIZONA_MIXER_CONTROLS("LINEOUTR", ARIZONA_OUT2RMIX_INPUT_1_SOURCE),
360ARIZONA_MIXER_CONTROLS("EPOUT", ARIZONA_OUT3LMIX_INPUT_1_SOURCE),
361ARIZONA_MIXER_CONTROLS("SPKOUTL", ARIZONA_OUT4LMIX_INPUT_1_SOURCE),
362ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE),
363ARIZONA_MIXER_CONTROLS("SPKDATL", ARIZONA_OUT5LMIX_INPUT_1_SOURCE),
364ARIZONA_MIXER_CONTROLS("SPKDATR", ARIZONA_OUT5RMIX_INPUT_1_SOURCE),
365
366SOC_DOUBLE_R("HPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
367 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
368SOC_DOUBLE_R("LINEOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
369 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1),
370SOC_SINGLE("EPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
371 ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
372SOC_DOUBLE_R("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
373 ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
374SOC_DOUBLE_R("SPKDAT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L,
375 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_MUTE_SHIFT, 1, 1),
376
377SOC_DOUBLE_R_TLV("HPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
378 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_VOL_SHIFT,
379 0xbf, 0, digital_tlv),
380SOC_DOUBLE_R_TLV("LINEOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
381 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT,
382 0xbf, 0, digital_tlv),
383SOC_SINGLE_TLV("EPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
384 ARIZONA_OUT3L_VOL_SHIFT, 0xbf, 0, digital_tlv),
385SOC_DOUBLE_R_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
386 ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_VOL_SHIFT,
387 0xbf, 0, digital_tlv),
388SOC_DOUBLE_R_TLV("SPKDAT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L,
389 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT,
390 0xbf, 0, digital_tlv),
391
392SOC_DOUBLE("SPKDAT Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
393 ARIZONA_SPK1R_MUTE_SHIFT, 1, 1),
394
395SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp),
396SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp),
397
398SOC_SINGLE("Noise Gate Switch", ARIZONA_NOISE_GATE_CONTROL,
399 ARIZONA_NGATE_ENA_SHIFT, 1, 0),
400SOC_SINGLE_TLV("Noise Gate Threshold Volume", ARIZONA_NOISE_GATE_CONTROL,
401 ARIZONA_NGATE_THR_SHIFT, 7, 1, ng_tlv),
402SOC_ENUM("Noise Gate Hold", arizona_ng_hold),
403
404WM8998_NG_SRC("HPOUTL", ARIZONA_NOISE_GATE_SELECT_1L),
405WM8998_NG_SRC("HPOUTR", ARIZONA_NOISE_GATE_SELECT_1R),
406WM8998_NG_SRC("LINEOUTL", ARIZONA_NOISE_GATE_SELECT_2L),
407WM8998_NG_SRC("LINEOUTR", ARIZONA_NOISE_GATE_SELECT_2R),
408WM8998_NG_SRC("EPOUT", ARIZONA_NOISE_GATE_SELECT_3L),
409WM8998_NG_SRC("SPKOUTL", ARIZONA_NOISE_GATE_SELECT_4L),
410WM8998_NG_SRC("SPKOUTR", ARIZONA_NOISE_GATE_SELECT_4R),
411WM8998_NG_SRC("SPKDATL", ARIZONA_NOISE_GATE_SELECT_5L),
412WM8998_NG_SRC("SPKDATR", ARIZONA_NOISE_GATE_SELECT_5R),
413
414ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE),
415ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE),
416ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE),
417ARIZONA_MIXER_CONTROLS("AIF1TX4", ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE),
418ARIZONA_MIXER_CONTROLS("AIF1TX5", ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE),
419ARIZONA_MIXER_CONTROLS("AIF1TX6", ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE),
420
421ARIZONA_MIXER_CONTROLS("AIF2TX1", ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE),
422ARIZONA_MIXER_CONTROLS("AIF2TX2", ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE),
423ARIZONA_MIXER_CONTROLS("AIF2TX3", ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE),
424ARIZONA_MIXER_CONTROLS("AIF2TX4", ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE),
425ARIZONA_MIXER_CONTROLS("AIF2TX5", ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE),
426ARIZONA_MIXER_CONTROLS("AIF2TX6", ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE),
427
428ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
429ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
430
431ARIZONA_GAINMUX_CONTROLS("SLIMTX1", ARIZONA_SLIMTX1MIX_INPUT_1_SOURCE),
432ARIZONA_GAINMUX_CONTROLS("SLIMTX2", ARIZONA_SLIMTX2MIX_INPUT_1_SOURCE),
433ARIZONA_GAINMUX_CONTROLS("SLIMTX3", ARIZONA_SLIMTX3MIX_INPUT_1_SOURCE),
434ARIZONA_GAINMUX_CONTROLS("SLIMTX4", ARIZONA_SLIMTX4MIX_INPUT_1_SOURCE),
435ARIZONA_GAINMUX_CONTROLS("SLIMTX5", ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE),
436ARIZONA_GAINMUX_CONTROLS("SLIMTX6", ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE),
437
438ARIZONA_GAINMUX_CONTROLS("SPDIFTX1", ARIZONA_SPDIFTX1MIX_INPUT_1_SOURCE),
439ARIZONA_GAINMUX_CONTROLS("SPDIFTX2", ARIZONA_SPDIFTX2MIX_INPUT_1_SOURCE),
440};
441
442ARIZONA_MUX_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
443ARIZONA_MUX_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE);
444ARIZONA_MUX_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE);
445ARIZONA_MUX_ENUMS(EQ4, ARIZONA_EQ4MIX_INPUT_1_SOURCE);
446
447ARIZONA_MUX_ENUMS(DRC1L, ARIZONA_DRC1LMIX_INPUT_1_SOURCE);
448ARIZONA_MUX_ENUMS(DRC1R, ARIZONA_DRC1RMIX_INPUT_1_SOURCE);
449
450ARIZONA_MIXER_ENUMS(LHPF1, ARIZONA_HPLP1MIX_INPUT_1_SOURCE);
451ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE);
452ARIZONA_MIXER_ENUMS(LHPF3, ARIZONA_HPLP3MIX_INPUT_1_SOURCE);
453ARIZONA_MIXER_ENUMS(LHPF4, ARIZONA_HPLP4MIX_INPUT_1_SOURCE);
454
455ARIZONA_MIXER_ENUMS(PWM1, ARIZONA_PWM1MIX_INPUT_1_SOURCE);
456ARIZONA_MIXER_ENUMS(PWM2, ARIZONA_PWM2MIX_INPUT_1_SOURCE);
457
458ARIZONA_MIXER_ENUMS(OUT1L, ARIZONA_OUT1LMIX_INPUT_1_SOURCE);
459ARIZONA_MIXER_ENUMS(OUT1R, ARIZONA_OUT1RMIX_INPUT_1_SOURCE);
460ARIZONA_MIXER_ENUMS(OUT2L, ARIZONA_OUT2LMIX_INPUT_1_SOURCE);
461ARIZONA_MIXER_ENUMS(OUT2R, ARIZONA_OUT2RMIX_INPUT_1_SOURCE);
462ARIZONA_MIXER_ENUMS(OUT3, ARIZONA_OUT3LMIX_INPUT_1_SOURCE);
463ARIZONA_MIXER_ENUMS(SPKOUTL, ARIZONA_OUT4LMIX_INPUT_1_SOURCE);
464ARIZONA_MIXER_ENUMS(SPKOUTR, ARIZONA_OUT4RMIX_INPUT_1_SOURCE);
465ARIZONA_MIXER_ENUMS(SPKDATL, ARIZONA_OUT5LMIX_INPUT_1_SOURCE);
466ARIZONA_MIXER_ENUMS(SPKDATR, ARIZONA_OUT5RMIX_INPUT_1_SOURCE);
467
468ARIZONA_MIXER_ENUMS(AIF1TX1, ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE);
469ARIZONA_MIXER_ENUMS(AIF1TX2, ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE);
470ARIZONA_MIXER_ENUMS(AIF1TX3, ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE);
471ARIZONA_MIXER_ENUMS(AIF1TX4, ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE);
472ARIZONA_MIXER_ENUMS(AIF1TX5, ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE);
473ARIZONA_MIXER_ENUMS(AIF1TX6, ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE);
474
475ARIZONA_MIXER_ENUMS(AIF2TX1, ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE);
476ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
477ARIZONA_MIXER_ENUMS(AIF2TX3, ARIZONA_AIF2TX3MIX_INPUT_1_SOURCE);
478ARIZONA_MIXER_ENUMS(AIF2TX4, ARIZONA_AIF2TX4MIX_INPUT_1_SOURCE);
479ARIZONA_MIXER_ENUMS(AIF2TX5, ARIZONA_AIF2TX5MIX_INPUT_1_SOURCE);
480ARIZONA_MIXER_ENUMS(AIF2TX6, ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE);
481
482ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
483ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
484
485ARIZONA_MUX_ENUMS(SLIMTX1, ARIZONA_SLIMTX1MIX_INPUT_1_SOURCE);
486ARIZONA_MUX_ENUMS(SLIMTX2, ARIZONA_SLIMTX2MIX_INPUT_1_SOURCE);
487ARIZONA_MUX_ENUMS(SLIMTX3, ARIZONA_SLIMTX3MIX_INPUT_1_SOURCE);
488ARIZONA_MUX_ENUMS(SLIMTX4, ARIZONA_SLIMTX4MIX_INPUT_1_SOURCE);
489ARIZONA_MUX_ENUMS(SLIMTX5, ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE);
490ARIZONA_MUX_ENUMS(SLIMTX6, ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE);
491
492ARIZONA_MUX_ENUMS(SPD1TX1, ARIZONA_SPDIFTX1MIX_INPUT_1_SOURCE);
493ARIZONA_MUX_ENUMS(SPD1TX2, ARIZONA_SPDIFTX2MIX_INPUT_1_SOURCE);
494
495ARIZONA_MUX_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
496ARIZONA_MUX_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
497ARIZONA_MUX_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
498ARIZONA_MUX_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
499
500ARIZONA_MUX_ENUMS(ISRC1INT1, ARIZONA_ISRC1INT1MIX_INPUT_1_SOURCE);
501ARIZONA_MUX_ENUMS(ISRC1INT2, ARIZONA_ISRC1INT2MIX_INPUT_1_SOURCE);
502ARIZONA_MUX_ENUMS(ISRC1INT3, ARIZONA_ISRC1INT3MIX_INPUT_1_SOURCE);
503ARIZONA_MUX_ENUMS(ISRC1INT4, ARIZONA_ISRC1INT4MIX_INPUT_1_SOURCE);
504
505ARIZONA_MUX_ENUMS(ISRC1DEC1, ARIZONA_ISRC1DEC1MIX_INPUT_1_SOURCE);
506ARIZONA_MUX_ENUMS(ISRC1DEC2, ARIZONA_ISRC1DEC2MIX_INPUT_1_SOURCE);
507ARIZONA_MUX_ENUMS(ISRC1DEC3, ARIZONA_ISRC1DEC3MIX_INPUT_1_SOURCE);
508ARIZONA_MUX_ENUMS(ISRC1DEC4, ARIZONA_ISRC1DEC4MIX_INPUT_1_SOURCE);
509
510ARIZONA_MUX_ENUMS(ISRC2INT1, ARIZONA_ISRC2INT1MIX_INPUT_1_SOURCE);
511ARIZONA_MUX_ENUMS(ISRC2INT2, ARIZONA_ISRC2INT2MIX_INPUT_1_SOURCE);
512
513ARIZONA_MUX_ENUMS(ISRC2DEC1, ARIZONA_ISRC2DEC1MIX_INPUT_1_SOURCE);
514ARIZONA_MUX_ENUMS(ISRC2DEC2, ARIZONA_ISRC2DEC2MIX_INPUT_1_SOURCE);
515
516static const char * const wm8998_aec_loopback_texts[] = {
517 "HPOUTL", "HPOUTR", "LINEOUTL", "LINEOUTR", "EPOUT",
518 "SPKOUTL", "SPKOUTR", "SPKDATL", "SPKDATR",
519};
520
521static const unsigned int wm8998_aec_loopback_values[] = {
522 0, 1, 2, 3, 4, 6, 7, 8, 9,
523};
524
525static const SOC_VALUE_ENUM_SINGLE_DECL(wm8998_aec1_loopback,
526 ARIZONA_DAC_AEC_CONTROL_1,
527 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf,
528 wm8998_aec_loopback_texts,
529 wm8998_aec_loopback_values);
530
531static const SOC_VALUE_ENUM_SINGLE_DECL(wm8998_aec2_loopback,
532 ARIZONA_DAC_AEC_CONTROL_2,
533 ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf,
534 wm8998_aec_loopback_texts,
535 wm8998_aec_loopback_values);
536
537static const struct snd_kcontrol_new wm8998_aec_loopback_mux[] = {
538 SOC_DAPM_ENUM("AEC1 Loopback", wm8998_aec1_loopback),
539 SOC_DAPM_ENUM("AEC2 Loopback", wm8998_aec2_loopback),
540};
541
542static const struct snd_soc_dapm_widget wm8998_dapm_widgets[] = {
543SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1,
544 ARIZONA_SYSCLK_ENA_SHIFT, 0, NULL, 0),
545SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
546 ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
547SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK,
548 ARIZONA_OPCLK_ENA_SHIFT, 0, NULL, 0),
549SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK,
550 ARIZONA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0),
551
552SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0),
553SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0),
554SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
555SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS),
556SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0, 0),
557SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0),
558
559SND_SOC_DAPM_SIGGEN("TONE"),
560SND_SOC_DAPM_SIGGEN("HAPTICS"),
561
562SND_SOC_DAPM_INPUT("IN1AL"),
563SND_SOC_DAPM_INPUT("IN1AR"),
564SND_SOC_DAPM_INPUT("IN1BL"),
565SND_SOC_DAPM_INPUT("IN1BR"),
566SND_SOC_DAPM_INPUT("IN2A"),
567SND_SOC_DAPM_INPUT("IN2B"),
568
569SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &wm8998_in1mux[0]),
570SND_SOC_DAPM_MUX("IN1R Mux", SND_SOC_NOPM, 0, 0, &wm8998_in1mux[1]),
571SND_SOC_DAPM_MUX("IN2 Mux", SND_SOC_NOPM, 0, 0, &wm8998_in2mux),
572
573SND_SOC_DAPM_OUTPUT("DRC1 Signal Activity"),
574
575SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
576 0, NULL, 0, arizona_in_ev,
577 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
578 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
579SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
580 0, NULL, 0, arizona_in_ev,
581 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
582 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
583SND_SOC_DAPM_PGA_E("IN2 PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
584 0, NULL, 0, arizona_in_ev,
585 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
586 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
587
588SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
589 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
590SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2,
591 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
592SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3,
593 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
594
595SND_SOC_DAPM_PGA("Tone Generator 1", ARIZONA_TONE_GENERATOR_1,
596 ARIZONA_TONE1_ENA_SHIFT, 0, NULL, 0),
597SND_SOC_DAPM_PGA("Tone Generator 2", ARIZONA_TONE_GENERATOR_1,
598 ARIZONA_TONE2_ENA_SHIFT, 0, NULL, 0),
599
600SND_SOC_DAPM_PGA("EQ1", ARIZONA_EQ1_1, ARIZONA_EQ1_ENA_SHIFT, 0, NULL, 0),
601SND_SOC_DAPM_PGA("EQ2", ARIZONA_EQ2_1, ARIZONA_EQ2_ENA_SHIFT, 0, NULL, 0),
602SND_SOC_DAPM_PGA("EQ3", ARIZONA_EQ3_1, ARIZONA_EQ3_ENA_SHIFT, 0, NULL, 0),
603SND_SOC_DAPM_PGA("EQ4", ARIZONA_EQ4_1, ARIZONA_EQ4_ENA_SHIFT, 0, NULL, 0),
604
605SND_SOC_DAPM_PGA("DRC1L", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1L_ENA_SHIFT, 0,
606 NULL, 0),
607SND_SOC_DAPM_PGA("DRC1R", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1R_ENA_SHIFT, 0,
608 NULL, 0),
609
610SND_SOC_DAPM_PGA("LHPF1", ARIZONA_HPLPF1_1, ARIZONA_LHPF1_ENA_SHIFT, 0,
611 NULL, 0),
612SND_SOC_DAPM_PGA("LHPF2", ARIZONA_HPLPF2_1, ARIZONA_LHPF2_ENA_SHIFT, 0,
613 NULL, 0),
614SND_SOC_DAPM_PGA("LHPF3", ARIZONA_HPLPF3_1, ARIZONA_LHPF3_ENA_SHIFT, 0,
615 NULL, 0),
616SND_SOC_DAPM_PGA("LHPF4", ARIZONA_HPLPF4_1, ARIZONA_LHPF4_ENA_SHIFT, 0,
617 NULL, 0),
618
619SND_SOC_DAPM_PGA("PWM1 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM1_ENA_SHIFT,
620 0, NULL, 0),
621SND_SOC_DAPM_PGA("PWM2 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM2_ENA_SHIFT,
622 0, NULL, 0),
623
624SND_SOC_DAPM_PGA_E("ASRC1L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC1L_ENA_SHIFT, 0,
625 NULL, 0, wm8998_asrc_ev, SND_SOC_DAPM_PRE_PMU),
626SND_SOC_DAPM_PGA_E("ASRC1R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC1R_ENA_SHIFT, 0,
627 NULL, 0, wm8998_asrc_ev, SND_SOC_DAPM_PRE_PMU),
628SND_SOC_DAPM_PGA_E("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0,
629 NULL, 0, wm8998_asrc_ev, SND_SOC_DAPM_PRE_PMU),
630SND_SOC_DAPM_PGA_E("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
631 NULL, 0, wm8998_asrc_ev, SND_SOC_DAPM_PRE_PMU),
632
633SND_SOC_DAPM_PGA("ISRC1INT1", ARIZONA_ISRC_1_CTRL_3,
634 ARIZONA_ISRC1_INT0_ENA_SHIFT, 0, NULL, 0),
635SND_SOC_DAPM_PGA("ISRC1INT2", ARIZONA_ISRC_1_CTRL_3,
636 ARIZONA_ISRC1_INT1_ENA_SHIFT, 0, NULL, 0),
637SND_SOC_DAPM_PGA("ISRC1INT3", ARIZONA_ISRC_1_CTRL_3,
638 ARIZONA_ISRC1_INT2_ENA_SHIFT, 0, NULL, 0),
639SND_SOC_DAPM_PGA("ISRC1INT4", ARIZONA_ISRC_1_CTRL_3,
640 ARIZONA_ISRC1_INT3_ENA_SHIFT, 0, NULL, 0),
641
642SND_SOC_DAPM_PGA("ISRC1DEC1", ARIZONA_ISRC_1_CTRL_3,
643 ARIZONA_ISRC1_DEC0_ENA_SHIFT, 0, NULL, 0),
644SND_SOC_DAPM_PGA("ISRC1DEC2", ARIZONA_ISRC_1_CTRL_3,
645 ARIZONA_ISRC1_DEC1_ENA_SHIFT, 0, NULL, 0),
646SND_SOC_DAPM_PGA("ISRC1DEC3", ARIZONA_ISRC_1_CTRL_3,
647 ARIZONA_ISRC1_DEC2_ENA_SHIFT, 0, NULL, 0),
648SND_SOC_DAPM_PGA("ISRC1DEC4", ARIZONA_ISRC_1_CTRL_3,
649 ARIZONA_ISRC1_DEC3_ENA_SHIFT, 0, NULL, 0),
650
651SND_SOC_DAPM_PGA("ISRC2INT1", ARIZONA_ISRC_2_CTRL_3,
652 ARIZONA_ISRC2_INT0_ENA_SHIFT, 0, NULL, 0),
653SND_SOC_DAPM_PGA("ISRC2INT2", ARIZONA_ISRC_2_CTRL_3,
654 ARIZONA_ISRC2_INT1_ENA_SHIFT, 0, NULL, 0),
655
656SND_SOC_DAPM_PGA("ISRC2DEC1", ARIZONA_ISRC_2_CTRL_3,
657 ARIZONA_ISRC2_DEC0_ENA_SHIFT, 0, NULL, 0),
658SND_SOC_DAPM_PGA("ISRC2DEC2", ARIZONA_ISRC_2_CTRL_3,
659 ARIZONA_ISRC2_DEC1_ENA_SHIFT, 0, NULL, 0),
660
661SND_SOC_DAPM_MUX("AEC1 Loopback", ARIZONA_DAC_AEC_CONTROL_1,
662 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
663 &wm8998_aec_loopback_mux[0]),
664
665SND_SOC_DAPM_MUX("AEC2 Loopback", ARIZONA_DAC_AEC_CONTROL_2,
666 ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0,
667 &wm8998_aec_loopback_mux[1]),
668
669SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
670 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
671SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
672 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX2_ENA_SHIFT, 0),
673SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0,
674 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX3_ENA_SHIFT, 0),
675SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0,
676 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX4_ENA_SHIFT, 0),
677SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0,
678 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX5_ENA_SHIFT, 0),
679SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0,
680 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX6_ENA_SHIFT, 0),
681
682SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0,
683 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX1_ENA_SHIFT, 0),
684SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0,
685 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX2_ENA_SHIFT, 0),
686SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0,
687 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX3_ENA_SHIFT, 0),
688SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0,
689 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX4_ENA_SHIFT, 0),
690SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0,
691 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX5_ENA_SHIFT, 0),
692SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0,
693 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX6_ENA_SHIFT, 0),
694
695SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
696 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX1_ENA_SHIFT, 0),
697SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
698 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX2_ENA_SHIFT, 0),
699SND_SOC_DAPM_AIF_OUT("AIF2TX3", NULL, 0,
700 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX3_ENA_SHIFT, 0),
701SND_SOC_DAPM_AIF_OUT("AIF2TX4", NULL, 0,
702 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX4_ENA_SHIFT, 0),
703SND_SOC_DAPM_AIF_OUT("AIF2TX5", NULL, 0,
704 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX5_ENA_SHIFT, 0),
705SND_SOC_DAPM_AIF_OUT("AIF2TX6", NULL, 0,
706 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX6_ENA_SHIFT, 0),
707
708SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
709 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX1_ENA_SHIFT, 0),
710SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
711 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX2_ENA_SHIFT, 0),
712SND_SOC_DAPM_AIF_IN("AIF2RX3", NULL, 0,
713 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX3_ENA_SHIFT, 0),
714SND_SOC_DAPM_AIF_IN("AIF2RX4", NULL, 0,
715 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX4_ENA_SHIFT, 0),
716SND_SOC_DAPM_AIF_IN("AIF2RX5", NULL, 0,
717 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX5_ENA_SHIFT, 0),
718SND_SOC_DAPM_AIF_IN("AIF2RX6", NULL, 0,
719 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX6_ENA_SHIFT, 0),
720
721SND_SOC_DAPM_AIF_IN("SLIMRX1", NULL, 0,
722 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
723 ARIZONA_SLIMRX1_ENA_SHIFT, 0),
724SND_SOC_DAPM_AIF_IN("SLIMRX2", NULL, 0,
725 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
726 ARIZONA_SLIMRX2_ENA_SHIFT, 0),
727SND_SOC_DAPM_AIF_IN("SLIMRX3", NULL, 0,
728 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
729 ARIZONA_SLIMRX3_ENA_SHIFT, 0),
730SND_SOC_DAPM_AIF_IN("SLIMRX4", NULL, 0,
731 ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE,
732 ARIZONA_SLIMRX4_ENA_SHIFT, 0),
733
734SND_SOC_DAPM_AIF_OUT("SLIMTX1", NULL, 0,
735 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
736 ARIZONA_SLIMTX1_ENA_SHIFT, 0),
737SND_SOC_DAPM_AIF_OUT("SLIMTX2", NULL, 0,
738 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
739 ARIZONA_SLIMTX2_ENA_SHIFT, 0),
740SND_SOC_DAPM_AIF_OUT("SLIMTX3", NULL, 0,
741 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
742 ARIZONA_SLIMTX3_ENA_SHIFT, 0),
743SND_SOC_DAPM_AIF_OUT("SLIMTX4", NULL, 0,
744 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
745 ARIZONA_SLIMTX4_ENA_SHIFT, 0),
746SND_SOC_DAPM_AIF_OUT("SLIMTX5", NULL, 0,
747 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
748 ARIZONA_SLIMTX5_ENA_SHIFT, 0),
749SND_SOC_DAPM_AIF_OUT("SLIMTX6", NULL, 0,
750 ARIZONA_SLIMBUS_TX_CHANNEL_ENABLE,
751 ARIZONA_SLIMTX6_ENA_SHIFT, 0),
752
753SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
754 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX1_ENA_SHIFT, 0),
755SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
756 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX2_ENA_SHIFT, 0),
757
758SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
759 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX1_ENA_SHIFT, 0),
760SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
761 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
762
763SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
764 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
765 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
766SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
767 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
768 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
769SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1,
770 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
771 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
772SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1,
773 ARIZONA_OUT2R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
774 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
775SND_SOC_DAPM_PGA_E("OUT3", ARIZONA_OUTPUT_ENABLES_1,
776 ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
777 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
778SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
779 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
780 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
781SND_SOC_DAPM_PGA_E("OUT5R", ARIZONA_OUTPUT_ENABLES_1,
782 ARIZONA_OUT5R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
783 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
784
785SND_SOC_DAPM_PGA("SPD1TX1", ARIZONA_SPD1_TX_CONTROL,
786 ARIZONA_SPD1_VAL1_SHIFT, 0, NULL, 0),
787SND_SOC_DAPM_PGA("SPD1TX2", ARIZONA_SPD1_TX_CONTROL,
788 ARIZONA_SPD1_VAL2_SHIFT, 0, NULL, 0),
789SND_SOC_DAPM_OUT_DRV("SPD1", ARIZONA_SPD1_TX_CONTROL,
790 ARIZONA_SPD1_ENA_SHIFT, 0, NULL, 0),
791
792ARIZONA_MUX_WIDGETS(EQ1, "EQ1"),
793ARIZONA_MUX_WIDGETS(EQ2, "EQ2"),
794ARIZONA_MUX_WIDGETS(EQ3, "EQ3"),
795ARIZONA_MUX_WIDGETS(EQ4, "EQ4"),
796
797ARIZONA_MUX_WIDGETS(DRC1L, "DRC1L"),
798ARIZONA_MUX_WIDGETS(DRC1R, "DRC1R"),
799
800ARIZONA_MIXER_WIDGETS(LHPF1, "LHPF1"),
801ARIZONA_MIXER_WIDGETS(LHPF2, "LHPF2"),
802ARIZONA_MIXER_WIDGETS(LHPF3, "LHPF3"),
803ARIZONA_MIXER_WIDGETS(LHPF4, "LHPF4"),
804
805ARIZONA_MIXER_WIDGETS(PWM1, "PWM1"),
806ARIZONA_MIXER_WIDGETS(PWM2, "PWM2"),
807
808ARIZONA_MIXER_WIDGETS(OUT1L, "HPOUTL"),
809ARIZONA_MIXER_WIDGETS(OUT1R, "HPOUTR"),
810ARIZONA_MIXER_WIDGETS(OUT2L, "LINEOUTL"),
811ARIZONA_MIXER_WIDGETS(OUT2R, "LINEOUTR"),
812ARIZONA_MIXER_WIDGETS(OUT3, "EPOUT"),
813ARIZONA_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"),
814ARIZONA_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"),
815ARIZONA_MIXER_WIDGETS(SPKDATL, "SPKDATL"),
816ARIZONA_MIXER_WIDGETS(SPKDATR, "SPKDATR"),
817
818ARIZONA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
819ARIZONA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
820ARIZONA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
821ARIZONA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
822ARIZONA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
823ARIZONA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
824
825ARIZONA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
826ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
827ARIZONA_MIXER_WIDGETS(AIF2TX3, "AIF2TX3"),
828ARIZONA_MIXER_WIDGETS(AIF2TX4, "AIF2TX4"),
829ARIZONA_MIXER_WIDGETS(AIF2TX5, "AIF2TX5"),
830ARIZONA_MIXER_WIDGETS(AIF2TX6, "AIF2TX6"),
831
832ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
833ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
834
835ARIZONA_MUX_WIDGETS(SLIMTX1, "SLIMTX1"),
836ARIZONA_MUX_WIDGETS(SLIMTX2, "SLIMTX2"),
837ARIZONA_MUX_WIDGETS(SLIMTX3, "SLIMTX3"),
838ARIZONA_MUX_WIDGETS(SLIMTX4, "SLIMTX4"),
839ARIZONA_MUX_WIDGETS(SLIMTX5, "SLIMTX5"),
840ARIZONA_MUX_WIDGETS(SLIMTX6, "SLIMTX6"),
841
842ARIZONA_MUX_WIDGETS(SPD1TX1, "SPDIFTX1"),
843ARIZONA_MUX_WIDGETS(SPD1TX2, "SPDIFTX2"),
844
845ARIZONA_MUX_WIDGETS(ASRC1L, "ASRC1L"),
846ARIZONA_MUX_WIDGETS(ASRC1R, "ASRC1R"),
847ARIZONA_MUX_WIDGETS(ASRC2L, "ASRC2L"),
848ARIZONA_MUX_WIDGETS(ASRC2R, "ASRC2R"),
849
850ARIZONA_MUX_WIDGETS(ISRC1DEC1, "ISRC1DEC1"),
851ARIZONA_MUX_WIDGETS(ISRC1DEC2, "ISRC1DEC2"),
852ARIZONA_MUX_WIDGETS(ISRC1DEC3, "ISRC1DEC3"),
853ARIZONA_MUX_WIDGETS(ISRC1DEC4, "ISRC1DEC4"),
854
855ARIZONA_MUX_WIDGETS(ISRC1INT1, "ISRC1INT1"),
856ARIZONA_MUX_WIDGETS(ISRC1INT2, "ISRC1INT2"),
857ARIZONA_MUX_WIDGETS(ISRC1INT3, "ISRC1INT3"),
858ARIZONA_MUX_WIDGETS(ISRC1INT4, "ISRC1INT4"),
859
860ARIZONA_MUX_WIDGETS(ISRC2DEC1, "ISRC2DEC1"),
861ARIZONA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"),
862
863ARIZONA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
864ARIZONA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
865
866SND_SOC_DAPM_OUTPUT("HPOUTL"),
867SND_SOC_DAPM_OUTPUT("HPOUTR"),
868SND_SOC_DAPM_OUTPUT("LINEOUTL"),
869SND_SOC_DAPM_OUTPUT("LINEOUTR"),
870SND_SOC_DAPM_OUTPUT("EPOUT"),
871SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
872SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
873SND_SOC_DAPM_OUTPUT("SPKOUTRN"),
874SND_SOC_DAPM_OUTPUT("SPKOUTRP"),
875SND_SOC_DAPM_OUTPUT("SPKDATL"),
876SND_SOC_DAPM_OUTPUT("SPKDATR"),
877SND_SOC_DAPM_OUTPUT("SPDIF"),
878
879SND_SOC_DAPM_OUTPUT("MICSUPP"),
880};
881
882#define ARIZONA_MIXER_INPUT_ROUTES(name) \
883 { name, "Tone Generator 1", "Tone Generator 1" }, \
884 { name, "Tone Generator 2", "Tone Generator 2" }, \
885 { name, "Haptics", "HAPTICS" }, \
886 { name, "AEC", "AEC1 Loopback" }, \
887 { name, "AEC2", "AEC2 Loopback" }, \
888 { name, "IN1L", "IN1L PGA" }, \
889 { name, "IN1R", "IN1R PGA" }, \
890 { name, "IN2L", "IN2 PGA" }, \
891 { name, "AIF1RX1", "AIF1RX1" }, \
892 { name, "AIF1RX2", "AIF1RX2" }, \
893 { name, "AIF1RX3", "AIF1RX3" }, \
894 { name, "AIF1RX4", "AIF1RX4" }, \
895 { name, "AIF1RX5", "AIF1RX5" }, \
896 { name, "AIF1RX6", "AIF1RX6" }, \
897 { name, "AIF2RX1", "AIF2RX1" }, \
898 { name, "AIF2RX2", "AIF2RX2" }, \
899 { name, "AIF2RX3", "AIF2RX3" }, \
900 { name, "AIF2RX4", "AIF2RX4" }, \
901 { name, "AIF2RX5", "AIF2RX5" }, \
902 { name, "AIF2RX6", "AIF2RX6" }, \
903 { name, "AIF3RX1", "AIF3RX1" }, \
904 { name, "AIF3RX2", "AIF3RX2" }, \
905 { name, "SLIMRX1", "SLIMRX1" }, \
906 { name, "SLIMRX2", "SLIMRX2" }, \
907 { name, "SLIMRX3", "SLIMRX3" }, \
908 { name, "SLIMRX4", "SLIMRX4" }, \
909 { name, "EQ1", "EQ1" }, \
910 { name, "EQ2", "EQ2" }, \
911 { name, "EQ3", "EQ3" }, \
912 { name, "EQ4", "EQ4" }, \
913 { name, "DRC1L", "DRC1L" }, \
914 { name, "DRC1R", "DRC1R" }, \
915 { name, "LHPF1", "LHPF1" }, \
916 { name, "LHPF2", "LHPF2" }, \
917 { name, "LHPF3", "LHPF3" }, \
918 { name, "LHPF4", "LHPF4" }, \
919 { name, "ASRC1L", "ASRC1L" }, \
920 { name, "ASRC1R", "ASRC1R" }, \
921 { name, "ASRC2L", "ASRC2L" }, \
922 { name, "ASRC2R", "ASRC2R" }, \
923 { name, "ISRC1DEC1", "ISRC1DEC1" }, \
924 { name, "ISRC1DEC2", "ISRC1DEC2" }, \
925 { name, "ISRC1DEC3", "ISRC1DEC3" }, \
926 { name, "ISRC1DEC4", "ISRC1DEC4" }, \
927 { name, "ISRC1INT1", "ISRC1INT1" }, \
928 { name, "ISRC1INT2", "ISRC1INT2" }, \
929 { name, "ISRC1INT3", "ISRC1INT3" }, \
930 { name, "ISRC1INT4", "ISRC1INT4" }, \
931 { name, "ISRC2DEC1", "ISRC2DEC1" }, \
932 { name, "ISRC2DEC2", "ISRC2DEC2" }, \
933 { name, "ISRC2INT1", "ISRC2INT1" }, \
934 { name, "ISRC2INT2", "ISRC2INT2" }
935
936static const struct snd_soc_dapm_route wm8998_dapm_routes[] = {
937 { "AIF2 Capture", NULL, "DBVDD2" },
938 { "AIF2 Playback", NULL, "DBVDD2" },
939
940 { "AIF3 Capture", NULL, "DBVDD3" },
941 { "AIF3 Playback", NULL, "DBVDD3" },
942
943 { "OUT1L", NULL, "CPVDD" },
944 { "OUT1R", NULL, "CPVDD" },
945 { "OUT2L", NULL, "CPVDD" },
946 { "OUT2R", NULL, "CPVDD" },
947 { "OUT3", NULL, "CPVDD" },
948
949 { "OUT4L", NULL, "SPKVDDL" },
950 { "OUT4R", NULL, "SPKVDDR" },
951
952 { "OUT1L", NULL, "SYSCLK" },
953 { "OUT1R", NULL, "SYSCLK" },
954 { "OUT2L", NULL, "SYSCLK" },
955 { "OUT2R", NULL, "SYSCLK" },
956 { "OUT3", NULL, "SYSCLK" },
957 { "OUT4L", NULL, "SYSCLK" },
958 { "OUT4R", NULL, "SYSCLK" },
959 { "OUT5L", NULL, "SYSCLK" },
960 { "OUT5R", NULL, "SYSCLK" },
961
962 { "IN1AL", NULL, "SYSCLK" },
963 { "IN1AR", NULL, "SYSCLK" },
964 { "IN1BL", NULL, "SYSCLK" },
965 { "IN1BR", NULL, "SYSCLK" },
966 { "IN2A", NULL, "SYSCLK" },
967 { "IN2B", NULL, "SYSCLK" },
968
969 { "SPD1", NULL, "SYSCLK" },
970 { "SPD1", NULL, "SPD1TX1" },
971 { "SPD1", NULL, "SPD1TX2" },
972
973 { "MICBIAS1", NULL, "MICVDD" },
974 { "MICBIAS2", NULL, "MICVDD" },
975 { "MICBIAS3", NULL, "MICVDD" },
976
977 { "Tone Generator 1", NULL, "SYSCLK" },
978 { "Tone Generator 2", NULL, "SYSCLK" },
979
980 { "Tone Generator 1", NULL, "TONE" },
981 { "Tone Generator 2", NULL, "TONE" },
982
983 { "AIF1 Capture", NULL, "AIF1TX1" },
984 { "AIF1 Capture", NULL, "AIF1TX2" },
985 { "AIF1 Capture", NULL, "AIF1TX3" },
986 { "AIF1 Capture", NULL, "AIF1TX4" },
987 { "AIF1 Capture", NULL, "AIF1TX5" },
988 { "AIF1 Capture", NULL, "AIF1TX6" },
989
990 { "AIF1RX1", NULL, "AIF1 Playback" },
991 { "AIF1RX2", NULL, "AIF1 Playback" },
992 { "AIF1RX3", NULL, "AIF1 Playback" },
993 { "AIF1RX4", NULL, "AIF1 Playback" },
994 { "AIF1RX5", NULL, "AIF1 Playback" },
995 { "AIF1RX6", NULL, "AIF1 Playback" },
996
997 { "AIF2 Capture", NULL, "AIF2TX1" },
998 { "AIF2 Capture", NULL, "AIF2TX2" },
999 { "AIF2 Capture", NULL, "AIF2TX3" },
1000 { "AIF2 Capture", NULL, "AIF2TX4" },
1001 { "AIF2 Capture", NULL, "AIF2TX5" },
1002 { "AIF2 Capture", NULL, "AIF2TX6" },
1003
1004 { "AIF2RX1", NULL, "AIF2 Playback" },
1005 { "AIF2RX2", NULL, "AIF2 Playback" },
1006 { "AIF2RX3", NULL, "AIF2 Playback" },
1007 { "AIF2RX4", NULL, "AIF2 Playback" },
1008 { "AIF2RX5", NULL, "AIF2 Playback" },
1009 { "AIF2RX6", NULL, "AIF2 Playback" },
1010
1011 { "AIF3 Capture", NULL, "AIF3TX1" },
1012 { "AIF3 Capture", NULL, "AIF3TX2" },
1013
1014 { "AIF3RX1", NULL, "AIF3 Playback" },
1015 { "AIF3RX2", NULL, "AIF3 Playback" },
1016
1017 { "Slim1 Capture", NULL, "SLIMTX1" },
1018 { "Slim1 Capture", NULL, "SLIMTX2" },
1019 { "Slim1 Capture", NULL, "SLIMTX3" },
1020 { "Slim1 Capture", NULL, "SLIMTX4" },
1021
1022 { "Slim2 Capture", NULL, "SLIMTX5" },
1023 { "Slim2 Capture", NULL, "SLIMTX6" },
1024
1025 { "SLIMRX1", NULL, "Slim1 Playback" },
1026 { "SLIMRX2", NULL, "Slim1 Playback" },
1027
1028 { "SLIMRX3", NULL, "Slim2 Playback" },
1029 { "SLIMRX4", NULL, "Slim2 Playback" },
1030
1031 { "AIF1 Playback", NULL, "SYSCLK" },
1032 { "AIF2 Playback", NULL, "SYSCLK" },
1033 { "AIF3 Playback", NULL, "SYSCLK" },
1034 { "Slim1 Playback", NULL, "SYSCLK" },
1035 { "Slim2 Playback", NULL, "SYSCLK" },
1036
1037 { "AIF1 Capture", NULL, "SYSCLK" },
1038 { "AIF2 Capture", NULL, "SYSCLK" },
1039 { "AIF3 Capture", NULL, "SYSCLK" },
1040 { "Slim1 Capture", NULL, "SYSCLK" },
1041 { "Slim2 Capture", NULL, "SYSCLK" },
1042
1043 { "IN1L Mux", "A", "IN1AL" },
1044 { "IN1R Mux", "A", "IN1AR" },
1045 { "IN1L Mux", "B", "IN1BL" },
1046 { "IN1R Mux", "B", "IN1BR" },
1047
1048 { "IN2 Mux", "A", "IN2A" },
1049 { "IN2 Mux", "B", "IN2B" },
1050
1051 { "IN1L PGA", NULL, "IN1L Mux" },
1052 { "IN1R PGA", NULL, "IN1R Mux" },
1053 { "IN2 PGA", NULL, "IN2 Mux" },
1054
1055 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUTL"),
1056 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUTR"),
1057 ARIZONA_MIXER_ROUTES("OUT2L", "LINEOUTL"),
1058 ARIZONA_MIXER_ROUTES("OUT2R", "LINEOUTR"),
1059 ARIZONA_MIXER_ROUTES("OUT3", "EPOUT"),
1060
1061 ARIZONA_MIXER_ROUTES("OUT4L", "SPKOUTL"),
1062 ARIZONA_MIXER_ROUTES("OUT4R", "SPKOUTR"),
1063 ARIZONA_MIXER_ROUTES("OUT5L", "SPKDATL"),
1064 ARIZONA_MIXER_ROUTES("OUT5R", "SPKDATR"),
1065
1066 ARIZONA_MIXER_ROUTES("PWM1 Driver", "PWM1"),
1067 ARIZONA_MIXER_ROUTES("PWM2 Driver", "PWM2"),
1068
1069 ARIZONA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
1070 ARIZONA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
1071 ARIZONA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
1072 ARIZONA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
1073 ARIZONA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
1074 ARIZONA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
1075
1076 ARIZONA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
1077 ARIZONA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
1078 ARIZONA_MIXER_ROUTES("AIF2TX3", "AIF2TX3"),
1079 ARIZONA_MIXER_ROUTES("AIF2TX4", "AIF2TX4"),
1080 ARIZONA_MIXER_ROUTES("AIF2TX5", "AIF2TX5"),
1081 ARIZONA_MIXER_ROUTES("AIF2TX6", "AIF2TX6"),
1082
1083 ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
1084 ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
1085
1086 ARIZONA_MUX_ROUTES("SLIMTX1", "SLIMTX1"),
1087 ARIZONA_MUX_ROUTES("SLIMTX2", "SLIMTX2"),
1088 ARIZONA_MUX_ROUTES("SLIMTX3", "SLIMTX3"),
1089 ARIZONA_MUX_ROUTES("SLIMTX4", "SLIMTX4"),
1090 ARIZONA_MUX_ROUTES("SLIMTX5", "SLIMTX5"),
1091 ARIZONA_MUX_ROUTES("SLIMTX6", "SLIMTX6"),
1092
1093 ARIZONA_MUX_ROUTES("SPD1TX1", "SPDIFTX1"),
1094 ARIZONA_MUX_ROUTES("SPD1TX2", "SPDIFTX2"),
1095
1096 ARIZONA_MUX_ROUTES("EQ1", "EQ1"),
1097 ARIZONA_MUX_ROUTES("EQ2", "EQ2"),
1098 ARIZONA_MUX_ROUTES("EQ3", "EQ3"),
1099 ARIZONA_MUX_ROUTES("EQ4", "EQ4"),
1100
1101 ARIZONA_MUX_ROUTES("DRC1L", "DRC1L"),
1102 ARIZONA_MUX_ROUTES("DRC1R", "DRC1R"),
1103
1104 ARIZONA_MIXER_ROUTES("LHPF1", "LHPF1"),
1105 ARIZONA_MIXER_ROUTES("LHPF2", "LHPF2"),
1106 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
1107 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
1108
1109 ARIZONA_MUX_ROUTES("ASRC1L", "ASRC1L"),
1110 ARIZONA_MUX_ROUTES("ASRC1R", "ASRC1R"),
1111 ARIZONA_MUX_ROUTES("ASRC2L", "ASRC2L"),
1112 ARIZONA_MUX_ROUTES("ASRC2R", "ASRC2R"),
1113
1114 ARIZONA_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),
1115 ARIZONA_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),
1116 ARIZONA_MUX_ROUTES("ISRC1INT3", "ISRC1INT3"),
1117 ARIZONA_MUX_ROUTES("ISRC1INT4", "ISRC1INT4"),
1118
1119 ARIZONA_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),
1120 ARIZONA_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),
1121 ARIZONA_MUX_ROUTES("ISRC1DEC3", "ISRC1DEC3"),
1122 ARIZONA_MUX_ROUTES("ISRC1DEC4", "ISRC1DEC4"),
1123
1124 ARIZONA_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),
1125 ARIZONA_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),
1126
1127 ARIZONA_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),
1128 ARIZONA_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),
1129
1130 { "AEC1 Loopback", "HPOUTL", "OUT1L" },
1131 { "AEC1 Loopback", "HPOUTR", "OUT1R" },
1132 { "AEC2 Loopback", "HPOUTL", "OUT1L" },
1133 { "AEC2 Loopback", "HPOUTR", "OUT1R" },
1134 { "HPOUTL", NULL, "OUT1L" },
1135 { "HPOUTR", NULL, "OUT1R" },
1136
1137 { "AEC1 Loopback", "LINEOUTL", "OUT2L" },
1138 { "AEC1 Loopback", "LINEOUTR", "OUT2R" },
1139 { "AEC2 Loopback", "LINEOUTL", "OUT2L" },
1140 { "AEC2 Loopback", "LINEOUTR", "OUT2R" },
1141 { "LINEOUTL", NULL, "OUT2L" },
1142 { "LINEOUTR", NULL, "OUT2R" },
1143
1144 { "AEC1 Loopback", "EPOUT", "OUT3" },
1145 { "AEC2 Loopback", "EPOUT", "OUT3" },
1146 { "EPOUT", NULL, "OUT3" },
1147
1148 { "AEC1 Loopback", "SPKOUTL", "OUT4L" },
1149 { "AEC2 Loopback", "SPKOUTL", "OUT4L" },
1150 { "SPKOUTLN", NULL, "OUT4L" },
1151 { "SPKOUTLP", NULL, "OUT4L" },
1152
1153 { "AEC1 Loopback", "SPKOUTR", "OUT4R" },
1154 { "AEC2 Loopback", "SPKOUTR", "OUT4R" },
1155 { "SPKOUTRN", NULL, "OUT4R" },
1156 { "SPKOUTRP", NULL, "OUT4R" },
1157
1158 { "SPDIF", NULL, "SPD1" },
1159
1160 { "AEC1 Loopback", "SPKDATL", "OUT5L" },
1161 { "AEC1 Loopback", "SPKDATR", "OUT5R" },
1162 { "AEC2 Loopback", "SPKDATL", "OUT5L" },
1163 { "AEC2 Loopback", "SPKDATR", "OUT5R" },
1164 { "SPKDATL", NULL, "OUT5L" },
1165 { "SPKDATR", NULL, "OUT5R" },
1166
1167 { "MICSUPP", NULL, "SYSCLK" },
1168
1169 { "DRC1 Signal Activity", NULL, "DRC1L" },
1170 { "DRC1 Signal Activity", NULL, "DRC1R" },
1171};
1172
1173#define WM8998_RATES SNDRV_PCM_RATE_8000_192000
1174
1175#define WM8998_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1176 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1177
1178static struct snd_soc_dai_driver wm8998_dai[] = {
1179 {
1180 .name = "wm8998-aif1",
1181 .id = 1,
1182 .base = ARIZONA_AIF1_BCLK_CTRL,
1183 .playback = {
1184 .stream_name = "AIF1 Playback",
1185 .channels_min = 1,
1186 .channels_max = 6,
1187 .rates = WM8998_RATES,
1188 .formats = WM8998_FORMATS,
1189 },
1190 .capture = {
1191 .stream_name = "AIF1 Capture",
1192 .channels_min = 1,
1193 .channels_max = 6,
1194 .rates = WM8998_RATES,
1195 .formats = WM8998_FORMATS,
1196 },
1197 .ops = &arizona_dai_ops,
1198 .symmetric_rates = 1,
1199 .symmetric_samplebits = 1,
1200 },
1201 {
1202 .name = "wm8998-aif2",
1203 .id = 2,
1204 .base = ARIZONA_AIF2_BCLK_CTRL,
1205 .playback = {
1206 .stream_name = "AIF2 Playback",
1207 .channels_min = 1,
1208 .channels_max = 6,
1209 .rates = WM8998_RATES,
1210 .formats = WM8998_FORMATS,
1211 },
1212 .capture = {
1213 .stream_name = "AIF2 Capture",
1214 .channels_min = 1,
1215 .channels_max = 6,
1216 .rates = WM8998_RATES,
1217 .formats = WM8998_FORMATS,
1218 },
1219 .ops = &arizona_dai_ops,
1220 .symmetric_rates = 1,
1221 .symmetric_samplebits = 1,
1222 },
1223 {
1224 .name = "wm8998-aif3",
1225 .id = 3,
1226 .base = ARIZONA_AIF3_BCLK_CTRL,
1227 .playback = {
1228 .stream_name = "AIF3 Playback",
1229 .channels_min = 1,
1230 .channels_max = 2,
1231 .rates = WM8998_RATES,
1232 .formats = WM8998_FORMATS,
1233 },
1234 .capture = {
1235 .stream_name = "AIF3 Capture",
1236 .channels_min = 1,
1237 .channels_max = 2,
1238 .rates = WM8998_RATES,
1239 .formats = WM8998_FORMATS,
1240 },
1241 .ops = &arizona_dai_ops,
1242 .symmetric_rates = 1,
1243 .symmetric_samplebits = 1,
1244 },
1245 {
1246 .name = "wm8998-slim1",
1247 .id = 4,
1248 .playback = {
1249 .stream_name = "Slim1 Playback",
1250 .channels_min = 1,
1251 .channels_max = 2,
1252 .rates = WM8998_RATES,
1253 .formats = WM8998_FORMATS,
1254 },
1255 .capture = {
1256 .stream_name = "Slim1 Capture",
1257 .channels_min = 1,
1258 .channels_max = 4,
1259 .rates = WM8998_RATES,
1260 .formats = WM8998_FORMATS,
1261 },
1262 .ops = &arizona_simple_dai_ops,
1263 },
1264 {
1265 .name = "wm8998-slim2",
1266 .id = 5,
1267 .playback = {
1268 .stream_name = "Slim2 Playback",
1269 .channels_min = 1,
1270 .channels_max = 2,
1271 .rates = WM8998_RATES,
1272 .formats = WM8998_FORMATS,
1273 },
1274 .capture = {
1275 .stream_name = "Slim2 Capture",
1276 .channels_min = 1,
1277 .channels_max = 2,
1278 .rates = WM8998_RATES,
1279 .formats = WM8998_FORMATS,
1280 },
1281 .ops = &arizona_simple_dai_ops,
1282 },
1283};
1284
1285static int wm8998_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1286 unsigned int Fref, unsigned int Fout)
1287{
1288 struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
1289
1290 switch (fll_id) {
1291 case WM8998_FLL1:
1292 return arizona_set_fll(&wm8998->fll[0], source, Fref, Fout);
1293 case WM8998_FLL2:
1294 return arizona_set_fll(&wm8998->fll[1], source, Fref, Fout);
1295 case WM8998_FLL1_REFCLK:
1296 return arizona_set_fll_refclk(&wm8998->fll[0], source, Fref,
1297 Fout);
1298 case WM8998_FLL2_REFCLK:
1299 return arizona_set_fll_refclk(&wm8998->fll[1], source, Fref,
1300 Fout);
1301 default:
1302 return -EINVAL;
1303 }
1304}
1305
1306static int wm8998_codec_probe(struct snd_soc_codec *codec)
1307{
1308 struct wm8998_priv *priv = snd_soc_codec_get_drvdata(codec);
1309 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1310
1311 priv->core.arizona->dapm = dapm;
1312
1313 arizona_init_spk(codec);
1314 arizona_init_gpio(codec);
1315
1316 snd_soc_dapm_disable_pin(dapm, "HAPTICS");
1317
1318 return 0;
1319}
1320
1321static int wm8998_codec_remove(struct snd_soc_codec *codec)
1322{
1323 struct wm8998_priv *priv = snd_soc_codec_get_drvdata(codec);
1324
1325 priv->core.arizona->dapm = NULL;
1326
1327 return 0;
1328}
1329
1330#define WM8998_DIG_VU 0x0200
1331
1332static unsigned int wm8998_digital_vu[] = {
1333 ARIZONA_DAC_DIGITAL_VOLUME_1L,
1334 ARIZONA_DAC_DIGITAL_VOLUME_1R,
1335 ARIZONA_DAC_DIGITAL_VOLUME_2L,
1336 ARIZONA_DAC_DIGITAL_VOLUME_2R,
1337 ARIZONA_DAC_DIGITAL_VOLUME_3L,
1338 ARIZONA_DAC_DIGITAL_VOLUME_4L,
1339 ARIZONA_DAC_DIGITAL_VOLUME_4R,
1340 ARIZONA_DAC_DIGITAL_VOLUME_5L,
1341 ARIZONA_DAC_DIGITAL_VOLUME_5R,
1342};
1343
1344static struct regmap *wm8998_get_regmap(struct device *dev)
1345{
1346 struct wm8998_priv *priv = dev_get_drvdata(dev);
1347
1348 return priv->core.arizona->regmap;
1349}
1350
1351static struct snd_soc_codec_driver soc_codec_dev_wm8998 = {
1352 .probe = wm8998_codec_probe,
1353 .remove = wm8998_codec_remove,
1354 .get_regmap = wm8998_get_regmap,
1355
1356 .idle_bias_off = true,
1357
1358 .set_sysclk = arizona_set_sysclk,
1359 .set_pll = wm8998_set_fll,
1360
1361 .controls = wm8998_snd_controls,
1362 .num_controls = ARRAY_SIZE(wm8998_snd_controls),
1363 .dapm_widgets = wm8998_dapm_widgets,
1364 .num_dapm_widgets = ARRAY_SIZE(wm8998_dapm_widgets),
1365 .dapm_routes = wm8998_dapm_routes,
1366 .num_dapm_routes = ARRAY_SIZE(wm8998_dapm_routes),
1367};
1368
1369static int wm8998_probe(struct platform_device *pdev)
1370{
1371 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
1372 struct wm8998_priv *wm8998;
1373 int i;
1374
1375 wm8998 = devm_kzalloc(&pdev->dev, sizeof(struct wm8998_priv),
1376 GFP_KERNEL);
1377 if (!wm8998)
1378 return -ENOMEM;
1379 platform_set_drvdata(pdev, wm8998);
1380
1381 wm8998->core.arizona = arizona;
1382 wm8998->core.num_inputs = 3; /* IN1L, IN1R, IN2 */
1383
1384 for (i = 0; i < ARRAY_SIZE(wm8998->fll); i++)
1385 wm8998->fll[i].vco_mult = 1;
1386
1387 arizona_init_fll(arizona, 1, ARIZONA_FLL1_CONTROL_1 - 1,
1388 ARIZONA_IRQ_FLL1_LOCK, ARIZONA_IRQ_FLL1_CLOCK_OK,
1389 &wm8998->fll[0]);
1390 arizona_init_fll(arizona, 2, ARIZONA_FLL2_CONTROL_1 - 1,
1391 ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK,
1392 &wm8998->fll[1]);
1393
1394 for (i = 0; i < ARRAY_SIZE(wm8998_dai); i++)
1395 arizona_init_dai(&wm8998->core, i);
1396
1397 /* Latch volume update bits */
1398 for (i = 0; i < ARRAY_SIZE(wm8998_digital_vu); i++)
1399 regmap_update_bits(arizona->regmap, wm8998_digital_vu[i],
1400 WM8998_DIG_VU, WM8998_DIG_VU);
1401
1402 pm_runtime_enable(&pdev->dev);
1403 pm_runtime_idle(&pdev->dev);
1404
1405 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8998,
1406 wm8998_dai, ARRAY_SIZE(wm8998_dai));
1407}
1408
1409static int wm8998_remove(struct platform_device *pdev)
1410{
1411 snd_soc_unregister_codec(&pdev->dev);
1412 pm_runtime_disable(&pdev->dev);
1413
1414 return 0;
1415}
1416
1417static struct platform_driver wm8998_codec_driver = {
1418 .driver = {
1419 .name = "wm8998-codec",
1420 },
1421 .probe = wm8998_probe,
1422 .remove = wm8998_remove,
1423};
1424
1425module_platform_driver(wm8998_codec_driver);
1426
1427MODULE_DESCRIPTION("ASoC WM8998 driver");
1428MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.wolfsonmicro.com>");
1429MODULE_LICENSE("GPL v2");
1430MODULE_ALIAS("platform:wm8998-codec");
diff --git a/sound/soc/codecs/wm8998.h b/sound/soc/codecs/wm8998.h
new file mode 100644
index 000000000000..1e8647252162
--- /dev/null
+++ b/sound/soc/codecs/wm8998.h
@@ -0,0 +1,23 @@
1/*
2 * wm8998.h -- ALSA SoC Audio driver for WM8998 codecs
3 *
4 * Copyright 2015 Cirrus Logic, Inc.
5 *
6 * Author: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM8998_H
14#define _WM8998_H
15
16#include "arizona.h"
17
18#define WM8998_FLL1 1
19#define WM8998_FLL2 2
20#define WM8998_FLL1_REFCLK 3
21#define WM8998_FLL2_REFCLK 4
22
23#endif
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index add6bb99661d..4495a40a9468 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -80,12 +80,13 @@ struct davinci_mcasp {
80 80
81 /* McASP specific data */ 81 /* McASP specific data */
82 int tdm_slots; 82 int tdm_slots;
83 u32 tdm_mask[2];
84 int slot_width;
83 u8 op_mode; 85 u8 op_mode;
84 u8 num_serializer; 86 u8 num_serializer;
85 u8 *serial_dir; 87 u8 *serial_dir;
86 u8 version; 88 u8 version;
87 u8 bclk_div; 89 u8 bclk_div;
88 u16 bclk_lrclk_ratio;
89 int streams; 90 int streams;
90 u32 irq_request[2]; 91 u32 irq_request[2];
91 int dma_request[2]; 92 int dma_request[2];
@@ -556,8 +557,21 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id,
556 mcasp->bclk_div = div; 557 mcasp->bclk_div = div;
557 break; 558 break;
558 559
559 case 2: /* BCLK/LRCLK ratio */ 560 case 2: /*
560 mcasp->bclk_lrclk_ratio = div; 561 * BCLK/LRCLK ratio descries how many bit-clock cycles
562 * fit into one frame. The clock ratio is given for a
563 * full period of data (for I2S format both left and
564 * right channels), so it has to be divided by number
565 * of tdm-slots (for I2S - divided by 2).
566 * Instead of storing this ratio, we calculate a new
567 * tdm_slot width by dividing the the ratio by the
568 * number of configured tdm slots.
569 */
570 mcasp->slot_width = div / mcasp->tdm_slots;
571 if (div % mcasp->tdm_slots)
572 dev_warn(mcasp->dev,
573 "%s(): BCLK/LRCLK %d is not divisible by %d tdm slots",
574 __func__, div, mcasp->tdm_slots);
561 break; 575 break;
562 576
563 default: 577 default:
@@ -596,12 +610,92 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id,
596 return 0; 610 return 0;
597} 611}
598 612
613/* All serializers must have equal number of channels */
614static int davinci_mcasp_ch_constraint(struct davinci_mcasp *mcasp, int stream,
615 int serializers)
616{
617 struct snd_pcm_hw_constraint_list *cl = &mcasp->chconstr[stream];
618 unsigned int *list = (unsigned int *) cl->list;
619 int slots = mcasp->tdm_slots;
620 int i, count = 0;
621
622 if (mcasp->tdm_mask[stream])
623 slots = hweight32(mcasp->tdm_mask[stream]);
624
625 for (i = 2; i <= slots; i++)
626 list[count++] = i;
627
628 for (i = 2; i <= serializers; i++)
629 list[count++] = i*slots;
630
631 cl->count = count;
632
633 return 0;
634}
635
636static int davinci_mcasp_set_ch_constraints(struct davinci_mcasp *mcasp)
637{
638 int rx_serializers = 0, tx_serializers = 0, ret, i;
639
640 for (i = 0; i < mcasp->num_serializer; i++)
641 if (mcasp->serial_dir[i] == TX_MODE)
642 tx_serializers++;
643 else if (mcasp->serial_dir[i] == RX_MODE)
644 rx_serializers++;
645
646 ret = davinci_mcasp_ch_constraint(mcasp, SNDRV_PCM_STREAM_PLAYBACK,
647 tx_serializers);
648 if (ret)
649 return ret;
650
651 ret = davinci_mcasp_ch_constraint(mcasp, SNDRV_PCM_STREAM_CAPTURE,
652 rx_serializers);
653
654 return ret;
655}
656
657
658static int davinci_mcasp_set_tdm_slot(struct snd_soc_dai *dai,
659 unsigned int tx_mask,
660 unsigned int rx_mask,
661 int slots, int slot_width)
662{
663 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
664
665 dev_dbg(mcasp->dev,
666 "%s() tx_mask 0x%08x rx_mask 0x%08x slots %d width %d\n",
667 __func__, tx_mask, rx_mask, slots, slot_width);
668
669 if (tx_mask >= (1<<slots) || rx_mask >= (1<<slots)) {
670 dev_err(mcasp->dev,
671 "Bad tdm mask tx: 0x%08x rx: 0x%08x slots %d\n",
672 tx_mask, rx_mask, slots);
673 return -EINVAL;
674 }
675
676 if (slot_width &&
677 (slot_width < 8 || slot_width > 32 || slot_width % 4 != 0)) {
678 dev_err(mcasp->dev, "%s: Unsupported slot_width %d\n",
679 __func__, slot_width);
680 return -EINVAL;
681 }
682
683 mcasp->tdm_slots = slots;
684 mcasp->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = rx_mask;
685 mcasp->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = tx_mask;
686 mcasp->slot_width = slot_width;
687
688 return davinci_mcasp_set_ch_constraints(mcasp);
689}
690
599static int davinci_config_channel_size(struct davinci_mcasp *mcasp, 691static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
600 int word_length) 692 int sample_width)
601{ 693{
602 u32 fmt; 694 u32 fmt;
603 u32 tx_rotate = (word_length / 4) & 0x7; 695 u32 tx_rotate = (sample_width / 4) & 0x7;
604 u32 mask = (1ULL << word_length) - 1; 696 u32 mask = (1ULL << sample_width) - 1;
697 u32 slot_width = sample_width;
698
605 /* 699 /*
606 * For captured data we should not rotate, inversion and masking is 700 * For captured data we should not rotate, inversion and masking is
607 * enoguh to get the data to the right position: 701 * enoguh to get the data to the right position:
@@ -614,28 +708,23 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
614 u32 rx_rotate = 0; 708 u32 rx_rotate = 0;
615 709
616 /* 710 /*
617 * if s BCLK-to-LRCLK ratio has been configured via the set_clkdiv() 711 * Setting the tdm slot width either with set_clkdiv() or
618 * callback, take it into account here. That allows us to for example 712 * set_tdm_slot() allows us to for example send 32 bits per
619 * send 32 bits per channel to the codec, while only 16 of them carry 713 * channel to the codec, while only 16 of them carry audio
620 * audio payload. 714 * payload.
621 * The clock ratio is given for a full period of data (for I2S format
622 * both left and right channels), so it has to be divided by number of
623 * tdm-slots (for I2S - divided by 2).
624 */ 715 */
625 if (mcasp->bclk_lrclk_ratio) { 716 if (mcasp->slot_width) {
626 u32 slot_length = mcasp->bclk_lrclk_ratio / mcasp->tdm_slots;
627
628 /* 717 /*
629 * When we have more bclk then it is needed for the data, we 718 * When we have more bclk then it is needed for the
630 * need to use the rotation to move the received samples to have 719 * data, we need to use the rotation to move the
631 * correct alignment. 720 * received samples to have correct alignment.
632 */ 721 */
633 rx_rotate = (slot_length - word_length) / 4; 722 slot_width = mcasp->slot_width;
634 word_length = slot_length; 723 rx_rotate = (slot_width - sample_width) / 4;
635 } 724 }
636 725
637 /* mapping of the XSSZ bit-field as described in the datasheet */ 726 /* mapping of the XSSZ bit-field as described in the datasheet */
638 fmt = (word_length >> 1) - 1; 727 fmt = (slot_width >> 1) - 1;
639 728
640 if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) { 729 if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) {
641 mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt), 730 mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt),
@@ -663,7 +752,7 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
663 u8 rx_ser = 0; 752 u8 rx_ser = 0;
664 u8 slots = mcasp->tdm_slots; 753 u8 slots = mcasp->tdm_slots;
665 u8 max_active_serializers = (channels + slots - 1) / slots; 754 u8 max_active_serializers = (channels + slots - 1) / slots;
666 int active_serializers, numevt, n; 755 int active_serializers, numevt;
667 u32 reg; 756 u32 reg;
668 /* Default configuration */ 757 /* Default configuration */
669 if (mcasp->version < MCASP_VERSION_3) 758 if (mcasp->version < MCASP_VERSION_3)
@@ -745,9 +834,8 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
745 * The number of words for numevt need to be in steps of active 834 * The number of words for numevt need to be in steps of active
746 * serializers. 835 * serializers.
747 */ 836 */
748 n = numevt % active_serializers; 837 numevt = (numevt / active_serializers) * active_serializers;
749 if (n) 838
750 numevt += (active_serializers - n);
751 while (period_words % numevt && numevt > 0) 839 while (period_words % numevt && numevt > 0)
752 numevt -= active_serializers; 840 numevt -= active_serializers;
753 if (numevt <= 0) 841 if (numevt <= 0)
@@ -777,33 +865,50 @@ static int mcasp_i2s_hw_param(struct davinci_mcasp *mcasp, int stream,
777 865
778 /* 866 /*
779 * If more than one serializer is needed, then use them with 867 * If more than one serializer is needed, then use them with
780 * their specified tdm_slots count. Otherwise, one serializer 868 * all the specified tdm_slots. Otherwise, one serializer can
781 * can cope with the transaction using as many slots as channels 869 * cope with the transaction using just as many slots as there
782 * in the stream, requires channels symmetry 870 * are channels in the stream.
783 */ 871 */
784 active_serializers = (channels + total_slots - 1) / total_slots; 872 if (mcasp->tdm_mask[stream]) {
785 if (active_serializers == 1) 873 active_slots = hweight32(mcasp->tdm_mask[stream]);
786 active_slots = channels; 874 active_serializers = (channels + active_slots - 1) /
787 else 875 active_slots;
788 active_slots = total_slots; 876 if (active_serializers == 1) {
789 877 active_slots = channels;
790 for (i = 0; i < active_slots; i++) 878 for (i = 0; i < total_slots; i++) {
791 mask |= (1 << i); 879 if ((1 << i) & mcasp->tdm_mask[stream]) {
880 mask |= (1 << i);
881 if (--active_slots <= 0)
882 break;
883 }
884 }
885 }
886 } else {
887 active_serializers = (channels + total_slots - 1) / total_slots;
888 if (active_serializers == 1)
889 active_slots = channels;
890 else
891 active_slots = total_slots;
792 892
893 for (i = 0; i < active_slots; i++)
894 mask |= (1 << i);
895 }
793 mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC); 896 mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC);
794 897
795 if (!mcasp->dat_port) 898 if (!mcasp->dat_port)
796 busel = TXSEL; 899 busel = TXSEL;
797 900
798 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask); 901 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
799 mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD); 902 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask);
800 mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, 903 mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD);
801 FSXMOD(total_slots), FSXMOD(0x1FF)); 904 mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG,
802 905 FSXMOD(total_slots), FSXMOD(0x1FF));
803 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask); 906 } else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
804 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD); 907 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask);
805 mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, 908 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD);
806 FSRMOD(total_slots), FSRMOD(0x1FF)); 909 mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG,
910 FSRMOD(total_slots), FSRMOD(0x1FF));
911 }
807 912
808 return 0; 913 return 0;
809} 914}
@@ -923,6 +1028,9 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
923 int sbits = params_width(params); 1028 int sbits = params_width(params);
924 int ppm, div; 1029 int ppm, div;
925 1030
1031 if (mcasp->slot_width)
1032 sbits = mcasp->slot_width;
1033
926 div = davinci_mcasp_calc_clk_div(mcasp, rate*sbits*slots, 1034 div = davinci_mcasp_calc_clk_div(mcasp, rate*sbits*slots,
927 &ppm); 1035 &ppm);
928 if (ppm) 1036 if (ppm)
@@ -1028,6 +1136,9 @@ static int davinci_mcasp_hw_rule_rate(struct snd_pcm_hw_params *params,
1028 struct snd_interval range; 1136 struct snd_interval range;
1029 int i; 1137 int i;
1030 1138
1139 if (rd->mcasp->slot_width)
1140 sbits = rd->mcasp->slot_width;
1141
1031 snd_interval_any(&range); 1142 snd_interval_any(&range);
1032 range.empty = 1; 1143 range.empty = 1;
1033 1144
@@ -1070,10 +1181,14 @@ static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params,
1070 1181
1071 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { 1182 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
1072 if (snd_mask_test(fmt, i)) { 1183 if (snd_mask_test(fmt, i)) {
1073 uint bclk_freq = snd_pcm_format_width(i)*slots*rate; 1184 uint sbits = snd_pcm_format_width(i);
1074 int ppm; 1185 int ppm;
1075 1186
1076 davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm); 1187 if (rd->mcasp->slot_width)
1188 sbits = rd->mcasp->slot_width;
1189
1190 davinci_mcasp_calc_clk_div(rd->mcasp, sbits*slots*rate,
1191 &ppm);
1077 if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) { 1192 if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) {
1078 snd_mask_set(&nfmt, i); 1193 snd_mask_set(&nfmt, i);
1079 count++; 1194 count++;
@@ -1095,6 +1210,10 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
1095 &mcasp->ruledata[substream->stream]; 1210 &mcasp->ruledata[substream->stream];
1096 u32 max_channels = 0; 1211 u32 max_channels = 0;
1097 int i, dir; 1212 int i, dir;
1213 int tdm_slots = mcasp->tdm_slots;
1214
1215 if (mcasp->tdm_mask[substream->stream])
1216 tdm_slots = hweight32(mcasp->tdm_mask[substream->stream]);
1098 1217
1099 mcasp->substreams[substream->stream] = substream; 1218 mcasp->substreams[substream->stream] = substream;
1100 1219
@@ -1115,7 +1234,7 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
1115 max_channels++; 1234 max_channels++;
1116 } 1235 }
1117 ruledata->serializers = max_channels; 1236 ruledata->serializers = max_channels;
1118 max_channels *= mcasp->tdm_slots; 1237 max_channels *= tdm_slots;
1119 /* 1238 /*
1120 * If the already active stream has less channels than the calculated 1239 * If the already active stream has less channels than the calculated
1121 * limnit based on the seirializers * tdm_slots, we need to use that as 1240 * limnit based on the seirializers * tdm_slots, we need to use that as
@@ -1125,15 +1244,25 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
1125 */ 1244 */
1126 if (mcasp->channels && mcasp->channels < max_channels) 1245 if (mcasp->channels && mcasp->channels < max_channels)
1127 max_channels = mcasp->channels; 1246 max_channels = mcasp->channels;
1247 /*
1248 * But we can always allow channels upto the amount of
1249 * the available tdm_slots.
1250 */
1251 if (max_channels < tdm_slots)
1252 max_channels = tdm_slots;
1128 1253
1129 snd_pcm_hw_constraint_minmax(substream->runtime, 1254 snd_pcm_hw_constraint_minmax(substream->runtime,
1130 SNDRV_PCM_HW_PARAM_CHANNELS, 1255 SNDRV_PCM_HW_PARAM_CHANNELS,
1131 2, max_channels); 1256 2, max_channels);
1132 1257
1133 if (mcasp->chconstr[substream->stream].count) 1258 snd_pcm_hw_constraint_list(substream->runtime,
1134 snd_pcm_hw_constraint_list(substream->runtime, 1259 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1135 0, SNDRV_PCM_HW_PARAM_CHANNELS, 1260 &mcasp->chconstr[substream->stream]);
1136 &mcasp->chconstr[substream->stream]); 1261
1262 if (mcasp->slot_width)
1263 snd_pcm_hw_constraint_minmax(substream->runtime,
1264 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1265 8, mcasp->slot_width);
1137 1266
1138 /* 1267 /*
1139 * If we rely on implicit BCLK divider setting we should 1268 * If we rely on implicit BCLK divider setting we should
@@ -1185,6 +1314,7 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
1185 .set_fmt = davinci_mcasp_set_dai_fmt, 1314 .set_fmt = davinci_mcasp_set_dai_fmt,
1186 .set_clkdiv = davinci_mcasp_set_clkdiv, 1315 .set_clkdiv = davinci_mcasp_set_clkdiv,
1187 .set_sysclk = davinci_mcasp_set_sysclk, 1316 .set_sysclk = davinci_mcasp_set_sysclk,
1317 .set_tdm_slot = davinci_mcasp_set_tdm_slot,
1188}; 1318};
1189 1319
1190static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai) 1320static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai)
@@ -1299,6 +1429,7 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
1299 .ops = &davinci_mcasp_dai_ops, 1429 .ops = &davinci_mcasp_dai_ops,
1300 1430
1301 .symmetric_samplebits = 1, 1431 .symmetric_samplebits = 1,
1432 .symmetric_rates = 1,
1302 }, 1433 },
1303 { 1434 {
1304 .name = "davinci-mcasp.1", 1435 .name = "davinci-mcasp.1",
@@ -1514,59 +1645,6 @@ nodata:
1514 return pdata; 1645 return pdata;
1515} 1646}
1516 1647
1517/* All serializers must have equal number of channels */
1518static int davinci_mcasp_ch_constraint(struct davinci_mcasp *mcasp,
1519 struct snd_pcm_hw_constraint_list *cl,
1520 int serializers)
1521{
1522 unsigned int *list;
1523 int i, count = 0;
1524
1525 if (serializers <= 1)
1526 return 0;
1527
1528 list = devm_kzalloc(mcasp->dev, sizeof(unsigned int) *
1529 (mcasp->tdm_slots + serializers - 2),
1530 GFP_KERNEL);
1531 if (!list)
1532 return -ENOMEM;
1533
1534 for (i = 2; i <= mcasp->tdm_slots; i++)
1535 list[count++] = i;
1536
1537 for (i = 2; i <= serializers; i++)
1538 list[count++] = i*mcasp->tdm_slots;
1539
1540 cl->count = count;
1541 cl->list = list;
1542
1543 return 0;
1544}
1545
1546
1547static int davinci_mcasp_init_ch_constraints(struct davinci_mcasp *mcasp)
1548{
1549 int rx_serializers = 0, tx_serializers = 0, ret, i;
1550
1551 for (i = 0; i < mcasp->num_serializer; i++)
1552 if (mcasp->serial_dir[i] == TX_MODE)
1553 tx_serializers++;
1554 else if (mcasp->serial_dir[i] == RX_MODE)
1555 rx_serializers++;
1556
1557 ret = davinci_mcasp_ch_constraint(mcasp, &mcasp->chconstr[
1558 SNDRV_PCM_STREAM_PLAYBACK],
1559 tx_serializers);
1560 if (ret)
1561 return ret;
1562
1563 ret = davinci_mcasp_ch_constraint(mcasp, &mcasp->chconstr[
1564 SNDRV_PCM_STREAM_CAPTURE],
1565 rx_serializers);
1566
1567 return ret;
1568}
1569
1570enum { 1648enum {
1571 PCM_EDMA, 1649 PCM_EDMA,
1572 PCM_SDMA, 1650 PCM_SDMA,
@@ -1685,7 +1763,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1685 1763
1686 irq = platform_get_irq_byname(pdev, "common"); 1764 irq = platform_get_irq_byname(pdev, "common");
1687 if (irq >= 0) { 1765 if (irq >= 0) {
1688 irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_common\n", 1766 irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_common",
1689 dev_name(&pdev->dev)); 1767 dev_name(&pdev->dev));
1690 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, 1768 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
1691 davinci_mcasp_common_irq_handler, 1769 davinci_mcasp_common_irq_handler,
@@ -1702,7 +1780,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1702 1780
1703 irq = platform_get_irq_byname(pdev, "rx"); 1781 irq = platform_get_irq_byname(pdev, "rx");
1704 if (irq >= 0) { 1782 if (irq >= 0) {
1705 irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_rx\n", 1783 irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_rx",
1706 dev_name(&pdev->dev)); 1784 dev_name(&pdev->dev));
1707 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, 1785 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
1708 davinci_mcasp_rx_irq_handler, 1786 davinci_mcasp_rx_irq_handler,
@@ -1717,7 +1795,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1717 1795
1718 irq = platform_get_irq_byname(pdev, "tx"); 1796 irq = platform_get_irq_byname(pdev, "tx");
1719 if (irq >= 0) { 1797 if (irq >= 0) {
1720 irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_tx\n", 1798 irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_tx",
1721 dev_name(&pdev->dev)); 1799 dev_name(&pdev->dev));
1722 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, 1800 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
1723 davinci_mcasp_tx_irq_handler, 1801 davinci_mcasp_tx_irq_handler,
@@ -1783,7 +1861,28 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1783 mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE; 1861 mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE;
1784 } 1862 }
1785 1863
1786 ret = davinci_mcasp_init_ch_constraints(mcasp); 1864 /* Allocate memory for long enough list for all possible
1865 * scenarios. Maximum number tdm slots is 32 and there cannot
1866 * be more serializers than given in the configuration. The
1867 * serializer directions could be taken into account, but it
1868 * would make code much more complex and save only couple of
1869 * bytes.
1870 */
1871 mcasp->chconstr[SNDRV_PCM_STREAM_PLAYBACK].list =
1872 devm_kzalloc(mcasp->dev, sizeof(unsigned int) *
1873 (32 + mcasp->num_serializer - 2),
1874 GFP_KERNEL);
1875
1876 mcasp->chconstr[SNDRV_PCM_STREAM_CAPTURE].list =
1877 devm_kzalloc(mcasp->dev, sizeof(unsigned int) *
1878 (32 + mcasp->num_serializer - 2),
1879 GFP_KERNEL);
1880
1881 if (!mcasp->chconstr[SNDRV_PCM_STREAM_PLAYBACK].list ||
1882 !mcasp->chconstr[SNDRV_PCM_STREAM_CAPTURE].list)
1883 return -ENOMEM;
1884
1885 ret = davinci_mcasp_set_ch_constraints(mcasp);
1787 if (ret) 1886 if (ret)
1788 goto err; 1887 goto err;
1789 1888
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index a3e97b46b64e..6e6a70c5c2bd 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -131,23 +131,32 @@ static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream)
131 131
132 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 132 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
133 for (i = 0; i < 4; i++) 133 for (i = 0; i < 4; i++)
134 i2s_write_reg(dev->i2s_base, TOR(i), 0); 134 i2s_read_reg(dev->i2s_base, TOR(i));
135 } else { 135 } else {
136 for (i = 0; i < 4; i++) 136 for (i = 0; i < 4; i++)
137 i2s_write_reg(dev->i2s_base, ROR(i), 0); 137 i2s_read_reg(dev->i2s_base, ROR(i));
138 } 138 }
139} 139}
140 140
141static void i2s_start(struct dw_i2s_dev *dev, 141static void i2s_start(struct dw_i2s_dev *dev,
142 struct snd_pcm_substream *substream) 142 struct snd_pcm_substream *substream)
143{ 143{
144 144 u32 i, irq;
145 i2s_write_reg(dev->i2s_base, IER, 1); 145 i2s_write_reg(dev->i2s_base, IER, 1);
146 146
147 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 147 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
148 for (i = 0; i < 4; i++) {
149 irq = i2s_read_reg(dev->i2s_base, IMR(i));
150 i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x30);
151 }
148 i2s_write_reg(dev->i2s_base, ITER, 1); 152 i2s_write_reg(dev->i2s_base, ITER, 1);
149 else 153 } else {
154 for (i = 0; i < 4; i++) {
155 irq = i2s_read_reg(dev->i2s_base, IMR(i));
156 i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x03);
157 }
150 i2s_write_reg(dev->i2s_base, IRER, 1); 158 i2s_write_reg(dev->i2s_base, IRER, 1);
159 }
151 160
152 i2s_write_reg(dev->i2s_base, CER, 1); 161 i2s_write_reg(dev->i2s_base, CER, 1);
153} 162}
@@ -273,23 +282,25 @@ static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
273 282
274 config->sample_rate = params_rate(params); 283 config->sample_rate = params_rate(params);
275 284
276 if (dev->i2s_clk_cfg) { 285 if (dev->capability & DW_I2S_MASTER) {
277 ret = dev->i2s_clk_cfg(config); 286 if (dev->i2s_clk_cfg) {
278 if (ret < 0) { 287 ret = dev->i2s_clk_cfg(config);
279 dev_err(dev->dev, "runtime audio clk config fail\n"); 288 if (ret < 0) {
280 return ret; 289 dev_err(dev->dev, "runtime audio clk config fail\n");
281 } 290 return ret;
282 } else { 291 }
283 u32 bitclk = config->sample_rate * config->data_width * 2; 292 } else {
284 293 u32 bitclk = config->sample_rate *
285 ret = clk_set_rate(dev->clk, bitclk); 294 config->data_width * 2;
286 if (ret) { 295
287 dev_err(dev->dev, "Can't set I2S clock rate: %d\n", 296 ret = clk_set_rate(dev->clk, bitclk);
288 ret); 297 if (ret) {
289 return ret; 298 dev_err(dev->dev, "Can't set I2S clock rate: %d\n",
299 ret);
300 return ret;
301 }
290 } 302 }
291 } 303 }
292
293 return 0; 304 return 0;
294} 305}
295 306
@@ -339,12 +350,43 @@ static int dw_i2s_trigger(struct snd_pcm_substream *substream,
339 return ret; 350 return ret;
340} 351}
341 352
353static int dw_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
354{
355 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
356 int ret = 0;
357
358 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
359 case SND_SOC_DAIFMT_CBM_CFM:
360 if (dev->capability & DW_I2S_SLAVE)
361 ret = 0;
362 else
363 ret = -EINVAL;
364 break;
365 case SND_SOC_DAIFMT_CBS_CFS:
366 if (dev->capability & DW_I2S_MASTER)
367 ret = 0;
368 else
369 ret = -EINVAL;
370 break;
371 case SND_SOC_DAIFMT_CBM_CFS:
372 case SND_SOC_DAIFMT_CBS_CFM:
373 ret = -EINVAL;
374 break;
375 default:
376 dev_dbg(dev->dev, "dwc : Invalid master/slave format\n");
377 ret = -EINVAL;
378 break;
379 }
380 return ret;
381}
382
342static struct snd_soc_dai_ops dw_i2s_dai_ops = { 383static struct snd_soc_dai_ops dw_i2s_dai_ops = {
343 .startup = dw_i2s_startup, 384 .startup = dw_i2s_startup,
344 .shutdown = dw_i2s_shutdown, 385 .shutdown = dw_i2s_shutdown,
345 .hw_params = dw_i2s_hw_params, 386 .hw_params = dw_i2s_hw_params,
346 .prepare = dw_i2s_prepare, 387 .prepare = dw_i2s_prepare,
347 .trigger = dw_i2s_trigger, 388 .trigger = dw_i2s_trigger,
389 .set_fmt = dw_i2s_set_fmt,
348}; 390};
349 391
350static const struct snd_soc_component_driver dw_i2s_component = { 392static const struct snd_soc_component_driver dw_i2s_component = {
@@ -357,7 +399,8 @@ static int dw_i2s_suspend(struct snd_soc_dai *dai)
357{ 399{
358 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); 400 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
359 401
360 clk_disable(dev->clk); 402 if (dev->capability & DW_I2S_MASTER)
403 clk_disable(dev->clk);
361 return 0; 404 return 0;
362} 405}
363 406
@@ -365,7 +408,8 @@ static int dw_i2s_resume(struct snd_soc_dai *dai)
365{ 408{
366 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); 409 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
367 410
368 clk_enable(dev->clk); 411 if (dev->capability & DW_I2S_MASTER)
412 clk_enable(dev->clk);
369 return 0; 413 return 0;
370} 414}
371 415
@@ -443,6 +487,14 @@ static int dw_configure_dai(struct dw_i2s_dev *dev,
443 dw_i2s_dai->capture.rates = rates; 487 dw_i2s_dai->capture.rates = rates;
444 } 488 }
445 489
490 if (COMP1_MODE_EN(comp1)) {
491 dev_dbg(dev->dev, "designware: i2s master mode supported\n");
492 dev->capability |= DW_I2S_MASTER;
493 } else {
494 dev_dbg(dev->dev, "designware: i2s slave mode supported\n");
495 dev->capability |= DW_I2S_SLAVE;
496 }
497
446 return 0; 498 return 0;
447} 499}
448 500
@@ -529,6 +581,7 @@ static int dw_i2s_probe(struct platform_device *pdev)
529 struct resource *res; 581 struct resource *res;
530 int ret; 582 int ret;
531 struct snd_soc_dai_driver *dw_i2s_dai; 583 struct snd_soc_dai_driver *dw_i2s_dai;
584 const char *clk_id;
532 585
533 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); 586 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
534 if (!dev) { 587 if (!dev) {
@@ -550,32 +603,35 @@ static int dw_i2s_probe(struct platform_device *pdev)
550 return PTR_ERR(dev->i2s_base); 603 return PTR_ERR(dev->i2s_base);
551 604
552 dev->dev = &pdev->dev; 605 dev->dev = &pdev->dev;
606
553 if (pdata) { 607 if (pdata) {
608 dev->capability = pdata->cap;
609 clk_id = NULL;
554 ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata); 610 ret = dw_configure_dai_by_pd(dev, dw_i2s_dai, res, pdata);
555 if (ret < 0) 611 } else {
556 return ret; 612 clk_id = "i2sclk";
613 ret = dw_configure_dai_by_dt(dev, dw_i2s_dai, res);
614 }
615 if (ret < 0)
616 return ret;
557 617
558 dev->capability = pdata->cap; 618 if (dev->capability & DW_I2S_MASTER) {
559 dev->i2s_clk_cfg = pdata->i2s_clk_cfg; 619 if (pdata) {
560 if (!dev->i2s_clk_cfg) { 620 dev->i2s_clk_cfg = pdata->i2s_clk_cfg;
561 dev_err(&pdev->dev, "no clock configure method\n"); 621 if (!dev->i2s_clk_cfg) {
562 return -ENODEV; 622 dev_err(&pdev->dev, "no clock configure method\n");
623 return -ENODEV;
624 }
563 } 625 }
626 dev->clk = devm_clk_get(&pdev->dev, clk_id);
564 627
565 dev->clk = devm_clk_get(&pdev->dev, NULL); 628 if (IS_ERR(dev->clk))
566 } else { 629 return PTR_ERR(dev->clk);
567 ret = dw_configure_dai_by_dt(dev, dw_i2s_dai, res); 630
631 ret = clk_prepare_enable(dev->clk);
568 if (ret < 0) 632 if (ret < 0)
569 return ret; 633 return ret;
570
571 dev->clk = devm_clk_get(&pdev->dev, "i2sclk");
572 } 634 }
573 if (IS_ERR(dev->clk))
574 return PTR_ERR(dev->clk);
575
576 ret = clk_prepare_enable(dev->clk);
577 if (ret < 0)
578 return ret;
579 635
580 dev_set_drvdata(&pdev->dev, dev); 636 dev_set_drvdata(&pdev->dev, dev);
581 ret = devm_snd_soc_register_component(&pdev->dev, &dw_i2s_component, 637 ret = devm_snd_soc_register_component(&pdev->dev, &dw_i2s_component,
@@ -597,7 +653,8 @@ static int dw_i2s_probe(struct platform_device *pdev)
597 return 0; 653 return 0;
598 654
599err_clk_disable: 655err_clk_disable:
600 clk_disable_unprepare(dev->clk); 656 if (dev->capability & DW_I2S_MASTER)
657 clk_disable_unprepare(dev->clk);
601 return ret; 658 return ret;
602} 659}
603 660
@@ -605,7 +662,8 @@ static int dw_i2s_remove(struct platform_device *pdev)
605{ 662{
606 struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); 663 struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
607 664
608 clk_disable_unprepare(dev->clk); 665 if (dev->capability & DW_I2S_MASTER)
666 clk_disable_unprepare(dev->clk);
609 667
610 return 0; 668 return 0;
611} 669}
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 5aeb6ed4827e..1b05d1c5d9fd 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -14,6 +14,9 @@
14#include <linux/i2c.h> 14#include <linux/i2c.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/of_platform.h> 16#include <linux/of_platform.h>
17#if IS_ENABLED(CONFIG_SND_AC97_CODEC)
18#include <sound/ac97_codec.h>
19#endif
17#include <sound/pcm_params.h> 20#include <sound/pcm_params.h>
18#include <sound/soc.h> 21#include <sound/soc.h>
19 22
@@ -115,6 +118,11 @@ static const struct snd_soc_dapm_widget fsl_asoc_card_dapm_widgets[] = {
115 SND_SOC_DAPM_MIC("DMIC", NULL), 118 SND_SOC_DAPM_MIC("DMIC", NULL),
116}; 119};
117 120
121static bool fsl_asoc_card_is_ac97(struct fsl_asoc_card_priv *priv)
122{
123 return priv->dai_fmt == SND_SOC_DAIFMT_AC97;
124}
125
118static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream, 126static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
119 struct snd_pcm_hw_params *params) 127 struct snd_pcm_hw_params *params)
120{ 128{
@@ -133,7 +141,9 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
133 * set_bias_level(), bypass the remaining settings in hw_params(). 141 * set_bias_level(), bypass the remaining settings in hw_params().
134 * Note: (dai_fmt & CBM_CFM) includes CBM_CFM and CBM_CFS. 142 * Note: (dai_fmt & CBM_CFM) includes CBM_CFM and CBM_CFS.
135 */ 143 */
136 if (priv->card.set_bias_level && priv->dai_fmt & SND_SOC_DAIFMT_CBM_CFM) 144 if ((priv->card.set_bias_level &&
145 priv->dai_fmt & SND_SOC_DAIFMT_CBM_CFM) ||
146 fsl_asoc_card_is_ac97(priv))
137 return 0; 147 return 0;
138 148
139 /* Specific configurations of DAIs starts from here */ 149 /* Specific configurations of DAIs starts from here */
@@ -300,7 +310,7 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
300 ext_port--; 310 ext_port--;
301 311
302 /* 312 /*
303 * Use asynchronous mode (6 wires) for all cases. 313 * Use asynchronous mode (6 wires) for all cases except AC97.
304 * If only 4 wires are needed, just set SSI into 314 * If only 4 wires are needed, just set SSI into
305 * synchronous mode and enable 4 PADs in IOMUX. 315 * synchronous mode and enable 4 PADs in IOMUX.
306 */ 316 */
@@ -346,15 +356,30 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
346 IMX_AUDMUX_V2_PTCR_TCLKDIR; 356 IMX_AUDMUX_V2_PTCR_TCLKDIR;
347 break; 357 break;
348 default: 358 default:
349 return -EINVAL; 359 if (!fsl_asoc_card_is_ac97(priv))
360 return -EINVAL;
361 }
362
363 if (fsl_asoc_card_is_ac97(priv)) {
364 int_ptcr = IMX_AUDMUX_V2_PTCR_SYN |
365 IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) |
366 IMX_AUDMUX_V2_PTCR_TCLKDIR;
367 ext_ptcr = IMX_AUDMUX_V2_PTCR_SYN |
368 IMX_AUDMUX_V2_PTCR_TFSEL(int_port) |
369 IMX_AUDMUX_V2_PTCR_TFSDIR;
350 } 370 }
351 371
352 /* Asynchronous mode can not be set along with RCLKDIR */ 372 /* Asynchronous mode can not be set along with RCLKDIR */
353 ret = imx_audmux_v2_configure_port(int_port, 0, 373 if (!fsl_asoc_card_is_ac97(priv)) {
354 IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port)); 374 unsigned int pdcr =
355 if (ret) { 375 IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port);
356 dev_err(dev, "audmux internal port setup failed\n"); 376
357 return ret; 377 ret = imx_audmux_v2_configure_port(int_port, 0,
378 pdcr);
379 if (ret) {
380 dev_err(dev, "audmux internal port setup failed\n");
381 return ret;
382 }
358 } 383 }
359 384
360 ret = imx_audmux_v2_configure_port(int_port, int_ptcr, 385 ret = imx_audmux_v2_configure_port(int_port, int_ptcr,
@@ -364,11 +389,16 @@ static int fsl_asoc_card_audmux_init(struct device_node *np,
364 return ret; 389 return ret;
365 } 390 }
366 391
367 ret = imx_audmux_v2_configure_port(ext_port, 0, 392 if (!fsl_asoc_card_is_ac97(priv)) {
368 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)); 393 unsigned int pdcr =
369 if (ret) { 394 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port);
370 dev_err(dev, "audmux external port setup failed\n"); 395
371 return ret; 396 ret = imx_audmux_v2_configure_port(ext_port, 0,
397 pdcr);
398 if (ret) {
399 dev_err(dev, "audmux external port setup failed\n");
400 return ret;
401 }
372 } 402 }
373 403
374 ret = imx_audmux_v2_configure_port(ext_port, ext_ptcr, 404 ret = imx_audmux_v2_configure_port(ext_port, ext_ptcr,
@@ -389,6 +419,23 @@ static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
389 struct device *dev = card->dev; 419 struct device *dev = card->dev;
390 int ret; 420 int ret;
391 421
422 if (fsl_asoc_card_is_ac97(priv)) {
423#if IS_ENABLED(CONFIG_SND_AC97_CODEC)
424 struct snd_soc_codec *codec = card->rtd[0].codec;
425 struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec);
426
427 /*
428 * Use slots 3/4 for S/PDIF so SSI won't try to enable
429 * other slots and send some samples there
430 * due to SLOTREQ bits for S/PDIF received from codec
431 */
432 snd_ac97_update_bits(ac97, AC97_EXTENDED_STATUS,
433 AC97_EA_SPSA_SLOT_MASK, AC97_EA_SPSA_3_4);
434#endif
435
436 return 0;
437 }
438
392 ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id, 439 ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id,
393 codec_priv->mclk_freq, SND_SOC_CLOCK_IN); 440 codec_priv->mclk_freq, SND_SOC_CLOCK_IN);
394 if (ret) { 441 if (ret) {
@@ -407,7 +454,6 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
407 struct platform_device *cpu_pdev; 454 struct platform_device *cpu_pdev;
408 struct fsl_asoc_card_priv *priv; 455 struct fsl_asoc_card_priv *priv;
409 struct i2c_client *codec_dev; 456 struct i2c_client *codec_dev;
410 struct clk *codec_clk;
411 const char *codec_dai_name; 457 const char *codec_dai_name;
412 u32 width; 458 u32 width;
413 int ret; 459 int ret;
@@ -420,9 +466,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
420 /* Give a chance to old DT binding */ 466 /* Give a chance to old DT binding */
421 if (!cpu_np) 467 if (!cpu_np)
422 cpu_np = of_parse_phandle(np, "ssi-controller", 0); 468 cpu_np = of_parse_phandle(np, "ssi-controller", 0);
423 codec_np = of_parse_phandle(np, "audio-codec", 0); 469 if (!cpu_np) {
424 if (!cpu_np || !codec_np) { 470 dev_err(&pdev->dev, "CPU phandle missing or invalid\n");
425 dev_err(&pdev->dev, "phandle missing or invalid\n");
426 ret = -EINVAL; 471 ret = -EINVAL;
427 goto fail; 472 goto fail;
428 } 473 }
@@ -434,22 +479,24 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
434 goto fail; 479 goto fail;
435 } 480 }
436 481
437 codec_dev = of_find_i2c_device_by_node(codec_np); 482 codec_np = of_parse_phandle(np, "audio-codec", 0);
438 if (!codec_dev) { 483 if (codec_np)
439 dev_err(&pdev->dev, "failed to find codec platform device\n"); 484 codec_dev = of_find_i2c_device_by_node(codec_np);
440 ret = -EINVAL; 485 else
441 goto fail; 486 codec_dev = NULL;
442 }
443 487
444 asrc_np = of_parse_phandle(np, "audio-asrc", 0); 488 asrc_np = of_parse_phandle(np, "audio-asrc", 0);
445 if (asrc_np) 489 if (asrc_np)
446 asrc_pdev = of_find_device_by_node(asrc_np); 490 asrc_pdev = of_find_device_by_node(asrc_np);
447 491
448 /* Get the MCLK rate only, and leave it controlled by CODEC drivers */ 492 /* Get the MCLK rate only, and leave it controlled by CODEC drivers */
449 codec_clk = clk_get(&codec_dev->dev, NULL); 493 if (codec_dev) {
450 if (!IS_ERR(codec_clk)) { 494 struct clk *codec_clk = clk_get(&codec_dev->dev, NULL);
451 priv->codec_priv.mclk_freq = clk_get_rate(codec_clk); 495
452 clk_put(codec_clk); 496 if (!IS_ERR(codec_clk)) {
497 priv->codec_priv.mclk_freq = clk_get_rate(codec_clk);
498 clk_put(codec_clk);
499 }
453 } 500 }
454 501
455 /* Default sample rate and format, will be updated in hw_params() */ 502 /* Default sample rate and format, will be updated in hw_params() */
@@ -486,9 +533,20 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
486 priv->codec_priv.fll_id = WM8960_SYSCLK_AUTO; 533 priv->codec_priv.fll_id = WM8960_SYSCLK_AUTO;
487 priv->codec_priv.pll_id = WM8960_SYSCLK_AUTO; 534 priv->codec_priv.pll_id = WM8960_SYSCLK_AUTO;
488 priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; 535 priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
536 } else if (of_device_is_compatible(np, "fsl,imx-audio-ac97")) {
537 codec_dai_name = "ac97-hifi";
538 priv->card.set_bias_level = NULL;
539 priv->dai_fmt = SND_SOC_DAIFMT_AC97;
489 } else { 540 } else {
490 dev_err(&pdev->dev, "unknown Device Tree compatible\n"); 541 dev_err(&pdev->dev, "unknown Device Tree compatible\n");
491 return -EINVAL; 542 ret = -EINVAL;
543 goto asrc_fail;
544 }
545
546 if (!fsl_asoc_card_is_ac97(priv) && !codec_dev) {
547 dev_err(&pdev->dev, "failed to find codec device\n");
548 ret = -EINVAL;
549 goto asrc_fail;
492 } 550 }
493 551
494 /* Common settings for corresponding Freescale CPU DAI driver */ 552 /* Common settings for corresponding Freescale CPU DAI driver */
@@ -507,7 +565,9 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
507 priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1; 565 priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
508 } 566 }
509 567
510 sprintf(priv->name, "%s-audio", codec_dev->name); 568 snprintf(priv->name, sizeof(priv->name), "%s-audio",
569 fsl_asoc_card_is_ac97(priv) ? "ac97" :
570 codec_dev->name);
511 571
512 /* Initialize sound card */ 572 /* Initialize sound card */
513 priv->pdev = pdev; 573 priv->pdev = pdev;
@@ -531,8 +591,26 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
531 591
532 /* Normal DAI Link */ 592 /* Normal DAI Link */
533 priv->dai_link[0].cpu_of_node = cpu_np; 593 priv->dai_link[0].cpu_of_node = cpu_np;
534 priv->dai_link[0].codec_of_node = codec_np;
535 priv->dai_link[0].codec_dai_name = codec_dai_name; 594 priv->dai_link[0].codec_dai_name = codec_dai_name;
595
596 if (!fsl_asoc_card_is_ac97(priv))
597 priv->dai_link[0].codec_of_node = codec_np;
598 else {
599 u32 idx;
600
601 ret = of_property_read_u32(cpu_np, "cell-index", &idx);
602 if (ret) {
603 dev_err(&pdev->dev,
604 "cannot get CPU index property\n");
605 goto asrc_fail;
606 }
607
608 priv->dai_link[0].codec_name =
609 devm_kasprintf(&pdev->dev, GFP_KERNEL,
610 "ac97-codec.%u",
611 (unsigned int)idx);
612 }
613
536 priv->dai_link[0].platform_of_node = cpu_np; 614 priv->dai_link[0].platform_of_node = cpu_np;
537 priv->dai_link[0].dai_fmt = priv->dai_fmt; 615 priv->dai_link[0].dai_fmt = priv->dai_fmt;
538 priv->card.num_links = 1; 616 priv->card.num_links = 1;
@@ -543,6 +621,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
543 priv->dai_link[1].platform_of_node = asrc_np; 621 priv->dai_link[1].platform_of_node = asrc_np;
544 priv->dai_link[2].codec_dai_name = codec_dai_name; 622 priv->dai_link[2].codec_dai_name = codec_dai_name;
545 priv->dai_link[2].codec_of_node = codec_np; 623 priv->dai_link[2].codec_of_node = codec_np;
624 priv->dai_link[2].codec_name =
625 priv->dai_link[0].codec_name;
546 priv->dai_link[2].cpu_of_node = cpu_np; 626 priv->dai_link[2].cpu_of_node = cpu_np;
547 priv->dai_link[2].dai_fmt = priv->dai_fmt; 627 priv->dai_link[2].dai_fmt = priv->dai_fmt;
548 priv->card.num_links = 3; 628 priv->card.num_links = 3;
@@ -578,20 +658,22 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
578 658
579asrc_fail: 659asrc_fail:
580 of_node_put(asrc_np); 660 of_node_put(asrc_np);
581fail:
582 of_node_put(codec_np); 661 of_node_put(codec_np);
662fail:
583 of_node_put(cpu_np); 663 of_node_put(cpu_np);
584 664
585 return ret; 665 return ret;
586} 666}
587 667
588static const struct of_device_id fsl_asoc_card_dt_ids[] = { 668static const struct of_device_id fsl_asoc_card_dt_ids[] = {
669 { .compatible = "fsl,imx-audio-ac97", },
589 { .compatible = "fsl,imx-audio-cs42888", }, 670 { .compatible = "fsl,imx-audio-cs42888", },
590 { .compatible = "fsl,imx-audio-sgtl5000", }, 671 { .compatible = "fsl,imx-audio-sgtl5000", },
591 { .compatible = "fsl,imx-audio-wm8962", }, 672 { .compatible = "fsl,imx-audio-wm8962", },
592 { .compatible = "fsl,imx-audio-wm8960", }, 673 { .compatible = "fsl,imx-audio-wm8960", },
593 {} 674 {}
594}; 675};
676MODULE_DEVICE_TABLE(of, fsl_asoc_card_dt_ids);
595 677
596static struct platform_driver fsl_asoc_card_driver = { 678static struct platform_driver fsl_asoc_card_driver = {
597 .probe = fsl_asoc_card_probe, 679 .probe = fsl_asoc_card_probe,
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 837979ea5c92..59f234e51971 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -652,6 +652,24 @@ static const struct snd_soc_component_driver fsl_esai_component = {
652 .name = "fsl-esai", 652 .name = "fsl-esai",
653}; 653};
654 654
655static const struct reg_default fsl_esai_reg_defaults[] = {
656 {0x8, 0x00000000},
657 {0x10, 0x00000000},
658 {0x18, 0x00000000},
659 {0x98, 0x00000000},
660 {0xd0, 0x00000000},
661 {0xd4, 0x00000000},
662 {0xd8, 0x00000000},
663 {0xdc, 0x00000000},
664 {0xe0, 0x00000000},
665 {0xe4, 0x0000ffff},
666 {0xe8, 0x0000ffff},
667 {0xec, 0x0000ffff},
668 {0xf0, 0x0000ffff},
669 {0xf8, 0x00000000},
670 {0xfc, 0x00000000},
671};
672
655static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg) 673static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
656{ 674{
657 switch (reg) { 675 switch (reg) {
@@ -684,6 +702,31 @@ static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
684 } 702 }
685} 703}
686 704
705static bool fsl_esai_volatile_reg(struct device *dev, unsigned int reg)
706{
707 switch (reg) {
708 case REG_ESAI_ETDR:
709 case REG_ESAI_ERDR:
710 case REG_ESAI_ESR:
711 case REG_ESAI_TFSR:
712 case REG_ESAI_RFSR:
713 case REG_ESAI_TX0:
714 case REG_ESAI_TX1:
715 case REG_ESAI_TX2:
716 case REG_ESAI_TX3:
717 case REG_ESAI_TX4:
718 case REG_ESAI_TX5:
719 case REG_ESAI_RX0:
720 case REG_ESAI_RX1:
721 case REG_ESAI_RX2:
722 case REG_ESAI_RX3:
723 case REG_ESAI_SAISR:
724 return true;
725 default:
726 return false;
727 }
728}
729
687static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg) 730static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg)
688{ 731{
689 switch (reg) { 732 switch (reg) {
@@ -721,8 +764,12 @@ static const struct regmap_config fsl_esai_regmap_config = {
721 .val_bits = 32, 764 .val_bits = 32,
722 765
723 .max_register = REG_ESAI_PCRC, 766 .max_register = REG_ESAI_PCRC,
767 .reg_defaults = fsl_esai_reg_defaults,
768 .num_reg_defaults = ARRAY_SIZE(fsl_esai_reg_defaults),
724 .readable_reg = fsl_esai_readable_reg, 769 .readable_reg = fsl_esai_readable_reg,
770 .volatile_reg = fsl_esai_volatile_reg,
725 .writeable_reg = fsl_esai_writeable_reg, 771 .writeable_reg = fsl_esai_writeable_reg,
772 .cache_type = REGCACHE_RBTREE,
726}; 773};
727 774
728static int fsl_esai_probe(struct platform_device *pdev) 775static int fsl_esai_probe(struct platform_device *pdev)
@@ -853,10 +900,51 @@ static const struct of_device_id fsl_esai_dt_ids[] = {
853}; 900};
854MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids); 901MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
855 902
903#ifdef CONFIG_PM_SLEEP
904static int fsl_esai_suspend(struct device *dev)
905{
906 struct fsl_esai *esai = dev_get_drvdata(dev);
907
908 regcache_cache_only(esai->regmap, true);
909 regcache_mark_dirty(esai->regmap);
910
911 return 0;
912}
913
914static int fsl_esai_resume(struct device *dev)
915{
916 struct fsl_esai *esai = dev_get_drvdata(dev);
917 int ret;
918
919 regcache_cache_only(esai->regmap, false);
920
921 /* FIFO reset for safety */
922 regmap_update_bits(esai->regmap, REG_ESAI_TFCR,
923 ESAI_xFCR_xFR, ESAI_xFCR_xFR);
924 regmap_update_bits(esai->regmap, REG_ESAI_RFCR,
925 ESAI_xFCR_xFR, ESAI_xFCR_xFR);
926
927 ret = regcache_sync(esai->regmap);
928 if (ret)
929 return ret;
930
931 /* FIFO reset done */
932 regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0);
933 regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0);
934
935 return 0;
936}
937#endif /* CONFIG_PM_SLEEP */
938
939static const struct dev_pm_ops fsl_esai_pm_ops = {
940 SET_SYSTEM_SLEEP_PM_OPS(fsl_esai_suspend, fsl_esai_resume)
941};
942
856static struct platform_driver fsl_esai_driver = { 943static struct platform_driver fsl_esai_driver = {
857 .probe = fsl_esai_probe, 944 .probe = fsl_esai_probe,
858 .driver = { 945 .driver = {
859 .name = "fsl-esai-dai", 946 .name = "fsl-esai-dai",
947 .pm = &fsl_esai_pm_ops,
860 .of_match_table = fsl_esai_dt_ids, 948 .of_match_table = fsl_esai_dt_ids,
861 }, 949 },
862}; 950};
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index a18fd92c4a85..a4435f5e3be9 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -27,13 +27,13 @@
27#define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\ 27#define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\
28 FSL_SAI_CSR_FEIE) 28 FSL_SAI_CSR_FEIE)
29 29
30static u32 fsl_sai_rates[] = { 30static const unsigned int fsl_sai_rates[] = {
31 8000, 11025, 12000, 16000, 22050, 31 8000, 11025, 12000, 16000, 22050,
32 24000, 32000, 44100, 48000, 64000, 32 24000, 32000, 44100, 48000, 64000,
33 88200, 96000, 176400, 192000 33 88200, 96000, 176400, 192000
34}; 34};
35 35
36static struct snd_pcm_hw_constraint_list fsl_sai_rate_constraints = { 36static const struct snd_pcm_hw_constraint_list fsl_sai_rate_constraints = {
37 .count = ARRAY_SIZE(fsl_sai_rates), 37 .count = ARRAY_SIZE(fsl_sai_rates),
38 .list = fsl_sai_rates, 38 .list = fsl_sai_rates,
39}; 39};
@@ -637,6 +637,8 @@ static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
637static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg) 637static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
638{ 638{
639 switch (reg) { 639 switch (reg) {
640 case FSL_SAI_TCSR:
641 case FSL_SAI_RCSR:
640 case FSL_SAI_TFR: 642 case FSL_SAI_TFR:
641 case FSL_SAI_RFR: 643 case FSL_SAI_RFR:
642 case FSL_SAI_TDR: 644 case FSL_SAI_TDR:
@@ -681,6 +683,7 @@ static const struct regmap_config fsl_sai_regmap_config = {
681 .readable_reg = fsl_sai_readable_reg, 683 .readable_reg = fsl_sai_readable_reg,
682 .volatile_reg = fsl_sai_volatile_reg, 684 .volatile_reg = fsl_sai_volatile_reg,
683 .writeable_reg = fsl_sai_writeable_reg, 685 .writeable_reg = fsl_sai_writeable_reg,
686 .cache_type = REGCACHE_FLAT,
684}; 687};
685 688
686static int fsl_sai_probe(struct platform_device *pdev) 689static int fsl_sai_probe(struct platform_device *pdev)
@@ -801,11 +804,42 @@ static const struct of_device_id fsl_sai_ids[] = {
801 { .compatible = "fsl,imx6sx-sai", }, 804 { .compatible = "fsl,imx6sx-sai", },
802 { /* sentinel */ } 805 { /* sentinel */ }
803}; 806};
807MODULE_DEVICE_TABLE(of, fsl_sai_ids);
808
809#ifdef CONFIG_PM_SLEEP
810static int fsl_sai_suspend(struct device *dev)
811{
812 struct fsl_sai *sai = dev_get_drvdata(dev);
813
814 regcache_cache_only(sai->regmap, true);
815 regcache_mark_dirty(sai->regmap);
816
817 return 0;
818}
819
820static int fsl_sai_resume(struct device *dev)
821{
822 struct fsl_sai *sai = dev_get_drvdata(dev);
823
824 regcache_cache_only(sai->regmap, false);
825 regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
826 regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR);
827 msleep(1);
828 regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
829 regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
830 return regcache_sync(sai->regmap);
831}
832#endif /* CONFIG_PM_SLEEP */
833
834static const struct dev_pm_ops fsl_sai_pm_ops = {
835 SET_SYSTEM_SLEEP_PM_OPS(fsl_sai_suspend, fsl_sai_resume)
836};
804 837
805static struct platform_driver fsl_sai_driver = { 838static struct platform_driver fsl_sai_driver = {
806 .probe = fsl_sai_probe, 839 .probe = fsl_sai_probe,
807 .driver = { 840 .driver = {
808 .name = "fsl-sai", 841 .name = "fsl-sai",
842 .pm = &fsl_sai_pm_ops,
809 .of_match_table = fsl_sai_ids, 843 .of_match_table = fsl_sai_ids,
810 }, 844 },
811}; 845};
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index ab729f2426fe..3d59bb6719f2 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -108,6 +108,8 @@ struct fsl_spdif_priv {
108 struct clk *sysclk; 108 struct clk *sysclk;
109 struct snd_dmaengine_dai_dma_data dma_params_tx; 109 struct snd_dmaengine_dai_dma_data dma_params_tx;
110 struct snd_dmaengine_dai_dma_data dma_params_rx; 110 struct snd_dmaengine_dai_dma_data dma_params_rx;
111 /* regcache for SRPC */
112 u32 regcache_srpc;
111}; 113};
112 114
113/* DPLL locked and lock loss interrupt handler */ 115/* DPLL locked and lock loss interrupt handler */
@@ -300,6 +302,8 @@ static int spdif_softreset(struct fsl_spdif_priv *spdif_priv)
300 struct regmap *regmap = spdif_priv->regmap; 302 struct regmap *regmap = spdif_priv->regmap;
301 u32 val, cycle = 1000; 303 u32 val, cycle = 1000;
302 304
305 regcache_cache_bypass(regmap, true);
306
303 regmap_write(regmap, REG_SPDIF_SCR, SCR_SOFT_RESET); 307 regmap_write(regmap, REG_SPDIF_SCR, SCR_SOFT_RESET);
304 308
305 /* 309 /*
@@ -310,6 +314,10 @@ static int spdif_softreset(struct fsl_spdif_priv *spdif_priv)
310 regmap_read(regmap, REG_SPDIF_SCR, &val); 314 regmap_read(regmap, REG_SPDIF_SCR, &val);
311 } while ((val & SCR_SOFT_RESET) && cycle--); 315 } while ((val & SCR_SOFT_RESET) && cycle--);
312 316
317 regcache_cache_bypass(regmap, false);
318 regcache_mark_dirty(regmap);
319 regcache_sync(regmap);
320
313 if (cycle) 321 if (cycle)
314 return 0; 322 return 0;
315 else 323 else
@@ -997,6 +1005,14 @@ static const struct snd_soc_component_driver fsl_spdif_component = {
997}; 1005};
998 1006
999/* FSL SPDIF REGMAP */ 1007/* FSL SPDIF REGMAP */
1008static const struct reg_default fsl_spdif_reg_defaults[] = {
1009 {0x0, 0x00000400},
1010 {0x4, 0x00000000},
1011 {0xc, 0x00000000},
1012 {0x34, 0x00000000},
1013 {0x38, 0x00000000},
1014 {0x50, 0x00020f00},
1015};
1000 1016
1001static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) 1017static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg)
1002{ 1018{
@@ -1022,6 +1038,26 @@ static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg)
1022 } 1038 }
1023} 1039}
1024 1040
1041static bool fsl_spdif_volatile_reg(struct device *dev, unsigned int reg)
1042{
1043 switch (reg) {
1044 case REG_SPDIF_SRPC:
1045 case REG_SPDIF_SIS:
1046 case REG_SPDIF_SRL:
1047 case REG_SPDIF_SRR:
1048 case REG_SPDIF_SRCSH:
1049 case REG_SPDIF_SRCSL:
1050 case REG_SPDIF_SRU:
1051 case REG_SPDIF_SRQ:
1052 case REG_SPDIF_STL:
1053 case REG_SPDIF_STR:
1054 case REG_SPDIF_SRFM:
1055 return true;
1056 default:
1057 return false;
1058 }
1059}
1060
1025static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg) 1061static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg)
1026{ 1062{
1027 switch (reg) { 1063 switch (reg) {
@@ -1047,8 +1083,12 @@ static const struct regmap_config fsl_spdif_regmap_config = {
1047 .val_bits = 32, 1083 .val_bits = 32,
1048 1084
1049 .max_register = REG_SPDIF_STC, 1085 .max_register = REG_SPDIF_STC,
1086 .reg_defaults = fsl_spdif_reg_defaults,
1087 .num_reg_defaults = ARRAY_SIZE(fsl_spdif_reg_defaults),
1050 .readable_reg = fsl_spdif_readable_reg, 1088 .readable_reg = fsl_spdif_readable_reg,
1089 .volatile_reg = fsl_spdif_volatile_reg,
1051 .writeable_reg = fsl_spdif_writeable_reg, 1090 .writeable_reg = fsl_spdif_writeable_reg,
1091 .cache_type = REGCACHE_RBTREE,
1052}; 1092};
1053 1093
1054static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, 1094static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
@@ -1271,6 +1311,38 @@ static int fsl_spdif_probe(struct platform_device *pdev)
1271 return ret; 1311 return ret;
1272} 1312}
1273 1313
1314#ifdef CONFIG_PM_SLEEP
1315static int fsl_spdif_suspend(struct device *dev)
1316{
1317 struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev);
1318
1319 regmap_read(spdif_priv->regmap, REG_SPDIF_SRPC,
1320 &spdif_priv->regcache_srpc);
1321
1322 regcache_cache_only(spdif_priv->regmap, true);
1323 regcache_mark_dirty(spdif_priv->regmap);
1324
1325 return 0;
1326}
1327
1328static int fsl_spdif_resume(struct device *dev)
1329{
1330 struct fsl_spdif_priv *spdif_priv = dev_get_drvdata(dev);
1331
1332 regcache_cache_only(spdif_priv->regmap, false);
1333
1334 regmap_update_bits(spdif_priv->regmap, REG_SPDIF_SRPC,
1335 SRPC_CLKSRC_SEL_MASK | SRPC_GAINSEL_MASK,
1336 spdif_priv->regcache_srpc);
1337
1338 return regcache_sync(spdif_priv->regmap);
1339}
1340#endif /* CONFIG_PM_SLEEP */
1341
1342static const struct dev_pm_ops fsl_spdif_pm = {
1343 SET_SYSTEM_SLEEP_PM_OPS(fsl_spdif_suspend, fsl_spdif_resume)
1344};
1345
1274static const struct of_device_id fsl_spdif_dt_ids[] = { 1346static const struct of_device_id fsl_spdif_dt_ids[] = {
1275 { .compatible = "fsl,imx35-spdif", }, 1347 { .compatible = "fsl,imx35-spdif", },
1276 { .compatible = "fsl,vf610-spdif", }, 1348 { .compatible = "fsl,vf610-spdif", },
@@ -1282,6 +1354,7 @@ static struct platform_driver fsl_spdif_driver = {
1282 .driver = { 1354 .driver = {
1283 .name = "fsl-spdif-dai", 1355 .name = "fsl-spdif-dai",
1284 .of_match_table = fsl_spdif_dt_ids, 1356 .of_match_table = fsl_spdif_dt_ids,
1357 .pm = &fsl_spdif_pm,
1285 }, 1358 },
1286 .probe = fsl_spdif_probe, 1359 .probe = fsl_spdif_probe,
1287}; 1360};
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 8ec6fb208ea0..95d2392303eb 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -111,12 +111,75 @@ struct fsl_ssi_rxtx_reg_val {
111 struct fsl_ssi_reg_val rx; 111 struct fsl_ssi_reg_val rx;
112 struct fsl_ssi_reg_val tx; 112 struct fsl_ssi_reg_val tx;
113}; 113};
114
115static const struct reg_default fsl_ssi_reg_defaults[] = {
116 {0x10, 0x00000000},
117 {0x18, 0x00003003},
118 {0x1c, 0x00000200},
119 {0x20, 0x00000200},
120 {0x24, 0x00040000},
121 {0x28, 0x00040000},
122 {0x38, 0x00000000},
123 {0x48, 0x00000000},
124 {0x4c, 0x00000000},
125 {0x54, 0x00000000},
126 {0x58, 0x00000000},
127};
128
129static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg)
130{
131 switch (reg) {
132 case CCSR_SSI_SACCEN:
133 case CCSR_SSI_SACCDIS:
134 return false;
135 default:
136 return true;
137 }
138}
139
140static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg)
141{
142 switch (reg) {
143 case CCSR_SSI_STX0:
144 case CCSR_SSI_STX1:
145 case CCSR_SSI_SRX0:
146 case CCSR_SSI_SRX1:
147 case CCSR_SSI_SISR:
148 case CCSR_SSI_SFCSR:
149 case CCSR_SSI_SACADD:
150 case CCSR_SSI_SACDAT:
151 case CCSR_SSI_SATAG:
152 case CCSR_SSI_SACCST:
153 return true;
154 default:
155 return false;
156 }
157}
158
159static bool fsl_ssi_writeable_reg(struct device *dev, unsigned int reg)
160{
161 switch (reg) {
162 case CCSR_SSI_SRX0:
163 case CCSR_SSI_SRX1:
164 case CCSR_SSI_SACCST:
165 return false;
166 default:
167 return true;
168 }
169}
170
114static const struct regmap_config fsl_ssi_regconfig = { 171static const struct regmap_config fsl_ssi_regconfig = {
115 .max_register = CCSR_SSI_SACCDIS, 172 .max_register = CCSR_SSI_SACCDIS,
116 .reg_bits = 32, 173 .reg_bits = 32,
117 .val_bits = 32, 174 .val_bits = 32,
118 .reg_stride = 4, 175 .reg_stride = 4,
119 .val_format_endian = REGMAP_ENDIAN_NATIVE, 176 .val_format_endian = REGMAP_ENDIAN_NATIVE,
177 .reg_defaults = fsl_ssi_reg_defaults,
178 .num_reg_defaults = ARRAY_SIZE(fsl_ssi_reg_defaults),
179 .readable_reg = fsl_ssi_readable_reg,
180 .volatile_reg = fsl_ssi_volatile_reg,
181 .writeable_reg = fsl_ssi_writeable_reg,
182 .cache_type = REGCACHE_RBTREE,
120}; 183};
121 184
122struct fsl_ssi_soc_data { 185struct fsl_ssi_soc_data {
@@ -176,6 +239,9 @@ struct fsl_ssi_private {
176 unsigned int baudclk_streams; 239 unsigned int baudclk_streams;
177 unsigned int bitclk_freq; 240 unsigned int bitclk_freq;
178 241
242 /*regcache for SFCSR*/
243 u32 regcache_sfcsr;
244
179 /* DMA params */ 245 /* DMA params */
180 struct snd_dmaengine_dai_dma_data dma_params_tx; 246 struct snd_dmaengine_dai_dma_data dma_params_tx;
181 struct snd_dmaengine_dai_dma_data dma_params_rx; 247 struct snd_dmaengine_dai_dma_data dma_params_rx;
@@ -249,7 +315,8 @@ MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
249 315
250static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private) 316static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private)
251{ 317{
252 return !!(ssi_private->dai_fmt & SND_SOC_DAIFMT_AC97); 318 return (ssi_private->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) ==
319 SND_SOC_DAIFMT_AC97;
253} 320}
254 321
255static bool fsl_ssi_is_i2s_master(struct fsl_ssi_private *ssi_private) 322static bool fsl_ssi_is_i2s_master(struct fsl_ssi_private *ssi_private)
@@ -947,7 +1014,7 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
947 CCSR_SSI_SCR_TCH_EN); 1014 CCSR_SSI_SCR_TCH_EN);
948 } 1015 }
949 1016
950 if (fmt & SND_SOC_DAIFMT_AC97) 1017 if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_AC97)
951 fsl_ssi_setup_ac97(ssi_private); 1018 fsl_ssi_setup_ac97(ssi_private);
952 1019
953 return 0; 1020 return 0;
@@ -1513,10 +1580,46 @@ static int fsl_ssi_remove(struct platform_device *pdev)
1513 return 0; 1580 return 0;
1514} 1581}
1515 1582
1583#ifdef CONFIG_PM_SLEEP
1584static int fsl_ssi_suspend(struct device *dev)
1585{
1586 struct fsl_ssi_private *ssi_private = dev_get_drvdata(dev);
1587 struct regmap *regs = ssi_private->regs;
1588
1589 regmap_read(regs, CCSR_SSI_SFCSR,
1590 &ssi_private->regcache_sfcsr);
1591
1592 regcache_cache_only(regs, true);
1593 regcache_mark_dirty(regs);
1594
1595 return 0;
1596}
1597
1598static int fsl_ssi_resume(struct device *dev)
1599{
1600 struct fsl_ssi_private *ssi_private = dev_get_drvdata(dev);
1601 struct regmap *regs = ssi_private->regs;
1602
1603 regcache_cache_only(regs, false);
1604
1605 regmap_update_bits(regs, CCSR_SSI_SFCSR,
1606 CCSR_SSI_SFCSR_RFWM1_MASK | CCSR_SSI_SFCSR_TFWM1_MASK |
1607 CCSR_SSI_SFCSR_RFWM0_MASK | CCSR_SSI_SFCSR_TFWM0_MASK,
1608 ssi_private->regcache_sfcsr);
1609
1610 return regcache_sync(regs);
1611}
1612#endif /* CONFIG_PM_SLEEP */
1613
1614static const struct dev_pm_ops fsl_ssi_pm = {
1615 SET_SYSTEM_SLEEP_PM_OPS(fsl_ssi_suspend, fsl_ssi_resume)
1616};
1617
1516static struct platform_driver fsl_ssi_driver = { 1618static struct platform_driver fsl_ssi_driver = {
1517 .driver = { 1619 .driver = {
1518 .name = "fsl-ssi-dai", 1620 .name = "fsl-ssi-dai",
1519 .of_match_table = fsl_ssi_ids, 1621 .of_match_table = fsl_ssi_ids,
1622 .pm = &fsl_ssi_pm,
1520 }, 1623 },
1521 .probe = fsl_ssi_probe, 1624 .probe = fsl_ssi_probe,
1522 .remove = fsl_ssi_remove, 1625 .remove = fsl_ssi_remove,
diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c
index 33da26a12457..a407e833c612 100644
--- a/sound/soc/fsl/imx-spdif.c
+++ b/sound/soc/fsl/imx-spdif.c
@@ -89,6 +89,7 @@ MODULE_DEVICE_TABLE(of, imx_spdif_dt_ids);
89static struct platform_driver imx_spdif_driver = { 89static struct platform_driver imx_spdif_driver = {
90 .driver = { 90 .driver = {
91 .name = "imx-spdif", 91 .name = "imx-spdif",
92 .pm = &snd_soc_pm_ops,
92 .of_match_table = imx_spdif_dt_ids, 93 .of_match_table = imx_spdif_dt_ids,
93 }, 94 },
94 .probe = imx_spdif_audio_probe, 95 .probe = imx_spdif_audio_probe,
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index 48b2d24dd1f0..b95132e2f9dc 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -95,7 +95,8 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
95 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 95 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
96 case SND_SOC_DAIFMT_I2S: 96 case SND_SOC_DAIFMT_I2S:
97 /* data on rising edge of bclk, frame low 1clk before data */ 97 /* data on rising edge of bclk, frame low 1clk before data */
98 strcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0; 98 strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP | SSI_STCR_TFSI |
99 SSI_STCR_TEFS;
99 scr |= SSI_SCR_NET; 100 scr |= SSI_SCR_NET;
100 if (ssi->flags & IMX_SSI_USE_I2S_SLAVE) { 101 if (ssi->flags & IMX_SSI_USE_I2S_SLAVE) {
101 scr &= ~SSI_I2S_MODE_MASK; 102 scr &= ~SSI_I2S_MODE_MASK;
@@ -104,33 +105,31 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
104 break; 105 break;
105 case SND_SOC_DAIFMT_LEFT_J: 106 case SND_SOC_DAIFMT_LEFT_J:
106 /* data on rising edge of bclk, frame high with data */ 107 /* data on rising edge of bclk, frame high with data */
107 strcr |= SSI_STCR_TXBIT0; 108 strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP;
108 break; 109 break;
109 case SND_SOC_DAIFMT_DSP_B: 110 case SND_SOC_DAIFMT_DSP_B:
110 /* data on rising edge of bclk, frame high with data */ 111 /* data on rising edge of bclk, frame high with data */
111 strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0; 112 strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP | SSI_STCR_TFSL;
112 break; 113 break;
113 case SND_SOC_DAIFMT_DSP_A: 114 case SND_SOC_DAIFMT_DSP_A:
114 /* data on rising edge of bclk, frame high 1clk before data */ 115 /* data on rising edge of bclk, frame high 1clk before data */
115 strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0 | SSI_STCR_TEFS; 116 strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP | SSI_STCR_TFSL |
117 SSI_STCR_TEFS;
116 break; 118 break;
117 } 119 }
118 120
119 /* DAI clock inversion */ 121 /* DAI clock inversion */
120 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 122 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
121 case SND_SOC_DAIFMT_IB_IF: 123 case SND_SOC_DAIFMT_IB_IF:
122 strcr |= SSI_STCR_TFSI; 124 strcr ^= SSI_STCR_TSCKP | SSI_STCR_TFSI;
123 strcr &= ~SSI_STCR_TSCKP;
124 break; 125 break;
125 case SND_SOC_DAIFMT_IB_NF: 126 case SND_SOC_DAIFMT_IB_NF:
126 strcr &= ~(SSI_STCR_TSCKP | SSI_STCR_TFSI); 127 strcr ^= SSI_STCR_TSCKP;
127 break; 128 break;
128 case SND_SOC_DAIFMT_NB_IF: 129 case SND_SOC_DAIFMT_NB_IF:
129 strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP; 130 strcr ^= SSI_STCR_TFSI;
130 break; 131 break;
131 case SND_SOC_DAIFMT_NB_NF: 132 case SND_SOC_DAIFMT_NB_NF:
132 strcr &= ~SSI_STCR_TFSI;
133 strcr |= SSI_STCR_TSCKP;
134 break; 133 break;
135 } 134 }
136 135
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 3ff76d419436..54c33204541f 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -151,7 +151,9 @@ static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
151 } 151 }
152 152
153 if (set->slots) { 153 if (set->slots) {
154 ret = snd_soc_dai_set_tdm_slot(dai, 0, 0, 154 ret = snd_soc_dai_set_tdm_slot(dai,
155 set->tx_slot_mask,
156 set->rx_slot_mask,
155 set->slots, 157 set->slots,
156 set->slot_width); 158 set->slot_width);
157 if (ret && ret != -ENOTSUPP) { 159 if (ret && ret != -ENOTSUPP) {
@@ -243,7 +245,9 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
243 return ret; 245 return ret;
244 246
245 /* Parse TDM slot */ 247 /* Parse TDM slot */
246 ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width); 248 ret = snd_soc_of_parse_tdm_slot(np, &dai->tx_slot_mask,
249 &dai->rx_slot_mask,
250 &dai->slots, &dai->slot_width);
247 if (ret) 251 if (ret)
248 return ret; 252 return ret;
249 253
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index 05fde5e6e257..7b778ab85f8b 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -12,6 +12,7 @@ config SND_MFLD_MACHINE
12 12
13config SND_SST_MFLD_PLATFORM 13config SND_SST_MFLD_PLATFORM
14 tristate 14 tristate
15 select SND_SOC_COMPRESS
15 16
16config SND_SST_IPC 17config SND_SST_IPC
17 tristate 18 tristate
@@ -138,4 +139,18 @@ config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH
138config SND_SOC_INTEL_SKYLAKE 139config SND_SOC_INTEL_SKYLAKE
139 tristate 140 tristate
140 select SND_HDA_EXT_CORE 141 select SND_HDA_EXT_CORE
142 select SND_SOC_TOPOLOGY
141 select SND_SOC_INTEL_SST 143 select SND_SOC_INTEL_SST
144
145config SND_SOC_INTEL_SKL_RT286_MACH
146 tristate "ASoC Audio driver for SKL with RT286 I2S mode"
147 depends on X86 && ACPI
148 select SND_SOC_INTEL_SST
149 select SND_SOC_INTEL_SKYLAKE
150 select SND_SOC_RT286
151 select SND_SOC_DMIC
152 help
153 This adds support for ASoC machine driver for Skylake platforms
154 with RT286 I2S audio codec.
155 Say Y if you have such a device
156 If unsure select "N".
diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
index 683e50116152..0487cfaac538 100644
--- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
@@ -368,23 +368,6 @@ static void sst_media_close(struct snd_pcm_substream *substream,
368 kfree(stream); 368 kfree(stream);
369} 369}
370 370
371static inline unsigned int get_current_pipe_id(struct snd_soc_dai *dai,
372 struct snd_pcm_substream *substream)
373{
374 struct sst_data *sst = snd_soc_dai_get_drvdata(dai);
375 struct sst_dev_stream_map *map = sst->pdata->pdev_strm_map;
376 struct sst_runtime_stream *stream =
377 substream->runtime->private_data;
378 u32 str_id = stream->stream_info.str_id;
379 unsigned int pipe_id;
380
381 pipe_id = map[str_id].device_id;
382
383 dev_dbg(dai->dev, "got pipe_id = %#x for str_id = %d\n",
384 pipe_id, str_id);
385 return pipe_id;
386}
387
388static int sst_media_prepare(struct snd_pcm_substream *substream, 371static int sst_media_prepare(struct snd_pcm_substream *substream,
389 struct snd_soc_dai *dai) 372 struct snd_soc_dai *dai)
390{ 373{
@@ -529,7 +512,7 @@ static struct snd_soc_dai_driver sst_platform_dai[] = {
529}, 512},
530{ 513{
531 .name = "compress-cpu-dai", 514 .name = "compress-cpu-dai",
532 .compress_dai = 1, 515 .compress_new = snd_soc_new_compress,
533 .ops = &sst_compr_dai_ops, 516 .ops = &sst_compr_dai_ops,
534 .playback = { 517 .playback = {
535 .stream_name = "Compress Playback", 518 .stream_name = "Compress Playback",
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index cb94895c9edb..371c4565cad8 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -6,6 +6,7 @@ snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o
6snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o 6snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
7snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o 7snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o
8snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o 8snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o
9snd-soc-skl_rt286-objs := skl_rt286.o
9 10
10obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o 11obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
11obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o 12obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
@@ -15,3 +16,4 @@ obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o
15obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o 16obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
16obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o 17obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o
17obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o 18obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o
19obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o
diff --git a/sound/soc/intel/boards/broadwell.c b/sound/soc/intel/boards/broadwell.c
index 8bafaf6ceab1..3f8a1e10bed0 100644
--- a/sound/soc/intel/boards/broadwell.c
+++ b/sound/soc/intel/boards/broadwell.c
@@ -266,18 +266,11 @@ static int broadwell_audio_probe(struct platform_device *pdev)
266{ 266{
267 broadwell_rt286.dev = &pdev->dev; 267 broadwell_rt286.dev = &pdev->dev;
268 268
269 return snd_soc_register_card(&broadwell_rt286); 269 return devm_snd_soc_register_card(&pdev->dev, &broadwell_rt286);
270}
271
272static int broadwell_audio_remove(struct platform_device *pdev)
273{
274 snd_soc_unregister_card(&broadwell_rt286);
275 return 0;
276} 270}
277 271
278static struct platform_driver broadwell_audio = { 272static struct platform_driver broadwell_audio = {
279 .probe = broadwell_audio_probe, 273 .probe = broadwell_audio_probe,
280 .remove = broadwell_audio_remove,
281 .driver = { 274 .driver = {
282 .name = "broadwell-audio", 275 .name = "broadwell-audio",
283 }, 276 },
diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c
new file mode 100644
index 000000000000..a73a431bd8b7
--- /dev/null
+++ b/sound/soc/intel/boards/skl_rt286.c
@@ -0,0 +1,259 @@
1/*
2 * Intel Skylake I2S Machine Driver
3 *
4 * Copyright (C) 2014-2015, Intel Corporation. All rights reserved.
5 *
6 * Modified from:
7 * Intel Broadwell Wildcatpoint SST Audio
8 *
9 * Copyright (C) 2013, Intel Corporation. All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License version
13 * 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
20
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/soc.h>
26#include <sound/jack.h>
27#include <sound/pcm_params.h>
28#include "../../codecs/rt286.h"
29
30static struct snd_soc_jack skylake_headset;
31/* Headset jack detection DAPM pins */
32static struct snd_soc_jack_pin skylake_headset_pins[] = {
33 {
34 .pin = "Mic Jack",
35 .mask = SND_JACK_MICROPHONE,
36 },
37 {
38 .pin = "Headphone Jack",
39 .mask = SND_JACK_HEADPHONE,
40 },
41};
42
43static const struct snd_kcontrol_new skylake_controls[] = {
44 SOC_DAPM_PIN_SWITCH("Speaker"),
45 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
46 SOC_DAPM_PIN_SWITCH("Mic Jack"),
47};
48
49static const struct snd_soc_dapm_widget skylake_widgets[] = {
50 SND_SOC_DAPM_HP("Headphone Jack", NULL),
51 SND_SOC_DAPM_SPK("Speaker", NULL),
52 SND_SOC_DAPM_MIC("Mic Jack", NULL),
53 SND_SOC_DAPM_MIC("DMIC2", NULL),
54 SND_SOC_DAPM_MIC("SoC DMIC", NULL),
55};
56
57static const struct snd_soc_dapm_route skylake_rt286_map[] = {
58 /* speaker */
59 {"Speaker", NULL, "SPOR"},
60 {"Speaker", NULL, "SPOL"},
61
62 /* HP jack connectors - unknown if we have jack deteck */
63 {"Headphone Jack", NULL, "HPO Pin"},
64
65 /* other jacks */
66 {"MIC1", NULL, "Mic Jack"},
67
68 /* digital mics */
69 {"DMIC1 Pin", NULL, "DMIC2"},
70 {"DMIC AIF", NULL, "SoC DMIC"},
71
72 /* CODEC BE connections */
73 { "AIF1 Playback", NULL, "ssp0 Tx"},
74 { "ssp0 Tx", NULL, "codec0_out"},
75 { "ssp0 Tx", NULL, "codec1_out"},
76
77 { "codec0_in", NULL, "ssp0 Rx" },
78 { "codec1_in", NULL, "ssp0 Rx" },
79 { "ssp0 Rx", NULL, "AIF1 Capture" },
80
81 { "dmic01_hifi", NULL, "DMIC01 Rx" },
82 { "DMIC01 Rx", NULL, "Capture" },
83
84 { "hif1", NULL, "iDisp Tx"},
85 { "iDisp Tx", NULL, "iDisp_out"},
86
87};
88
89static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
90{
91 struct snd_soc_codec *codec = rtd->codec;
92 int ret;
93
94 ret = snd_soc_card_jack_new(rtd->card, "Headset",
95 SND_JACK_HEADSET | SND_JACK_BTN_0,
96 &skylake_headset,
97 skylake_headset_pins, ARRAY_SIZE(skylake_headset_pins));
98
99 if (ret)
100 return ret;
101
102 rt286_mic_detect(codec, &skylake_headset);
103
104 return 0;
105}
106
107
108static int skylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
109 struct snd_pcm_hw_params *params)
110{
111 struct snd_interval *rate = hw_param_interval(params,
112 SNDRV_PCM_HW_PARAM_RATE);
113 struct snd_interval *channels = hw_param_interval(params,
114 SNDRV_PCM_HW_PARAM_CHANNELS);
115
116 /* The output is 48KHz, stereo, 16bits */
117 rate->min = rate->max = 48000;
118 channels->min = channels->max = 2;
119 params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
120
121 return 0;
122}
123
124static int skylake_rt286_hw_params(struct snd_pcm_substream *substream,
125 struct snd_pcm_hw_params *params)
126{
127 struct snd_soc_pcm_runtime *rtd = substream->private_data;
128 struct snd_soc_dai *codec_dai = rtd->codec_dai;
129 int ret;
130
131 ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000,
132 SND_SOC_CLOCK_IN);
133 if (ret < 0)
134 dev_err(rtd->dev, "set codec sysclk failed: %d\n", ret);
135
136 return ret;
137}
138
139static struct snd_soc_ops skylake_rt286_ops = {
140 .hw_params = skylake_rt286_hw_params,
141};
142
143/* skylake digital audio interface glue - connects codec <--> CPU */
144static struct snd_soc_dai_link skylake_rt286_dais[] = {
145 /* Front End DAI links */
146 {
147 .name = "Skl Audio Port",
148 .stream_name = "Audio",
149 .cpu_dai_name = "System Pin",
150 .platform_name = "0000:00:1f.3",
151 .nonatomic = 1,
152 .dynamic = 1,
153 .codec_name = "snd-soc-dummy",
154 .codec_dai_name = "snd-soc-dummy-dai",
155 .trigger = {
156 SND_SOC_DPCM_TRIGGER_POST,
157 SND_SOC_DPCM_TRIGGER_POST
158 },
159 .dpcm_playback = 1,
160 },
161 {
162 .name = "Skl Audio Capture Port",
163 .stream_name = "Audio Record",
164 .cpu_dai_name = "System Pin",
165 .platform_name = "0000:00:1f.3",
166 .nonatomic = 1,
167 .dynamic = 1,
168 .codec_name = "snd-soc-dummy",
169 .codec_dai_name = "snd-soc-dummy-dai",
170 .trigger = {
171 SND_SOC_DPCM_TRIGGER_POST,
172 SND_SOC_DPCM_TRIGGER_POST
173 },
174 .dpcm_capture = 1,
175 },
176 {
177 .name = "Skl Audio Reference cap",
178 .stream_name = "refcap",
179 .cpu_dai_name = "Reference Pin",
180 .codec_name = "snd-soc-dummy",
181 .codec_dai_name = "snd-soc-dummy-dai",
182 .platform_name = "0000:00:1f.3",
183 .init = NULL,
184 .dpcm_capture = 1,
185 .ignore_suspend = 1,
186 .nonatomic = 1,
187 .dynamic = 1,
188 },
189
190 /* Back End DAI links */
191 {
192 /* SSP0 - Codec */
193 .name = "SSP0-Codec",
194 .be_id = 0,
195 .cpu_dai_name = "SSP0 Pin",
196 .platform_name = "0000:00:1f.3",
197 .no_pcm = 1,
198 .codec_name = "i2c-INT343A:00",
199 .codec_dai_name = "rt286-aif1",
200 .init = skylake_rt286_codec_init,
201 .dai_fmt = SND_SOC_DAIFMT_I2S |
202 SND_SOC_DAIFMT_NB_NF |
203 SND_SOC_DAIFMT_CBS_CFS,
204 .ignore_suspend = 1,
205 .ignore_pmdown_time = 1,
206 .be_hw_params_fixup = skylake_ssp0_fixup,
207 .ops = &skylake_rt286_ops,
208 .dpcm_playback = 1,
209 .dpcm_capture = 1,
210 },
211 {
212 .name = "dmic01",
213 .be_id = 1,
214 .cpu_dai_name = "DMIC01 Pin",
215 .codec_name = "dmic-codec",
216 .codec_dai_name = "dmic-hifi",
217 .platform_name = "0000:00:1f.3",
218 .ignore_suspend = 1,
219 .dpcm_capture = 1,
220 .no_pcm = 1,
221 },
222};
223
224/* skylake audio machine driver for SPT + RT286S */
225static struct snd_soc_card skylake_rt286 = {
226 .name = "skylake-rt286",
227 .owner = THIS_MODULE,
228 .dai_link = skylake_rt286_dais,
229 .num_links = ARRAY_SIZE(skylake_rt286_dais),
230 .controls = skylake_controls,
231 .num_controls = ARRAY_SIZE(skylake_controls),
232 .dapm_widgets = skylake_widgets,
233 .num_dapm_widgets = ARRAY_SIZE(skylake_widgets),
234 .dapm_routes = skylake_rt286_map,
235 .num_dapm_routes = ARRAY_SIZE(skylake_rt286_map),
236 .fully_routed = true,
237};
238
239static int skylake_audio_probe(struct platform_device *pdev)
240{
241 skylake_rt286.dev = &pdev->dev;
242
243 return devm_snd_soc_register_card(&pdev->dev, &skylake_rt286);
244}
245
246static struct platform_driver skylake_audio = {
247 .probe = skylake_audio_probe,
248 .driver = {
249 .name = "skl_alc286s_i2s",
250 },
251};
252
253module_platform_driver(skylake_audio)
254
255/* Module information */
256MODULE_AUTHOR("Omair Mohammed Abdullah <omair.m.abdullah@intel.com>");
257MODULE_DESCRIPTION("Intel SST Audio for Skylake");
258MODULE_LICENSE("GPL v2");
259MODULE_ALIAS("platform:skl_alc286s_i2s");
diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile
index f24154ca4e98..d9105584c51f 100644
--- a/sound/soc/intel/common/Makefile
+++ b/sound/soc/intel/common/Makefile
@@ -1,7 +1,11 @@
1snd-soc-sst-dsp-objs := sst-dsp.o sst-firmware.o 1snd-soc-sst-dsp-objs := sst-dsp.o
2snd-soc-sst-acpi-objs := sst-acpi.o 2snd-soc-sst-acpi-objs := sst-acpi.o
3snd-soc-sst-ipc-objs := sst-ipc.o 3snd-soc-sst-ipc-objs := sst-ipc.o
4 4
5ifneq ($(CONFIG_DW_DMAC_CORE),)
6snd-soc-sst-dsp-objs += sst-firmware.o
7endif
8
5obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o 9obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o
6obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o 10obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o
7 11
diff --git a/sound/soc/intel/common/sst-dsp-priv.h b/sound/soc/intel/common/sst-dsp-priv.h
index cbd568eac033..2151652d37b7 100644
--- a/sound/soc/intel/common/sst-dsp-priv.h
+++ b/sound/soc/intel/common/sst-dsp-priv.h
@@ -314,6 +314,7 @@ struct sst_dsp {
314 int sst_state; 314 int sst_state;
315 struct skl_cl_dev cl_dev; 315 struct skl_cl_dev cl_dev;
316 u32 intr_status; 316 u32 intr_status;
317 const struct firmware *fw;
317}; 318};
318 319
319/* Size optimised DRAM/IRAM memcpy */ 320/* Size optimised DRAM/IRAM memcpy */
diff --git a/sound/soc/intel/common/sst-dsp.c b/sound/soc/intel/common/sst-dsp.c
index a627236dd1f5..c9452e02e0dd 100644
--- a/sound/soc/intel/common/sst-dsp.c
+++ b/sound/soc/intel/common/sst-dsp.c
@@ -420,6 +420,7 @@ void sst_dsp_inbox_read(struct sst_dsp *sst, void *message, size_t bytes)
420} 420}
421EXPORT_SYMBOL_GPL(sst_dsp_inbox_read); 421EXPORT_SYMBOL_GPL(sst_dsp_inbox_read);
422 422
423#if IS_ENABLED(CONFIG_DW_DMAC_CORE)
423struct sst_dsp *sst_dsp_new(struct device *dev, 424struct sst_dsp *sst_dsp_new(struct device *dev,
424 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata) 425 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata)
425{ 426{
@@ -484,6 +485,7 @@ void sst_dsp_free(struct sst_dsp *sst)
484 sst_dma_free(sst->dma); 485 sst_dma_free(sst->dma);
485} 486}
486EXPORT_SYMBOL_GPL(sst_dsp_free); 487EXPORT_SYMBOL_GPL(sst_dsp_free);
488#endif
487 489
488/* Module information */ 490/* Module information */
489MODULE_AUTHOR("Liam Girdwood"); 491MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/intel/common/sst-dsp.h b/sound/soc/intel/common/sst-dsp.h
index 1f45f18715c0..859f0de00339 100644
--- a/sound/soc/intel/common/sst-dsp.h
+++ b/sound/soc/intel/common/sst-dsp.h
@@ -216,10 +216,12 @@ struct sst_pdata {
216 void *dsp; 216 void *dsp;
217}; 217};
218 218
219#if IS_ENABLED(CONFIG_DW_DMAC_CORE)
219/* Initialization */ 220/* Initialization */
220struct sst_dsp *sst_dsp_new(struct device *dev, 221struct sst_dsp *sst_dsp_new(struct device *dev,
221 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata); 222 struct sst_dsp_device *sst_dev, struct sst_pdata *pdata);
222void sst_dsp_free(struct sst_dsp *sst); 223void sst_dsp_free(struct sst_dsp *sst);
224#endif
223 225
224/* SHIM Read / Write */ 226/* SHIM Read / Write */
225void sst_dsp_shim_write(struct sst_dsp *sst, u32 offset, u32 value); 227void sst_dsp_shim_write(struct sst_dsp *sst, u32 offset, u32 value);
diff --git a/sound/soc/intel/common/sst-firmware.c b/sound/soc/intel/common/sst-firmware.c
index ebcca6dc48d1..1636a1eeb002 100644
--- a/sound/soc/intel/common/sst-firmware.c
+++ b/sound/soc/intel/common/sst-firmware.c
@@ -26,7 +26,6 @@
26#include <linux/acpi.h> 26#include <linux/acpi.h>
27 27
28/* supported DMA engine drivers */ 28/* supported DMA engine drivers */
29#include <linux/platform_data/dma-dw.h>
30#include <linux/dma/dw.h> 29#include <linux/dma/dw.h>
31 30
32#include <asm/page.h> 31#include <asm/page.h>
@@ -169,12 +168,6 @@ err:
169 return ret; 168 return ret;
170} 169}
171 170
172static struct dw_dma_platform_data dw_pdata = {
173 .is_private = 1,
174 .chan_allocation_order = CHAN_ALLOCATION_ASCENDING,
175 .chan_priority = CHAN_PRIORITY_ASCENDING,
176};
177
178static struct dw_dma_chip *dw_probe(struct device *dev, struct resource *mem, 171static struct dw_dma_chip *dw_probe(struct device *dev, struct resource *mem,
179 int irq) 172 int irq)
180{ 173{
@@ -195,7 +188,8 @@ static struct dw_dma_chip *dw_probe(struct device *dev, struct resource *mem,
195 return ERR_PTR(err); 188 return ERR_PTR(err);
196 189
197 chip->dev = dev; 190 chip->dev = dev;
198 err = dw_dma_probe(chip, &dw_pdata); 191
192 err = dw_dma_probe(chip, NULL);
199 if (err) 193 if (err)
200 return ERR_PTR(err); 194 return ERR_PTR(err);
201 195
diff --git a/sound/soc/intel/haswell/sst-haswell-ipc.c b/sound/soc/intel/haswell/sst-haswell-ipc.c
index f6efa9d4acad..b27f25f70730 100644
--- a/sound/soc/intel/haswell/sst-haswell-ipc.c
+++ b/sound/soc/intel/haswell/sst-haswell-ipc.c
@@ -302,6 +302,10 @@ struct sst_hsw {
302 struct sst_hsw_ipc_dx_reply dx; 302 struct sst_hsw_ipc_dx_reply dx;
303 void *dx_context; 303 void *dx_context;
304 dma_addr_t dx_context_paddr; 304 dma_addr_t dx_context_paddr;
305 enum sst_hsw_device_id dx_dev;
306 enum sst_hsw_device_mclk dx_mclk;
307 enum sst_hsw_device_mode dx_mode;
308 u32 dx_clock_divider;
305 309
306 /* boot */ 310 /* boot */
307 wait_queue_head_t boot_wait; 311 wait_queue_head_t boot_wait;
@@ -1400,10 +1404,10 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw,
1400 1404
1401 trace_ipc_request("set device config", dev); 1405 trace_ipc_request("set device config", dev);
1402 1406
1403 config.ssp_interface = dev; 1407 hsw->dx_dev = config.ssp_interface = dev;
1404 config.clock_frequency = mclk; 1408 hsw->dx_mclk = config.clock_frequency = mclk;
1405 config.mode = mode; 1409 hsw->dx_mode = config.mode = mode;
1406 config.clock_divider = clock_divider; 1410 hsw->dx_clock_divider = config.clock_divider = clock_divider;
1407 if (mode == SST_HSW_DEVICE_TDM_CLOCK_MASTER) 1411 if (mode == SST_HSW_DEVICE_TDM_CLOCK_MASTER)
1408 config.channels = 4; 1412 config.channels = 4;
1409 else 1413 else
@@ -1704,10 +1708,10 @@ int sst_hsw_dsp_runtime_resume(struct sst_hsw *hsw)
1704 return -EIO; 1708 return -EIO;
1705 } 1709 }
1706 1710
1707 /* Set ADSP SSP port settings */ 1711 /* Set ADSP SSP port settings - sadly the FW does not store SSP port
1708 ret = sst_hsw_device_set_config(hsw, SST_HSW_DEVICE_SSP_0, 1712 settings as part of the PM context. */
1709 SST_HSW_DEVICE_MCLK_FREQ_24_MHZ, 1713 ret = sst_hsw_device_set_config(hsw, hsw->dx_dev, hsw->dx_mclk,
1710 SST_HSW_DEVICE_CLOCK_MASTER, 9); 1714 hsw->dx_mode, hsw->dx_clock_divider);
1711 if (ret < 0) 1715 if (ret < 0)
1712 dev_err(dev, "error: SSP re-initialization failed\n"); 1716 dev_err(dev, "error: SSP re-initialization failed\n");
1713 1717
diff --git a/sound/soc/intel/skylake/Makefile b/sound/soc/intel/skylake/Makefile
index 27db22178204..914b6dab9bea 100644
--- a/sound/soc/intel/skylake/Makefile
+++ b/sound/soc/intel/skylake/Makefile
@@ -1,4 +1,5 @@
1snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o skl-messages.o 1snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o skl-messages.o \
2skl-topology.o
2 3
3obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o 4obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o
4 5
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 826d4fd8930a..50a109503a3f 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -54,6 +54,24 @@ static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab)
54 return 0; 54 return 0;
55} 55}
56 56
57#define NOTIFICATION_PARAM_ID 3
58#define NOTIFICATION_MASK 0xf
59
60/* disable notfication for underruns/overruns from firmware module */
61static void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable)
62{
63 struct notification_mask mask;
64 struct skl_ipc_large_config_msg msg = {0};
65
66 mask.notify = NOTIFICATION_MASK;
67 mask.enable = enable;
68
69 msg.large_param_id = NOTIFICATION_PARAM_ID;
70 msg.param_data_size = sizeof(mask);
71
72 skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)&mask);
73}
74
57int skl_init_dsp(struct skl *skl) 75int skl_init_dsp(struct skl *skl)
58{ 76{
59 void __iomem *mmio_base; 77 void __iomem *mmio_base;
@@ -79,7 +97,10 @@ int skl_init_dsp(struct skl *skl)
79 97
80 ret = skl_sst_dsp_init(bus->dev, mmio_base, irq, 98 ret = skl_sst_dsp_init(bus->dev, mmio_base, irq,
81 loader_ops, &skl->skl_sst); 99 loader_ops, &skl->skl_sst);
100 if (ret < 0)
101 return ret;
82 102
103 skl_dsp_enable_notification(skl->skl_sst, false);
83 dev_dbg(bus->dev, "dsp registration status=%d\n", ret); 104 dev_dbg(bus->dev, "dsp registration status=%d\n", ret);
84 105
85 return ret; 106 return ret;
@@ -122,6 +143,7 @@ int skl_suspend_dsp(struct skl *skl)
122int skl_resume_dsp(struct skl *skl) 143int skl_resume_dsp(struct skl *skl)
123{ 144{
124 struct skl_sst *ctx = skl->skl_sst; 145 struct skl_sst *ctx = skl->skl_sst;
146 int ret;
125 147
126 /* if ppcap is not supported return 0 */ 148 /* if ppcap is not supported return 0 */
127 if (!skl->ebus.ppcap) 149 if (!skl->ebus.ppcap)
@@ -131,7 +153,12 @@ int skl_resume_dsp(struct skl *skl)
131 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); 153 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
132 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true); 154 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true);
133 155
134 return skl_dsp_wake(ctx->dsp); 156 ret = skl_dsp_wake(ctx->dsp);
157 if (ret < 0)
158 return ret;
159
160 skl_dsp_enable_notification(skl->skl_sst, false);
161 return ret;
135} 162}
136 163
137enum skl_bitdepth skl_get_bit_depth(int params) 164enum skl_bitdepth skl_get_bit_depth(int params)
@@ -294,6 +321,7 @@ static void skl_copy_copier_caps(struct skl_module_cfg *mconfig,
294 (mconfig->formats_config.caps_size) / 4; 321 (mconfig->formats_config.caps_size) / 4;
295} 322}
296 323
324#define SKL_NON_GATEWAY_CPR_NODE_ID 0xFFFFFFFF
297/* 325/*
298 * Calculate the gatewat settings required for copier module, type of 326 * Calculate the gatewat settings required for copier module, type of
299 * gateway and index of gateway to use 327 * gateway and index of gateway to use
@@ -303,6 +331,7 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
303 struct skl_cpr_cfg *cpr_mconfig) 331 struct skl_cpr_cfg *cpr_mconfig)
304{ 332{
305 union skl_connector_node_id node_id = {0}; 333 union skl_connector_node_id node_id = {0};
334 union skl_ssp_dma_node ssp_node = {0};
306 struct skl_pipe_params *params = mconfig->pipe->p_params; 335 struct skl_pipe_params *params = mconfig->pipe->p_params;
307 336
308 switch (mconfig->dev_type) { 337 switch (mconfig->dev_type) {
@@ -320,9 +349,9 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
320 (SKL_CONN_SOURCE == mconfig->hw_conn_type) ? 349 (SKL_CONN_SOURCE == mconfig->hw_conn_type) ?
321 SKL_DMA_I2S_LINK_OUTPUT_CLASS : 350 SKL_DMA_I2S_LINK_OUTPUT_CLASS :
322 SKL_DMA_I2S_LINK_INPUT_CLASS; 351 SKL_DMA_I2S_LINK_INPUT_CLASS;
323 node_id.node.vindex = params->host_dma_id + 352 ssp_node.dma_node.time_slot_index = mconfig->time_slot;
324 (mconfig->time_slot << 1) + 353 ssp_node.dma_node.i2s_instance = mconfig->vbus_id;
325 (mconfig->vbus_id << 3); 354 node_id.node.vindex = ssp_node.val;
326 break; 355 break;
327 356
328 case SKL_DEVICE_DMIC: 357 case SKL_DEVICE_DMIC:
@@ -339,13 +368,18 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
339 node_id.node.vindex = params->link_dma_id; 368 node_id.node.vindex = params->link_dma_id;
340 break; 369 break;
341 370
342 default: 371 case SKL_DEVICE_HDAHOST:
343 node_id.node.dma_type = 372 node_id.node.dma_type =
344 (SKL_CONN_SOURCE == mconfig->hw_conn_type) ? 373 (SKL_CONN_SOURCE == mconfig->hw_conn_type) ?
345 SKL_DMA_HDA_HOST_OUTPUT_CLASS : 374 SKL_DMA_HDA_HOST_OUTPUT_CLASS :
346 SKL_DMA_HDA_HOST_INPUT_CLASS; 375 SKL_DMA_HDA_HOST_INPUT_CLASS;
347 node_id.node.vindex = params->host_dma_id; 376 node_id.node.vindex = params->host_dma_id;
348 break; 377 break;
378
379 default:
380 cpr_mconfig->gtw_cfg.node_id = SKL_NON_GATEWAY_CPR_NODE_ID;
381 cpr_mconfig->cpr_feature_mask = 0;
382 return;
349 } 383 }
350 384
351 cpr_mconfig->gtw_cfg.node_id = node_id.val; 385 cpr_mconfig->gtw_cfg.node_id = node_id.val;
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
index 13036b19d7e5..b0c7bd113aac 100644
--- a/sound/soc/intel/skylake/skl-nhlt.c
+++ b/sound/soc/intel/skylake/skl-nhlt.c
@@ -25,7 +25,7 @@ static u8 OSC_UUID[16] = {0x6E, 0x88, 0x9F, 0xA6, 0xEB, 0x6C, 0x94, 0x45,
25 25
26#define DSDT_NHLT_PATH "\\_SB.PCI0.HDAS" 26#define DSDT_NHLT_PATH "\\_SB.PCI0.HDAS"
27 27
28void __iomem *skl_nhlt_init(struct device *dev) 28void *skl_nhlt_init(struct device *dev)
29{ 29{
30 acpi_handle handle; 30 acpi_handle handle;
31 union acpi_object *obj; 31 union acpi_object *obj;
@@ -40,17 +40,17 @@ void __iomem *skl_nhlt_init(struct device *dev)
40 if (obj && obj->type == ACPI_TYPE_BUFFER) { 40 if (obj && obj->type == ACPI_TYPE_BUFFER) {
41 nhlt_ptr = (struct nhlt_resource_desc *)obj->buffer.pointer; 41 nhlt_ptr = (struct nhlt_resource_desc *)obj->buffer.pointer;
42 42
43 return ioremap_cache(nhlt_ptr->min_addr, nhlt_ptr->length); 43 return memremap(nhlt_ptr->min_addr, nhlt_ptr->length,
44 MEMREMAP_WB);
44 } 45 }
45 46
46 dev_err(dev, "device specific method to extract NHLT blob failed\n"); 47 dev_err(dev, "device specific method to extract NHLT blob failed\n");
47 return NULL; 48 return NULL;
48} 49}
49 50
50void skl_nhlt_free(void __iomem *addr) 51void skl_nhlt_free(void *addr)
51{ 52{
52 iounmap(addr); 53 memunmap(addr);
53 addr = NULL;
54} 54}
55 55
56static struct nhlt_specific_cfg *skl_get_specific_cfg( 56static struct nhlt_specific_cfg *skl_get_specific_cfg(
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index 7d617bf493bc..a2f94ce1679d 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -24,6 +24,7 @@
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include "skl.h" 26#include "skl.h"
27#include "skl-topology.h"
27 28
28#define HDA_MONO 1 29#define HDA_MONO 1
29#define HDA_STEREO 2 30#define HDA_STEREO 2
@@ -115,7 +116,7 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,
115 116
116 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 117 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
117 ret = pm_runtime_get_sync(dai->dev); 118 ret = pm_runtime_get_sync(dai->dev);
118 if (ret) 119 if (ret < 0)
119 return ret; 120 return ret;
120 121
121 stream = snd_hdac_ext_stream_assign(ebus, substream, 122 stream = snd_hdac_ext_stream_assign(ebus, substream,
@@ -214,6 +215,8 @@ static int skl_pcm_hw_params(struct snd_pcm_substream *substream,
214 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); 215 struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
215 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream); 216 struct hdac_ext_stream *stream = get_hdac_ext_stream(substream);
216 struct snd_pcm_runtime *runtime = substream->runtime; 217 struct snd_pcm_runtime *runtime = substream->runtime;
218 struct skl_pipe_params p_params = {0};
219 struct skl_module_cfg *m_cfg;
217 int ret, dma_id; 220 int ret, dma_id;
218 221
219 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); 222 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
@@ -228,6 +231,16 @@ static int skl_pcm_hw_params(struct snd_pcm_substream *substream,
228 dma_id = hdac_stream(stream)->stream_tag - 1; 231 dma_id = hdac_stream(stream)->stream_tag - 1;
229 dev_dbg(dai->dev, "dma_id=%d\n", dma_id); 232 dev_dbg(dai->dev, "dma_id=%d\n", dma_id);
230 233
234 p_params.s_fmt = snd_pcm_format_width(params_format(params));
235 p_params.ch = params_channels(params);
236 p_params.s_freq = params_rate(params);
237 p_params.host_dma_id = dma_id;
238 p_params.stream = substream->stream;
239
240 m_cfg = skl_tplg_fe_get_cpr_module(dai, p_params.stream);
241 if (m_cfg)
242 skl_tplg_update_pipe_params(dai->dev, m_cfg, &p_params);
243
231 return 0; 244 return 0;
232} 245}
233 246
@@ -268,6 +281,46 @@ static int skl_pcm_hw_free(struct snd_pcm_substream *substream,
268 return skl_substream_free_pages(ebus_to_hbus(ebus), substream); 281 return skl_substream_free_pages(ebus_to_hbus(ebus), substream);
269} 282}
270 283
284static int skl_be_hw_params(struct snd_pcm_substream *substream,
285 struct snd_pcm_hw_params *params,
286 struct snd_soc_dai *dai)
287{
288 struct skl_pipe_params p_params = {0};
289
290 p_params.s_fmt = snd_pcm_format_width(params_format(params));
291 p_params.ch = params_channels(params);
292 p_params.s_freq = params_rate(params);
293 p_params.stream = substream->stream;
294 skl_tplg_be_update_params(dai, &p_params);
295
296 return 0;
297}
298
299static int skl_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
300 struct snd_soc_dai *dai)
301{
302 struct skl *skl = get_skl_ctx(dai->dev);
303 struct skl_sst *ctx = skl->skl_sst;
304 struct skl_module_cfg *mconfig;
305
306 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
307 if (!mconfig)
308 return -EIO;
309
310 switch (cmd) {
311 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
312 case SNDRV_PCM_TRIGGER_RESUME:
313 return skl_run_pipe(ctx, mconfig->pipe);
314
315 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
316 case SNDRV_PCM_TRIGGER_SUSPEND:
317 return skl_stop_pipe(ctx, mconfig->pipe);
318
319 default:
320 return 0;
321 }
322}
323
271static int skl_link_hw_params(struct snd_pcm_substream *substream, 324static int skl_link_hw_params(struct snd_pcm_substream *substream,
272 struct snd_pcm_hw_params *params, 325 struct snd_pcm_hw_params *params,
273 struct snd_soc_dai *dai) 326 struct snd_soc_dai *dai)
@@ -277,9 +330,8 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
277 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 330 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
278 struct skl_dma_params *dma_params; 331 struct skl_dma_params *dma_params;
279 struct snd_soc_dai *codec_dai = rtd->codec_dai; 332 struct snd_soc_dai *codec_dai = rtd->codec_dai;
280 int dma_id; 333 struct skl_pipe_params p_params = {0};
281 334
282 pr_debug("%s\n", __func__);
283 link_dev = snd_hdac_ext_stream_assign(ebus, substream, 335 link_dev = snd_hdac_ext_stream_assign(ebus, substream,
284 HDAC_EXT_STREAM_TYPE_LINK); 336 HDAC_EXT_STREAM_TYPE_LINK);
285 if (!link_dev) 337 if (!link_dev)
@@ -293,7 +345,14 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream,
293 if (dma_params) 345 if (dma_params)
294 dma_params->stream_tag = hdac_stream(link_dev)->stream_tag; 346 dma_params->stream_tag = hdac_stream(link_dev)->stream_tag;
295 snd_soc_dai_set_dma_data(codec_dai, substream, (void *)dma_params); 347 snd_soc_dai_set_dma_data(codec_dai, substream, (void *)dma_params);
296 dma_id = hdac_stream(link_dev)->stream_tag - 1; 348
349 p_params.s_fmt = snd_pcm_format_width(params_format(params));
350 p_params.ch = params_channels(params);
351 p_params.s_freq = params_rate(params);
352 p_params.stream = substream->stream;
353 p_params.link_dma_id = hdac_stream(link_dev)->stream_tag - 1;
354
355 skl_tplg_be_update_params(dai, &p_params);
297 356
298 return 0; 357 return 0;
299} 358}
@@ -308,27 +367,12 @@ static int skl_link_pcm_prepare(struct snd_pcm_substream *substream,
308 unsigned int format_val = 0; 367 unsigned int format_val = 0;
309 struct skl_dma_params *dma_params; 368 struct skl_dma_params *dma_params;
310 struct snd_soc_dai *codec_dai = rtd->codec_dai; 369 struct snd_soc_dai *codec_dai = rtd->codec_dai;
311 struct snd_pcm_hw_params *params;
312 struct snd_interval *channels, *rate;
313 struct hdac_ext_link *link; 370 struct hdac_ext_link *link;
314 371
315 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
316 if (link_dev->link_prepared) { 372 if (link_dev->link_prepared) {
317 dev_dbg(dai->dev, "already stream is prepared - returning\n"); 373 dev_dbg(dai->dev, "already stream is prepared - returning\n");
318 return 0; 374 return 0;
319 } 375 }
320 params = devm_kzalloc(dai->dev, sizeof(*params), GFP_KERNEL);
321 if (params == NULL)
322 return -ENOMEM;
323
324 channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
325 channels->min = channels->max = substream->runtime->channels;
326 rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
327 rate->min = rate->max = substream->runtime->rate;
328 snd_mask_set(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT -
329 SNDRV_PCM_HW_PARAM_FIRST_MASK],
330 substream->runtime->format);
331
332 376
333 dma_params = (struct skl_dma_params *) 377 dma_params = (struct skl_dma_params *)
334 snd_soc_dai_get_dma_data(codec_dai, substream); 378 snd_soc_dai_get_dma_data(codec_dai, substream);
@@ -399,13 +443,13 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream,
399 return 0; 443 return 0;
400} 444}
401 445
402static int skl_hda_be_startup(struct snd_pcm_substream *substream, 446static int skl_be_startup(struct snd_pcm_substream *substream,
403 struct snd_soc_dai *dai) 447 struct snd_soc_dai *dai)
404{ 448{
405 return pm_runtime_get_sync(dai->dev); 449 return pm_runtime_get_sync(dai->dev);
406} 450}
407 451
408static void skl_hda_be_shutdown(struct snd_pcm_substream *substream, 452static void skl_be_shutdown(struct snd_pcm_substream *substream,
409 struct snd_soc_dai *dai) 453 struct snd_soc_dai *dai)
410{ 454{
411 pm_runtime_mark_last_busy(dai->dev); 455 pm_runtime_mark_last_busy(dai->dev);
@@ -418,20 +462,28 @@ static struct snd_soc_dai_ops skl_pcm_dai_ops = {
418 .prepare = skl_pcm_prepare, 462 .prepare = skl_pcm_prepare,
419 .hw_params = skl_pcm_hw_params, 463 .hw_params = skl_pcm_hw_params,
420 .hw_free = skl_pcm_hw_free, 464 .hw_free = skl_pcm_hw_free,
465 .trigger = skl_pcm_trigger,
421}; 466};
422 467
423static struct snd_soc_dai_ops skl_dmic_dai_ops = { 468static struct snd_soc_dai_ops skl_dmic_dai_ops = {
424 .startup = skl_hda_be_startup, 469 .startup = skl_be_startup,
425 .shutdown = skl_hda_be_shutdown, 470 .hw_params = skl_be_hw_params,
471 .shutdown = skl_be_shutdown,
472};
473
474static struct snd_soc_dai_ops skl_be_ssp_dai_ops = {
475 .startup = skl_be_startup,
476 .hw_params = skl_be_hw_params,
477 .shutdown = skl_be_shutdown,
426}; 478};
427 479
428static struct snd_soc_dai_ops skl_link_dai_ops = { 480static struct snd_soc_dai_ops skl_link_dai_ops = {
429 .startup = skl_hda_be_startup, 481 .startup = skl_be_startup,
430 .prepare = skl_link_pcm_prepare, 482 .prepare = skl_link_pcm_prepare,
431 .hw_params = skl_link_hw_params, 483 .hw_params = skl_link_hw_params,
432 .hw_free = skl_link_hw_free, 484 .hw_free = skl_link_hw_free,
433 .trigger = skl_link_pcm_trigger, 485 .trigger = skl_link_pcm_trigger,
434 .shutdown = skl_hda_be_shutdown, 486 .shutdown = skl_be_shutdown,
435}; 487};
436 488
437static struct snd_soc_dai_driver skl_platform_dai[] = { 489static struct snd_soc_dai_driver skl_platform_dai[] = {
@@ -488,6 +540,24 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
488}, 540},
489/* BE CPU Dais */ 541/* BE CPU Dais */
490{ 542{
543 .name = "SSP0 Pin",
544 .ops = &skl_be_ssp_dai_ops,
545 .playback = {
546 .stream_name = "ssp0 Tx",
547 .channels_min = HDA_STEREO,
548 .channels_max = HDA_STEREO,
549 .rates = SNDRV_PCM_RATE_48000,
550 .formats = SNDRV_PCM_FMTBIT_S16_LE,
551 },
552 .capture = {
553 .stream_name = "ssp0 Rx",
554 .channels_min = HDA_STEREO,
555 .channels_max = HDA_STEREO,
556 .rates = SNDRV_PCM_RATE_48000,
557 .formats = SNDRV_PCM_FMTBIT_S16_LE,
558 },
559},
560{
491 .name = "iDisp Pin", 561 .name = "iDisp Pin",
492 .ops = &skl_link_dai_ops, 562 .ops = &skl_link_dai_ops,
493 .playback = { 563 .playback = {
@@ -510,17 +580,6 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
510 }, 580 },
511}, 581},
512{ 582{
513 .name = "DMIC23 Pin",
514 .ops = &skl_dmic_dai_ops,
515 .capture = {
516 .stream_name = "DMIC23 Rx",
517 .channels_min = HDA_STEREO,
518 .channels_max = HDA_STEREO,
519 .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000,
520 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
521 },
522},
523{
524 .name = "HD-Codec Pin", 583 .name = "HD-Codec Pin",
525 .ops = &skl_link_dai_ops, 584 .ops = &skl_link_dai_ops,
526 .playback = { 585 .playback = {
@@ -538,28 +597,6 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
538 .formats = SNDRV_PCM_FMTBIT_S16_LE, 597 .formats = SNDRV_PCM_FMTBIT_S16_LE,
539 }, 598 },
540}, 599},
541{
542 .name = "HD-Codec-SPK Pin",
543 .ops = &skl_link_dai_ops,
544 .playback = {
545 .stream_name = "HD-Codec-SPK Tx",
546 .channels_min = HDA_STEREO,
547 .channels_max = HDA_STEREO,
548 .rates = SNDRV_PCM_RATE_48000,
549 .formats = SNDRV_PCM_FMTBIT_S16_LE,
550 },
551},
552{
553 .name = "HD-Codec-AMIC Pin",
554 .ops = &skl_link_dai_ops,
555 .capture = {
556 .stream_name = "HD-Codec-AMIC Rx",
557 .channels_min = HDA_STEREO,
558 .channels_max = HDA_STEREO,
559 .rates = SNDRV_PCM_RATE_48000,
560 .formats = SNDRV_PCM_FMTBIT_S16_LE,
561 },
562},
563}; 600};
564 601
565static int skl_platform_open(struct snd_pcm_substream *substream) 602static int skl_platform_open(struct snd_pcm_substream *substream)
@@ -577,7 +614,7 @@ static int skl_platform_open(struct snd_pcm_substream *substream)
577 return 0; 614 return 0;
578} 615}
579 616
580static int skl_pcm_trigger(struct snd_pcm_substream *substream, 617static int skl_coupled_trigger(struct snd_pcm_substream *substream,
581 int cmd) 618 int cmd)
582{ 619{
583 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 620 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
@@ -651,7 +688,7 @@ static int skl_pcm_trigger(struct snd_pcm_substream *substream,
651 return 0; 688 return 0;
652} 689}
653 690
654static int skl_dsp_trigger(struct snd_pcm_substream *substream, 691static int skl_decoupled_trigger(struct snd_pcm_substream *substream,
655 int cmd) 692 int cmd)
656{ 693{
657 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 694 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
@@ -708,9 +745,9 @@ static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream,
708 struct hdac_ext_bus *ebus = get_bus_ctx(substream); 745 struct hdac_ext_bus *ebus = get_bus_ctx(substream);
709 746
710 if (ebus->ppcap) 747 if (ebus->ppcap)
711 return skl_dsp_trigger(substream, cmd); 748 return skl_decoupled_trigger(substream, cmd);
712 else 749 else
713 return skl_pcm_trigger(substream, cmd); 750 return skl_coupled_trigger(substream, cmd);
714} 751}
715 752
716/* calculate runtime delay from LPIB */ 753/* calculate runtime delay from LPIB */
@@ -877,7 +914,17 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
877 return retval; 914 return retval;
878} 915}
879 916
917static int skl_platform_soc_probe(struct snd_soc_platform *platform)
918{
919 struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev);
920
921 if (ebus->ppcap)
922 return skl_tplg_init(platform, ebus);
923
924 return 0;
925}
880static struct snd_soc_platform_driver skl_platform_drv = { 926static struct snd_soc_platform_driver skl_platform_drv = {
927 .probe = skl_platform_soc_probe,
881 .ops = &skl_platform_ops, 928 .ops = &skl_platform_ops,
882 .pcm_new = skl_pcm_new, 929 .pcm_new = skl_pcm_new,
883 .pcm_free = skl_pcm_free, 930 .pcm_free = skl_pcm_free,
@@ -890,6 +937,11 @@ static const struct snd_soc_component_driver skl_component = {
890int skl_platform_register(struct device *dev) 937int skl_platform_register(struct device *dev)
891{ 938{
892 int ret; 939 int ret;
940 struct hdac_ext_bus *ebus = dev_get_drvdata(dev);
941 struct skl *skl = ebus_to_skl(ebus);
942
943 INIT_LIST_HEAD(&skl->ppl_list);
944 INIT_LIST_HEAD(&skl->dapm_path_list);
893 945
894 ret = snd_soc_register_platform(dev, &skl_platform_drv); 946 ret = snd_soc_register_platform(dev, &skl_platform_drv);
895 if (ret) { 947 if (ret) {
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.c b/sound/soc/intel/skylake/skl-sst-dsp.c
index 94875b008b0b..1bfb7f63b572 100644
--- a/sound/soc/intel/skylake/skl-sst-dsp.c
+++ b/sound/soc/intel/skylake/skl-sst-dsp.c
@@ -175,7 +175,7 @@ static int skl_dsp_core_power_down(struct sst_dsp *ctx)
175 /* poll with timeout to check if operation successful */ 175 /* poll with timeout to check if operation successful */
176 return sst_dsp_register_poll(ctx, 176 return sst_dsp_register_poll(ctx,
177 SKL_ADSP_REG_ADSPCS, 177 SKL_ADSP_REG_ADSPCS,
178 SKL_ADSPCS_SPA_MASK, 178 SKL_ADSPCS_CPA_MASK,
179 0, 179 0,
180 SKL_DSP_PD_TO, 180 SKL_DSP_PD_TO,
181 "Power down"); 181 "Power down");
@@ -262,6 +262,11 @@ irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id)
262 val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPIS); 262 val = sst_dsp_shim_read_unlocked(ctx, SKL_ADSP_REG_ADSPIS);
263 ctx->intr_status = val; 263 ctx->intr_status = val;
264 264
265 if (val == 0xffffffff) {
266 spin_unlock(&ctx->spinlock);
267 return IRQ_NONE;
268 }
269
265 if (val & SKL_ADSPIS_IPC) { 270 if (val & SKL_ADSPIS_IPC) {
266 skl_ipc_int_disable(ctx); 271 skl_ipc_int_disable(ctx);
267 result = IRQ_WAKE_THREAD; 272 result = IRQ_WAKE_THREAD;
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
index 937a0a3a63a0..3345ea0d4414 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
@@ -464,6 +464,18 @@ void skl_ipc_op_int_enable(struct sst_dsp *ctx)
464 SKL_ADSP_REG_HIPCCTL_BUSY, SKL_ADSP_REG_HIPCCTL_BUSY); 464 SKL_ADSP_REG_HIPCCTL_BUSY, SKL_ADSP_REG_HIPCCTL_BUSY);
465} 465}
466 466
467void skl_ipc_op_int_disable(struct sst_dsp *ctx)
468{
469 /* disable IPC DONE interrupt */
470 sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_HIPCCTL,
471 SKL_ADSP_REG_HIPCCTL_DONE, 0);
472
473 /* Disable IPC BUSY interrupt */
474 sst_dsp_shim_update_bits_unlocked(ctx, SKL_ADSP_REG_HIPCCTL,
475 SKL_ADSP_REG_HIPCCTL_BUSY, 0);
476
477}
478
467bool skl_ipc_int_status(struct sst_dsp *ctx) 479bool skl_ipc_int_status(struct sst_dsp *ctx)
468{ 480{
469 return sst_dsp_shim_read_unlocked(ctx, 481 return sst_dsp_shim_read_unlocked(ctx,
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
index 9f5f67202858..f1a154e45dc3 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
@@ -116,6 +116,7 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
116 116
117void skl_ipc_int_enable(struct sst_dsp *dsp); 117void skl_ipc_int_enable(struct sst_dsp *dsp);
118void skl_ipc_op_int_enable(struct sst_dsp *ctx); 118void skl_ipc_op_int_enable(struct sst_dsp *ctx);
119void skl_ipc_op_int_disable(struct sst_dsp *ctx);
119void skl_ipc_int_disable(struct sst_dsp *dsp); 120void skl_ipc_int_disable(struct sst_dsp *dsp);
120 121
121bool skl_ipc_int_status(struct sst_dsp *dsp); 122bool skl_ipc_int_status(struct sst_dsp *dsp);
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
index c18ea51b7484..3b83dc99f1d4 100644
--- a/sound/soc/intel/skylake/skl-sst.c
+++ b/sound/soc/intel/skylake/skl-sst.c
@@ -70,15 +70,31 @@ static int skl_transfer_firmware(struct sst_dsp *ctx,
70static int skl_load_base_firmware(struct sst_dsp *ctx) 70static int skl_load_base_firmware(struct sst_dsp *ctx)
71{ 71{
72 int ret = 0, i; 72 int ret = 0, i;
73 const struct firmware *fw = NULL;
74 struct skl_sst *skl = ctx->thread_context; 73 struct skl_sst *skl = ctx->thread_context;
75 u32 reg; 74 u32 reg;
76 75
77 ret = request_firmware(&fw, "dsp_fw_release.bin", ctx->dev); 76 skl->boot_complete = false;
77 init_waitqueue_head(&skl->boot_wait);
78
79 if (ctx->fw == NULL) {
80 ret = request_firmware(&ctx->fw, "dsp_fw_release.bin", ctx->dev);
81 if (ret < 0) {
82 dev_err(ctx->dev, "Request firmware failed %d\n", ret);
83 skl_dsp_disable_core(ctx);
84 return -EIO;
85 }
86 }
87
88 ret = skl_dsp_boot(ctx);
78 if (ret < 0) { 89 if (ret < 0) {
79 dev_err(ctx->dev, "Request firmware failed %d\n", ret); 90 dev_err(ctx->dev, "Boot dsp core failed ret: %d", ret);
80 skl_dsp_disable_core(ctx); 91 goto skl_load_base_firmware_failed;
81 return -EIO; 92 }
93
94 ret = skl_cldma_prepare(ctx);
95 if (ret < 0) {
96 dev_err(ctx->dev, "CL dma prepare failed : %d", ret);
97 goto skl_load_base_firmware_failed;
82 } 98 }
83 99
84 /* enable Interrupt */ 100 /* enable Interrupt */
@@ -102,7 +118,7 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
102 goto skl_load_base_firmware_failed; 118 goto skl_load_base_firmware_failed;
103 } 119 }
104 120
105 ret = skl_transfer_firmware(ctx, fw->data, fw->size); 121 ret = skl_transfer_firmware(ctx, ctx->fw->data, ctx->fw->size);
106 if (ret < 0) { 122 if (ret < 0) {
107 dev_err(ctx->dev, "Transfer firmware failed%d\n", ret); 123 dev_err(ctx->dev, "Transfer firmware failed%d\n", ret);
108 goto skl_load_base_firmware_failed; 124 goto skl_load_base_firmware_failed;
@@ -118,13 +134,12 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
118 dev_dbg(ctx->dev, "Download firmware successful%d\n", ret); 134 dev_dbg(ctx->dev, "Download firmware successful%d\n", ret);
119 skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING); 135 skl_dsp_set_state_locked(ctx, SKL_DSP_RUNNING);
120 } 136 }
121 release_firmware(fw);
122
123 return 0; 137 return 0;
124 138
125skl_load_base_firmware_failed: 139skl_load_base_firmware_failed:
126 skl_dsp_disable_core(ctx); 140 skl_dsp_disable_core(ctx);
127 release_firmware(fw); 141 release_firmware(ctx->fw);
142 ctx->fw = NULL;
128 return ret; 143 return ret;
129} 144}
130 145
@@ -172,6 +187,12 @@ static int skl_set_dsp_D3(struct sst_dsp *ctx)
172 } 187 }
173 skl_dsp_set_state_locked(ctx, SKL_DSP_RESET); 188 skl_dsp_set_state_locked(ctx, SKL_DSP_RESET);
174 189
190 /* disable Interrupt */
191 ctx->cl_dev.ops.cl_cleanup_controller(ctx);
192 skl_cldma_int_disable(ctx);
193 skl_ipc_op_int_disable(ctx);
194 skl_ipc_int_disable(ctx);
195
175 return ret; 196 return ret;
176} 197}
177 198
@@ -235,22 +256,6 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
235 if (ret) 256 if (ret)
236 return ret; 257 return ret;
237 258
238 skl->boot_complete = false;
239 init_waitqueue_head(&skl->boot_wait);
240
241 ret = skl_dsp_boot(sst);
242 if (ret < 0) {
243 dev_err(skl->dev, "Boot dsp core failed ret: %d", ret);
244 goto free_ipc;
245 }
246
247 ret = skl_cldma_prepare(sst);
248 if (ret < 0) {
249 dev_err(dev, "CL dma prepare failed : %d", ret);
250 goto free_ipc;
251 }
252
253
254 ret = sst->fw_ops.load_fw(sst); 259 ret = sst->fw_ops.load_fw(sst);
255 if (ret < 0) { 260 if (ret < 0) {
256 dev_err(dev, "Load base fw failed : %d", ret); 261 dev_err(dev, "Load base fw failed : %d", ret);
@@ -262,7 +267,6 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
262 267
263 return 0; 268 return 0;
264 269
265free_ipc:
266 skl_ipc_free(&skl->ipc); 270 skl_ipc_free(&skl->ipc);
267 return ret; 271 return ret;
268} 272}
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
new file mode 100644
index 000000000000..a7854c8fc523
--- /dev/null
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -0,0 +1,1252 @@
1/*
2 * skl-topology.c - Implements Platform component ALSA controls/widget
3 * handlers.
4 *
5 * Copyright (C) 2014-2015 Intel Corp
6 * Author: Jeeja KP <jeeja.kp@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as version 2, as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 */
18
19#include <linux/slab.h>
20#include <linux/types.h>
21#include <linux/firmware.h>
22#include <sound/soc.h>
23#include <sound/soc-topology.h>
24#include "skl-sst-dsp.h"
25#include "skl-sst-ipc.h"
26#include "skl-topology.h"
27#include "skl.h"
28#include "skl-tplg-interface.h"
29
30#define SKL_CH_FIXUP_MASK (1 << 0)
31#define SKL_RATE_FIXUP_MASK (1 << 1)
32#define SKL_FMT_FIXUP_MASK (1 << 2)
33
34/*
35 * SKL DSP driver modelling uses only few DAPM widgets so for rest we will
36 * ignore. This helpers checks if the SKL driver handles this widget type
37 */
38static int is_skl_dsp_widget_type(struct snd_soc_dapm_widget *w)
39{
40 switch (w->id) {
41 case snd_soc_dapm_dai_link:
42 case snd_soc_dapm_dai_in:
43 case snd_soc_dapm_aif_in:
44 case snd_soc_dapm_aif_out:
45 case snd_soc_dapm_dai_out:
46 case snd_soc_dapm_switch:
47 return false;
48 default:
49 return true;
50 }
51}
52
53/*
54 * Each pipelines needs memory to be allocated. Check if we have free memory
55 * from available pool. Then only add this to pool
56 * This is freed when pipe is deleted
57 * Note: DSP does actual memory management we only keep track for complete
58 * pool
59 */
60static bool skl_tplg_alloc_pipe_mem(struct skl *skl,
61 struct skl_module_cfg *mconfig)
62{
63 struct skl_sst *ctx = skl->skl_sst;
64
65 if (skl->resource.mem + mconfig->pipe->memory_pages >
66 skl->resource.max_mem) {
67 dev_err(ctx->dev,
68 "%s: module_id %d instance %d\n", __func__,
69 mconfig->id.module_id,
70 mconfig->id.instance_id);
71 dev_err(ctx->dev,
72 "exceeds ppl memory available %d mem %d\n",
73 skl->resource.max_mem, skl->resource.mem);
74 return false;
75 }
76
77 skl->resource.mem += mconfig->pipe->memory_pages;
78 return true;
79}
80
81/*
82 * Pipeline needs needs DSP CPU resources for computation, this is
83 * quantified in MCPS (Million Clocks Per Second) required for module/pipe
84 *
85 * Each pipelines needs mcps to be allocated. Check if we have mcps for this
86 * pipe. This adds the mcps to driver counter
87 * This is removed on pipeline delete
88 */
89static bool skl_tplg_alloc_pipe_mcps(struct skl *skl,
90 struct skl_module_cfg *mconfig)
91{
92 struct skl_sst *ctx = skl->skl_sst;
93
94 if (skl->resource.mcps + mconfig->mcps > skl->resource.max_mcps) {
95 dev_err(ctx->dev,
96 "%s: module_id %d instance %d\n", __func__,
97 mconfig->id.module_id, mconfig->id.instance_id);
98 dev_err(ctx->dev,
99 "exceeds ppl memory available %d > mem %d\n",
100 skl->resource.max_mcps, skl->resource.mcps);
101 return false;
102 }
103
104 skl->resource.mcps += mconfig->mcps;
105 return true;
106}
107
108/*
109 * Free the mcps when tearing down
110 */
111static void
112skl_tplg_free_pipe_mcps(struct skl *skl, struct skl_module_cfg *mconfig)
113{
114 skl->resource.mcps -= mconfig->mcps;
115}
116
117/*
118 * Free the memory when tearing down
119 */
120static void
121skl_tplg_free_pipe_mem(struct skl *skl, struct skl_module_cfg *mconfig)
122{
123 skl->resource.mem -= mconfig->pipe->memory_pages;
124}
125
126
127static void skl_dump_mconfig(struct skl_sst *ctx,
128 struct skl_module_cfg *mcfg)
129{
130 dev_dbg(ctx->dev, "Dumping config\n");
131 dev_dbg(ctx->dev, "Input Format:\n");
132 dev_dbg(ctx->dev, "channels = %d\n", mcfg->in_fmt.channels);
133 dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->in_fmt.s_freq);
134 dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->in_fmt.ch_cfg);
135 dev_dbg(ctx->dev, "valid bit depth = %d\n",
136 mcfg->in_fmt.valid_bit_depth);
137 dev_dbg(ctx->dev, "Output Format:\n");
138 dev_dbg(ctx->dev, "channels = %d\n", mcfg->out_fmt.channels);
139 dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->out_fmt.s_freq);
140 dev_dbg(ctx->dev, "valid bit depth = %d\n",
141 mcfg->out_fmt.valid_bit_depth);
142 dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->out_fmt.ch_cfg);
143}
144
145static void skl_tplg_update_params(struct skl_module_fmt *fmt,
146 struct skl_pipe_params *params, int fixup)
147{
148 if (fixup & SKL_RATE_FIXUP_MASK)
149 fmt->s_freq = params->s_freq;
150 if (fixup & SKL_CH_FIXUP_MASK)
151 fmt->channels = params->ch;
152 if (fixup & SKL_FMT_FIXUP_MASK)
153 fmt->valid_bit_depth = params->s_fmt;
154}
155
156/*
157 * A pipeline may have modules which impact the pcm parameters, like SRC,
158 * channel converter, format converter.
159 * We need to calculate the output params by applying the 'fixup'
160 * Topology will tell driver which type of fixup is to be applied by
161 * supplying the fixup mask, so based on that we calculate the output
162 *
163 * Now In FE the pcm hw_params is source/target format. Same is applicable
164 * for BE with its hw_params invoked.
165 * here based on FE, BE pipeline and direction we calculate the input and
166 * outfix and then apply that for a module
167 */
168static void skl_tplg_update_params_fixup(struct skl_module_cfg *m_cfg,
169 struct skl_pipe_params *params, bool is_fe)
170{
171 int in_fixup, out_fixup;
172 struct skl_module_fmt *in_fmt, *out_fmt;
173
174 in_fmt = &m_cfg->in_fmt;
175 out_fmt = &m_cfg->out_fmt;
176
177 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) {
178 if (is_fe) {
179 in_fixup = m_cfg->params_fixup;
180 out_fixup = (~m_cfg->converter) &
181 m_cfg->params_fixup;
182 } else {
183 out_fixup = m_cfg->params_fixup;
184 in_fixup = (~m_cfg->converter) &
185 m_cfg->params_fixup;
186 }
187 } else {
188 if (is_fe) {
189 out_fixup = m_cfg->params_fixup;
190 in_fixup = (~m_cfg->converter) &
191 m_cfg->params_fixup;
192 } else {
193 in_fixup = m_cfg->params_fixup;
194 out_fixup = (~m_cfg->converter) &
195 m_cfg->params_fixup;
196 }
197 }
198
199 skl_tplg_update_params(in_fmt, params, in_fixup);
200 skl_tplg_update_params(out_fmt, params, out_fixup);
201}
202
203/*
204 * A module needs input and output buffers, which are dependent upon pcm
205 * params, so once we have calculate params, we need buffer calculation as
206 * well.
207 */
208static void skl_tplg_update_buffer_size(struct skl_sst *ctx,
209 struct skl_module_cfg *mcfg)
210{
211 int multiplier = 1;
212
213 if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT)
214 multiplier = 5;
215
216 mcfg->ibs = (mcfg->in_fmt.s_freq / 1000) *
217 (mcfg->in_fmt.channels) *
218 (mcfg->in_fmt.bit_depth >> 3) *
219 multiplier;
220
221 mcfg->obs = (mcfg->out_fmt.s_freq / 1000) *
222 (mcfg->out_fmt.channels) *
223 (mcfg->out_fmt.bit_depth >> 3) *
224 multiplier;
225}
226
227static void skl_tplg_update_module_params(struct snd_soc_dapm_widget *w,
228 struct skl_sst *ctx)
229{
230 struct skl_module_cfg *m_cfg = w->priv;
231 struct skl_pipe_params *params = m_cfg->pipe->p_params;
232 int p_conn_type = m_cfg->pipe->conn_type;
233 bool is_fe;
234
235 if (!m_cfg->params_fixup)
236 return;
237
238 dev_dbg(ctx->dev, "Mconfig for widget=%s BEFORE updation\n",
239 w->name);
240
241 skl_dump_mconfig(ctx, m_cfg);
242
243 if (p_conn_type == SKL_PIPE_CONN_TYPE_FE)
244 is_fe = true;
245 else
246 is_fe = false;
247
248 skl_tplg_update_params_fixup(m_cfg, params, is_fe);
249 skl_tplg_update_buffer_size(ctx, m_cfg);
250
251 dev_dbg(ctx->dev, "Mconfig for widget=%s AFTER updation\n",
252 w->name);
253
254 skl_dump_mconfig(ctx, m_cfg);
255}
256
257/*
258 * A pipe can have multiple modules, each of them will be a DAPM widget as
259 * well. While managing a pipeline we need to get the list of all the
260 * widgets in a pipelines, so this helper - skl_tplg_get_pipe_widget() helps
261 * to get the SKL type widgets in that pipeline
262 */
263static int skl_tplg_alloc_pipe_widget(struct device *dev,
264 struct snd_soc_dapm_widget *w, struct skl_pipe *pipe)
265{
266 struct skl_module_cfg *src_module = NULL;
267 struct snd_soc_dapm_path *p = NULL;
268 struct skl_pipe_module *p_module = NULL;
269
270 p_module = devm_kzalloc(dev, sizeof(*p_module), GFP_KERNEL);
271 if (!p_module)
272 return -ENOMEM;
273
274 p_module->w = w;
275 list_add_tail(&p_module->node, &pipe->w_list);
276
277 snd_soc_dapm_widget_for_each_sink_path(w, p) {
278 if ((p->sink->priv == NULL)
279 && (!is_skl_dsp_widget_type(w)))
280 continue;
281
282 if ((p->sink->priv != NULL) && p->connect
283 && is_skl_dsp_widget_type(p->sink)) {
284
285 src_module = p->sink->priv;
286 if (pipe->ppl_id == src_module->pipe->ppl_id)
287 skl_tplg_alloc_pipe_widget(dev,
288 p->sink, pipe);
289 }
290 }
291 return 0;
292}
293
294/*
295 * Inside a pipe instance, we can have various modules. These modules need
296 * to instantiated in DSP by invoking INIT_MODULE IPC, which is achieved by
297 * skl_init_module() routine, so invoke that for all modules in a pipeline
298 */
299static int
300skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
301{
302 struct skl_pipe_module *w_module;
303 struct snd_soc_dapm_widget *w;
304 struct skl_module_cfg *mconfig;
305 struct skl_sst *ctx = skl->skl_sst;
306 int ret = 0;
307
308 list_for_each_entry(w_module, &pipe->w_list, node) {
309 w = w_module->w;
310 mconfig = w->priv;
311
312 /* check resource available */
313 if (!skl_tplg_alloc_pipe_mcps(skl, mconfig))
314 return -ENOMEM;
315
316 /*
317 * apply fix/conversion to module params based on
318 * FE/BE params
319 */
320 skl_tplg_update_module_params(w, ctx);
321 ret = skl_init_module(ctx, mconfig, NULL);
322 if (ret < 0)
323 return ret;
324 }
325
326 return 0;
327}
328
329/*
330 * Mixer module represents a pipeline. So in the Pre-PMU event of mixer we
331 * need create the pipeline. So we do following:
332 * - check the resources
333 * - Create the pipeline
334 * - Initialize the modules in pipeline
335 * - finally bind all modules together
336 */
337static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
338 struct skl *skl)
339{
340 int ret;
341 struct skl_module_cfg *mconfig = w->priv;
342 struct skl_pipe_module *w_module;
343 struct skl_pipe *s_pipe = mconfig->pipe;
344 struct skl_module_cfg *src_module = NULL, *dst_module;
345 struct skl_sst *ctx = skl->skl_sst;
346
347 /* check resource available */
348 if (!skl_tplg_alloc_pipe_mcps(skl, mconfig))
349 return -EBUSY;
350
351 if (!skl_tplg_alloc_pipe_mem(skl, mconfig))
352 return -ENOMEM;
353
354 /*
355 * Create a list of modules for pipe.
356 * This list contains modules from source to sink
357 */
358 ret = skl_create_pipeline(ctx, mconfig->pipe);
359 if (ret < 0)
360 return ret;
361
362 /*
363 * we create a w_list of all widgets in that pipe. This list is not
364 * freed on PMD event as widgets within a pipe are static. This
365 * saves us cycles to get widgets in pipe every time.
366 *
367 * So if we have already initialized all the widgets of a pipeline
368 * we skip, so check for list_empty and create the list if empty
369 */
370 if (list_empty(&s_pipe->w_list)) {
371 ret = skl_tplg_alloc_pipe_widget(ctx->dev, w, s_pipe);
372 if (ret < 0)
373 return ret;
374 }
375
376 /* Init all pipe modules from source to sink */
377 ret = skl_tplg_init_pipe_modules(skl, s_pipe);
378 if (ret < 0)
379 return ret;
380
381 /* Bind modules from source to sink */
382 list_for_each_entry(w_module, &s_pipe->w_list, node) {
383 dst_module = w_module->w->priv;
384
385 if (src_module == NULL) {
386 src_module = dst_module;
387 continue;
388 }
389
390 ret = skl_bind_modules(ctx, src_module, dst_module);
391 if (ret < 0)
392 return ret;
393
394 src_module = dst_module;
395 }
396
397 return 0;
398}
399
400/*
401 * A PGA represents a module in a pipeline. So in the Pre-PMU event of PGA
402 * we need to do following:
403 * - Bind to sink pipeline
404 * Since the sink pipes can be running and we don't get mixer event on
405 * connect for already running mixer, we need to find the sink pipes
406 * here and bind to them. This way dynamic connect works.
407 * - Start sink pipeline, if not running
408 * - Then run current pipe
409 */
410static int skl_tplg_pga_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w,
411 struct skl *skl)
412{
413 struct snd_soc_dapm_path *p;
414 struct skl_dapm_path_list *path_list;
415 struct snd_soc_dapm_widget *source, *sink;
416 struct skl_module_cfg *src_mconfig, *sink_mconfig;
417 struct skl_sst *ctx = skl->skl_sst;
418 int ret = 0;
419
420 source = w;
421 src_mconfig = source->priv;
422
423 /*
424 * find which sink it is connected to, bind with the sink,
425 * if sink is not started, start sink pipe first, then start
426 * this pipe
427 */
428 snd_soc_dapm_widget_for_each_source_path(w, p) {
429 if (!p->connect)
430 continue;
431
432 dev_dbg(ctx->dev, "%s: src widget=%s\n", __func__, w->name);
433 dev_dbg(ctx->dev, "%s: sink widget=%s\n", __func__, p->sink->name);
434
435 /*
436 * here we will check widgets in sink pipelines, so that
437 * can be any widgets type and we are only interested if
438 * they are ones used for SKL so check that first
439 */
440 if ((p->sink->priv != NULL) &&
441 is_skl_dsp_widget_type(p->sink)) {
442
443 sink = p->sink;
444 src_mconfig = source->priv;
445 sink_mconfig = sink->priv;
446
447 /* Bind source to sink, mixin is always source */
448 ret = skl_bind_modules(ctx, src_mconfig, sink_mconfig);
449 if (ret)
450 return ret;
451
452 /* Start sinks pipe first */
453 if (sink_mconfig->pipe->state != SKL_PIPE_STARTED) {
454 ret = skl_run_pipe(ctx, sink_mconfig->pipe);
455 if (ret)
456 return ret;
457 }
458
459 path_list = kzalloc(
460 sizeof(struct skl_dapm_path_list),
461 GFP_KERNEL);
462 if (path_list == NULL)
463 return -ENOMEM;
464
465 /* Add connected path to one global list */
466 path_list->dapm_path = p;
467 list_add_tail(&path_list->node, &skl->dapm_path_list);
468 break;
469 }
470 }
471
472 /* Start source pipe last after starting all sinks */
473 ret = skl_run_pipe(ctx, src_mconfig->pipe);
474 if (ret)
475 return ret;
476
477 return 0;
478}
479
480/*
481 * in the Post-PMU event of mixer we need to do following:
482 * - Check if this pipe is running
483 * - if not, then
484 * - bind this pipeline to its source pipeline
485 * if source pipe is already running, this means it is a dynamic
486 * connection and we need to bind only to that pipe
487 * - start this pipeline
488 */
489static int skl_tplg_mixer_dapm_post_pmu_event(struct snd_soc_dapm_widget *w,
490 struct skl *skl)
491{
492 int ret = 0;
493 struct snd_soc_dapm_path *p;
494 struct snd_soc_dapm_widget *source, *sink;
495 struct skl_module_cfg *src_mconfig, *sink_mconfig;
496 struct skl_sst *ctx = skl->skl_sst;
497 int src_pipe_started = 0;
498
499 sink = w;
500 sink_mconfig = sink->priv;
501
502 /*
503 * If source pipe is already started, that means source is driving
504 * one more sink before this sink got connected, Since source is
505 * started, bind this sink to source and start this pipe.
506 */
507 snd_soc_dapm_widget_for_each_sink_path(w, p) {
508 if (!p->connect)
509 continue;
510
511 dev_dbg(ctx->dev, "sink widget=%s\n", w->name);
512 dev_dbg(ctx->dev, "src widget=%s\n", p->source->name);
513
514 /*
515 * here we will check widgets in sink pipelines, so that
516 * can be any widgets type and we are only interested if
517 * they are ones used for SKL so check that first
518 */
519 if ((p->source->priv != NULL) &&
520 is_skl_dsp_widget_type(p->source)) {
521 source = p->source;
522 src_mconfig = source->priv;
523 sink_mconfig = sink->priv;
524 src_pipe_started = 1;
525
526 /*
527 * check pipe state, then no need to bind or start
528 * the pipe
529 */
530 if (src_mconfig->pipe->state != SKL_PIPE_STARTED)
531 src_pipe_started = 0;
532 }
533 }
534
535 if (src_pipe_started) {
536 ret = skl_bind_modules(ctx, src_mconfig, sink_mconfig);
537 if (ret)
538 return ret;
539
540 ret = skl_run_pipe(ctx, sink_mconfig->pipe);
541 }
542
543 return ret;
544}
545
546/*
547 * in the Pre-PMD event of mixer we need to do following:
548 * - Stop the pipe
549 * - find the source connections and remove that from dapm_path_list
550 * - unbind with source pipelines if still connected
551 */
552static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w,
553 struct skl *skl)
554{
555 struct snd_soc_dapm_widget *source, *sink;
556 struct skl_module_cfg *src_mconfig, *sink_mconfig;
557 int ret = 0, path_found = 0;
558 struct skl_dapm_path_list *path_list, *tmp_list;
559 struct skl_sst *ctx = skl->skl_sst;
560
561 sink = w;
562 sink_mconfig = sink->priv;
563
564 /* Stop the pipe */
565 ret = skl_stop_pipe(ctx, sink_mconfig->pipe);
566 if (ret)
567 return ret;
568
569 /*
570 * This list, dapm_path_list handling here does not need any locks
571 * as we are under dapm lock while handling widget events.
572 * List can be manipulated safely only under dapm widgets handler
573 * routines
574 */
575 list_for_each_entry_safe(path_list, tmp_list,
576 &skl->dapm_path_list, node) {
577 if (path_list->dapm_path->sink == sink) {
578 dev_dbg(ctx->dev, "Path found = %s\n",
579 path_list->dapm_path->name);
580 source = path_list->dapm_path->source;
581 src_mconfig = source->priv;
582 path_found = 1;
583
584 list_del(&path_list->node);
585 kfree(path_list);
586 break;
587 }
588 }
589
590 /*
591 * If path_found == 1, that means pmd for source pipe has
592 * not occurred, source is connected to some other sink.
593 * so its responsibility of sink to unbind itself from source.
594 */
595 if (path_found) {
596 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
597 if (ret < 0)
598 return ret;
599
600 ret = skl_unbind_modules(ctx, src_mconfig, sink_mconfig);
601 }
602
603 return ret;
604}
605
606/*
607 * in the Post-PMD event of mixer we need to do following:
608 * - Free the mcps used
609 * - Free the mem used
610 * - Unbind the modules within the pipeline
611 * - Delete the pipeline (modules are not required to be explicitly
612 * deleted, pipeline delete is enough here
613 */
614static int skl_tplg_mixer_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
615 struct skl *skl)
616{
617 struct skl_module_cfg *mconfig = w->priv;
618 struct skl_pipe_module *w_module;
619 struct skl_module_cfg *src_module = NULL, *dst_module;
620 struct skl_sst *ctx = skl->skl_sst;
621 struct skl_pipe *s_pipe = mconfig->pipe;
622 int ret = 0;
623
624 skl_tplg_free_pipe_mcps(skl, mconfig);
625
626 list_for_each_entry(w_module, &s_pipe->w_list, node) {
627 dst_module = w_module->w->priv;
628
629 if (src_module == NULL) {
630 src_module = dst_module;
631 continue;
632 }
633
634 ret = skl_unbind_modules(ctx, src_module, dst_module);
635 if (ret < 0)
636 return ret;
637
638 src_module = dst_module;
639 }
640
641 ret = skl_delete_pipe(ctx, mconfig->pipe);
642 skl_tplg_free_pipe_mem(skl, mconfig);
643
644 return ret;
645}
646
647/*
648 * in the Post-PMD event of PGA we need to do following:
649 * - Free the mcps used
650 * - Stop the pipeline
651 * - In source pipe is connected, unbind with source pipelines
652 */
653static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w,
654 struct skl *skl)
655{
656 struct snd_soc_dapm_widget *source, *sink;
657 struct skl_module_cfg *src_mconfig, *sink_mconfig;
658 int ret = 0, path_found = 0;
659 struct skl_dapm_path_list *path_list, *tmp_path_list;
660 struct skl_sst *ctx = skl->skl_sst;
661
662 source = w;
663 src_mconfig = source->priv;
664
665 skl_tplg_free_pipe_mcps(skl, src_mconfig);
666 /* Stop the pipe since this is a mixin module */
667 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
668 if (ret)
669 return ret;
670
671 list_for_each_entry_safe(path_list, tmp_path_list, &skl->dapm_path_list, node) {
672 if (path_list->dapm_path->source == source) {
673 dev_dbg(ctx->dev, "Path found = %s\n",
674 path_list->dapm_path->name);
675 sink = path_list->dapm_path->sink;
676 sink_mconfig = sink->priv;
677 path_found = 1;
678
679 list_del(&path_list->node);
680 kfree(path_list);
681 break;
682 }
683 }
684
685 /*
686 * This is a connector and if path is found that means
687 * unbind between source and sink has not happened yet
688 */
689 if (path_found) {
690 ret = skl_stop_pipe(ctx, src_mconfig->pipe);
691 if (ret < 0)
692 return ret;
693
694 ret = skl_unbind_modules(ctx, src_mconfig, sink_mconfig);
695 }
696
697 return ret;
698}
699
700/*
701 * In modelling, we assume there will be ONLY one mixer in a pipeline. If
702 * mixer is not required then it is treated as static mixer aka vmixer with
703 * a hard path to source module
704 * So we don't need to check if source is started or not as hard path puts
705 * dependency on each other
706 */
707static int skl_tplg_vmixer_event(struct snd_soc_dapm_widget *w,
708 struct snd_kcontrol *k, int event)
709{
710 struct snd_soc_dapm_context *dapm = w->dapm;
711 struct skl *skl = get_skl_ctx(dapm->dev);
712
713 switch (event) {
714 case SND_SOC_DAPM_PRE_PMU:
715 return skl_tplg_mixer_dapm_pre_pmu_event(w, skl);
716
717 case SND_SOC_DAPM_POST_PMD:
718 return skl_tplg_mixer_dapm_post_pmd_event(w, skl);
719 }
720
721 return 0;
722}
723
724/*
725 * In modelling, we assume there will be ONLY one mixer in a pipeline. If a
726 * second one is required that is created as another pipe entity.
727 * The mixer is responsible for pipe management and represent a pipeline
728 * instance
729 */
730static int skl_tplg_mixer_event(struct snd_soc_dapm_widget *w,
731 struct snd_kcontrol *k, int event)
732{
733 struct snd_soc_dapm_context *dapm = w->dapm;
734 struct skl *skl = get_skl_ctx(dapm->dev);
735
736 switch (event) {
737 case SND_SOC_DAPM_PRE_PMU:
738 return skl_tplg_mixer_dapm_pre_pmu_event(w, skl);
739
740 case SND_SOC_DAPM_POST_PMU:
741 return skl_tplg_mixer_dapm_post_pmu_event(w, skl);
742
743 case SND_SOC_DAPM_PRE_PMD:
744 return skl_tplg_mixer_dapm_pre_pmd_event(w, skl);
745
746 case SND_SOC_DAPM_POST_PMD:
747 return skl_tplg_mixer_dapm_post_pmd_event(w, skl);
748 }
749
750 return 0;
751}
752
753/*
754 * In modelling, we assumed rest of the modules in pipeline are PGA. But we
755 * are interested in last PGA (leaf PGA) in a pipeline to disconnect with
756 * the sink when it is running (two FE to one BE or one FE to two BE)
757 * scenarios
758 */
759static int skl_tplg_pga_event(struct snd_soc_dapm_widget *w,
760 struct snd_kcontrol *k, int event)
761
762{
763 struct snd_soc_dapm_context *dapm = w->dapm;
764 struct skl *skl = get_skl_ctx(dapm->dev);
765
766 switch (event) {
767 case SND_SOC_DAPM_PRE_PMU:
768 return skl_tplg_pga_dapm_pre_pmu_event(w, skl);
769
770 case SND_SOC_DAPM_POST_PMD:
771 return skl_tplg_pga_dapm_post_pmd_event(w, skl);
772 }
773
774 return 0;
775}
776
777/*
778 * The FE params are passed by hw_params of the DAI.
779 * On hw_params, the params are stored in Gateway module of the FE and we
780 * need to calculate the format in DSP module configuration, that
781 * conversion is done here
782 */
783int skl_tplg_update_pipe_params(struct device *dev,
784 struct skl_module_cfg *mconfig,
785 struct skl_pipe_params *params)
786{
787 struct skl_pipe *pipe = mconfig->pipe;
788 struct skl_module_fmt *format = NULL;
789
790 memcpy(pipe->p_params, params, sizeof(*params));
791
792 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK)
793 format = &mconfig->in_fmt;
794 else
795 format = &mconfig->out_fmt;
796
797 /* set the hw_params */
798 format->s_freq = params->s_freq;
799 format->channels = params->ch;
800 format->valid_bit_depth = skl_get_bit_depth(params->s_fmt);
801
802 /*
803 * 16 bit is 16 bit container whereas 24 bit is in 32 bit
804 * container so update bit depth accordingly
805 */
806 switch (format->valid_bit_depth) {
807 case SKL_DEPTH_16BIT:
808 format->bit_depth = format->valid_bit_depth;
809 break;
810
811 case SKL_DEPTH_24BIT:
812 format->bit_depth = SKL_DEPTH_32BIT;
813 break;
814
815 default:
816 dev_err(dev, "Invalid bit depth %x for pipe\n",
817 format->valid_bit_depth);
818 return -EINVAL;
819 }
820
821 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) {
822 mconfig->ibs = (format->s_freq / 1000) *
823 (format->channels) *
824 (format->bit_depth >> 3);
825 } else {
826 mconfig->obs = (format->s_freq / 1000) *
827 (format->channels) *
828 (format->bit_depth >> 3);
829 }
830
831 return 0;
832}
833
834/*
835 * Query the module config for the FE DAI
836 * This is used to find the hw_params set for that DAI and apply to FE
837 * pipeline
838 */
839struct skl_module_cfg *
840skl_tplg_fe_get_cpr_module(struct snd_soc_dai *dai, int stream)
841{
842 struct snd_soc_dapm_widget *w;
843 struct snd_soc_dapm_path *p = NULL;
844
845 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
846 w = dai->playback_widget;
847 snd_soc_dapm_widget_for_each_sink_path(w, p) {
848 if (p->connect && p->sink->power &&
849 is_skl_dsp_widget_type(p->sink))
850 continue;
851
852 if (p->sink->priv) {
853 dev_dbg(dai->dev, "set params for %s\n",
854 p->sink->name);
855 return p->sink->priv;
856 }
857 }
858 } else {
859 w = dai->capture_widget;
860 snd_soc_dapm_widget_for_each_source_path(w, p) {
861 if (p->connect && p->source->power &&
862 is_skl_dsp_widget_type(p->source))
863 continue;
864
865 if (p->source->priv) {
866 dev_dbg(dai->dev, "set params for %s\n",
867 p->source->name);
868 return p->source->priv;
869 }
870 }
871 }
872
873 return NULL;
874}
875
876static u8 skl_tplg_be_link_type(int dev_type)
877{
878 int ret;
879
880 switch (dev_type) {
881 case SKL_DEVICE_BT:
882 ret = NHLT_LINK_SSP;
883 break;
884
885 case SKL_DEVICE_DMIC:
886 ret = NHLT_LINK_DMIC;
887 break;
888
889 case SKL_DEVICE_I2S:
890 ret = NHLT_LINK_SSP;
891 break;
892
893 case SKL_DEVICE_HDALINK:
894 ret = NHLT_LINK_HDA;
895 break;
896
897 default:
898 ret = NHLT_LINK_INVALID;
899 break;
900 }
901
902 return ret;
903}
904
905/*
906 * Fill the BE gateway parameters
907 * The BE gateway expects a blob of parameters which are kept in the ACPI
908 * NHLT blob, so query the blob for interface type (i2s/pdm) and instance.
909 * The port can have multiple settings so pick based on the PCM
910 * parameters
911 */
912static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai,
913 struct skl_module_cfg *mconfig,
914 struct skl_pipe_params *params)
915{
916 struct skl_pipe *pipe = mconfig->pipe;
917 struct nhlt_specific_cfg *cfg;
918 struct skl *skl = get_skl_ctx(dai->dev);
919 int link_type = skl_tplg_be_link_type(mconfig->dev_type);
920
921 memcpy(pipe->p_params, params, sizeof(*params));
922
923 /* update the blob based on virtual bus_id*/
924 cfg = skl_get_ep_blob(skl, mconfig->vbus_id, link_type,
925 params->s_fmt, params->ch,
926 params->s_freq, params->stream);
927 if (cfg) {
928 mconfig->formats_config.caps_size = cfg->size;
929 mconfig->formats_config.caps = (u32 *) &cfg->caps;
930 } else {
931 dev_err(dai->dev, "Blob NULL for id %x type %d dirn %d\n",
932 mconfig->vbus_id, link_type,
933 params->stream);
934 dev_err(dai->dev, "PCM: ch %d, freq %d, fmt %d\n",
935 params->ch, params->s_freq, params->s_fmt);
936 return -EINVAL;
937 }
938
939 return 0;
940}
941
942static int skl_tplg_be_set_src_pipe_params(struct snd_soc_dai *dai,
943 struct snd_soc_dapm_widget *w,
944 struct skl_pipe_params *params)
945{
946 struct snd_soc_dapm_path *p;
947 int ret = -EIO;
948
949 snd_soc_dapm_widget_for_each_source_path(w, p) {
950 if (p->connect && is_skl_dsp_widget_type(p->source) &&
951 p->source->priv) {
952
953 if (!p->source->power) {
954 ret = skl_tplg_be_fill_pipe_params(
955 dai, p->source->priv,
956 params);
957 if (ret < 0)
958 return ret;
959 } else {
960 return -EBUSY;
961 }
962 } else {
963 ret = skl_tplg_be_set_src_pipe_params(
964 dai, p->source, params);
965 if (ret < 0)
966 return ret;
967 }
968 }
969
970 return ret;
971}
972
973static int skl_tplg_be_set_sink_pipe_params(struct snd_soc_dai *dai,
974 struct snd_soc_dapm_widget *w, struct skl_pipe_params *params)
975{
976 struct snd_soc_dapm_path *p = NULL;
977 int ret = -EIO;
978
979 snd_soc_dapm_widget_for_each_sink_path(w, p) {
980 if (p->connect && is_skl_dsp_widget_type(p->sink) &&
981 p->sink->priv) {
982
983 if (!p->sink->power) {
984 ret = skl_tplg_be_fill_pipe_params(
985 dai, p->sink->priv, params);
986 if (ret < 0)
987 return ret;
988 } else {
989 return -EBUSY;
990 }
991
992 } else {
993 ret = skl_tplg_be_set_sink_pipe_params(
994 dai, p->sink, params);
995 if (ret < 0)
996 return ret;
997 }
998 }
999
1000 return ret;
1001}
1002
1003/*
1004 * BE hw_params can be a source parameters (capture) or sink parameters
1005 * (playback). Based on sink and source we need to either find the source
1006 * list or the sink list and set the pipeline parameters
1007 */
1008int skl_tplg_be_update_params(struct snd_soc_dai *dai,
1009 struct skl_pipe_params *params)
1010{
1011 struct snd_soc_dapm_widget *w;
1012
1013 if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1014 w = dai->playback_widget;
1015
1016 return skl_tplg_be_set_src_pipe_params(dai, w, params);
1017
1018 } else {
1019 w = dai->capture_widget;
1020
1021 return skl_tplg_be_set_sink_pipe_params(dai, w, params);
1022 }
1023
1024 return 0;
1025}
1026
1027static const struct snd_soc_tplg_widget_events skl_tplg_widget_ops[] = {
1028 {SKL_MIXER_EVENT, skl_tplg_mixer_event},
1029 {SKL_VMIXER_EVENT, skl_tplg_vmixer_event},
1030 {SKL_PGA_EVENT, skl_tplg_pga_event},
1031};
1032
1033/*
1034 * The topology binary passes the pin info for a module so initialize the pin
1035 * info passed into module instance
1036 */
1037static void skl_fill_module_pin_info(struct skl_dfw_module_pin *dfw_pin,
1038 struct skl_module_pin *m_pin,
1039 bool is_dynamic, int max_pin)
1040{
1041 int i;
1042
1043 for (i = 0; i < max_pin; i++) {
1044 m_pin[i].id.module_id = dfw_pin[i].module_id;
1045 m_pin[i].id.instance_id = dfw_pin[i].instance_id;
1046 m_pin[i].in_use = false;
1047 m_pin[i].is_dynamic = is_dynamic;
1048 }
1049}
1050
1051/*
1052 * Add pipeline from topology binary into driver pipeline list
1053 *
1054 * If already added we return that instance
1055 * Otherwise we create a new instance and add into driver list
1056 */
1057static struct skl_pipe *skl_tplg_add_pipe(struct device *dev,
1058 struct skl *skl, struct skl_dfw_pipe *dfw_pipe)
1059{
1060 struct skl_pipeline *ppl;
1061 struct skl_pipe *pipe;
1062 struct skl_pipe_params *params;
1063
1064 list_for_each_entry(ppl, &skl->ppl_list, node) {
1065 if (ppl->pipe->ppl_id == dfw_pipe->pipe_id)
1066 return ppl->pipe;
1067 }
1068
1069 ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL);
1070 if (!ppl)
1071 return NULL;
1072
1073 pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL);
1074 if (!pipe)
1075 return NULL;
1076
1077 params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL);
1078 if (!params)
1079 return NULL;
1080
1081 pipe->ppl_id = dfw_pipe->pipe_id;
1082 pipe->memory_pages = dfw_pipe->memory_pages;
1083 pipe->pipe_priority = dfw_pipe->pipe_priority;
1084 pipe->conn_type = dfw_pipe->conn_type;
1085 pipe->state = SKL_PIPE_INVALID;
1086 pipe->p_params = params;
1087 INIT_LIST_HEAD(&pipe->w_list);
1088
1089 ppl->pipe = pipe;
1090 list_add(&ppl->node, &skl->ppl_list);
1091
1092 return ppl->pipe;
1093}
1094
1095/*
1096 * Topology core widget load callback
1097 *
1098 * This is used to save the private data for each widget which gives
1099 * information to the driver about module and pipeline parameters which DSP
1100 * FW expects like ids, resource values, formats etc
1101 */
1102static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
1103 struct snd_soc_dapm_widget *w,
1104 struct snd_soc_tplg_dapm_widget *tplg_w)
1105{
1106 int ret;
1107 struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt);
1108 struct skl *skl = ebus_to_skl(ebus);
1109 struct hdac_bus *bus = ebus_to_hbus(ebus);
1110 struct skl_module_cfg *mconfig;
1111 struct skl_pipe *pipe;
1112 struct skl_dfw_module *dfw_config =
1113 (struct skl_dfw_module *)tplg_w->priv.data;
1114
1115 if (!tplg_w->priv.size)
1116 goto bind_event;
1117
1118 mconfig = devm_kzalloc(bus->dev, sizeof(*mconfig), GFP_KERNEL);
1119
1120 if (!mconfig)
1121 return -ENOMEM;
1122
1123 w->priv = mconfig;
1124 mconfig->id.module_id = dfw_config->module_id;
1125 mconfig->id.instance_id = dfw_config->instance_id;
1126 mconfig->mcps = dfw_config->max_mcps;
1127 mconfig->ibs = dfw_config->ibs;
1128 mconfig->obs = dfw_config->obs;
1129 mconfig->core_id = dfw_config->core_id;
1130 mconfig->max_in_queue = dfw_config->max_in_queue;
1131 mconfig->max_out_queue = dfw_config->max_out_queue;
1132 mconfig->is_loadable = dfw_config->is_loadable;
1133 mconfig->in_fmt.channels = dfw_config->in_fmt.channels;
1134 mconfig->in_fmt.s_freq = dfw_config->in_fmt.freq;
1135 mconfig->in_fmt.bit_depth = dfw_config->in_fmt.bit_depth;
1136 mconfig->in_fmt.valid_bit_depth =
1137 dfw_config->in_fmt.valid_bit_depth;
1138 mconfig->in_fmt.ch_cfg = dfw_config->in_fmt.ch_cfg;
1139 mconfig->out_fmt.channels = dfw_config->out_fmt.channels;
1140 mconfig->out_fmt.s_freq = dfw_config->out_fmt.freq;
1141 mconfig->out_fmt.bit_depth = dfw_config->out_fmt.bit_depth;
1142 mconfig->out_fmt.valid_bit_depth =
1143 dfw_config->out_fmt.valid_bit_depth;
1144 mconfig->out_fmt.ch_cfg = dfw_config->out_fmt.ch_cfg;
1145 mconfig->params_fixup = dfw_config->params_fixup;
1146 mconfig->converter = dfw_config->converter;
1147 mconfig->m_type = dfw_config->module_type;
1148 mconfig->vbus_id = dfw_config->vbus_id;
1149
1150 pipe = skl_tplg_add_pipe(bus->dev, skl, &dfw_config->pipe);
1151 if (pipe)
1152 mconfig->pipe = pipe;
1153
1154 mconfig->dev_type = dfw_config->dev_type;
1155 mconfig->hw_conn_type = dfw_config->hw_conn_type;
1156 mconfig->time_slot = dfw_config->time_slot;
1157 mconfig->formats_config.caps_size = dfw_config->caps.caps_size;
1158
1159 mconfig->m_in_pin = devm_kzalloc(bus->dev,
1160 (mconfig->max_in_queue) *
1161 sizeof(*mconfig->m_in_pin),
1162 GFP_KERNEL);
1163 if (!mconfig->m_in_pin)
1164 return -ENOMEM;
1165
1166 mconfig->m_out_pin = devm_kzalloc(bus->dev, (mconfig->max_out_queue) *
1167 sizeof(*mconfig->m_out_pin),
1168 GFP_KERNEL);
1169 if (!mconfig->m_out_pin)
1170 return -ENOMEM;
1171
1172 skl_fill_module_pin_info(dfw_config->in_pin, mconfig->m_in_pin,
1173 dfw_config->is_dynamic_in_pin,
1174 mconfig->max_in_queue);
1175
1176 skl_fill_module_pin_info(dfw_config->out_pin, mconfig->m_out_pin,
1177 dfw_config->is_dynamic_out_pin,
1178 mconfig->max_out_queue);
1179
1180
1181 if (mconfig->formats_config.caps_size == 0)
1182 goto bind_event;
1183
1184 mconfig->formats_config.caps = (u32 *)devm_kzalloc(bus->dev,
1185 mconfig->formats_config.caps_size, GFP_KERNEL);
1186
1187 if (mconfig->formats_config.caps == NULL)
1188 return -ENOMEM;
1189
1190 memcpy(mconfig->formats_config.caps, dfw_config->caps.caps,
1191 dfw_config->caps.caps_size);
1192
1193bind_event:
1194 if (tplg_w->event_type == 0) {
1195 dev_dbg(bus->dev, "ASoC: No event handler required\n");
1196 return 0;
1197 }
1198
1199 ret = snd_soc_tplg_widget_bind_event(w, skl_tplg_widget_ops,
1200 ARRAY_SIZE(skl_tplg_widget_ops),
1201 tplg_w->event_type);
1202
1203 if (ret) {
1204 dev_err(bus->dev, "%s: No matching event handlers found for %d\n",
1205 __func__, tplg_w->event_type);
1206 return -EINVAL;
1207 }
1208
1209 return 0;
1210}
1211
1212static struct snd_soc_tplg_ops skl_tplg_ops = {
1213 .widget_load = skl_tplg_widget_load,
1214};
1215
1216/* This will be read from topology manifest, currently defined here */
1217#define SKL_MAX_MCPS 30000000
1218#define SKL_FW_MAX_MEM 1000000
1219
1220/*
1221 * SKL topology init routine
1222 */
1223int skl_tplg_init(struct snd_soc_platform *platform, struct hdac_ext_bus *ebus)
1224{
1225 int ret;
1226 const struct firmware *fw;
1227 struct hdac_bus *bus = ebus_to_hbus(ebus);
1228 struct skl *skl = ebus_to_skl(ebus);
1229
1230 ret = request_firmware(&fw, "dfw_sst.bin", bus->dev);
1231 if (ret < 0) {
1232 dev_err(bus->dev, "tplg fw %s load failed with %d\n",
1233 "dfw_sst.bin", ret);
1234 return ret;
1235 }
1236
1237 /*
1238 * The complete tplg for SKL is loaded as index 0, we don't use
1239 * any other index
1240 */
1241 ret = snd_soc_tplg_component_load(&platform->component,
1242 &skl_tplg_ops, fw, 0);
1243 if (ret < 0) {
1244 dev_err(bus->dev, "tplg component load failed%d\n", ret);
1245 return -EINVAL;
1246 }
1247
1248 skl->resource.max_mcps = SKL_MAX_MCPS;
1249 skl->resource.max_mem = SKL_FW_MAX_MEM;
1250
1251 return 0;
1252}
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index 8c7767baa94f..76053a8de41c 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -129,6 +129,11 @@ struct skl_src_module_cfg {
129 enum skl_s_freq src_cfg; 129 enum skl_s_freq src_cfg;
130} __packed; 130} __packed;
131 131
132struct notification_mask {
133 u32 notify;
134 u32 enable;
135} __packed;
136
132struct skl_up_down_mixer_cfg { 137struct skl_up_down_mixer_cfg {
133 struct skl_base_cfg base_cfg; 138 struct skl_base_cfg base_cfg;
134 enum skl_ch_cfg out_ch_cfg; 139 enum skl_ch_cfg out_ch_cfg;
@@ -153,8 +158,7 @@ enum skl_dma_type {
153union skl_ssp_dma_node { 158union skl_ssp_dma_node {
154 u8 val; 159 u8 val;
155 struct { 160 struct {
156 u8 dual_mono:1; 161 u8 time_slot_index:4;
157 u8 time_slot:3;
158 u8 i2s_instance:4; 162 u8 i2s_instance:4;
159 } dma_node; 163 } dma_node;
160}; 164};
@@ -263,6 +267,34 @@ struct skl_module_cfg {
263 struct skl_specific_cfg formats_config; 267 struct skl_specific_cfg formats_config;
264}; 268};
265 269
270struct skl_pipeline {
271 struct skl_pipe *pipe;
272 struct list_head node;
273};
274
275struct skl_dapm_path_list {
276 struct snd_soc_dapm_path *dapm_path;
277 struct list_head node;
278};
279
280static inline struct skl *get_skl_ctx(struct device *dev)
281{
282 struct hdac_ext_bus *ebus = dev_get_drvdata(dev);
283
284 return ebus_to_skl(ebus);
285}
286
287int skl_tplg_be_update_params(struct snd_soc_dai *dai,
288 struct skl_pipe_params *params);
289void skl_tplg_set_be_dmic_config(struct snd_soc_dai *dai,
290 struct skl_pipe_params *params, int stream);
291int skl_tplg_init(struct snd_soc_platform *platform,
292 struct hdac_ext_bus *ebus);
293struct skl_module_cfg *skl_tplg_fe_get_cpr_module(
294 struct snd_soc_dai *dai, int stream);
295int skl_tplg_update_pipe_params(struct device *dev,
296 struct skl_module_cfg *mconfig, struct skl_pipe_params *params);
297
266int skl_create_pipeline(struct skl_sst *ctx, struct skl_pipe *pipe); 298int skl_create_pipeline(struct skl_sst *ctx, struct skl_pipe *pipe);
267 299
268int skl_run_pipe(struct skl_sst *ctx, struct skl_pipe *pipe); 300int skl_run_pipe(struct skl_sst *ctx, struct skl_pipe *pipe);
diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h
index a50689825bca..2bc396d54cbe 100644
--- a/sound/soc/intel/skylake/skl-tplg-interface.h
+++ b/sound/soc/intel/skylake/skl-tplg-interface.h
@@ -19,6 +19,29 @@
19#ifndef __HDA_TPLG_INTERFACE_H__ 19#ifndef __HDA_TPLG_INTERFACE_H__
20#define __HDA_TPLG_INTERFACE_H__ 20#define __HDA_TPLG_INTERFACE_H__
21 21
22/*
23 * Default types range from 0~12. type can range from 0 to 0xff
24 * SST types start at higher to avoid any overlapping in future
25 */
26#define SOC_CONTROL_TYPE_HDA_SST_ALGO_PARAMS 0x100
27#define SOC_CONTROL_TYPE_HDA_SST_MUX 0x101
28#define SOC_CONTROL_TYPE_HDA_SST_MIX 0x101
29#define SOC_CONTROL_TYPE_HDA_SST_BYTE 0x103
30
31#define HDA_SST_CFG_MAX 900 /* size of copier cfg*/
32#define MAX_IN_QUEUE 8
33#define MAX_OUT_QUEUE 8
34
35/* Event types goes here */
36/* Reserve event type 0 for no event handlers */
37enum skl_event_types {
38 SKL_EVENT_NONE = 0,
39 SKL_MIXER_EVENT,
40 SKL_MUX_EVENT,
41 SKL_VMIXER_EVENT,
42 SKL_PGA_EVENT
43};
44
22/** 45/**
23 * enum skl_ch_cfg - channel configuration 46 * enum skl_ch_cfg - channel configuration
24 * 47 *
@@ -83,6 +106,66 @@ enum skl_dev_type {
83 SKL_DEVICE_I2S = 0x2, 106 SKL_DEVICE_I2S = 0x2,
84 SKL_DEVICE_SLIMBUS = 0x3, 107 SKL_DEVICE_SLIMBUS = 0x3,
85 SKL_DEVICE_HDALINK = 0x4, 108 SKL_DEVICE_HDALINK = 0x4,
109 SKL_DEVICE_HDAHOST = 0x5,
86 SKL_DEVICE_NONE 110 SKL_DEVICE_NONE
87}; 111};
112
113struct skl_dfw_module_pin {
114 u16 module_id;
115 u16 instance_id;
116} __packed;
117
118struct skl_dfw_module_fmt {
119 u32 channels;
120 u32 freq;
121 u32 bit_depth;
122 u32 valid_bit_depth;
123 u32 ch_cfg;
124} __packed;
125
126struct skl_dfw_module_caps {
127 u32 caps_size;
128 u32 caps[HDA_SST_CFG_MAX];
129};
130
131struct skl_dfw_pipe {
132 u8 pipe_id;
133 u8 pipe_priority;
134 u16 conn_type;
135 u32 memory_pages;
136} __packed;
137
138struct skl_dfw_module {
139 u16 module_id;
140 u16 instance_id;
141 u32 max_mcps;
142 u8 core_id;
143 u8 max_in_queue;
144 u8 max_out_queue;
145 u8 is_loadable;
146 u8 conn_type;
147 u8 dev_type;
148 u8 hw_conn_type;
149 u8 time_slot;
150 u32 obs;
151 u32 ibs;
152 u32 params_fixup;
153 u32 converter;
154 u32 module_type;
155 u32 vbus_id;
156 u8 is_dynamic_in_pin;
157 u8 is_dynamic_out_pin;
158 struct skl_dfw_pipe pipe;
159 struct skl_dfw_module_fmt in_fmt;
160 struct skl_dfw_module_fmt out_fmt;
161 struct skl_dfw_module_pin in_pin[MAX_IN_QUEUE];
162 struct skl_dfw_module_pin out_pin[MAX_OUT_QUEUE];
163 struct skl_dfw_module_caps caps;
164} __packed;
165
166struct skl_dfw_algo_data {
167 u32 max;
168 char *params;
169} __packed;
170
88#endif 171#endif
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index 348d094e81d6..5319529aedf7 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -166,12 +166,20 @@ static int skl_runtime_suspend(struct device *dev)
166 struct pci_dev *pci = to_pci_dev(dev); 166 struct pci_dev *pci = to_pci_dev(dev);
167 struct hdac_ext_bus *ebus = pci_get_drvdata(pci); 167 struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
168 struct hdac_bus *bus = ebus_to_hbus(ebus); 168 struct hdac_bus *bus = ebus_to_hbus(ebus);
169 struct skl *skl = ebus_to_skl(ebus);
170 int ret;
169 171
170 dev_dbg(bus->dev, "in %s\n", __func__); 172 dev_dbg(bus->dev, "in %s\n", __func__);
171 173
172 /* enable controller wake up event */ 174 /* enable controller wake up event */
173 snd_hdac_chip_updatew(bus, WAKEEN, 0, STATESTS_INT_MASK); 175 snd_hdac_chip_updatew(bus, WAKEEN, 0, STATESTS_INT_MASK);
174 176
177 snd_hdac_ext_bus_link_power_down_all(ebus);
178
179 ret = skl_suspend_dsp(skl);
180 if (ret < 0)
181 return ret;
182
175 snd_hdac_bus_stop_chip(bus); 183 snd_hdac_bus_stop_chip(bus);
176 snd_hdac_bus_enter_link_reset(bus); 184 snd_hdac_bus_enter_link_reset(bus);
177 185
@@ -183,7 +191,7 @@ static int skl_runtime_resume(struct device *dev)
183 struct pci_dev *pci = to_pci_dev(dev); 191 struct pci_dev *pci = to_pci_dev(dev);
184 struct hdac_ext_bus *ebus = pci_get_drvdata(pci); 192 struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
185 struct hdac_bus *bus = ebus_to_hbus(ebus); 193 struct hdac_bus *bus = ebus_to_hbus(ebus);
186 struct skl *hda = ebus_to_skl(ebus); 194 struct skl *skl = ebus_to_skl(ebus);
187 int status; 195 int status;
188 196
189 dev_dbg(bus->dev, "in %s\n", __func__); 197 dev_dbg(bus->dev, "in %s\n", __func__);
@@ -191,12 +199,12 @@ static int skl_runtime_resume(struct device *dev)
191 /* Read STATESTS before controller reset */ 199 /* Read STATESTS before controller reset */
192 status = snd_hdac_chip_readw(bus, STATESTS); 200 status = snd_hdac_chip_readw(bus, STATESTS);
193 201
194 skl_init_pci(hda); 202 skl_init_pci(skl);
195 snd_hdac_bus_init_chip(bus, true); 203 snd_hdac_bus_init_chip(bus, true);
196 /* disable controller Wake Up event */ 204 /* disable controller Wake Up event */
197 snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0); 205 snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0);
198 206
199 return 0; 207 return skl_resume_dsp(skl);
200} 208}
201#endif /* CONFIG_PM */ 209#endif /* CONFIG_PM */
202 210
@@ -453,21 +461,28 @@ static int skl_probe(struct pci_dev *pci,
453 if (err < 0) 461 if (err < 0)
454 goto out_free; 462 goto out_free;
455 463
464 skl->nhlt = skl_nhlt_init(bus->dev);
465
466 if (skl->nhlt == NULL)
467 goto out_free;
468
456 pci_set_drvdata(skl->pci, ebus); 469 pci_set_drvdata(skl->pci, ebus);
457 470
458 /* check if dsp is there */ 471 /* check if dsp is there */
459 if (ebus->ppcap) { 472 if (ebus->ppcap) {
460 /* TODO register with dsp IPC */ 473 err = skl_init_dsp(skl);
461 dev_dbg(bus->dev, "Register dsp\n"); 474 if (err < 0) {
475 dev_dbg(bus->dev, "error failed to register dsp\n");
476 goto out_free;
477 }
462 } 478 }
463
464 if (ebus->mlcap) 479 if (ebus->mlcap)
465 snd_hdac_ext_bus_get_ml_capabilities(ebus); 480 snd_hdac_ext_bus_get_ml_capabilities(ebus);
466 481
467 /* create device for soc dmic */ 482 /* create device for soc dmic */
468 err = skl_dmic_device_register(skl); 483 err = skl_dmic_device_register(skl);
469 if (err < 0) 484 if (err < 0)
470 goto out_free; 485 goto out_dsp_free;
471 486
472 /* register platform dai and controls */ 487 /* register platform dai and controls */
473 err = skl_platform_register(bus->dev); 488 err = skl_platform_register(bus->dev);
@@ -491,6 +506,8 @@ out_unregister:
491 skl_platform_unregister(bus->dev); 506 skl_platform_unregister(bus->dev);
492out_dmic_free: 507out_dmic_free:
493 skl_dmic_device_unregister(skl); 508 skl_dmic_device_unregister(skl);
509out_dsp_free:
510 skl_free_dsp(skl);
494out_free: 511out_free:
495 skl->init_failed = 1; 512 skl->init_failed = 1;
496 skl_free(ebus); 513 skl_free(ebus);
@@ -507,6 +524,7 @@ static void skl_remove(struct pci_dev *pci)
507 pm_runtime_get_noresume(&pci->dev); 524 pm_runtime_get_noresume(&pci->dev);
508 pci_dev_put(pci); 525 pci_dev_put(pci);
509 skl_platform_unregister(&pci->dev); 526 skl_platform_unregister(&pci->dev);
527 skl_free_dsp(skl);
510 skl_dmic_device_unregister(skl); 528 skl_dmic_device_unregister(skl);
511 skl_free(ebus); 529 skl_free(ebus);
512 dev_set_drvdata(&pci->dev, NULL); 530 dev_set_drvdata(&pci->dev, NULL);
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index f7fdbb02947f..dd2e79ae45a8 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -48,6 +48,13 @@
48#define AZX_REG_VS_SDXEFIFOS_XBASE 0x1094 48#define AZX_REG_VS_SDXEFIFOS_XBASE 0x1094
49#define AZX_REG_VS_SDXEFIFOS_XINTERVAL 0x20 49#define AZX_REG_VS_SDXEFIFOS_XINTERVAL 0x20
50 50
51struct skl_dsp_resource {
52 u32 max_mcps;
53 u32 max_mem;
54 u32 mcps;
55 u32 mem;
56};
57
51struct skl { 58struct skl {
52 struct hdac_ext_bus ebus; 59 struct hdac_ext_bus ebus;
53 struct pci_dev *pci; 60 struct pci_dev *pci;
@@ -55,8 +62,12 @@ struct skl {
55 unsigned int init_failed:1; /* delayed init failed */ 62 unsigned int init_failed:1; /* delayed init failed */
56 struct platform_device *dmic_dev; 63 struct platform_device *dmic_dev;
57 64
58 void __iomem *nhlt; /* nhlt ptr */ 65 void *nhlt; /* nhlt ptr */
59 struct skl_sst *skl_sst; /* sst skl ctx */ 66 struct skl_sst *skl_sst; /* sst skl ctx */
67
68 struct skl_dsp_resource resource;
69 struct list_head ppl_list;
70 struct list_head dapm_path_list;
60}; 71};
61 72
62#define skl_to_ebus(s) (&(s)->ebus) 73#define skl_to_ebus(s) (&(s)->ebus)
@@ -72,8 +83,8 @@ struct skl_dma_params {
72int skl_platform_unregister(struct device *dev); 83int skl_platform_unregister(struct device *dev);
73int skl_platform_register(struct device *dev); 84int skl_platform_register(struct device *dev);
74 85
75void __iomem *skl_nhlt_init(struct device *dev); 86void *skl_nhlt_init(struct device *dev);
76void skl_nhlt_free(void __iomem *addr); 87void skl_nhlt_free(void *addr);
77struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance, 88struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance,
78 u8 link_type, u8 s_fmt, u8 no_ch, u32 s_rate, u8 dirn); 89 u8 link_type, u8 s_fmt, u8 no_ch, u32 s_rate, u8 dirn);
79 90
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index b05fb1c1a848..794a3499e567 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -485,6 +485,7 @@ static const struct of_device_id jz4740_of_matches[] = {
485 { .compatible = "ingenic,jz4780-i2s", .data = (void *)JZ_I2S_JZ4780 }, 485 { .compatible = "ingenic,jz4780-i2s", .data = (void *)JZ_I2S_JZ4780 },
486 { /* sentinel */ } 486 { /* sentinel */ }
487}; 487};
488MODULE_DEVICE_TABLE(of, jz4740_of_matches);
488#endif 489#endif
489 490
490static int jz4740_i2s_dev_probe(struct platform_device *pdev) 491static int jz4740_i2s_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/kirkwood/armada-370-db.c b/sound/soc/kirkwood/armada-370-db.c
index de7563bdc5c2..e0304d544f26 100644
--- a/sound/soc/kirkwood/armada-370-db.c
+++ b/sound/soc/kirkwood/armada-370-db.c
@@ -130,6 +130,7 @@ static const struct of_device_id a370db_dt_ids[] = {
130 { .compatible = "marvell,a370db-audio" }, 130 { .compatible = "marvell,a370db-audio" },
131 { }, 131 { },
132}; 132};
133MODULE_DEVICE_TABLE(of, a370db_dt_ids);
133 134
134static struct platform_driver a370db_driver = { 135static struct platform_driver a370db_driver = {
135 .driver = { 136 .driver = {
diff --git a/sound/soc/mediatek/mt8173-max98090.c b/sound/soc/mediatek/mt8173-max98090.c
index 684e8a78bed0..71a1a35047ba 100644
--- a/sound/soc/mediatek/mt8173-max98090.c
+++ b/sound/soc/mediatek/mt8173-max98090.c
@@ -179,21 +179,13 @@ static int mt8173_max98090_dev_probe(struct platform_device *pdev)
179 } 179 }
180 card->dev = &pdev->dev; 180 card->dev = &pdev->dev;
181 181
182 ret = snd_soc_register_card(card); 182 ret = devm_snd_soc_register_card(&pdev->dev, card);
183 if (ret) 183 if (ret)
184 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", 184 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
185 __func__, ret); 185 __func__, ret);
186 return ret; 186 return ret;
187} 187}
188 188
189static int mt8173_max98090_dev_remove(struct platform_device *pdev)
190{
191 struct snd_soc_card *card = platform_get_drvdata(pdev);
192
193 snd_soc_unregister_card(card);
194 return 0;
195}
196
197static const struct of_device_id mt8173_max98090_dt_match[] = { 189static const struct of_device_id mt8173_max98090_dt_match[] = {
198 { .compatible = "mediatek,mt8173-max98090", }, 190 { .compatible = "mediatek,mt8173-max98090", },
199 { } 191 { }
@@ -209,7 +201,6 @@ static struct platform_driver mt8173_max98090_driver = {
209#endif 201#endif
210 }, 202 },
211 .probe = mt8173_max98090_dev_probe, 203 .probe = mt8173_max98090_dev_probe,
212 .remove = mt8173_max98090_dev_remove,
213}; 204};
214 205
215module_platform_driver(mt8173_max98090_driver); 206module_platform_driver(mt8173_max98090_driver);
diff --git a/sound/soc/mediatek/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173-rt5650-rt5676.c
index 86cf9752f18a..50ba538eccb3 100644
--- a/sound/soc/mediatek/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173-rt5650-rt5676.c
@@ -246,21 +246,13 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
246 card->dev = &pdev->dev; 246 card->dev = &pdev->dev;
247 platform_set_drvdata(pdev, card); 247 platform_set_drvdata(pdev, card);
248 248
249 ret = snd_soc_register_card(card); 249 ret = devm_snd_soc_register_card(&pdev->dev, card);
250 if (ret) 250 if (ret)
251 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", 251 dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
252 __func__, ret); 252 __func__, ret);
253 return ret; 253 return ret;
254} 254}
255 255
256static int mt8173_rt5650_rt5676_dev_remove(struct platform_device *pdev)
257{
258 struct snd_soc_card *card = platform_get_drvdata(pdev);
259
260 snd_soc_unregister_card(card);
261 return 0;
262}
263
264static const struct of_device_id mt8173_rt5650_rt5676_dt_match[] = { 256static const struct of_device_id mt8173_rt5650_rt5676_dt_match[] = {
265 { .compatible = "mediatek,mt8173-rt5650-rt5676", }, 257 { .compatible = "mediatek,mt8173-rt5650-rt5676", },
266 { } 258 { }
@@ -276,7 +268,6 @@ static struct platform_driver mt8173_rt5650_rt5676_driver = {
276#endif 268#endif
277 }, 269 },
278 .probe = mt8173_rt5650_rt5676_dev_probe, 270 .probe = mt8173_rt5650_rt5676_dev_probe,
279 .remove = mt8173_rt5650_rt5676_dev_remove,
280}; 271};
281 272
282module_platform_driver(mt8173_rt5650_rt5676_driver); 273module_platform_driver(mt8173_rt5650_rt5676_driver);
diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c
index d190fe017559..f5baf3c38863 100644
--- a/sound/soc/mediatek/mtk-afe-pcm.c
+++ b/sound/soc/mediatek/mtk-afe-pcm.c
@@ -549,6 +549,23 @@ static int mtk_afe_dais_startup(struct snd_pcm_substream *substream,
549 memif->substream = substream; 549 memif->substream = substream;
550 550
551 snd_soc_set_runtime_hwparams(substream, &mtk_afe_hardware); 551 snd_soc_set_runtime_hwparams(substream, &mtk_afe_hardware);
552
553 /*
554 * Capture cannot use ping-pong buffer since hw_ptr at IRQ may be
555 * smaller than period_size due to AFE's internal buffer.
556 * This easily leads to overrun when avail_min is period_size.
557 * One more period can hold the possible unread buffer.
558 */
559 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
560 ret = snd_pcm_hw_constraint_minmax(runtime,
561 SNDRV_PCM_HW_PARAM_PERIODS,
562 3,
563 mtk_afe_hardware.periods_max);
564 if (ret < 0) {
565 dev_err(afe->dev, "hw_constraint_minmax failed\n");
566 return ret;
567 }
568 }
552 ret = snd_pcm_hw_constraint_integer(runtime, 569 ret = snd_pcm_hw_constraint_integer(runtime,
553 SNDRV_PCM_HW_PARAM_PERIODS); 570 SNDRV_PCM_HW_PARAM_PERIODS);
554 if (ret < 0) 571 if (ret < 0)
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
index 6e6fce6a14ba..2b23ffbac6b1 100644
--- a/sound/soc/mxs/mxs-sgtl5000.c
+++ b/sound/soc/mxs/mxs-sgtl5000.c
@@ -142,7 +142,7 @@ static int mxs_sgtl5000_probe(struct platform_device *pdev)
142 card->dev = &pdev->dev; 142 card->dev = &pdev->dev;
143 platform_set_drvdata(pdev, card); 143 platform_set_drvdata(pdev, card);
144 144
145 ret = snd_soc_register_card(card); 145 ret = devm_snd_soc_register_card(&pdev->dev, card);
146 if (ret) { 146 if (ret) {
147 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", 147 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
148 ret); 148 ret);
@@ -154,12 +154,8 @@ static int mxs_sgtl5000_probe(struct platform_device *pdev)
154 154
155static int mxs_sgtl5000_remove(struct platform_device *pdev) 155static int mxs_sgtl5000_remove(struct platform_device *pdev)
156{ 156{
157 struct snd_soc_card *card = platform_get_drvdata(pdev);
158
159 mxs_saif_put_mclk(0); 157 mxs_saif_put_mclk(0);
160 158
161 snd_soc_unregister_card(card);
162
163 return 0; 159 return 0;
164} 160}
165 161
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 3bebfb1d3a6f..99538900a253 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -297,7 +297,7 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
297 dev_err(card->dev, "Failed to add TPA6130A2 controls\n"); 297 dev_err(card->dev, "Failed to add TPA6130A2 controls\n");
298 return err; 298 return err;
299 } 299 }
300 snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42); 300 snd_soc_limit_volume(card, "TPA6130A2 Headphone Playback Volume", 42);
301 301
302 err = omap_mcbsp_st_add_controls(rtd, 2); 302 err = omap_mcbsp_st_add_controls(rtd, 2);
303 if (err < 0) { 303 if (err < 0) {
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 39cea80846c3..f2bf8661dd21 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -1,7 +1,6 @@
1config SND_PXA2XX_SOC 1config SND_PXA2XX_SOC
2 tristate "SoC Audio for the Intel PXA2xx chip" 2 tristate "SoC Audio for the Intel PXA2xx chip"
3 depends on ARCH_PXA 3 depends on ARCH_PXA
4 select SND_ARM
5 select SND_PXA2XX_LIB 4 select SND_PXA2XX_LIB
6 help 5 help
7 Say Y or M if you want to add support for codecs attached to 6 Say Y or M if you want to add support for codecs attached to
@@ -25,7 +24,6 @@ config SND_PXA2XX_AC97
25config SND_PXA2XX_SOC_AC97 24config SND_PXA2XX_SOC_AC97
26 tristate 25 tristate
27 select AC97_BUS 26 select AC97_BUS
28 select SND_ARM
29 select SND_PXA2XX_LIB_AC97 27 select SND_PXA2XX_LIB_AC97
30 select SND_SOC_AC97_BUS 28 select SND_SOC_AC97_BUS
31 29
diff --git a/sound/soc/pxa/brownstone.c b/sound/soc/pxa/brownstone.c
index 2b26318bc200..6147e86e9b0f 100644
--- a/sound/soc/pxa/brownstone.c
+++ b/sound/soc/pxa/brownstone.c
@@ -116,26 +116,19 @@ static int brownstone_probe(struct platform_device *pdev)
116 int ret; 116 int ret;
117 117
118 brownstone.dev = &pdev->dev; 118 brownstone.dev = &pdev->dev;
119 ret = snd_soc_register_card(&brownstone); 119 ret = devm_snd_soc_register_card(&pdev->dev, &brownstone);
120 if (ret) 120 if (ret)
121 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 121 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
122 ret); 122 ret);
123 return ret; 123 return ret;
124} 124}
125 125
126static int brownstone_remove(struct platform_device *pdev)
127{
128 snd_soc_unregister_card(&brownstone);
129 return 0;
130}
131
132static struct platform_driver mmp_driver = { 126static struct platform_driver mmp_driver = {
133 .driver = { 127 .driver = {
134 .name = "brownstone-audio", 128 .name = "brownstone-audio",
135 .pm = &snd_soc_pm_ops, 129 .pm = &snd_soc_pm_ops,
136 }, 130 },
137 .probe = brownstone_probe, 131 .probe = brownstone_probe,
138 .remove = brownstone_remove,
139}; 132};
140 133
141module_platform_driver(mmp_driver); 134module_platform_driver(mmp_driver);
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 3580d10c9f28..c97dc13d3608 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -295,28 +295,19 @@ static int corgi_probe(struct platform_device *pdev)
295 295
296 card->dev = &pdev->dev; 296 card->dev = &pdev->dev;
297 297
298 ret = snd_soc_register_card(card); 298 ret = devm_snd_soc_register_card(&pdev->dev, card);
299 if (ret) 299 if (ret)
300 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 300 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
301 ret); 301 ret);
302 return ret; 302 return ret;
303} 303}
304 304
305static int corgi_remove(struct platform_device *pdev)
306{
307 struct snd_soc_card *card = platform_get_drvdata(pdev);
308
309 snd_soc_unregister_card(card);
310 return 0;
311}
312
313static struct platform_driver corgi_driver = { 305static struct platform_driver corgi_driver = {
314 .driver = { 306 .driver = {
315 .name = "corgi-audio", 307 .name = "corgi-audio",
316 .pm = &snd_soc_pm_ops, 308 .pm = &snd_soc_pm_ops,
317 }, 309 },
318 .probe = corgi_probe, 310 .probe = corgi_probe,
319 .remove = corgi_remove,
320}; 311};
321 312
322module_platform_driver(corgi_driver); 313module_platform_driver(corgi_driver);
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c
index d72e124a3676..1de876529aa1 100644
--- a/sound/soc/pxa/e740_wm9705.c
+++ b/sound/soc/pxa/e740_wm9705.c
@@ -138,7 +138,7 @@ static int e740_probe(struct platform_device *pdev)
138 138
139 card->dev = &pdev->dev; 139 card->dev = &pdev->dev;
140 140
141 ret = snd_soc_register_card(card); 141 ret = devm_snd_soc_register_card(&pdev->dev, card);
142 if (ret) { 142 if (ret) {
143 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 143 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
144 ret); 144 ret);
@@ -149,10 +149,7 @@ static int e740_probe(struct platform_device *pdev)
149 149
150static int e740_remove(struct platform_device *pdev) 150static int e740_remove(struct platform_device *pdev)
151{ 151{
152 struct snd_soc_card *card = platform_get_drvdata(pdev);
153
154 gpio_free_array(e740_audio_gpios, ARRAY_SIZE(e740_audio_gpios)); 152 gpio_free_array(e740_audio_gpios, ARRAY_SIZE(e740_audio_gpios));
155 snd_soc_unregister_card(card);
156 return 0; 153 return 0;
157} 154}
158 155
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
index 48f2d7c2e68c..b7eb7cd5df7d 100644
--- a/sound/soc/pxa/e750_wm9705.c
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -120,7 +120,7 @@ static int e750_probe(struct platform_device *pdev)
120 120
121 card->dev = &pdev->dev; 121 card->dev = &pdev->dev;
122 122
123 ret = snd_soc_register_card(card); 123 ret = devm_snd_soc_register_card(&pdev->dev, card);
124 if (ret) { 124 if (ret) {
125 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 125 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
126 ret); 126 ret);
@@ -131,10 +131,7 @@ static int e750_probe(struct platform_device *pdev)
131 131
132static int e750_remove(struct platform_device *pdev) 132static int e750_remove(struct platform_device *pdev)
133{ 133{
134 struct snd_soc_card *card = platform_get_drvdata(pdev);
135
136 gpio_free_array(e750_audio_gpios, ARRAY_SIZE(e750_audio_gpios)); 134 gpio_free_array(e750_audio_gpios, ARRAY_SIZE(e750_audio_gpios));
137 snd_soc_unregister_card(card);
138 return 0; 135 return 0;
139} 136}
140 137
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index 45d4bd46fff6..41bf71466a7b 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -119,7 +119,7 @@ static int e800_probe(struct platform_device *pdev)
119 119
120 card->dev = &pdev->dev; 120 card->dev = &pdev->dev;
121 121
122 ret = snd_soc_register_card(card); 122 ret = devm_snd_soc_register_card(&pdev->dev, card);
123 if (ret) { 123 if (ret) {
124 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 124 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
125 ret); 125 ret);
@@ -130,10 +130,7 @@ static int e800_probe(struct platform_device *pdev)
130 130
131static int e800_remove(struct platform_device *pdev) 131static int e800_remove(struct platform_device *pdev)
132{ 132{
133 struct snd_soc_card *card = platform_get_drvdata(pdev);
134
135 gpio_free_array(e800_audio_gpios, ARRAY_SIZE(e800_audio_gpios)); 133 gpio_free_array(e800_audio_gpios, ARRAY_SIZE(e800_audio_gpios));
136 snd_soc_unregister_card(card);
137 return 0; 134 return 0;
138} 135}
139 136
diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c
index 9f8be7cd567e..ecbf2873b7ff 100644
--- a/sound/soc/pxa/hx4700.c
+++ b/sound/soc/pxa/hx4700.c
@@ -193,7 +193,7 @@ static int hx4700_audio_probe(struct platform_device *pdev)
193 return ret; 193 return ret;
194 194
195 snd_soc_card_hx4700.dev = &pdev->dev; 195 snd_soc_card_hx4700.dev = &pdev->dev;
196 ret = snd_soc_register_card(&snd_soc_card_hx4700); 196 ret = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_hx4700);
197 if (ret) 197 if (ret)
198 gpio_free_array(hx4700_audio_gpios, 198 gpio_free_array(hx4700_audio_gpios,
199 ARRAY_SIZE(hx4700_audio_gpios)); 199 ARRAY_SIZE(hx4700_audio_gpios));
@@ -203,8 +203,6 @@ static int hx4700_audio_probe(struct platform_device *pdev)
203 203
204static int hx4700_audio_remove(struct platform_device *pdev) 204static int hx4700_audio_remove(struct platform_device *pdev)
205{ 205{
206 snd_soc_unregister_card(&snd_soc_card_hx4700);
207
208 gpio_set_value(GPIO92_HX4700_HP_DRIVER, 0); 206 gpio_set_value(GPIO92_HX4700_HP_DRIVER, 0);
209 gpio_set_value(GPIO107_HX4700_SPK_nSD, 0); 207 gpio_set_value(GPIO107_HX4700_SPK_nSD, 0);
210 208
diff --git a/sound/soc/pxa/imote2.c b/sound/soc/pxa/imote2.c
index 29fabbfd21f1..9d0e40771ef5 100644
--- a/sound/soc/pxa/imote2.c
+++ b/sound/soc/pxa/imote2.c
@@ -72,28 +72,19 @@ static int imote2_probe(struct platform_device *pdev)
72 72
73 card->dev = &pdev->dev; 73 card->dev = &pdev->dev;
74 74
75 ret = snd_soc_register_card(card); 75 ret = devm_snd_soc_register_card(&pdev->dev, card);
76 if (ret) 76 if (ret)
77 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 77 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
78 ret); 78 ret);
79 return ret; 79 return ret;
80} 80}
81 81
82static int imote2_remove(struct platform_device *pdev)
83{
84 struct snd_soc_card *card = platform_get_drvdata(pdev);
85
86 snd_soc_unregister_card(card);
87 return 0;
88}
89
90static struct platform_driver imote2_driver = { 82static struct platform_driver imote2_driver = {
91 .driver = { 83 .driver = {
92 .name = "imote2-audio", 84 .name = "imote2-audio",
93 .pm = &snd_soc_pm_ops, 85 .pm = &snd_soc_pm_ops,
94 }, 86 },
95 .probe = imote2_probe, 87 .probe = imote2_probe,
96 .remove = imote2_remove,
97}; 88};
98 89
99module_platform_driver(imote2_driver); 90module_platform_driver(imote2_driver);
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index a9615a574546..29bc60e85e92 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -181,7 +181,7 @@ static int mioa701_wm9713_probe(struct platform_device *pdev)
181 return -ENODEV; 181 return -ENODEV;
182 182
183 mioa701.dev = &pdev->dev; 183 mioa701.dev = &pdev->dev;
184 rc = snd_soc_register_card(&mioa701); 184 rc = devm_snd_soc_register_card(&pdev->dev, &mioa701);
185 if (!rc) 185 if (!rc)
186 dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will" 186 dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will"
187 "lead to overheating and possible destruction of your device." 187 "lead to overheating and possible destruction of your device."
@@ -189,17 +189,8 @@ static int mioa701_wm9713_probe(struct platform_device *pdev)
189 return rc; 189 return rc;
190} 190}
191 191
192static int mioa701_wm9713_remove(struct platform_device *pdev)
193{
194 struct snd_soc_card *card = platform_get_drvdata(pdev);
195
196 snd_soc_unregister_card(card);
197 return 0;
198}
199
200static struct platform_driver mioa701_wm9713_driver = { 192static struct platform_driver mioa701_wm9713_driver = {
201 .probe = mioa701_wm9713_probe, 193 .probe = mioa701_wm9713_probe,
202 .remove = mioa701_wm9713_remove,
203 .driver = { 194 .driver = {
204 .name = "mioa701-wm9713", 195 .name = "mioa701-wm9713",
205 .pm = &snd_soc_pm_ops, 196 .pm = &snd_soc_pm_ops,
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index c20bbc042425..4e74d9573f03 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -140,22 +140,15 @@ static int palm27x_asoc_probe(struct platform_device *pdev)
140 140
141 palm27x_asoc.dev = &pdev->dev; 141 palm27x_asoc.dev = &pdev->dev;
142 142
143 ret = snd_soc_register_card(&palm27x_asoc); 143 ret = devm_snd_soc_register_card(&pdev->dev, &palm27x_asoc);
144 if (ret) 144 if (ret)
145 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 145 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
146 ret); 146 ret);
147 return ret; 147 return ret;
148} 148}
149 149
150static int palm27x_asoc_remove(struct platform_device *pdev)
151{
152 snd_soc_unregister_card(&palm27x_asoc);
153 return 0;
154}
155
156static struct platform_driver palm27x_wm9712_driver = { 150static struct platform_driver palm27x_wm9712_driver = {
157 .probe = palm27x_asoc_probe, 151 .probe = palm27x_asoc_probe,
158 .remove = palm27x_asoc_remove,
159 .driver = { 152 .driver = {
160 .name = "palm27x-asoc", 153 .name = "palm27x-asoc",
161 .pm = &snd_soc_pm_ops, 154 .pm = &snd_soc_pm_ops,
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index 80b457ac522a..84d0e2e50808 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -267,28 +267,19 @@ static int poodle_probe(struct platform_device *pdev)
267 267
268 card->dev = &pdev->dev; 268 card->dev = &pdev->dev;
269 269
270 ret = snd_soc_register_card(card); 270 ret = devm_snd_soc_register_card(&pdev->dev, card);
271 if (ret) 271 if (ret)
272 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 272 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
273 ret); 273 ret);
274 return ret; 274 return ret;
275} 275}
276 276
277static int poodle_remove(struct platform_device *pdev)
278{
279 struct snd_soc_card *card = platform_get_drvdata(pdev);
280
281 snd_soc_unregister_card(card);
282 return 0;
283}
284
285static struct platform_driver poodle_driver = { 277static struct platform_driver poodle_driver = {
286 .driver = { 278 .driver = {
287 .name = "poodle-audio", 279 .name = "poodle-audio",
288 .pm = &snd_soc_pm_ops, 280 .pm = &snd_soc_pm_ops,
289 }, 281 },
290 .probe = poodle_probe, 282 .probe = poodle_probe,
291 .remove = poodle_remove,
292}; 283};
293 284
294module_platform_driver(poodle_driver); 285module_platform_driver(poodle_driver);
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 3da485ec1de7..da03fad1b9cd 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -809,6 +809,7 @@ static const struct of_device_id pxa_ssp_of_ids[] = {
809 { .compatible = "mrvl,pxa-ssp-dai" }, 809 { .compatible = "mrvl,pxa-ssp-dai" },
810 {} 810 {}
811}; 811};
812MODULE_DEVICE_TABLE(of, pxa_ssp_of_ids);
812#endif 813#endif
813 814
814static int asoc_ssp_probe(struct platform_device *pdev) 815static int asoc_ssp_probe(struct platform_device *pdev)
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index 1f6054650991..f3de615aacd7 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/dmaengine.h> 17#include <linux/dmaengine.h>
18#include <linux/dma/pxa-dma.h>
18 19
19#include <sound/core.h> 20#include <sound/core.h>
20#include <sound/ac97_codec.h> 21#include <sound/ac97_codec.h>
@@ -49,7 +50,11 @@ static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
49 .reset = pxa2xx_ac97_cold_reset, 50 .reset = pxa2xx_ac97_cold_reset,
50}; 51};
51 52
52static unsigned long pxa2xx_ac97_pcm_stereo_in_req = 12; 53static struct pxad_param pxa2xx_ac97_pcm_stereo_in_req = {
54 .prio = PXAD_PRIO_LOWEST,
55 .drcmr = 11,
56};
57
53static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_in = { 58static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_in = {
54 .addr = __PREG(PCDR), 59 .addr = __PREG(PCDR),
55 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 60 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
@@ -57,7 +62,11 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_in = {
57 .filter_data = &pxa2xx_ac97_pcm_stereo_in_req, 62 .filter_data = &pxa2xx_ac97_pcm_stereo_in_req,
58}; 63};
59 64
60static unsigned long pxa2xx_ac97_pcm_stereo_out_req = 11; 65static struct pxad_param pxa2xx_ac97_pcm_stereo_out_req = {
66 .prio = PXAD_PRIO_LOWEST,
67 .drcmr = 12,
68};
69
61static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_out = { 70static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_out = {
62 .addr = __PREG(PCDR), 71 .addr = __PREG(PCDR),
63 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, 72 .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
@@ -65,7 +74,10 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_out = {
65 .filter_data = &pxa2xx_ac97_pcm_stereo_out_req, 74 .filter_data = &pxa2xx_ac97_pcm_stereo_out_req,
66}; 75};
67 76
68static unsigned long pxa2xx_ac97_pcm_aux_mono_out_req = 10; 77static struct pxad_param pxa2xx_ac97_pcm_aux_mono_out_req = {
78 .prio = PXAD_PRIO_LOWEST,
79 .drcmr = 10,
80};
69static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_out = { 81static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_out = {
70 .addr = __PREG(MODR), 82 .addr = __PREG(MODR),
71 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, 83 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
@@ -73,7 +85,10 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_out = {
73 .filter_data = &pxa2xx_ac97_pcm_aux_mono_out_req, 85 .filter_data = &pxa2xx_ac97_pcm_aux_mono_out_req,
74}; 86};
75 87
76static unsigned long pxa2xx_ac97_pcm_aux_mono_in_req = 9; 88static struct pxad_param pxa2xx_ac97_pcm_aux_mono_in_req = {
89 .prio = PXAD_PRIO_LOWEST,
90 .drcmr = 9,
91};
77static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_in = { 92static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_in = {
78 .addr = __PREG(MODR), 93 .addr = __PREG(MODR),
79 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, 94 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
@@ -81,7 +96,10 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_in = {
81 .filter_data = &pxa2xx_ac97_pcm_aux_mono_in_req, 96 .filter_data = &pxa2xx_ac97_pcm_aux_mono_in_req,
82}; 97};
83 98
84static unsigned long pxa2xx_ac97_pcm_aux_mic_mono_req = 8; 99static struct pxad_param pxa2xx_ac97_pcm_aux_mic_mono_req = {
100 .prio = PXAD_PRIO_LOWEST,
101 .drcmr = 8,
102};
85static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_mic_mono_in = { 103static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_mic_mono_in = {
86 .addr = __PREG(MCDR), 104 .addr = __PREG(MCDR),
87 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, 105 .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES,
@@ -89,9 +107,8 @@ static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_mic_mono_in = {
89 .filter_data = &pxa2xx_ac97_pcm_aux_mic_mono_req, 107 .filter_data = &pxa2xx_ac97_pcm_aux_mic_mono_req,
90}; 108};
91 109
92static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, 110static int pxa2xx_ac97_hifi_startup(struct snd_pcm_substream *substream,
93 struct snd_pcm_hw_params *params, 111 struct snd_soc_dai *cpu_dai)
94 struct snd_soc_dai *cpu_dai)
95{ 112{
96 struct snd_dmaengine_dai_dma_data *dma_data; 113 struct snd_dmaengine_dai_dma_data *dma_data;
97 114
@@ -105,9 +122,8 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
105 return 0; 122 return 0;
106} 123}
107 124
108static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream, 125static int pxa2xx_ac97_aux_startup(struct snd_pcm_substream *substream,
109 struct snd_pcm_hw_params *params, 126 struct snd_soc_dai *cpu_dai)
110 struct snd_soc_dai *cpu_dai)
111{ 127{
112 struct snd_dmaengine_dai_dma_data *dma_data; 128 struct snd_dmaengine_dai_dma_data *dma_data;
113 129
@@ -121,9 +137,8 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
121 return 0; 137 return 0;
122} 138}
123 139
124static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, 140static int pxa2xx_ac97_mic_startup(struct snd_pcm_substream *substream,
125 struct snd_pcm_hw_params *params, 141 struct snd_soc_dai *cpu_dai)
126 struct snd_soc_dai *cpu_dai)
127{ 142{
128 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 143 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
129 return -ENODEV; 144 return -ENODEV;
@@ -139,15 +154,15 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
139 SNDRV_PCM_RATE_48000) 154 SNDRV_PCM_RATE_48000)
140 155
141static const struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = { 156static const struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = {
142 .hw_params = pxa2xx_ac97_hw_params, 157 .startup = pxa2xx_ac97_hifi_startup,
143}; 158};
144 159
145static const struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = { 160static const struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = {
146 .hw_params = pxa2xx_ac97_hw_aux_params, 161 .startup = pxa2xx_ac97_aux_startup,
147}; 162};
148 163
149static const struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = { 164static const struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = {
150 .hw_params = pxa2xx_ac97_hw_mic_params, 165 .startup = pxa2xx_ac97_mic_startup,
151}; 166};
152 167
153/* 168/*
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 6b4e40036910..0389cf7b4b1e 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -319,6 +319,9 @@ static int pxa2xx_i2s_probe(struct snd_soc_dai *dai)
319 /* Along with FIFO servicing */ 319 /* Along with FIFO servicing */
320 SAIMR &= ~(SAIMR_RFS | SAIMR_TFS); 320 SAIMR &= ~(SAIMR_RFS | SAIMR_TFS);
321 321
322 snd_soc_dai_init_dma_data(dai, &pxa2xx_i2s_pcm_stereo_out,
323 &pxa2xx_i2s_pcm_stereo_in);
324
322 return 0; 325 return 0;
323} 326}
324 327
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index 831ee37d2e3e..9f390398d518 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -15,8 +15,6 @@
15#include <linux/dmaengine.h> 15#include <linux/dmaengine.h>
16#include <linux/of.h> 16#include <linux/of.h>
17 17
18#include <mach/dma.h>
19
20#include <sound/core.h> 18#include <sound/core.h>
21#include <sound/soc.h> 19#include <sound/soc.h>
22#include <sound/pxa2xx-lib.h> 20#include <sound/pxa2xx-lib.h>
@@ -27,11 +25,8 @@
27static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, 25static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
28 struct snd_pcm_hw_params *params) 26 struct snd_pcm_hw_params *params)
29{ 27{
30 struct snd_pcm_runtime *runtime = substream->runtime;
31 struct pxa2xx_runtime_data *prtd = runtime->private_data;
32 struct snd_soc_pcm_runtime *rtd = substream->private_data; 28 struct snd_soc_pcm_runtime *rtd = substream->private_data;
33 struct snd_dmaengine_dai_dma_data *dma; 29 struct snd_dmaengine_dai_dma_data *dma;
34 int ret;
35 30
36 dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 31 dma = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
37 32
@@ -40,40 +35,13 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
40 if (!dma) 35 if (!dma)
41 return 0; 36 return 0;
42 37
43 /* this may get called several times by oss emulation
44 * with different params */
45 if (prtd->params == NULL) {
46 prtd->params = dma;
47 ret = pxa_request_dma("name", DMA_PRIO_LOW,
48 pxa2xx_pcm_dma_irq, substream);
49 if (ret < 0)
50 return ret;
51 prtd->dma_ch = ret;
52 } else if (prtd->params != dma) {
53 pxa_free_dma(prtd->dma_ch);
54 prtd->params = dma;
55 ret = pxa_request_dma("name", DMA_PRIO_LOW,
56 pxa2xx_pcm_dma_irq, substream);
57 if (ret < 0)
58 return ret;
59 prtd->dma_ch = ret;
60 }
61
62 return __pxa2xx_pcm_hw_params(substream, params); 38 return __pxa2xx_pcm_hw_params(substream, params);
63} 39}
64 40
65static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) 41static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
66{ 42{
67 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
68
69 __pxa2xx_pcm_hw_free(substream); 43 __pxa2xx_pcm_hw_free(substream);
70 44
71 if (prtd->dma_ch >= 0) {
72 pxa_free_dma(prtd->dma_ch);
73 prtd->dma_ch = -1;
74 prtd->params = NULL;
75 }
76
77 return 0; 45 return 0;
78} 46}
79 47
@@ -132,6 +100,7 @@ static const struct of_device_id snd_soc_pxa_audio_match[] = {
132 { .compatible = "mrvl,pxa-pcm-audio" }, 100 { .compatible = "mrvl,pxa-pcm-audio" },
133 { } 101 { }
134}; 102};
103MODULE_DEVICE_TABLE(of, snd_soc_pxa_audio_match);
135#endif 104#endif
136 105
137static struct platform_driver pxa_pcm_driver = { 106static struct platform_driver pxa_pcm_driver = {
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 461123ad5ff2..b00222620fd0 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -305,7 +305,7 @@ static int spitz_probe(struct platform_device *pdev)
305 305
306 card->dev = &pdev->dev; 306 card->dev = &pdev->dev;
307 307
308 ret = snd_soc_register_card(card); 308 ret = devm_snd_soc_register_card(&pdev->dev, card);
309 if (ret) { 309 if (ret) {
310 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 310 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
311 ret); 311 ret);
@@ -322,9 +322,6 @@ err1:
322 322
323static int spitz_remove(struct platform_device *pdev) 323static int spitz_remove(struct platform_device *pdev)
324{ 324{
325 struct snd_soc_card *card = platform_get_drvdata(pdev);
326
327 snd_soc_unregister_card(card);
328 gpio_free(spitz_mic_gpio); 325 gpio_free(spitz_mic_gpio);
329 return 0; 326 return 0;
330} 327}
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index f59f566551ef..49518dd642aa 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -233,7 +233,7 @@ static int tosa_probe(struct platform_device *pdev)
233 233
234 card->dev = &pdev->dev; 234 card->dev = &pdev->dev;
235 235
236 ret = snd_soc_register_card(card); 236 ret = devm_snd_soc_register_card(&pdev->dev, card);
237 if (ret) { 237 if (ret) {
238 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 238 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
239 ret); 239 ret);
@@ -244,10 +244,7 @@ static int tosa_probe(struct platform_device *pdev)
244 244
245static int tosa_remove(struct platform_device *pdev) 245static int tosa_remove(struct platform_device *pdev)
246{ 246{
247 struct snd_soc_card *card = platform_get_drvdata(pdev);
248
249 gpio_free(TOSA_GPIO_L_MUTE); 247 gpio_free(TOSA_GPIO_L_MUTE);
250 snd_soc_unregister_card(card);
251 return 0; 248 return 0;
252} 249}
253 250
diff --git a/sound/soc/pxa/ttc-dkb.c b/sound/soc/pxa/ttc-dkb.c
index 1753c7d9e760..65c20f779177 100644
--- a/sound/soc/pxa/ttc-dkb.c
+++ b/sound/soc/pxa/ttc-dkb.c
@@ -128,7 +128,7 @@ static int ttc_dkb_probe(struct platform_device *pdev)
128 128
129 card->dev = &pdev->dev; 129 card->dev = &pdev->dev;
130 130
131 ret = snd_soc_register_card(card); 131 ret = devm_snd_soc_register_card(&pdev->dev, card);
132 if (ret) 132 if (ret)
133 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", 133 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
134 ret); 134 ret);
@@ -136,22 +136,12 @@ static int ttc_dkb_probe(struct platform_device *pdev)
136 return ret; 136 return ret;
137} 137}
138 138
139static int ttc_dkb_remove(struct platform_device *pdev)
140{
141 struct snd_soc_card *card = platform_get_drvdata(pdev);
142
143 snd_soc_unregister_card(card);
144
145 return 0;
146}
147
148static struct platform_driver ttc_dkb_driver = { 139static struct platform_driver ttc_dkb_driver = {
149 .driver = { 140 .driver = {
150 .name = "ttc-dkb-audio", 141 .name = "ttc-dkb-audio",
151 .pm = &snd_soc_pm_ops, 142 .pm = &snd_soc_pm_ops,
152 }, 143 },
153 .probe = ttc_dkb_probe, 144 .probe = ttc_dkb_probe,
154 .remove = ttc_dkb_remove,
155}; 145};
156 146
157module_platform_driver(ttc_dkb_driver); 147module_platform_driver(ttc_dkb_driver);
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
index 97bc2023f08a..e5101e0d2d37 100644
--- a/sound/soc/qcom/lpass-cpu.c
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -438,7 +438,8 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
438 if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) { 438 if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) {
439 dev_err(&pdev->dev, 439 dev_err(&pdev->dev,
440 "%s() error getting mi2s-bit-clk: %ld\n", 440 "%s() error getting mi2s-bit-clk: %ld\n",
441 __func__, PTR_ERR(drvdata->mi2s_bit_clk[i])); 441 __func__,
442 PTR_ERR(drvdata->mi2s_bit_clk[dai_id]));
442 return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]); 443 return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]);
443 } 444 }
444 } 445 }
diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig
index 58bae8e2cf5f..f1e0c703e0d2 100644
--- a/sound/soc/rockchip/Kconfig
+++ b/sound/soc/rockchip/Kconfig
@@ -15,9 +15,17 @@ config SND_SOC_ROCKCHIP_I2S
15 Rockchip I2S device. The device supports upto maximum of 15 Rockchip I2S device. The device supports upto maximum of
16 8 channels each for play and record. 16 8 channels each for play and record.
17 17
18config SND_SOC_ROCKCHIP_SPDIF
19 tristate "Rockchip SPDIF Device Driver"
20 depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP
21 select SND_SOC_GENERIC_DMAENGINE_PCM
22 help
23 Say Y or M if you want to add support for SPDIF driver for
24 Rockchip SPDIF transceiver device.
25
18config SND_SOC_ROCKCHIP_MAX98090 26config SND_SOC_ROCKCHIP_MAX98090
19 tristate "ASoC support for Rockchip boards using a MAX98090 codec" 27 tristate "ASoC support for Rockchip boards using a MAX98090 codec"
20 depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB 28 depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP
21 select SND_SOC_ROCKCHIP_I2S 29 select SND_SOC_ROCKCHIP_I2S
22 select SND_SOC_MAX98090 30 select SND_SOC_MAX98090
23 select SND_SOC_TS3A227E 31 select SND_SOC_TS3A227E
@@ -27,7 +35,7 @@ config SND_SOC_ROCKCHIP_MAX98090
27 35
28config SND_SOC_ROCKCHIP_RT5645 36config SND_SOC_ROCKCHIP_RT5645
29 tristate "ASoC support for Rockchip boards using a RT5645/RT5650 codec" 37 tristate "ASoC support for Rockchip boards using a RT5645/RT5650 codec"
30 depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB 38 depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP
31 select SND_SOC_ROCKCHIP_I2S 39 select SND_SOC_ROCKCHIP_I2S
32 select SND_SOC_RT5645 40 select SND_SOC_RT5645
33 help 41 help
diff --git a/sound/soc/rockchip/Makefile b/sound/soc/rockchip/Makefile
index 1bc1dc3c729a..c0bf560125f3 100644
--- a/sound/soc/rockchip/Makefile
+++ b/sound/soc/rockchip/Makefile
@@ -1,7 +1,9 @@
1# ROCKCHIP Platform Support 1# ROCKCHIP Platform Support
2snd-soc-i2s-objs := rockchip_i2s.o 2snd-soc-rockchip-i2s-objs := rockchip_i2s.o
3snd-soc-rockchip-spdif-objs := rockchip_spdif.o
3 4
4obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-i2s.o 5obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-rockchip-i2s.o
6obj-$(CONFIG_SND_SOC_ROCKCHIP_SPDIF) += snd-soc-rockchip-spdif.o
5 7
6snd-soc-rockchip-max98090-objs := rockchip_max98090.o 8snd-soc-rockchip-max98090-objs := rockchip_max98090.o
7snd-soc-rockchip-rt5645-objs := rockchip_rt5645.o 9snd-soc-rockchip-rt5645-objs := rockchip_rt5645.o
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index b93610212e3d..58ee64594f07 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -226,6 +226,7 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
226 struct snd_soc_dai *dai) 226 struct snd_soc_dai *dai)
227{ 227{
228 struct rk_i2s_dev *i2s = to_info(dai); 228 struct rk_i2s_dev *i2s = to_info(dai);
229 struct snd_soc_pcm_runtime *rtd = substream->private_data;
229 unsigned int val = 0; 230 unsigned int val = 0;
230 231
231 switch (params_format(params)) { 232 switch (params_format(params)) {
@@ -245,13 +246,46 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
245 return -EINVAL; 246 return -EINVAL;
246 } 247 }
247 248
248 regmap_update_bits(i2s->regmap, I2S_TXCR, I2S_TXCR_VDW_MASK, val); 249 switch (params_channels(params)) {
249 regmap_update_bits(i2s->regmap, I2S_RXCR, I2S_RXCR_VDW_MASK, val); 250 case 8:
251 val |= I2S_CHN_8;
252 break;
253 case 6:
254 val |= I2S_CHN_6;
255 break;
256 case 4:
257 val |= I2S_CHN_4;
258 break;
259 case 2:
260 val |= I2S_CHN_2;
261 break;
262 default:
263 dev_err(i2s->dev, "invalid channel: %d\n",
264 params_channels(params));
265 return -EINVAL;
266 }
267
268 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
269 regmap_update_bits(i2s->regmap, I2S_RXCR,
270 I2S_RXCR_VDW_MASK | I2S_RXCR_CSR_MASK,
271 val);
272 else
273 regmap_update_bits(i2s->regmap, I2S_TXCR,
274 I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK,
275 val);
276
250 regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK, 277 regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,
251 I2S_DMACR_TDL(16)); 278 I2S_DMACR_TDL(16));
252 regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK, 279 regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK,
253 I2S_DMACR_RDL(16)); 280 I2S_DMACR_RDL(16));
254 281
282 val = I2S_CKR_TRCM_TXRX;
283 if (dai->driver->symmetric_rates || rtd->dai_link->symmetric_rates)
284 val = I2S_CKR_TRCM_TXSHARE;
285
286 regmap_update_bits(i2s->regmap, I2S_CKR,
287 I2S_CKR_TRCM_MASK,
288 val);
255 return 0; 289 return 0;
256} 290}
257 291
@@ -415,10 +449,12 @@ static const struct regmap_config rockchip_i2s_regmap_config = {
415 449
416static int rockchip_i2s_probe(struct platform_device *pdev) 450static int rockchip_i2s_probe(struct platform_device *pdev)
417{ 451{
452 struct device_node *node = pdev->dev.of_node;
418 struct rk_i2s_dev *i2s; 453 struct rk_i2s_dev *i2s;
419 struct resource *res; 454 struct resource *res;
420 void __iomem *regs; 455 void __iomem *regs;
421 int ret; 456 int ret;
457 int val;
422 458
423 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); 459 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
424 if (!i2s) { 460 if (!i2s) {
@@ -475,6 +511,14 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
475 goto err_pm_disable; 511 goto err_pm_disable;
476 } 512 }
477 513
514 /* refine capture channels */
515 if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) {
516 if (val >= 2 && val <= 8)
517 rockchip_i2s_dai.capture.channels_max = val;
518 else
519 rockchip_i2s_dai.capture.channels_max = 2;
520 }
521
478 ret = devm_snd_soc_register_component(&pdev->dev, 522 ret = devm_snd_soc_register_component(&pdev->dev,
479 &rockchip_i2s_component, 523 &rockchip_i2s_component,
480 &rockchip_i2s_dai, 1); 524 &rockchip_i2s_dai, 1);
diff --git a/sound/soc/rockchip/rockchip_i2s.h b/sound/soc/rockchip/rockchip_i2s.h
index 93f456f518a9..dc6e2c74d088 100644
--- a/sound/soc/rockchip/rockchip_i2s.h
+++ b/sound/soc/rockchip/rockchip_i2s.h
@@ -49,6 +49,9 @@
49 * RXCR 49 * RXCR
50 * receive operation control register 50 * receive operation control register
51*/ 51*/
52#define I2S_RXCR_CSR_SHIFT 15
53#define I2S_RXCR_CSR(x) (x << I2S_RXCR_CSR_SHIFT)
54#define I2S_RXCR_CSR_MASK (3 << I2S_RXCR_CSR_SHIFT)
52#define I2S_RXCR_HWT BIT(14) 55#define I2S_RXCR_HWT BIT(14)
53#define I2S_RXCR_SJM_SHIFT 12 56#define I2S_RXCR_SJM_SHIFT 12
54#define I2S_RXCR_SJM_R (0 << I2S_RXCR_SJM_SHIFT) 57#define I2S_RXCR_SJM_R (0 << I2S_RXCR_SJM_SHIFT)
@@ -75,6 +78,12 @@
75 * CKR 78 * CKR
76 * clock generation register 79 * clock generation register
77*/ 80*/
81#define I2S_CKR_TRCM_SHIFT 28
82#define I2S_CKR_TRCM(x) (x << I2S_CKR_TRCM_SHIFT)
83#define I2S_CKR_TRCM_TXRX (0 << I2S_CKR_TRCM_SHIFT)
84#define I2S_CKR_TRCM_TXSHARE (1 << I2S_CKR_TRCM_SHIFT)
85#define I2S_CKR_TRCM_RXSHARE (2 << I2S_CKR_TRCM_SHIFT)
86#define I2S_CKR_TRCM_MASK (3 << I2S_CKR_TRCM_SHIFT)
78#define I2S_CKR_MSS_SHIFT 27 87#define I2S_CKR_MSS_SHIFT 27
79#define I2S_CKR_MSS_MASTER (0 << I2S_CKR_MSS_SHIFT) 88#define I2S_CKR_MSS_MASTER (0 << I2S_CKR_MSS_SHIFT)
80#define I2S_CKR_MSS_SLAVE (1 << I2S_CKR_MSS_SHIFT) 89#define I2S_CKR_MSS_SLAVE (1 << I2S_CKR_MSS_SHIFT)
@@ -207,6 +216,13 @@ enum {
207 ROCKCHIP_DIV_BCLK, 216 ROCKCHIP_DIV_BCLK,
208}; 217};
209 218
219/* channel select */
220#define I2S_CSR_SHIFT 15
221#define I2S_CHN_2 (0 << I2S_CSR_SHIFT)
222#define I2S_CHN_4 (1 << I2S_CSR_SHIFT)
223#define I2S_CHN_6 (2 << I2S_CSR_SHIFT)
224#define I2S_CHN_8 (3 << I2S_CSR_SHIFT)
225
210/* I2S REGS */ 226/* I2S REGS */
211#define I2S_TXCR (0x0000) 227#define I2S_TXCR (0x0000)
212#define I2S_RXCR (0x0004) 228#define I2S_RXCR (0x0004)
diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c
new file mode 100644
index 000000000000..a38a3029062c
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_spdif.c
@@ -0,0 +1,405 @@
1/* sound/soc/rockchip/rk_spdif.c
2 *
3 * ALSA SoC Audio Layer - Rockchip I2S Controller driver
4 *
5 * Copyright (c) 2014 Rockchip Electronics Co. Ltd.
6 * Author: Jianqun <jay.xu@rock-chips.com>
7 * Copyright (c) 2015 Collabora Ltd.
8 * Author: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/delay.h>
17#include <linux/of_gpio.h>
18#include <linux/clk.h>
19#include <linux/pm_runtime.h>
20#include <linux/mfd/syscon.h>
21#include <linux/regmap.h>
22#include <sound/pcm_params.h>
23#include <sound/dmaengine_pcm.h>
24
25#include "rockchip_spdif.h"
26
27enum rk_spdif_type {
28 RK_SPDIF_RK3066,
29 RK_SPDIF_RK3188,
30 RK_SPDIF_RK3288,
31};
32
33#define RK3288_GRF_SOC_CON2 0x24c
34
35struct rk_spdif_dev {
36 struct device *dev;
37
38 struct clk *mclk;
39 struct clk *hclk;
40
41 struct snd_dmaengine_dai_dma_data playback_dma_data;
42
43 struct regmap *regmap;
44};
45
46static const struct of_device_id rk_spdif_match[] = {
47 { .compatible = "rockchip,rk3066-spdif",
48 .data = (void *) RK_SPDIF_RK3066 },
49 { .compatible = "rockchip,rk3188-spdif",
50 .data = (void *) RK_SPDIF_RK3188 },
51 { .compatible = "rockchip,rk3288-spdif",
52 .data = (void *) RK_SPDIF_RK3288 },
53 {},
54};
55MODULE_DEVICE_TABLE(of, rk_spdif_match);
56
57static int rk_spdif_runtime_suspend(struct device *dev)
58{
59 struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
60
61 clk_disable_unprepare(spdif->mclk);
62 clk_disable_unprepare(spdif->hclk);
63
64 return 0;
65}
66
67static int rk_spdif_runtime_resume(struct device *dev)
68{
69 struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
70 int ret;
71
72 ret = clk_prepare_enable(spdif->mclk);
73 if (ret) {
74 dev_err(spdif->dev, "mclk clock enable failed %d\n", ret);
75 return ret;
76 }
77
78 ret = clk_prepare_enable(spdif->hclk);
79 if (ret) {
80 dev_err(spdif->dev, "hclk clock enable failed %d\n", ret);
81 return ret;
82 }
83
84 return 0;
85}
86
87static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
88 struct snd_pcm_hw_params *params,
89 struct snd_soc_dai *dai)
90{
91 struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
92 unsigned int val = SPDIF_CFGR_HALFWORD_ENABLE;
93 int srate, mclk;
94 int ret;
95
96 srate = params_rate(params);
97 switch (srate) {
98 case 32000:
99 case 48000:
100 case 96000:
101 mclk = 96000 * 128; /* 12288000 hz */
102 break;
103 case 44100:
104 mclk = 44100 * 256; /* 11289600 hz */
105 break;
106 case 192000:
107 mclk = 192000 * 128; /* 24576000 hz */
108 break;
109 default:
110 return -EINVAL;
111 }
112
113 switch (params_format(params)) {
114 case SNDRV_PCM_FORMAT_S16_LE:
115 val |= SPDIF_CFGR_VDW_16;
116 break;
117 case SNDRV_PCM_FORMAT_S20_3LE:
118 val |= SPDIF_CFGR_VDW_20;
119 break;
120 case SNDRV_PCM_FORMAT_S24_LE:
121 val |= SPDIF_CFGR_VDW_24;
122 break;
123 default:
124 return -EINVAL;
125 }
126
127 /* Set clock and calculate divider */
128 ret = clk_set_rate(spdif->mclk, mclk);
129 if (ret != 0) {
130 dev_err(spdif->dev, "Failed to set module clock rate: %d\n",
131 ret);
132 return ret;
133 }
134
135 val |= SPDIF_CFGR_CLK_DIV(mclk/(srate * 256));
136 ret = regmap_update_bits(spdif->regmap, SPDIF_CFGR,
137 SPDIF_CFGR_CLK_DIV_MASK | SPDIF_CFGR_HALFWORD_ENABLE |
138 SDPIF_CFGR_VDW_MASK,
139 val);
140
141 return ret;
142}
143
144static int rk_spdif_trigger(struct snd_pcm_substream *substream,
145 int cmd, struct snd_soc_dai *dai)
146{
147 struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
148 int ret;
149
150 switch (cmd) {
151 case SNDRV_PCM_TRIGGER_START:
152 case SNDRV_PCM_TRIGGER_RESUME:
153 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
154 ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
155 SPDIF_DMACR_TDE_ENABLE,
156 SPDIF_DMACR_TDE_ENABLE);
157
158 if (ret != 0)
159 return ret;
160
161 ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
162 SPDIF_XFER_TXS_START,
163 SPDIF_XFER_TXS_START);
164 break;
165 case SNDRV_PCM_TRIGGER_SUSPEND:
166 case SNDRV_PCM_TRIGGER_STOP:
167 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
168 ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
169 SPDIF_DMACR_TDE_ENABLE,
170 SPDIF_DMACR_TDE_DISABLE);
171
172 if (ret != 0)
173 return ret;
174
175 ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
176 SPDIF_XFER_TXS_START,
177 SPDIF_XFER_TXS_STOP);
178 break;
179 default:
180 ret = -EINVAL;
181 break;
182 }
183
184 return ret;
185}
186
187static int rk_spdif_dai_probe(struct snd_soc_dai *dai)
188{
189 struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
190
191 dai->playback_dma_data = &spdif->playback_dma_data;
192
193 return 0;
194}
195
196static const struct snd_soc_dai_ops rk_spdif_dai_ops = {
197 .hw_params = rk_spdif_hw_params,
198 .trigger = rk_spdif_trigger,
199};
200
201static struct snd_soc_dai_driver rk_spdif_dai = {
202 .probe = rk_spdif_dai_probe,
203 .playback = {
204 .stream_name = "Playback",
205 .channels_min = 2,
206 .channels_max = 2,
207 .rates = (SNDRV_PCM_RATE_32000 |
208 SNDRV_PCM_RATE_44100 |
209 SNDRV_PCM_RATE_48000 |
210 SNDRV_PCM_RATE_96000 |
211 SNDRV_PCM_RATE_192000),
212 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
213 SNDRV_PCM_FMTBIT_S20_3LE |
214 SNDRV_PCM_FMTBIT_S24_LE),
215 },
216 .ops = &rk_spdif_dai_ops,
217};
218
219static const struct snd_soc_component_driver rk_spdif_component = {
220 .name = "rockchip-spdif",
221};
222
223static bool rk_spdif_wr_reg(struct device *dev, unsigned int reg)
224{
225 switch (reg) {
226 case SPDIF_CFGR:
227 case SPDIF_DMACR:
228 case SPDIF_INTCR:
229 case SPDIF_XFER:
230 case SPDIF_SMPDR:
231 return true;
232 default:
233 return false;
234 }
235}
236
237static bool rk_spdif_rd_reg(struct device *dev, unsigned int reg)
238{
239 switch (reg) {
240 case SPDIF_CFGR:
241 case SPDIF_SDBLR:
242 case SPDIF_INTCR:
243 case SPDIF_INTSR:
244 case SPDIF_XFER:
245 return true;
246 default:
247 return false;
248 }
249}
250
251static bool rk_spdif_volatile_reg(struct device *dev, unsigned int reg)
252{
253 switch (reg) {
254 case SPDIF_INTSR:
255 case SPDIF_SDBLR:
256 return true;
257 default:
258 return false;
259 }
260}
261
262static const struct regmap_config rk_spdif_regmap_config = {
263 .reg_bits = 32,
264 .reg_stride = 4,
265 .val_bits = 32,
266 .max_register = SPDIF_SMPDR,
267 .writeable_reg = rk_spdif_wr_reg,
268 .readable_reg = rk_spdif_rd_reg,
269 .volatile_reg = rk_spdif_volatile_reg,
270 .cache_type = REGCACHE_FLAT,
271};
272
273static int rk_spdif_probe(struct platform_device *pdev)
274{
275 struct device_node *np = pdev->dev.of_node;
276 struct rk_spdif_dev *spdif;
277 const struct of_device_id *match;
278 struct resource *res;
279 void __iomem *regs;
280 int ret;
281
282 match = of_match_node(rk_spdif_match, np);
283 if ((int) match->data == RK_SPDIF_RK3288) {
284 struct regmap *grf;
285
286 grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
287 if (IS_ERR(grf)) {
288 dev_err(&pdev->dev,
289 "rockchip_spdif missing 'rockchip,grf' \n");
290 return PTR_ERR(grf);
291 }
292
293 /* Select the 8 channel SPDIF solution on RK3288 as
294 * the 2 channel one does not appear to work
295 */
296 regmap_write(grf, RK3288_GRF_SOC_CON2, BIT(1) << 16);
297 }
298
299 spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
300 if (!spdif)
301 return -ENOMEM;
302
303 spdif->hclk = devm_clk_get(&pdev->dev, "hclk");
304 if (IS_ERR(spdif->hclk)) {
305 dev_err(&pdev->dev, "Can't retrieve rk_spdif bus clock\n");
306 return PTR_ERR(spdif->hclk);
307 }
308 ret = clk_prepare_enable(spdif->hclk);
309 if (ret) {
310 dev_err(spdif->dev, "hclock enable failed %d\n", ret);
311 return ret;
312 }
313
314 spdif->mclk = devm_clk_get(&pdev->dev, "mclk");
315 if (IS_ERR(spdif->mclk)) {
316 dev_err(&pdev->dev, "Can't retrieve rk_spdif master clock\n");
317 return PTR_ERR(spdif->mclk);
318 }
319
320 ret = clk_prepare_enable(spdif->mclk);
321 if (ret) {
322 dev_err(spdif->dev, "clock enable failed %d\n", ret);
323 return ret;
324 }
325
326 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
327 regs = devm_ioremap_resource(&pdev->dev, res);
328 if (IS_ERR(regs))
329 return PTR_ERR(regs);
330
331 spdif->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "hclk", regs,
332 &rk_spdif_regmap_config);
333 if (IS_ERR(spdif->regmap)) {
334 dev_err(&pdev->dev,
335 "Failed to initialise managed register map\n");
336 return PTR_ERR(spdif->regmap);
337 }
338
339 spdif->playback_dma_data.addr = res->start + SPDIF_SMPDR;
340 spdif->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
341 spdif->playback_dma_data.maxburst = 4;
342
343 spdif->dev = &pdev->dev;
344 dev_set_drvdata(&pdev->dev, spdif);
345
346 pm_runtime_set_active(&pdev->dev);
347 pm_runtime_enable(&pdev->dev);
348 pm_request_idle(&pdev->dev);
349
350 ret = devm_snd_soc_register_component(&pdev->dev,
351 &rk_spdif_component,
352 &rk_spdif_dai, 1);
353 if (ret) {
354 dev_err(&pdev->dev, "Could not register DAI\n");
355 goto err_pm_runtime;
356 }
357
358 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
359 if (ret) {
360 dev_err(&pdev->dev, "Could not register PCM\n");
361 goto err_pm_runtime;
362 }
363
364 return 0;
365
366err_pm_runtime:
367 pm_runtime_disable(&pdev->dev);
368
369 return ret;
370}
371
372static int rk_spdif_remove(struct platform_device *pdev)
373{
374 struct rk_spdif_dev *spdif = dev_get_drvdata(&pdev->dev);
375
376 pm_runtime_disable(&pdev->dev);
377 if (!pm_runtime_status_suspended(&pdev->dev))
378 rk_spdif_runtime_suspend(&pdev->dev);
379
380 clk_disable_unprepare(spdif->mclk);
381 clk_disable_unprepare(spdif->hclk);
382
383 return 0;
384}
385
386static const struct dev_pm_ops rk_spdif_pm_ops = {
387 SET_RUNTIME_PM_OPS(rk_spdif_runtime_suspend, rk_spdif_runtime_resume,
388 NULL)
389};
390
391static struct platform_driver rk_spdif_driver = {
392 .probe = rk_spdif_probe,
393 .remove = rk_spdif_remove,
394 .driver = {
395 .name = "rockchip-spdif",
396 .of_match_table = of_match_ptr(rk_spdif_match),
397 .pm = &rk_spdif_pm_ops,
398 },
399};
400module_platform_driver(rk_spdif_driver);
401
402MODULE_ALIAS("platform:rockchip-spdif");
403MODULE_DESCRIPTION("ROCKCHIP SPDIF transceiver Interface");
404MODULE_AUTHOR("Sjoerd Simons <sjoerd.simons@collabora.co.uk>");
405MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/rockchip/rockchip_spdif.h b/sound/soc/rockchip/rockchip_spdif.h
new file mode 100644
index 000000000000..07f86a21046a
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_spdif.h
@@ -0,0 +1,63 @@
1/*
2 * ALSA SoC Audio Layer - Rockchip SPDIF transceiver driver
3 *
4 * Copyright (c) 2015 Collabora Ltd.
5 * Author: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef _ROCKCHIP_SPDIF_H
13#define _ROCKCHIP_SPDIF_H
14
15/*
16 * CFGR
17 * transfer configuration register
18*/
19#define SPDIF_CFGR_CLK_DIV_SHIFT (16)
20#define SPDIF_CFGR_CLK_DIV_MASK (0xff << SPDIF_CFGR_CLK_DIV_SHIFT)
21#define SPDIF_CFGR_CLK_DIV(x) (x << SPDIF_CFGR_CLK_DIV_SHIFT)
22
23#define SPDIF_CFGR_HALFWORD_SHIFT 2
24#define SPDIF_CFGR_HALFWORD_DISABLE (0 << SPDIF_CFGR_HALFWORD_SHIFT)
25#define SPDIF_CFGR_HALFWORD_ENABLE (1 << SPDIF_CFGR_HALFWORD_SHIFT)
26
27#define SPDIF_CFGR_VDW_SHIFT 0
28#define SPDIF_CFGR_VDW(x) (x << SPDIF_CFGR_VDW_SHIFT)
29#define SDPIF_CFGR_VDW_MASK (0xf << SPDIF_CFGR_VDW_SHIFT)
30
31#define SPDIF_CFGR_VDW_16 SPDIF_CFGR_VDW(0x00)
32#define SPDIF_CFGR_VDW_20 SPDIF_CFGR_VDW(0x01)
33#define SPDIF_CFGR_VDW_24 SPDIF_CFGR_VDW(0x10)
34
35/*
36 * DMACR
37 * DMA control register
38*/
39#define SPDIF_DMACR_TDE_SHIFT 5
40#define SPDIF_DMACR_TDE_DISABLE (0 << SPDIF_DMACR_TDE_SHIFT)
41#define SPDIF_DMACR_TDE_ENABLE (1 << SPDIF_DMACR_TDE_SHIFT)
42
43#define SPDIF_DMACR_TDL_SHIFT 0
44#define SPDIF_DMACR_TDL(x) ((x) << SPDIF_DMACR_TDL_SHIFT)
45#define SPDIF_DMACR_TDL_MASK (0x1f << SDPIF_DMACR_TDL_SHIFT)
46
47/*
48 * XFER
49 * Transfer control register
50*/
51#define SPDIF_XFER_TXS_SHIFT 0
52#define SPDIF_XFER_TXS_STOP (0 << SPDIF_XFER_TXS_SHIFT)
53#define SPDIF_XFER_TXS_START (1 << SPDIF_XFER_TXS_SHIFT)
54
55#define SPDIF_CFGR (0x0000)
56#define SPDIF_SDBLR (0x0004)
57#define SPDIF_DMACR (0x0008)
58#define SPDIF_INTCR (0x000c)
59#define SPDIF_INTSR (0x0010)
60#define SPDIF_XFER (0x0018)
61#define SPDIF_SMPDR (0x0020)
62
63#endif /* _ROCKCHIP_SPDIF_H */
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
index c72e9fb26658..5f5825faeb2a 100644
--- a/sound/soc/samsung/h1940_uda1380.c
+++ b/sound/soc/samsung/h1940_uda1380.c
@@ -26,16 +26,15 @@
26#include <mach/gpio-samsung.h> 26#include <mach/gpio-samsung.h>
27#include "s3c24xx-i2s.h" 27#include "s3c24xx-i2s.h"
28 28
29static unsigned int rates[] = { 29static const unsigned int rates[] = {
30 11025, 30 11025,
31 22050, 31 22050,
32 44100, 32 44100,
33}; 33};
34 34
35static struct snd_pcm_hw_constraint_list hw_rates = { 35static const struct snd_pcm_hw_constraint_list hw_rates = {
36 .count = ARRAY_SIZE(rates), 36 .count = ARRAY_SIZE(rates),
37 .list = rates, 37 .list = rates,
38 .mask = 0,
39}; 38};
40 39
41static struct snd_soc_jack hp_jack; 40static struct snd_soc_jack hp_jack;
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
index 35e37c457f1f..fa096abe9e75 100644
--- a/sound/soc/samsung/rx1950_uda1380.c
+++ b/sound/soc/samsung/rx1950_uda1380.c
@@ -38,16 +38,15 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream,
38static int rx1950_spk_power(struct snd_soc_dapm_widget *w, 38static int rx1950_spk_power(struct snd_soc_dapm_widget *w,
39 struct snd_kcontrol *kcontrol, int event); 39 struct snd_kcontrol *kcontrol, int event);
40 40
41static unsigned int rates[] = { 41static const unsigned int rates[] = {
42 16000, 42 16000,
43 44100, 43 44100,
44 48000, 44 48000,
45}; 45};
46 46
47static struct snd_pcm_hw_constraint_list hw_rates = { 47static const struct snd_pcm_hw_constraint_list hw_rates = {
48 .count = ARRAY_SIZE(rates), 48 .count = ARRAY_SIZE(rates),
49 .list = rates, 49 .list = rates,
50 .mask = 0,
51}; 50};
52 51
53static struct snd_soc_jack hp_jack; 52static struct snd_soc_jack hp_jack;
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 07114b0b0dc1..206d1edab07c 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -37,10 +37,11 @@ config SND_SOC_SH4_SIU
37config SND_SOC_RCAR 37config SND_SOC_RCAR
38 tristate "R-Car series SRU/SCU/SSIU/SSI support" 38 tristate "R-Car series SRU/SCU/SSIU/SSI support"
39 depends on DMA_OF 39 depends on DMA_OF
40 depends on COMMON_CLK
40 select SND_SIMPLE_CARD 41 select SND_SIMPLE_CARD
41 select REGMAP_MMIO 42 select REGMAP_MMIO
42 help 43 help
43 This option enables R-Car SUR/SCU/SSIU/SSI sound support 44 This option enables R-Car SRU/SCU/SSIU/SSI sound support
44 45
45config SND_SOC_RSRC_CARD 46config SND_SOC_RSRC_CARD
46 tristate "Renesas Sampling Rate Convert Sound Card" 47 tristate "Renesas Sampling Rate Convert Sound Card"
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index fefc881dbac2..2a5b3a293cd2 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -7,7 +7,7 @@
7 * License. See the file "COPYING" in the main directory of this archive 7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details. 8 * for more details.
9 */ 9 */
10#include <linux/sh_clk.h> 10#include <linux/clk-provider.h>
11#include "rsnd.h" 11#include "rsnd.h"
12 12
13#define CLKA 0 13#define CLKA 0
@@ -16,12 +16,26 @@
16#define CLKI 3 16#define CLKI 3
17#define CLKMAX 4 17#define CLKMAX 4
18 18
19#define CLKOUT 0
20#define CLKOUT1 1
21#define CLKOUT2 2
22#define CLKOUT3 3
23#define CLKOUTMAX 4
24
25#define BRRx_MASK(x) (0x3FF & x)
26
27static struct rsnd_mod_ops adg_ops = {
28 .name = "adg",
29};
30
19struct rsnd_adg { 31struct rsnd_adg {
20 struct clk *clk[CLKMAX]; 32 struct clk *clk[CLKMAX];
33 struct clk *clkout[CLKOUTMAX];
34 struct clk_onecell_data onecell;
35 struct rsnd_mod mod;
21 36
22 int rbga_rate_for_441khz_div_6; /* RBGA */ 37 int rbga_rate_for_441khz; /* RBGA */
23 int rbgb_rate_for_48khz_div_6; /* RBGB */ 38 int rbgb_rate_for_48khz; /* RBGB */
24 u32 ckr;
25}; 39};
26 40
27#define for_each_rsnd_clk(pos, adg, i) \ 41#define for_each_rsnd_clk(pos, adg, i) \
@@ -29,17 +43,36 @@ struct rsnd_adg {
29 (i < CLKMAX) && \ 43 (i < CLKMAX) && \
30 ((pos) = adg->clk[i]); \ 44 ((pos) = adg->clk[i]); \
31 i++) 45 i++)
46#define for_each_rsnd_clkout(pos, adg, i) \
47 for (i = 0; \
48 (i < CLKOUTMAX) && \
49 ((pos) = adg->clkout[i]); \
50 i++)
32#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg) 51#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)
33 52
53static u32 rsnd_adg_calculate_rbgx(unsigned long div)
54{
55 int i, ratio;
56
57 if (!div)
58 return 0;
59
60 for (i = 3; i >= 0; i--) {
61 ratio = 2 << (i * 2);
62 if (0 == (div % ratio))
63 return (u32)((i << 8) | ((div / ratio) - 1));
64 }
65
66 return ~0;
67}
34 68
35static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io) 69static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
36{ 70{
37 struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io); 71 struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);
38 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
39 int id = rsnd_mod_id(mod); 72 int id = rsnd_mod_id(mod);
40 int ws = id; 73 int ws = id;
41 74
42 if (rsnd_ssi_is_pin_sharing(rsnd_ssi_mod_get(priv, id))) { 75 if (rsnd_ssi_is_pin_sharing(io)) {
43 switch (id) { 76 switch (id) {
44 case 1: 77 case 1:
45 case 2: 78 case 2:
@@ -60,6 +93,9 @@ static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)
60int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod, 93int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod,
61 struct rsnd_dai_stream *io) 94 struct rsnd_dai_stream *io)
62{ 95{
96 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
97 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
98 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
63 int id = rsnd_mod_id(mod); 99 int id = rsnd_mod_id(mod);
64 int shift = (id % 2) ? 16 : 0; 100 int shift = (id % 2) ? 16 : 0;
65 u32 mask, val; 101 u32 mask, val;
@@ -69,21 +105,26 @@ int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod,
69 val = val << shift; 105 val = val << shift;
70 mask = 0xffff << shift; 106 mask = 0xffff << shift;
71 107
72 rsnd_mod_bset(mod, CMDOUT_TIMSEL, mask, val); 108 rsnd_mod_bset(adg_mod, CMDOUT_TIMSEL, mask, val);
73 109
74 return 0; 110 return 0;
75} 111}
76 112
77static int rsnd_adg_set_src_timsel_gen2(struct rsnd_mod *mod, 113static int rsnd_adg_set_src_timsel_gen2(struct rsnd_mod *src_mod,
78 struct rsnd_dai_stream *io, 114 struct rsnd_dai_stream *io,
79 u32 timsel) 115 u32 timsel)
80{ 116{
117 struct rsnd_priv *priv = rsnd_mod_to_priv(src_mod);
118 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
119 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
81 int is_play = rsnd_io_is_play(io); 120 int is_play = rsnd_io_is_play(io);
82 int id = rsnd_mod_id(mod); 121 int id = rsnd_mod_id(src_mod);
83 int shift = (id % 2) ? 16 : 0; 122 int shift = (id % 2) ? 16 : 0;
84 u32 mask, ws; 123 u32 mask, ws;
85 u32 in, out; 124 u32 in, out;
86 125
126 rsnd_mod_confirm_src(src_mod);
127
87 ws = rsnd_adg_ssi_ws_timing_gen2(io); 128 ws = rsnd_adg_ssi_ws_timing_gen2(io);
88 129
89 in = (is_play) ? timsel : ws; 130 in = (is_play) ? timsel : ws;
@@ -95,37 +136,38 @@ static int rsnd_adg_set_src_timsel_gen2(struct rsnd_mod *mod,
95 136
96 switch (id / 2) { 137 switch (id / 2) {
97 case 0: 138 case 0:
98 rsnd_mod_bset(mod, SRCIN_TIMSEL0, mask, in); 139 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL0, mask, in);
99 rsnd_mod_bset(mod, SRCOUT_TIMSEL0, mask, out); 140 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL0, mask, out);
100 break; 141 break;
101 case 1: 142 case 1:
102 rsnd_mod_bset(mod, SRCIN_TIMSEL1, mask, in); 143 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL1, mask, in);
103 rsnd_mod_bset(mod, SRCOUT_TIMSEL1, mask, out); 144 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL1, mask, out);
104 break; 145 break;
105 case 2: 146 case 2:
106 rsnd_mod_bset(mod, SRCIN_TIMSEL2, mask, in); 147 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL2, mask, in);
107 rsnd_mod_bset(mod, SRCOUT_TIMSEL2, mask, out); 148 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL2, mask, out);
108 break; 149 break;
109 case 3: 150 case 3:
110 rsnd_mod_bset(mod, SRCIN_TIMSEL3, mask, in); 151 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL3, mask, in);
111 rsnd_mod_bset(mod, SRCOUT_TIMSEL3, mask, out); 152 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL3, mask, out);
112 break; 153 break;
113 case 4: 154 case 4:
114 rsnd_mod_bset(mod, SRCIN_TIMSEL4, mask, in); 155 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL4, mask, in);
115 rsnd_mod_bset(mod, SRCOUT_TIMSEL4, mask, out); 156 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL4, mask, out);
116 break; 157 break;
117 } 158 }
118 159
119 return 0; 160 return 0;
120} 161}
121 162
122int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, 163int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *src_mod,
123 struct rsnd_dai_stream *io, 164 struct rsnd_dai_stream *io,
124 unsigned int src_rate, 165 unsigned int src_rate,
125 unsigned int dst_rate) 166 unsigned int dst_rate)
126{ 167{
127 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 168 struct rsnd_priv *priv = rsnd_mod_to_priv(src_mod);
128 struct rsnd_adg *adg = rsnd_priv_to_adg(priv); 169 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
170 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
129 struct device *dev = rsnd_priv_to_dev(priv); 171 struct device *dev = rsnd_priv_to_dev(priv);
130 int idx, sel, div, step, ret; 172 int idx, sel, div, step, ret;
131 u32 val, en; 173 u32 val, en;
@@ -134,10 +176,12 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
134 clk_get_rate(adg->clk[CLKA]), /* 0000: CLKA */ 176 clk_get_rate(adg->clk[CLKA]), /* 0000: CLKA */
135 clk_get_rate(adg->clk[CLKB]), /* 0001: CLKB */ 177 clk_get_rate(adg->clk[CLKB]), /* 0001: CLKB */
136 clk_get_rate(adg->clk[CLKC]), /* 0010: CLKC */ 178 clk_get_rate(adg->clk[CLKC]), /* 0010: CLKC */
137 adg->rbga_rate_for_441khz_div_6,/* 0011: RBGA */ 179 adg->rbga_rate_for_441khz, /* 0011: RBGA */
138 adg->rbgb_rate_for_48khz_div_6, /* 0100: RBGB */ 180 adg->rbgb_rate_for_48khz, /* 0100: RBGB */
139 }; 181 };
140 182
183 rsnd_mod_confirm_src(src_mod);
184
141 min = ~0; 185 min = ~0;
142 val = 0; 186 val = 0;
143 en = 0; 187 en = 0;
@@ -175,25 +219,27 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
175 return -EIO; 219 return -EIO;
176 } 220 }
177 221
178 ret = rsnd_adg_set_src_timsel_gen2(mod, io, val); 222 ret = rsnd_adg_set_src_timsel_gen2(src_mod, io, val);
179 if (ret < 0) { 223 if (ret < 0) {
180 dev_err(dev, "timsel error\n"); 224 dev_err(dev, "timsel error\n");
181 return ret; 225 return ret;
182 } 226 }
183 227
184 rsnd_mod_bset(mod, DIV_EN, en, en); 228 rsnd_mod_bset(adg_mod, DIV_EN, en, en);
185 229
186 dev_dbg(dev, "convert rate %d <-> %d\n", src_rate, dst_rate); 230 dev_dbg(dev, "convert rate %d <-> %d\n", src_rate, dst_rate);
187 231
188 return 0; 232 return 0;
189} 233}
190 234
191int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, 235int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *src_mod,
192 struct rsnd_dai_stream *io) 236 struct rsnd_dai_stream *io)
193{ 237{
194 u32 val = rsnd_adg_ssi_ws_timing_gen2(io); 238 u32 val = rsnd_adg_ssi_ws_timing_gen2(io);
195 239
196 return rsnd_adg_set_src_timsel_gen2(mod, io, val); 240 rsnd_mod_confirm_src(src_mod);
241
242 return rsnd_adg_set_src_timsel_gen2(src_mod, io, val);
197} 243}
198 244
199int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, 245int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
@@ -202,6 +248,7 @@ int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
202 unsigned int dst_rate) 248 unsigned int dst_rate)
203{ 249{
204 struct rsnd_adg *adg = rsnd_priv_to_adg(priv); 250 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
251 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
205 struct device *dev = rsnd_priv_to_dev(priv); 252 struct device *dev = rsnd_priv_to_dev(priv);
206 int idx, sel, div, shift; 253 int idx, sel, div, shift;
207 u32 mask, val; 254 u32 mask, val;
@@ -211,8 +258,8 @@ int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,
211 clk_get_rate(adg->clk[CLKB]), /* 001: CLKB */ 258 clk_get_rate(adg->clk[CLKB]), /* 001: CLKB */
212 clk_get_rate(adg->clk[CLKC]), /* 010: CLKC */ 259 clk_get_rate(adg->clk[CLKC]), /* 010: CLKC */
213 0, /* 011: MLBCLK (not used) */ 260 0, /* 011: MLBCLK (not used) */
214 adg->rbga_rate_for_441khz_div_6,/* 100: RBGA */ 261 adg->rbga_rate_for_441khz, /* 100: RBGA */
215 adg->rbgb_rate_for_48khz_div_6, /* 101: RBGB */ 262 adg->rbgb_rate_for_48khz, /* 101: RBGB */
216 }; 263 };
217 264
218 /* find div (= 1/128, 1/256, 1/512, 1/1024, 1/2048 */ 265 /* find div (= 1/128, 1/256, 1/512, 1/1024, 1/2048 */
@@ -238,13 +285,13 @@ find_rate:
238 285
239 switch (id / 4) { 286 switch (id / 4) {
240 case 0: 287 case 0:
241 rsnd_mod_bset(mod, AUDIO_CLK_SEL3, mask, val); 288 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL3, mask, val);
242 break; 289 break;
243 case 1: 290 case 1:
244 rsnd_mod_bset(mod, AUDIO_CLK_SEL4, mask, val); 291 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL4, mask, val);
245 break; 292 break;
246 case 2: 293 case 2:
247 rsnd_mod_bset(mod, AUDIO_CLK_SEL5, mask, val); 294 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL5, mask, val);
248 break; 295 break;
249 } 296 }
250 297
@@ -257,12 +304,17 @@ find_rate:
257 return 0; 304 return 0;
258} 305}
259 306
260static void rsnd_adg_set_ssi_clk(struct rsnd_mod *mod, u32 val) 307static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)
261{ 308{
262 int id = rsnd_mod_id(mod); 309 struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);
310 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
311 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
312 int id = rsnd_mod_id(ssi_mod);
263 int shift = (id % 4) * 8; 313 int shift = (id % 4) * 8;
264 u32 mask = 0xFF << shift; 314 u32 mask = 0xFF << shift;
265 315
316 rsnd_mod_confirm_ssi(ssi_mod);
317
266 val = val << shift; 318 val = val << shift;
267 319
268 /* 320 /*
@@ -274,13 +326,13 @@ static void rsnd_adg_set_ssi_clk(struct rsnd_mod *mod, u32 val)
274 326
275 switch (id / 4) { 327 switch (id / 4) {
276 case 0: 328 case 0:
277 rsnd_mod_bset(mod, AUDIO_CLK_SEL0, mask, val); 329 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL0, mask, val);
278 break; 330 break;
279 case 1: 331 case 1:
280 rsnd_mod_bset(mod, AUDIO_CLK_SEL1, mask, val); 332 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL1, mask, val);
281 break; 333 break;
282 case 2: 334 case 2:
283 rsnd_mod_bset(mod, AUDIO_CLK_SEL2, mask, val); 335 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL2, mask, val);
284 break; 336 break;
285 } 337 }
286} 338}
@@ -326,14 +378,14 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate)
326 } 378 }
327 379
328 /* 380 /*
329 * find 1/6 clock from BRGA/BRGB 381 * find divided clock from BRGA/BRGB
330 */ 382 */
331 if (rate == adg->rbga_rate_for_441khz_div_6) { 383 if (rate == adg->rbga_rate_for_441khz) {
332 data = 0x10; 384 data = 0x10;
333 goto found_clock; 385 goto found_clock;
334 } 386 }
335 387
336 if (rate == adg->rbgb_rate_for_48khz_div_6) { 388 if (rate == adg->rbgb_rate_for_48khz) {
337 data = 0x20; 389 data = 0x20;
338 goto found_clock; 390 goto found_clock;
339 } 391 }
@@ -342,29 +394,60 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate)
342 394
343found_clock: 395found_clock:
344 396
345 /* see rsnd_adg_ssi_clk_init() */
346 rsnd_mod_bset(mod, SSICKR, 0x00FF0000, adg->ckr);
347 rsnd_mod_write(mod, BRRA, 0x00000002); /* 1/6 */
348 rsnd_mod_write(mod, BRRB, 0x00000002); /* 1/6 */
349
350 /* 397 /*
351 * This "mod" = "ssi" here. 398 * This "mod" = "ssi" here.
352 * we can get "ssi id" from mod 399 * we can get "ssi id" from mod
353 */ 400 */
354 rsnd_adg_set_ssi_clk(mod, data); 401 rsnd_adg_set_ssi_clk(mod, data);
355 402
356 dev_dbg(dev, "ADG: ssi%d selects clk%d = %d", 403 dev_dbg(dev, "ADG: %s[%d] selects 0x%x for %d\n",
357 rsnd_mod_id(mod), i, rate); 404 rsnd_mod_name(mod), rsnd_mod_id(mod),
405 data, rate);
358 406
359 return 0; 407 return 0;
360} 408}
361 409
362static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg) 410static void rsnd_adg_get_clkin(struct rsnd_priv *priv,
411 struct rsnd_adg *adg)
412{
413 struct device *dev = rsnd_priv_to_dev(priv);
414 struct clk *clk;
415 static const char * const clk_name[] = {
416 [CLKA] = "clk_a",
417 [CLKB] = "clk_b",
418 [CLKC] = "clk_c",
419 [CLKI] = "clk_i",
420 };
421 int i;
422
423 for (i = 0; i < CLKMAX; i++) {
424 clk = devm_clk_get(dev, clk_name[i]);
425 adg->clk[i] = IS_ERR(clk) ? NULL : clk;
426 }
427
428 for_each_rsnd_clk(clk, adg, i)
429 dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk));
430}
431
432static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
433 struct rsnd_adg *adg)
363{ 434{
364 struct clk *clk; 435 struct clk *clk;
365 unsigned long rate; 436 struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
366 u32 ckr; 437 struct device *dev = rsnd_priv_to_dev(priv);
438 struct device_node *np = dev->of_node;
439 u32 ckr, rbgx, rbga, rbgb;
440 u32 rate, req_rate, div;
441 uint32_t count = 0;
442 unsigned long req_48kHz_rate, req_441kHz_rate;
367 int i; 443 int i;
444 const char *parent_clk_name = NULL;
445 static const char * const clkout_name[] = {
446 [CLKOUT] = "audio_clkout",
447 [CLKOUT1] = "audio_clkout1",
448 [CLKOUT2] = "audio_clkout2",
449 [CLKOUT3] = "audio_clkout3",
450 };
368 int brg_table[] = { 451 int brg_table[] = {
369 [CLKA] = 0x0, 452 [CLKA] = 0x0,
370 [CLKB] = 0x1, 453 [CLKB] = 0x1,
@@ -372,19 +455,34 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)
372 [CLKI] = 0x2, 455 [CLKI] = 0x2,
373 }; 456 };
374 457
458 of_property_read_u32(np, "#clock-cells", &count);
459
460 /*
461 * ADG supports BRRA/BRRB output only
462 * this means all clkout0/1/2/3 will be same rate
463 */
464 of_property_read_u32(np, "clock-frequency", &req_rate);
465 req_48kHz_rate = 0;
466 req_441kHz_rate = 0;
467 if (0 == (req_rate % 44100))
468 req_441kHz_rate = req_rate;
469 if (0 == (req_rate % 48000))
470 req_48kHz_rate = req_rate;
471
375 /* 472 /*
376 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC 473 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC
377 * have 44.1kHz or 48kHz base clocks for now. 474 * have 44.1kHz or 48kHz base clocks for now.
378 * 475 *
379 * SSI itself can divide parent clock by 1/1 - 1/16 476 * SSI itself can divide parent clock by 1/1 - 1/16
380 * So, BRGA outputs 44.1kHz base parent clock 1/32,
381 * and, BRGB outputs 48.0kHz base parent clock 1/32 here.
382 * see 477 * see
383 * rsnd_adg_ssi_clk_try_start() 478 * rsnd_adg_ssi_clk_try_start()
479 * rsnd_ssi_master_clk_start()
384 */ 480 */
385 ckr = 0; 481 ckr = 0;
386 adg->rbga_rate_for_441khz_div_6 = 0; 482 rbga = 2; /* default 1/6 */
387 adg->rbgb_rate_for_48khz_div_6 = 0; 483 rbgb = 2; /* default 1/6 */
484 adg->rbga_rate_for_441khz = 0;
485 adg->rbgb_rate_for_48khz = 0;
388 for_each_rsnd_clk(clk, adg, i) { 486 for_each_rsnd_clk(clk, adg, i) {
389 rate = clk_get_rate(clk); 487 rate = clk_get_rate(clk);
390 488
@@ -392,19 +490,86 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)
392 continue; 490 continue;
393 491
394 /* RBGA */ 492 /* RBGA */
395 if (!adg->rbga_rate_for_441khz_div_6 && (0 == rate % 44100)) { 493 if (!adg->rbga_rate_for_441khz && (0 == rate % 44100)) {
396 adg->rbga_rate_for_441khz_div_6 = rate / 6; 494 div = 6;
397 ckr |= brg_table[i] << 20; 495 if (req_441kHz_rate)
496 div = rate / req_441kHz_rate;
497 rbgx = rsnd_adg_calculate_rbgx(div);
498 if (BRRx_MASK(rbgx) == rbgx) {
499 rbga = rbgx;
500 adg->rbga_rate_for_441khz = rate / div;
501 ckr |= brg_table[i] << 20;
502 if (req_441kHz_rate)
503 parent_clk_name = __clk_get_name(clk);
504 }
398 } 505 }
399 506
400 /* RBGB */ 507 /* RBGB */
401 if (!adg->rbgb_rate_for_48khz_div_6 && (0 == rate % 48000)) { 508 if (!adg->rbgb_rate_for_48khz && (0 == rate % 48000)) {
402 adg->rbgb_rate_for_48khz_div_6 = rate / 6; 509 div = 6;
403 ckr |= brg_table[i] << 16; 510 if (req_48kHz_rate)
511 div = rate / req_48kHz_rate;
512 rbgx = rsnd_adg_calculate_rbgx(div);
513 if (BRRx_MASK(rbgx) == rbgx) {
514 rbgb = rbgx;
515 adg->rbgb_rate_for_48khz = rate / div;
516 ckr |= brg_table[i] << 16;
517 if (req_48kHz_rate) {
518 parent_clk_name = __clk_get_name(clk);
519 ckr |= 0x80000000;
520 }
521 }
404 } 522 }
405 } 523 }
406 524
407 adg->ckr = ckr; 525 /*
526 * ADG supports BRRA/BRRB output only.
527 * this means all clkout0/1/2/3 will be * same rate
528 */
529
530 /*
531 * for clkout
532 */
533 if (!count) {
534 clk = clk_register_fixed_rate(dev, clkout_name[CLKOUT],
535 parent_clk_name,
536 (parent_clk_name) ?
537 0 : CLK_IS_ROOT, req_rate);
538 if (!IS_ERR(clk)) {
539 adg->clkout[CLKOUT] = clk;
540 of_clk_add_provider(np, of_clk_src_simple_get, clk);
541 }
542 }
543 /*
544 * for clkout0/1/2/3
545 */
546 else {
547 for (i = 0; i < CLKOUTMAX; i++) {
548 clk = clk_register_fixed_rate(dev, clkout_name[i],
549 parent_clk_name,
550 (parent_clk_name) ?
551 0 : CLK_IS_ROOT,
552 req_rate);
553 if (!IS_ERR(clk)) {
554 adg->onecell.clks = adg->clkout;
555 adg->onecell.clk_num = CLKOUTMAX;
556
557 adg->clkout[i] = clk;
558
559 of_clk_add_provider(np, of_clk_src_onecell_get,
560 &adg->onecell);
561 }
562 }
563 }
564
565 rsnd_mod_bset(adg_mod, SSICKR, 0x00FF0000, ckr);
566 rsnd_mod_write(adg_mod, BRRA, rbga);
567 rsnd_mod_write(adg_mod, BRRB, rbgb);
568
569 for_each_rsnd_clkout(clk, adg, i)
570 dev_dbg(dev, "clkout %d : %p : %ld\n", i, clk, clk_get_rate(clk));
571 dev_dbg(dev, "SSICKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n",
572 ckr, rbga, rbgb);
408} 573}
409 574
410int rsnd_adg_probe(struct platform_device *pdev, 575int rsnd_adg_probe(struct platform_device *pdev,
@@ -413,8 +578,6 @@ int rsnd_adg_probe(struct platform_device *pdev,
413{ 578{
414 struct rsnd_adg *adg; 579 struct rsnd_adg *adg;
415 struct device *dev = rsnd_priv_to_dev(priv); 580 struct device *dev = rsnd_priv_to_dev(priv);
416 struct clk *clk;
417 int i;
418 581
419 adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); 582 adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL);
420 if (!adg) { 583 if (!adg) {
@@ -422,15 +585,16 @@ int rsnd_adg_probe(struct platform_device *pdev,
422 return -ENOMEM; 585 return -ENOMEM;
423 } 586 }
424 587
425 adg->clk[CLKA] = devm_clk_get(dev, "clk_a"); 588 /*
426 adg->clk[CLKB] = devm_clk_get(dev, "clk_b"); 589 * ADG is special module.
427 adg->clk[CLKC] = devm_clk_get(dev, "clk_c"); 590 * Use ADG mod without rsnd_mod_init() to make debug easy
428 adg->clk[CLKI] = devm_clk_get(dev, "clk_i"); 591 * for rsnd_write/rsnd_read
429 592 */
430 for_each_rsnd_clk(clk, adg, i) 593 adg->mod.ops = &adg_ops;
431 dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk)); 594 adg->mod.priv = priv;
432 595
433 rsnd_adg_ssi_clk_init(priv, adg); 596 rsnd_adg_get_clkin(priv, adg);
597 rsnd_adg_get_clkout(priv, adg);
434 598
435 priv->adg = adg; 599 priv->adg = adg;
436 600
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index f3feed5ce9b6..deed48ef28b8 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -110,6 +110,7 @@ static const struct rsnd_of_data rsnd_of_data_gen2 = {
110static const struct of_device_id rsnd_of_match[] = { 110static const struct of_device_id rsnd_of_match[] = {
111 { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 }, 111 { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 },
112 { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 }, 112 { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 },
113 { .compatible = "renesas,rcar_sound-gen3", .data = &rsnd_of_data_gen2 }, /* gen2 compatible */
113 {}, 114 {},
114}; 115};
115MODULE_DEVICE_TABLE(of, rsnd_of_match); 116MODULE_DEVICE_TABLE(of, rsnd_of_match);
@@ -126,6 +127,17 @@ MODULE_DEVICE_TABLE(of, rsnd_of_match);
126#define rsnd_info_id(priv, io, name) \ 127#define rsnd_info_id(priv, io, name) \
127 ((io)->info->name - priv->info->name##_info) 128 ((io)->info->name - priv->info->name##_info)
128 129
130void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
131{
132 if (mod->type != type) {
133 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
134 struct device *dev = rsnd_priv_to_dev(priv);
135
136 dev_warn(dev, "%s[%d] is not your expected module\n",
137 rsnd_mod_name(mod), rsnd_mod_id(mod));
138 }
139}
140
129/* 141/*
130 * rsnd_mod functions 142 * rsnd_mod functions
131 */ 143 */
@@ -288,7 +300,7 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
288/* 300/*
289 * rsnd_dai functions 301 * rsnd_dai functions
290 */ 302 */
291#define __rsnd_mod_call(mod, io, func, param...) \ 303#define rsnd_mod_call(mod, io, func, param...) \
292({ \ 304({ \
293 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ 305 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \
294 struct device *dev = rsnd_priv_to_dev(priv); \ 306 struct device *dev = rsnd_priv_to_dev(priv); \
@@ -296,24 +308,17 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
296 u8 val = (mod->status >> __rsnd_mod_shift_##func) & 0xF; \ 308 u8 val = (mod->status >> __rsnd_mod_shift_##func) & 0xF; \
297 u8 add = ((val + __rsnd_mod_add_##func) & 0xF); \ 309 u8 add = ((val + __rsnd_mod_add_##func) & 0xF); \
298 int ret = 0; \ 310 int ret = 0; \
299 int called = 0; \ 311 int call = (val == __rsnd_mod_call_##func) && (mod)->ops->func; \
300 if (val == __rsnd_mod_call_##func) { \
301 called = 1; \
302 ret = (mod)->ops->func(mod, io, param); \
303 } \
304 mod->status = (mod->status & ~mask) + \ 312 mod->status = (mod->status & ~mask) + \
305 (add << __rsnd_mod_shift_##func); \ 313 (add << __rsnd_mod_shift_##func); \
306 dev_dbg(dev, "%s[%d] 0x%08x %s\n", \ 314 dev_dbg(dev, "%s[%d]\t0x%08x %s\n", \
307 rsnd_mod_name(mod), rsnd_mod_id(mod), mod->status, \ 315 rsnd_mod_name(mod), rsnd_mod_id(mod), \
308 called ? #func : ""); \ 316 mod->status, call ? #func : ""); \
317 if (call) \
318 ret = (mod)->ops->func(mod, io, param); \
309 ret; \ 319 ret; \
310}) 320})
311 321
312#define rsnd_mod_call(mod, io, func, param...) \
313 (!(mod) ? -ENODEV : \
314 !((mod)->ops->func) ? 0 : \
315 __rsnd_mod_call(mod, io, func, param))
316
317#define rsnd_dai_call(fn, io, param...) \ 322#define rsnd_dai_call(fn, io, param...) \
318({ \ 323({ \
319 struct rsnd_mod *mod; \ 324 struct rsnd_mod *mod; \
@@ -322,9 +327,7 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io)
322 mod = (io)->mod[i]; \ 327 mod = (io)->mod[i]; \
323 if (!mod) \ 328 if (!mod) \
324 continue; \ 329 continue; \
325 ret = rsnd_mod_call(mod, io, fn, param); \ 330 ret |= rsnd_mod_call(mod, io, fn, param); \
326 if (ret < 0) \
327 break; \
328 } \ 331 } \
329 ret; \ 332 ret; \
330}) 333})
@@ -490,16 +493,10 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
490 break; 493 break;
491 case SNDRV_PCM_TRIGGER_STOP: 494 case SNDRV_PCM_TRIGGER_STOP:
492 ret = rsnd_dai_call(stop, io, priv); 495 ret = rsnd_dai_call(stop, io, priv);
493 if (ret < 0)
494 goto dai_trigger_end;
495 496
496 ret = rsnd_dai_call(quit, io, priv); 497 ret |= rsnd_dai_call(quit, io, priv);
497 if (ret < 0)
498 goto dai_trigger_end;
499 498
500 ret = rsnd_platform_call(priv, dai, stop, ssi_id); 499 ret |= rsnd_platform_call(priv, dai, stop, ssi_id);
501 if (ret < 0)
502 goto dai_trigger_end;
503 500
504 rsnd_dai_stream_quit(io); 501 rsnd_dai_stream_quit(io);
505 break; 502 break;
@@ -1224,20 +1221,11 @@ static int rsnd_probe(struct platform_device *pdev)
1224 }; 1221 };
1225 int ret, i; 1222 int ret, i;
1226 1223
1227 info = NULL; 1224 info = devm_kzalloc(&pdev->dev, sizeof(struct rcar_snd_info),
1228 of_data = NULL; 1225 GFP_KERNEL);
1229 if (of_id) { 1226 if (!info)
1230 info = devm_kzalloc(&pdev->dev, 1227 return -ENOMEM;
1231 sizeof(struct rcar_snd_info), GFP_KERNEL); 1228 of_data = of_id->data;
1232 of_data = of_id->data;
1233 } else {
1234 info = pdev->dev.platform_data;
1235 }
1236
1237 if (!info) {
1238 dev_err(dev, "driver needs R-Car sound information\n");
1239 return -ENODEV;
1240 }
1241 1229
1242 /* 1230 /*
1243 * init priv data 1231 * init priv data
diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c
index 05498bba5874..3cb214ab848b 100644
--- a/sound/soc/sh/rcar/ctu.c
+++ b/sound/soc/sh/rcar/ctu.c
@@ -35,7 +35,7 @@ static int rsnd_ctu_init(struct rsnd_mod *mod,
35 struct rsnd_dai_stream *io, 35 struct rsnd_dai_stream *io,
36 struct rsnd_priv *priv) 36 struct rsnd_priv *priv)
37{ 37{
38 rsnd_mod_hw_start(mod); 38 rsnd_mod_power_on(mod);
39 39
40 rsnd_ctu_initialize_lock(mod); 40 rsnd_ctu_initialize_lock(mod);
41 41
@@ -50,7 +50,7 @@ static int rsnd_ctu_quit(struct rsnd_mod *mod,
50 struct rsnd_dai_stream *io, 50 struct rsnd_dai_stream *io,
51 struct rsnd_priv *priv) 51 struct rsnd_priv *priv)
52{ 52{
53 rsnd_mod_hw_stop(mod); 53 rsnd_mod_power_off(mod);
54 54
55 return 0; 55 return 0;
56} 56}
@@ -66,7 +66,7 @@ struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id)
66 if (WARN_ON(id < 0 || id >= rsnd_ctu_nr(priv))) 66 if (WARN_ON(id < 0 || id >= rsnd_ctu_nr(priv)))
67 id = 0; 67 id = 0;
68 68
69 return &((struct rsnd_ctu *)(priv->ctu) + id)->mod; 69 return rsnd_mod_get((struct rsnd_ctu *)(priv->ctu) + id);
70} 70}
71 71
72static void rsnd_of_parse_ctu(struct platform_device *pdev, 72static void rsnd_of_parse_ctu(struct platform_device *pdev,
@@ -118,10 +118,8 @@ int rsnd_ctu_probe(struct platform_device *pdev,
118 int i, nr, ret; 118 int i, nr, ret;
119 119
120 /* This driver doesn't support Gen1 at this point */ 120 /* This driver doesn't support Gen1 at this point */
121 if (rsnd_is_gen1(priv)) { 121 if (rsnd_is_gen1(priv))
122 dev_warn(dev, "CTU is not supported on Gen1\n"); 122 return 0;
123 return -EINVAL;
124 }
125 123
126 rsnd_of_parse_ctu(pdev, of_data, priv); 124 rsnd_of_parse_ctu(pdev, of_data, priv);
127 125
@@ -150,7 +148,7 @@ int rsnd_ctu_probe(struct platform_device *pdev,
150 148
151 ctu->info = &info->ctu_info[i]; 149 ctu->info = &info->ctu_info[i];
152 150
153 ret = rsnd_mod_init(priv, &ctu->mod, &rsnd_ctu_ops, 151 ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops,
154 clk, RSND_MOD_CTU, i); 152 clk, RSND_MOD_CTU, i);
155 if (ret) 153 if (ret)
156 return ret; 154 return ret;
@@ -166,6 +164,6 @@ void rsnd_ctu_remove(struct platform_device *pdev,
166 int i; 164 int i;
167 165
168 for_each_rsnd_ctu(ctu, priv, i) { 166 for_each_rsnd_ctu(ctu, priv, i) {
169 rsnd_mod_quit(&ctu->mod); 167 rsnd_mod_quit(rsnd_mod_get(ctu));
170 } 168 }
171} 169}
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index bfbb8a5e93bd..5d084d040961 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -470,7 +470,7 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
470 dev_err(dev, "DVC is selected without SRC\n"); 470 dev_err(dev, "DVC is selected without SRC\n");
471 471
472 /* use SSIU or SSI ? */ 472 /* use SSIU or SSI ? */
473 if (is_ssi && rsnd_ssi_use_busif(io, mod)) 473 if (is_ssi && rsnd_ssi_use_busif(io))
474 is_ssi++; 474 is_ssi++;
475 475
476 return (is_from) ? 476 return (is_from) ?
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index 57796387d482..58f690900e6d 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -153,7 +153,7 @@ static int rsnd_dvc_init(struct rsnd_mod *mod,
153 struct rsnd_dai_stream *io, 153 struct rsnd_dai_stream *io,
154 struct rsnd_priv *priv) 154 struct rsnd_priv *priv)
155{ 155{
156 rsnd_mod_hw_start(mod); 156 rsnd_mod_power_on(mod);
157 157
158 rsnd_dvc_soft_reset(mod); 158 rsnd_dvc_soft_reset(mod);
159 159
@@ -175,7 +175,7 @@ static int rsnd_dvc_quit(struct rsnd_mod *mod,
175 struct rsnd_dai_stream *io, 175 struct rsnd_dai_stream *io,
176 struct rsnd_priv *priv) 176 struct rsnd_priv *priv)
177{ 177{
178 rsnd_mod_hw_stop(mod); 178 rsnd_mod_power_off(mod);
179 179
180 return 0; 180 return 0;
181} 181}
@@ -282,7 +282,7 @@ struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
282 if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv))) 282 if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv)))
283 id = 0; 283 id = 0;
284 284
285 return &((struct rsnd_dvc *)(priv->dvc) + id)->mod; 285 return rsnd_mod_get((struct rsnd_dvc *)(priv->dvc) + id);
286} 286}
287 287
288static void rsnd_of_parse_dvc(struct platform_device *pdev, 288static void rsnd_of_parse_dvc(struct platform_device *pdev,
@@ -333,10 +333,8 @@ int rsnd_dvc_probe(struct platform_device *pdev,
333 int i, nr, ret; 333 int i, nr, ret;
334 334
335 /* This driver doesn't support Gen1 at this point */ 335 /* This driver doesn't support Gen1 at this point */
336 if (rsnd_is_gen1(priv)) { 336 if (rsnd_is_gen1(priv))
337 dev_warn(dev, "CMD is not supported on Gen1\n"); 337 return 0;
338 return -EINVAL;
339 }
340 338
341 rsnd_of_parse_dvc(pdev, of_data, priv); 339 rsnd_of_parse_dvc(pdev, of_data, priv);
342 340
@@ -361,7 +359,7 @@ int rsnd_dvc_probe(struct platform_device *pdev,
361 359
362 dvc->info = &info->dvc_info[i]; 360 dvc->info = &info->dvc_info[i];
363 361
364 ret = rsnd_mod_init(priv, &dvc->mod, &rsnd_dvc_ops, 362 ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
365 clk, RSND_MOD_DVC, i); 363 clk, RSND_MOD_DVC, i);
366 if (ret) 364 if (ret)
367 return ret; 365 return ret;
@@ -377,6 +375,6 @@ void rsnd_dvc_remove(struct platform_device *pdev,
377 int i; 375 int i;
378 376
379 for_each_rsnd_dvc(dvc, priv, i) { 377 for_each_rsnd_dvc(dvc, priv, i) {
380 rsnd_mod_quit(&dvc->mod); 378 rsnd_mod_quit(rsnd_mod_get(dvc));
381 } 379 }
382} 380}
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index 916b38d54fda..edcf4cc2e84f 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -22,13 +22,15 @@
22#include "rsnd.h" 22#include "rsnd.h"
23 23
24struct rsnd_gen { 24struct rsnd_gen {
25 void __iomem *base[RSND_BASE_MAX];
26
27 struct rsnd_gen_ops *ops; 25 struct rsnd_gen_ops *ops;
28 26
27 /* RSND_BASE_MAX base */
28 void __iomem *base[RSND_BASE_MAX];
29 phys_addr_t res[RSND_BASE_MAX];
29 struct regmap *regmap[RSND_BASE_MAX]; 30 struct regmap *regmap[RSND_BASE_MAX];
31
32 /* RSND_REG_MAX base */
30 struct regmap_field *regs[RSND_REG_MAX]; 33 struct regmap_field *regs[RSND_REG_MAX];
31 phys_addr_t res[RSND_REG_MAX];
32}; 34};
33 35
34#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) 36#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen)
@@ -79,11 +81,11 @@ u32 rsnd_read(struct rsnd_priv *priv,
79 if (!rsnd_is_accessible_reg(priv, gen, reg)) 81 if (!rsnd_is_accessible_reg(priv, gen, reg))
80 return 0; 82 return 0;
81 83
84 regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
85
82 dev_dbg(dev, "r %s[%d] - %4d : %08x\n", 86 dev_dbg(dev, "r %s[%d] - %4d : %08x\n",
83 rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val); 87 rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val);
84 88
85 regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
86
87 return val; 89 return val;
88} 90}
89 91
@@ -182,6 +184,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
182 if (IS_ERR(regmap)) 184 if (IS_ERR(regmap))
183 return PTR_ERR(regmap); 185 return PTR_ERR(regmap);
184 186
187 /* RSND_BASE_MAX base */
185 gen->base[reg_id] = base; 188 gen->base[reg_id] = base;
186 gen->regmap[reg_id] = regmap; 189 gen->regmap[reg_id] = regmap;
187 gen->res[reg_id] = res->start; 190 gen->res[reg_id] = res->start;
@@ -198,6 +201,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
198 if (IS_ERR(regs)) 201 if (IS_ERR(regs))
199 return PTR_ERR(regs); 202 return PTR_ERR(regs);
200 203
204 /* RSND_REG_MAX base */
201 gen->regs[conf[i].idx] = regs; 205 gen->regs[conf[i].idx] = regs;
202 } 206 }
203 207
diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c
index 0d5c102db6f5..953dd0be9b60 100644
--- a/sound/soc/sh/rcar/mix.c
+++ b/sound/soc/sh/rcar/mix.c
@@ -58,7 +58,7 @@ static int rsnd_mix_init(struct rsnd_mod *mod,
58 struct rsnd_dai_stream *io, 58 struct rsnd_dai_stream *io,
59 struct rsnd_priv *priv) 59 struct rsnd_priv *priv)
60{ 60{
61 rsnd_mod_hw_start(mod); 61 rsnd_mod_power_on(mod);
62 62
63 rsnd_mix_soft_reset(mod); 63 rsnd_mix_soft_reset(mod);
64 64
@@ -83,7 +83,7 @@ static int rsnd_mix_quit(struct rsnd_mod *mod,
83 struct rsnd_dai_stream *io, 83 struct rsnd_dai_stream *io,
84 struct rsnd_priv *priv) 84 struct rsnd_priv *priv)
85{ 85{
86 rsnd_mod_hw_stop(mod); 86 rsnd_mod_power_off(mod);
87 87
88 return 0; 88 return 0;
89} 89}
@@ -99,7 +99,7 @@ struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id)
99 if (WARN_ON(id < 0 || id >= rsnd_mix_nr(priv))) 99 if (WARN_ON(id < 0 || id >= rsnd_mix_nr(priv)))
100 id = 0; 100 id = 0;
101 101
102 return &((struct rsnd_mix *)(priv->mix) + id)->mod; 102 return rsnd_mod_get((struct rsnd_mix *)(priv->mix) + id);
103} 103}
104 104
105static void rsnd_of_parse_mix(struct platform_device *pdev, 105static void rsnd_of_parse_mix(struct platform_device *pdev,
@@ -151,10 +151,8 @@ int rsnd_mix_probe(struct platform_device *pdev,
151 int i, nr, ret; 151 int i, nr, ret;
152 152
153 /* This driver doesn't support Gen1 at this point */ 153 /* This driver doesn't support Gen1 at this point */
154 if (rsnd_is_gen1(priv)) { 154 if (rsnd_is_gen1(priv))
155 dev_warn(dev, "MIX is not supported on Gen1\n"); 155 return 0;
156 return -EINVAL;
157 }
158 156
159 rsnd_of_parse_mix(pdev, of_data, priv); 157 rsnd_of_parse_mix(pdev, of_data, priv);
160 158
@@ -179,7 +177,7 @@ int rsnd_mix_probe(struct platform_device *pdev,
179 177
180 mix->info = &info->mix_info[i]; 178 mix->info = &info->mix_info[i];
181 179
182 ret = rsnd_mod_init(priv, &mix->mod, &rsnd_mix_ops, 180 ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops,
183 clk, RSND_MOD_MIX, i); 181 clk, RSND_MOD_MIX, i);
184 if (ret) 182 if (ret)
185 return ret; 183 return ret;
@@ -195,6 +193,6 @@ void rsnd_mix_remove(struct platform_device *pdev,
195 int i; 193 int i;
196 194
197 for_each_rsnd_mix(mix, priv, i) { 195 for_each_rsnd_mix(mix, priv, i) {
198 rsnd_mod_quit(&mix->mod); 196 rsnd_mod_quit(rsnd_mod_get(mix));
199 } 197 }
200} 198}
diff --git a/sound/soc/sh/rcar/rcar_snd.h b/sound/soc/sh/rcar/rcar_snd.h
new file mode 100644
index 000000000000..d8e33d38da43
--- /dev/null
+++ b/sound/soc/sh/rcar/rcar_snd.h
@@ -0,0 +1,117 @@
1/*
2 * Renesas R-Car SRU/SCU/SSIU/SSI support
3 *
4 * Copyright (C) 2013 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef RCAR_SND_H
13#define RCAR_SND_H
14
15
16#define RSND_GEN1_SRU 0
17#define RSND_GEN1_ADG 1
18#define RSND_GEN1_SSI 2
19
20#define RSND_GEN2_SCU 0
21#define RSND_GEN2_ADG 1
22#define RSND_GEN2_SSIU 2
23#define RSND_GEN2_SSI 3
24
25#define RSND_BASE_MAX 4
26
27/*
28 * flags
29 *
30 * 0xAB000000
31 *
32 * A : clock sharing settings
33 * B : SSI direction
34 */
35#define RSND_SSI_CLK_PIN_SHARE (1 << 31)
36#define RSND_SSI_NO_BUSIF (1 << 30) /* SSI+DMA without BUSIF */
37
38#define RSND_SSI(_dma_id, _irq, _flags) \
39{ .dma_id = _dma_id, .irq = _irq, .flags = _flags }
40#define RSND_SSI_UNUSED \
41{ .dma_id = -1, .irq = -1, .flags = 0 }
42
43struct rsnd_ssi_platform_info {
44 int dma_id;
45 int irq;
46 u32 flags;
47};
48
49#define RSND_SRC(rate, _dma_id) \
50{ .convert_rate = rate, .dma_id = _dma_id, }
51#define RSND_SRC_UNUSED \
52{ .convert_rate = 0, .dma_id = -1, }
53
54struct rsnd_src_platform_info {
55 u32 convert_rate; /* sampling rate convert */
56 int dma_id; /* for Gen2 SCU */
57 int irq;
58};
59
60/*
61 * flags
62 */
63struct rsnd_ctu_platform_info {
64 u32 flags;
65};
66
67struct rsnd_mix_platform_info {
68 u32 flags;
69};
70
71struct rsnd_dvc_platform_info {
72 u32 flags;
73};
74
75struct rsnd_dai_path_info {
76 struct rsnd_ssi_platform_info *ssi;
77 struct rsnd_src_platform_info *src;
78 struct rsnd_ctu_platform_info *ctu;
79 struct rsnd_mix_platform_info *mix;
80 struct rsnd_dvc_platform_info *dvc;
81};
82
83struct rsnd_dai_platform_info {
84 struct rsnd_dai_path_info playback;
85 struct rsnd_dai_path_info capture;
86};
87
88/*
89 * flags
90 *
91 * 0x0000000A
92 *
93 * A : generation
94 */
95#define RSND_GEN_MASK (0xF << 0)
96#define RSND_GEN1 (1 << 0) /* fixme */
97#define RSND_GEN2 (2 << 0) /* fixme */
98
99struct rcar_snd_info {
100 u32 flags;
101 struct rsnd_ssi_platform_info *ssi_info;
102 int ssi_info_nr;
103 struct rsnd_src_platform_info *src_info;
104 int src_info_nr;
105 struct rsnd_ctu_platform_info *ctu_info;
106 int ctu_info_nr;
107 struct rsnd_mix_platform_info *mix_info;
108 int mix_info_nr;
109 struct rsnd_dvc_platform_info *dvc_info;
110 int dvc_info_nr;
111 struct rsnd_dai_platform_info *dai_info;
112 int dai_info_nr;
113 int (*start)(int id);
114 int (*stop)(int id);
115};
116
117#endif
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 7a0e52b4640a..085329878525 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -21,10 +21,11 @@
21#include <linux/of_irq.h> 21#include <linux/of_irq.h>
22#include <linux/sh_dma.h> 22#include <linux/sh_dma.h>
23#include <linux/workqueue.h> 23#include <linux/workqueue.h>
24#include <sound/rcar_snd.h>
25#include <sound/soc.h> 24#include <sound/soc.h>
26#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
27 26
27#include "rcar_snd.h"
28
28/* 29/*
29 * pseudo register 30 * pseudo register
30 * 31 *
@@ -214,6 +215,7 @@ struct rsnd_dma {
214}; 215};
215#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en) 216#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
216#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp) 217#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
218#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
217 219
218void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma); 220void rsnd_dma_start(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
219void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma); 221void rsnd_dma_stop(struct rsnd_dai_stream *io, struct rsnd_dma *dma);
@@ -225,8 +227,6 @@ int rsnd_dma_probe(struct platform_device *pdev,
225struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, 227struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
226 struct rsnd_mod *mod, char *name); 228 struct rsnd_mod *mod, char *name);
227 229
228#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
229
230/* 230/*
231 * R-Car sound mod 231 * R-Car sound mod
232 */ 232 */
@@ -330,8 +330,9 @@ struct rsnd_mod {
330#define rsnd_mod_to_priv(mod) ((mod)->priv) 330#define rsnd_mod_to_priv(mod) ((mod)->priv)
331#define rsnd_mod_to_dma(mod) (&(mod)->dma) 331#define rsnd_mod_to_dma(mod) (&(mod)->dma)
332#define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1) 332#define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1)
333#define rsnd_mod_hw_start(mod) clk_enable((mod)->clk) 333#define rsnd_mod_power_on(mod) clk_enable((mod)->clk)
334#define rsnd_mod_hw_stop(mod) clk_disable((mod)->clk) 334#define rsnd_mod_power_off(mod) clk_disable((mod)->clk)
335#define rsnd_mod_get(ip) (&(ip)->mod)
335 336
336int rsnd_mod_init(struct rsnd_priv *priv, 337int rsnd_mod_init(struct rsnd_priv *priv,
337 struct rsnd_mod *mod, 338 struct rsnd_mod *mod,
@@ -571,9 +572,12 @@ int rsnd_ssi_probe(struct platform_device *pdev,
571void rsnd_ssi_remove(struct platform_device *pdev, 572void rsnd_ssi_remove(struct platform_device *pdev,
572 struct rsnd_priv *priv); 573 struct rsnd_priv *priv);
573struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); 574struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
574int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
575int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); 575int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);
576int rsnd_ssi_use_busif(struct rsnd_dai_stream *io, struct rsnd_mod *mod); 576int rsnd_ssi_use_busif(struct rsnd_dai_stream *io);
577
578#define rsnd_ssi_is_pin_sharing(io) \
579 __rsnd_ssi_is_pin_sharing(rsnd_io_to_mod_ssi(io))
580int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
577 581
578/* 582/*
579 * R-Car SRC 583 * R-Car SRC
@@ -627,4 +631,15 @@ void rsnd_dvc_remove(struct platform_device *pdev,
627 struct rsnd_priv *priv); 631 struct rsnd_priv *priv);
628struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id); 632struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id);
629 633
634#ifdef DEBUG
635void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type);
636#define rsnd_mod_confirm_ssi(mssi) rsnd_mod_make_sure(mssi, RSND_MOD_SSI)
637#define rsnd_mod_confirm_src(msrc) rsnd_mod_make_sure(msrc, RSND_MOD_SRC)
638#define rsnd_mod_confirm_dvc(mdvc) rsnd_mod_make_sure(mdvc, RSND_MOD_DVC)
639#else
640#define rsnd_mod_confirm_ssi(mssi)
641#define rsnd_mod_confirm_src(msrc)
642#define rsnd_mod_confirm_dvc(mdvc)
643#endif
644
630#endif 645#endif
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 89a18e102feb..261b50217c48 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -159,7 +159,7 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
159 /* 159 /*
160 * SSI_MODE1 160 * SSI_MODE1
161 */ 161 */
162 if (rsnd_ssi_is_pin_sharing(ssi_mod)) { 162 if (rsnd_ssi_is_pin_sharing(io)) {
163 int shift = -1; 163 int shift = -1;
164 switch (ssi_id) { 164 switch (ssi_id) {
165 case 1: 165 case 1:
@@ -352,7 +352,7 @@ static int rsnd_src_init(struct rsnd_mod *mod,
352{ 352{
353 struct rsnd_src *src = rsnd_mod_to_src(mod); 353 struct rsnd_src *src = rsnd_mod_to_src(mod);
354 354
355 rsnd_mod_hw_start(mod); 355 rsnd_mod_power_on(mod);
356 356
357 rsnd_src_soft_reset(mod); 357 rsnd_src_soft_reset(mod);
358 358
@@ -373,7 +373,7 @@ static int rsnd_src_quit(struct rsnd_mod *mod,
373 struct rsnd_src *src = rsnd_mod_to_src(mod); 373 struct rsnd_src *src = rsnd_mod_to_src(mod);
374 struct device *dev = rsnd_priv_to_dev(priv); 374 struct device *dev = rsnd_priv_to_dev(priv);
375 375
376 rsnd_mod_hw_stop(mod); 376 rsnd_mod_power_off(mod);
377 377
378 if (src->err) 378 if (src->err)
379 dev_warn(dev, "%s[%d] under/over flow err = %d\n", 379 dev_warn(dev, "%s[%d] under/over flow err = %d\n",
@@ -918,11 +918,10 @@ static void rsnd_src_reconvert_update(struct rsnd_dai_stream *io,
918 rsnd_mod_write(mod, SRC_IFSVR, fsrate); 918 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
919} 919}
920 920
921static int rsnd_src_pcm_new(struct rsnd_mod *mod, 921static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod,
922 struct rsnd_dai_stream *io, 922 struct rsnd_dai_stream *io,
923 struct snd_soc_pcm_runtime *rtd) 923 struct snd_soc_pcm_runtime *rtd)
924{ 924{
925 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
926 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 925 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
927 struct rsnd_src *src = rsnd_mod_to_src(mod); 926 struct rsnd_src *src = rsnd_mod_to_src(mod);
928 int ret; 927 int ret;
@@ -932,12 +931,6 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod,
932 */ 931 */
933 932
934 /* 933 /*
935 * Gen1 is not supported
936 */
937 if (rsnd_is_gen1(priv))
938 return 0;
939
940 /*
941 * SRC sync convert needs clock master 934 * SRC sync convert needs clock master
942 */ 935 */
943 if (!rsnd_rdai_is_clk_master(rdai)) 936 if (!rsnd_rdai_is_clk_master(rdai))
@@ -975,7 +968,7 @@ static struct rsnd_mod_ops rsnd_src_gen2_ops = {
975 .start = rsnd_src_start_gen2, 968 .start = rsnd_src_start_gen2,
976 .stop = rsnd_src_stop_gen2, 969 .stop = rsnd_src_stop_gen2,
977 .hw_params = rsnd_src_hw_params, 970 .hw_params = rsnd_src_hw_params,
978 .pcm_new = rsnd_src_pcm_new, 971 .pcm_new = rsnd_src_pcm_new_gen2,
979}; 972};
980 973
981struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) 974struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
@@ -983,7 +976,7 @@ struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
983 if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv))) 976 if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv)))
984 id = 0; 977 id = 0;
985 978
986 return &((struct rsnd_src *)(priv->src) + id)->mod; 979 return rsnd_mod_get((struct rsnd_src *)(priv->src) + id);
987} 980}
988 981
989static void rsnd_of_parse_src(struct platform_device *pdev, 982static void rsnd_of_parse_src(struct platform_device *pdev,
@@ -1043,8 +1036,10 @@ int rsnd_src_probe(struct platform_device *pdev,
1043 int i, nr, ret; 1036 int i, nr, ret;
1044 1037
1045 ops = NULL; 1038 ops = NULL;
1046 if (rsnd_is_gen1(priv)) 1039 if (rsnd_is_gen1(priv)) {
1047 ops = &rsnd_src_gen1_ops; 1040 ops = &rsnd_src_gen1_ops;
1041 dev_warn(dev, "Gen1 support will be removed soon\n");
1042 }
1048 if (rsnd_is_gen2(priv)) 1043 if (rsnd_is_gen2(priv))
1049 ops = &rsnd_src_gen2_ops; 1044 ops = &rsnd_src_gen2_ops;
1050 if (!ops) { 1045 if (!ops) {
@@ -1078,7 +1073,7 @@ int rsnd_src_probe(struct platform_device *pdev,
1078 1073
1079 src->info = &info->src_info[i]; 1074 src->info = &info->src_info[i];
1080 1075
1081 ret = rsnd_mod_init(priv, &src->mod, ops, clk, RSND_MOD_SRC, i); 1076 ret = rsnd_mod_init(priv, rsnd_mod_get(src), ops, clk, RSND_MOD_SRC, i);
1082 if (ret) 1077 if (ret)
1083 return ret; 1078 return ret;
1084 } 1079 }
@@ -1093,6 +1088,6 @@ void rsnd_src_remove(struct platform_device *pdev,
1093 int i; 1088 int i;
1094 1089
1095 for_each_rsnd_src(src, priv, i) { 1090 for_each_rsnd_src(src, priv, i) {
1096 rsnd_mod_quit(&src->mod); 1091 rsnd_mod_quit(rsnd_mod_get(src));
1097 } 1092 }
1098} 1093}
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index d45b9a7e324e..1427ec21bd7e 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -79,7 +79,6 @@ struct rsnd_ssi {
79 79
80#define rsnd_ssi_nr(priv) ((priv)->ssi_nr) 80#define rsnd_ssi_nr(priv) ((priv)->ssi_nr)
81#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) 81#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod)
82#define rsnd_dma_to_ssi(dma) rsnd_mod_to_ssi(rsnd_dma_to_mod(dma))
83#define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0) 82#define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0)
84#define rsnd_ssi_parent(ssi) ((ssi)->parent) 83#define rsnd_ssi_parent(ssi) ((ssi)->parent)
85#define rsnd_ssi_mode_flags(p) ((p)->info->flags) 84#define rsnd_ssi_mode_flags(p) ((p)->info->flags)
@@ -87,8 +86,9 @@ struct rsnd_ssi {
87#define rsnd_ssi_of_node(priv) \ 86#define rsnd_ssi_of_node(priv) \
88 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi") 87 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi")
89 88
90int rsnd_ssi_use_busif(struct rsnd_dai_stream *io, struct rsnd_mod *mod) 89int rsnd_ssi_use_busif(struct rsnd_dai_stream *io)
91{ 90{
91 struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);
92 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 92 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
93 int use_busif = 0; 93 int use_busif = 0;
94 94
@@ -128,10 +128,8 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
128 struct rsnd_priv *priv = rsnd_io_to_priv(io); 128 struct rsnd_priv *priv = rsnd_io_to_priv(io);
129 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 129 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
130 struct device *dev = rsnd_priv_to_dev(priv); 130 struct device *dev = rsnd_priv_to_dev(priv);
131 int i, j, ret; 131 struct rsnd_mod *mod = rsnd_mod_get(ssi);
132 int adg_clk_div_table[] = { 132 int j, ret;
133 1, 6, /* see adg.c */
134 };
135 int ssi_clk_mul_table[] = { 133 int ssi_clk_mul_table[] = {
136 1, 2, 4, 8, 16, 6, 12, 134 1, 2, 4, 8, 16, 6, 12,
137 }; 135 };
@@ -141,28 +139,25 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
141 /* 139 /*
142 * Find best clock, and try to start ADG 140 * Find best clock, and try to start ADG
143 */ 141 */
144 for (i = 0; i < ARRAY_SIZE(adg_clk_div_table); i++) { 142 for (j = 0; j < ARRAY_SIZE(ssi_clk_mul_table); j++) {
145 for (j = 0; j < ARRAY_SIZE(ssi_clk_mul_table); j++) { 143
146 144 /*
147 /* 145 * this driver is assuming that
148 * this driver is assuming that 146 * system word is 64fs (= 2 x 32bit)
149 * system word is 64fs (= 2 x 32bit) 147 * see rsnd_ssi_init()
150 * see rsnd_ssi_init() 148 */
151 */ 149 main_rate = rate * 32 * 2 * ssi_clk_mul_table[j];
152 main_rate = rate / adg_clk_div_table[i] 150
153 * 32 * 2 * ssi_clk_mul_table[j]; 151 ret = rsnd_adg_ssi_clk_try_start(mod, main_rate);
154 152 if (0 == ret) {
155 ret = rsnd_adg_ssi_clk_try_start(&ssi->mod, main_rate); 153 ssi->cr_clk = FORCE | SWL_32 |
156 if (0 == ret) { 154 SCKD | SWSD | CKDV(j);
157 ssi->cr_clk = FORCE | SWL_32 | 155
158 SCKD | SWSD | CKDV(j); 156 dev_dbg(dev, "%s[%d] outputs %u Hz\n",
159 157 rsnd_mod_name(mod),
160 dev_dbg(dev, "%s[%d] outputs %u Hz\n", 158 rsnd_mod_id(mod), rate);
161 rsnd_mod_name(&ssi->mod), 159
162 rsnd_mod_id(&ssi->mod), rate); 160 return 0;
163
164 return 0;
165 }
166 } 161 }
167 } 162 }
168 163
@@ -172,8 +167,10 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi,
172 167
173static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi) 168static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi)
174{ 169{
170 struct rsnd_mod *mod = rsnd_mod_get(ssi);
171
175 ssi->cr_clk = 0; 172 ssi->cr_clk = 0;
176 rsnd_adg_ssi_clk_stop(&ssi->mod); 173 rsnd_adg_ssi_clk_stop(mod);
177} 174}
178 175
179static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, 176static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
@@ -182,11 +179,12 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
182 struct rsnd_priv *priv = rsnd_io_to_priv(io); 179 struct rsnd_priv *priv = rsnd_io_to_priv(io);
183 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 180 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
184 struct device *dev = rsnd_priv_to_dev(priv); 181 struct device *dev = rsnd_priv_to_dev(priv);
182 struct rsnd_mod *mod = rsnd_mod_get(ssi);
185 u32 cr_mode; 183 u32 cr_mode;
186 u32 cr; 184 u32 cr;
187 185
188 if (0 == ssi->usrcnt) { 186 if (0 == ssi->usrcnt) {
189 rsnd_mod_hw_start(&ssi->mod); 187 rsnd_mod_power_on(mod);
190 188
191 if (rsnd_rdai_is_clk_master(rdai)) { 189 if (rsnd_rdai_is_clk_master(rdai)) {
192 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi); 190 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi);
@@ -198,7 +196,7 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
198 } 196 }
199 } 197 }
200 198
201 if (rsnd_ssi_is_dma_mode(&ssi->mod)) { 199 if (rsnd_ssi_is_dma_mode(mod)) {
202 cr_mode = UIEN | OIEN | /* over/under run */ 200 cr_mode = UIEN | OIEN | /* over/under run */
203 DMEN; /* DMA : enable DMA */ 201 DMEN; /* DMA : enable DMA */
204 } else { 202 } else {
@@ -210,24 +208,25 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
210 cr_mode | 208 cr_mode |
211 EN; 209 EN;
212 210
213 rsnd_mod_write(&ssi->mod, SSICR, cr); 211 rsnd_mod_write(mod, SSICR, cr);
214 212
215 /* enable WS continue */ 213 /* enable WS continue */
216 if (rsnd_rdai_is_clk_master(rdai)) 214 if (rsnd_rdai_is_clk_master(rdai))
217 rsnd_mod_write(&ssi->mod, SSIWSR, CONT); 215 rsnd_mod_write(mod, SSIWSR, CONT);
218 216
219 /* clear error status */ 217 /* clear error status */
220 rsnd_mod_write(&ssi->mod, SSISR, 0); 218 rsnd_mod_write(mod, SSISR, 0);
221 219
222 ssi->usrcnt++; 220 ssi->usrcnt++;
223 221
224 dev_dbg(dev, "%s[%d] hw started\n", 222 dev_dbg(dev, "%s[%d] hw started\n",
225 rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); 223 rsnd_mod_name(mod), rsnd_mod_id(mod));
226} 224}
227 225
228static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi) 226static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi)
229{ 227{
230 struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); 228 struct rsnd_mod *mod = rsnd_mod_get(ssi);
229 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
231 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 230 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
232 struct device *dev = rsnd_priv_to_dev(priv); 231 struct device *dev = rsnd_priv_to_dev(priv);
233 u32 cr; 232 u32 cr;
@@ -247,15 +246,15 @@ static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi)
247 cr = ssi->cr_own | 246 cr = ssi->cr_own |
248 ssi->cr_clk; 247 ssi->cr_clk;
249 248
250 rsnd_mod_write(&ssi->mod, SSICR, cr | EN); 249 rsnd_mod_write(mod, SSICR, cr | EN);
251 rsnd_ssi_status_check(&ssi->mod, DIRQ); 250 rsnd_ssi_status_check(mod, DIRQ);
252 251
253 /* 252 /*
254 * disable SSI, 253 * disable SSI,
255 * and, wait idle state 254 * and, wait idle state
256 */ 255 */
257 rsnd_mod_write(&ssi->mod, SSICR, cr); /* disabled all */ 256 rsnd_mod_write(mod, SSICR, cr); /* disabled all */
258 rsnd_ssi_status_check(&ssi->mod, IIRQ); 257 rsnd_ssi_status_check(mod, IIRQ);
259 258
260 if (rsnd_rdai_is_clk_master(rdai)) { 259 if (rsnd_rdai_is_clk_master(rdai)) {
261 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi); 260 struct rsnd_ssi *ssi_parent = rsnd_ssi_parent(ssi);
@@ -266,13 +265,13 @@ static void rsnd_ssi_hw_stop(struct rsnd_dai_stream *io, struct rsnd_ssi *ssi)
266 rsnd_ssi_master_clk_stop(ssi); 265 rsnd_ssi_master_clk_stop(ssi);
267 } 266 }
268 267
269 rsnd_mod_hw_stop(&ssi->mod); 268 rsnd_mod_power_off(mod);
270 269
271 ssi->chan = 0; 270 ssi->chan = 0;
272 } 271 }
273 272
274 dev_dbg(dev, "%s[%d] hw stopped\n", 273 dev_dbg(dev, "%s[%d] hw stopped\n",
275 rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); 274 rsnd_mod_name(mod), rsnd_mod_id(mod));
276} 275}
277 276
278/* 277/*
@@ -371,7 +370,7 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod,
371 /* It will be removed on rsnd_ssi_hw_stop */ 370 /* It will be removed on rsnd_ssi_hw_stop */
372 ssi->chan = chan; 371 ssi->chan = chan;
373 if (ssi_parent) 372 if (ssi_parent)
374 return rsnd_ssi_hw_params(&ssi_parent->mod, io, 373 return rsnd_ssi_hw_params(rsnd_mod_get(ssi_parent), io,
375 substream, params); 374 substream, params);
376 375
377 return 0; 376 return 0;
@@ -379,12 +378,14 @@ static int rsnd_ssi_hw_params(struct rsnd_mod *mod,
379 378
380static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status) 379static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status)
381{ 380{
381 struct rsnd_mod *mod = rsnd_mod_get(ssi);
382
382 /* under/over flow error */ 383 /* under/over flow error */
383 if (status & (UIRQ | OIRQ)) { 384 if (status & (UIRQ | OIRQ)) {
384 ssi->err++; 385 ssi->err++;
385 386
386 /* clear error status */ 387 /* clear error status */
387 rsnd_mod_write(&ssi->mod, SSISR, 0); 388 rsnd_mod_write(mod, SSISR, 0);
388 } 389 }
389} 390}
390 391
@@ -394,7 +395,7 @@ static int rsnd_ssi_start(struct rsnd_mod *mod,
394{ 395{
395 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 396 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
396 397
397 rsnd_src_ssiu_start(mod, io, rsnd_ssi_use_busif(io, mod)); 398 rsnd_src_ssiu_start(mod, io, rsnd_ssi_use_busif(io));
398 399
399 rsnd_ssi_hw_start(ssi, io); 400 rsnd_ssi_hw_start(ssi, io);
400 401
@@ -554,7 +555,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
554 rsnd_dma_quit(io, rsnd_mod_to_dma(mod)); 555 rsnd_dma_quit(io, rsnd_mod_to_dma(mod));
555 556
556 /* PIO will request IRQ again */ 557 /* PIO will request IRQ again */
557 devm_free_irq(dev, irq, ssi); 558 devm_free_irq(dev, irq, mod);
558 559
559 return 0; 560 return 0;
560} 561}
@@ -613,7 +614,7 @@ static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_dai_stream *io,
613 int is_play = rsnd_io_is_play(io); 614 int is_play = rsnd_io_is_play(io);
614 char *name; 615 char *name;
615 616
616 if (rsnd_ssi_use_busif(io, mod)) 617 if (rsnd_ssi_use_busif(io))
617 name = is_play ? "rxu" : "txu"; 618 name = is_play ? "rxu" : "txu";
618 else 619 else
619 name = is_play ? "rx" : "tx"; 620 name = is_play ? "rx" : "tx";
@@ -656,10 +657,10 @@ struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id)
656 if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv))) 657 if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv)))
657 id = 0; 658 id = 0;
658 659
659 return &((struct rsnd_ssi *)(priv->ssi) + id)->mod; 660 return rsnd_mod_get((struct rsnd_ssi *)(priv->ssi) + id);
660} 661}
661 662
662int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod) 663int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
663{ 664{
664 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 665 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
665 666
@@ -668,10 +669,12 @@ int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
668 669
669static void rsnd_ssi_parent_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi) 670static void rsnd_ssi_parent_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi)
670{ 671{
671 if (!rsnd_ssi_is_pin_sharing(&ssi->mod)) 672 struct rsnd_mod *mod = rsnd_mod_get(ssi);
673
674 if (!__rsnd_ssi_is_pin_sharing(mod))
672 return; 675 return;
673 676
674 switch (rsnd_mod_id(&ssi->mod)) { 677 switch (rsnd_mod_id(mod)) {
675 case 1: 678 case 1:
676 case 2: 679 case 2:
677 ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 0)); 680 ssi->parent = rsnd_mod_to_ssi(rsnd_ssi_mod_get(priv, 0));
@@ -697,9 +700,6 @@ static void rsnd_of_parse_ssi(struct platform_device *pdev,
697 struct device *dev = &pdev->dev; 700 struct device *dev = &pdev->dev;
698 int nr, i; 701 int nr, i;
699 702
700 if (!of_data)
701 return;
702
703 node = rsnd_ssi_of_node(priv); 703 node = rsnd_ssi_of_node(priv);
704 if (!node) 704 if (!node)
705 return; 705 return;
@@ -794,7 +794,8 @@ int rsnd_ssi_probe(struct platform_device *pdev,
794 else if (rsnd_ssi_pio_available(ssi)) 794 else if (rsnd_ssi_pio_available(ssi))
795 ops = &rsnd_ssi_pio_ops; 795 ops = &rsnd_ssi_pio_ops;
796 796
797 ret = rsnd_mod_init(priv, &ssi->mod, ops, clk, RSND_MOD_SSI, i); 797 ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk,
798 RSND_MOD_SSI, i);
798 if (ret) 799 if (ret)
799 return ret; 800 return ret;
800 801
@@ -811,6 +812,6 @@ void rsnd_ssi_remove(struct platform_device *pdev,
811 int i; 812 int i;
812 813
813 for_each_rsnd_ssi(ssi, priv, i) { 814 for_each_rsnd_ssi(ssi, priv, i) {
814 rsnd_mod_quit(&ssi->mod); 815 rsnd_mod_quit(rsnd_mod_get(ssi));
815 } 816 }
816} 817}
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
index abb0d956231c..76b2ab8c2b4a 100644
--- a/sound/soc/sh/siu_dai.c
+++ b/sound/soc/sh/siu_dai.c
@@ -738,7 +738,7 @@ static int siu_probe(struct platform_device *pdev)
738 struct siu_info *info; 738 struct siu_info *info;
739 int ret; 739 int ret;
740 740
741 info = kmalloc(sizeof(*info), GFP_KERNEL); 741 info = devm_kmalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
742 if (!info) 742 if (!info)
743 return -ENOMEM; 743 return -ENOMEM;
744 siu_i2s_data = info; 744 siu_i2s_data = info;
@@ -746,7 +746,7 @@ static int siu_probe(struct platform_device *pdev)
746 746
747 ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev); 747 ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev);
748 if (ret) 748 if (ret)
749 goto ereqfw; 749 return ret;
750 750
751 /* 751 /*
752 * Loaded firmware is "const" - read only, but we have to modify it in 752 * Loaded firmware is "const" - read only, but we have to modify it in
@@ -757,89 +757,52 @@ static int siu_probe(struct platform_device *pdev)
757 release_firmware(fw_entry); 757 release_firmware(fw_entry);
758 758
759 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 759 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
760 if (!res) { 760 if (!res)
761 ret = -ENODEV; 761 return -ENODEV;
762 goto egetres;
763 }
764 762
765 region = request_mem_region(res->start, resource_size(res), 763 region = devm_request_mem_region(&pdev->dev, res->start,
766 pdev->name); 764 resource_size(res), pdev->name);
767 if (!region) { 765 if (!region) {
768 dev_err(&pdev->dev, "SIU region already claimed\n"); 766 dev_err(&pdev->dev, "SIU region already claimed\n");
769 ret = -EBUSY; 767 return -EBUSY;
770 goto ereqmemreg;
771 } 768 }
772 769
773 ret = -ENOMEM; 770 info->pram = devm_ioremap(&pdev->dev, res->start, PRAM_SIZE);
774 info->pram = ioremap(res->start, PRAM_SIZE);
775 if (!info->pram) 771 if (!info->pram)
776 goto emappram; 772 return -ENOMEM;
777 info->xram = ioremap(res->start + XRAM_OFFSET, XRAM_SIZE); 773 info->xram = devm_ioremap(&pdev->dev, res->start + XRAM_OFFSET,
774 XRAM_SIZE);
778 if (!info->xram) 775 if (!info->xram)
779 goto emapxram; 776 return -ENOMEM;
780 info->yram = ioremap(res->start + YRAM_OFFSET, YRAM_SIZE); 777 info->yram = devm_ioremap(&pdev->dev, res->start + YRAM_OFFSET,
778 YRAM_SIZE);
781 if (!info->yram) 779 if (!info->yram)
782 goto emapyram; 780 return -ENOMEM;
783 info->reg = ioremap(res->start + REG_OFFSET, resource_size(res) - 781 info->reg = devm_ioremap(&pdev->dev, res->start + REG_OFFSET,
784 REG_OFFSET); 782 resource_size(res) - REG_OFFSET);
785 if (!info->reg) 783 if (!info->reg)
786 goto emapreg; 784 return -ENOMEM;
787 785
788 dev_set_drvdata(&pdev->dev, info); 786 dev_set_drvdata(&pdev->dev, info);
789 787
790 /* register using ARRAY version so we can keep dai name */ 788 /* register using ARRAY version so we can keep dai name */
791 ret = snd_soc_register_component(&pdev->dev, &siu_i2s_component, 789 ret = devm_snd_soc_register_component(&pdev->dev, &siu_i2s_component,
792 &siu_i2s_dai, 1); 790 &siu_i2s_dai, 1);
793 if (ret < 0) 791 if (ret < 0)
794 goto edaiinit; 792 return ret;
795 793
796 ret = snd_soc_register_platform(&pdev->dev, &siu_platform); 794 ret = devm_snd_soc_register_platform(&pdev->dev, &siu_platform);
797 if (ret < 0) 795 if (ret < 0)
798 goto esocregp; 796 return ret;
799 797
800 pm_runtime_enable(&pdev->dev); 798 pm_runtime_enable(&pdev->dev);
801 799
802 return ret; 800 return 0;
803
804esocregp:
805 snd_soc_unregister_component(&pdev->dev);
806edaiinit:
807 iounmap(info->reg);
808emapreg:
809 iounmap(info->yram);
810emapyram:
811 iounmap(info->xram);
812emapxram:
813 iounmap(info->pram);
814emappram:
815 release_mem_region(res->start, resource_size(res));
816ereqmemreg:
817egetres:
818ereqfw:
819 kfree(info);
820
821 return ret;
822} 801}
823 802
824static int siu_remove(struct platform_device *pdev) 803static int siu_remove(struct platform_device *pdev)
825{ 804{
826 struct siu_info *info = dev_get_drvdata(&pdev->dev);
827 struct resource *res;
828
829 pm_runtime_disable(&pdev->dev); 805 pm_runtime_disable(&pdev->dev);
830
831 snd_soc_unregister_platform(&pdev->dev);
832 snd_soc_unregister_component(&pdev->dev);
833
834 iounmap(info->reg);
835 iounmap(info->yram);
836 iounmap(info->xram);
837 iounmap(info->pram);
838 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
839 if (res)
840 release_mem_region(res->start, resource_size(res));
841 kfree(info);
842
843 return 0; 806 return 0;
844} 807}
845 808
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 025c38fbe3c0..12a9820feac1 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -612,8 +612,15 @@ static struct snd_compr_ops soc_compr_dyn_ops = {
612 .get_codec_caps = soc_compr_get_codec_caps 612 .get_codec_caps = soc_compr_get_codec_caps
613}; 613};
614 614
615/* create a new compress */ 615/**
616int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) 616 * snd_soc_new_compress - create a new compress.
617 *
618 * @rtd: The runtime for which we will create compress
619 * @num: the device index number (zero based - shared with normal PCMs)
620 *
621 * Return: 0 for success, else error.
622 */
623int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
617{ 624{
618 struct snd_soc_codec *codec = rtd->codec; 625 struct snd_soc_codec *codec = rtd->codec;
619 struct snd_soc_platform *platform = rtd->platform; 626 struct snd_soc_platform *platform = rtd->platform;
@@ -703,3 +710,4 @@ compr_err:
703 kfree(compr); 710 kfree(compr);
704 return ret; 711 return ret;
705} 712}
713EXPORT_SYMBOL_GPL(snd_soc_new_compress);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 6173d15236c3..24b096066a07 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1370,9 +1370,9 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1370 soc_dpcm_debugfs_add(rtd); 1370 soc_dpcm_debugfs_add(rtd);
1371#endif 1371#endif
1372 1372
1373 if (cpu_dai->driver->compress_dai) { 1373 if (cpu_dai->driver->compress_new) {
1374 /*create compress_device"*/ 1374 /*create compress_device"*/
1375 ret = soc_new_compress(rtd, num); 1375 ret = cpu_dai->driver->compress_new(rtd, num);
1376 if (ret < 0) { 1376 if (ret < 0) {
1377 dev_err(card->dev, "ASoC: can't create compress %s\n", 1377 dev_err(card->dev, "ASoC: can't create compress %s\n",
1378 dai_link->stream_name); 1378 dai_link->stream_name);
@@ -3291,13 +3291,38 @@ int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
3291} 3291}
3292EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets); 3292EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets);
3293 3293
3294static int snd_soc_of_get_slot_mask(struct device_node *np,
3295 const char *prop_name,
3296 unsigned int *mask)
3297{
3298 u32 val;
3299 const __be32 *of_slot_mask = of_get_property(np, prop_name, &val);
3300 int i;
3301
3302 if (!of_slot_mask)
3303 return 0;
3304 val /= sizeof(u32);
3305 for (i = 0; i < val; i++)
3306 if (be32_to_cpup(&of_slot_mask[i]))
3307 *mask |= (1 << i);
3308
3309 return val;
3310}
3311
3294int snd_soc_of_parse_tdm_slot(struct device_node *np, 3312int snd_soc_of_parse_tdm_slot(struct device_node *np,
3313 unsigned int *tx_mask,
3314 unsigned int *rx_mask,
3295 unsigned int *slots, 3315 unsigned int *slots,
3296 unsigned int *slot_width) 3316 unsigned int *slot_width)
3297{ 3317{
3298 u32 val; 3318 u32 val;
3299 int ret; 3319 int ret;
3300 3320
3321 if (tx_mask)
3322 snd_soc_of_get_slot_mask(np, "dai-tdm-slot-tx-mask", tx_mask);
3323 if (rx_mask)
3324 snd_soc_of_get_slot_mask(np, "dai-tdm-slot-rx-mask", rx_mask);
3325
3301 if (of_property_read_bool(np, "dai-tdm-slot-num")) { 3326 if (of_property_read_bool(np, "dai-tdm-slot-num")) {
3302 ret = of_property_read_u32(np, "dai-tdm-slot-num", &val); 3327 ret = of_property_read_u32(np, "dai-tdm-slot-num", &val);
3303 if (ret) 3328 if (ret)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index f4bf21a5539b..016eba10b1ec 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -509,6 +509,18 @@ static bool dapm_kcontrol_set_value(const struct snd_kcontrol *kcontrol,
509} 509}
510 510
511/** 511/**
512 * snd_soc_dapm_kcontrol_widget() - Returns the widget associated to a
513 * kcontrol
514 * @kcontrol: The kcontrol
515 */
516struct snd_soc_dapm_widget *snd_soc_dapm_kcontrol_widget(
517 struct snd_kcontrol *kcontrol)
518{
519 return dapm_kcontrol_get_wlist(kcontrol)->widgets[0];
520}
521EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_widget);
522
523/**
512 * snd_soc_dapm_kcontrol_dapm() - Returns the dapm context associated to a 524 * snd_soc_dapm_kcontrol_dapm() - Returns the dapm context associated to a
513 * kcontrol 525 * kcontrol
514 * @kcontrol: The kcontrol 526 * @kcontrol: The kcontrol
@@ -779,7 +791,7 @@ static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm,
779 * Determine if a kcontrol is shared. If it is, look it up. If it isn't, 791 * Determine if a kcontrol is shared. If it is, look it up. If it isn't,
780 * create it. Either way, add the widget into the control's widget list 792 * create it. Either way, add the widget into the control's widget list
781 */ 793 */
782static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w, 794static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w,
783 int kci) 795 int kci)
784{ 796{
785 struct snd_soc_dapm_context *dapm = w->dapm; 797 struct snd_soc_dapm_context *dapm = w->dapm;
@@ -810,6 +822,7 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
810 switch (w->id) { 822 switch (w->id) {
811 case snd_soc_dapm_switch: 823 case snd_soc_dapm_switch:
812 case snd_soc_dapm_mixer: 824 case snd_soc_dapm_mixer:
825 case snd_soc_dapm_pga:
813 wname_in_long_name = true; 826 wname_in_long_name = true;
814 kcname_in_long_name = true; 827 kcname_in_long_name = true;
815 break; 828 break;
@@ -899,7 +912,7 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
899 continue; 912 continue;
900 913
901 if (!w->kcontrols[i]) { 914 if (!w->kcontrols[i]) {
902 ret = dapm_create_or_share_mixmux_kcontrol(w, i); 915 ret = dapm_create_or_share_kcontrol(w, i);
903 if (ret < 0) 916 if (ret < 0)
904 return ret; 917 return ret;
905 } 918 }
@@ -952,7 +965,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
952 return -EINVAL; 965 return -EINVAL;
953 } 966 }
954 967
955 ret = dapm_create_or_share_mixmux_kcontrol(w, 0); 968 ret = dapm_create_or_share_kcontrol(w, 0);
956 if (ret < 0) 969 if (ret < 0)
957 return ret; 970 return ret;
958 971
@@ -967,9 +980,13 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
967/* create new dapm volume control */ 980/* create new dapm volume control */
968static int dapm_new_pga(struct snd_soc_dapm_widget *w) 981static int dapm_new_pga(struct snd_soc_dapm_widget *w)
969{ 982{
970 if (w->num_kcontrols) 983 int i, ret;
971 dev_err(w->dapm->dev, 984
972 "ASoC: PGA controls not supported: '%s'\n", w->name); 985 for (i = 0; i < w->num_kcontrols; i++) {
986 ret = dapm_create_or_share_kcontrol(w, i);
987 if (ret < 0)
988 return ret;
989 }
973 990
974 return 0; 991 return 0;
975} 992}
@@ -3473,11 +3490,29 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
3473 switch (event) { 3490 switch (event) {
3474 case SND_SOC_DAPM_PRE_PMU: 3491 case SND_SOC_DAPM_PRE_PMU:
3475 substream.stream = SNDRV_PCM_STREAM_CAPTURE; 3492 substream.stream = SNDRV_PCM_STREAM_CAPTURE;
3493 if (source->driver->ops && source->driver->ops->startup) {
3494 ret = source->driver->ops->startup(&substream, source);
3495 if (ret < 0) {
3496 dev_err(source->dev,
3497 "ASoC: startup() failed: %d\n", ret);
3498 goto out;
3499 }
3500 source->active++;
3501 }
3476 ret = soc_dai_hw_params(&substream, params, source); 3502 ret = soc_dai_hw_params(&substream, params, source);
3477 if (ret < 0) 3503 if (ret < 0)
3478 goto out; 3504 goto out;
3479 3505
3480 substream.stream = SNDRV_PCM_STREAM_PLAYBACK; 3506 substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
3507 if (sink->driver->ops && sink->driver->ops->startup) {
3508 ret = sink->driver->ops->startup(&substream, sink);
3509 if (ret < 0) {
3510 dev_err(sink->dev,
3511 "ASoC: startup() failed: %d\n", ret);
3512 goto out;
3513 }
3514 sink->active++;
3515 }
3481 ret = soc_dai_hw_params(&substream, params, sink); 3516 ret = soc_dai_hw_params(&substream, params, sink);
3482 if (ret < 0) 3517 if (ret < 0)
3483 goto out; 3518 goto out;
@@ -3497,11 +3532,23 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
3497 if (ret != 0 && ret != -ENOTSUPP) 3532 if (ret != 0 && ret != -ENOTSUPP)
3498 dev_warn(sink->dev, "ASoC: Failed to mute: %d\n", ret); 3533 dev_warn(sink->dev, "ASoC: Failed to mute: %d\n", ret);
3499 ret = 0; 3534 ret = 0;
3535
3536 source->active--;
3537 if (source->driver->ops && source->driver->ops->shutdown) {
3538 substream.stream = SNDRV_PCM_STREAM_CAPTURE;
3539 source->driver->ops->shutdown(&substream, source);
3540 }
3541
3542 sink->active--;
3543 if (sink->driver->ops && sink->driver->ops->shutdown) {
3544 substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
3545 sink->driver->ops->shutdown(&substream, sink);
3546 }
3500 break; 3547 break;
3501 3548
3502 default: 3549 default:
3503 WARN(1, "Unknown event %d\n", event); 3550 WARN(1, "Unknown event %d\n", event);
3504 return -EINVAL; 3551 ret = -EINVAL;
3505 } 3552 }
3506 3553
3507out: 3554out:
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
index 100d92b5b77e..ecd38e52285a 100644
--- a/sound/soc/soc-ops.c
+++ b/sound/soc/soc-ops.c
@@ -207,6 +207,34 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
207EXPORT_SYMBOL_GPL(snd_soc_info_volsw); 207EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
208 208
209/** 209/**
210 * snd_soc_info_volsw_sx - Mixer info callback for SX TLV controls
211 * @kcontrol: mixer control
212 * @uinfo: control element information
213 *
214 * Callback to provide information about a single mixer control, or a double
215 * mixer control that spans 2 registers of the SX TLV type. SX TLV controls
216 * have a range that represents both positive and negative values either side
217 * of zero but without a sign bit.
218 *
219 * Returns 0 for success.
220 */
221int snd_soc_info_volsw_sx(struct snd_kcontrol *kcontrol,
222 struct snd_ctl_elem_info *uinfo)
223{
224 struct soc_mixer_control *mc =
225 (struct soc_mixer_control *)kcontrol->private_value;
226
227 snd_soc_info_volsw(kcontrol, uinfo);
228 /* Max represents the number of levels in an SX control not the
229 * maximum value, so add the minimum value back on
230 */
231 uinfo->value.integer.max += mc->min;
232
233 return 0;
234}
235EXPORT_SYMBOL_GPL(snd_soc_info_volsw_sx);
236
237/**
210 * snd_soc_get_volsw - single mixer get callback 238 * snd_soc_get_volsw - single mixer get callback
211 * @kcontrol: mixer control 239 * @kcontrol: mixer control
212 * @ucontrol: control element information 240 * @ucontrol: control element information
@@ -560,16 +588,16 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range);
560/** 588/**
561 * snd_soc_limit_volume - Set new limit to an existing volume control. 589 * snd_soc_limit_volume - Set new limit to an existing volume control.
562 * 590 *
563 * @codec: where to look for the control 591 * @card: where to look for the control
564 * @name: Name of the control 592 * @name: Name of the control
565 * @max: new maximum limit 593 * @max: new maximum limit
566 * 594 *
567 * Return 0 for success, else error. 595 * Return 0 for success, else error.
568 */ 596 */
569int snd_soc_limit_volume(struct snd_soc_codec *codec, 597int snd_soc_limit_volume(struct snd_soc_card *card,
570 const char *name, int max) 598 const char *name, int max)
571{ 599{
572 struct snd_card *card = codec->component.card->snd_card; 600 struct snd_card *snd_card = card->snd_card;
573 struct snd_kcontrol *kctl; 601 struct snd_kcontrol *kctl;
574 struct soc_mixer_control *mc; 602 struct soc_mixer_control *mc;
575 int found = 0; 603 int found = 0;
@@ -579,7 +607,7 @@ int snd_soc_limit_volume(struct snd_soc_codec *codec,
579 if (unlikely(!name || max <= 0)) 607 if (unlikely(!name || max <= 0))
580 return -EINVAL; 608 return -EINVAL;
581 609
582 list_for_each_entry(kctl, &card->controls, list) { 610 list_for_each_entry(kctl, &snd_card->controls, list) {
583 if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name))) { 611 if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name))) {
584 found = 1; 612 found = 1;
585 break; 613 break;
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 70e4b9d8bdcd..317395824cd7 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -34,6 +34,24 @@
34 34
35#define DPCM_MAX_BE_USERS 8 35#define DPCM_MAX_BE_USERS 8
36 36
37/*
38 * snd_soc_dai_stream_valid() - check if a DAI supports the given stream
39 *
40 * Returns true if the DAI supports the indicated stream type.
41 */
42static bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream)
43{
44 struct snd_soc_pcm_stream *codec_stream;
45
46 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
47 codec_stream = &dai->driver->playback;
48 else
49 codec_stream = &dai->driver->capture;
50
51 /* If the codec specifies any rate at all, it supports the stream. */
52 return codec_stream->rates;
53}
54
37/** 55/**
38 * snd_soc_runtime_activate() - Increment active count for PCM runtime components 56 * snd_soc_runtime_activate() - Increment active count for PCM runtime components
39 * @rtd: ASoC PCM runtime that is activated 57 * @rtd: ASoC PCM runtime that is activated
@@ -371,6 +389,20 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream)
371 389
372 /* first calculate min/max only for CODECs in the DAI link */ 390 /* first calculate min/max only for CODECs in the DAI link */
373 for (i = 0; i < rtd->num_codecs; i++) { 391 for (i = 0; i < rtd->num_codecs; i++) {
392
393 /*
394 * Skip CODECs which don't support the current stream type.
395 * Otherwise, since the rate, channel, and format values will
396 * zero in that case, we would have no usable settings left,
397 * causing the resulting setup to fail.
398 * At least one CODEC should match, otherwise we should have
399 * bailed out on a higher level, since there would be no
400 * CODEC to support the transfer direction in that case.
401 */
402 if (!snd_soc_dai_stream_valid(rtd->codec_dais[i],
403 substream->stream))
404 continue;
405
374 codec_dai_drv = rtd->codec_dais[i]->driver; 406 codec_dai_drv = rtd->codec_dais[i]->driver;
375 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 407 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
376 codec_stream = &codec_dai_drv->playback; 408 codec_stream = &codec_dai_drv->playback;
@@ -827,6 +859,23 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
827 struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; 859 struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
828 struct snd_pcm_hw_params codec_params; 860 struct snd_pcm_hw_params codec_params;
829 861
862 /*
863 * Skip CODECs which don't support the current stream type,
864 * the idea being that if a CODEC is not used for the currently
865 * set up transfer direction, it should not need to be
866 * configured, especially since the configuration used might
867 * not even be supported by that CODEC. There may be cases
868 * however where a CODEC needs to be set up although it is
869 * actually not being used for the transfer, e.g. if a
870 * capture-only CODEC is acting as an LRCLK and/or BCLK master
871 * for the DAI link including a playback-only CODEC.
872 * If this becomes necessary, we will have to augment the
873 * machine driver setup with information on how to act, so
874 * we can do the right thing here.
875 */
876 if (!snd_soc_dai_stream_valid(codec_dai, substream->stream))
877 continue;
878
830 /* copy params for each codec */ 879 /* copy params for each codec */
831 codec_params = *params; 880 codec_params = *params;
832 881
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c
index 69d01cd925ce..8d7ec80af51b 100644
--- a/sound/soc/soc-topology.c
+++ b/sound/soc/soc-topology.c
@@ -1558,7 +1558,7 @@ static int soc_tplg_pcm_dai_elems_load(struct soc_tplg *tplg,
1558 pcm_dai = (struct snd_soc_tplg_pcm_dai *)tplg->pos; 1558 pcm_dai = (struct snd_soc_tplg_pcm_dai *)tplg->pos;
1559 1559
1560 if (soc_tplg_check_elem_count(tplg, 1560 if (soc_tplg_check_elem_count(tplg,
1561 sizeof(struct snd_soc_tplg_pcm_dai), count, 1561 sizeof(struct snd_soc_tplg_pcm), count,
1562 hdr->payload_size, "PCM DAI")) { 1562 hdr->payload_size, "PCM DAI")) {
1563 dev_err(tplg->dev, "ASoC: invalid count %d for PCM DAI elems\n", 1563 dev_err(tplg->dev, "ASoC: invalid count %d for PCM DAI elems\n",
1564 count); 1564 count);
@@ -1566,7 +1566,7 @@ static int soc_tplg_pcm_dai_elems_load(struct soc_tplg *tplg,
1566 } 1566 }
1567 1567
1568 dev_dbg(tplg->dev, "ASoC: adding %d PCM DAIs\n", count); 1568 dev_dbg(tplg->dev, "ASoC: adding %d PCM DAIs\n", count);
1569 tplg->pos += sizeof(struct snd_soc_tplg_pcm_dai) * count; 1569 tplg->pos += sizeof(struct snd_soc_tplg_pcm) * count;
1570 1570
1571 dobj = kzalloc(sizeof(struct snd_soc_dobj), GFP_KERNEL); 1571 dobj = kzalloc(sizeof(struct snd_soc_dobj), GFP_KERNEL);
1572 if (dobj == NULL) 1572 if (dobj == NULL)
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index 362c69ac1d6c..53dd085d3ee2 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -101,6 +101,15 @@ static struct snd_soc_codec_driver dummy_codec;
101 SNDRV_PCM_FMTBIT_S32_LE | \ 101 SNDRV_PCM_FMTBIT_S32_LE | \
102 SNDRV_PCM_FMTBIT_U32_LE | \ 102 SNDRV_PCM_FMTBIT_U32_LE | \
103 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) 103 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
104/*
105 * The dummy CODEC is only meant to be used in situations where there is no
106 * actual hardware.
107 *
108 * If there is actual hardware even if it does not have a control bus
109 * the hardware will still have constraints like supported samplerates, etc.
110 * which should be modelled. And the data flow graph also should be modelled
111 * using DAPM.
112 */
104static struct snd_soc_dai_driver dummy_dai = { 113static struct snd_soc_dai_driver dummy_dai = {
105 .name = "snd-soc-dummy-dai", 114 .name = "snd-soc-dummy-dai",
106 .playback = { 115 .playback = {
diff --git a/sound/soc/spear/Kconfig b/sound/soc/spear/Kconfig
index 0a53053495f3..4fb91412ebec 100644
--- a/sound/soc/spear/Kconfig
+++ b/sound/soc/spear/Kconfig
@@ -1,6 +1,6 @@
1config SND_SPEAR_SOC 1config SND_SPEAR_SOC
2 tristate 2 tristate
3 select SND_DMAENGINE_PCM 3 select SND_SOC_GENERIC_DMAENGINE_PCM
4 4
5config SND_SPEAR_SPDIF_OUT 5config SND_SPEAR_SPDIF_OUT
6 tristate 6 tristate
diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c
index f6eefe1b8f8f..843f037a317d 100644
--- a/sound/soc/sti/uniperif_player.c
+++ b/sound/soc/sti/uniperif_player.c
@@ -989,8 +989,8 @@ static int uni_player_parse_dt(struct platform_device *pdev,
989 if (!info) 989 if (!info)
990 return -ENOMEM; 990 return -ENOMEM;
991 991
992 of_property_read_u32(pnode, "version", &player->ver); 992 if (of_property_read_u32(pnode, "version", &player->ver) ||
993 if (player->ver == SND_ST_UNIPERIF_VERSION_UNKNOWN) { 993 player->ver == SND_ST_UNIPERIF_VERSION_UNKNOWN) {
994 dev_err(dev, "Unknown uniperipheral version "); 994 dev_err(dev, "Unknown uniperipheral version ");
995 return -EINVAL; 995 return -EINVAL;
996 } 996 }
@@ -998,10 +998,16 @@ static int uni_player_parse_dt(struct platform_device *pdev,
998 if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) 998 if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
999 info->underflow_enabled = 1; 999 info->underflow_enabled = 1;
1000 1000
1001 of_property_read_u32(pnode, "uniperiph-id", &info->id); 1001 if (of_property_read_u32(pnode, "uniperiph-id", &info->id)) {
1002 dev_err(dev, "uniperipheral id not defined");
1003 return -EINVAL;
1004 }
1002 1005
1003 /* Read the device mode property */ 1006 /* Read the device mode property */
1004 of_property_read_string(pnode, "mode", &mode); 1007 if (of_property_read_string(pnode, "mode", &mode)) {
1008 dev_err(dev, "uniperipheral mode not defined");
1009 return -EINVAL;
1010 }
1005 1011
1006 if (strcasecmp(mode, "hdmi") == 0) 1012 if (strcasecmp(mode, "hdmi") == 0)
1007 info->player_type = SND_ST_UNIPERIF_PLAYER_TYPE_HDMI; 1013 info->player_type = SND_ST_UNIPERIF_PLAYER_TYPE_HDMI;
diff --git a/sound/soc/sti/uniperif_reader.c b/sound/soc/sti/uniperif_reader.c
index c502626f339b..f791239a3087 100644
--- a/sound/soc/sti/uniperif_reader.c
+++ b/sound/soc/sti/uniperif_reader.c
@@ -316,7 +316,11 @@ static int uni_reader_parse_dt(struct platform_device *pdev,
316 if (!info) 316 if (!info)
317 return -ENOMEM; 317 return -ENOMEM;
318 318
319 of_property_read_u32(node, "version", &reader->ver); 319 if (of_property_read_u32(node, "version", &reader->ver) ||
320 reader->ver == SND_ST_UNIPERIF_VERSION_UNKNOWN) {
321 dev_err(&pdev->dev, "Unknown uniperipheral version ");
322 return -EINVAL;
323 }
320 324
321 /* Save the info structure */ 325 /* Save the info structure */
322 reader->info = info; 326 reader->info = info;
diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
new file mode 100644
index 000000000000..84c72ec6ad73
--- /dev/null
+++ b/sound/soc/sunxi/Kconfig
@@ -0,0 +1,11 @@
1menu "Allwinner SoC Audio support"
2
3config SND_SUN4I_CODEC
4 tristate "Allwinner A10 Codec Support"
5 select SND_SOC_GENERIC_DMAENGINE_PCM
6 select REGMAP_MMIO
7 help
8 Select Y or M to add support for the Codec embedded in the Allwinner
9 A10 and affiliated SoCs.
10
11endmenu
diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
new file mode 100644
index 000000000000..ea8a08c881d6
--- /dev/null
+++ b/sound/soc/sunxi/Makefile
@@ -0,0 +1,2 @@
1obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
2
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
new file mode 100644
index 000000000000..bcbf4da168b6
--- /dev/null
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -0,0 +1,712 @@
1/*
2 * Copyright 2014 Emilio López <emilio@elopez.com.ar>
3 * Copyright 2014 Jon Smirl <jonsmirl@gmail.com>
4 * Copyright 2015 Maxime Ripard <maxime.ripard@free-electrons.com>
5 *
6 * Based on the Allwinner SDK driver, released under the GPL.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/init.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/delay.h>
24#include <linux/slab.h>
25#include <linux/of.h>
26#include <linux/of_platform.h>
27#include <linux/of_address.h>
28#include <linux/clk.h>
29#include <linux/regmap.h>
30
31#include <sound/core.h>
32#include <sound/pcm.h>
33#include <sound/pcm_params.h>
34#include <sound/soc.h>
35#include <sound/tlv.h>
36#include <sound/initval.h>
37#include <sound/dmaengine_pcm.h>
38
39/* Codec DAC register offsets and bit fields */
40#define SUN4I_CODEC_DAC_DPC (0x00)
41#define SUN4I_CODEC_DAC_DPC_EN_DA (31)
42#define SUN4I_CODEC_DAC_DPC_DVOL (12)
43#define SUN4I_CODEC_DAC_FIFOC (0x04)
44#define SUN4I_CODEC_DAC_FIFOC_DAC_FS (29)
45#define SUN4I_CODEC_DAC_FIFOC_FIR_VERSION (28)
46#define SUN4I_CODEC_DAC_FIFOC_SEND_LASAT (26)
47#define SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE (24)
48#define SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT (21)
49#define SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL (8)
50#define SUN4I_CODEC_DAC_FIFOC_MONO_EN (6)
51#define SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS (5)
52#define SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN (4)
53#define SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH (0)
54#define SUN4I_CODEC_DAC_FIFOS (0x08)
55#define SUN4I_CODEC_DAC_TXDATA (0x0c)
56#define SUN4I_CODEC_DAC_ACTL (0x10)
57#define SUN4I_CODEC_DAC_ACTL_DACAENR (31)
58#define SUN4I_CODEC_DAC_ACTL_DACAENL (30)
59#define SUN4I_CODEC_DAC_ACTL_MIXEN (29)
60#define SUN4I_CODEC_DAC_ACTL_LDACLMIXS (15)
61#define SUN4I_CODEC_DAC_ACTL_RDACRMIXS (14)
62#define SUN4I_CODEC_DAC_ACTL_LDACRMIXS (13)
63#define SUN4I_CODEC_DAC_ACTL_DACPAS (8)
64#define SUN4I_CODEC_DAC_ACTL_MIXPAS (7)
65#define SUN4I_CODEC_DAC_ACTL_PA_MUTE (6)
66#define SUN4I_CODEC_DAC_ACTL_PA_VOL (0)
67#define SUN4I_CODEC_DAC_TUNE (0x14)
68#define SUN4I_CODEC_DAC_DEBUG (0x18)
69
70/* Codec ADC register offsets and bit fields */
71#define SUN4I_CODEC_ADC_FIFOC (0x1c)
72#define SUN4I_CODEC_ADC_FIFOC_EN_AD (28)
73#define SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE (24)
74#define SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL (8)
75#define SUN4I_CODEC_ADC_FIFOC_MONO_EN (7)
76#define SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS (6)
77#define SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN (4)
78#define SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH (0)
79#define SUN4I_CODEC_ADC_FIFOS (0x20)
80#define SUN4I_CODEC_ADC_RXDATA (0x24)
81#define SUN4I_CODEC_ADC_ACTL (0x28)
82#define SUN4I_CODEC_ADC_ACTL_ADC_R_EN (31)
83#define SUN4I_CODEC_ADC_ACTL_ADC_L_EN (30)
84#define SUN4I_CODEC_ADC_ACTL_PREG1EN (29)
85#define SUN4I_CODEC_ADC_ACTL_PREG2EN (28)
86#define SUN4I_CODEC_ADC_ACTL_VMICEN (27)
87#define SUN4I_CODEC_ADC_ACTL_VADCG (20)
88#define SUN4I_CODEC_ADC_ACTL_ADCIS (17)
89#define SUN4I_CODEC_ADC_ACTL_PA_EN (4)
90#define SUN4I_CODEC_ADC_ACTL_DDE (3)
91#define SUN4I_CODEC_ADC_DEBUG (0x2c)
92
93/* Other various ADC registers */
94#define SUN4I_CODEC_DAC_TXCNT (0x30)
95#define SUN4I_CODEC_ADC_RXCNT (0x34)
96#define SUN4I_CODEC_AC_SYS_VERI (0x38)
97#define SUN4I_CODEC_AC_MIC_PHONE_CAL (0x3c)
98
99struct sun4i_codec {
100 struct device *dev;
101 struct regmap *regmap;
102 struct clk *clk_apb;
103 struct clk *clk_module;
104
105 struct snd_dmaengine_dai_dma_data playback_dma_data;
106};
107
108static void sun4i_codec_start_playback(struct sun4i_codec *scodec)
109{
110 /*
111 * FIXME: according to the BSP, we might need to drive a PA
112 * GPIO high here on some boards
113 */
114
115 /* Flush TX FIFO */
116 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
117 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH),
118 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH));
119
120 /* Enable DAC DRQ */
121 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
122 BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN),
123 BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN));
124}
125
126static void sun4i_codec_stop_playback(struct sun4i_codec *scodec)
127{
128 /*
129 * FIXME: according to the BSP, we might need to drive a PA
130 * GPIO low here on some boards
131 */
132
133 /* Disable DAC DRQ */
134 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
135 BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN),
136 0);
137}
138
139static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd,
140 struct snd_soc_dai *dai)
141{
142 struct snd_soc_pcm_runtime *rtd = substream->private_data;
143 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
144
145 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
146 return -ENOTSUPP;
147
148 switch (cmd) {
149 case SNDRV_PCM_TRIGGER_START:
150 case SNDRV_PCM_TRIGGER_RESUME:
151 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
152 sun4i_codec_start_playback(scodec);
153 break;
154
155 case SNDRV_PCM_TRIGGER_STOP:
156 case SNDRV_PCM_TRIGGER_SUSPEND:
157 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
158 sun4i_codec_stop_playback(scodec);
159 break;
160
161 default:
162 return -EINVAL;
163 }
164
165 return 0;
166}
167
168static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
169 struct snd_soc_dai *dai)
170{
171 struct snd_soc_pcm_runtime *rtd = substream->private_data;
172 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
173 u32 val;
174
175 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
176 return -ENOTSUPP;
177
178 /* Flush the TX FIFO */
179 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
180 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH),
181 BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH));
182
183 /* Set TX FIFO Empty Trigger Level */
184 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
185 0x3f << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL,
186 0xf << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL);
187
188 if (substream->runtime->rate > 32000)
189 /* Use 64 bits FIR filter */
190 val = 0;
191 else
192 /* Use 32 bits FIR filter */
193 val = BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION);
194
195 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
196 BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION),
197 val);
198
199 /* Send zeros when we have an underrun */
200 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
201 BIT(SUN4I_CODEC_DAC_FIFOC_SEND_LASAT),
202 0);
203
204 return 0;
205}
206
207static unsigned long sun4i_codec_get_mod_freq(struct snd_pcm_hw_params *params)
208{
209 unsigned int rate = params_rate(params);
210
211 switch (rate) {
212 case 176400:
213 case 88200:
214 case 44100:
215 case 33075:
216 case 22050:
217 case 14700:
218 case 11025:
219 case 7350:
220 return 22579200;
221
222 case 192000:
223 case 96000:
224 case 48000:
225 case 32000:
226 case 24000:
227 case 16000:
228 case 12000:
229 case 8000:
230 return 24576000;
231
232 default:
233 return 0;
234 }
235}
236
237static int sun4i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
238{
239 unsigned int rate = params_rate(params);
240
241 switch (rate) {
242 case 192000:
243 case 176400:
244 return 6;
245
246 case 96000:
247 case 88200:
248 return 7;
249
250 case 48000:
251 case 44100:
252 return 0;
253
254 case 32000:
255 case 33075:
256 return 1;
257
258 case 24000:
259 case 22050:
260 return 2;
261
262 case 16000:
263 case 14700:
264 return 3;
265
266 case 12000:
267 case 11025:
268 return 4;
269
270 case 8000:
271 case 7350:
272 return 5;
273
274 default:
275 return -EINVAL;
276 }
277}
278
279static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
280 struct snd_pcm_hw_params *params,
281 struct snd_soc_dai *dai)
282{
283 struct snd_soc_pcm_runtime *rtd = substream->private_data;
284 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
285 unsigned long clk_freq;
286 int ret, hwrate;
287 u32 val;
288
289 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
290 return -ENOTSUPP;
291
292 clk_freq = sun4i_codec_get_mod_freq(params);
293 if (!clk_freq)
294 return -EINVAL;
295
296 ret = clk_set_rate(scodec->clk_module, clk_freq);
297 if (ret)
298 return ret;
299
300 hwrate = sun4i_codec_get_hw_rate(params);
301 if (hwrate < 0)
302 return hwrate;
303
304 /* Set DAC sample rate */
305 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
306 7 << SUN4I_CODEC_DAC_FIFOC_DAC_FS,
307 hwrate << SUN4I_CODEC_DAC_FIFOC_DAC_FS);
308
309 /* Set the number of channels we want to use */
310 if (params_channels(params) == 1)
311 val = BIT(SUN4I_CODEC_DAC_FIFOC_MONO_EN);
312 else
313 val = 0;
314
315 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
316 BIT(SUN4I_CODEC_DAC_FIFOC_MONO_EN),
317 val);
318
319 /* Set the number of sample bits to either 16 or 24 bits */
320 if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32) {
321 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
322 BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS),
323 BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS));
324
325 /* Set TX FIFO mode to padding the LSBs with 0 */
326 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
327 BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE),
328 0);
329
330 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
331 } else {
332 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
333 BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS),
334 0);
335
336 /* Set TX FIFO mode to repeat the MSB */
337 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
338 BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE),
339 BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE));
340
341 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
342 }
343
344 return 0;
345}
346
347static int sun4i_codec_startup(struct snd_pcm_substream *substream,
348 struct snd_soc_dai *dai)
349{
350 struct snd_soc_pcm_runtime *rtd = substream->private_data;
351 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
352
353 /*
354 * Stop issuing DRQ when we have room for less than 16 samples
355 * in our TX FIFO
356 */
357 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
358 3 << SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT,
359 3 << SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT);
360
361 return clk_prepare_enable(scodec->clk_module);
362}
363
364static void sun4i_codec_shutdown(struct snd_pcm_substream *substream,
365 struct snd_soc_dai *dai)
366{
367 struct snd_soc_pcm_runtime *rtd = substream->private_data;
368 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
369
370 clk_disable_unprepare(scodec->clk_module);
371}
372
373static const struct snd_soc_dai_ops sun4i_codec_dai_ops = {
374 .startup = sun4i_codec_startup,
375 .shutdown = sun4i_codec_shutdown,
376 .trigger = sun4i_codec_trigger,
377 .hw_params = sun4i_codec_hw_params,
378 .prepare = sun4i_codec_prepare,
379};
380
381static struct snd_soc_dai_driver sun4i_codec_dai = {
382 .name = "Codec",
383 .ops = &sun4i_codec_dai_ops,
384 .playback = {
385 .stream_name = "Codec Playback",
386 .channels_min = 1,
387 .channels_max = 2,
388 .rate_min = 8000,
389 .rate_max = 192000,
390 .rates = SNDRV_PCM_RATE_8000_48000 |
391 SNDRV_PCM_RATE_96000 |
392 SNDRV_PCM_RATE_192000,
393 .formats = SNDRV_PCM_FMTBIT_S16_LE |
394 SNDRV_PCM_FMTBIT_S32_LE,
395 .sig_bits = 24,
396 },
397};
398
399/*** Codec ***/
400static const struct snd_kcontrol_new sun4i_codec_pa_mute =
401 SOC_DAPM_SINGLE("Switch", SUN4I_CODEC_DAC_ACTL,
402 SUN4I_CODEC_DAC_ACTL_PA_MUTE, 1, 0);
403
404static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1);
405
406static const struct snd_kcontrol_new sun4i_codec_widgets[] = {
407 SOC_SINGLE_TLV("PA Volume", SUN4I_CODEC_DAC_ACTL,
408 SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0,
409 sun4i_codec_pa_volume_scale),
410};
411
412static const struct snd_kcontrol_new sun4i_codec_left_mixer_controls[] = {
413 SOC_DAPM_SINGLE("Left DAC Playback Switch", SUN4I_CODEC_DAC_ACTL,
414 SUN4I_CODEC_DAC_ACTL_LDACLMIXS, 1, 0),
415};
416
417static const struct snd_kcontrol_new sun4i_codec_right_mixer_controls[] = {
418 SOC_DAPM_SINGLE("Right DAC Playback Switch", SUN4I_CODEC_DAC_ACTL,
419 SUN4I_CODEC_DAC_ACTL_RDACRMIXS, 1, 0),
420 SOC_DAPM_SINGLE("Left DAC Playback Switch", SUN4I_CODEC_DAC_ACTL,
421 SUN4I_CODEC_DAC_ACTL_LDACRMIXS, 1, 0),
422};
423
424static const struct snd_kcontrol_new sun4i_codec_pa_mixer_controls[] = {
425 SOC_DAPM_SINGLE("DAC Playback Switch", SUN4I_CODEC_DAC_ACTL,
426 SUN4I_CODEC_DAC_ACTL_DACPAS, 1, 0),
427 SOC_DAPM_SINGLE("Mixer Playback Switch", SUN4I_CODEC_DAC_ACTL,
428 SUN4I_CODEC_DAC_ACTL_MIXPAS, 1, 0),
429};
430
431static const struct snd_soc_dapm_widget sun4i_codec_dapm_widgets[] = {
432 /* Digital parts of the DACs */
433 SND_SOC_DAPM_SUPPLY("DAC", SUN4I_CODEC_DAC_DPC,
434 SUN4I_CODEC_DAC_DPC_EN_DA, 0,
435 NULL, 0),
436
437 /* Analog parts of the DACs */
438 SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
439 SUN4I_CODEC_DAC_ACTL_DACAENL, 0),
440 SND_SOC_DAPM_DAC("Right DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
441 SUN4I_CODEC_DAC_ACTL_DACAENR, 0),
442
443 /* Mixers */
444 SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
445 sun4i_codec_left_mixer_controls,
446 ARRAY_SIZE(sun4i_codec_left_mixer_controls)),
447 SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
448 sun4i_codec_right_mixer_controls,
449 ARRAY_SIZE(sun4i_codec_right_mixer_controls)),
450
451 /* Global Mixer Enable */
452 SND_SOC_DAPM_SUPPLY("Mixer Enable", SUN4I_CODEC_DAC_ACTL,
453 SUN4I_CODEC_DAC_ACTL_MIXEN, 0, NULL, 0),
454
455 /* Pre-Amplifier */
456 SND_SOC_DAPM_MIXER("Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
457 SUN4I_CODEC_ADC_ACTL_PA_EN, 0,
458 sun4i_codec_pa_mixer_controls,
459 ARRAY_SIZE(sun4i_codec_pa_mixer_controls)),
460 SND_SOC_DAPM_SWITCH("Pre-Amplifier Mute", SND_SOC_NOPM, 0, 0,
461 &sun4i_codec_pa_mute),
462
463 SND_SOC_DAPM_OUTPUT("HP Right"),
464 SND_SOC_DAPM_OUTPUT("HP Left"),
465};
466
467static const struct snd_soc_dapm_route sun4i_codec_dapm_routes[] = {
468 /* Left DAC Routes */
469 { "Left DAC", NULL, "DAC" },
470
471 /* Right DAC Routes */
472 { "Right DAC", NULL, "DAC" },
473
474 /* Right Mixer Routes */
475 { "Right Mixer", NULL, "Mixer Enable" },
476 { "Right Mixer", "Left DAC Playback Switch", "Left DAC" },
477 { "Right Mixer", "Right DAC Playback Switch", "Right DAC" },
478
479 /* Left Mixer Routes */
480 { "Left Mixer", NULL, "Mixer Enable" },
481 { "Left Mixer", "Left DAC Playback Switch", "Left DAC" },
482
483 /* Pre-Amplifier Mixer Routes */
484 { "Pre-Amplifier", "Mixer Playback Switch", "Left Mixer" },
485 { "Pre-Amplifier", "Mixer Playback Switch", "Right Mixer" },
486 { "Pre-Amplifier", "DAC Playback Switch", "Left DAC" },
487 { "Pre-Amplifier", "DAC Playback Switch", "Right DAC" },
488
489 /* PA -> HP path */
490 { "Pre-Amplifier Mute", "Switch", "Pre-Amplifier" },
491 { "HP Right", NULL, "Pre-Amplifier Mute" },
492 { "HP Left", NULL, "Pre-Amplifier Mute" },
493};
494
495static struct snd_soc_codec_driver sun4i_codec_codec = {
496 .controls = sun4i_codec_widgets,
497 .num_controls = ARRAY_SIZE(sun4i_codec_widgets),
498 .dapm_widgets = sun4i_codec_dapm_widgets,
499 .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_dapm_widgets),
500 .dapm_routes = sun4i_codec_dapm_routes,
501 .num_dapm_routes = ARRAY_SIZE(sun4i_codec_dapm_routes),
502};
503
504static const struct snd_soc_component_driver sun4i_codec_component = {
505 .name = "sun4i-codec",
506};
507
508#define SUN4I_CODEC_RATES SNDRV_PCM_RATE_8000_192000
509#define SUN4I_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
510 SNDRV_PCM_FMTBIT_S32_LE)
511
512static int sun4i_codec_dai_probe(struct snd_soc_dai *dai)
513{
514 struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai);
515 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
516
517 snd_soc_dai_init_dma_data(dai, &scodec->playback_dma_data,
518 NULL);
519
520 return 0;
521}
522
523static struct snd_soc_dai_driver dummy_cpu_dai = {
524 .name = "sun4i-codec-cpu-dai",
525 .probe = sun4i_codec_dai_probe,
526 .playback = {
527 .stream_name = "Playback",
528 .channels_min = 1,
529 .channels_max = 2,
530 .rates = SUN4I_CODEC_RATES,
531 .formats = SUN4I_CODEC_FORMATS,
532 .sig_bits = 24,
533 },
534};
535
536static const struct regmap_config sun4i_codec_regmap_config = {
537 .reg_bits = 32,
538 .reg_stride = 4,
539 .val_bits = 32,
540 .max_register = SUN4I_CODEC_AC_MIC_PHONE_CAL,
541};
542
543static const struct of_device_id sun4i_codec_of_match[] = {
544 { .compatible = "allwinner,sun4i-a10-codec" },
545 { .compatible = "allwinner,sun7i-a20-codec" },
546 {}
547};
548MODULE_DEVICE_TABLE(of, sun4i_codec_of_match);
549
550static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
551 int *num_links)
552{
553 struct snd_soc_dai_link *link = devm_kzalloc(dev, sizeof(*link),
554 GFP_KERNEL);
555 if (!link)
556 return NULL;
557
558 link->name = "cdc";
559 link->stream_name = "CDC PCM";
560 link->codec_dai_name = "Codec";
561 link->cpu_dai_name = dev_name(dev);
562 link->codec_name = dev_name(dev);
563 link->platform_name = dev_name(dev);
564 link->dai_fmt = SND_SOC_DAIFMT_I2S;
565
566 *num_links = 1;
567
568 return link;
569};
570
571static struct snd_soc_card *sun4i_codec_create_card(struct device *dev)
572{
573 struct snd_soc_card *card;
574
575 card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
576 if (!card)
577 return NULL;
578
579 card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
580 if (!card->dai_link)
581 return NULL;
582
583 card->dev = dev;
584 card->name = "sun4i-codec";
585
586 return card;
587};
588
589static int sun4i_codec_probe(struct platform_device *pdev)
590{
591 struct snd_soc_card *card;
592 struct sun4i_codec *scodec;
593 struct resource *res;
594 void __iomem *base;
595 int ret;
596
597 scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
598 if (!scodec)
599 return -ENOMEM;
600
601 scodec->dev = &pdev->dev;
602
603 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
604 base = devm_ioremap_resource(&pdev->dev, res);
605 if (IS_ERR(base)) {
606 dev_err(&pdev->dev, "Failed to map the registers\n");
607 return PTR_ERR(base);
608 }
609
610 scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
611 &sun4i_codec_regmap_config);
612 if (IS_ERR(scodec->regmap)) {
613 dev_err(&pdev->dev, "Failed to create our regmap\n");
614 return PTR_ERR(scodec->regmap);
615 }
616
617 /* Get the clocks from the DT */
618 scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
619 if (IS_ERR(scodec->clk_apb)) {
620 dev_err(&pdev->dev, "Failed to get the APB clock\n");
621 return PTR_ERR(scodec->clk_apb);
622 }
623
624 scodec->clk_module = devm_clk_get(&pdev->dev, "codec");
625 if (IS_ERR(scodec->clk_module)) {
626 dev_err(&pdev->dev, "Failed to get the module clock\n");
627 return PTR_ERR(scodec->clk_module);
628 }
629
630 /* Enable the bus clock */
631 if (clk_prepare_enable(scodec->clk_apb)) {
632 dev_err(&pdev->dev, "Failed to enable the APB clock\n");
633 return -EINVAL;
634 }
635
636 /* DMA configuration for TX FIFO */
637 scodec->playback_dma_data.addr = res->start + SUN4I_CODEC_DAC_TXDATA;
638 scodec->playback_dma_data.maxburst = 4;
639 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
640
641 ret = snd_soc_register_codec(&pdev->dev, &sun4i_codec_codec,
642 &sun4i_codec_dai, 1);
643 if (ret) {
644 dev_err(&pdev->dev, "Failed to register our codec\n");
645 goto err_clk_disable;
646 }
647
648 ret = devm_snd_soc_register_component(&pdev->dev,
649 &sun4i_codec_component,
650 &dummy_cpu_dai, 1);
651 if (ret) {
652 dev_err(&pdev->dev, "Failed to register our DAI\n");
653 goto err_unregister_codec;
654 }
655
656 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
657 if (ret) {
658 dev_err(&pdev->dev, "Failed to register against DMAEngine\n");
659 goto err_unregister_codec;
660 }
661
662 card = sun4i_codec_create_card(&pdev->dev);
663 if (!card) {
664 dev_err(&pdev->dev, "Failed to create our card\n");
665 goto err_unregister_codec;
666 }
667
668 platform_set_drvdata(pdev, card);
669 snd_soc_card_set_drvdata(card, scodec);
670
671 ret = snd_soc_register_card(card);
672 if (ret) {
673 dev_err(&pdev->dev, "Failed to register our card\n");
674 goto err_unregister_codec;
675 }
676
677 return 0;
678
679err_unregister_codec:
680 snd_soc_unregister_codec(&pdev->dev);
681err_clk_disable:
682 clk_disable_unprepare(scodec->clk_apb);
683 return ret;
684}
685
686static int sun4i_codec_remove(struct platform_device *pdev)
687{
688 struct snd_soc_card *card = platform_get_drvdata(pdev);
689 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
690
691 snd_soc_unregister_card(card);
692 snd_soc_unregister_codec(&pdev->dev);
693 clk_disable_unprepare(scodec->clk_apb);
694
695 return 0;
696}
697
698static struct platform_driver sun4i_codec_driver = {
699 .driver = {
700 .name = "sun4i-codec",
701 .of_match_table = sun4i_codec_of_match,
702 },
703 .probe = sun4i_codec_probe,
704 .remove = sun4i_codec_remove,
705};
706module_platform_driver(sun4i_codec_driver);
707
708MODULE_DESCRIPTION("Allwinner A10 codec driver");
709MODULE_AUTHOR("Emilio López <emilio@elopez.com.ar>");
710MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
711MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
712MODULE_LICENSE("GPL");
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
index 4e0c0e502ade..ba9fc099cf67 100644
--- a/sound/soc/ux500/mop500.c
+++ b/sound/soc/ux500/mop500.c
@@ -152,6 +152,7 @@ static const struct of_device_id snd_soc_mop500_match[] = {
152 { .compatible = "stericsson,snd-soc-mop500", }, 152 { .compatible = "stericsson,snd-soc-mop500", },
153 {}, 153 {},
154}; 154};
155MODULE_DEVICE_TABLE(of, snd_soc_mop500_match);
155 156
156static struct platform_driver snd_soc_mop500_driver = { 157static struct platform_driver snd_soc_mop500_driver = {
157 .driver = { 158 .driver = {
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index f5df08ded770..6ba8ae9ecc7a 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -843,6 +843,7 @@ static const struct of_device_id ux500_msp_i2s_match[] = {
843 { .compatible = "stericsson,ux500-msp-i2s", }, 843 { .compatible = "stericsson,ux500-msp-i2s", },
844 {}, 844 {},
845}; 845};
846MODULE_DEVICE_TABLE(of, ux500_msp_i2s_match);
846 847
847static struct platform_driver msp_i2s_driver = { 848static struct platform_driver msp_i2s_driver = {
848 .driver = { 849 .driver = {
diff --git a/sound/synth/emux/emux_oss.c b/sound/synth/emux/emux_oss.c
index 82e350e9501c..ac75816ada7c 100644
--- a/sound/synth/emux/emux_oss.c
+++ b/sound/synth/emux/emux_oss.c
@@ -69,7 +69,8 @@ snd_emux_init_seq_oss(struct snd_emux *emu)
69 struct snd_seq_oss_reg *arg; 69 struct snd_seq_oss_reg *arg;
70 struct snd_seq_device *dev; 70 struct snd_seq_device *dev;
71 71
72 if (snd_seq_device_new(emu->card, 0, SNDRV_SEQ_DEV_ID_OSS, 72 /* using device#1 here for avoiding conflicts with OPL3 */
73 if (snd_seq_device_new(emu->card, 1, SNDRV_SEQ_DEV_ID_OSS,
73 sizeof(struct snd_seq_oss_reg), &dev) < 0) 74 sizeof(struct snd_seq_oss_reg), &dev) < 0)
74 return; 75 return;
75 76