aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-04-13 08:14:29 -0400
committerTakashi Iwai <tiwai@suse.de>2015-04-13 08:14:29 -0400
commitce4524e5a78123fbf2db5b1549798c91a6d98294 (patch)
treefc6450c80af14542f8bdb6b4726674669d259969 /sound
parentf2aa111041ce36b94e651d882458dea502e76721 (diff)
parent7667428f80526d908124e0647ac5dbe3dad88900 (diff)
Merge tag 'asoc-v4.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v4.1 More updates for v4.1, pretty much all drivers: - Lots of cleanups from Lars, mainly moving things from the CODEC level to the card level. - Continuing improvements to rcar from Morimoto-san, pcm512x from Howard and Peter, the Intel platforms from Vinod, Jie, Jin and Han, and to rt5670 from Bard. - Support for some non-DSP Qualcomm platforms, Google's Storm platform, Maxmim MAX98925 CODECs and the Ingenic JZ4780 SoC.
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/Kconfig1
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/atmel/Kconfig9
-rw-r--r--sound/soc/atmel/Makefile2
-rw-r--r--sound/soc/atmel/atmel-pcm-dma.c4
-rw-r--r--sound/soc/atmel/atmel-pcm-pdc.c79
-rw-r--r--sound/soc/atmel/atmel-pcm.c121
-rw-r--r--sound/soc/atmel/atmel-pcm.h5
-rw-r--r--sound/soc/codecs/Kconfig4
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/ab8500-codec.c2
-rw-r--r--sound/soc/codecs/ak4554.c2
-rw-r--r--sound/soc/codecs/ak4642.c41
-rw-r--r--sound/soc/codecs/arizona.c6
-rw-r--r--sound/soc/codecs/cs4271.c4
-rw-r--r--sound/soc/codecs/cx20442.c4
-rw-r--r--sound/soc/codecs/max98090.c17
-rw-r--r--sound/soc/codecs/max98925.c655
-rw-r--r--sound/soc/codecs/max98925.h832
-rw-r--r--sound/soc/codecs/pcm512x.c27
-rw-r--r--sound/soc/codecs/rt286.c25
-rw-r--r--sound/soc/codecs/rt5631.c2
-rw-r--r--sound/soc/codecs/rt5645.c90
-rw-r--r--sound/soc/codecs/rt5645.h2
-rw-r--r--sound/soc/codecs/rt5670.c213
-rw-r--r--sound/soc/codecs/rt5670.h7
-rw-r--r--sound/soc/codecs/rt5677.c163
-rw-r--r--sound/soc/codecs/rt5677.h79
-rw-r--r--sound/soc/codecs/tlv320aic23-i2c.c4
-rw-r--r--sound/soc/codecs/wm2200.c9
-rw-r--r--sound/soc/codecs/wm5100.c7
-rw-r--r--sound/soc/codecs/wm5102.c1
-rw-r--r--sound/soc/codecs/wm8350.c25
-rw-r--r--sound/soc/codecs/wm8731.c34
-rw-r--r--sound/soc/codecs/wm8741.c8
-rw-r--r--sound/soc/codecs/wm8753.c73
-rw-r--r--sound/soc/codecs/wm8804-i2c.c1
-rw-r--r--sound/soc/codecs/wm8804-spi.c1
-rw-r--r--sound/soc/codecs/wm8804.c297
-rw-r--r--sound/soc/codecs/wm8804.h1
-rw-r--r--sound/soc/codecs/wm8971.c99
-rw-r--r--sound/soc/codecs/wm8996.c12
-rw-r--r--sound/soc/davinci/davinci-evm.c17
-rw-r--r--sound/soc/davinci/davinci-mcasp.c236
-rw-r--r--sound/soc/fsl/Kconfig4
-rw-r--r--sound/soc/fsl/fsl_ssi.c32
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.c2
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c2
-rw-r--r--sound/soc/fsl/pcm030-audio-fabric.c2
-rw-r--r--sound/soc/fsl/wm1133-ev1.c3
-rw-r--r--sound/soc/generic/simple-card.c30
-rw-r--r--sound/soc/intel/Makefile42
-rw-r--r--sound/soc/intel/atom/Makefile7
-rw-r--r--sound/soc/intel/atom/sst-atom-controls.c (renamed from sound/soc/intel/sst-atom-controls.c)0
-rw-r--r--sound/soc/intel/atom/sst-atom-controls.h (renamed from sound/soc/intel/sst-atom-controls.h)0
-rw-r--r--sound/soc/intel/atom/sst-mfld-dsp.h (renamed from sound/soc/intel/sst-mfld-dsp.h)0
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform-compress.c (renamed from sound/soc/intel/sst-mfld-platform-compress.c)0
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform-pcm.c (renamed from sound/soc/intel/sst-mfld-platform-pcm.c)0
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform.h (renamed from sound/soc/intel/sst-mfld-platform.h)0
-rw-r--r--sound/soc/intel/atom/sst/Makefile (renamed from sound/soc/intel/sst/Makefile)0
-rw-r--r--sound/soc/intel/atom/sst/sst.c (renamed from sound/soc/intel/sst/sst.c)2
-rw-r--r--sound/soc/intel/atom/sst/sst.h (renamed from sound/soc/intel/sst/sst.h)0
-rw-r--r--sound/soc/intel/atom/sst/sst_acpi.c (renamed from sound/soc/intel/sst/sst_acpi.c)4
-rw-r--r--sound/soc/intel/atom/sst/sst_drv_interface.c (renamed from sound/soc/intel/sst/sst_drv_interface.c)4
-rw-r--r--sound/soc/intel/atom/sst/sst_ipc.c (renamed from sound/soc/intel/sst/sst_ipc.c)2
-rw-r--r--sound/soc/intel/atom/sst/sst_loader.c (renamed from sound/soc/intel/sst/sst_loader.c)2
-rw-r--r--sound/soc/intel/atom/sst/sst_pci.c (renamed from sound/soc/intel/sst/sst_pci.c)0
-rw-r--r--sound/soc/intel/atom/sst/sst_pvt.c (renamed from sound/soc/intel/sst/sst_pvt.c)26
-rw-r--r--sound/soc/intel/atom/sst/sst_stream.c (renamed from sound/soc/intel/sst/sst_stream.c)2
-rw-r--r--sound/soc/intel/baytrail/Makefile4
-rw-r--r--sound/soc/intel/baytrail/sst-baytrail-dsp.c (renamed from sound/soc/intel/sst-baytrail-dsp.c)4
-rw-r--r--sound/soc/intel/baytrail/sst-baytrail-ipc.c (renamed from sound/soc/intel/sst-baytrail-ipc.c)364
-rw-r--r--sound/soc/intel/baytrail/sst-baytrail-ipc.h (renamed from sound/soc/intel/sst-baytrail-ipc.h)0
-rw-r--r--sound/soc/intel/baytrail/sst-baytrail-pcm.c (renamed from sound/soc/intel/sst-baytrail-pcm.c)4
-rw-r--r--sound/soc/intel/boards/Makefile15
-rw-r--r--sound/soc/intel/boards/broadwell.c (renamed from sound/soc/intel/broadwell.c)34
-rw-r--r--sound/soc/intel/boards/byt-max98090.c (renamed from sound/soc/intel/byt-max98090.c)2
-rw-r--r--sound/soc/intel/boards/byt-rt5640.c (renamed from sound/soc/intel/byt-rt5640.c)4
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c (renamed from sound/soc/intel/bytcr_dpcm_rt5640.c)4
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5645.c (renamed from sound/soc/intel/cht_bsw_rt5645.c)4
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5672.c (renamed from sound/soc/intel/cht_bsw_rt5672.c)99
-rw-r--r--sound/soc/intel/boards/haswell.c (renamed from sound/soc/intel/haswell.c)6
-rw-r--r--sound/soc/intel/boards/mfld_machine.c (renamed from sound/soc/intel/mfld_machine.c)0
-rw-r--r--sound/soc/intel/common/Makefile7
-rw-r--r--sound/soc/intel/common/sst-acpi.c (renamed from sound/soc/intel/sst-acpi.c)1
-rw-r--r--sound/soc/intel/common/sst-dsp-priv.h (renamed from sound/soc/intel/sst-dsp-priv.h)13
-rw-r--r--sound/soc/intel/common/sst-dsp.c (renamed from sound/soc/intel/sst-dsp.c)0
-rw-r--r--sound/soc/intel/common/sst-dsp.h (renamed from sound/soc/intel/sst-dsp.h)2
-rw-r--r--sound/soc/intel/common/sst-firmware.c (renamed from sound/soc/intel/sst-firmware.c)10
-rw-r--r--sound/soc/intel/common/sst-ipc.c294
-rw-r--r--sound/soc/intel/common/sst-ipc.h91
-rw-r--r--sound/soc/intel/haswell/Makefile4
-rw-r--r--sound/soc/intel/haswell/sst-haswell-dsp.c (renamed from sound/soc/intel/sst-haswell-dsp.c)9
-rw-r--r--sound/soc/intel/haswell/sst-haswell-ipc.c (renamed from sound/soc/intel/sst-haswell-ipc.c)794
-rw-r--r--sound/soc/intel/haswell/sst-haswell-ipc.h (renamed from sound/soc/intel/sst-haswell-ipc.h)53
-rw-r--r--sound/soc/intel/haswell/sst-haswell-pcm.c (renamed from sound/soc/intel/sst-haswell-pcm.c)140
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c84
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c2
-rw-r--r--sound/soc/nuc900/nuc900-audio.h3
-rw-r--r--sound/soc/nuc900/nuc900-pcm.c31
-rw-r--r--sound/soc/omap/Kconfig2
-rw-r--r--sound/soc/omap/n810.c23
-rw-r--r--sound/soc/omap/omap-hdmi-audio.c2
-rw-r--r--sound/soc/qcom/Kconfig25
-rw-r--r--sound/soc/qcom/Makefile11
-rw-r--r--sound/soc/qcom/lpass-cpu.c491
-rw-r--r--sound/soc/qcom/lpass-lpaif-ipq806x.h172
-rw-r--r--sound/soc/qcom/lpass-platform.c526
-rw-r--r--sound/soc/qcom/lpass.h51
-rw-r--r--sound/soc/qcom/storm.c162
-rw-r--r--sound/soc/sh/Kconfig6
-rw-r--r--sound/soc/sh/fsi.c71
-rw-r--r--sound/soc/sh/rcar/Makefile7
-rw-r--r--sound/soc/sh/rcar/adg.c4
-rw-r--r--sound/soc/sh/rcar/core.c278
-rw-r--r--sound/soc/sh/rcar/dma.c616
-rw-r--r--sound/soc/sh/rcar/dvc.c45
-rw-r--r--sound/soc/sh/rcar/gen.c152
-rw-r--r--sound/soc/sh/rcar/rsnd.h92
-rw-r--r--sound/soc/sh/rcar/rsrc-card.c512
-rw-r--r--sound/soc/sh/rcar/src.c250
-rw-r--r--sound/soc/sh/rcar/ssi.c73
-rw-r--r--sound/soc/soc-core.c110
-rw-r--r--sound/soc/soc-dapm.c182
-rw-r--r--sound/soc/soc-pcm.c16
-rw-r--r--sound/soc/tegra/tegra_alc5632.c5
-rw-r--r--sound/soc/tegra/tegra_rt5677.c6
-rw-r--r--sound/soc/tegra/tegra_wm8903.c3
-rw-r--r--sound/soc/tegra/tegra_wm9712.c6
-rw-r--r--sound/soc/ux500/mop500_ab8500.c36
130 files changed, 7429 insertions, 1978 deletions
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index dcc79aa0236b..3ba52da18bc6 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -47,6 +47,7 @@ source "sound/soc/kirkwood/Kconfig"
47source "sound/soc/intel/Kconfig" 47source "sound/soc/intel/Kconfig"
48source "sound/soc/mxs/Kconfig" 48source "sound/soc/mxs/Kconfig"
49source "sound/soc/pxa/Kconfig" 49source "sound/soc/pxa/Kconfig"
50source "sound/soc/qcom/Kconfig"
50source "sound/soc/rockchip/Kconfig" 51source "sound/soc/rockchip/Kconfig"
51source "sound/soc/samsung/Kconfig" 52source "sound/soc/samsung/Kconfig"
52source "sound/soc/sh/Kconfig" 53source "sound/soc/sh/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 5b3c8f67c8db..974ba708b482 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_SND_SOC) += nuc900/
28obj-$(CONFIG_SND_SOC) += omap/ 28obj-$(CONFIG_SND_SOC) += omap/
29obj-$(CONFIG_SND_SOC) += kirkwood/ 29obj-$(CONFIG_SND_SOC) += kirkwood/
30obj-$(CONFIG_SND_SOC) += pxa/ 30obj-$(CONFIG_SND_SOC) += pxa/
31obj-$(CONFIG_SND_SOC) += qcom/
31obj-$(CONFIG_SND_SOC) += rockchip/ 32obj-$(CONFIG_SND_SOC) += rockchip/
32obj-$(CONFIG_SND_SOC) += samsung/ 33obj-$(CONFIG_SND_SOC) += samsung/
33obj-$(CONFIG_SND_SOC) += sh/ 34obj-$(CONFIG_SND_SOC) += sh/
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index 1579e994acf8..e7d08806f3e9 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -25,7 +25,8 @@ config SND_ATMEL_SOC_SSC
25 25
26config SND_AT91_SOC_SAM9G20_WM8731 26config SND_AT91_SOC_SAM9G20_WM8731
27 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" 27 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
28 depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC 28 depends on ARCH_AT91 || COMPILE_TEST
29 depends on ATMEL_SSC && SND_ATMEL_SOC && SND_SOC_I2C_AND_SPI
29 select SND_ATMEL_SOC_PDC 30 select SND_ATMEL_SOC_PDC
30 select SND_ATMEL_SOC_SSC 31 select SND_ATMEL_SOC_SSC
31 select SND_SOC_WM8731 32 select SND_SOC_WM8731
@@ -35,7 +36,8 @@ config SND_AT91_SOC_SAM9G20_WM8731
35 36
36config SND_ATMEL_SOC_WM8904 37config SND_ATMEL_SOC_WM8904
37 tristate "Atmel ASoC driver for boards using WM8904 codec" 38 tristate "Atmel ASoC driver for boards using WM8904 codec"
38 depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC && I2C 39 depends on ARCH_AT91 || COMPILE_TEST
40 depends on ATMEL_SSC && SND_ATMEL_SOC && I2C
39 select SND_ATMEL_SOC_SSC 41 select SND_ATMEL_SOC_SSC
40 select SND_ATMEL_SOC_DMA 42 select SND_ATMEL_SOC_DMA
41 select SND_SOC_WM8904 43 select SND_SOC_WM8904
@@ -45,7 +47,8 @@ config SND_ATMEL_SOC_WM8904
45 47
46config SND_AT91_SOC_SAM9X5_WM8731 48config SND_AT91_SOC_SAM9X5_WM8731
47 tristate "SoC Audio support for WM8731-based at91sam9x5 board" 49 tristate "SoC Audio support for WM8731-based at91sam9x5 board"
48 depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC 50 depends on ARCH_AT91 || COMPILE_TEST
51 depends on ATMEL_SSC && SND_ATMEL_SOC && SND_SOC_I2C_AND_SPI
49 select SND_ATMEL_SOC_SSC 52 select SND_ATMEL_SOC_SSC
50 select SND_ATMEL_SOC_DMA 53 select SND_ATMEL_SOC_DMA
51 select SND_SOC_WM8731 54 select SND_SOC_WM8731
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
index 466a821da98c..b327e5cc8de3 100644
--- a/sound/soc/atmel/Makefile
+++ b/sound/soc/atmel/Makefile
@@ -1,10 +1,8 @@
1# AT91 Platform Support 1# AT91 Platform Support
2snd-soc-atmel-pcm-objs := atmel-pcm.o
3snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o 2snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o
4snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o 3snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o
5snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o 4snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o
6 5
7obj-$(CONFIG_SND_ATMEL_SOC) += snd-soc-atmel-pcm.o
8obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o 6obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o
9obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o 7obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o
10obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o 8obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c
index b8e7bad05eb1..b6625c8c411b 100644
--- a/sound/soc/atmel/atmel-pcm-dma.c
+++ b/sound/soc/atmel/atmel-pcm-dma.c
@@ -54,7 +54,7 @@ static const struct snd_pcm_hardware atmel_pcm_dma_hardware = {
54 .period_bytes_max = 2 * 0xffff, /* if 2 bytes format */ 54 .period_bytes_max = 2 * 0xffff, /* if 2 bytes format */
55 .periods_min = 8, 55 .periods_min = 8,
56 .periods_max = 1024, /* no limit */ 56 .periods_max = 1024, /* no limit */
57 .buffer_bytes_max = ATMEL_SSC_DMABUF_SIZE, 57 .buffer_bytes_max = 512 * 1024,
58}; 58};
59 59
60/** 60/**
@@ -119,7 +119,7 @@ static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream,
119static const struct snd_dmaengine_pcm_config atmel_dmaengine_pcm_config = { 119static const struct snd_dmaengine_pcm_config atmel_dmaengine_pcm_config = {
120 .prepare_slave_config = atmel_pcm_configure_dma, 120 .prepare_slave_config = atmel_pcm_configure_dma,
121 .pcm_hardware = &atmel_pcm_dma_hardware, 121 .pcm_hardware = &atmel_pcm_dma_hardware,
122 .prealloc_buffer_size = ATMEL_SSC_DMABUF_SIZE, 122 .prealloc_buffer_size = 64 * 1024,
123}; 123};
124 124
125int atmel_pcm_dma_platform_register(struct device *dev) 125int atmel_pcm_dma_platform_register(struct device *dev)
diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c
index a366b3503c28..da861b44413f 100644
--- a/sound/soc/atmel/atmel-pcm-pdc.c
+++ b/sound/soc/atmel/atmel-pcm-pdc.c
@@ -47,6 +47,85 @@
47#include "atmel-pcm.h" 47#include "atmel-pcm.h"
48 48
49 49
50static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
51 int stream)
52{
53 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
54 struct snd_dma_buffer *buf = &substream->dma_buffer;
55 size_t size = ATMEL_SSC_DMABUF_SIZE;
56
57 buf->dev.type = SNDRV_DMA_TYPE_DEV;
58 buf->dev.dev = pcm->card->dev;
59 buf->private_data = NULL;
60 buf->area = dma_alloc_coherent(pcm->card->dev, size,
61 &buf->addr, GFP_KERNEL);
62 pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%zu\n",
63 (void *)buf->area, (void *)(long)buf->addr, size);
64
65 if (!buf->area)
66 return -ENOMEM;
67
68 buf->bytes = size;
69 return 0;
70}
71
72static int atmel_pcm_mmap(struct snd_pcm_substream *substream,
73 struct vm_area_struct *vma)
74{
75 return remap_pfn_range(vma, vma->vm_start,
76 substream->dma_buffer.addr >> PAGE_SHIFT,
77 vma->vm_end - vma->vm_start, vma->vm_page_prot);
78}
79
80static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
81{
82 struct snd_card *card = rtd->card->snd_card;
83 struct snd_pcm *pcm = rtd->pcm;
84 int ret;
85
86 ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
87 if (ret)
88 return ret;
89
90 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
91 pr_debug("atmel-pcm: allocating PCM playback DMA buffer\n");
92 ret = atmel_pcm_preallocate_dma_buffer(pcm,
93 SNDRV_PCM_STREAM_PLAYBACK);
94 if (ret)
95 goto out;
96 }
97
98 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
99 pr_debug("atmel-pcm: allocating PCM capture DMA buffer\n");
100 ret = atmel_pcm_preallocate_dma_buffer(pcm,
101 SNDRV_PCM_STREAM_CAPTURE);
102 if (ret)
103 goto out;
104 }
105 out:
106 return ret;
107}
108
109static void atmel_pcm_free(struct snd_pcm *pcm)
110{
111 struct snd_pcm_substream *substream;
112 struct snd_dma_buffer *buf;
113 int stream;
114
115 for (stream = 0; stream < 2; stream++) {
116 substream = pcm->streams[stream].substream;
117 if (!substream)
118 continue;
119
120 buf = &substream->dma_buffer;
121 if (!buf->area)
122 continue;
123 dma_free_coherent(pcm->card->dev, buf->bytes,
124 buf->area, buf->addr);
125 buf->area = NULL;
126 }
127}
128
50/*--------------------------------------------------------------------------*\ 129/*--------------------------------------------------------------------------*\
51 * Hardware definition 130 * Hardware definition
52\*--------------------------------------------------------------------------*/ 131\*--------------------------------------------------------------------------*/
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
deleted file mode 100644
index 8ae3fa5ac60a..000000000000
--- a/sound/soc/atmel/atmel-pcm.c
+++ /dev/null
@@ -1,121 +0,0 @@
1/*
2 * atmel-pcm.c -- ALSA PCM interface for the Atmel atmel SoC.
3 *
4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2008 Atmel
6 *
7 * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
8 *
9 * Based on at91-pcm. by:
10 * Frank Mandarino <fmandarino@endrelia.com>
11 * Copyright 2006 Endrelia Technologies Inc.
12 *
13 * Based on pxa2xx-pcm.c by:
14 *
15 * Author: Nicolas Pitre
16 * Created: Nov 30, 2004
17 * Copyright: (C) 2004 MontaVista Software, Inc.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 */
33
34#include <linux/module.h>
35#include <linux/dma-mapping.h>
36#include <sound/pcm.h>
37#include <sound/soc.h>
38#include "atmel-pcm.h"
39
40static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
41 int stream)
42{
43 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
44 struct snd_dma_buffer *buf = &substream->dma_buffer;
45 size_t size = ATMEL_SSC_DMABUF_SIZE;
46
47 buf->dev.type = SNDRV_DMA_TYPE_DEV;
48 buf->dev.dev = pcm->card->dev;
49 buf->private_data = NULL;
50 buf->area = dma_alloc_coherent(pcm->card->dev, size,
51 &buf->addr, GFP_KERNEL);
52 pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%zu\n",
53 (void *)buf->area, (void *)(long)buf->addr, size);
54
55 if (!buf->area)
56 return -ENOMEM;
57
58 buf->bytes = size;
59 return 0;
60}
61
62int atmel_pcm_mmap(struct snd_pcm_substream *substream,
63 struct vm_area_struct *vma)
64{
65 return remap_pfn_range(vma, vma->vm_start,
66 substream->dma_buffer.addr >> PAGE_SHIFT,
67 vma->vm_end - vma->vm_start, vma->vm_page_prot);
68}
69EXPORT_SYMBOL_GPL(atmel_pcm_mmap);
70
71int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
72{
73 struct snd_card *card = rtd->card->snd_card;
74 struct snd_pcm *pcm = rtd->pcm;
75 int ret;
76
77 ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
78 if (ret)
79 return ret;
80
81 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
82 pr_debug("atmel-pcm: allocating PCM playback DMA buffer\n");
83 ret = atmel_pcm_preallocate_dma_buffer(pcm,
84 SNDRV_PCM_STREAM_PLAYBACK);
85 if (ret)
86 goto out;
87 }
88
89 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
90 pr_debug("atmel-pcm: allocating PCM capture DMA buffer\n");
91 ret = atmel_pcm_preallocate_dma_buffer(pcm,
92 SNDRV_PCM_STREAM_CAPTURE);
93 if (ret)
94 goto out;
95 }
96 out:
97 return ret;
98}
99EXPORT_SYMBOL_GPL(atmel_pcm_new);
100
101void atmel_pcm_free(struct snd_pcm *pcm)
102{
103 struct snd_pcm_substream *substream;
104 struct snd_dma_buffer *buf;
105 int stream;
106
107 for (stream = 0; stream < 2; stream++) {
108 substream = pcm->streams[stream].substream;
109 if (!substream)
110 continue;
111
112 buf = &substream->dma_buffer;
113 if (!buf->area)
114 continue;
115 dma_free_coherent(pcm->card->dev, buf->bytes,
116 buf->area, buf->addr);
117 buf->area = NULL;
118 }
119}
120EXPORT_SYMBOL_GPL(atmel_pcm_free);
121
diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h
index 12ae814eff21..6eaf081cad50 100644
--- a/sound/soc/atmel/atmel-pcm.h
+++ b/sound/soc/atmel/atmel-pcm.h
@@ -83,11 +83,6 @@ struct atmel_pcm_dma_params {
83#define ssc_readx(base, reg) (__raw_readl((base) + (reg))) 83#define ssc_readx(base, reg) (__raw_readl((base) + (reg)))
84#define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg)) 84#define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg))
85 85
86int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd);
87void atmel_pcm_free(struct snd_pcm *pcm);
88int atmel_pcm_mmap(struct snd_pcm_substream *substream,
89 struct vm_area_struct *vma);
90
91#if defined(CONFIG_SND_ATMEL_SOC_PDC) || \ 86#if defined(CONFIG_SND_ATMEL_SOC_PDC) || \
92 defined(CONFIG_SND_ATMEL_SOC_PDC_MODULE) 87 defined(CONFIG_SND_ATMEL_SOC_PDC_MODULE)
93int atmel_pcm_pdc_platform_register(struct device *dev); 88int atmel_pcm_pdc_platform_register(struct device *dev);
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0bddd929837f..061c46587628 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -70,6 +70,7 @@ config SND_SOC_ALL_CODECS
70 select SND_SOC_MAX98090 if I2C 70 select SND_SOC_MAX98090 if I2C
71 select SND_SOC_MAX98095 if I2C 71 select SND_SOC_MAX98095 if I2C
72 select SND_SOC_MAX98357A if GPIOLIB 72 select SND_SOC_MAX98357A if GPIOLIB
73 select SND_SOC_MAX98925 if I2C
73 select SND_SOC_MAX9850 if I2C 74 select SND_SOC_MAX9850 if I2C
74 select SND_SOC_MAX9768 if I2C 75 select SND_SOC_MAX9768 if I2C
75 select SND_SOC_MAX9877 if I2C 76 select SND_SOC_MAX9877 if I2C
@@ -461,6 +462,9 @@ config SND_SOC_MAX98095
461config SND_SOC_MAX98357A 462config SND_SOC_MAX98357A
462 tristate 463 tristate
463 464
465config SND_SOC_MAX98925
466 tristate
467
464config SND_SOC_MAX9850 468config SND_SOC_MAX9850
465 tristate 469 tristate
466 470
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 7acb6c174cb4..abe2d7edf65c 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -65,6 +65,7 @@ snd-soc-max98088-objs := max98088.o
65snd-soc-max98090-objs := max98090.o 65snd-soc-max98090-objs := max98090.o
66snd-soc-max98095-objs := max98095.o 66snd-soc-max98095-objs := max98095.o
67snd-soc-max98357a-objs := max98357a.o 67snd-soc-max98357a-objs := max98357a.o
68snd-soc-max98925-objs := max98925.o
68snd-soc-max9850-objs := max9850.o 69snd-soc-max9850-objs := max9850.o
69snd-soc-mc13783-objs := mc13783.o 70snd-soc-mc13783-objs := mc13783.o
70snd-soc-ml26124-objs := ml26124.o 71snd-soc-ml26124-objs := ml26124.o
@@ -249,6 +250,7 @@ obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
249obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o 250obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o
250obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o 251obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
251obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o 252obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o
253obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
252obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 254obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
253obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o 255obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
254obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o 256obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 7895689588da..88ca9cb0ce79 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -2003,7 +2003,6 @@ static int ab8500_audio_setup_mics(struct snd_soc_codec *codec,
2003 2003
2004 return 0; 2004 return 0;
2005} 2005}
2006EXPORT_SYMBOL_GPL(ab8500_audio_setup_mics);
2007 2006
2008static int ab8500_audio_set_ear_cmv(struct snd_soc_codec *codec, 2007static int ab8500_audio_set_ear_cmv(struct snd_soc_codec *codec,
2009 enum ear_cm_voltage ear_cmv) 2008 enum ear_cm_voltage ear_cmv)
@@ -2036,7 +2035,6 @@ static int ab8500_audio_set_ear_cmv(struct snd_soc_codec *codec,
2036 2035
2037 return 0; 2036 return 0;
2038} 2037}
2039EXPORT_SYMBOL_GPL(ab8500_audio_set_ear_cmv);
2040 2038
2041static int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai, 2039static int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai,
2042 unsigned int delay) 2040 unsigned int delay)
diff --git a/sound/soc/codecs/ak4554.c b/sound/soc/codecs/ak4554.c
index 16ce9f9fefa1..298dedc05140 100644
--- a/sound/soc/codecs/ak4554.c
+++ b/sound/soc/codecs/ak4554.c
@@ -84,7 +84,7 @@ static int ak4554_soc_remove(struct platform_device *pdev)
84 return 0; 84 return 0;
85} 85}
86 86
87static struct of_device_id ak4554_of_match[] = { 87static const struct of_device_id ak4554_of_match[] = {
88 { .compatible = "asahi-kasei,ak4554" }, 88 { .compatible = "asahi-kasei,ak4554" },
89 {}, 89 {},
90}; 90};
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index dde8b49c19ad..13585e88f597 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -97,6 +97,9 @@
97#define PMMP (1 << 2) /* MPWR pin Power Management */ 97#define PMMP (1 << 2) /* MPWR pin Power Management */
98#define MGAIN0 (1 << 0) /* MIC amp gain*/ 98#define MGAIN0 (1 << 0) /* MIC amp gain*/
99 99
100/* SG_SL2 */
101#define LOPS (1 << 6) /* Stero Line-out Power Save Mode */
102
100/* TIMER */ 103/* TIMER */
101#define ZTM(param) ((param & 0x3) << 4) /* ALC Zero Crossing TimeOut */ 104#define ZTM(param) ((param & 0x3) << 4) /* ALC Zero Crossing TimeOut */
102#define WTM(param) (((param & 0x4) << 4) | ((param & 0x3) << 2)) 105#define WTM(param) (((param & 0x4) << 4) | ((param & 0x3) << 2))
@@ -168,6 +171,29 @@ static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = {
168 SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0), 171 SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0),
169}; 172};
170 173
174/* event handlers */
175static int ak4642_lout_event(struct snd_soc_dapm_widget *w,
176 struct snd_kcontrol *kcontrol, int event)
177{
178 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
179
180 switch (event) {
181 case SND_SOC_DAPM_PRE_PMD:
182 case SND_SOC_DAPM_PRE_PMU:
183 /* Power save mode ON */
184 snd_soc_update_bits(codec, SG_SL2, LOPS, LOPS);
185 break;
186 case SND_SOC_DAPM_POST_PMU:
187 case SND_SOC_DAPM_POST_PMD:
188 /* Power save mode OFF */
189 mdelay(300);
190 snd_soc_update_bits(codec, SG_SL2, LOPS, 0);
191 break;
192 }
193
194 return 0;
195}
196
171static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = { 197static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
172 198
173 /* Outputs */ 199 /* Outputs */
@@ -182,12 +208,15 @@ static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
182 208
183 SND_SOC_DAPM_PGA("DACH", MD_CTL4, 0, 0, NULL, 0), 209 SND_SOC_DAPM_PGA("DACH", MD_CTL4, 0, 0, NULL, 0),
184 210
185 SND_SOC_DAPM_MIXER("LINEOUT Mixer", PW_MGMT1, 3, 0, 211 SND_SOC_DAPM_MIXER_E("LINEOUT Mixer", PW_MGMT1, 3, 0,
186 &ak4642_lout_mixer_controls[0], 212 &ak4642_lout_mixer_controls[0],
187 ARRAY_SIZE(ak4642_lout_mixer_controls)), 213 ARRAY_SIZE(ak4642_lout_mixer_controls),
214 ak4642_lout_event,
215 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
216 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
188 217
189 /* DAC */ 218 /* DAC */
190 SND_SOC_DAPM_DAC("DAC", "HiFi Playback", PW_MGMT1, 2, 0), 219 SND_SOC_DAPM_DAC("DAC", NULL, PW_MGMT1, 2, 0),
191}; 220};
192 221
193static const struct snd_soc_dapm_route ak4642_intercon[] = { 222static const struct snd_soc_dapm_route ak4642_intercon[] = {
@@ -205,6 +234,8 @@ static const struct snd_soc_dapm_route ak4642_intercon[] = {
205 {"DACH", NULL, "DAC"}, 234 {"DACH", NULL, "DAC"},
206 235
207 {"LINEOUT Mixer", "DACL", "DAC"}, 236 {"LINEOUT Mixer", "DACL", "DAC"},
237
238 { "DAC", NULL, "Playback" },
208}; 239};
209 240
210/* 241/*
@@ -468,13 +499,13 @@ static struct snd_soc_dai_driver ak4642_dai = {
468 .name = "ak4642-hifi", 499 .name = "ak4642-hifi",
469 .playback = { 500 .playback = {
470 .stream_name = "Playback", 501 .stream_name = "Playback",
471 .channels_min = 1, 502 .channels_min = 2,
472 .channels_max = 2, 503 .channels_max = 2,
473 .rates = SNDRV_PCM_RATE_8000_48000, 504 .rates = SNDRV_PCM_RATE_8000_48000,
474 .formats = SNDRV_PCM_FMTBIT_S16_LE }, 505 .formats = SNDRV_PCM_FMTBIT_S16_LE },
475 .capture = { 506 .capture = {
476 .stream_name = "Capture", 507 .stream_name = "Capture",
477 .channels_min = 1, 508 .channels_min = 2,
478 .channels_max = 2, 509 .channels_max = 2,
479 .rates = SNDRV_PCM_RATE_8000_48000, 510 .rates = SNDRV_PCM_RATE_8000_48000,
480 .formats = SNDRV_PCM_FMTBIT_S16_LE }, 511 .formats = SNDRV_PCM_FMTBIT_S16_LE },
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 29202610dd0d..9015b44a9e11 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -1901,7 +1901,7 @@ static int arizona_is_enabled_fll(struct arizona_fll *fll)
1901static int arizona_enable_fll(struct arizona_fll *fll) 1901static int arizona_enable_fll(struct arizona_fll *fll)
1902{ 1902{
1903 struct arizona *arizona = fll->arizona; 1903 struct arizona *arizona = fll->arizona;
1904 int ret; 1904 unsigned long time_left;
1905 bool use_sync = false; 1905 bool use_sync = false;
1906 int already_enabled = arizona_is_enabled_fll(fll); 1906 int already_enabled = arizona_is_enabled_fll(fll);
1907 struct arizona_fll_cfg cfg; 1907 struct arizona_fll_cfg cfg;
@@ -1977,9 +1977,9 @@ static int arizona_enable_fll(struct arizona_fll *fll)
1977 regmap_update_bits_async(arizona->regmap, fll->base + 1, 1977 regmap_update_bits_async(arizona->regmap, fll->base + 1,
1978 ARIZONA_FLL1_FREERUN, 0); 1978 ARIZONA_FLL1_FREERUN, 0);
1979 1979
1980 ret = wait_for_completion_timeout(&fll->ok, 1980 time_left = wait_for_completion_timeout(&fll->ok,
1981 msecs_to_jiffies(250)); 1981 msecs_to_jiffies(250));
1982 if (ret == 0) 1982 if (time_left == 0)
1983 arizona_fll_warn(fll, "Timed out waiting for lock\n"); 1983 arizona_fll_warn(fll, "Timed out waiting for lock\n");
1984 1984
1985 return 0; 1985 return 0;
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index 7d3a6accaf9a..e770ee6f36da 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -561,10 +561,10 @@ static int cs4271_codec_probe(struct snd_soc_codec *codec)
561 if (gpio_is_valid(cs4271->gpio_nreset)) { 561 if (gpio_is_valid(cs4271->gpio_nreset)) {
562 /* Reset codec */ 562 /* Reset codec */
563 gpio_direction_output(cs4271->gpio_nreset, 0); 563 gpio_direction_output(cs4271->gpio_nreset, 0);
564 udelay(1); 564 mdelay(1);
565 gpio_set_value(cs4271->gpio_nreset, 1); 565 gpio_set_value(cs4271->gpio_nreset, 1);
566 /* Give the codec time to wake up */ 566 /* Give the codec time to wake up */
567 udelay(1); 567 mdelay(1);
568 } 568 }
569 569
570 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2, 570 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 0b10979513c4..0f334bc1b63c 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -420,7 +420,7 @@ static int cx20442_platform_probe(struct platform_device *pdev)
420 &cx20442_codec_dev, &cx20442_dai, 1); 420 &cx20442_codec_dev, &cx20442_dai, 1);
421} 421}
422 422
423static int __exit cx20442_platform_remove(struct platform_device *pdev) 423static int cx20442_platform_remove(struct platform_device *pdev)
424{ 424{
425 snd_soc_unregister_codec(&pdev->dev); 425 snd_soc_unregister_codec(&pdev->dev);
426 return 0; 426 return 0;
@@ -431,7 +431,7 @@ static struct platform_driver cx20442_platform_driver = {
431 .name = "cx20442-codec", 431 .name = "cx20442-codec",
432 }, 432 },
433 .probe = cx20442_platform_probe, 433 .probe = cx20442_platform_probe,
434 .remove = __exit_p(cx20442_platform_remove), 434 .remove = cx20442_platform_remove,
435}; 435};
436 436
437module_platform_driver(cx20442_platform_driver); 437module_platform_driver(cx20442_platform_driver);
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index b112b1c2c394..3e33ef2acf3c 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -2605,8 +2605,24 @@ err_enable:
2605 return ret; 2605 return ret;
2606} 2606}
2607 2607
2608static void max98090_i2c_shutdown(struct i2c_client *i2c)
2609{
2610 struct max98090_priv *max98090 = dev_get_drvdata(&i2c->dev);
2611
2612 /*
2613 * Enable volume smoothing, disable zero cross. This will cause
2614 * a quick 40ms ramp to mute on shutdown.
2615 */
2616 regmap_write(max98090->regmap,
2617 M98090_REG_LEVEL_CONTROL, M98090_VSENN_MASK);
2618 regmap_write(max98090->regmap,
2619 M98090_REG_DEVICE_SHUTDOWN, 0x00);
2620 msleep(40);
2621}
2622
2608static int max98090_i2c_remove(struct i2c_client *client) 2623static int max98090_i2c_remove(struct i2c_client *client)
2609{ 2624{
2625 max98090_i2c_shutdown(client);
2610 snd_soc_unregister_codec(&client->dev); 2626 snd_soc_unregister_codec(&client->dev);
2611 return 0; 2627 return 0;
2612} 2628}
@@ -2696,6 +2712,7 @@ static struct i2c_driver max98090_i2c_driver = {
2696 .acpi_match_table = ACPI_PTR(max98090_acpi_match), 2712 .acpi_match_table = ACPI_PTR(max98090_acpi_match),
2697 }, 2713 },
2698 .probe = max98090_i2c_probe, 2714 .probe = max98090_i2c_probe,
2715 .shutdown = max98090_i2c_shutdown,
2699 .remove = max98090_i2c_remove, 2716 .remove = max98090_i2c_remove,
2700 .id_table = max98090_i2c_id, 2717 .id_table = max98090_i2c_id,
2701}; 2718};
diff --git a/sound/soc/codecs/max98925.c b/sound/soc/codecs/max98925.c
new file mode 100644
index 000000000000..9b5a17de4690
--- /dev/null
+++ b/sound/soc/codecs/max98925.c
@@ -0,0 +1,655 @@
1/*
2 * max98925.c -- ALSA SoC Stereo MAX98925 driver
3 * Copyright 2013-15 Maxim Integrated Products
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/delay.h>
9#include <linux/i2c.h>
10#include <linux/module.h>
11#include <linux/regmap.h>
12#include <linux/slab.h>
13#include <linux/cdev.h>
14#include <sound/pcm.h>
15#include <sound/pcm_params.h>
16#include <sound/soc.h>
17#include <sound/tlv.h>
18#include "max98925.h"
19
20static const char *const dai_text[] = {
21 "Left", "Right", "LeftRight", "LeftRightDiv2",
22};
23
24static const char * const max98925_boost_voltage_text[] = {
25 "8.5V", "8.25V", "8.0V", "7.75V", "7.5V", "7.25V", "7.0V", "6.75V",
26 "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V"
27};
28
29static SOC_ENUM_SINGLE_DECL(max98925_boost_voltage,
30 MAX98925_CONFIGURATION, M98925_BST_VOUT_SHIFT,
31 max98925_boost_voltage_text);
32
33static const char *const hpf_text[] = {
34 "Disable", "DC Block", "100Hz", "200Hz", "400Hz", "800Hz",
35};
36
37static const struct reg_default max98925_reg[] = {
38 { 0x0B, 0x00 }, /* IRQ Enable0 */
39 { 0x0C, 0x00 }, /* IRQ Enable1 */
40 { 0x0D, 0x00 }, /* IRQ Enable2 */
41 { 0x0E, 0x00 }, /* IRQ Clear0 */
42 { 0x0F, 0x00 }, /* IRQ Clear1 */
43 { 0x10, 0x00 }, /* IRQ Clear2 */
44 { 0x11, 0xC0 }, /* Map0 */
45 { 0x12, 0x00 }, /* Map1 */
46 { 0x13, 0x00 }, /* Map2 */
47 { 0x14, 0xF0 }, /* Map3 */
48 { 0x15, 0x00 }, /* Map4 */
49 { 0x16, 0xAB }, /* Map5 */
50 { 0x17, 0x89 }, /* Map6 */
51 { 0x18, 0x00 }, /* Map7 */
52 { 0x19, 0x00 }, /* Map8 */
53 { 0x1A, 0x06 }, /* DAI Clock Mode 1 */
54 { 0x1B, 0xC0 }, /* DAI Clock Mode 2 */
55 { 0x1C, 0x00 }, /* DAI Clock Divider Denominator MSBs */
56 { 0x1D, 0x00 }, /* DAI Clock Divider Denominator LSBs */
57 { 0x1E, 0xF0 }, /* DAI Clock Divider Numerator MSBs */
58 { 0x1F, 0x00 }, /* DAI Clock Divider Numerator LSBs */
59 { 0x20, 0x50 }, /* Format */
60 { 0x21, 0x00 }, /* TDM Slot Select */
61 { 0x22, 0x00 }, /* DOUT Configuration VMON */
62 { 0x23, 0x00 }, /* DOUT Configuration IMON */
63 { 0x24, 0x00 }, /* DOUT Configuration VBAT */
64 { 0x25, 0x00 }, /* DOUT Configuration VBST */
65 { 0x26, 0x00 }, /* DOUT Configuration FLAG */
66 { 0x27, 0xFF }, /* DOUT HiZ Configuration 1 */
67 { 0x28, 0xFF }, /* DOUT HiZ Configuration 2 */
68 { 0x29, 0xFF }, /* DOUT HiZ Configuration 3 */
69 { 0x2A, 0xFF }, /* DOUT HiZ Configuration 4 */
70 { 0x2B, 0x02 }, /* DOUT Drive Strength */
71 { 0x2C, 0x90 }, /* Filters */
72 { 0x2D, 0x00 }, /* Gain */
73 { 0x2E, 0x02 }, /* Gain Ramping */
74 { 0x2F, 0x00 }, /* Speaker Amplifier */
75 { 0x30, 0x0A }, /* Threshold */
76 { 0x31, 0x00 }, /* ALC Attack */
77 { 0x32, 0x80 }, /* ALC Atten and Release */
78 { 0x33, 0x00 }, /* ALC Infinite Hold Release */
79 { 0x34, 0x92 }, /* ALC Configuration */
80 { 0x35, 0x01 }, /* Boost Converter */
81 { 0x36, 0x00 }, /* Block Enable */
82 { 0x37, 0x00 }, /* Configuration */
83 { 0x38, 0x00 }, /* Global Enable */
84 { 0x3A, 0x00 }, /* Boost Limiter */
85};
86
87static const struct soc_enum max98925_dai_enum =
88 SOC_ENUM_SINGLE(MAX98925_GAIN, 5, ARRAY_SIZE(dai_text), dai_text);
89
90static const struct soc_enum max98925_hpf_enum =
91 SOC_ENUM_SINGLE(MAX98925_FILTERS, 0, ARRAY_SIZE(hpf_text), hpf_text);
92
93static const struct snd_kcontrol_new max98925_hpf_sel_mux =
94 SOC_DAPM_ENUM("Rc Filter MUX Mux", max98925_hpf_enum);
95
96static const struct snd_kcontrol_new max98925_dai_sel_mux =
97 SOC_DAPM_ENUM("DAI IN MUX Mux", max98925_dai_enum);
98
99static int max98925_dac_event(struct snd_soc_dapm_widget *w,
100 struct snd_kcontrol *kcontrol, int event)
101{
102 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
103 struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
104
105 switch (event) {
106 case SND_SOC_DAPM_PRE_PMU:
107 regmap_update_bits(max98925->regmap,
108 MAX98925_BLOCK_ENABLE,
109 M98925_BST_EN_MASK |
110 M98925_ADC_IMON_EN_MASK | M98925_ADC_VMON_EN_MASK,
111 M98925_BST_EN_MASK |
112 M98925_ADC_IMON_EN_MASK | M98925_ADC_VMON_EN_MASK);
113 break;
114 case SND_SOC_DAPM_POST_PMD:
115 regmap_update_bits(max98925->regmap,
116 MAX98925_BLOCK_ENABLE, M98925_BST_EN_MASK |
117 M98925_ADC_IMON_EN_MASK | M98925_ADC_VMON_EN_MASK, 0);
118 break;
119 default:
120 return 0;
121 }
122 return 0;
123}
124
125static const struct snd_soc_dapm_widget max98925_dapm_widgets[] = {
126 SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
127 SND_SOC_DAPM_MUX("DAI IN MUX", SND_SOC_NOPM, 0, 0,
128 &max98925_dai_sel_mux),
129 SND_SOC_DAPM_MUX("Rc Filter MUX", SND_SOC_NOPM, 0, 0,
130 &max98925_hpf_sel_mux),
131 SND_SOC_DAPM_DAC_E("Amp Enable", NULL, MAX98925_BLOCK_ENABLE,
132 M98925_SPK_EN_SHIFT, 0, max98925_dac_event,
133 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
134 SND_SOC_DAPM_SUPPLY("Global Enable", MAX98925_GLOBAL_ENABLE,
135 M98925_EN_SHIFT, 0, NULL, 0),
136 SND_SOC_DAPM_OUTPUT("BE_OUT"),
137};
138
139static const struct snd_soc_dapm_route max98925_audio_map[] = {
140 {"DAI IN MUX", "Left", "DAI_OUT"},
141 {"DAI IN MUX", "Right", "DAI_OUT"},
142 {"DAI IN MUX", "LeftRight", "DAI_OUT"},
143 {"DAI IN MUX", "LeftRightDiv2", "DAI_OUT"},
144 {"Rc Filter MUX", "Disable", "DAI IN MUX"},
145 {"Rc Filter MUX", "DC Block", "DAI IN MUX"},
146 {"Rc Filter MUX", "100Hz", "DAI IN MUX"},
147 {"Rc Filter MUX", "200Hz", "DAI IN MUX"},
148 {"Rc Filter MUX", "400Hz", "DAI IN MUX"},
149 {"Rc Filter MUX", "800Hz", "DAI IN MUX"},
150 {"Amp Enable", NULL, "Rc Filter MUX"},
151 {"BE_OUT", NULL, "Amp Enable"},
152 {"BE_OUT", NULL, "Global Enable"},
153};
154
155static bool max98925_volatile_register(struct device *dev, unsigned int reg)
156{
157 switch (reg) {
158 case MAX98925_VBAT_DATA:
159 case MAX98925_VBST_DATA:
160 case MAX98925_LIVE_STATUS0:
161 case MAX98925_LIVE_STATUS1:
162 case MAX98925_LIVE_STATUS2:
163 case MAX98925_STATE0:
164 case MAX98925_STATE1:
165 case MAX98925_STATE2:
166 case MAX98925_FLAG0:
167 case MAX98925_FLAG1:
168 case MAX98925_FLAG2:
169 case MAX98925_REV_VERSION:
170 return true;
171 default:
172 return false;
173 }
174}
175
176static bool max98925_readable_register(struct device *dev, unsigned int reg)
177{
178 switch (reg) {
179 case MAX98925_IRQ_CLEAR0:
180 case MAX98925_IRQ_CLEAR1:
181 case MAX98925_IRQ_CLEAR2:
182 case MAX98925_ALC_HOLD_RLS:
183 return false;
184 default:
185 return true;
186 }
187}
188
189static DECLARE_TLV_DB_SCALE(max98925_spk_tlv, -600, 100, 0);
190
191static const struct snd_kcontrol_new max98925_snd_controls[] = {
192 SOC_SINGLE_TLV("Speaker Volume", MAX98925_GAIN,
193 M98925_SPK_GAIN_SHIFT, (1<<M98925_SPK_GAIN_WIDTH)-1, 0,
194 max98925_spk_tlv),
195 SOC_SINGLE("Ramp Switch", MAX98925_GAIN_RAMPING,
196 M98925_SPK_RMP_EN_SHIFT, 1, 0),
197 SOC_SINGLE("ZCD Switch", MAX98925_GAIN_RAMPING,
198 M98925_SPK_ZCD_EN_SHIFT, 1, 0),
199 SOC_SINGLE("ALC Switch", MAX98925_THRESHOLD,
200 M98925_ALC_EN_SHIFT, 1, 0),
201 SOC_SINGLE("ALC Threshold", MAX98925_THRESHOLD, M98925_ALC_TH_SHIFT,
202 (1<<M98925_ALC_TH_WIDTH)-1, 0),
203 SOC_ENUM("Boost Output Voltage", max98925_boost_voltage),
204};
205
206/* codec sample rate and n/m dividers parameter table */
207static const struct {
208 int rate;
209 int sr;
210 int divisors[3][2];
211} rate_table[] = {
212 {
213 .rate = 8000,
214 .sr = 0,
215 .divisors = { {1, 375}, {5, 1764}, {1, 384} }
216 },
217 {
218 .rate = 11025,
219 .sr = 1,
220 .divisors = { {147, 40000}, {1, 256}, {147, 40960} }
221 },
222 {
223 .rate = 12000,
224 .sr = 2,
225 .divisors = { {1, 250}, {5, 1176}, {1, 256} }
226 },
227 {
228 .rate = 16000,
229 .sr = 3,
230 .divisors = { {2, 375}, {5, 882}, {1, 192} }
231 },
232 {
233 .rate = 22050,
234 .sr = 4,
235 .divisors = { {147, 20000}, {1, 128}, {147, 20480} }
236 },
237 {
238 .rate = 24000,
239 .sr = 5,
240 .divisors = { {1, 125}, {5, 588}, {1, 128} }
241 },
242 {
243 .rate = 32000,
244 .sr = 6,
245 .divisors = { {4, 375}, {5, 441}, {1, 96} }
246 },
247 {
248 .rate = 44100,
249 .sr = 7,
250 .divisors = { {147, 10000}, {1, 64}, {147, 10240} }
251 },
252 {
253 .rate = 48000,
254 .sr = 8,
255 .divisors = { {2, 125}, {5, 294}, {1, 64} }
256 },
257};
258
259static inline int max98925_rate_value(struct snd_soc_codec *codec,
260 int rate, int clock, int *value, int *n, int *m)
261{
262 int ret = -EINVAL;
263 int i;
264
265 for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
266 if (rate_table[i].rate >= rate) {
267 *value = rate_table[i].sr;
268 *n = rate_table[i].divisors[clock][0];
269 *m = rate_table[i].divisors[clock][1];
270 ret = 0;
271 break;
272 }
273 }
274 dev_dbg(codec->dev, "%s: sample rate is %d, returning %d\n",
275 __func__, rate_table[i].rate, *value);
276 return ret;
277}
278
279static void max98925_set_sense_data(struct max98925_priv *max98925)
280{
281 /* set VMON slots */
282 regmap_update_bits(max98925->regmap,
283 MAX98925_DOUT_CFG_VMON,
284 M98925_DAI_VMON_EN_MASK, M98925_DAI_VMON_EN_MASK);
285 regmap_update_bits(max98925->regmap,
286 MAX98925_DOUT_CFG_VMON,
287 M98925_DAI_VMON_SLOT_MASK,
288 max98925->v_slot << M98925_DAI_VMON_SLOT_SHIFT);
289 /* set IMON slots */
290 regmap_update_bits(max98925->regmap,
291 MAX98925_DOUT_CFG_IMON,
292 M98925_DAI_IMON_EN_MASK, M98925_DAI_IMON_EN_MASK);
293 regmap_update_bits(max98925->regmap,
294 MAX98925_DOUT_CFG_IMON,
295 M98925_DAI_IMON_SLOT_MASK,
296 max98925->i_slot << M98925_DAI_IMON_SLOT_SHIFT);
297}
298
299static int max98925_dai_set_fmt(struct snd_soc_dai *codec_dai,
300 unsigned int fmt)
301{
302 struct snd_soc_codec *codec = codec_dai->codec;
303 struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
304 unsigned int invert = 0;
305
306 dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
307 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
308 case SND_SOC_DAIFMT_CBS_CFS:
309 /* set DAI to slave mode */
310 regmap_update_bits(max98925->regmap,
311 MAX98925_DAI_CLK_MODE2,
312 M98925_DAI_MAS_MASK, 0);
313 max98925_set_sense_data(max98925);
314 break;
315 case SND_SOC_DAIFMT_CBM_CFM:
316 /*
317 * set left channel DAI to master mode,
318 * right channel always slave
319 */
320 regmap_update_bits(max98925->regmap,
321 MAX98925_DAI_CLK_MODE2,
322 M98925_DAI_MAS_MASK, M98925_DAI_MAS_MASK);
323 break;
324 case SND_SOC_DAIFMT_CBS_CFM:
325 case SND_SOC_DAIFMT_CBM_CFS:
326 default:
327 dev_err(codec->dev, "DAI clock mode unsupported");
328 return -EINVAL;
329 }
330
331 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
332 case SND_SOC_DAIFMT_NB_NF:
333 break;
334 case SND_SOC_DAIFMT_NB_IF:
335 invert = M98925_DAI_WCI_MASK;
336 break;
337 case SND_SOC_DAIFMT_IB_NF:
338 invert = M98925_DAI_BCI_MASK;
339 break;
340 case SND_SOC_DAIFMT_IB_IF:
341 invert = M98925_DAI_BCI_MASK | M98925_DAI_WCI_MASK;
342 break;
343 default:
344 dev_err(codec->dev, "DAI invert mode unsupported");
345 return -EINVAL;
346 }
347
348 regmap_update_bits(max98925->regmap, MAX98925_FORMAT,
349 M98925_DAI_BCI_MASK, invert);
350 return 0;
351}
352
353static int max98925_set_clock(struct max98925_priv *max98925,
354 struct snd_pcm_hw_params *params)
355{
356 unsigned int dai_sr = 0, clock, mdll, n, m;
357 struct snd_soc_codec *codec = max98925->codec;
358 int rate = params_rate(params);
359 /* BCLK/LRCLK ratio calculation */
360 int blr_clk_ratio = params_channels(params) * max98925->ch_size;
361
362 switch (blr_clk_ratio) {
363 case 32:
364 regmap_update_bits(max98925->regmap,
365 MAX98925_DAI_CLK_MODE2,
366 M98925_DAI_BSEL_MASK, M98925_DAI_BSEL_32);
367 break;
368 case 48:
369 regmap_update_bits(max98925->regmap,
370 MAX98925_DAI_CLK_MODE2,
371 M98925_DAI_BSEL_MASK, M98925_DAI_BSEL_48);
372 break;
373 case 64:
374 regmap_update_bits(max98925->regmap,
375 MAX98925_DAI_CLK_MODE2,
376 M98925_DAI_BSEL_MASK, M98925_DAI_BSEL_64);
377 break;
378 default:
379 return -EINVAL;
380 }
381
382 switch (max98925->sysclk) {
383 case 6000000:
384 clock = 0;
385 mdll = M98925_MDLL_MULT_MCLKx16;
386 break;
387 case 11289600:
388 clock = 1;
389 mdll = M98925_MDLL_MULT_MCLKx8;
390 break;
391 case 12000000:
392 clock = 0;
393 mdll = M98925_MDLL_MULT_MCLKx8;
394 break;
395 case 12288000:
396 clock = 2;
397 mdll = M98925_MDLL_MULT_MCLKx8;
398 break;
399 default:
400 dev_info(max98925->codec->dev, "unsupported sysclk %d\n",
401 max98925->sysclk);
402 return -EINVAL;
403 }
404
405 if (max98925_rate_value(codec, rate, clock, &dai_sr, &n, &m))
406 return -EINVAL;
407
408 /* set DAI_SR to correct LRCLK frequency */
409 regmap_update_bits(max98925->regmap,
410 MAX98925_DAI_CLK_MODE2,
411 M98925_DAI_SR_MASK, dai_sr << M98925_DAI_SR_SHIFT);
412 /* set DAI m divider */
413 regmap_write(max98925->regmap,
414 MAX98925_DAI_CLK_DIV_M_MSBS, m >> 8);
415 regmap_write(max98925->regmap,
416 MAX98925_DAI_CLK_DIV_M_LSBS, m & 0xFF);
417 /* set DAI n divider */
418 regmap_write(max98925->regmap,
419 MAX98925_DAI_CLK_DIV_N_MSBS, n >> 8);
420 regmap_write(max98925->regmap,
421 MAX98925_DAI_CLK_DIV_N_LSBS, n & 0xFF);
422 /* set MDLL */
423 regmap_update_bits(max98925->regmap, MAX98925_DAI_CLK_MODE1,
424 M98925_MDLL_MULT_MASK, mdll << M98925_MDLL_MULT_SHIFT);
425 return 0;
426}
427
428static int max98925_dai_hw_params(struct snd_pcm_substream *substream,
429 struct snd_pcm_hw_params *params,
430 struct snd_soc_dai *dai)
431{
432 struct snd_soc_codec *codec = dai->codec;
433 struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
434
435 switch (snd_pcm_format_width(params_format(params))) {
436 case 16:
437 regmap_update_bits(max98925->regmap,
438 MAX98925_FORMAT,
439 M98925_DAI_CHANSZ_MASK, M98925_DAI_CHANSZ_16);
440 max98925->ch_size = 16;
441 break;
442 case 24:
443 regmap_update_bits(max98925->regmap,
444 MAX98925_FORMAT,
445 M98925_DAI_CHANSZ_MASK, M98925_DAI_CHANSZ_24);
446 max98925->ch_size = 24;
447 break;
448 case 32:
449 regmap_update_bits(max98925->regmap,
450 MAX98925_FORMAT,
451 M98925_DAI_CHANSZ_MASK, M98925_DAI_CHANSZ_32);
452 max98925->ch_size = 32;
453 break;
454 default:
455 pr_err("%s: format unsupported %d",
456 __func__, params_format(params));
457 return -EINVAL;
458 }
459 dev_dbg(codec->dev, "%s: format supported %d",
460 __func__, params_format(params));
461 return max98925_set_clock(max98925, params);
462}
463
464static int max98925_dai_set_sysclk(struct snd_soc_dai *dai,
465 int clk_id, unsigned int freq, int dir)
466{
467 struct snd_soc_codec *codec = dai->codec;
468 struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
469
470 switch (clk_id) {
471 case 0:
472 /* use MCLK for Left channel, right channel always BCLK */
473 regmap_update_bits(max98925->regmap,
474 MAX98925_DAI_CLK_MODE1,
475 M98925_DAI_CLK_SOURCE_MASK, 0);
476 break;
477 case 1:
478 /* configure dai clock source to BCLK instead of MCLK */
479 regmap_update_bits(max98925->regmap,
480 MAX98925_DAI_CLK_MODE1,
481 M98925_DAI_CLK_SOURCE_MASK,
482 M98925_DAI_CLK_SOURCE_MASK);
483 break;
484 default:
485 return -EINVAL;
486 }
487 max98925->sysclk = freq;
488 return 0;
489}
490
491#define MAX98925_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
492 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
493
494static const struct snd_soc_dai_ops max98925_dai_ops = {
495 .set_sysclk = max98925_dai_set_sysclk,
496 .set_fmt = max98925_dai_set_fmt,
497 .hw_params = max98925_dai_hw_params,
498};
499
500static struct snd_soc_dai_driver max98925_dai[] = {
501 {
502 .name = "max98925-aif1",
503 .playback = {
504 .stream_name = "HiFi Playback",
505 .channels_min = 1,
506 .channels_max = 2,
507 .rates = SNDRV_PCM_RATE_8000_48000,
508 .formats = MAX98925_FORMATS,
509 },
510 .capture = {
511 .stream_name = "HiFi Capture",
512 .channels_min = 1,
513 .channels_max = 2,
514 .rates = SNDRV_PCM_RATE_8000_48000,
515 .formats = MAX98925_FORMATS,
516 },
517 .ops = &max98925_dai_ops,
518 }
519};
520
521static int max98925_probe(struct snd_soc_codec *codec)
522{
523 struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
524
525 max98925->codec = codec;
526 codec->control_data = max98925->regmap;
527 regmap_write(max98925->regmap, MAX98925_GLOBAL_ENABLE, 0x00);
528 /* It's not the default but we need to set DAI_DLY */
529 regmap_write(max98925->regmap,
530 MAX98925_FORMAT, M98925_DAI_DLY_MASK);
531 regmap_write(max98925->regmap, MAX98925_TDM_SLOT_SELECT, 0xC8);
532 regmap_write(max98925->regmap, MAX98925_DOUT_HIZ_CFG1, 0xFF);
533 regmap_write(max98925->regmap, MAX98925_DOUT_HIZ_CFG2, 0xFF);
534 regmap_write(max98925->regmap, MAX98925_DOUT_HIZ_CFG3, 0xFF);
535 regmap_write(max98925->regmap, MAX98925_DOUT_HIZ_CFG4, 0xF0);
536 regmap_write(max98925->regmap, MAX98925_FILTERS, 0xD8);
537 regmap_write(max98925->regmap, MAX98925_ALC_CONFIGURATION, 0xF8);
538 regmap_write(max98925->regmap, MAX98925_CONFIGURATION, 0xF0);
539 /* Disable ALC muting */
540 regmap_write(max98925->regmap, MAX98925_BOOST_LIMITER, 0xF8);
541 return 0;
542}
543
544static const struct snd_soc_codec_driver soc_codec_dev_max98925 = {
545 .probe = max98925_probe,
546 .controls = max98925_snd_controls,
547 .num_controls = ARRAY_SIZE(max98925_snd_controls),
548 .dapm_routes = max98925_audio_map,
549 .num_dapm_routes = ARRAY_SIZE(max98925_audio_map),
550 .dapm_widgets = max98925_dapm_widgets,
551 .num_dapm_widgets = ARRAY_SIZE(max98925_dapm_widgets),
552};
553
554static const struct regmap_config max98925_regmap = {
555 .reg_bits = 8,
556 .val_bits = 8,
557 .max_register = MAX98925_REV_VERSION,
558 .reg_defaults = max98925_reg,
559 .num_reg_defaults = ARRAY_SIZE(max98925_reg),
560 .volatile_reg = max98925_volatile_register,
561 .readable_reg = max98925_readable_register,
562 .cache_type = REGCACHE_RBTREE,
563};
564
565static int max98925_i2c_probe(struct i2c_client *i2c,
566 const struct i2c_device_id *id)
567{
568 int ret, reg;
569 u32 value;
570 struct max98925_priv *max98925;
571
572 max98925 = devm_kzalloc(&i2c->dev,
573 sizeof(*max98925), GFP_KERNEL);
574 if (!max98925)
575 return -ENOMEM;
576
577 i2c_set_clientdata(i2c, max98925);
578 max98925->regmap = devm_regmap_init_i2c(i2c, &max98925_regmap);
579 if (IS_ERR(max98925->regmap)) {
580 ret = PTR_ERR(max98925->regmap);
581 dev_err(&i2c->dev,
582 "Failed to allocate regmap: %d\n", ret);
583 goto err_out;
584 }
585
586 if (!of_property_read_u32(i2c->dev.of_node, "vmon-slot-no", &value)) {
587 if (value > M98925_DAI_VMON_SLOT_1E_1F) {
588 dev_err(&i2c->dev, "vmon slot number is wrong:\n");
589 return -EINVAL;
590 }
591 max98925->v_slot = value;
592 }
593 if (!of_property_read_u32(i2c->dev.of_node, "imon-slot-no", &value)) {
594 if (value > M98925_DAI_IMON_SLOT_1E_1F) {
595 dev_err(&i2c->dev, "imon slot number is wrong:\n");
596 return -EINVAL;
597 }
598 max98925->i_slot = value;
599 }
600 ret = regmap_read(max98925->regmap,
601 MAX98925_REV_VERSION, &reg);
602 if ((ret < 0) ||
603 ((reg != MAX98925_VERSION) &&
604 (reg != MAX98925_VERSION1))) {
605 dev_err(&i2c->dev,
606 "device initialization error (%d 0x%02X)\n",
607 ret, reg);
608 goto err_out;
609 }
610 dev_info(&i2c->dev, "device version 0x%02X\n", reg);
611
612 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98925,
613 max98925_dai, ARRAY_SIZE(max98925_dai));
614 if (ret < 0)
615 dev_err(&i2c->dev,
616 "Failed to register codec: %d\n", ret);
617err_out:
618 return ret;
619}
620
621static int max98925_i2c_remove(struct i2c_client *client)
622{
623 snd_soc_unregister_codec(&client->dev);
624 return 0;
625}
626
627static const struct i2c_device_id max98925_i2c_id[] = {
628 { "max98925", 0 },
629 { }
630};
631MODULE_DEVICE_TABLE(i2c, max98925_i2c_id);
632
633static const struct of_device_id max98925_of_match[] = {
634 { .compatible = "maxim,max98925", },
635 { }
636};
637MODULE_DEVICE_TABLE(of, max98925_of_match);
638
639static struct i2c_driver max98925_i2c_driver = {
640 .driver = {
641 .name = "max98925",
642 .owner = THIS_MODULE,
643 .of_match_table = of_match_ptr(max98925_of_match),
644 .pm = NULL,
645 },
646 .probe = max98925_i2c_probe,
647 .remove = max98925_i2c_remove,
648 .id_table = max98925_i2c_id,
649};
650
651module_i2c_driver(max98925_i2c_driver)
652
653MODULE_DESCRIPTION("ALSA SoC MAX98925 driver");
654MODULE_AUTHOR("Ralph Birt <rdbirt@gmail.com>, Anish kumar <anish.kumar@maximintegrated.com>");
655MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98925.h b/sound/soc/codecs/max98925.h
new file mode 100644
index 000000000000..3783248f2780
--- /dev/null
+++ b/sound/soc/codecs/max98925.h
@@ -0,0 +1,832 @@
1/*
2 * max98925.h -- MAX98925 ALSA SoC Audio driver
3 *
4 * Copyright 2013-2015 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _MAX98925_H
12#define _MAX98925_H
13
14#define MAX98925_VERSION 0x51
15#define MAX98925_VERSION1 0x80
16#define MAX98925_VBAT_DATA 0x00
17#define MAX98925_VBST_DATA 0x01
18#define MAX98925_LIVE_STATUS0 0x02
19#define MAX98925_LIVE_STATUS1 0x03
20#define MAX98925_LIVE_STATUS2 0x04
21#define MAX98925_STATE0 0x05
22#define MAX98925_STATE1 0x06
23#define MAX98925_STATE2 0x07
24#define MAX98925_FLAG0 0x08
25#define MAX98925_FLAG1 0x09
26#define MAX98925_FLAG2 0x0A
27#define MAX98925_IRQ_ENABLE0 0x0B
28#define MAX98925_IRQ_ENABLE1 0x0C
29#define MAX98925_IRQ_ENABLE2 0x0D
30#define MAX98925_IRQ_CLEAR0 0x0E
31#define MAX98925_IRQ_CLEAR1 0x0F
32#define MAX98925_IRQ_CLEAR2 0x10
33#define MAX98925_MAP0 0x11
34#define MAX98925_MAP1 0x12
35#define MAX98925_MAP2 0x13
36#define MAX98925_MAP3 0x14
37#define MAX98925_MAP4 0x15
38#define MAX98925_MAP5 0x16
39#define MAX98925_MAP6 0x17
40#define MAX98925_MAP7 0x18
41#define MAX98925_MAP8 0x19
42#define MAX98925_DAI_CLK_MODE1 0x1A
43#define MAX98925_DAI_CLK_MODE2 0x1B
44#define MAX98925_DAI_CLK_DIV_M_MSBS 0x1C
45#define MAX98925_DAI_CLK_DIV_M_LSBS 0x1D
46#define MAX98925_DAI_CLK_DIV_N_MSBS 0x1E
47#define MAX98925_DAI_CLK_DIV_N_LSBS 0x1F
48#define MAX98925_FORMAT 0x20
49#define MAX98925_TDM_SLOT_SELECT 0x21
50#define MAX98925_DOUT_CFG_VMON 0x22
51#define MAX98925_DOUT_CFG_IMON 0x23
52#define MAX98925_DOUT_CFG_VBAT 0x24
53#define MAX98925_DOUT_CFG_VBST 0x25
54#define MAX98925_DOUT_CFG_FLAG 0x26
55#define MAX98925_DOUT_HIZ_CFG1 0x27
56#define MAX98925_DOUT_HIZ_CFG2 0x28
57#define MAX98925_DOUT_HIZ_CFG3 0x29
58#define MAX98925_DOUT_HIZ_CFG4 0x2A
59#define MAX98925_DOUT_DRV_STRENGTH 0x2B
60#define MAX98925_FILTERS 0x2C
61#define MAX98925_GAIN 0x2D
62#define MAX98925_GAIN_RAMPING 0x2E
63#define MAX98925_SPK_AMP 0x2F
64#define MAX98925_THRESHOLD 0x30
65#define MAX98925_ALC_ATTACK 0x31
66#define MAX98925_ALC_ATTEN_RLS 0x32
67#define MAX98925_ALC_HOLD_RLS 0x33
68#define MAX98925_ALC_CONFIGURATION 0x34
69#define MAX98925_BOOST_CONVERTER 0x35
70#define MAX98925_BLOCK_ENABLE 0x36
71#define MAX98925_CONFIGURATION 0x37
72#define MAX98925_GLOBAL_ENABLE 0x38
73#define MAX98925_BOOST_LIMITER 0x3A
74#define MAX98925_REV_VERSION 0xFF
75
76#define MAX98925_REG_CNT (MAX98925_R03A_BOOST_LIMITER+1)
77
78/* MAX98925 Register Bit Fields */
79
80/* MAX98925_R002_LIVE_STATUS0 */
81#define M98925_THERMWARN_STATUS_MASK (1<<3)
82#define M98925_THERMWARN_STATUS_SHIFT 3
83#define M98925_THERMWARN_STATUS_WIDTH 1
84#define M98925_THERMSHDN_STATUS_MASK (1<<1)
85#define M98925_THERMSHDN_STATUS_SHIFT 1
86#define M98925_THERMSHDN_STATUS_WIDTH 1
87
88/* MAX98925_R003_LIVE_STATUS1 */
89#define M98925_SPKCURNT_STATUS_MASK (1<<5)
90#define M98925_SPKCURNT_STATUS_SHIFT 5
91#define M98925_SPKCURNT_STATUS_WIDTH 1
92#define M98925_WATCHFAIL_STATUS_MASK (1<<4)
93#define M98925_WATCHFAIL_STATUS_SHIFT 4
94#define M98925_WATCHFAIL_STATUS_WIDTH 1
95#define M98925_ALCINFH_STATUS_MASK (1<<3)
96#define M98925_ALCINFH_STATUS_SHIFT 3
97#define M98925_ALCINFH_STATUS_WIDTH 1
98#define M98925_ALCACT_STATUS_MASK (1<<2)
99#define M98925_ALCACT_STATUS_SHIFT 2
100#define M98925_ALCACT_STATUS_WIDTH 1
101#define M98925_ALCMUT_STATUS_MASK (1<<1)
102#define M98925_ALCMUT_STATUS_SHIFT 1
103#define M98925_ALCMUT_STATUS_WIDTH 1
104#define M98925_ACLP_STATUS_MASK (1<<0)
105#define M98925_ACLP_STATUS_SHIFT 0
106#define M98925_ACLP_STATUS_WIDTH 1
107
108/* MAX98925_R004_LIVE_STATUS2 */
109#define M98925_SLOTOVRN_STATUS_MASK (1<<6)
110#define M98925_SLOTOVRN_STATUS_SHIFT 6
111#define M98925_SLOTOVRN_STATUS_WIDTH 1
112#define M98925_INVALSLOT_STATUS_MASK (1<<5)
113#define M98925_INVALSLOT_STATUS_SHIFT 5
114#define M98925_INVALSLOT_STATUS_WIDTH 1
115#define M98925_SLOTCNFLT_STATUS_MASK (1<<4)
116#define M98925_SLOTCNFLT_STATUS_SHIFT 4
117#define M98925_SLOTCNFLT_STATUS_WIDTH 1
118#define M98925_VBSTOVFL_STATUS_MASK (1<<3)
119#define M98925_VBSTOVFL_STATUS_SHIFT 3
120#define M98925_VBSTOVFL_STATUS_WIDTH 1
121#define M98925_VBATOVFL_STATUS_MASK (1<<2)
122#define M98925_VBATOVFL_STATUS_SHIFT 2
123#define M98925_VBATOVFL_STATUS_WIDTH 1
124#define M98925_IMONOVFL_STATUS_MASK (1<<1)
125#define M98925_IMONOVFL_STATUS_SHIFT 1
126#define M98925_IMONOVFL_STATUS_WIDTH 1
127#define M98925_VMONOVFL_STATUS_MASK (1<<0)
128#define M98925_VMONOVFL_STATUS_SHIFT 0
129#define M98925_VMONOVFL_STATUS_WIDTH 1
130
131/* MAX98925_R005_STATE0 */
132#define M98925_THERMWARN_END_STATE_MASK (1<<3)
133#define M98925_THERMWARN_END_STATE_SHIFT 3
134#define M98925_THERMWARN_END_STATE_WIDTH 1
135#define M98925_THERMWARN_BGN_STATE_MASK (1<<2)
136#define M98925_THERMWARN_BGN_STATE_SHIFT 1
137#define M98925_THERMWARN_BGN_STATE_WIDTH 1
138#define M98925_THERMSHDN_END_STATE_MASK (1<<1)
139#define M98925_THERMSHDN_END_STATE_SHIFT 1
140#define M98925_THERMSHDN_END_STATE_WIDTH 1
141#define M98925_THERMSHDN_BGN_STATE_MASK (1<<0)
142#define M98925_THERMSHDN_BGN_STATE_SHIFT 0
143#define M98925_THERMSHDN_BGN_STATE_WIDTH 1
144
145/* MAX98925_R006_STATE1 */
146#define M98925_SPRCURNT_STATE_MASK (1<<5)
147#define M98925_SPRCURNT_STATE_SHIFT 5
148#define M98925_SPRCURNT_STATE_WIDTH 1
149#define M98925_WATCHFAIL_STATE_MASK (1<<4)
150#define M98925_WATCHFAIL_STATE_SHIFT 4
151#define M98925_WATCHFAIL_STATE_WIDTH 1
152#define M98925_ALCINFH_STATE_MASK (1<<3)
153#define M98925_ALCINFH_STATE_SHIFT 3
154#define M98925_ALCINFH_STATE_WIDTH 1
155#define M98925_ALCACT_STATE_MASK (1<<2)
156#define M98925_ALCACT_STATE_SHIFT 2
157#define M98925_ALCACT_STATE_WIDTH 1
158#define M98925_ALCMUT_STATE_MASK (1<<1)
159#define M98925_ALCMUT_STATE_SHIFT 1
160#define M98925_ALCMUT_STATE_WIDTH 1
161#define M98925_ALCP_STATE_MASK (1<<0)
162#define M98925_ALCP_STATE_SHIFT 0
163#define M98925_ALCP_STATE_WIDTH 1
164
165/* MAX98925_R007_STATE2 */
166#define M98925_SLOTOVRN_STATE_MASK (1<<6)
167#define M98925_SLOTOVRN_STATE_SHIFT 6
168#define M98925_SLOTOVRN_STATE_WIDTH 1
169#define M98925_INVALSLOT_STATE_MASK (1<<5)
170#define M98925_INVALSLOT_STATE_SHIFT 5
171#define M98925_INVALSLOT_STATE_WIDTH 1
172#define M98925_SLOTCNFLT_STATE_MASK (1<<4)
173#define M98925_SLOTCNFLT_STATE_SHIFT 4
174#define M98925_SLOTCNFLT_STATE_WIDTH 1
175#define M98925_VBSTOVFL_STATE_MASK (1<<3)
176#define M98925_VBSTOVFL_STATE_SHIFT 3
177#define M98925_VBSTOVFL_STATE_WIDTH 1
178#define M98925_VBATOVFL_STATE_MASK (1<<2)
179#define M98925_VBATOVFL_STATE_SHIFT 2
180#define M98925_VBATOVFL_STATE_WIDTH 1
181#define M98925_IMONOVFL_STATE_MASK (1<<1)
182#define M98925_IMONOVFL_STATE_SHIFT 1
183#define M98925_IMONOVFL_STATE_WIDTH 1
184#define M98925_VMONOVFL_STATE_MASK (1<<0)
185#define M98925_VMONOVFL_STATE_SHIFT 0
186#define M98925_VMONOVFL_STATE_WIDTH 1
187
188/* MAX98925_R008_FLAG0 */
189#define M98925_THERMWARN_END_FLAG_MASK (1<<3)
190#define M98925_THERMWARN_END_FLAG_SHIFT 3
191#define M98925_THERMWARN_END_FLAG_WIDTH 1
192#define M98925_THERMWARN_BGN_FLAG_MASK (1<<2)
193#define M98925_THERMWARN_BGN_FLAG_SHIFT 2
194#define M98925_THERMWARN_BGN_FLAG_WIDTH 1
195#define M98925_THERMSHDN_END_FLAG_MASK (1<<1)
196#define M98925_THERMSHDN_END_FLAG_SHIFT 1
197#define M98925_THERMSHDN_END_FLAG_WIDTH 1
198#define M98925_THERMSHDN_BGN_FLAG_MASK (1<<0)
199#define M98925_THERMSHDN_BGN_FLAG_SHIFT 0
200#define M98925_THERMSHDN_BGN_FLAG_WIDTH 1
201
202/* MAX98925_R009_FLAG1 */
203#define M98925_SPKCURNT_FLAG_MASK (1<<5)
204#define M98925_SPKCURNT_FLAG_SHIFT 5
205#define M98925_SPKCURNT_FLAG_WIDTH 1
206#define M98925_WATCHFAIL_FLAG_MASK (1<<4)
207#define M98925_WATCHFAIL_FLAG_SHIFT 4
208#define M98925_WATCHFAIL_FLAG_WIDTH 1
209#define M98925_ALCINFH_FLAG_MASK (1<<3)
210#define M98925_ALCINFH_FLAG_SHIFT 3
211#define M98925_ALCINFH_FLAG_WIDTH 1
212#define M98925_ALCACT_FLAG_MASK (1<<2)
213#define M98925_ALCACT_FLAG_SHIFT 2
214#define M98925_ALCACT_FLAG_WIDTH 1
215#define M98925_ALCMUT_FLAG_MASK (1<<1)
216#define M98925_ALCMUT_FLAG_SHIFT 1
217#define M98925_ALCMUT_FLAG_WIDTH 1
218#define M98925_ALCP_FLAG_MASK (1<<0)
219#define M98925_ALCP_FLAG_SHIFT 0
220#define M98925_ALCP_FLAG_WIDTH 1
221
222/* MAX98925_R00A_FLAG2 */
223#define M98925_SLOTOVRN_FLAG_MASK (1<<6)
224#define M98925_SLOTOVRN_FLAG_SHIFT 6
225#define M98925_SLOTOVRN_FLAG_WIDTH 1
226#define M98925_INVALSLOT_FLAG_MASK (1<<5)
227#define M98925_INVALSLOT_FLAG_SHIFT 5
228#define M98925_INVALSLOT_FLAG_WIDTH 1
229#define M98925_SLOTCNFLT_FLAG_MASK (1<<4)
230#define M98925_SLOTCNFLT_FLAG_SHIFT 4
231#define M98925_SLOTCNFLT_FLAG_WIDTH 1
232#define M98925_VBSTOVFL_FLAG_MASK (1<<3)
233#define M98925_VBSTOVFL_FLAG_SHIFT 3
234#define M98925_VBSTOVFL_FLAG_WIDTH 1
235#define M98925_VBATOVFL_FLAG_MASK (1<<2)
236#define M98925_VBATOVFL_FLAG_SHIFT 2
237#define M98925_VBATOVFL_FLAG_WIDTH 1
238#define M98925_IMONOVFL_FLAG_MASK (1<<1)
239#define M98925_IMONOVFL_FLAG_SHIFT 1
240#define M98925_IMONOVFL_FLAG_WIDTH 1
241#define M98925_VMONOVFL_FLAG_MASK (1<<0)
242#define M98925_VMONOVFL_FLAG_SHIFT 0
243#define M98925_VMONOVFL_FLAG_WIDTH 1
244
245/* MAX98925_R00B_IRQ_ENABLE0 */
246#define M98925_THERMWARN_END_EN_MASK (1<<3)
247#define M98925_THERMWARN_END_EN_SHIFT 3
248#define M98925_THERMWARN_END_EN_WIDTH 1
249#define M98925_THERMWARN_BGN_EN_MASK (1<<2)
250#define M98925_THERMWARN_BGN_EN_SHIFT 2
251#define M98925_THERMWARN_BGN_EN_WIDTH 1
252#define M98925_THERMSHDN_END_EN_MASK (1<<1)
253#define M98925_THERMSHDN_END_EN_SHIFT 1
254#define M98925_THERMSHDN_END_EN_WIDTH 1
255#define M98925_THERMSHDN_BGN_EN_MASK (1<<0)
256#define M98925_THERMSHDN_BGN_EN_SHIFT 0
257#define M98925_THERMSHDN_BGN_EN_WIDTH 1
258
259/* MAX98925_R00C_IRQ_ENABLE1 */
260#define M98925_SPKCURNT_EN_MASK (1<<5)
261#define M98925_SPKCURNT_EN_SHIFT 5
262#define M98925_SPKCURNT_EN_WIDTH 1
263#define M98925_WATCHFAIL_EN_MASK (1<<4)
264#define M98925_WATCHFAIL_EN_SHIFT 4
265#define M98925_WATCHFAIL_EN_WIDTH 1
266#define M98925_ALCINFH_EN_MASK (1<<3)
267#define M98925_ALCINFH_EN_SHIFT 3
268#define M98925_ALCINFH_EN_WIDTH 1
269#define M98925_ALCACT_EN_MASK (1<<2)
270#define M98925_ALCACT_EN_SHIFT 2
271#define M98925_ALCACT_EN_WIDTH 1
272#define M98925_ALCMUT_EN_MASK (1<<1)
273#define M98925_ALCMUT_EN_SHIFT 1
274#define M98925_ALCMUT_EN_WIDTH 1
275#define M98925_ALCP_EN_MASK (1<<0)
276#define M98925_ALCP_EN_SHIFT 0
277#define M98925_ALCP_EN_WIDTH 1
278
279/* MAX98925_R00D_IRQ_ENABLE2 */
280#define M98925_SLOTOVRN_EN_MASK (1<<6)
281#define M98925_SLOTOVRN_EN_SHIFT 6
282#define M98925_SLOTOVRN_EN_WIDTH 1
283#define M98925_INVALSLOT_EN_MASK (1<<5)
284#define M98925_INVALSLOT_EN_SHIFT 5
285#define M98925_INVALSLOT_EN_WIDTH 1
286#define M98925_SLOTCNFLT_EN_MASK (1<<4)
287#define M98925_SLOTCNFLT_EN_SHIFT 4
288#define M98925_SLOTCNFLT_EN_WIDTH 1
289#define M98925_VBSTOVFL_EN_MASK (1<<3)
290#define M98925_VBSTOVFL_EN_SHIFT 3
291#define M98925_VBSTOVFL_EN_WIDTH 1
292#define M98925_VBATOVFL_EN_MASK (1<<2)
293#define M98925_VBATOVFL_EN_SHIFT 2
294#define M98925_VBATOVFL_EN_WIDTH 1
295#define M98925_IMONOVFL_EN_MASK (1<<1)
296#define M98925_IMONOVFL_EN_SHIFT 1
297#define M98925_IMONOVFL_EN_WIDTH 1
298#define M98925_VMONOVFL_EN_MASK (1<<0)
299#define M98925_VMONOVFL_EN_SHIFT 0
300#define M98925_VMONOVFL_EN_WIDTH 1
301
302/* MAX98925_R00E_IRQ_CLEAR0 */
303#define M98925_THERMWARN_END_CLR_MASK (1<<3)
304#define M98925_THERMWARN_END_CLR_SHIFT 3
305#define M98925_THERMWARN_END_CLR_WIDTH 1
306#define M98925_THERMWARN_BGN_CLR_MASK (1<<2)
307#define M98925_THERMWARN_BGN_CLR_SHIFT 2
308#define M98925_THERMWARN_BGN_CLR_WIDTH 1
309#define M98925_THERMSHDN_END_CLR_MASK (1<<1)
310#define M98925_THERMSHDN_END_CLR_SHIFT 1
311#define M98925_THERMSHDN_END_CLR_WIDTH 1
312#define M98925_THERMSHDN_BGN_CLR_MASK (1<<0)
313#define M98925_THERMSHDN_BGN_CLR_SHIFT 0
314#define M98925_THERMSHDN_BGN_CLR_WIDTH 1
315
316/* MAX98925_R00F_IRQ_CLEAR1 */
317#define M98925_SPKCURNT_CLR_MASK (1<<5)
318#define M98925_SPKCURNT_CLR_SHIFT 5
319#define M98925_SPKCURNT_CLR_WIDTH 1
320#define M98925_WATCHFAIL_CLR_MASK (1<<4)
321#define M98925_WATCHFAIL_CLR_SHIFT 4
322#define M98925_WATCHFAIL_CLR_WIDTH 1
323#define M98925_ALCINFH_CLR_MASK (1<<3)
324#define M98925_ALCINFH_CLR_SHIFT 3
325#define M98925_ALCINFH_CLR_WIDTH 1
326#define M98925_ALCACT_CLR_MASK (1<<2)
327#define M98925_ALCACT_CLR_SHIFT 2
328#define M98925_ALCACT_CLR_WIDTH 1
329#define M98925_ALCMUT_CLR_MASK (1<<1)
330#define M98925_ALCMUT_CLR_SHIFT 1
331#define M98925_ALCMUT_CLR_WIDTH 1
332#define M98925_ALCP_CLR_MASK (1<<0)
333#define M98925_ALCP_CLR_SHIFT 0
334#define M98925_ALCP_CLR_WIDTH 1
335
336/* MAX98925_R010_IRQ_CLEAR2 */
337#define M98925_SLOTOVRN_CLR_MASK (1<<6)
338#define M98925_SLOTOVRN_CLR_SHIFT 6
339#define M98925_SLOTOVRN_CLR_WIDTH 1
340#define M98925_INVALSLOT_CLR_MASK (1<<5)
341#define M98925_INVALSLOT_CLR_SHIFT 5
342#define M98925_INVALSLOT_CLR_WIDTH 1
343#define M98925_SLOTCNFLT_CLR_MASK (1<<4)
344#define M98925_SLOTCNFLT_CLR_SHIFT 4
345#define M98925_SLOTCNFLT_CLR_WIDTH 1
346#define M98925_VBSTOVFL_CLR_MASK (1<<3)
347#define M98925_VBSTOVFL_CLR_SHIFT 3
348#define M98925_VBSTOVFL_CLR_WIDTH 1
349#define M98925_VBATOVFL_CLR_MASK (1<<2)
350#define M98925_VBATOVFL_CLR_SHIFT 2
351#define M98925_VBATOVFL_CLR_WIDTH 1
352#define M98925_IMONOVFL_CLR_MASK (1<<1)
353#define M98925_IMONOVFL_CLR_SHIFT 1
354#define M98925_IMONOVFL_CLR_WIDTH 1
355#define M98925_VMONOVFL_CLR_MASK (1<<0)
356#define M98925_VMONOVFL_CLR_SHIFT 0
357#define M98925_VMONOVFL_CLR_WIDTH 1
358
359/* MAX98925_R011_MAP0 */
360#define M98925_ER_THERMWARN_EN_MASK (1<<7)
361#define M98925_ER_THERMWARN_EN_SHIFT 7
362#define M98925_ER_THERMWARN_EN_WIDTH 1
363#define M98925_ER_THERMWARN_MAP_MASK (0x07<<4)
364#define M98925_ER_THERMWARN_MAP_SHIFT 4
365#define M98925_ER_THERMWARN_MAP_WIDTH 3
366
367/* MAX98925_R012_MAP1 */
368#define M98925_ER_ALCMUT_EN_MASK (1<<7)
369#define M98925_ER_ALCMUT_EN_SHIFT 7
370#define M98925_ER_ALCMUT_EN_WIDTH 1
371#define M98925_ER_ALCMUT_MAP_MASK (0x07<<4)
372#define M98925_ER_ALCMUT_MAP_SHIFT 4
373#define M98925_ER_ALCMUT_MAP_WIDTH 3
374#define M98925_ER_ALCP_EN_MASK (1<<3)
375#define M98925_ER_ALCP_EN_SHIFT 3
376#define M98925_ER_ALCP_EN_WIDTH 1
377#define M98925_ER_ALCP_MAP_MASK (0x07<<0)
378#define M98925_ER_ALCP_MAP_SHIFT 0
379#define M98925_ER_ALCP_MAP_WIDTH 3
380
381/* MAX98925_R013_MAP2 */
382#define M98925_ER_ALCINFH_EN_MASK (1<<7)
383#define M98925_ER_ALCINFH_EN_SHIFT 7
384#define M98925_ER_ALCINFH_EN_WIDTH 1
385#define M98925_ER_ALCINFH_MAP_MASK (0x07<<4)
386#define M98925_ER_ALCINFH_MAP_SHIFT 4
387#define M98925_ER_ALCINFH_MAP_WIDTH 3
388#define M98925_ER_ALCACT_EN_MASK (1<<3)
389#define M98925_ER_ALCACT_EN_SHIFT 3
390#define M98925_ER_ALCACT_EN_WIDTH 1
391#define M98925_ER_ALCACT_MAP_MASK (0x07<<0)
392#define M98925_ER_ALCACT_MAP_SHIFT 0
393#define M98925_ER_ALCACT_MAP_WIDTH 3
394
395/* MAX98925_R014_MAP3 */
396#define M98925_ER_SPKCURNT_EN_MASK (1<<7)
397#define M98925_ER_SPKCURNT_EN_SHIFT 7
398#define M98925_ER_SPKCURNT_EN_WIDTH 1
399#define M98925_ER_SPKCURNT_MAP_MASK (0x07<<4)
400#define M98925_ER_SPKCURNT_MAP_SHIFT 4
401#define M98925_ER_SPKCURNT_MAP_WIDTH 3
402
403/* MAX98925_R015_MAP4 */
404/* RESERVED */
405
406/* MAX98925_R016_MAP5 */
407#define M98925_ER_IMONOVFL_EN_MASK (1<<7)
408#define M98925_ER_IMONOVFL_EN_SHIFT 7
409#define M98925_ER_IMONOVFL_EN_WIDTH 1
410#define M98925_ER_IMONOVFL_MAP_MASK (0x07<<4)
411#define M98925_ER_IMONOVFL_MAP_SHIFT 4
412#define M98925_ER_IMONOVFL_MAP_WIDTH 3
413#define M98925_ER_VMONOVFL_EN_MASK (1<<3)
414#define M98925_ER_VMONOVFL_EN_SHIFT 3
415#define M98925_ER_VMONOVFL_EN_WIDTH 1
416#define M98925_ER_VMONOVFL_MAP_MASK (0x07<<0)
417#define M98925_ER_VMONOVFL_MAP_SHIFT 0
418#define M98925_ER_VMONOVFL_MAP_WIDTH 3
419
420/* MAX98925_R017_MAP6 */
421#define M98925_ER_VBSTOVFL_EN_MASK (1<<7)
422#define M98925_ER_VBSTOVFL_EN_SHIFT 7
423#define M98925_ER_VBSTOVFL_EN_WIDTH 1
424#define M98925_ER_VBSTOVFL_MAP_MASK (0x07<<4)
425#define M98925_ER_VBSTOVFL_MAP_SHIFT 4
426#define M98925_ER_VBSTOVFL_MAP_WIDTH 3
427#define M98925_ER_VBATOVFL_EN_MASK (1<<3)
428#define M98925_ER_VBATOVFL_EN_SHIFT 3
429#define M98925_ER_VBATOVFL_EN_WIDTH 1
430#define M98925_ER_VBATOVFL_MAP_MASK (0x07<<0)
431#define M98925_ER_VBATOVFL_MAP_SHIFT 0
432#define M98925_ER_VBATOVFL_MAP_WIDTH 3
433
434/* MAX98925_R018_MAP7 */
435#define M98925_ER_INVALSLOT_EN_MASK (1<<7)
436#define M98925_ER_INVALSLOT_EN_SHIFT 7
437#define M98925_ER_INVALSLOT_EN_WIDTH 1
438#define M98925_ER_INVALSLOT_MAP_MASK (0x07<<4)
439#define M98925_ER_INVALSLOT_MAP_SHIFT 4
440#define M98925_ER_INVALSLOT_MAP_WIDTH 3
441#define M98925_ER_SLOTCNFLT_EN_MASK (1<<3)
442#define M98925_ER_SLOTCNFLT_EN_SHIFT 3
443#define M98925_ER_SLOTCNFLT_EN_WIDTH 1
444#define M98925_ER_SLOTCNFLT_MAP_MASK (0x07<<0)
445#define M98925_ER_SLOTCNFLT_MAP_SHIFT 0
446#define M98925_ER_SLOTCNFLT_MAP_WIDTH 3
447
448/* MAX98925_R019_MAP8 */
449#define M98925_ER_SLOTOVRN_EN_MASK (1<<3)
450#define M98925_ER_SLOTOVRN_EN_SHIFT 3
451#define M98925_ER_SLOTOVRN_EN_WIDTH 1
452#define M98925_ER_SLOTOVRN_MAP_MASK (0x07<<0)
453#define M98925_ER_SLOTOVRN_MAP_SHIFT 0
454#define M98925_ER_SLOTOVRN_MAP_WIDTH 3
455
456/* MAX98925_R01A_DAI_CLK_MODE1 */
457#define M98925_DAI_CLK_SOURCE_MASK (1<<6)
458#define M98925_DAI_CLK_SOURCE_SHIFT 6
459#define M98925_DAI_CLK_SOURCE_WIDTH 1
460#define M98925_MDLL_MULT_MASK (0x0F<<0)
461#define M98925_MDLL_MULT_SHIFT 0
462#define M98925_MDLL_MULT_WIDTH 4
463
464#define M98925_MDLL_MULT_MCLKx8 6
465#define M98925_MDLL_MULT_MCLKx16 8
466
467/* MAX98925_R01B_DAI_CLK_MODE2 */
468#define M98925_DAI_SR_MASK (0x0F<<4)
469#define M98925_DAI_SR_SHIFT 4
470#define M98925_DAI_SR_WIDTH 4
471#define M98925_DAI_MAS_MASK (1<<3)
472#define M98925_DAI_MAS_SHIFT 3
473#define M98925_DAI_MAS_WIDTH 1
474#define M98925_DAI_BSEL_MASK (0x07<<0)
475#define M98925_DAI_BSEL_SHIFT 0
476#define M98925_DAI_BSEL_WIDTH 3
477
478#define M98925_DAI_BSEL_32 (0 << M98925_DAI_BSEL_SHIFT)
479#define M98925_DAI_BSEL_48 (1 << M98925_DAI_BSEL_SHIFT)
480#define M98925_DAI_BSEL_64 (2 << M98925_DAI_BSEL_SHIFT)
481#define M98925_DAI_BSEL_256 (6 << M98925_DAI_BSEL_SHIFT)
482
483/* MAX98925_R01C_DAI_CLK_DIV_M_MSBS */
484#define M98925_DAI_M_MSBS_MASK (0xFF<<0)
485#define M98925_DAI_M_MSBS_SHIFT 0
486#define M98925_DAI_M_MSBS_WIDTH 8
487
488/* MAX98925_R01D_DAI_CLK_DIV_M_LSBS */
489#define M98925_DAI_M_LSBS_MASK (0xFF<<0)
490#define M98925_DAI_M_LSBS_SHIFT 0
491#define M98925_DAI_M_LSBS_WIDTH 8
492
493/* MAX98925_R01E_DAI_CLK_DIV_N_MSBS */
494#define M98925_DAI_N_MSBS_MASK (0x7F<<0)
495#define M98925_DAI_N_MSBS_SHIFT 0
496#define M98925_DAI_N_MSBS_WIDTH 7
497
498/* MAX98925_R01F_DAI_CLK_DIV_N_LSBS */
499#define M98925_DAI_N_LSBS_MASK (0xFF<<0)
500#define M98925_DAI_N_LSBS_SHIFT 0
501#define M98925_DAI_N_LSBS_WIDTH 8
502
503/* MAX98925_R020_FORMAT */
504#define M98925_DAI_CHANSZ_MASK (0x03<<6)
505#define M98925_DAI_CHANSZ_SHIFT 6
506#define M98925_DAI_CHANSZ_WIDTH 2
507#define M98925_DAI_EXTBCLK_HIZ_MASK (1<<4)
508#define M98925_DAI_EXTBCLK_HIZ_SHIFT 4
509#define M98925_DAI_EXTBCLK_HIZ_WIDTH 1
510#define M98925_DAI_WCI_MASK (1<<3)
511#define M98925_DAI_WCI_SHIFT 3
512#define M98925_DAI_WCI_WIDTH 1
513#define M98925_DAI_BCI_MASK (1<<2)
514#define M98925_DAI_BCI_SHIFT 2
515#define M98925_DAI_BCI_WIDTH 1
516#define M98925_DAI_DLY_MASK (1<<1)
517#define M98925_DAI_DLY_SHIFT 1
518#define M98925_DAI_DLY_WIDTH 1
519#define M98925_DAI_TDM_MASK (1<<0)
520#define M98925_DAI_TDM_SHIFT 0
521#define M98925_DAI_TDM_WIDTH 1
522
523#define M98925_DAI_CHANSZ_16 (1 << M98925_DAI_CHANSZ_SHIFT)
524#define M98925_DAI_CHANSZ_24 (2 << M98925_DAI_CHANSZ_SHIFT)
525#define M98925_DAI_CHANSZ_32 (3 << M98925_DAI_CHANSZ_SHIFT)
526
527/* MAX98925_R021_TDM_SLOT_SELECT */
528#define M98925_DAI_DO_EN_MASK (1<<7)
529#define M98925_DAI_DO_EN_SHIFT 7
530#define M98925_DAI_DO_EN_WIDTH 1
531#define M98925_DAI_DIN_EN_MASK (1<<6)
532#define M98925_DAI_DIN_EN_SHIFT 6
533#define M98925_DAI_DIN_EN_WIDTH 1
534#define M98925_DAI_INR_SOURCE_MASK (0x07<<3)
535#define M98925_DAI_INR_SOURCE_SHIFT 3
536#define M98925_DAI_INR_SOURCE_WIDTH 3
537#define M98925_DAI_INL_SOURCE_MASK (0x07<<0)
538#define M98925_DAI_INL_SOURCE_SHIFT 0
539#define M98925_DAI_INL_SOURCE_WIDTH 3
540
541/* MAX98925_R022_DOUT_CFG_VMON */
542#define M98925_DAI_VMON_EN_MASK (1<<5)
543#define M98925_DAI_VMON_EN_SHIFT 5
544#define M98925_DAI_VMON_EN_WIDTH 1
545#define M98925_DAI_VMON_SLOT_MASK (0x1F<<0)
546#define M98925_DAI_VMON_SLOT_SHIFT 0
547#define M98925_DAI_VMON_SLOT_WIDTH 5
548
549#define M98925_DAI_VMON_SLOT_00_01 (0 << M98925_DAI_VMON_SLOT_SHIFT)
550#define M98925_DAI_VMON_SLOT_01_02 (1 << M98925_DAI_VMON_SLOT_SHIFT)
551#define M98925_DAI_VMON_SLOT_02_03 (2 << M98925_DAI_VMON_SLOT_SHIFT)
552#define M98925_DAI_VMON_SLOT_03_04 (3 << M98925_DAI_VMON_SLOT_SHIFT)
553#define M98925_DAI_VMON_SLOT_04_05 (4 << M98925_DAI_VMON_SLOT_SHIFT)
554#define M98925_DAI_VMON_SLOT_05_06 (5 << M98925_DAI_VMON_SLOT_SHIFT)
555#define M98925_DAI_VMON_SLOT_06_07 (6 << M98925_DAI_VMON_SLOT_SHIFT)
556#define M98925_DAI_VMON_SLOT_07_08 (7 << M98925_DAI_VMON_SLOT_SHIFT)
557#define M98925_DAI_VMON_SLOT_08_09 (8 << M98925_DAI_VMON_SLOT_SHIFT)
558#define M98925_DAI_VMON_SLOT_09_0A (9 << M98925_DAI_VMON_SLOT_SHIFT)
559#define M98925_DAI_VMON_SLOT_0A_0B (10 << M98925_DAI_VMON_SLOT_SHIFT)
560#define M98925_DAI_VMON_SLOT_0B_0C (11 << M98925_DAI_VMON_SLOT_SHIFT)
561#define M98925_DAI_VMON_SLOT_0C_0D (12 << M98925_DAI_VMON_SLOT_SHIFT)
562#define M98925_DAI_VMON_SLOT_0D_0E (13 << M98925_DAI_VMON_SLOT_SHIFT)
563#define M98925_DAI_VMON_SLOT_0E_0F (14 << M98925_DAI_VMON_SLOT_SHIFT)
564#define M98925_DAI_VMON_SLOT_0F_10 (15 << M98925_DAI_VMON_SLOT_SHIFT)
565#define M98925_DAI_VMON_SLOT_10_11 (16 << M98925_DAI_VMON_SLOT_SHIFT)
566#define M98925_DAI_VMON_SLOT_11_12 (17 << M98925_DAI_VMON_SLOT_SHIFT)
567#define M98925_DAI_VMON_SLOT_12_13 (18 << M98925_DAI_VMON_SLOT_SHIFT)
568#define M98925_DAI_VMON_SLOT_13_14 (19 << M98925_DAI_VMON_SLOT_SHIFT)
569#define M98925_DAI_VMON_SLOT_14_15 (20 << M98925_DAI_VMON_SLOT_SHIFT)
570#define M98925_DAI_VMON_SLOT_15_16 (21 << M98925_DAI_VMON_SLOT_SHIFT)
571#define M98925_DAI_VMON_SLOT_16_17 (22 << M98925_DAI_VMON_SLOT_SHIFT)
572#define M98925_DAI_VMON_SLOT_17_18 (23 << M98925_DAI_VMON_SLOT_SHIFT)
573#define M98925_DAI_VMON_SLOT_18_19 (24 << M98925_DAI_VMON_SLOT_SHIFT)
574#define M98925_DAI_VMON_SLOT_19_1A (25 << M98925_DAI_VMON_SLOT_SHIFT)
575#define M98925_DAI_VMON_SLOT_1A_1B (26 << M98925_DAI_VMON_SLOT_SHIFT)
576#define M98925_DAI_VMON_SLOT_1B_1C (27 << M98925_DAI_VMON_SLOT_SHIFT)
577#define M98925_DAI_VMON_SLOT_1C_1D (28 << M98925_DAI_VMON_SLOT_SHIFT)
578#define M98925_DAI_VMON_SLOT_1D_1E (29 << M98925_DAI_VMON_SLOT_SHIFT)
579#define M98925_DAI_VMON_SLOT_1E_1F (30 << M98925_DAI_VMON_SLOT_SHIFT)
580
581/* MAX98925_R023_DOUT_CFG_IMON */
582#define M98925_DAI_IMON_EN_MASK (1<<5)
583#define M98925_DAI_IMON_EN_SHIFT 5
584#define M98925_DAI_IMON_EN_WIDTH 1
585#define M98925_DAI_IMON_SLOT_MASK (0x1F<<0)
586#define M98925_DAI_IMON_SLOT_SHIFT 0
587#define M98925_DAI_IMON_SLOT_WIDTH 5
588
589#define M98925_DAI_IMON_SLOT_00_01 (0 << M98925_DAI_IMON_SLOT_SHIFT)
590#define M98925_DAI_IMON_SLOT_01_02 (1 << M98925_DAI_IMON_SLOT_SHIFT)
591#define M98925_DAI_IMON_SLOT_02_03 (2 << M98925_DAI_IMON_SLOT_SHIFT)
592#define M98925_DAI_IMON_SLOT_03_04 (3 << M98925_DAI_IMON_SLOT_SHIFT)
593#define M98925_DAI_IMON_SLOT_04_05 (4 << M98925_DAI_IMON_SLOT_SHIFT)
594#define M98925_DAI_IMON_SLOT_05_06 (5 << M98925_DAI_IMON_SLOT_SHIFT)
595#define M98925_DAI_IMON_SLOT_06_07 (6 << M98925_DAI_IMON_SLOT_SHIFT)
596#define M98925_DAI_IMON_SLOT_07_08 (7 << M98925_DAI_IMON_SLOT_SHIFT)
597#define M98925_DAI_IMON_SLOT_08_09 (8 << M98925_DAI_IMON_SLOT_SHIFT)
598#define M98925_DAI_IMON_SLOT_09_0A (9 << M98925_DAI_IMON_SLOT_SHIFT)
599#define M98925_DAI_IMON_SLOT_0A_0B (10 << M98925_DAI_IMON_SLOT_SHIFT)
600#define M98925_DAI_IMON_SLOT_0B_0C (11 << M98925_DAI_IMON_SLOT_SHIFT)
601#define M98925_DAI_IMON_SLOT_0C_0D (12 << M98925_DAI_IMON_SLOT_SHIFT)
602#define M98925_DAI_IMON_SLOT_0D_0E (13 << M98925_DAI_IMON_SLOT_SHIFT)
603#define M98925_DAI_IMON_SLOT_0E_0F (14 << M98925_DAI_IMON_SLOT_SHIFT)
604#define M98925_DAI_IMON_SLOT_0F_10 (15 << M98925_DAI_IMON_SLOT_SHIFT)
605#define M98925_DAI_IMON_SLOT_10_11 (16 << M98925_DAI_IMON_SLOT_SHIFT)
606#define M98925_DAI_IMON_SLOT_11_12 (17 << M98925_DAI_IMON_SLOT_SHIFT)
607#define M98925_DAI_IMON_SLOT_12_13 (18 << M98925_DAI_IMON_SLOT_SHIFT)
608#define M98925_DAI_IMON_SLOT_13_14 (19 << M98925_DAI_IMON_SLOT_SHIFT)
609#define M98925_DAI_IMON_SLOT_14_15 (20 << M98925_DAI_IMON_SLOT_SHIFT)
610#define M98925_DAI_IMON_SLOT_15_16 (21 << M98925_DAI_IMON_SLOT_SHIFT)
611#define M98925_DAI_IMON_SLOT_16_17 (22 << M98925_DAI_IMON_SLOT_SHIFT)
612#define M98925_DAI_IMON_SLOT_17_18 (23 << M98925_DAI_IMON_SLOT_SHIFT)
613#define M98925_DAI_IMON_SLOT_18_19 (24 << M98925_DAI_IMON_SLOT_SHIFT)
614#define M98925_DAI_IMON_SLOT_19_1A (25 << M98925_DAI_IMON_SLOT_SHIFT)
615#define M98925_DAI_IMON_SLOT_1A_1B (26 << M98925_DAI_IMON_SLOT_SHIFT)
616#define M98925_DAI_IMON_SLOT_1B_1C (27 << M98925_DAI_IMON_SLOT_SHIFT)
617#define M98925_DAI_IMON_SLOT_1C_1D (28 << M98925_DAI_IMON_SLOT_SHIFT)
618#define M98925_DAI_IMON_SLOT_1D_1E (29 << M98925_DAI_IMON_SLOT_SHIFT)
619#define M98925_DAI_IMON_SLOT_1E_1F (30 << M98925_DAI_IMON_SLOT_SHIFT)
620
621/* MAX98925_R024_DOUT_CFG_VBAT */
622#define M98925_DAI_VBAT_EN_MASK (1<<5)
623#define M98925_DAI_VBAT_EN_SHIFT 5
624#define M98925_DAI_VBAT_EN_WIDTH 1
625#define M98925_DAI_VBAT_SLOT_MASK (0x1F<<0)
626#define M98925_DAI_VBAT_SLOT_SHIFT 0
627#define M98925_DAI_VBAT_SLOT_WIDTH 5
628
629/* MAX98925_R025_DOUT_CFG_VBST */
630#define M98925_DAI_VBST_EN_MASK (1<<5)
631#define M98925_DAI_VBST_EN_SHIFT 5
632#define M98925_DAI_VBST_EN_WIDTH 1
633#define M98925_DAI_VBST_SLOT_MASK (0x1F<<0)
634#define M98925_DAI_VBST_SLOT_SHIFT 0
635#define M98925_DAI_VBST_SLOT_WIDTH 5
636
637/* MAX98925_R026_DOUT_CFG_FLAG */
638#define M98925_DAI_FLAG_EN_MASK (1<<5)
639#define M98925_DAI_FLAG_EN_SHIFT 5
640#define M98925_DAI_FLAG_EN_WIDTH 1
641#define M98925_DAI_FLAG_SLOT_MASK (0x1F<<0)
642#define M98925_DAI_FLAG_SLOT_SHIFT 0
643#define M98925_DAI_FLAG_SLOT_WIDTH 5
644
645/* MAX98925_R027_DOUT_HIZ_CFG1 */
646#define M98925_DAI_SLOT_HIZ_CFG1_MASK (0xFF<<0)
647#define M98925_DAI_SLOT_HIZ_CFG1_SHIFT 0
648#define M98925_DAI_SLOT_HIZ_CFG1_WIDTH 8
649
650/* MAX98925_R028_DOUT_HIZ_CFG2 */
651#define M98925_DAI_SLOT_HIZ_CFG2_MASK (0xFF<<0)
652#define M98925_DAI_SLOT_HIZ_CFG2_SHIFT 0
653#define M98925_DAI_SLOT_HIZ_CFG2_WIDTH 8
654
655/* MAX98925_R029_DOUT_HIZ_CFG3 */
656#define M98925_DAI_SLOT_HIZ_CFG3_MASK (0xFF<<0)
657#define M98925_DAI_SLOT_HIZ_CFG3_SHIFT 0
658#define M98925_DAI_SLOT_HIZ_CFG3_WIDTH 8
659
660/* MAX98925_R02A_DOUT_HIZ_CFG4 */
661#define M98925_DAI_SLOT_HIZ_CFG4_MASK (0xFF<<0)
662#define M98925_DAI_SLOT_HIZ_CFG4_SHIFT 0
663#define M98925_DAI_SLOT_HIZ_CFG4_WIDTH 8
664
665/* MAX98925_R02B_DOUT_DRV_STRENGTH */
666#define M98925_DAI_OUT_DRIVE_MASK (0x03<<0)
667#define M98925_DAI_OUT_DRIVE_SHIFT 0
668#define M98925_DAI_OUT_DRIVE_WIDTH 2
669
670/* MAX98925_R02C_FILTERS */
671#define M98925_ADC_DITHER_EN_MASK (1<<7)
672#define M98925_ADC_DITHER_EN_SHIFT 7
673#define M98925_ADC_DITHER_EN_WIDTH 1
674#define M98925_IV_DCB_EN_MASK (1<<6)
675#define M98925_IV_DCB_EN_SHIFT 6
676#define M98925_IV_DCB_EN_WIDTH 1
677#define M98925_DAC_DITHER_EN_MASK (1<<4)
678#define M98925_DAC_DITHER_EN_SHIFT 4
679#define M98925_DAC_DITHER_EN_WIDTH 1
680#define M98925_DAC_FILTER_MODE_MASK (1<<3)
681#define M98925_DAC_FILTER_MODE_SHIFT 3
682#define M98925_DAC_FILTER_MODE_WIDTH 1
683#define M98925_DAC_HPF_MASK (0x07<<0)
684#define M98925_DAC_HPF_SHIFT 0
685#define M98925_DAC_HPF_WIDTH 3
686#define M98925_DAC_HPF_DISABLE (0 << M98925_DAC_HPF_SHIFT)
687#define M98925_DAC_HPF_DC_BLOCK (1 << M98925_DAC_HPF_SHIFT)
688#define M98925_DAC_HPF_EN_100 (2 << M98925_DAC_HPF_SHIFT)
689#define M98925_DAC_HPF_EN_200 (3 << M98925_DAC_HPF_SHIFT)
690#define M98925_DAC_HPF_EN_400 (4 << M98925_DAC_HPF_SHIFT)
691#define M98925_DAC_HPF_EN_800 (5 << M98925_DAC_HPF_SHIFT)
692
693/* MAX98925_R02D_GAIN */
694#define M98925_DAC_IN_SEL_MASK (0x03<<5)
695#define M98925_DAC_IN_SEL_SHIFT 5
696#define M98925_DAC_IN_SEL_WIDTH 2
697#define M98925_SPK_GAIN_MASK (0x1F<<0)
698#define M98925_SPK_GAIN_SHIFT 0
699#define M98925_SPK_GAIN_WIDTH 5
700
701#define M98925_DAC_IN_SEL_LEFT_DAI (0 << M98925_DAC_IN_SEL_SHIFT)
702#define M98925_DAC_IN_SEL_RIGHT_DAI (1 << M98925_DAC_IN_SEL_SHIFT)
703#define M98925_DAC_IN_SEL_SUMMED_DAI (2 << M98925_DAC_IN_SEL_SHIFT)
704#define M98925_DAC_IN_SEL_DIV2_SUMMED_DAI (3 << M98925_DAC_IN_SEL_SHIFT)
705
706/* MAX98925_R02E_GAIN_RAMPING */
707#define M98925_SPK_RMP_EN_MASK (1<<1)
708#define M98925_SPK_RMP_EN_SHIFT 1
709#define M98925_SPK_RMP_EN_WIDTH 1
710#define M98925_SPK_ZCD_EN_MASK (1<<0)
711#define M98925_SPK_ZCD_EN_SHIFT 0
712#define M98925_SPK_ZCD_EN_WIDTH 1
713
714/* MAX98925_R02F_SPK_AMP */
715#define M98925_SPK_MODE_MASK (1<<0)
716#define M98925_SPK_MODE_SHIFT 0
717#define M98925_SPK_MODE_WIDTH 1
718
719/* MAX98925_R030_THRESHOLD */
720#define M98925_ALC_EN_MASK (1<<5)
721#define M98925_ALC_EN_SHIFT 5
722#define M98925_ALC_EN_WIDTH 1
723#define M98925_ALC_TH_MASK (0x1F<<0)
724#define M98925_ALC_TH_SHIFT 0
725#define M98925_ALC_TH_WIDTH 5
726
727/* MAX98925_R031_ALC_ATTACK */
728#define M98925_ALC_ATK_STEP_MASK (0x0F<<4)
729#define M98925_ALC_ATK_STEP_SHIFT 4
730#define M98925_ALC_ATK_STEP_WIDTH 4
731#define M98925_ALC_ATK_RATE_MASK (0x7<<0)
732#define M98925_ALC_ATK_RATE_SHIFT 0
733#define M98925_ALC_ATK_RATE_WIDTH 3
734
735/* MAX98925_R032_ALC_ATTEN_RLS */
736#define M98925_ALC_MAX_ATTEN_MASK (0x0F<<4)
737#define M98925_ALC_MAX_ATTEN_SHIFT 4
738#define M98925_ALC_MAX_ATTEN_WIDTH 4
739#define M98925_ALC_RLS_RATE_MASK (0x7<<0)
740#define M98925_ALC_RLS_RATE_SHIFT 0
741#define M98925_ALC_RLS_RATE_WIDTH 3
742
743/* MAX98925_R033_ALC_HOLD_RLS */
744#define M98925_ALC_RLS_TGR_MASK (1<<0)
745#define M98925_ALC_RLS_TGR_SHIFT 0
746#define M98925_ALC_RLS_TGR_WIDTH 1
747
748/* MAX98925_R034_ALC_CONFIGURATION */
749#define M98925_ALC_MUTE_EN_MASK (1<<7)
750#define M98925_ALC_MUTE_EN_SHIFT 7
751#define M98925_ALC_MUTE_EN_WIDTH 1
752#define M98925_ALC_MUTE_DLY_MASK (0x07<<4)
753#define M98925_ALC_MUTE_DLY_SHIFT 4
754#define M98925_ALC_MUTE_DLY_WIDTH 3
755#define M98925_ALC_RLS_DBT_MASK (0x07<<0)
756#define M98925_ALC_RLS_DBT_SHIFT 0
757#define M98925_ALC_RLS_DBT_WIDTH 3
758
759/* MAX98925_R035_BOOST_CONVERTER */
760#define M98925_BST_SYNC_MASK (1<<7)
761#define M98925_BST_SYNC_SHIFT 7
762#define M98925_BST_SYNC_WIDTH 1
763#define M98925_BST_PHASE_MASK (0x03<<4)
764#define M98925_BST_PHASE_SHIFT 4
765#define M98925_BST_PHASE_WIDTH 2
766#define M98925_BST_SKIP_MODE_MASK (0x03<<0)
767#define M98925_BST_SKIP_MODE_SHIFT 0
768#define M98925_BST_SKIP_MODE_WIDTH 2
769
770/* MAX98925_R036_BLOCK_ENABLE */
771#define M98925_BST_EN_MASK (1<<7)
772#define M98925_BST_EN_SHIFT 7
773#define M98925_BST_EN_WIDTH 1
774#define M98925_WATCH_EN_MASK (1<<6)
775#define M98925_WATCH_EN_SHIFT 6
776#define M98925_WATCH_EN_WIDTH 1
777#define M98925_CLKMON_EN_MASK (1<<5)
778#define M98925_CLKMON_EN_SHIFT 5
779#define M98925_CLKMON_EN_WIDTH 1
780#define M98925_SPK_EN_MASK (1<<4)
781#define M98925_SPK_EN_SHIFT 4
782#define M98925_SPK_EN_WIDTH 1
783#define M98925_ADC_VBST_EN_MASK (1<<3)
784#define M98925_ADC_VBST_EN_SHIFT 3
785#define M98925_ADC_VBST_EN_WIDTH 1
786#define M98925_ADC_VBAT_EN_MASK (1<<2)
787#define M98925_ADC_VBAT_EN_SHIFT 2
788#define M98925_ADC_VBAT_EN_WIDTH 1
789#define M98925_ADC_IMON_EN_MASK (1<<1)
790#define M98925_ADC_IMON_EN_SHIFT 1
791#define M98925_ADC_IMON_EN_WIDTH 1
792#define M98925_ADC_VMON_EN_MASK (1<<0)
793#define M98925_ADC_VMON_EN_SHIFT 0
794#define M98925_ADC_VMON_EN_WIDTH 1
795
796/* MAX98925_R037_CONFIGURATION */
797#define M98925_BST_VOUT_MASK (0x0F<<4)
798#define M98925_BST_VOUT_SHIFT 4
799#define M98925_BST_VOUT_WIDTH 4
800#define M98925_THERMWARN_LEVEL_MASK (0x03<<2)
801#define M98925_THERMWARN_LEVEL_SHIFT 2
802#define M98925_THERMWARN_LEVEL_WIDTH 2
803#define M98925_WATCH_TIME_MASK (0x03<<0)
804#define M98925_WATCH_TIME_SHIFT 0
805#define M98925_WATCH_TIME_WIDTH 2
806
807/* MAX98925_R038_GLOBAL_ENABLE */
808#define M98925_EN_MASK (1<<7)
809#define M98925_EN_SHIFT 7
810#define M98925_EN_WIDTH 1
811
812/* MAX98925_R03A_BOOST_LIMITER */
813#define M98925_BST_ILIM_MASK (0x1F<<3)
814#define M98925_BST_ILIM_SHIFT 3
815#define M98925_BST_ILIM_WIDTH 5
816
817/* MAX98925_R0FF_VERSION */
818#define M98925_REV_ID_MASK (0xFF<<0)
819#define M98925_REV_ID_SHIFT 0
820#define M98925_REV_ID_WIDTH 8
821
822struct max98925_priv {
823 struct regmap *regmap;
824 struct snd_soc_codec *codec;
825 struct max98925_pdata *pdata;
826 unsigned int sysclk;
827 unsigned int v_slot;
828 unsigned int i_slot;
829 unsigned int spk_gain;
830 unsigned int ch_size;
831};
832#endif
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
index 4b5f1fe9be97..5a30fdd0da00 100644
--- a/sound/soc/codecs/pcm512x.c
+++ b/sound/soc/codecs/pcm512x.c
@@ -391,9 +391,9 @@ static const struct soc_enum pcm512x_veds =
391static const struct snd_kcontrol_new pcm512x_controls[] = { 391static const struct snd_kcontrol_new pcm512x_controls[] = {
392SOC_DOUBLE_R_TLV("Digital Playback Volume", PCM512x_DIGITAL_VOLUME_2, 392SOC_DOUBLE_R_TLV("Digital Playback Volume", PCM512x_DIGITAL_VOLUME_2,
393 PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv), 393 PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv),
394SOC_DOUBLE_TLV("Playback Volume", PCM512x_ANALOG_GAIN_CTRL, 394SOC_DOUBLE_TLV("Analogue Playback Volume", PCM512x_ANALOG_GAIN_CTRL,
395 PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv), 395 PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv),
396SOC_DOUBLE_TLV("Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST, 396SOC_DOUBLE_TLV("Analogue Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST,
397 PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv), 397 PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv),
398SOC_DOUBLE("Digital Playback Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT, 398SOC_DOUBLE("Digital Playback Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT,
399 PCM512x_RQMR_SHIFT, 1, 1), 399 PCM512x_RQMR_SHIFT, 1, 1),
@@ -713,8 +713,8 @@ static int pcm512x_find_pll_coeff(struct snd_soc_dai *dai,
713 713
714 /* pllin_rate / P (or here, den) cannot be greater than 20 MHz */ 714 /* pllin_rate / P (or here, den) cannot be greater than 20 MHz */
715 if (pllin_rate / den > 20000000 && num < 8) { 715 if (pllin_rate / den > 20000000 && num < 8) {
716 num *= 20000000 / (pllin_rate / den); 716 num *= DIV_ROUND_UP(pllin_rate / den, 20000000);
717 den *= 20000000 / (pllin_rate / den); 717 den *= DIV_ROUND_UP(pllin_rate / den, 20000000);
718 } 718 }
719 dev_dbg(dev, "num / den = %lu / %lu\n", num, den); 719 dev_dbg(dev, "num / den = %lu / %lu\n", num, den);
720 720
@@ -1296,25 +1296,6 @@ static int pcm512x_hw_params(struct snd_pcm_substream *substream,
1296 ret, pcm512x->pll_out); 1296 ret, pcm512x->pll_out);
1297 return ret; 1297 return ret;
1298 } 1298 }
1299
1300 gpio = PCM512x_G1OE << (4 - 1);
1301 ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_EN,
1302 gpio, gpio);
1303 if (ret != 0) {
1304 dev_err(codec->dev, "Failed to enable gpio %d: %d\n",
1305 4, ret);
1306 return ret;
1307 }
1308
1309 gpio = PCM512x_GPIO_OUTPUT_1 + 4 - 1;
1310 ret = regmap_update_bits(pcm512x->regmap, gpio,
1311 PCM512x_GxSL, PCM512x_GxSL_PLLLK);
1312 if (ret != 0) {
1313 dev_err(codec->dev,
1314 "Failed to output pll lock on %d: %d\n",
1315 ret, 4);
1316 return ret;
1317 }
1318 } 1299 }
1319 1300
1320 ret = regmap_update_bits(pcm512x->regmap, PCM512x_SYNCHRONIZE, 1301 ret = regmap_update_bits(pcm512x->regmap, PCM512x_SYNCHRONIZE,
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index 826037090c83..0fcda35a3a93 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -397,7 +397,7 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
397 397
398 if (jack) { 398 if (jack) {
399 /* enable IRQ */ 399 /* enable IRQ */
400 if (rt286->jack->status | SND_JACK_HEADPHONE) 400 if (rt286->jack->status & SND_JACK_HEADPHONE)
401 snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO1"); 401 snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO1");
402 regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x2); 402 regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x2);
403 /* Send an initial empty report */ 403 /* Send an initial empty report */
@@ -1048,7 +1048,6 @@ static int rt286_probe(struct snd_soc_codec *codec)
1048 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec); 1048 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
1049 1049
1050 rt286->codec = codec; 1050 rt286->codec = codec;
1051 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
1052 1051
1053 if (rt286->i2c->irq) { 1052 if (rt286->i2c->irq) {
1054 regmap_update_bits(rt286->regmap, 1053 regmap_update_bits(rt286->regmap,
@@ -1220,7 +1219,7 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1220{ 1219{
1221 struct rt286_platform_data *pdata = dev_get_platdata(&i2c->dev); 1220 struct rt286_platform_data *pdata = dev_get_platdata(&i2c->dev);
1222 struct rt286_priv *rt286; 1221 struct rt286_priv *rt286;
1223 int i, ret; 1222 int i, ret, val;
1224 1223
1225 rt286 = devm_kzalloc(&i2c->dev, sizeof(*rt286), 1224 rt286 = devm_kzalloc(&i2c->dev, sizeof(*rt286),
1226 GFP_KERNEL); 1225 GFP_KERNEL);
@@ -1235,11 +1234,15 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1235 return ret; 1234 return ret;
1236 } 1235 }
1237 1236
1238 regmap_read(rt286->regmap, 1237 ret = regmap_read(rt286->regmap,
1239 RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &ret); 1238 RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &val);
1240 if (ret != RT286_VENDOR_ID && ret != RT288_VENDOR_ID) { 1239 if (ret != 0) {
1240 dev_err(&i2c->dev, "I2C error %d\n", ret);
1241 return ret;
1242 }
1243 if (val != RT286_VENDOR_ID && val != RT288_VENDOR_ID) {
1241 dev_err(&i2c->dev, 1244 dev_err(&i2c->dev,
1242 "Device with ID register %x is not rt286\n", ret); 1245 "Device with ID register %x is not rt286\n", val);
1243 return -ENODEV; 1246 return -ENODEV;
1244 } 1247 }
1245 1248
@@ -1247,6 +1250,14 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1247 rt286->i2c = i2c; 1250 rt286->i2c = i2c;
1248 i2c_set_clientdata(i2c, rt286); 1251 i2c_set_clientdata(i2c, rt286);
1249 1252
1253 /* restore codec default */
1254 for (i = 0; i < INDEX_CACHE_SIZE; i++)
1255 regmap_write(rt286->regmap, rt286->index_cache[i].reg,
1256 rt286->index_cache[i].def);
1257 for (i = 0; i < ARRAY_SIZE(rt286_reg); i++)
1258 regmap_write(rt286->regmap, rt286_reg[i].reg,
1259 rt286_reg[i].def);
1260
1250 if (pdata) 1261 if (pdata)
1251 rt286->pdata = *pdata; 1262 rt286->pdata = *pdata;
1252 1263
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c
index c61852742ee3..2c10d77727af 100644
--- a/sound/soc/codecs/rt5631.c
+++ b/sound/soc/codecs/rt5631.c
@@ -1675,7 +1675,7 @@ static const struct i2c_device_id rt5631_i2c_id[] = {
1675MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id); 1675MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id);
1676 1676
1677#ifdef CONFIG_OF 1677#ifdef CONFIG_OF
1678static struct of_device_id rt5631_i2c_dt_ids[] = { 1678static const struct of_device_id rt5631_i2c_dt_ids[] = {
1679 { .compatible = "realtek,rt5631"}, 1679 { .compatible = "realtek,rt5631"},
1680 { .compatible = "realtek,alc5631"}, 1680 { .compatible = "realtek,alc5631"},
1681 { } 1681 { }
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index c9a4c5be083b..69528ae5410c 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -1270,6 +1270,8 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on)
1270 snd_soc_update_bits(codec, RT5645_PWR_ANLG1, 1270 snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
1271 RT5645_PWR_HP_L | RT5645_PWR_HP_R | 1271 RT5645_PWR_HP_L | RT5645_PWR_HP_R |
1272 RT5645_PWR_HA, 0); 1272 RT5645_PWR_HA, 0);
1273 snd_soc_update_bits(codec, RT5645_DEPOP_M2,
1274 RT5645_DEPOP_MASK, 0);
1273 } 1275 }
1274 } 1276 }
1275} 1277}
@@ -1538,8 +1540,6 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = {
1538 1540
1539 SND_SOC_DAPM_SUPPLY_S("adc stereo1 filter", 1, RT5645_PWR_DIG2, 1541 SND_SOC_DAPM_SUPPLY_S("adc stereo1 filter", 1, RT5645_PWR_DIG2,
1540 RT5645_PWR_ADC_S1F_BIT, 0, NULL, 0), 1542 RT5645_PWR_ADC_S1F_BIT, 0, NULL, 0),
1541 SND_SOC_DAPM_SUPPLY_S("adc stereo2 filter", 1, RT5645_PWR_DIG2,
1542 RT5645_PWR_ADC_S2F_BIT, 0, NULL, 0),
1543 SND_SOC_DAPM_MIXER_E("Sto1 ADC MIXL", SND_SOC_NOPM, 0, 0, 1543 SND_SOC_DAPM_MIXER_E("Sto1 ADC MIXL", SND_SOC_NOPM, 0, 0,
1544 rt5645_sto1_adc_l_mix, ARRAY_SIZE(rt5645_sto1_adc_l_mix), 1544 rt5645_sto1_adc_l_mix, ARRAY_SIZE(rt5645_sto1_adc_l_mix),
1545 NULL, 0), 1545 NULL, 0),
@@ -1729,7 +1729,6 @@ static const struct snd_soc_dapm_widget rt5650_specific_dapm_widgets[] = {
1729 1729
1730static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { 1730static const struct snd_soc_dapm_route rt5645_dapm_routes[] = {
1731 { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc }, 1731 { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc },
1732 { "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc },
1733 { "adc mono left filter", NULL, "ADC MONO L ASRC", is_using_asrc }, 1732 { "adc mono left filter", NULL, "ADC MONO L ASRC", is_using_asrc },
1734 { "adc mono right filter", NULL, "ADC MONO R ASRC", is_using_asrc }, 1733 { "adc mono right filter", NULL, "ADC MONO R ASRC", is_using_asrc },
1735 { "dac mono left filter", NULL, "DAC MONO L ASRC", is_using_asrc }, 1734 { "dac mono left filter", NULL, "DAC MONO L ASRC", is_using_asrc },
@@ -2052,7 +2051,7 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream,
2052{ 2051{
2053 struct snd_soc_codec *codec = dai->codec; 2052 struct snd_soc_codec *codec = dai->codec;
2054 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); 2053 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
2055 unsigned int val_len = 0, val_clk, mask_clk; 2054 unsigned int val_len = 0, val_clk, mask_clk, dl_sft;
2056 int pre_div, bclk_ms, frame_size; 2055 int pre_div, bclk_ms, frame_size;
2057 2056
2058 rt5645->lrck[dai->id] = params_rate(params); 2057 rt5645->lrck[dai->id] = params_rate(params);
@@ -2066,6 +2065,16 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream,
2066 dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size); 2065 dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
2067 return -EINVAL; 2066 return -EINVAL;
2068 } 2067 }
2068
2069 switch (rt5645->codec_type) {
2070 case CODEC_TYPE_RT5650:
2071 dl_sft = 4;
2072 break;
2073 default:
2074 dl_sft = 2;
2075 break;
2076 }
2077
2069 bclk_ms = frame_size > 32; 2078 bclk_ms = frame_size > 32;
2070 rt5645->bclk[dai->id] = rt5645->lrck[dai->id] * (32 << bclk_ms); 2079 rt5645->bclk[dai->id] = rt5645->lrck[dai->id] * (32 << bclk_ms);
2071 2080
@@ -2078,13 +2087,13 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream,
2078 case 16: 2087 case 16:
2079 break; 2088 break;
2080 case 20: 2089 case 20:
2081 val_len |= RT5645_I2S_DL_20; 2090 val_len = 0x1;
2082 break; 2091 break;
2083 case 24: 2092 case 24:
2084 val_len |= RT5645_I2S_DL_24; 2093 val_len = 0x2;
2085 break; 2094 break;
2086 case 8: 2095 case 8:
2087 val_len |= RT5645_I2S_DL_8; 2096 val_len = 0x3;
2088 break; 2097 break;
2089 default: 2098 default:
2090 return -EINVAL; 2099 return -EINVAL;
@@ -2096,7 +2105,7 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream,
2096 val_clk = bclk_ms << RT5645_I2S_BCLK_MS1_SFT | 2105 val_clk = bclk_ms << RT5645_I2S_BCLK_MS1_SFT |
2097 pre_div << RT5645_I2S_PD1_SFT; 2106 pre_div << RT5645_I2S_PD1_SFT;
2098 snd_soc_update_bits(codec, RT5645_I2S1_SDP, 2107 snd_soc_update_bits(codec, RT5645_I2S1_SDP,
2099 RT5645_I2S_DL_MASK, val_len); 2108 (0x3 << dl_sft), (val_len << dl_sft));
2100 snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk); 2109 snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk);
2101 break; 2110 break;
2102 case RT5645_AIF2: 2111 case RT5645_AIF2:
@@ -2104,7 +2113,7 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream,
2104 val_clk = bclk_ms << RT5645_I2S_BCLK_MS2_SFT | 2113 val_clk = bclk_ms << RT5645_I2S_BCLK_MS2_SFT |
2105 pre_div << RT5645_I2S_PD2_SFT; 2114 pre_div << RT5645_I2S_PD2_SFT;
2106 snd_soc_update_bits(codec, RT5645_I2S2_SDP, 2115 snd_soc_update_bits(codec, RT5645_I2S2_SDP,
2107 RT5645_I2S_DL_MASK, val_len); 2116 (0x3 << dl_sft), (val_len << dl_sft));
2108 snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk); 2117 snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk);
2109 break; 2118 break;
2110 default: 2119 default:
@@ -2119,7 +2128,16 @@ static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2119{ 2128{
2120 struct snd_soc_codec *codec = dai->codec; 2129 struct snd_soc_codec *codec = dai->codec;
2121 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); 2130 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
2122 unsigned int reg_val = 0; 2131 unsigned int reg_val = 0, pol_sft;
2132
2133 switch (rt5645->codec_type) {
2134 case CODEC_TYPE_RT5650:
2135 pol_sft = 8;
2136 break;
2137 default:
2138 pol_sft = 7;
2139 break;
2140 }
2123 2141
2124 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 2142 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2125 case SND_SOC_DAIFMT_CBM_CFM: 2143 case SND_SOC_DAIFMT_CBM_CFM:
@@ -2137,7 +2155,7 @@ static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2137 case SND_SOC_DAIFMT_NB_NF: 2155 case SND_SOC_DAIFMT_NB_NF:
2138 break; 2156 break;
2139 case SND_SOC_DAIFMT_IB_NF: 2157 case SND_SOC_DAIFMT_IB_NF:
2140 reg_val |= RT5645_I2S_BP_INV; 2158 reg_val |= (1 << pol_sft);
2141 break; 2159 break;
2142 default: 2160 default:
2143 return -EINVAL; 2161 return -EINVAL;
@@ -2161,12 +2179,12 @@ static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2161 switch (dai->id) { 2179 switch (dai->id) {
2162 case RT5645_AIF1: 2180 case RT5645_AIF1:
2163 snd_soc_update_bits(codec, RT5645_I2S1_SDP, 2181 snd_soc_update_bits(codec, RT5645_I2S1_SDP,
2164 RT5645_I2S_MS_MASK | RT5645_I2S_BP_MASK | 2182 RT5645_I2S_MS_MASK | (1 << pol_sft) |
2165 RT5645_I2S_DF_MASK, reg_val); 2183 RT5645_I2S_DF_MASK, reg_val);
2166 break; 2184 break;
2167 case RT5645_AIF2: 2185 case RT5645_AIF2:
2168 snd_soc_update_bits(codec, RT5645_I2S2_SDP, 2186 snd_soc_update_bits(codec, RT5645_I2S2_SDP,
2169 RT5645_I2S_MS_MASK | RT5645_I2S_BP_MASK | 2187 RT5645_I2S_MS_MASK | (1 << pol_sft) |
2170 RT5645_I2S_DF_MASK, reg_val); 2188 RT5645_I2S_DF_MASK, reg_val);
2171 break; 2189 break;
2172 default: 2190 default:
@@ -2285,23 +2303,42 @@ static int rt5645_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
2285 unsigned int rx_mask, int slots, int slot_width) 2303 unsigned int rx_mask, int slots, int slot_width)
2286{ 2304{
2287 struct snd_soc_codec *codec = dai->codec; 2305 struct snd_soc_codec *codec = dai->codec;
2288 unsigned int val = 0; 2306 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
2307 unsigned int i_slot_sft, o_slot_sft, i_width_sht, o_width_sht, en_sft;
2308 unsigned int mask, val = 0;
2289 2309
2310 switch (rt5645->codec_type) {
2311 case CODEC_TYPE_RT5650:
2312 en_sft = 15;
2313 i_slot_sft = 10;
2314 o_slot_sft = 8;
2315 i_width_sht = 6;
2316 o_width_sht = 4;
2317 mask = 0x8ff0;
2318 break;
2319 default:
2320 en_sft = 14;
2321 i_slot_sft = o_slot_sft = 12;
2322 i_width_sht = o_width_sht = 10;
2323 mask = 0x7c00;
2324 break;
2325 }
2290 if (rx_mask || tx_mask) { 2326 if (rx_mask || tx_mask) {
2291 val |= (1 << 14); 2327 val |= (1 << en_sft);
2292 snd_soc_update_bits(codec, RT5645_BASS_BACK, 2328 if (rt5645->codec_type == CODEC_TYPE_RT5645)
2293 RT5645_G_BB_BST_MASK, RT5645_G_BB_BST_25DB); 2329 snd_soc_update_bits(codec, RT5645_BASS_BACK,
2330 RT5645_G_BB_BST_MASK, RT5645_G_BB_BST_25DB);
2294 } 2331 }
2295 2332
2296 switch (slots) { 2333 switch (slots) {
2297 case 4: 2334 case 4:
2298 val |= (1 << 12); 2335 val |= (1 << i_slot_sft) | (1 << o_slot_sft);
2299 break; 2336 break;
2300 case 6: 2337 case 6:
2301 val |= (2 << 12); 2338 val |= (2 << i_slot_sft) | (2 << o_slot_sft);
2302 break; 2339 break;
2303 case 8: 2340 case 8:
2304 val |= (3 << 12); 2341 val |= (3 << i_slot_sft) | (3 << o_slot_sft);
2305 break; 2342 break;
2306 case 2: 2343 case 2:
2307 default: 2344 default:
@@ -2310,20 +2347,20 @@ static int rt5645_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
2310 2347
2311 switch (slot_width) { 2348 switch (slot_width) {
2312 case 20: 2349 case 20:
2313 val |= (1 << 10); 2350 val |= (1 << i_width_sht) | (1 << o_width_sht);
2314 break; 2351 break;
2315 case 24: 2352 case 24:
2316 val |= (2 << 10); 2353 val |= (2 << i_width_sht) | (2 << o_width_sht);
2317 break; 2354 break;
2318 case 32: 2355 case 32:
2319 val |= (3 << 10); 2356 val |= (3 << i_width_sht) | (3 << o_width_sht);
2320 break; 2357 break;
2321 case 16: 2358 case 16:
2322 default: 2359 default:
2323 break; 2360 break;
2324 } 2361 }
2325 2362
2326 snd_soc_update_bits(codec, RT5645_TDM_CTRL_1, 0x7c00, val); 2363 snd_soc_update_bits(codec, RT5645_TDM_CTRL_1, mask, val);
2327 2364
2328 return 0; 2365 return 0;
2329} 2366}
@@ -2361,7 +2398,8 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec,
2361 2398
2362 case SND_SOC_BIAS_OFF: 2399 case SND_SOC_BIAS_OFF:
2363 snd_soc_write(codec, RT5645_DEPOP_M2, 0x1100); 2400 snd_soc_write(codec, RT5645_DEPOP_M2, 0x1100);
2364 snd_soc_write(codec, RT5645_GEN_CTRL1, 0x0128); 2401 snd_soc_update_bits(codec, RT5645_GEN_CTRL1,
2402 RT5645_DIG_GATE_CTRL, 0);
2365 snd_soc_update_bits(codec, RT5645_PWR_ANLG1, 2403 snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
2366 RT5645_PWR_VREF1 | RT5645_PWR_MB | 2404 RT5645_PWR_VREF1 | RT5645_PWR_MB |
2367 RT5645_PWR_BG | RT5645_PWR_VREF2 | 2405 RT5645_PWR_BG | RT5645_PWR_VREF2 |
@@ -2598,7 +2636,7 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5645 = {
2598static const struct regmap_config rt5645_regmap = { 2636static const struct regmap_config rt5645_regmap = {
2599 .reg_bits = 8, 2637 .reg_bits = 8,
2600 .val_bits = 16, 2638 .val_bits = 16,
2601 2639 .use_single_rw = true,
2602 .max_register = RT5645_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5645_ranges) * 2640 .max_register = RT5645_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5645_ranges) *
2603 RT5645_PR_SPACING), 2641 RT5645_PR_SPACING),
2604 .volatile_reg = rt5645_volatile_register, 2642 .volatile_reg = rt5645_volatile_register,
diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h
index dbfd98c22f4d..db78e9462876 100644
--- a/sound/soc/codecs/rt5645.h
+++ b/sound/soc/codecs/rt5645.h
@@ -804,8 +804,6 @@
804#define RT5645_PWR_DAC_MF_L_BIT 10 804#define RT5645_PWR_DAC_MF_L_BIT 10
805#define RT5645_PWR_DAC_MF_R (0x1 << 9) 805#define RT5645_PWR_DAC_MF_R (0x1 << 9)
806#define RT5645_PWR_DAC_MF_R_BIT 9 806#define RT5645_PWR_DAC_MF_R_BIT 9
807#define RT5645_PWR_ADC_S2F (0x1 << 8)
808#define RT5645_PWR_ADC_S2F_BIT 8
809#define RT5645_PWR_PDM1 (0x1 << 7) 807#define RT5645_PWR_PDM1 (0x1 << 7)
810#define RT5645_PWR_PDM1_BIT 7 808#define RT5645_PWR_PDM1_BIT 7
811#define RT5645_PWR_PDM2 (0x1 << 6) 809#define RT5645_PWR_PDM2 (0x1 << 6)
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
index fd102613d20d..cc7f84a150a7 100644
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -403,6 +403,189 @@ static bool rt5670_readable_register(struct device *dev, unsigned int reg)
403 } 403 }
404} 404}
405 405
406/**
407 * rt5670_headset_detect - Detect headset.
408 * @codec: SoC audio codec device.
409 * @jack_insert: Jack insert or not.
410 *
411 * Detect whether is headset or not when jack inserted.
412 *
413 * Returns detect status.
414 */
415
416static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert)
417{
418 int val;
419 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
420
421 if (jack_insert) {
422 snd_soc_dapm_force_enable_pin(&codec->dapm,
423 "Mic Det Power");
424 snd_soc_dapm_sync(&codec->dapm);
425 snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x0);
426 snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
427 RT5670_CBJ_DET_MODE | RT5670_CBJ_MN_JD,
428 RT5670_CBJ_MN_JD);
429 snd_soc_write(codec, RT5670_GPIO_CTRL2, 0x0004);
430 snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
431 RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ);
432 snd_soc_update_bits(codec, RT5670_CJ_CTRL1,
433 RT5670_CBJ_BST1_EN, RT5670_CBJ_BST1_EN);
434 snd_soc_write(codec, RT5670_JD_CTRL3, 0x00f0);
435 snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
436 RT5670_CBJ_MN_JD, RT5670_CBJ_MN_JD);
437 snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
438 RT5670_CBJ_MN_JD, 0);
439 msleep(300);
440 val = snd_soc_read(codec, RT5670_CJ_CTRL3) & 0x7;
441 if (val == 0x1 || val == 0x2) {
442 rt5670->jack_type = SND_JACK_HEADSET;
443 /* for push button */
444 snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x8);
445 snd_soc_update_bits(codec, RT5670_IL_CMD, 0x40, 0x40);
446 snd_soc_read(codec, RT5670_IL_CMD);
447 } else {
448 snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
449 rt5670->jack_type = SND_JACK_HEADPHONE;
450 snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power");
451 snd_soc_dapm_sync(&codec->dapm);
452 }
453 } else {
454 snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x0);
455 snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
456 rt5670->jack_type = 0;
457 snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power");
458 snd_soc_dapm_sync(&codec->dapm);
459 }
460
461 return rt5670->jack_type;
462}
463
464void rt5670_jack_suspend(struct snd_soc_codec *codec)
465{
466 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
467
468 rt5670->jack_type_saved = rt5670->jack_type;
469 rt5670_headset_detect(codec, 0);
470}
471EXPORT_SYMBOL_GPL(rt5670_jack_suspend);
472
473void rt5670_jack_resume(struct snd_soc_codec *codec)
474{
475 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
476
477 if (rt5670->jack_type_saved)
478 rt5670_headset_detect(codec, 1);
479}
480EXPORT_SYMBOL_GPL(rt5670_jack_resume);
481
482static int rt5670_button_detect(struct snd_soc_codec *codec)
483{
484 int btn_type, val;
485
486 val = snd_soc_read(codec, RT5670_IL_CMD);
487 btn_type = val & 0xff80;
488 snd_soc_write(codec, RT5670_IL_CMD, val);
489 if (btn_type != 0) {
490 msleep(20);
491 val = snd_soc_read(codec, RT5670_IL_CMD);
492 snd_soc_write(codec, RT5670_IL_CMD, val);
493 }
494
495 return btn_type;
496}
497
498static int rt5670_irq_detection(void *data)
499{
500 struct rt5670_priv *rt5670 = (struct rt5670_priv *)data;
501 struct snd_soc_jack_gpio *gpio = &rt5670->hp_gpio;
502 struct snd_soc_jack *jack = rt5670->jack;
503 int val, btn_type, report = jack->status;
504
505 if (rt5670->pdata.jd_mode == 1) /* 2 port */
506 val = snd_soc_read(rt5670->codec, RT5670_A_JD_CTRL1) & 0x0070;
507 else
508 val = snd_soc_read(rt5670->codec, RT5670_A_JD_CTRL1) & 0x0020;
509
510 switch (val) {
511 /* jack in */
512 case 0x30: /* 2 port */
513 case 0x0: /* 1 port or 2 port */
514 if (rt5670->jack_type == 0) {
515 report = rt5670_headset_detect(rt5670->codec, 1);
516 /* for push button and jack out */
517 gpio->debounce_time = 25;
518 break;
519 }
520 btn_type = 0;
521 if (snd_soc_read(rt5670->codec, RT5670_INT_IRQ_ST) & 0x4) {
522 /* button pressed */
523 report = SND_JACK_HEADSET;
524 btn_type = rt5670_button_detect(rt5670->codec);
525 switch (btn_type) {
526 case 0x2000: /* up */
527 report |= SND_JACK_BTN_1;
528 break;
529 case 0x0400: /* center */
530 report |= SND_JACK_BTN_0;
531 break;
532 case 0x0080: /* down */
533 report |= SND_JACK_BTN_2;
534 break;
535 default:
536 dev_err(rt5670->codec->dev,
537 "Unexpected button code 0x%04x\n",
538 btn_type);
539 break;
540 }
541 }
542 if (btn_type == 0)/* button release */
543 report = rt5670->jack_type;
544
545 break;
546 /* jack out */
547 case 0x70: /* 2 port */
548 case 0x10: /* 2 port */
549 case 0x20: /* 1 port */
550 report = 0;
551 snd_soc_update_bits(rt5670->codec, RT5670_INT_IRQ_ST, 0x1, 0x0);
552 rt5670_headset_detect(rt5670->codec, 0);
553 gpio->debounce_time = 150; /* for jack in */
554 break;
555 default:
556 break;
557 }
558
559 return report;
560}
561
562int rt5670_set_jack_detect(struct snd_soc_codec *codec,
563 struct snd_soc_jack *jack)
564{
565 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
566 int ret;
567
568 rt5670->jack = jack;
569 rt5670->hp_gpio.gpiod_dev = codec->dev;
570 rt5670->hp_gpio.name = "headphone detect";
571 rt5670->hp_gpio.report = SND_JACK_HEADSET |
572 SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2;
573 rt5670->hp_gpio.debounce_time = 150;
574 rt5670->hp_gpio.wake = true;
575 rt5670->hp_gpio.data = (struct rt5670_priv *)rt5670;
576 rt5670->hp_gpio.jack_status_check = rt5670_irq_detection;
577
578 ret = snd_soc_jack_add_gpios(rt5670->jack, 1,
579 &rt5670->hp_gpio);
580 if (ret) {
581 dev_err(codec->dev, "Adding jack GPIO failed\n");
582 return ret;
583 }
584
585 return 0;
586}
587EXPORT_SYMBOL_GPL(rt5670_set_jack_detect);
588
406static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); 589static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
407static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); 590static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
408static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); 591static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
@@ -517,11 +700,9 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
517 struct snd_soc_dapm_widget *sink) 700 struct snd_soc_dapm_widget *sink)
518{ 701{
519 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); 702 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
520 unsigned int val; 703 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
521 704
522 val = snd_soc_read(codec, RT5670_GLB_CLK); 705 if (rt5670->sysclk_src == RT5670_SCLK_S_PLL1)
523 val &= RT5670_SCLK_SRC_MASK;
524 if (val == RT5670_SCLK_SRC_PLL1)
525 return 1; 706 return 1;
526 else 707 else
527 return 0; 708 return 0;
@@ -2271,16 +2452,6 @@ static int rt5670_set_dai_sysclk(struct snd_soc_dai *dai,
2271 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); 2452 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
2272 unsigned int reg_val = 0; 2453 unsigned int reg_val = 0;
2273 2454
2274 if (freq == rt5670->sysclk && clk_id == rt5670->sysclk_src)
2275 return 0;
2276
2277 if (rt5670->pdata.jd_mode) {
2278 if (clk_id == RT5670_SCLK_S_PLL1)
2279 snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1");
2280 else
2281 snd_soc_dapm_disable_pin(&codec->dapm, "PLL1");
2282 snd_soc_dapm_sync(&codec->dapm);
2283 }
2284 switch (clk_id) { 2455 switch (clk_id) {
2285 case RT5670_SCLK_S_MCLK: 2456 case RT5670_SCLK_S_MCLK:
2286 reg_val |= RT5670_SCLK_SRC_MCLK; 2457 reg_val |= RT5670_SCLK_SRC_MCLK;
@@ -2298,7 +2469,8 @@ static int rt5670_set_dai_sysclk(struct snd_soc_dai *dai,
2298 snd_soc_update_bits(codec, RT5670_GLB_CLK, 2469 snd_soc_update_bits(codec, RT5670_GLB_CLK,
2299 RT5670_SCLK_SRC_MASK, reg_val); 2470 RT5670_SCLK_SRC_MASK, reg_val);
2300 rt5670->sysclk = freq; 2471 rt5670->sysclk = freq;
2301 rt5670->sysclk_src = clk_id; 2472 if (clk_id != RT5670_SCLK_S_RCCLK)
2473 rt5670->sysclk_src = clk_id;
2302 2474
2303 dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); 2475 dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
2304 2476
@@ -2517,6 +2689,7 @@ static int rt5670_remove(struct snd_soc_codec *codec)
2517 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); 2689 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
2518 2690
2519 regmap_write(rt5670->regmap, RT5670_RESET, 0); 2691 regmap_write(rt5670->regmap, RT5670_RESET, 0);
2692 snd_soc_jack_free_gpios(rt5670->jack, 1, &rt5670->hp_gpio);
2520 return 0; 2693 return 0;
2521} 2694}
2522 2695
@@ -2676,6 +2849,7 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
2676 if (dmi_check_system(dmi_platform_intel_braswell)) { 2849 if (dmi_check_system(dmi_platform_intel_braswell)) {
2677 rt5670->pdata.dmic_en = true; 2850 rt5670->pdata.dmic_en = true;
2678 rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P; 2851 rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P;
2852 rt5670->pdata.dev_gpio = true;
2679 rt5670->pdata.jd_mode = 1; 2853 rt5670->pdata.jd_mode = 1;
2680 } 2854 }
2681 2855
@@ -2717,12 +2891,17 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
2717 regmap_update_bits(rt5670->regmap, RT5670_IN2, 2891 regmap_update_bits(rt5670->regmap, RT5670_IN2,
2718 RT5670_IN_DF2, RT5670_IN_DF2); 2892 RT5670_IN_DF2, RT5670_IN_DF2);
2719 2893
2720 if (i2c->irq) { 2894 if (rt5670->pdata.dev_gpio) {
2895 /* for push button */
2896 regmap_write(rt5670->regmap, RT5670_IL_CMD, 0x0000);
2897 regmap_write(rt5670->regmap, RT5670_IL_CMD2, 0x0010);
2898 regmap_write(rt5670->regmap, RT5670_IL_CMD3, 0x0014);
2899 /* for irq */
2721 regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1, 2900 regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1,
2722 RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ); 2901 RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ);
2723 regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2, 2902 regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
2724 RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT); 2903 RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT);
2725 2904 regmap_update_bits(rt5670->regmap, RT5670_DIG_MISC, 0x8, 0x8);
2726 } 2905 }
2727 2906
2728 if (rt5670->pdata.jd_mode) { 2907 if (rt5670->pdata.jd_mode) {
diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h
index 0a67adbcfbc3..dc2b46236c5c 100644
--- a/sound/soc/codecs/rt5670.h
+++ b/sound/soc/codecs/rt5670.h
@@ -1988,6 +1988,8 @@ struct rt5670_priv {
1988 struct snd_soc_codec *codec; 1988 struct snd_soc_codec *codec;
1989 struct rt5670_platform_data pdata; 1989 struct rt5670_platform_data pdata;
1990 struct regmap *regmap; 1990 struct regmap *regmap;
1991 struct snd_soc_jack *jack;
1992 struct snd_soc_jack_gpio hp_gpio;
1991 1993
1992 int sysclk; 1994 int sysclk;
1993 int sysclk_src; 1995 int sysclk_src;
@@ -2002,6 +2004,11 @@ struct rt5670_priv {
2002 int dsp_sw; /* expected parameter setting */ 2004 int dsp_sw; /* expected parameter setting */
2003 int dsp_rate; 2005 int dsp_rate;
2004 int jack_type; 2006 int jack_type;
2007 int jack_type_saved;
2005}; 2008};
2006 2009
2010void rt5670_jack_suspend(struct snd_soc_codec *codec);
2011void rt5670_jack_resume(struct snd_soc_codec *codec);
2012int rt5670_set_jack_detect(struct snd_soc_codec *codec,
2013 struct snd_soc_jack *jack);
2007#endif /* __RT5670_H__ */ 2014#endif /* __RT5670_H__ */
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index c2a6e4091357..af182586712d 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -1034,6 +1034,169 @@ static int can_use_asrc(struct snd_soc_dapm_widget *source,
1034 return 0; 1034 return 0;
1035} 1035}
1036 1036
1037/**
1038 * rt5677_sel_asrc_clk_src - select ASRC clock source for a set of filters
1039 * @codec: SoC audio codec device.
1040 * @filter_mask: mask of filters.
1041 * @clk_src: clock source
1042 *
1043 * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5677 can
1044 * only support standard 32fs or 64fs i2s format, ASRC should be enabled to
1045 * support special i2s clock format such as Intel's 100fs(100 * sampling rate).
1046 * ASRC function will track i2s clock and generate a corresponding system clock
1047 * for codec. This function provides an API to select the clock source for a
1048 * set of filters specified by the mask. And the codec driver will turn on ASRC
1049 * for these filters if ASRC is selected as their clock source.
1050 */
1051int rt5677_sel_asrc_clk_src(struct snd_soc_codec *codec,
1052 unsigned int filter_mask, unsigned int clk_src)
1053{
1054 struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
1055 unsigned int asrc3_mask = 0, asrc3_value = 0;
1056 unsigned int asrc4_mask = 0, asrc4_value = 0;
1057 unsigned int asrc5_mask = 0, asrc5_value = 0;
1058 unsigned int asrc6_mask = 0, asrc6_value = 0;
1059 unsigned int asrc7_mask = 0, asrc7_value = 0;
1060
1061 switch (clk_src) {
1062 case RT5677_CLK_SEL_SYS:
1063 case RT5677_CLK_SEL_I2S1_ASRC:
1064 case RT5677_CLK_SEL_I2S2_ASRC:
1065 case RT5677_CLK_SEL_I2S3_ASRC:
1066 case RT5677_CLK_SEL_I2S4_ASRC:
1067 case RT5677_CLK_SEL_I2S5_ASRC:
1068 case RT5677_CLK_SEL_I2S6_ASRC:
1069 case RT5677_CLK_SEL_SYS2:
1070 case RT5677_CLK_SEL_SYS3:
1071 case RT5677_CLK_SEL_SYS4:
1072 case RT5677_CLK_SEL_SYS5:
1073 case RT5677_CLK_SEL_SYS6:
1074 case RT5677_CLK_SEL_SYS7:
1075 break;
1076
1077 default:
1078 return -EINVAL;
1079 }
1080
1081 /* ASRC 3 */
1082 if (filter_mask & RT5677_DA_STEREO_FILTER) {
1083 asrc3_mask |= RT5677_DA_STO_CLK_SEL_MASK;
1084 asrc3_value = (asrc3_value & ~RT5677_DA_STO_CLK_SEL_MASK)
1085 | (clk_src << RT5677_DA_STO_CLK_SEL_SFT);
1086 }
1087
1088 if (filter_mask & RT5677_DA_MONO2_L_FILTER) {
1089 asrc3_mask |= RT5677_DA_MONO2L_CLK_SEL_MASK;
1090 asrc3_value = (asrc3_value & ~RT5677_DA_MONO2L_CLK_SEL_MASK)
1091 | (clk_src << RT5677_DA_MONO2L_CLK_SEL_SFT);
1092 }
1093
1094 if (filter_mask & RT5677_DA_MONO2_R_FILTER) {
1095 asrc3_mask |= RT5677_DA_MONO2R_CLK_SEL_MASK;
1096 asrc3_value = (asrc3_value & ~RT5677_DA_MONO2R_CLK_SEL_MASK)
1097 | (clk_src << RT5677_DA_MONO2R_CLK_SEL_SFT);
1098 }
1099
1100 if (asrc3_mask)
1101 regmap_update_bits(rt5677->regmap, RT5677_ASRC_3, asrc3_mask,
1102 asrc3_value);
1103
1104 /* ASRC 4 */
1105 if (filter_mask & RT5677_DA_MONO3_L_FILTER) {
1106 asrc4_mask |= RT5677_DA_MONO3L_CLK_SEL_MASK;
1107 asrc4_value = (asrc4_value & ~RT5677_DA_MONO3L_CLK_SEL_MASK)
1108 | (clk_src << RT5677_DA_MONO3L_CLK_SEL_SFT);
1109 }
1110
1111 if (filter_mask & RT5677_DA_MONO3_R_FILTER) {
1112 asrc4_mask |= RT5677_DA_MONO3R_CLK_SEL_MASK;
1113 asrc4_value = (asrc4_value & ~RT5677_DA_MONO3R_CLK_SEL_MASK)
1114 | (clk_src << RT5677_DA_MONO3R_CLK_SEL_SFT);
1115 }
1116
1117 if (filter_mask & RT5677_DA_MONO4_L_FILTER) {
1118 asrc4_mask |= RT5677_DA_MONO4L_CLK_SEL_MASK;
1119 asrc4_value = (asrc4_value & ~RT5677_DA_MONO4L_CLK_SEL_MASK)
1120 | (clk_src << RT5677_DA_MONO4L_CLK_SEL_SFT);
1121 }
1122
1123 if (filter_mask & RT5677_DA_MONO4_R_FILTER) {
1124 asrc4_mask |= RT5677_DA_MONO4R_CLK_SEL_MASK;
1125 asrc4_value = (asrc4_value & ~RT5677_DA_MONO4R_CLK_SEL_MASK)
1126 | (clk_src << RT5677_DA_MONO4R_CLK_SEL_SFT);
1127 }
1128
1129 if (asrc4_mask)
1130 regmap_update_bits(rt5677->regmap, RT5677_ASRC_4, asrc4_mask,
1131 asrc4_value);
1132
1133 /* ASRC 5 */
1134 if (filter_mask & RT5677_AD_STEREO1_FILTER) {
1135 asrc5_mask |= RT5677_AD_STO1_CLK_SEL_MASK;
1136 asrc5_value = (asrc5_value & ~RT5677_AD_STO1_CLK_SEL_MASK)
1137 | (clk_src << RT5677_AD_STO1_CLK_SEL_SFT);
1138 }
1139
1140 if (filter_mask & RT5677_AD_STEREO2_FILTER) {
1141 asrc5_mask |= RT5677_AD_STO2_CLK_SEL_MASK;
1142 asrc5_value = (asrc5_value & ~RT5677_AD_STO2_CLK_SEL_MASK)
1143 | (clk_src << RT5677_AD_STO2_CLK_SEL_SFT);
1144 }
1145
1146 if (filter_mask & RT5677_AD_STEREO3_FILTER) {
1147 asrc5_mask |= RT5677_AD_STO3_CLK_SEL_MASK;
1148 asrc5_value = (asrc5_value & ~RT5677_AD_STO3_CLK_SEL_MASK)
1149 | (clk_src << RT5677_AD_STO3_CLK_SEL_SFT);
1150 }
1151
1152 if (filter_mask & RT5677_AD_STEREO4_FILTER) {
1153 asrc5_mask |= RT5677_AD_STO4_CLK_SEL_MASK;
1154 asrc5_value = (asrc5_value & ~RT5677_AD_STO4_CLK_SEL_MASK)
1155 | (clk_src << RT5677_AD_STO4_CLK_SEL_SFT);
1156 }
1157
1158 if (asrc5_mask)
1159 regmap_update_bits(rt5677->regmap, RT5677_ASRC_5, asrc5_mask,
1160 asrc5_value);
1161
1162 /* ASRC 6 */
1163 if (filter_mask & RT5677_AD_MONO_L_FILTER) {
1164 asrc6_mask |= RT5677_AD_MONOL_CLK_SEL_MASK;
1165 asrc6_value = (asrc6_value & ~RT5677_AD_MONOL_CLK_SEL_MASK)
1166 | (clk_src << RT5677_AD_MONOL_CLK_SEL_SFT);
1167 }
1168
1169 if (filter_mask & RT5677_AD_MONO_R_FILTER) {
1170 asrc6_mask |= RT5677_AD_MONOR_CLK_SEL_MASK;
1171 asrc6_value = (asrc6_value & ~RT5677_AD_MONOR_CLK_SEL_MASK)
1172 | (clk_src << RT5677_AD_MONOR_CLK_SEL_SFT);
1173 }
1174
1175 if (asrc6_mask)
1176 regmap_update_bits(rt5677->regmap, RT5677_ASRC_6, asrc6_mask,
1177 asrc6_value);
1178
1179 /* ASRC 7 */
1180 if (filter_mask & RT5677_DSP_OB_0_3_FILTER) {
1181 asrc7_mask |= RT5677_DSP_OB_0_3_CLK_SEL_MASK;
1182 asrc7_value = (asrc7_value & ~RT5677_DSP_OB_0_3_CLK_SEL_MASK)
1183 | (clk_src << RT5677_DSP_OB_0_3_CLK_SEL_SFT);
1184 }
1185
1186 if (filter_mask & RT5677_DSP_OB_4_7_FILTER) {
1187 asrc7_mask |= RT5677_DSP_OB_4_7_CLK_SEL_MASK;
1188 asrc7_value = (asrc7_value & ~RT5677_DSP_OB_4_7_CLK_SEL_MASK)
1189 | (clk_src << RT5677_DSP_OB_4_7_CLK_SEL_SFT);
1190 }
1191
1192 if (asrc7_mask)
1193 regmap_update_bits(rt5677->regmap, RT5677_ASRC_7, asrc7_mask,
1194 asrc7_value);
1195
1196 return 0;
1197}
1198EXPORT_SYMBOL_GPL(rt5677_sel_asrc_clk_src);
1199
1037/* Digital Mixer */ 1200/* Digital Mixer */
1038static const struct snd_kcontrol_new rt5677_sto1_adc_l_mix[] = { 1201static const struct snd_kcontrol_new rt5677_sto1_adc_l_mix[] = {
1039 SOC_DAPM_SINGLE("ADC1 Switch", RT5677_STO1_ADC_MIXER, 1202 SOC_DAPM_SINGLE("ADC1 Switch", RT5677_STO1_ADC_MIXER,
diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h
index 07df96b43f59..9dceb41d18ea 100644
--- a/sound/soc/codecs/rt5677.h
+++ b/sound/soc/codecs/rt5677.h
@@ -1406,6 +1406,46 @@
1406#define RT5677_DSP_CLK_SRC_PLL2 (0x0 << 7) 1406#define RT5677_DSP_CLK_SRC_PLL2 (0x0 << 7)
1407#define RT5677_DSP_CLK_SRC_BYPASS (0x1 << 7) 1407#define RT5677_DSP_CLK_SRC_BYPASS (0x1 << 7)
1408 1408
1409/* ASRC Control 3 (0x85) */
1410#define RT5677_DA_STO_CLK_SEL_MASK (0xf << 12)
1411#define RT5677_DA_STO_CLK_SEL_SFT 12
1412#define RT5677_DA_MONO2L_CLK_SEL_MASK (0xf << 4)
1413#define RT5677_DA_MONO2L_CLK_SEL_SFT 4
1414#define RT5677_DA_MONO2R_CLK_SEL_MASK (0xf << 0)
1415#define RT5677_DA_MONO2R_CLK_SEL_SFT 0
1416
1417/* ASRC Control 4 (0x86) */
1418#define RT5677_DA_MONO3L_CLK_SEL_MASK (0xf << 12)
1419#define RT5677_DA_MONO3L_CLK_SEL_SFT 12
1420#define RT5677_DA_MONO3R_CLK_SEL_MASK (0xf << 8)
1421#define RT5677_DA_MONO3R_CLK_SEL_SFT 8
1422#define RT5677_DA_MONO4L_CLK_SEL_MASK (0xf << 4)
1423#define RT5677_DA_MONO4L_CLK_SEL_SFT 4
1424#define RT5677_DA_MONO4R_CLK_SEL_MASK (0xf << 0)
1425#define RT5677_DA_MONO4R_CLK_SEL_SFT 0
1426
1427/* ASRC Control 5 (0x87) */
1428#define RT5677_AD_STO1_CLK_SEL_MASK (0xf << 12)
1429#define RT5677_AD_STO1_CLK_SEL_SFT 12
1430#define RT5677_AD_STO2_CLK_SEL_MASK (0xf << 8)
1431#define RT5677_AD_STO2_CLK_SEL_SFT 8
1432#define RT5677_AD_STO3_CLK_SEL_MASK (0xf << 4)
1433#define RT5677_AD_STO3_CLK_SEL_SFT 4
1434#define RT5677_AD_STO4_CLK_SEL_MASK (0xf << 0)
1435#define RT5677_AD_STO4_CLK_SEL_SFT 0
1436
1437/* ASRC Control 6 (0x88) */
1438#define RT5677_AD_MONOL_CLK_SEL_MASK (0xf << 12)
1439#define RT5677_AD_MONOL_CLK_SEL_SFT 12
1440#define RT5677_AD_MONOR_CLK_SEL_MASK (0xf << 8)
1441#define RT5677_AD_MONOR_CLK_SEL_SFT 8
1442
1443/* ASRC Control 7 (0x89) */
1444#define RT5677_DSP_OB_0_3_CLK_SEL_MASK (0xf << 12)
1445#define RT5677_DSP_OB_0_3_CLK_SEL_SFT 12
1446#define RT5677_DSP_OB_4_7_CLK_SEL_MASK (0xf << 8)
1447#define RT5677_DSP_OB_4_7_CLK_SEL_SFT 8
1448
1409/* VAD Function Control 4 (0x9f) */ 1449/* VAD Function Control 4 (0x9f) */
1410#define RT5677_VAD_SRC_MASK (0x7 << 8) 1450#define RT5677_VAD_SRC_MASK (0x7 << 8)
1411#define RT5677_VAD_SRC_SFT 8 1451#define RT5677_VAD_SRC_SFT 8
@@ -1670,6 +1710,42 @@ enum rt5677_type {
1670 RT5676, 1710 RT5676,
1671}; 1711};
1672 1712
1713/* ASRC clock source selection */
1714enum {
1715 RT5677_CLK_SEL_SYS,
1716 RT5677_CLK_SEL_I2S1_ASRC,
1717 RT5677_CLK_SEL_I2S2_ASRC,
1718 RT5677_CLK_SEL_I2S3_ASRC,
1719 RT5677_CLK_SEL_I2S4_ASRC,
1720 RT5677_CLK_SEL_I2S5_ASRC,
1721 RT5677_CLK_SEL_I2S6_ASRC,
1722 RT5677_CLK_SEL_SYS2,
1723 RT5677_CLK_SEL_SYS3,
1724 RT5677_CLK_SEL_SYS4,
1725 RT5677_CLK_SEL_SYS5,
1726 RT5677_CLK_SEL_SYS6,
1727 RT5677_CLK_SEL_SYS7,
1728};
1729
1730/* filter mask */
1731enum {
1732 RT5677_DA_STEREO_FILTER = 0x1,
1733 RT5677_DA_MONO2_L_FILTER = (0x1 << 1),
1734 RT5677_DA_MONO2_R_FILTER = (0x1 << 2),
1735 RT5677_DA_MONO3_L_FILTER = (0x1 << 3),
1736 RT5677_DA_MONO3_R_FILTER = (0x1 << 4),
1737 RT5677_DA_MONO4_L_FILTER = (0x1 << 5),
1738 RT5677_DA_MONO4_R_FILTER = (0x1 << 6),
1739 RT5677_AD_STEREO1_FILTER = (0x1 << 7),
1740 RT5677_AD_STEREO2_FILTER = (0x1 << 8),
1741 RT5677_AD_STEREO3_FILTER = (0x1 << 9),
1742 RT5677_AD_STEREO4_FILTER = (0x1 << 10),
1743 RT5677_AD_MONO_L_FILTER = (0x1 << 11),
1744 RT5677_AD_MONO_R_FILTER = (0x1 << 12),
1745 RT5677_DSP_OB_0_3_FILTER = (0x1 << 13),
1746 RT5677_DSP_OB_4_7_FILTER = (0x1 << 14),
1747};
1748
1673struct rt5677_priv { 1749struct rt5677_priv {
1674 struct snd_soc_codec *codec; 1750 struct snd_soc_codec *codec;
1675 struct rt5677_platform_data pdata; 1751 struct rt5677_platform_data pdata;
@@ -1696,4 +1772,7 @@ struct rt5677_priv {
1696 bool is_vref_slow; 1772 bool is_vref_slow;
1697}; 1773};
1698 1774
1775int rt5677_sel_asrc_clk_src(struct snd_soc_codec *codec,
1776 unsigned int filter_mask, unsigned int clk_src);
1777
1699#endif /* __RT5677_H__ */ 1778#endif /* __RT5677_H__ */
diff --git a/sound/soc/codecs/tlv320aic23-i2c.c b/sound/soc/codecs/tlv320aic23-i2c.c
index f13701995482..78a94af65518 100644
--- a/sound/soc/codecs/tlv320aic23-i2c.c
+++ b/sound/soc/codecs/tlv320aic23-i2c.c
@@ -31,7 +31,7 @@ static int tlv320aic23_i2c_probe(struct i2c_client *i2c,
31 return tlv320aic23_probe(&i2c->dev, regmap); 31 return tlv320aic23_probe(&i2c->dev, regmap);
32} 32}
33 33
34static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c) 34static int tlv320aic23_i2c_remove(struct i2c_client *i2c)
35{ 35{
36 snd_soc_unregister_codec(&i2c->dev); 36 snd_soc_unregister_codec(&i2c->dev);
37 return 0; 37 return 0;
@@ -56,7 +56,7 @@ static struct i2c_driver tlv320aic23_i2c_driver = {
56 .of_match_table = of_match_ptr(tlv320aic23_of_match), 56 .of_match_table = of_match_ptr(tlv320aic23_of_match),
57 }, 57 },
58 .probe = tlv320aic23_i2c_probe, 58 .probe = tlv320aic23_i2c_probe,
59 .remove = __exit_p(tlv320aic23_i2c_remove), 59 .remove = tlv320aic23_i2c_remove,
60 .id_table = tlv320aic23_id, 60 .id_table = tlv320aic23_id,
61}; 61};
62 62
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
index 15599845a660..5a9da28f4f33 100644
--- a/sound/soc/codecs/wm2200.c
+++ b/sound/soc/codecs/wm2200.c
@@ -1554,7 +1554,6 @@ static int wm2200_probe(struct snd_soc_codec *codec)
1554 int ret; 1554 int ret;
1555 1555
1556 wm2200->codec = codec; 1556 wm2200->codec = codec;
1557 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
1558 1557
1559 ret = snd_soc_add_codec_controls(codec, wm_adsp1_fw_controls, 2); 1558 ret = snd_soc_add_codec_controls(codec, wm_adsp1_fw_controls, 2);
1560 if (ret != 0) 1559 if (ret != 0)
@@ -1942,6 +1941,7 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1942 struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec); 1941 struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
1943 struct _fll_div factors; 1942 struct _fll_div factors;
1944 int ret, i, timeout; 1943 int ret, i, timeout;
1944 unsigned long time_left;
1945 1945
1946 if (!Fout) { 1946 if (!Fout) {
1947 dev_dbg(codec->dev, "FLL disabled"); 1947 dev_dbg(codec->dev, "FLL disabled");
@@ -2021,9 +2021,10 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2021 /* Poll for the lock; will use the interrupt to exit quickly */ 2021 /* Poll for the lock; will use the interrupt to exit quickly */
2022 for (i = 0; i < timeout; i++) { 2022 for (i = 0; i < timeout; i++) {
2023 if (i2c->irq) { 2023 if (i2c->irq) {
2024 ret = wait_for_completion_timeout(&wm2200->fll_lock, 2024 time_left = wait_for_completion_timeout(
2025 msecs_to_jiffies(25)); 2025 &wm2200->fll_lock,
2026 if (ret > 0) 2026 msecs_to_jiffies(25));
2027 if (time_left > 0)
2027 break; 2028 break;
2028 } else { 2029 } else {
2029 msleep(1); 2030 msleep(1);
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index ea09db585aa1..96740379b711 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -1762,6 +1762,7 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1762 struct _fll_div factors; 1762 struct _fll_div factors;
1763 struct wm5100_fll *fll; 1763 struct wm5100_fll *fll;
1764 int ret, base, lock, i, timeout; 1764 int ret, base, lock, i, timeout;
1765 unsigned long time_left;
1765 1766
1766 switch (fll_id) { 1767 switch (fll_id) {
1767 case WM5100_FLL1: 1768 case WM5100_FLL1:
@@ -1842,9 +1843,9 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1842 /* Poll for the lock; will use interrupt when we can test */ 1843 /* Poll for the lock; will use interrupt when we can test */
1843 for (i = 0; i < timeout; i++) { 1844 for (i = 0; i < timeout; i++) {
1844 if (i2c->irq) { 1845 if (i2c->irq) {
1845 ret = wait_for_completion_timeout(&fll->lock, 1846 time_left = wait_for_completion_timeout(&fll->lock,
1846 msecs_to_jiffies(25)); 1847 msecs_to_jiffies(25));
1847 if (ret > 0) 1848 if (time_left > 0)
1848 break; 1849 break;
1849 } else { 1850 } else {
1850 msleep(1); 1851 msleep(1);
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index 6d0fe0ac95a3..0c6d1bc0526e 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -1861,7 +1861,6 @@ static unsigned int wm5102_digital_vu[] = {
1861 ARIZONA_DAC_DIGITAL_VOLUME_2L, 1861 ARIZONA_DAC_DIGITAL_VOLUME_2L,
1862 ARIZONA_DAC_DIGITAL_VOLUME_2R, 1862 ARIZONA_DAC_DIGITAL_VOLUME_2R,
1863 ARIZONA_DAC_DIGITAL_VOLUME_3L, 1863 ARIZONA_DAC_DIGITAL_VOLUME_3L,
1864 ARIZONA_DAC_DIGITAL_VOLUME_3R,
1865 ARIZONA_DAC_DIGITAL_VOLUME_4L, 1864 ARIZONA_DAC_DIGITAL_VOLUME_4L,
1866 ARIZONA_DAC_DIGITAL_VOLUME_4R, 1865 ARIZONA_DAC_DIGITAL_VOLUME_4R,
1867 ARIZONA_DAC_DIGITAL_VOLUME_5L, 1866 ARIZONA_DAC_DIGITAL_VOLUME_5L,
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index c81a9eab3e3e..c65e5a75fc1a 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -69,14 +69,14 @@ struct wm8350_data {
69 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; 69 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
70 int fll_freq_out; 70 int fll_freq_out;
71 int fll_freq_in; 71 int fll_freq_in;
72 struct delayed_work pga_work;
72}; 73};
73 74
74/* 75/*
75 * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown. 76 * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown.
76 */ 77 */
77static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec) 78static inline int wm8350_out1_ramp_step(struct wm8350_data *wm8350_data)
78{ 79{
79 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
80 struct wm8350_output *out1 = &wm8350_data->out1; 80 struct wm8350_output *out1 = &wm8350_data->out1;
81 struct wm8350 *wm8350 = wm8350_data->wm8350; 81 struct wm8350 *wm8350 = wm8350_data->wm8350;
82 int left_complete = 0, right_complete = 0; 82 int left_complete = 0, right_complete = 0;
@@ -140,9 +140,8 @@ static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec)
140/* 140/*
141 * Ramp OUT2 PGA volume to minimise pops at stream startup and shutdown. 141 * Ramp OUT2 PGA volume to minimise pops at stream startup and shutdown.
142 */ 142 */
143static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec) 143static inline int wm8350_out2_ramp_step(struct wm8350_data *wm8350_data)
144{ 144{
145 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
146 struct wm8350_output *out2 = &wm8350_data->out2; 145 struct wm8350_output *out2 = &wm8350_data->out2;
147 struct wm8350 *wm8350 = wm8350_data->wm8350; 146 struct wm8350 *wm8350 = wm8350_data->wm8350;
148 int left_complete = 0, right_complete = 0; 147 int left_complete = 0, right_complete = 0;
@@ -210,10 +209,8 @@ static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec)
210 */ 209 */
211static void wm8350_pga_work(struct work_struct *work) 210static void wm8350_pga_work(struct work_struct *work)
212{ 211{
213 struct snd_soc_dapm_context *dapm = 212 struct wm8350_data *wm8350_data =
214 container_of(work, struct snd_soc_dapm_context, delayed_work.work); 213 container_of(work, struct wm8350_data, pga_work.work);
215 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
216 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
217 struct wm8350_output *out1 = &wm8350_data->out1, 214 struct wm8350_output *out1 = &wm8350_data->out1,
218 *out2 = &wm8350_data->out2; 215 *out2 = &wm8350_data->out2;
219 int i, out1_complete, out2_complete; 216 int i, out1_complete, out2_complete;
@@ -226,9 +223,9 @@ static void wm8350_pga_work(struct work_struct *work)
226 for (i = 0; i <= 63; i++) { 223 for (i = 0; i <= 63; i++) {
227 out1_complete = 1, out2_complete = 1; 224 out1_complete = 1, out2_complete = 1;
228 if (out1->ramp != WM8350_RAMP_NONE) 225 if (out1->ramp != WM8350_RAMP_NONE)
229 out1_complete = wm8350_out1_ramp_step(codec); 226 out1_complete = wm8350_out1_ramp_step(wm8350_data);
230 if (out2->ramp != WM8350_RAMP_NONE) 227 if (out2->ramp != WM8350_RAMP_NONE)
231 out2_complete = wm8350_out2_ramp_step(codec); 228 out2_complete = wm8350_out2_ramp_step(wm8350_data);
232 229
233 /* ramp finished ? */ 230 /* ramp finished ? */
234 if (out1_complete && out2_complete) 231 if (out1_complete && out2_complete)
@@ -283,7 +280,7 @@ static int pga_event(struct snd_soc_dapm_widget *w,
283 out->ramp = WM8350_RAMP_UP; 280 out->ramp = WM8350_RAMP_UP;
284 out->active = 1; 281 out->active = 1;
285 282
286 schedule_delayed_work(&codec->dapm.delayed_work, 283 schedule_delayed_work(&wm8350_data->pga_work,
287 msecs_to_jiffies(1)); 284 msecs_to_jiffies(1));
288 break; 285 break;
289 286
@@ -291,7 +288,7 @@ static int pga_event(struct snd_soc_dapm_widget *w,
291 out->ramp = WM8350_RAMP_DOWN; 288 out->ramp = WM8350_RAMP_DOWN;
292 out->active = 0; 289 out->active = 0;
293 290
294 schedule_delayed_work(&codec->dapm.delayed_work, 291 schedule_delayed_work(&wm8350_data->pga_work,
295 msecs_to_jiffies(1)); 292 msecs_to_jiffies(1));
296 break; 293 break;
297 } 294 }
@@ -1492,7 +1489,7 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec)
1492 /* Put the codec into reset if it wasn't already */ 1489 /* Put the codec into reset if it wasn't already */
1493 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1490 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1494 1491
1495 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8350_pga_work); 1492 INIT_DELAYED_WORK(&priv->pga_work, wm8350_pga_work);
1496 INIT_DELAYED_WORK(&priv->hpl.work, wm8350_hpl_work); 1493 INIT_DELAYED_WORK(&priv->hpl.work, wm8350_hpl_work);
1497 INIT_DELAYED_WORK(&priv->hpr.work, wm8350_hpr_work); 1494 INIT_DELAYED_WORK(&priv->hpr.work, wm8350_hpr_work);
1498 1495
@@ -1578,7 +1575,7 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec)
1578 1575
1579 /* if there was any work waiting then we run it now and 1576 /* if there was any work waiting then we run it now and
1580 * wait for its completion */ 1577 * wait for its completion */
1581 flush_delayed_work(&codec->dapm.delayed_work); 1578 flush_delayed_work(&priv->pga_work);
1582 1579
1583 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1580 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1584 1581
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index c6d10533e2bd..2245b6a32f3d 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -25,6 +25,7 @@
25#include <linux/spi/spi.h> 25#include <linux/spi/spi.h>
26#include <linux/of_device.h> 26#include <linux/of_device.h>
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <linux/clk.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include <sound/pcm.h> 30#include <sound/pcm.h>
30#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
@@ -45,6 +46,7 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
45/* codec private data */ 46/* codec private data */
46struct wm8731_priv { 47struct wm8731_priv {
47 struct regmap *regmap; 48 struct regmap *regmap;
49 struct clk *mclk;
48 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; 50 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
49 const struct snd_pcm_hw_constraint_list *constraints; 51 const struct snd_pcm_hw_constraint_list *constraints;
50 unsigned int sysclk; 52 unsigned int sysclk;
@@ -390,6 +392,8 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
390 switch (clk_id) { 392 switch (clk_id) {
391 case WM8731_SYSCLK_XTAL: 393 case WM8731_SYSCLK_XTAL:
392 case WM8731_SYSCLK_MCLK: 394 case WM8731_SYSCLK_MCLK:
395 if (wm8731->mclk && clk_set_rate(wm8731->mclk, freq))
396 return -EINVAL;
393 wm8731->sysclk_type = clk_id; 397 wm8731->sysclk_type = clk_id;
394 break; 398 break;
395 default: 399 default:
@@ -491,6 +495,8 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
491 495
492 switch (level) { 496 switch (level) {
493 case SND_SOC_BIAS_ON: 497 case SND_SOC_BIAS_ON:
498 if (wm8731->mclk)
499 clk_prepare_enable(wm8731->mclk);
494 break; 500 break;
495 case SND_SOC_BIAS_PREPARE: 501 case SND_SOC_BIAS_PREPARE:
496 break; 502 break;
@@ -509,6 +515,8 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
509 snd_soc_write(codec, WM8731_PWR, reg | 0x0040); 515 snd_soc_write(codec, WM8731_PWR, reg | 0x0040);
510 break; 516 break;
511 case SND_SOC_BIAS_OFF: 517 case SND_SOC_BIAS_OFF:
518 if (wm8731->mclk)
519 clk_disable_unprepare(wm8731->mclk);
512 snd_soc_write(codec, WM8731_PWR, 0xffff); 520 snd_soc_write(codec, WM8731_PWR, 0xffff);
513 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), 521 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
514 wm8731->supplies); 522 wm8731->supplies);
@@ -667,6 +675,19 @@ static int wm8731_spi_probe(struct spi_device *spi)
667 if (wm8731 == NULL) 675 if (wm8731 == NULL)
668 return -ENOMEM; 676 return -ENOMEM;
669 677
678 wm8731->mclk = devm_clk_get(&spi->dev, "mclk");
679 if (IS_ERR(wm8731->mclk)) {
680 ret = PTR_ERR(wm8731->mclk);
681 if (ret == -ENOENT) {
682 wm8731->mclk = NULL;
683 dev_warn(&spi->dev, "Assuming static MCLK\n");
684 } else {
685 dev_err(&spi->dev, "Failed to get MCLK: %d\n",
686 ret);
687 return ret;
688 }
689 }
690
670 mutex_init(&wm8731->lock); 691 mutex_init(&wm8731->lock);
671 692
672 wm8731->regmap = devm_regmap_init_spi(spi, &wm8731_regmap); 693 wm8731->regmap = devm_regmap_init_spi(spi, &wm8731_regmap);
@@ -718,6 +739,19 @@ static int wm8731_i2c_probe(struct i2c_client *i2c,
718 if (wm8731 == NULL) 739 if (wm8731 == NULL)
719 return -ENOMEM; 740 return -ENOMEM;
720 741
742 wm8731->mclk = devm_clk_get(&i2c->dev, "mclk");
743 if (IS_ERR(wm8731->mclk)) {
744 ret = PTR_ERR(wm8731->mclk);
745 if (ret == -ENOENT) {
746 wm8731->mclk = NULL;
747 dev_warn(&i2c->dev, "Assuming static MCLK\n");
748 } else {
749 dev_err(&i2c->dev, "Failed to get MCLK: %d\n",
750 ret);
751 return ret;
752 }
753 }
754
721 mutex_init(&wm8731->lock); 755 mutex_init(&wm8731->lock);
722 756
723 wm8731->regmap = devm_regmap_init_i2c(i2c, &wm8731_regmap); 757 wm8731->regmap = devm_regmap_init_i2c(i2c, &wm8731_regmap);
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 31bb4801a005..9e71c768966f 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -123,7 +123,7 @@ static struct {
123}; 123};
124 124
125static const unsigned int rates_11289[] = { 125static const unsigned int rates_11289[] = {
126 44100, 88235, 126 44100, 88200,
127}; 127};
128 128
129static const struct snd_pcm_hw_constraint_list constraints_11289 = { 129static const struct snd_pcm_hw_constraint_list constraints_11289 = {
@@ -150,7 +150,7 @@ static const struct snd_pcm_hw_constraint_list constraints_16384 = {
150}; 150};
151 151
152static const unsigned int rates_16934[] = { 152static const unsigned int rates_16934[] = {
153 44100, 88235, 153 44100, 88200,
154}; 154};
155 155
156static const struct snd_pcm_hw_constraint_list constraints_16934 = { 156static const struct snd_pcm_hw_constraint_list constraints_16934 = {
@@ -168,7 +168,7 @@ static const struct snd_pcm_hw_constraint_list constraints_18432 = {
168}; 168};
169 169
170static const unsigned int rates_22579[] = { 170static const unsigned int rates_22579[] = {
171 44100, 88235, 1764000 171 44100, 88200, 176400
172}; 172};
173 173
174static const struct snd_pcm_hw_constraint_list constraints_22579 = { 174static const struct snd_pcm_hw_constraint_list constraints_22579 = {
@@ -186,7 +186,7 @@ static const struct snd_pcm_hw_constraint_list constraints_24576 = {
186}; 186};
187 187
188static const unsigned int rates_36864[] = { 188static const unsigned int rates_36864[] = {
189 48000, 96000, 19200 189 48000, 96000, 192000
190}; 190};
191 191
192static const struct snd_pcm_hw_constraint_list constraints_36864 = { 192static const struct snd_pcm_hw_constraint_list constraints_36864 = {
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 21ca3a94fc96..c50a5959345f 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -153,6 +153,7 @@ struct wm8753_priv {
153 unsigned int hifi_fmt; 153 unsigned int hifi_fmt;
154 154
155 int dai_func; 155 int dai_func;
156 struct delayed_work charge_work;
156}; 157};
157 158
158#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0) 159#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
@@ -1326,9 +1327,19 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
1326 return 0; 1327 return 0;
1327} 1328}
1328 1329
1330static void wm8753_charge_work(struct work_struct *work)
1331{
1332 struct wm8753_priv *wm8753 =
1333 container_of(work, struct wm8753_priv, charge_work.work);
1334
1335 /* Set to 500k */
1336 regmap_update_bits(wm8753->regmap, WM8753_PWR1, 0x0180, 0x0100);
1337}
1338
1329static int wm8753_set_bias_level(struct snd_soc_codec *codec, 1339static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1330 enum snd_soc_bias_level level) 1340 enum snd_soc_bias_level level)
1331{ 1341{
1342 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1332 u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e; 1343 u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e;
1333 1344
1334 switch (level) { 1345 switch (level) {
@@ -1337,14 +1348,22 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1337 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0); 1348 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
1338 break; 1349 break;
1339 case SND_SOC_BIAS_PREPARE: 1350 case SND_SOC_BIAS_PREPARE:
1340 /* set vmid to 5k for quick power up */ 1351 /* Wait until fully charged */
1341 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1); 1352 flush_delayed_work(&wm8753->charge_work);
1342 break; 1353 break;
1343 case SND_SOC_BIAS_STANDBY: 1354 case SND_SOC_BIAS_STANDBY:
1344 /* mute dac and set vmid to 500k, enable VREF */ 1355 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1345 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141); 1356 /* set vmid to 5k for quick power up */
1357 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
1358 schedule_delayed_work(&wm8753->charge_work,
1359 msecs_to_jiffies(caps_charge));
1360 } else {
1361 /* mute dac and set vmid to 500k, enable VREF */
1362 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
1363 }
1346 break; 1364 break;
1347 case SND_SOC_BIAS_OFF: 1365 case SND_SOC_BIAS_OFF:
1366 cancel_delayed_work_sync(&wm8753->charge_work);
1348 snd_soc_write(codec, WM8753_PWR1, 0x0001); 1367 snd_soc_write(codec, WM8753_PWR1, 0x0001);
1349 break; 1368 break;
1350 } 1369 }
@@ -1428,38 +1447,12 @@ static struct snd_soc_dai_driver wm8753_dai[] = {
1428}, 1447},
1429}; 1448};
1430 1449
1431static void wm8753_work(struct work_struct *work)
1432{
1433 struct snd_soc_dapm_context *dapm =
1434 container_of(work, struct snd_soc_dapm_context,
1435 delayed_work.work);
1436 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
1437 wm8753_set_bias_level(codec, dapm->bias_level);
1438}
1439
1440static int wm8753_suspend(struct snd_soc_codec *codec)
1441{
1442 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1443 return 0;
1444}
1445
1446static int wm8753_resume(struct snd_soc_codec *codec) 1450static int wm8753_resume(struct snd_soc_codec *codec)
1447{ 1451{
1448 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 1452 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1449 1453
1450 regcache_sync(wm8753->regmap); 1454 regcache_sync(wm8753->regmap);
1451 1455
1452 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1453
1454 /* charge wm8753 caps */
1455 if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
1456 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1457 codec->dapm.bias_level = SND_SOC_BIAS_ON;
1458 queue_delayed_work(system_power_efficient_wq,
1459 &codec->dapm.delayed_work,
1460 msecs_to_jiffies(caps_charge));
1461 }
1462
1463 return 0; 1456 return 0;
1464} 1457}
1465 1458
@@ -1468,7 +1461,7 @@ static int wm8753_probe(struct snd_soc_codec *codec)
1468 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 1461 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1469 int ret; 1462 int ret;
1470 1463
1471 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work); 1464 INIT_DELAYED_WORK(&wm8753->charge_work, wm8753_charge_work);
1472 1465
1473 ret = wm8753_reset(codec); 1466 ret = wm8753_reset(codec);
1474 if (ret < 0) { 1467 if (ret < 0) {
@@ -1476,14 +1469,8 @@ static int wm8753_probe(struct snd_soc_codec *codec)
1476 return ret; 1469 return ret;
1477 } 1470 }
1478 1471
1479 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1480 wm8753->dai_func = 0; 1472 wm8753->dai_func = 0;
1481 1473
1482 /* charge output caps */
1483 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1484 schedule_delayed_work(&codec->dapm.delayed_work,
1485 msecs_to_jiffies(caps_charge));
1486
1487 /* set the update bits */ 1474 /* set the update bits */
1488 snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100); 1475 snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
1489 snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100); 1476 snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
@@ -1499,21 +1486,11 @@ static int wm8753_probe(struct snd_soc_codec *codec)
1499 return 0; 1486 return 0;
1500} 1487}
1501 1488
1502/* power down chip */
1503static int wm8753_remove(struct snd_soc_codec *codec)
1504{
1505 flush_delayed_work(&codec->dapm.delayed_work);
1506 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1507
1508 return 0;
1509}
1510
1511static struct snd_soc_codec_driver soc_codec_dev_wm8753 = { 1489static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
1512 .probe = wm8753_probe, 1490 .probe = wm8753_probe,
1513 .remove = wm8753_remove,
1514 .suspend = wm8753_suspend,
1515 .resume = wm8753_resume, 1491 .resume = wm8753_resume,
1516 .set_bias_level = wm8753_set_bias_level, 1492 .set_bias_level = wm8753_set_bias_level,
1493 .suspend_bias_off = true,
1517 1494
1518 .controls = wm8753_snd_controls, 1495 .controls = wm8753_snd_controls,
1519 .num_controls = ARRAY_SIZE(wm8753_snd_controls), 1496 .num_controls = ARRAY_SIZE(wm8753_snd_controls),
diff --git a/sound/soc/codecs/wm8804-i2c.c b/sound/soc/codecs/wm8804-i2c.c
index 5bd4af2b4059..6596f5f3a0c3 100644
--- a/sound/soc/codecs/wm8804-i2c.c
+++ b/sound/soc/codecs/wm8804-i2c.c
@@ -50,6 +50,7 @@ static struct i2c_driver wm8804_i2c_driver = {
50 .driver = { 50 .driver = {
51 .name = "wm8804", 51 .name = "wm8804",
52 .owner = THIS_MODULE, 52 .owner = THIS_MODULE,
53 .pm = &wm8804_pm,
53 .of_match_table = wm8804_of_match, 54 .of_match_table = wm8804_of_match,
54 }, 55 },
55 .probe = wm8804_i2c_probe, 56 .probe = wm8804_i2c_probe,
diff --git a/sound/soc/codecs/wm8804-spi.c b/sound/soc/codecs/wm8804-spi.c
index 287e11e90794..407a3cf391e5 100644
--- a/sound/soc/codecs/wm8804-spi.c
+++ b/sound/soc/codecs/wm8804-spi.c
@@ -43,6 +43,7 @@ static struct spi_driver wm8804_spi_driver = {
43 .driver = { 43 .driver = {
44 .name = "wm8804", 44 .name = "wm8804",
45 .owner = THIS_MODULE, 45 .owner = THIS_MODULE,
46 .pm = &wm8804_pm,
46 .of_match_table = wm8804_of_match, 47 .of_match_table = wm8804_of_match,
47 }, 48 },
48 .probe = wm8804_spi_probe, 49 .probe = wm8804_spi_probe,
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 1bd4ace29594..1e403f67cf16 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -13,8 +13,10 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/moduleparam.h> 14#include <linux/moduleparam.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/gpio/consumer.h>
16#include <linux/delay.h> 17#include <linux/delay.h>
17#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/pm_runtime.h>
18#include <linux/of_device.h> 20#include <linux/of_device.h>
19#include <linux/regulator/consumer.h> 21#include <linux/regulator/consumer.h>
20#include <linux/slab.h> 22#include <linux/slab.h>
@@ -24,6 +26,7 @@
24#include <sound/soc.h> 26#include <sound/soc.h>
25#include <sound/initval.h> 27#include <sound/initval.h>
26#include <sound/tlv.h> 28#include <sound/tlv.h>
29#include <sound/soc-dapm.h>
27 30
28#include "wm8804.h" 31#include "wm8804.h"
29 32
@@ -57,18 +60,23 @@ static const struct reg_default wm8804_reg_defaults[] = {
57}; 60};
58 61
59struct wm8804_priv { 62struct wm8804_priv {
63 struct device *dev;
60 struct regmap *regmap; 64 struct regmap *regmap;
61 struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES]; 65 struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES];
62 struct notifier_block disable_nb[WM8804_NUM_SUPPLIES]; 66 struct notifier_block disable_nb[WM8804_NUM_SUPPLIES];
63 int mclk_div; 67 int mclk_div;
64};
65 68
66static int txsrc_get(struct snd_kcontrol *kcontrol, 69 struct gpio_desc *reset;
67 struct snd_ctl_elem_value *ucontrol); 70
71 int aif_pwr;
72};
68 73
69static int txsrc_put(struct snd_kcontrol *kcontrol, 74static int txsrc_put(struct snd_kcontrol *kcontrol,
70 struct snd_ctl_elem_value *ucontrol); 75 struct snd_ctl_elem_value *ucontrol);
71 76
77static int wm8804_aif_event(struct snd_soc_dapm_widget *w,
78 struct snd_kcontrol *kcontrol, int event);
79
72/* 80/*
73 * We can't use the same notifier block for more than one supply and 81 * We can't use the same notifier block for more than one supply and
74 * there's no way I can see to get from a callback to the caller 82 * there's no way I can see to get from a callback to the caller
@@ -90,26 +98,62 @@ WM8804_REGULATOR_EVENT(0)
90WM8804_REGULATOR_EVENT(1) 98WM8804_REGULATOR_EVENT(1)
91 99
92static const char *txsrc_text[] = { "S/PDIF RX", "AIF" }; 100static const char *txsrc_text[] = { "S/PDIF RX", "AIF" };
93static SOC_ENUM_SINGLE_EXT_DECL(txsrc, txsrc_text); 101static const SOC_ENUM_SINGLE_DECL(txsrc, WM8804_SPDTX4, 6, txsrc_text);
94 102
95static const struct snd_kcontrol_new wm8804_snd_controls[] = { 103static const struct snd_kcontrol_new wm8804_tx_source_mux[] = {
96 SOC_ENUM_EXT("Input Source", txsrc, txsrc_get, txsrc_put), 104 SOC_DAPM_ENUM_EXT("Input Source", txsrc,
97 SOC_SINGLE("TX Playback Switch", WM8804_PWRDN, 2, 1, 1), 105 snd_soc_dapm_get_enum_double, txsrc_put),
98 SOC_SINGLE("AIF Playback Switch", WM8804_PWRDN, 4, 1, 1)
99}; 106};
100 107
101static int txsrc_get(struct snd_kcontrol *kcontrol, 108static const struct snd_soc_dapm_widget wm8804_dapm_widgets[] = {
102 struct snd_ctl_elem_value *ucontrol) 109SND_SOC_DAPM_OUTPUT("SPDIF Out"),
103{ 110SND_SOC_DAPM_INPUT("SPDIF In"),
104 struct snd_soc_codec *codec; 111
105 unsigned int src; 112SND_SOC_DAPM_PGA("SPDIFTX", WM8804_PWRDN, 2, 1, NULL, 0),
113SND_SOC_DAPM_PGA("SPDIFRX", WM8804_PWRDN, 1, 1, NULL, 0),
114
115SND_SOC_DAPM_MUX("Tx Source", SND_SOC_NOPM, 6, 0, wm8804_tx_source_mux),
116
117SND_SOC_DAPM_AIF_OUT_E("AIFTX", NULL, 0, SND_SOC_NOPM, 0, 0, wm8804_aif_event,
118 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
119SND_SOC_DAPM_AIF_IN_E("AIFRX", NULL, 0, SND_SOC_NOPM, 0, 0, wm8804_aif_event,
120 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
121};
122
123static const struct snd_soc_dapm_route wm8804_dapm_routes[] = {
124 { "AIFRX", NULL, "Playback" },
125 { "Tx Source", "AIF", "AIFRX" },
126
127 { "SPDIFRX", NULL, "SPDIF In" },
128 { "Tx Source", "S/PDIF RX", "SPDIFRX" },
106 129
107 codec = snd_soc_kcontrol_codec(kcontrol); 130 { "SPDIFTX", NULL, "Tx Source" },
108 src = snd_soc_read(codec, WM8804_SPDTX4); 131 { "SPDIF Out", NULL, "SPDIFTX" },
109 if (src & 0x40) 132
110 ucontrol->value.integer.value[0] = 1; 133 { "AIFTX", NULL, "SPDIFRX" },
111 else 134 { "Capture", NULL, "AIFTX" },
112 ucontrol->value.integer.value[0] = 0; 135};
136
137static int wm8804_aif_event(struct snd_soc_dapm_widget *w,
138 struct snd_kcontrol *kcontrol, int event)
139{
140 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
141 struct wm8804_priv *wm8804 = snd_soc_codec_get_drvdata(codec);
142
143 switch (event) {
144 case SND_SOC_DAPM_POST_PMU:
145 /* power up the aif */
146 if (!wm8804->aif_pwr)
147 snd_soc_update_bits(codec, WM8804_PWRDN, 0x10, 0x0);
148 wm8804->aif_pwr++;
149 break;
150 case SND_SOC_DAPM_POST_PMD:
151 /* power down only both paths are disabled */
152 wm8804->aif_pwr--;
153 if (!wm8804->aif_pwr)
154 snd_soc_update_bits(codec, WM8804_PWRDN, 0x10, 0x10);
155 break;
156 }
113 157
114 return 0; 158 return 0;
115} 159}
@@ -117,48 +161,33 @@ static int txsrc_get(struct snd_kcontrol *kcontrol,
117static int txsrc_put(struct snd_kcontrol *kcontrol, 161static int txsrc_put(struct snd_kcontrol *kcontrol,
118 struct snd_ctl_elem_value *ucontrol) 162 struct snd_ctl_elem_value *ucontrol)
119{ 163{
120 struct snd_soc_codec *codec; 164 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
121 unsigned int src, txpwr; 165 struct snd_soc_dapm_context *dapm = &codec->dapm;
166 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
167 unsigned int val = ucontrol->value.enumerated.item[0] << e->shift_l;
168 unsigned int mask = 1 << e->shift_l;
169 unsigned int txpwr;
170
171 if (val != 0 && val != mask)
172 return -EINVAL;
122 173
123 codec = snd_soc_kcontrol_codec(kcontrol); 174 snd_soc_dapm_mutex_lock(dapm);
124 175
125 if (ucontrol->value.integer.value[0] != 0 176 if (snd_soc_test_bits(codec, e->reg, mask, val)) {
126 && ucontrol->value.integer.value[0] != 1) 177 /* save the current power state of the transmitter */
127 return -EINVAL; 178 txpwr = snd_soc_read(codec, WM8804_PWRDN) & 0x4;
128 179
129 src = snd_soc_read(codec, WM8804_SPDTX4); 180 /* power down the transmitter */
130 switch ((src & 0x40) >> 6) { 181 snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x4);
131 case 0:
132 if (!ucontrol->value.integer.value[0])
133 return 0;
134 break;
135 case 1:
136 if (ucontrol->value.integer.value[1])
137 return 0;
138 break;
139 }
140 182
141 /* save the current power state of the transmitter */ 183 /* set the tx source */
142 txpwr = snd_soc_read(codec, WM8804_PWRDN) & 0x4; 184 snd_soc_update_bits(codec, e->reg, mask, val);
143 /* power down the transmitter */ 185
144 snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x4); 186 /* restore the transmitter's configuration */
145 /* set the tx source */ 187 snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, txpwr);
146 snd_soc_update_bits(codec, WM8804_SPDTX4, 0x40,
147 ucontrol->value.integer.value[0] << 6);
148
149 if (ucontrol->value.integer.value[0]) {
150 /* power down the receiver */
151 snd_soc_update_bits(codec, WM8804_PWRDN, 0x2, 0x2);
152 /* power up the AIF */
153 snd_soc_update_bits(codec, WM8804_PWRDN, 0x10, 0);
154 } else {
155 /* don't power down the AIF -- may be used as an output */
156 /* power up the receiver */
157 snd_soc_update_bits(codec, WM8804_PWRDN, 0x2, 0);
158 } 188 }
159 189
160 /* restore the transmitter's configuration */ 190 snd_soc_dapm_mutex_unlock(dapm);
161 snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, txpwr);
162 191
163 return 0; 192 return 0;
164} 193}
@@ -182,7 +211,7 @@ static bool wm8804_volatile(struct device *dev, unsigned int reg)
182 } 211 }
183} 212}
184 213
185static int wm8804_reset(struct wm8804_priv *wm8804) 214static int wm8804_soft_reset(struct wm8804_priv *wm8804)
186{ 215{
187 return regmap_write(wm8804->regmap, WM8804_RST_DEVID1, 0x0); 216 return regmap_write(wm8804->regmap, WM8804_RST_DEVID1, 0x0);
188} 217}
@@ -376,19 +405,19 @@ static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id,
376 int source, unsigned int freq_in, 405 int source, unsigned int freq_in,
377 unsigned int freq_out) 406 unsigned int freq_out)
378{ 407{
379 struct snd_soc_codec *codec; 408 struct snd_soc_codec *codec = dai->codec;
409 struct wm8804_priv *wm8804 = snd_soc_codec_get_drvdata(codec);
410 bool change;
380 411
381 codec = dai->codec;
382 if (!freq_in || !freq_out) { 412 if (!freq_in || !freq_out) {
383 /* disable the PLL */ 413 /* disable the PLL */
384 snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0x1); 414 regmap_update_bits_check(wm8804->regmap, WM8804_PWRDN,
385 return 0; 415 0x1, 0x1, &change);
416 if (change)
417 pm_runtime_put(wm8804->dev);
386 } else { 418 } else {
387 int ret; 419 int ret;
388 struct pll_div pll_div; 420 struct pll_div pll_div;
389 struct wm8804_priv *wm8804;
390
391 wm8804 = snd_soc_codec_get_drvdata(codec);
392 421
393 ret = pll_factors(&pll_div, freq_out, freq_in, 422 ret = pll_factors(&pll_div, freq_out, freq_in,
394 wm8804->mclk_div); 423 wm8804->mclk_div);
@@ -396,7 +425,10 @@ static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id,
396 return ret; 425 return ret;
397 426
398 /* power down the PLL before reprogramming it */ 427 /* power down the PLL before reprogramming it */
399 snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0x1); 428 regmap_update_bits_check(wm8804->regmap, WM8804_PWRDN,
429 0x1, 0x1, &change);
430 if (!change)
431 pm_runtime_get_sync(wm8804->dev);
400 432
401 /* set PLLN and PRESCALE */ 433 /* set PLLN and PRESCALE */
402 snd_soc_update_bits(codec, WM8804_PLL4, 0xf | 0x10, 434 snd_soc_update_bits(codec, WM8804_PLL4, 0xf | 0x10,
@@ -474,47 +506,6 @@ static int wm8804_set_clkdiv(struct snd_soc_dai *dai,
474 return 0; 506 return 0;
475} 507}
476 508
477static int wm8804_set_bias_level(struct snd_soc_codec *codec,
478 enum snd_soc_bias_level level)
479{
480 int ret;
481 struct wm8804_priv *wm8804;
482
483 wm8804 = snd_soc_codec_get_drvdata(codec);
484 switch (level) {
485 case SND_SOC_BIAS_ON:
486 break;
487 case SND_SOC_BIAS_PREPARE:
488 /* power up the OSC and the PLL */
489 snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0);
490 break;
491 case SND_SOC_BIAS_STANDBY:
492 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
493 ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies),
494 wm8804->supplies);
495 if (ret) {
496 dev_err(codec->dev,
497 "Failed to enable supplies: %d\n",
498 ret);
499 return ret;
500 }
501 regcache_sync(wm8804->regmap);
502 }
503 /* power down the OSC and the PLL */
504 snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0x9);
505 break;
506 case SND_SOC_BIAS_OFF:
507 /* power down the OSC and the PLL */
508 snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0x9);
509 regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies),
510 wm8804->supplies);
511 break;
512 }
513
514 codec->dapm.bias_level = level;
515 return 0;
516}
517
518static const struct snd_soc_dai_ops wm8804_dai_ops = { 509static const struct snd_soc_dai_ops wm8804_dai_ops = {
519 .hw_params = wm8804_hw_params, 510 .hw_params = wm8804_hw_params,
520 .set_fmt = wm8804_set_fmt, 511 .set_fmt = wm8804_set_fmt,
@@ -552,11 +543,12 @@ static struct snd_soc_dai_driver wm8804_dai = {
552}; 543};
553 544
554static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = { 545static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
555 .set_bias_level = wm8804_set_bias_level,
556 .idle_bias_off = true, 546 .idle_bias_off = true,
557 547
558 .controls = wm8804_snd_controls, 548 .dapm_widgets = wm8804_dapm_widgets,
559 .num_controls = ARRAY_SIZE(wm8804_snd_controls), 549 .num_dapm_widgets = ARRAY_SIZE(wm8804_dapm_widgets),
550 .dapm_routes = wm8804_dapm_routes,
551 .num_dapm_routes = ARRAY_SIZE(wm8804_dapm_routes),
560}; 552};
561 553
562const struct regmap_config wm8804_regmap_config = { 554const struct regmap_config wm8804_regmap_config = {
@@ -584,8 +576,17 @@ int wm8804_probe(struct device *dev, struct regmap *regmap)
584 576
585 dev_set_drvdata(dev, wm8804); 577 dev_set_drvdata(dev, wm8804);
586 578
579 wm8804->dev = dev;
587 wm8804->regmap = regmap; 580 wm8804->regmap = regmap;
588 581
582 wm8804->reset = devm_gpiod_get_optional(dev, "wlf,reset",
583 GPIOD_OUT_LOW);
584 if (IS_ERR(wm8804->reset)) {
585 ret = PTR_ERR(wm8804->reset);
586 dev_err(dev, "Failed to get reset line: %d\n", ret);
587 return ret;
588 }
589
589 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) 590 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++)
590 wm8804->supplies[i].supply = wm8804_supply_names[i]; 591 wm8804->supplies[i].supply = wm8804_supply_names[i];
591 592
@@ -601,12 +602,15 @@ int wm8804_probe(struct device *dev, struct regmap *regmap)
601 602
602 /* This should really be moved into the regulator core */ 603 /* This should really be moved into the regulator core */
603 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) { 604 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) {
604 ret = regulator_register_notifier(wm8804->supplies[i].consumer, 605 struct regulator *regulator = wm8804->supplies[i].consumer;
605 &wm8804->disable_nb[i]); 606
607 ret = devm_regulator_register_notifier(regulator,
608 &wm8804->disable_nb[i]);
606 if (ret != 0) { 609 if (ret != 0) {
607 dev_err(dev, 610 dev_err(dev,
608 "Failed to register regulator notifier: %d\n", 611 "Failed to register regulator notifier: %d\n",
609 ret); 612 ret);
613 return ret;
610 } 614 }
611 } 615 }
612 616
@@ -614,9 +618,12 @@ int wm8804_probe(struct device *dev, struct regmap *regmap)
614 wm8804->supplies); 618 wm8804->supplies);
615 if (ret) { 619 if (ret) {
616 dev_err(dev, "Failed to enable supplies: %d\n", ret); 620 dev_err(dev, "Failed to enable supplies: %d\n", ret);
617 goto err_reg_enable; 621 return ret;
618 } 622 }
619 623
624 if (wm8804->reset)
625 gpiod_set_value_cansleep(wm8804->reset, 1);
626
620 ret = regmap_read(regmap, WM8804_RST_DEVID1, &id1); 627 ret = regmap_read(regmap, WM8804_RST_DEVID1, &id1);
621 if (ret < 0) { 628 if (ret < 0) {
622 dev_err(dev, "Failed to read device ID: %d\n", ret); 629 dev_err(dev, "Failed to read device ID: %d\n", ret);
@@ -645,14 +652,26 @@ int wm8804_probe(struct device *dev, struct regmap *regmap)
645 } 652 }
646 dev_info(dev, "revision %c\n", id1 + 'A'); 653 dev_info(dev, "revision %c\n", id1 + 'A');
647 654
648 ret = wm8804_reset(wm8804); 655 if (!wm8804->reset) {
656 ret = wm8804_soft_reset(wm8804);
657 if (ret < 0) {
658 dev_err(dev, "Failed to issue reset: %d\n", ret);
659 goto err_reg_enable;
660 }
661 }
662
663 ret = snd_soc_register_codec(dev, &soc_codec_dev_wm8804,
664 &wm8804_dai, 1);
649 if (ret < 0) { 665 if (ret < 0) {
650 dev_err(dev, "Failed to issue reset: %d\n", ret); 666 dev_err(dev, "Failed to register CODEC: %d\n", ret);
651 goto err_reg_enable; 667 goto err_reg_enable;
652 } 668 }
653 669
654 return snd_soc_register_codec(dev, &soc_codec_dev_wm8804, 670 pm_runtime_set_active(dev);
655 &wm8804_dai, 1); 671 pm_runtime_enable(dev);
672 pm_runtime_idle(dev);
673
674 return 0;
656 675
657err_reg_enable: 676err_reg_enable:
658 regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies); 677 regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies);
@@ -662,18 +681,50 @@ EXPORT_SYMBOL_GPL(wm8804_probe);
662 681
663void wm8804_remove(struct device *dev) 682void wm8804_remove(struct device *dev)
664{ 683{
665 struct wm8804_priv *wm8804; 684 pm_runtime_disable(dev);
666 int i; 685 snd_soc_unregister_codec(dev);
686}
687EXPORT_SYMBOL_GPL(wm8804_remove);
667 688
668 wm8804 = dev_get_drvdata(dev); 689#if IS_ENABLED(CONFIG_PM)
690static int wm8804_runtime_resume(struct device *dev)
691{
692 struct wm8804_priv *wm8804 = dev_get_drvdata(dev);
693 int ret;
669 694
670 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); ++i) 695 ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies),
671 regulator_unregister_notifier(wm8804->supplies[i].consumer, 696 wm8804->supplies);
672 &wm8804->disable_nb[i]); 697 if (ret) {
698 dev_err(wm8804->dev, "Failed to enable supplies: %d\n", ret);
699 return ret;
700 }
673 701
674 snd_soc_unregister_codec(dev); 702 regcache_sync(wm8804->regmap);
703
704 /* Power up OSCCLK */
705 regmap_update_bits(wm8804->regmap, WM8804_PWRDN, 0x8, 0x0);
706
707 return 0;
675} 708}
676EXPORT_SYMBOL_GPL(wm8804_remove); 709
710static int wm8804_runtime_suspend(struct device *dev)
711{
712 struct wm8804_priv *wm8804 = dev_get_drvdata(dev);
713
714 /* Power down OSCCLK */
715 regmap_update_bits(wm8804->regmap, WM8804_PWRDN, 0x8, 0x8);
716
717 regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies),
718 wm8804->supplies);
719
720 return 0;
721}
722#endif
723
724const struct dev_pm_ops wm8804_pm = {
725 SET_RUNTIME_PM_OPS(wm8804_runtime_suspend, wm8804_runtime_resume, NULL)
726};
727EXPORT_SYMBOL_GPL(wm8804_pm);
677 728
678MODULE_DESCRIPTION("ASoC WM8804 driver"); 729MODULE_DESCRIPTION("ASoC WM8804 driver");
679MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>"); 730MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8804.h b/sound/soc/codecs/wm8804.h
index a39a2563dc67..aa72fa66c932 100644
--- a/sound/soc/codecs/wm8804.h
+++ b/sound/soc/codecs/wm8804.h
@@ -65,6 +65,7 @@
65#define WM8804_MCLKDIV_128FS 1 65#define WM8804_MCLKDIV_128FS 1
66 66
67extern const struct regmap_config wm8804_regmap_config; 67extern const struct regmap_config wm8804_regmap_config;
68extern const struct dev_pm_ops wm8804_pm;
68 69
69int wm8804_probe(struct device *dev, struct regmap *regmap); 70int wm8804_probe(struct device *dev, struct regmap *regmap);
70void wm8804_remove(struct device *dev); 71void wm8804_remove(struct device *dev);
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 39ddb9b8834c..f9cbabdc6238 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -31,11 +31,11 @@
31 31
32#define WM8971_REG_COUNT 43 32#define WM8971_REG_COUNT 43
33 33
34static struct workqueue_struct *wm8971_workq = NULL;
35
36/* codec private data */ 34/* codec private data */
37struct wm8971_priv { 35struct wm8971_priv {
38 unsigned int sysclk; 36 unsigned int sysclk;
37 struct delayed_work charge_work;
38 struct regmap *regmap;
39}; 39};
40 40
41/* 41/*
@@ -552,9 +552,19 @@ static int wm8971_mute(struct snd_soc_dai *dai, int mute)
552 return 0; 552 return 0;
553} 553}
554 554
555static void wm8971_charge_work(struct work_struct *work)
556{
557 struct wm8971_priv *wm8971 =
558 container_of(work, struct wm8971_priv, charge_work.work);
559
560 /* Set to 500k */
561 regmap_update_bits(wm8971->regmap, WM8971_PWR1, 0x0180, 0x0100);
562}
563
555static int wm8971_set_bias_level(struct snd_soc_codec *codec, 564static int wm8971_set_bias_level(struct snd_soc_codec *codec,
556 enum snd_soc_bias_level level) 565 enum snd_soc_bias_level level)
557{ 566{
567 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
558 u16 pwr_reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e; 568 u16 pwr_reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
559 569
560 switch (level) { 570 switch (level) {
@@ -563,15 +573,24 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec,
563 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x00c1); 573 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x00c1);
564 break; 574 break;
565 case SND_SOC_BIAS_PREPARE: 575 case SND_SOC_BIAS_PREPARE:
576 /* Wait until fully charged */
577 flush_delayed_work(&wm8971->charge_work);
566 break; 578 break;
567 case SND_SOC_BIAS_STANDBY: 579 case SND_SOC_BIAS_STANDBY:
568 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) 580 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
569 snd_soc_cache_sync(codec); 581 snd_soc_cache_sync(codec);
582 /* charge output caps - set vmid to 5k for quick power up */
583 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x01c0);
584 queue_delayed_work(system_power_efficient_wq,
585 &wm8971->charge_work, msecs_to_jiffies(1000));
586 } else {
587 /* mute dac and set vmid to 500k, enable VREF */
588 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
589 }
570 590
571 /* mute dac and set vmid to 500k, enable VREF */
572 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
573 break; 591 break;
574 case SND_SOC_BIAS_OFF: 592 case SND_SOC_BIAS_OFF:
593 cancel_delayed_work_sync(&wm8971->charge_work);
575 snd_soc_write(codec, WM8971_PWR1, 0x0001); 594 snd_soc_write(codec, WM8971_PWR1, 0x0001);
576 break; 595 break;
577 } 596 }
@@ -610,58 +629,14 @@ static struct snd_soc_dai_driver wm8971_dai = {
610 .ops = &wm8971_dai_ops, 629 .ops = &wm8971_dai_ops,
611}; 630};
612 631
613static void wm8971_work(struct work_struct *work)
614{
615 struct snd_soc_dapm_context *dapm =
616 container_of(work, struct snd_soc_dapm_context,
617 delayed_work.work);
618 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
619 wm8971_set_bias_level(codec, codec->dapm.bias_level);
620}
621
622static int wm8971_suspend(struct snd_soc_codec *codec)
623{
624 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
625 return 0;
626}
627
628static int wm8971_resume(struct snd_soc_codec *codec)
629{
630 u16 reg;
631
632 wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
633
634 /* charge wm8971 caps */
635 if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
636 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
637 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
638 codec->dapm.bias_level = SND_SOC_BIAS_ON;
639 queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
640 msecs_to_jiffies(1000));
641 }
642
643 return 0;
644}
645
646static int wm8971_probe(struct snd_soc_codec *codec) 632static int wm8971_probe(struct snd_soc_codec *codec)
647{ 633{
648 int ret = 0; 634 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
649 u16 reg;
650 635
651 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8971_work); 636 INIT_DELAYED_WORK(&wm8971->charge_work, wm8971_charge_work);
652 wm8971_workq = create_workqueue("wm8971");
653 if (wm8971_workq == NULL)
654 return -ENOMEM;
655 637
656 wm8971_reset(codec); 638 wm8971_reset(codec);
657 639
658 /* charge output caps - set vmid to 5k for quick power up */
659 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
660 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
661 codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
662 queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
663 msecs_to_jiffies(1000));
664
665 /* set the update bits */ 640 /* set the update bits */
666 snd_soc_update_bits(codec, WM8971_LDAC, 0x0100, 0x0100); 641 snd_soc_update_bits(codec, WM8971_LDAC, 0x0100, 0x0100);
667 snd_soc_update_bits(codec, WM8971_RDAC, 0x0100, 0x0100); 642 snd_soc_update_bits(codec, WM8971_RDAC, 0x0100, 0x0100);
@@ -672,26 +647,13 @@ static int wm8971_probe(struct snd_soc_codec *codec)
672 snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100); 647 snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100);
673 snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100); 648 snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100);
674 649
675 return ret;
676}
677
678
679/* power down chip */
680static int wm8971_remove(struct snd_soc_codec *codec)
681{
682 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
683
684 if (wm8971_workq)
685 destroy_workqueue(wm8971_workq);
686 return 0; 650 return 0;
687} 651}
688 652
689static struct snd_soc_codec_driver soc_codec_dev_wm8971 = { 653static struct snd_soc_codec_driver soc_codec_dev_wm8971 = {
690 .probe = wm8971_probe, 654 .probe = wm8971_probe,
691 .remove = wm8971_remove,
692 .suspend = wm8971_suspend,
693 .resume = wm8971_resume,
694 .set_bias_level = wm8971_set_bias_level, 655 .set_bias_level = wm8971_set_bias_level,
656 .suspend_bias_off = true,
695 657
696 .controls = wm8971_snd_controls, 658 .controls = wm8971_snd_controls,
697 .num_controls = ARRAY_SIZE(wm8971_snd_controls), 659 .num_controls = ARRAY_SIZE(wm8971_snd_controls),
@@ -715,7 +677,6 @@ static int wm8971_i2c_probe(struct i2c_client *i2c,
715 const struct i2c_device_id *id) 677 const struct i2c_device_id *id)
716{ 678{
717 struct wm8971_priv *wm8971; 679 struct wm8971_priv *wm8971;
718 struct regmap *regmap;
719 int ret; 680 int ret;
720 681
721 wm8971 = devm_kzalloc(&i2c->dev, sizeof(struct wm8971_priv), 682 wm8971 = devm_kzalloc(&i2c->dev, sizeof(struct wm8971_priv),
@@ -723,9 +684,9 @@ static int wm8971_i2c_probe(struct i2c_client *i2c,
723 if (wm8971 == NULL) 684 if (wm8971 == NULL)
724 return -ENOMEM; 685 return -ENOMEM;
725 686
726 regmap = devm_regmap_init_i2c(i2c, &wm8971_regmap); 687 wm8971->regmap = devm_regmap_init_i2c(i2c, &wm8971_regmap);
727 if (IS_ERR(regmap)) 688 if (IS_ERR(wm8971->regmap))
728 return PTR_ERR(regmap); 689 return PTR_ERR(wm8971->regmap);
729 690
730 i2c_set_clientdata(i2c, wm8971); 691 i2c_set_clientdata(i2c, wm8971);
731 692
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index dc92d5e4e942..308748a022c5 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -2009,7 +2009,7 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2009 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 2009 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
2010 struct i2c_client *i2c = to_i2c_client(codec->dev); 2010 struct i2c_client *i2c = to_i2c_client(codec->dev);
2011 struct _fll_div fll_div; 2011 struct _fll_div fll_div;
2012 unsigned long timeout; 2012 unsigned long timeout, time_left;
2013 int ret, reg, retry; 2013 int ret, reg, retry;
2014 2014
2015 /* Any change? */ 2015 /* Any change? */
@@ -2110,13 +2110,15 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2110 if (i2c->irq) 2110 if (i2c->irq)
2111 timeout *= 10; 2111 timeout *= 10;
2112 else 2112 else
2113 timeout /= 2; 2113 /* ensure timeout of atleast 1 jiffies */
2114 timeout = timeout/2 ? : 1;
2114 2115
2115 for (retry = 0; retry < 10; retry++) { 2116 for (retry = 0; retry < 10; retry++) {
2116 ret = wait_for_completion_timeout(&wm8996->fll_lock, 2117 time_left = wait_for_completion_timeout(&wm8996->fll_lock,
2117 timeout); 2118 timeout);
2118 if (ret != 0) { 2119 if (time_left != 0) {
2119 WARN_ON(!i2c->irq); 2120 WARN_ON(!i2c->irq);
2121 ret = 1;
2120 break; 2122 break;
2121 } 2123 }
2122 2124
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index b6bb5947a8a8..731fb0d86c6a 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -117,7 +117,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
117static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd) 117static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
118{ 118{
119 struct snd_soc_card *card = rtd->card; 119 struct snd_soc_card *card = rtd->card;
120 struct snd_soc_codec *codec = rtd->codec;
121 struct device_node *np = card->dev->of_node; 120 struct device_node *np = card->dev->of_node;
122 int ret; 121 int ret;
123 122
@@ -136,9 +135,9 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
136 } 135 }
137 136
138 /* not connected */ 137 /* not connected */
139 snd_soc_dapm_nc_pin(&codec->dapm, "MONO_LOUT"); 138 snd_soc_dapm_nc_pin(&card->dapm, "MONO_LOUT");
140 snd_soc_dapm_nc_pin(&codec->dapm, "HPLCOM"); 139 snd_soc_dapm_nc_pin(&card->dapm, "HPLCOM");
141 snd_soc_dapm_nc_pin(&codec->dapm, "HPRCOM"); 140 snd_soc_dapm_nc_pin(&card->dapm, "HPRCOM");
142 141
143 return 0; 142 return 0;
144} 143}
@@ -425,18 +424,8 @@ static int davinci_evm_probe(struct platform_device *pdev)
425 return ret; 424 return ret;
426} 425}
427 426
428static int davinci_evm_remove(struct platform_device *pdev)
429{
430 struct snd_soc_card *card = platform_get_drvdata(pdev);
431
432 snd_soc_unregister_card(card);
433
434 return 0;
435}
436
437static struct platform_driver davinci_evm_driver = { 427static struct platform_driver davinci_evm_driver = {
438 .probe = davinci_evm_probe, 428 .probe = davinci_evm_probe,
439 .remove = davinci_evm_remove,
440 .driver = { 429 .driver = {
441 .name = "davinci_evm", 430 .name = "davinci_evm",
442 .pm = &snd_soc_pm_ops, 431 .pm = &snd_soc_pm_ops,
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 0c882995a357..bb4b78eada58 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -27,6 +27,7 @@
27#include <linux/of_platform.h> 27#include <linux/of_platform.h>
28#include <linux/of_device.h> 28#include <linux/of_device.h>
29#include <linux/platform_data/davinci_asp.h> 29#include <linux/platform_data/davinci_asp.h>
30#include <linux/math64.h>
30 31
31#include <sound/asoundef.h> 32#include <sound/asoundef.h>
32#include <sound/core.h> 33#include <sound/core.h>
@@ -62,6 +63,12 @@ struct davinci_mcasp_context {
62 u32 config_regs[ARRAY_SIZE(context_regs)]; 63 u32 config_regs[ARRAY_SIZE(context_regs)];
63 u32 afifo_regs[2]; /* for read/write fifo control registers */ 64 u32 afifo_regs[2]; /* for read/write fifo control registers */
64 u32 *xrsr_regs; /* for serializer configuration */ 65 u32 *xrsr_regs; /* for serializer configuration */
66 bool pm_state;
67};
68
69struct davinci_mcasp_ruledata {
70 struct davinci_mcasp *mcasp;
71 int serializers;
65}; 72};
66 73
67struct davinci_mcasp { 74struct davinci_mcasp {
@@ -98,6 +105,8 @@ struct davinci_mcasp {
98#ifdef CONFIG_PM_SLEEP 105#ifdef CONFIG_PM_SLEEP
99 struct davinci_mcasp_context context; 106 struct davinci_mcasp_context context;
100#endif 107#endif
108
109 struct davinci_mcasp_ruledata ruledata[2];
101}; 110};
102 111
103static inline void mcasp_set_bits(struct davinci_mcasp *mcasp, u32 offset, 112static inline void mcasp_set_bits(struct davinci_mcasp *mcasp, u32 offset,
@@ -519,7 +528,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
519 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); 528 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
520 } 529 }
521out: 530out:
522 pm_runtime_put_sync(mcasp->dev); 531 pm_runtime_put(mcasp->dev);
523 return ret; 532 return ret;
524} 533}
525 534
@@ -528,6 +537,7 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id,
528{ 537{
529 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); 538 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
530 539
540 pm_runtime_get_sync(mcasp->dev);
531 switch (div_id) { 541 switch (div_id) {
532 case 0: /* MCLK divider */ 542 case 0: /* MCLK divider */
533 mcasp_mod_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, 543 mcasp_mod_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG,
@@ -553,6 +563,7 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id,
553 return -EINVAL; 563 return -EINVAL;
554 } 564 }
555 565
566 pm_runtime_put(mcasp->dev);
556 return 0; 567 return 0;
557} 568}
558 569
@@ -567,6 +578,7 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id,
567{ 578{
568 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); 579 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
569 580
581 pm_runtime_get_sync(mcasp->dev);
570 if (dir == SND_SOC_CLOCK_OUT) { 582 if (dir == SND_SOC_CLOCK_OUT) {
571 mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); 583 mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE);
572 mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); 584 mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE);
@@ -579,6 +591,7 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id,
579 591
580 mcasp->sysclk_freq = freq; 592 mcasp->sysclk_freq = freq;
581 593
594 pm_runtime_put(mcasp->dev);
582 return 0; 595 return 0;
583} 596}
584 597
@@ -863,6 +876,30 @@ static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp,
863 return 0; 876 return 0;
864} 877}
865 878
879static int davinci_mcasp_calc_clk_div(struct davinci_mcasp *mcasp,
880 unsigned int bclk_freq,
881 int *error_ppm)
882{
883 int div = mcasp->sysclk_freq / bclk_freq;
884 int rem = mcasp->sysclk_freq % bclk_freq;
885
886 if (rem != 0) {
887 if (div == 0 ||
888 ((mcasp->sysclk_freq / div) - bclk_freq) >
889 (bclk_freq - (mcasp->sysclk_freq / (div+1)))) {
890 div++;
891 rem = rem - bclk_freq;
892 }
893 }
894 if (error_ppm)
895 *error_ppm =
896 (div*1000000 + (int)div64_long(1000000LL*rem,
897 (int)bclk_freq))
898 /div - 1000000;
899
900 return div;
901}
902
866static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, 903static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
867 struct snd_pcm_hw_params *params, 904 struct snd_pcm_hw_params *params,
868 struct snd_soc_dai *cpu_dai) 905 struct snd_soc_dai *cpu_dai)
@@ -878,16 +915,20 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
878 * the machine driver, we need to calculate the ratio. 915 * the machine driver, we need to calculate the ratio.
879 */ 916 */
880 if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) { 917 if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) {
881 unsigned int bclk_freq = snd_soc_params_to_bclk(params); 918 int channels = params_channels(params);
882 unsigned int div = mcasp->sysclk_freq / bclk_freq; 919 int rate = params_rate(params);
883 if (mcasp->sysclk_freq % bclk_freq != 0) { 920 int sbits = params_width(params);
884 if (((mcasp->sysclk_freq / div) - bclk_freq) > 921 int ppm, div;
885 (bclk_freq - (mcasp->sysclk_freq / (div+1)))) 922
886 div++; 923 if (channels > mcasp->tdm_slots)
887 dev_warn(mcasp->dev, 924 channels = mcasp->tdm_slots;
888 "Inaccurate BCLK: %u Hz / %u != %u Hz\n", 925
889 mcasp->sysclk_freq, div, bclk_freq); 926 div = davinci_mcasp_calc_clk_div(mcasp, rate*sbits*channels,
890 } 927 &ppm);
928 if (ppm)
929 dev_info(mcasp->dev, "Sample-rate is off by %d PPM\n",
930 ppm);
931
891 __davinci_mcasp_set_clkdiv(cpu_dai, 1, div, 0); 932 __davinci_mcasp_set_clkdiv(cpu_dai, 1, div, 0);
892 } 933 }
893 934
@@ -969,10 +1010,126 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
969 return ret; 1010 return ret;
970} 1011}
971 1012
1013static const unsigned int davinci_mcasp_dai_rates[] = {
1014 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000,
1015 88200, 96000, 176400, 192000,
1016};
1017
1018#define DAVINCI_MAX_RATE_ERROR_PPM 1000
1019
1020static int davinci_mcasp_hw_rule_rate(struct snd_pcm_hw_params *params,
1021 struct snd_pcm_hw_rule *rule)
1022{
1023 struct davinci_mcasp_ruledata *rd = rule->private;
1024 struct snd_interval *ri =
1025 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
1026 int sbits = params_width(params);
1027 int channels = params_channels(params);
1028 unsigned int list[ARRAY_SIZE(davinci_mcasp_dai_rates)];
1029 int i, count = 0;
1030
1031 if (channels > rd->mcasp->tdm_slots)
1032 channels = rd->mcasp->tdm_slots;
1033
1034 for (i = 0; i < ARRAY_SIZE(davinci_mcasp_dai_rates); i++) {
1035 if (ri->min <= davinci_mcasp_dai_rates[i] &&
1036 ri->max >= davinci_mcasp_dai_rates[i]) {
1037 uint bclk_freq = sbits*channels*
1038 davinci_mcasp_dai_rates[i];
1039 int ppm;
1040
1041 davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm);
1042 if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM)
1043 list[count++] = davinci_mcasp_dai_rates[i];
1044 }
1045 }
1046 dev_dbg(rd->mcasp->dev,
1047 "%d frequencies (%d-%d) for %d sbits and %d channels\n",
1048 count, ri->min, ri->max, sbits, channels);
1049
1050 return snd_interval_list(hw_param_interval(params, rule->var),
1051 count, list, 0);
1052}
1053
1054static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params,
1055 struct snd_pcm_hw_rule *rule)
1056{
1057 struct davinci_mcasp_ruledata *rd = rule->private;
1058 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1059 struct snd_mask nfmt;
1060 int rate = params_rate(params);
1061 int channels = params_channels(params);
1062 int i, count = 0;
1063
1064 snd_mask_none(&nfmt);
1065
1066 if (channels > rd->mcasp->tdm_slots)
1067 channels = rd->mcasp->tdm_slots;
1068
1069 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
1070 if (snd_mask_test(fmt, i)) {
1071 uint bclk_freq = snd_pcm_format_width(i)*channels*rate;
1072 int ppm;
1073
1074 davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm);
1075 if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) {
1076 snd_mask_set(&nfmt, i);
1077 count++;
1078 }
1079 }
1080 }
1081 dev_dbg(rd->mcasp->dev,
1082 "%d possible sample format for %d Hz and %d channels\n",
1083 count, rate, channels);
1084
1085 return snd_mask_refine(fmt, &nfmt);
1086}
1087
1088static int davinci_mcasp_hw_rule_channels(struct snd_pcm_hw_params *params,
1089 struct snd_pcm_hw_rule *rule)
1090{
1091 struct davinci_mcasp_ruledata *rd = rule->private;
1092 struct snd_interval *ci =
1093 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
1094 int sbits = params_width(params);
1095 int rate = params_rate(params);
1096 int max_chan_per_wire = rd->mcasp->tdm_slots < ci->max ?
1097 rd->mcasp->tdm_slots : ci->max;
1098 unsigned int list[ci->max - ci->min + 1];
1099 int c1, c, count = 0;
1100
1101 for (c1 = ci->min; c1 <= max_chan_per_wire; c1++) {
1102 uint bclk_freq = c1*sbits*rate;
1103 int ppm;
1104
1105 davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm);
1106 if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) {
1107 /* If we can use all tdm_slots, we can put any
1108 amount of channels to remaining wires as
1109 long as they fit in. */
1110 if (c1 == rd->mcasp->tdm_slots) {
1111 for (c = c1; c <= rd->serializers*c1 &&
1112 c <= ci->max; c++)
1113 list[count++] = c;
1114 } else {
1115 list[count++] = c1;
1116 }
1117 }
1118 }
1119 dev_dbg(rd->mcasp->dev,
1120 "%d possible channel counts (%d-%d) for %d Hz and %d sbits\n",
1121 count, ci->min, ci->max, rate, sbits);
1122
1123 return snd_interval_list(hw_param_interval(params, rule->var),
1124 count, list, 0);
1125}
1126
972static int davinci_mcasp_startup(struct snd_pcm_substream *substream, 1127static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
973 struct snd_soc_dai *cpu_dai) 1128 struct snd_soc_dai *cpu_dai)
974{ 1129{
975 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); 1130 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
1131 struct davinci_mcasp_ruledata *ruledata =
1132 &mcasp->ruledata[substream->stream];
976 u32 max_channels = 0; 1133 u32 max_channels = 0;
977 int i, dir; 1134 int i, dir;
978 1135
@@ -994,6 +1151,7 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
994 if (mcasp->serial_dir[i] == dir) 1151 if (mcasp->serial_dir[i] == dir)
995 max_channels++; 1152 max_channels++;
996 } 1153 }
1154 ruledata->serializers = max_channels;
997 max_channels *= mcasp->tdm_slots; 1155 max_channels *= mcasp->tdm_slots;
998 /* 1156 /*
999 * If the already active stream has less channels than the calculated 1157 * If the already active stream has less channels than the calculated
@@ -1008,6 +1166,42 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
1008 snd_pcm_hw_constraint_minmax(substream->runtime, 1166 snd_pcm_hw_constraint_minmax(substream->runtime,
1009 SNDRV_PCM_HW_PARAM_CHANNELS, 1167 SNDRV_PCM_HW_PARAM_CHANNELS,
1010 2, max_channels); 1168 2, max_channels);
1169
1170 /*
1171 * If we rely on implicit BCLK divider setting we should
1172 * set constraints based on what we can provide.
1173 */
1174 if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) {
1175 int ret;
1176
1177 ruledata->mcasp = mcasp;
1178
1179 ret = snd_pcm_hw_rule_add(substream->runtime, 0,
1180 SNDRV_PCM_HW_PARAM_RATE,
1181 davinci_mcasp_hw_rule_rate,
1182 ruledata,
1183 SNDRV_PCM_HW_PARAM_FORMAT,
1184 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
1185 if (ret)
1186 return ret;
1187 ret = snd_pcm_hw_rule_add(substream->runtime, 0,
1188 SNDRV_PCM_HW_PARAM_FORMAT,
1189 davinci_mcasp_hw_rule_format,
1190 ruledata,
1191 SNDRV_PCM_HW_PARAM_RATE,
1192 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
1193 if (ret)
1194 return ret;
1195 ret = snd_pcm_hw_rule_add(substream->runtime, 0,
1196 SNDRV_PCM_HW_PARAM_CHANNELS,
1197 davinci_mcasp_hw_rule_channels,
1198 ruledata,
1199 SNDRV_PCM_HW_PARAM_RATE,
1200 SNDRV_PCM_HW_PARAM_FORMAT, -1);
1201 if (ret)
1202 return ret;
1203 }
1204
1011 return 0; 1205 return 0;
1012} 1206}
1013 1207
@@ -1053,6 +1247,10 @@ static int davinci_mcasp_suspend(struct snd_soc_dai *dai)
1053 u32 reg; 1247 u32 reg;
1054 int i; 1248 int i;
1055 1249
1250 context->pm_state = pm_runtime_enabled(mcasp->dev);
1251 if (!context->pm_state)
1252 pm_runtime_get_sync(mcasp->dev);
1253
1056 for (i = 0; i < ARRAY_SIZE(context_regs); i++) 1254 for (i = 0; i < ARRAY_SIZE(context_regs); i++)
1057 context->config_regs[i] = mcasp_get_reg(mcasp, context_regs[i]); 1255 context->config_regs[i] = mcasp_get_reg(mcasp, context_regs[i]);
1058 1256
@@ -1069,6 +1267,8 @@ static int davinci_mcasp_suspend(struct snd_soc_dai *dai)
1069 context->xrsr_regs[i] = mcasp_get_reg(mcasp, 1267 context->xrsr_regs[i] = mcasp_get_reg(mcasp,
1070 DAVINCI_MCASP_XRSRCTL_REG(i)); 1268 DAVINCI_MCASP_XRSRCTL_REG(i));
1071 1269
1270 pm_runtime_put_sync(mcasp->dev);
1271
1072 return 0; 1272 return 0;
1073} 1273}
1074 1274
@@ -1079,6 +1279,8 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai)
1079 u32 reg; 1279 u32 reg;
1080 int i; 1280 int i;
1081 1281
1282 pm_runtime_get_sync(mcasp->dev);
1283
1082 for (i = 0; i < ARRAY_SIZE(context_regs); i++) 1284 for (i = 0; i < ARRAY_SIZE(context_regs); i++)
1083 mcasp_set_reg(mcasp, context_regs[i], context->config_regs[i]); 1285 mcasp_set_reg(mcasp, context_regs[i], context->config_regs[i]);
1084 1286
@@ -1095,6 +1297,9 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai)
1095 mcasp_set_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i), 1297 mcasp_set_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
1096 context->xrsr_regs[i]); 1298 context->xrsr_regs[i]);
1097 1299
1300 if (!context->pm_state)
1301 pm_runtime_put_sync(mcasp->dev);
1302
1098 return 0; 1303 return 0;
1099} 1304}
1100#else 1305#else
@@ -1398,13 +1603,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1398 1603
1399 pm_runtime_enable(&pdev->dev); 1604 pm_runtime_enable(&pdev->dev);
1400 1605
1401 ret = pm_runtime_get_sync(&pdev->dev);
1402 if (IS_ERR_VALUE(ret)) {
1403 dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n");
1404 pm_runtime_disable(&pdev->dev);
1405 return ret;
1406 }
1407
1408 mcasp->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); 1606 mcasp->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
1409 if (!mcasp->base) { 1607 if (!mcasp->base) {
1410 dev_err(&pdev->dev, "ioremap failed\n"); 1608 dev_err(&pdev->dev, "ioremap failed\n");
@@ -1584,14 +1782,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1584 return 0; 1782 return 0;
1585 1783
1586err: 1784err:
1587 pm_runtime_put_sync(&pdev->dev);
1588 pm_runtime_disable(&pdev->dev); 1785 pm_runtime_disable(&pdev->dev);
1589 return ret; 1786 return ret;
1590} 1787}
1591 1788
1592static int davinci_mcasp_remove(struct platform_device *pdev) 1789static int davinci_mcasp_remove(struct platform_device *pdev)
1593{ 1790{
1594 pm_runtime_put_sync(&pdev->dev);
1595 pm_runtime_disable(&pdev->dev); 1791 pm_runtime_disable(&pdev->dev);
1596 1792
1597 return 0; 1793 return 0;
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 081e406b3713..19c302b0d763 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -24,7 +24,7 @@ config SND_SOC_FSL_SAI
24 in-tree drivers select it automatically. 24 in-tree drivers select it automatically.
25 25
26config SND_SOC_FSL_SSI 26config SND_SOC_FSL_SSI
27 tristate "Synchronous Serial Interface module support" 27 tristate "Synchronous Serial Interface module (SSI) support"
28 select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n 28 select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
29 select SND_SOC_IMX_PCM_FIQ if SND_IMX_SOC != n && (MXC_TZIC || MXC_AVIC) 29 select SND_SOC_IMX_PCM_FIQ if SND_IMX_SOC != n && (MXC_TZIC || MXC_AVIC)
30 select REGMAP_MMIO 30 select REGMAP_MMIO
@@ -35,7 +35,7 @@ config SND_SOC_FSL_SSI
35 in-tree drivers select it automatically. 35 in-tree drivers select it automatically.
36 36
37config SND_SOC_FSL_SPDIF 37config SND_SOC_FSL_SPDIF
38 tristate "Sony/Philips Digital Interface module support" 38 tristate "Sony/Philips Digital Interface (S/PDIF) module support"
39 select REGMAP_MMIO 39 select REGMAP_MMIO
40 select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n 40 select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
41 select SND_SOC_IMX_PCM_FIQ if SND_IMX_SOC != n && (MXC_TZIC || MXC_AVIC) 41 select SND_SOC_IMX_PCM_FIQ if SND_IMX_SOC != n && (MXC_TZIC || MXC_AVIC)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 6b0c8f717ec2..e8bb8eef1d16 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -1288,7 +1288,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1288 const struct of_device_id *of_id; 1288 const struct of_device_id *of_id;
1289 const char *p, *sprop; 1289 const char *p, *sprop;
1290 const uint32_t *iprop; 1290 const uint32_t *iprop;
1291 struct resource res; 1291 struct resource *res;
1292 void __iomem *iomem; 1292 void __iomem *iomem;
1293 char name[64]; 1293 char name[64];
1294 1294
@@ -1335,19 +1335,11 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1335 } 1335 }
1336 ssi_private->cpu_dai_drv.name = dev_name(&pdev->dev); 1336 ssi_private->cpu_dai_drv.name = dev_name(&pdev->dev);
1337 1337
1338 /* Get the addresses and IRQ */ 1338 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1339 ret = of_address_to_resource(np, 0, &res); 1339 iomem = devm_ioremap_resource(&pdev->dev, res);
1340 if (ret) { 1340 if (IS_ERR(iomem))
1341 dev_err(&pdev->dev, "could not determine device resources\n"); 1341 return PTR_ERR(iomem);
1342 return ret; 1342 ssi_private->ssi_phys = res->start;
1343 }
1344 ssi_private->ssi_phys = res.start;
1345
1346 iomem = devm_ioremap(&pdev->dev, res.start, resource_size(&res));
1347 if (!iomem) {
1348 dev_err(&pdev->dev, "could not map device resources\n");
1349 return -ENOMEM;
1350 }
1351 1343
1352 ret = of_property_match_string(np, "clock-names", "ipg"); 1344 ret = of_property_match_string(np, "clock-names", "ipg");
1353 if (ret < 0) { 1345 if (ret < 0) {
@@ -1393,8 +1385,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1393 return ret; 1385 return ret;
1394 } 1386 }
1395 1387
1396 ret = snd_soc_register_component(&pdev->dev, &fsl_ssi_component, 1388 ret = devm_snd_soc_register_component(&pdev->dev, &fsl_ssi_component,
1397 &ssi_private->cpu_dai_drv, 1); 1389 &ssi_private->cpu_dai_drv, 1);
1398 if (ret) { 1390 if (ret) {
1399 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); 1391 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
1400 goto error_asoc_register; 1392 goto error_asoc_register;
@@ -1407,13 +1399,13 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1407 if (ret < 0) { 1399 if (ret < 0) {
1408 dev_err(&pdev->dev, "could not claim irq %u\n", 1400 dev_err(&pdev->dev, "could not claim irq %u\n",
1409 ssi_private->irq); 1401 ssi_private->irq);
1410 goto error_irq; 1402 goto error_asoc_register;
1411 } 1403 }
1412 } 1404 }
1413 1405
1414 ret = fsl_ssi_debugfs_create(&ssi_private->dbg_stats, &pdev->dev); 1406 ret = fsl_ssi_debugfs_create(&ssi_private->dbg_stats, &pdev->dev);
1415 if (ret) 1407 if (ret)
1416 goto error_irq; 1408 goto error_asoc_register;
1417 1409
1418 /* 1410 /*
1419 * If codec-handle property is missing from SSI node, we assume 1411 * If codec-handle property is missing from SSI node, we assume
@@ -1454,9 +1446,6 @@ done:
1454error_sound_card: 1446error_sound_card:
1455 fsl_ssi_debugfs_remove(&ssi_private->dbg_stats); 1447 fsl_ssi_debugfs_remove(&ssi_private->dbg_stats);
1456 1448
1457error_irq:
1458 snd_soc_unregister_component(&pdev->dev);
1459
1460error_asoc_register: 1449error_asoc_register:
1461 if (ssi_private->soc->imx) 1450 if (ssi_private->soc->imx)
1462 fsl_ssi_imx_clean(pdev, ssi_private); 1451 fsl_ssi_imx_clean(pdev, ssi_private);
@@ -1472,7 +1461,6 @@ static int fsl_ssi_remove(struct platform_device *pdev)
1472 1461
1473 if (ssi_private->pdev) 1462 if (ssi_private->pdev)
1474 platform_device_unregister(ssi_private->pdev); 1463 platform_device_unregister(ssi_private->pdev);
1475 snd_soc_unregister_component(&pdev->dev);
1476 1464
1477 if (ssi_private->soc->imx) 1465 if (ssi_private->soc->imx)
1478 fsl_ssi_imx_clean(pdev, ssi_private); 1466 fsl_ssi_imx_clean(pdev, ssi_private);
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index 08d2a8069b0a..0bab76051fd8 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -326,7 +326,7 @@ static int psc_ac97_of_remove(struct platform_device *op)
326} 326}
327 327
328/* Match table for of_platform binding */ 328/* Match table for of_platform binding */
329static struct of_device_id psc_ac97_match[] = { 329static const struct of_device_id psc_ac97_match[] = {
330 { .compatible = "fsl,mpc5200-psc-ac97", }, 330 { .compatible = "fsl,mpc5200-psc-ac97", },
331 { .compatible = "fsl,mpc5200b-psc-ac97", }, 331 { .compatible = "fsl,mpc5200b-psc-ac97", },
332 {} 332 {}
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 51fb0c00fe73..d8232943ccb6 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -217,7 +217,7 @@ static int psc_i2s_of_remove(struct platform_device *op)
217} 217}
218 218
219/* Match table for of_platform binding */ 219/* Match table for of_platform binding */
220static struct of_device_id psc_i2s_match[] = { 220static const struct of_device_id psc_i2s_match[] = {
221 { .compatible = "fsl,mpc5200-psc-i2s", }, 221 { .compatible = "fsl,mpc5200-psc-i2s", },
222 { .compatible = "fsl,mpc5200b-psc-i2s", }, 222 { .compatible = "fsl,mpc5200b-psc-i2s", },
223 {} 223 {}
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c
index c44459d24c50..ec731223cab3 100644
--- a/sound/soc/fsl/pcm030-audio-fabric.c
+++ b/sound/soc/fsl/pcm030-audio-fabric.c
@@ -113,7 +113,7 @@ static int pcm030_fabric_remove(struct platform_device *op)
113 return ret; 113 return ret;
114} 114}
115 115
116static struct of_device_id pcm030_audio_match[] = { 116static const struct of_device_id pcm030_audio_match[] = {
117 { .compatible = "phytec,pcm030-audio-fabric", }, 117 { .compatible = "phytec,pcm030-audio-fabric", },
118 {} 118 {}
119}; 119};
diff --git a/sound/soc/fsl/wm1133-ev1.c b/sound/soc/fsl/wm1133-ev1.c
index 0653aa83c927..b454972dce35 100644
--- a/sound/soc/fsl/wm1133-ev1.c
+++ b/sound/soc/fsl/wm1133-ev1.c
@@ -202,7 +202,6 @@ static struct snd_soc_jack_pin mic_jack_pins[] = {
202static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd) 202static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
203{ 203{
204 struct snd_soc_codec *codec = rtd->codec; 204 struct snd_soc_codec *codec = rtd->codec;
205 struct snd_soc_dapm_context *dapm = &codec->dapm;
206 205
207 /* Headphone jack detection */ 206 /* Headphone jack detection */
208 snd_soc_card_jack_new(rtd->card, "Headphone", SND_JACK_HEADPHONE, 207 snd_soc_card_jack_new(rtd->card, "Headphone", SND_JACK_HEADPHONE,
@@ -216,7 +215,7 @@ static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
216 wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE, 215 wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE,
217 SND_JACK_BTN_0); 216 SND_JACK_BTN_0);
218 217
219 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); 218 snd_soc_dapm_force_enable_pin(&rtd->card->dapm, "Mic Bias");
220 219
221 return 0; 220 return 0;
222} 221}
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index c49a408fc7a6..33feee9ca8c3 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -125,14 +125,6 @@ static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
125{ 125{
126 int ret; 126 int ret;
127 127
128 if (set->fmt) {
129 ret = snd_soc_dai_set_fmt(dai, set->fmt);
130 if (ret && ret != -ENOTSUPP) {
131 dev_err(dai->dev, "simple-card: set_fmt error\n");
132 goto err;
133 }
134 }
135
136 if (set->sysclk) { 128 if (set->sysclk) {
137 ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0); 129 ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0);
138 if (ret && ret != -ENOTSUPP) { 130 if (ret && ret != -ENOTSUPP) {
@@ -269,12 +261,10 @@ static int asoc_simple_card_parse_daifmt(struct device_node *node,
269 struct device_node *codec, 261 struct device_node *codec,
270 char *prefix, int idx) 262 char *prefix, int idx)
271{ 263{
264 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
272 struct device *dev = simple_priv_to_dev(priv); 265 struct device *dev = simple_priv_to_dev(priv);
273 struct device_node *bitclkmaster = NULL; 266 struct device_node *bitclkmaster = NULL;
274 struct device_node *framemaster = NULL; 267 struct device_node *framemaster = NULL;
275 struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx);
276 struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai;
277 struct asoc_simple_dai *codec_dai = &dai_props->codec_dai;
278 unsigned int daifmt; 268 unsigned int daifmt;
279 269
280 daifmt = snd_soc_of_parse_daifmt(node, prefix, 270 daifmt = snd_soc_of_parse_daifmt(node, prefix,
@@ -289,8 +279,7 @@ static int asoc_simple_card_parse_daifmt(struct device_node *node,
289 */ 279 */
290 dev_dbg(dev, "Revert to legacy daifmt parsing\n"); 280 dev_dbg(dev, "Revert to legacy daifmt parsing\n");
291 281
292 cpu_dai->fmt = codec_dai->fmt = 282 daifmt = snd_soc_of_parse_daifmt(codec, NULL, NULL, NULL) |
293 snd_soc_of_parse_daifmt(codec, NULL, NULL, NULL) |
294 (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK); 283 (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK);
295 } else { 284 } else {
296 if (codec == bitclkmaster) 285 if (codec == bitclkmaster)
@@ -299,11 +288,10 @@ static int asoc_simple_card_parse_daifmt(struct device_node *node,
299 else 288 else
300 daifmt |= (codec == framemaster) ? 289 daifmt |= (codec == framemaster) ?
301 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; 290 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
302
303 cpu_dai->fmt = daifmt;
304 codec_dai->fmt = daifmt;
305 } 291 }
306 292
293 dai_link->dai_fmt = daifmt;
294
307 of_node_put(bitclkmaster); 295 of_node_put(bitclkmaster);
308 of_node_put(framemaster); 296 of_node_put(framemaster);
309 297
@@ -384,13 +372,12 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
384 dai_link->init = asoc_simple_card_dai_init; 372 dai_link->init = asoc_simple_card_dai_init;
385 373
386 dev_dbg(dev, "\tname : %s\n", dai_link->stream_name); 374 dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
387 dev_dbg(dev, "\tcpu : %s / %04x / %d\n", 375 dev_dbg(dev, "\tformat : %04x\n", dai_link->dai_fmt);
376 dev_dbg(dev, "\tcpu : %s / %d\n",
388 dai_link->cpu_dai_name, 377 dai_link->cpu_dai_name,
389 dai_props->cpu_dai.fmt,
390 dai_props->cpu_dai.sysclk); 378 dai_props->cpu_dai.sysclk);
391 dev_dbg(dev, "\tcodec : %s / %04x / %d\n", 379 dev_dbg(dev, "\tcodec : %s / %d\n",
392 dai_link->codec_dai_name, 380 dai_link->codec_dai_name,
393 dai_props->codec_dai.fmt,
394 dai_props->codec_dai.sysclk); 381 dai_props->codec_dai.sysclk);
395 382
396 /* 383 /*
@@ -577,14 +564,13 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
577 dai_link->codec_name = cinfo->codec; 564 dai_link->codec_name = cinfo->codec;
578 dai_link->cpu_dai_name = cinfo->cpu_dai.name; 565 dai_link->cpu_dai_name = cinfo->cpu_dai.name;
579 dai_link->codec_dai_name = cinfo->codec_dai.name; 566 dai_link->codec_dai_name = cinfo->codec_dai.name;
567 dai_link->dai_fmt = cinfo->daifmt;
580 dai_link->init = asoc_simple_card_dai_init; 568 dai_link->init = asoc_simple_card_dai_init;
581 memcpy(&priv->dai_props->cpu_dai, &cinfo->cpu_dai, 569 memcpy(&priv->dai_props->cpu_dai, &cinfo->cpu_dai,
582 sizeof(priv->dai_props->cpu_dai)); 570 sizeof(priv->dai_props->cpu_dai));
583 memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai, 571 memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai,
584 sizeof(priv->dai_props->codec_dai)); 572 sizeof(priv->dai_props->codec_dai));
585 573
586 priv->dai_props->cpu_dai.fmt |= cinfo->daifmt;
587 priv->dai_props->codec_dai.fmt |= cinfo->daifmt;
588 } 574 }
589 575
590 snd_soc_card_set_drvdata(&priv->snd_card, priv); 576 snd_soc_card_set_drvdata(&priv->snd_card, priv);
diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile
index a8e53c45c6b6..cd9aee9871a3 100644
--- a/sound/soc/intel/Makefile
+++ b/sound/soc/intel/Makefile
@@ -1,42 +1,10 @@
1# Core support 1# Core support
2snd-soc-sst-dsp-objs := sst-dsp.o sst-firmware.o 2obj-$(CONFIG_SND_SOC_INTEL_SST) += common/
3snd-soc-sst-acpi-objs := sst-acpi.o
4
5snd-soc-sst-mfld-platform-objs := sst-mfld-platform-pcm.o \
6 sst-mfld-platform-compress.o sst-atom-controls.o
7snd-soc-mfld-machine-objs := mfld_machine.o
8
9obj-$(CONFIG_SND_SST_MFLD_PLATFORM) += snd-soc-sst-mfld-platform.o
10obj-$(CONFIG_SND_MFLD_MACHINE) += snd-soc-mfld-machine.o
11
12obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o
13obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o
14 3
15# Platform Support 4# Platform Support
16snd-soc-sst-haswell-pcm-objs := \ 5obj-$(CONFIG_SND_SOC_INTEL_HASWELL) += haswell/
17 sst-haswell-ipc.o sst-haswell-pcm.o sst-haswell-dsp.o 6obj-$(CONFIG_SND_SOC_INTEL_BAYTRAIL) += baytrail/
18snd-soc-sst-baytrail-pcm-objs := \ 7obj-$(CONFIG_SND_SOC_INTEL_BAYTRAIL) += atom/
19 sst-baytrail-ipc.o sst-baytrail-pcm.o sst-baytrail-dsp.o
20
21obj-$(CONFIG_SND_SOC_INTEL_HASWELL) += snd-soc-sst-haswell-pcm.o
22obj-$(CONFIG_SND_SOC_INTEL_BAYTRAIL) += snd-soc-sst-baytrail-pcm.o
23 8
24# Machine support 9# Machine support
25snd-soc-sst-haswell-objs := haswell.o 10obj-$(CONFIG_SND_SOC_INTEL_SST) += boards/
26snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o
27snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o
28snd-soc-sst-broadwell-objs := broadwell.o
29snd-soc-sst-bytcr-dpcm-rt5640-objs := bytcr_dpcm_rt5640.o
30snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
31snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o
32
33obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
34obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
35obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o
36obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o
37obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-dpcm-rt5640.o
38obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
39obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o
40
41# DSP driver
42obj-$(CONFIG_SND_SST_IPC) += sst/
diff --git a/sound/soc/intel/atom/Makefile b/sound/soc/intel/atom/Makefile
new file mode 100644
index 000000000000..ce8074fa6d66
--- /dev/null
+++ b/sound/soc/intel/atom/Makefile
@@ -0,0 +1,7 @@
1snd-soc-sst-mfld-platform-objs := sst-mfld-platform-pcm.o \
2 sst-mfld-platform-compress.o sst-atom-controls.o
3
4obj-$(CONFIG_SND_SST_MFLD_PLATFORM) += snd-soc-sst-mfld-platform.o
5
6# DSP driver
7obj-$(CONFIG_SND_SST_IPC) += sst/
diff --git a/sound/soc/intel/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c
index 90aa5c0476f3..90aa5c0476f3 100644
--- a/sound/soc/intel/sst-atom-controls.c
+++ b/sound/soc/intel/atom/sst-atom-controls.c
diff --git a/sound/soc/intel/sst-atom-controls.h b/sound/soc/intel/atom/sst-atom-controls.h
index daecc58f28af..daecc58f28af 100644
--- a/sound/soc/intel/sst-atom-controls.h
+++ b/sound/soc/intel/atom/sst-atom-controls.h
diff --git a/sound/soc/intel/sst-mfld-dsp.h b/sound/soc/intel/atom/sst-mfld-dsp.h
index 4257263157cd..4257263157cd 100644
--- a/sound/soc/intel/sst-mfld-dsp.h
+++ b/sound/soc/intel/atom/sst-mfld-dsp.h
diff --git a/sound/soc/intel/sst-mfld-platform-compress.c b/sound/soc/intel/atom/sst-mfld-platform-compress.c
index 395168986462..395168986462 100644
--- a/sound/soc/intel/sst-mfld-platform-compress.c
+++ b/sound/soc/intel/atom/sst-mfld-platform-compress.c
diff --git a/sound/soc/intel/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
index 2fbaf2c75d17..2fbaf2c75d17 100644
--- a/sound/soc/intel/sst-mfld-platform-pcm.c
+++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
diff --git a/sound/soc/intel/sst-mfld-platform.h b/sound/soc/intel/atom/sst-mfld-platform.h
index 9094314be2b0..9094314be2b0 100644
--- a/sound/soc/intel/sst-mfld-platform.h
+++ b/sound/soc/intel/atom/sst-mfld-platform.h
diff --git a/sound/soc/intel/sst/Makefile b/sound/soc/intel/atom/sst/Makefile
index fd21726361b5..fd21726361b5 100644
--- a/sound/soc/intel/sst/Makefile
+++ b/sound/soc/intel/atom/sst/Makefile
diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/atom/sst/sst.c
index 1a7eeec444b1..96c2e420cce6 100644
--- a/sound/soc/intel/sst/sst.c
+++ b/sound/soc/intel/atom/sst/sst.c
@@ -32,7 +32,7 @@
32#include <asm/platform_sst_audio.h> 32#include <asm/platform_sst_audio.h>
33#include "../sst-mfld-platform.h" 33#include "../sst-mfld-platform.h"
34#include "sst.h" 34#include "sst.h"
35#include "../sst-dsp.h" 35#include "../../common/sst-dsp.h"
36 36
37MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>"); 37MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
38MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>"); 38MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
diff --git a/sound/soc/intel/sst/sst.h b/sound/soc/intel/atom/sst/sst.h
index 3f493862e98d..3f493862e98d 100644
--- a/sound/soc/intel/sst/sst.h
+++ b/sound/soc/intel/atom/sst/sst.h
diff --git a/sound/soc/intel/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
index b782dfdcdbba..05f693083911 100644
--- a/sound/soc/intel/sst/sst_acpi.c
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
@@ -39,7 +39,7 @@
39#include <acpi/actypes.h> 39#include <acpi/actypes.h>
40#include <acpi/acpi_bus.h> 40#include <acpi/acpi_bus.h>
41#include "../sst-mfld-platform.h" 41#include "../sst-mfld-platform.h"
42#include "../sst-dsp.h" 42#include "../../common/sst-dsp.h"
43#include "sst.h" 43#include "sst.h"
44 44
45struct sst_machines { 45struct sst_machines {
@@ -309,7 +309,7 @@ static int sst_acpi_probe(struct platform_device *pdev)
309 ctx->shim_regs64 = devm_kzalloc(ctx->dev, sizeof(*ctx->shim_regs64), 309 ctx->shim_regs64 = devm_kzalloc(ctx->dev, sizeof(*ctx->shim_regs64),
310 GFP_KERNEL); 310 GFP_KERNEL);
311 if (!ctx->shim_regs64) { 311 if (!ctx->shim_regs64) {
312 return -ENOMEM; 312 ret = -ENOMEM;
313 goto do_sst_cleanup; 313 goto do_sst_cleanup;
314 } 314 }
315 315
diff --git a/sound/soc/intel/sst/sst_drv_interface.c b/sound/soc/intel/atom/sst/sst_drv_interface.c
index f0e4b99b3aeb..7b50a9d17ec1 100644
--- a/sound/soc/intel/sst/sst_drv_interface.c
+++ b/sound/soc/intel/atom/sst/sst_drv_interface.c
@@ -32,7 +32,7 @@
32#include <asm/platform_sst_audio.h> 32#include <asm/platform_sst_audio.h>
33#include "../sst-mfld-platform.h" 33#include "../sst-mfld-platform.h"
34#include "sst.h" 34#include "sst.h"
35#include "../sst-dsp.h" 35#include "../../common/sst-dsp.h"
36 36
37 37
38 38
@@ -381,7 +381,7 @@ static int sst_cdev_tstamp(struct device *dev, unsigned int str_id,
381 tstamp->copied_total = fw_tstamp.ring_buffer_counter; 381 tstamp->copied_total = fw_tstamp.ring_buffer_counter;
382 tstamp->pcm_frames = fw_tstamp.frames_decoded; 382 tstamp->pcm_frames = fw_tstamp.frames_decoded;
383 tstamp->pcm_io_frames = div_u64(fw_tstamp.hardware_counter, 383 tstamp->pcm_io_frames = div_u64(fw_tstamp.hardware_counter,
384 (u64)((stream->num_ch) * SST_GET_BYTES_PER_SAMPLE(24))); 384 (u64)stream->num_ch * SST_GET_BYTES_PER_SAMPLE(24));
385 tstamp->sampling_rate = fw_tstamp.sampling_frequency; 385 tstamp->sampling_rate = fw_tstamp.sampling_frequency;
386 386
387 dev_dbg(dev, "PCM = %u\n", tstamp->pcm_io_frames); 387 dev_dbg(dev, "PCM = %u\n", tstamp->pcm_io_frames);
diff --git a/sound/soc/intel/sst/sst_ipc.c b/sound/soc/intel/atom/sst/sst_ipc.c
index 484e60978477..5a278618466c 100644
--- a/sound/soc/intel/sst/sst_ipc.c
+++ b/sound/soc/intel/atom/sst/sst_ipc.c
@@ -32,7 +32,7 @@
32#include <asm/platform_sst_audio.h> 32#include <asm/platform_sst_audio.h>
33#include "../sst-mfld-platform.h" 33#include "../sst-mfld-platform.h"
34#include "sst.h" 34#include "sst.h"
35#include "../sst-dsp.h" 35#include "../../common/sst-dsp.h"
36 36
37struct sst_block *sst_create_block(struct intel_sst_drv *ctx, 37struct sst_block *sst_create_block(struct intel_sst_drv *ctx,
38 u32 msg_id, u32 drv_id) 38 u32 msg_id, u32 drv_id)
diff --git a/sound/soc/intel/sst/sst_loader.c b/sound/soc/intel/atom/sst/sst_loader.c
index e88907ae8b15..33917146d9c4 100644
--- a/sound/soc/intel/sst/sst_loader.c
+++ b/sound/soc/intel/atom/sst/sst_loader.c
@@ -37,7 +37,7 @@
37#include <asm/platform_sst_audio.h> 37#include <asm/platform_sst_audio.h>
38#include "../sst-mfld-platform.h" 38#include "../sst-mfld-platform.h"
39#include "sst.h" 39#include "sst.h"
40#include "../sst-dsp.h" 40#include "../../common/sst-dsp.h"
41 41
42void memcpy32_toio(void __iomem *dst, const void *src, int count) 42void memcpy32_toio(void __iomem *dst, const void *src, int count)
43{ 43{
diff --git a/sound/soc/intel/sst/sst_pci.c b/sound/soc/intel/atom/sst/sst_pci.c
index 3a0b3bf0af97..3a0b3bf0af97 100644
--- a/sound/soc/intel/sst/sst_pci.c
+++ b/sound/soc/intel/atom/sst/sst_pci.c
diff --git a/sound/soc/intel/sst/sst_pvt.c b/sound/soc/intel/atom/sst/sst_pvt.c
index 4b7720864492..adb32fefd693 100644
--- a/sound/soc/intel/sst/sst_pvt.c
+++ b/sound/soc/intel/atom/sst/sst_pvt.c
@@ -34,7 +34,7 @@
34#include <asm/platform_sst_audio.h> 34#include <asm/platform_sst_audio.h>
35#include "../sst-mfld-platform.h" 35#include "../sst-mfld-platform.h"
36#include "sst.h" 36#include "sst.h"
37#include "../sst-dsp.h" 37#include "../../common/sst-dsp.h"
38 38
39int sst_shim_write(void __iomem *addr, int offset, int value) 39int sst_shim_write(void __iomem *addr, int offset, int value)
40{ 40{
@@ -111,30 +111,6 @@ int sst_wait_interruptible(struct intel_sst_drv *sst_drv_ctx,
111 111
112} 112}
113 113
114unsigned long long read_shim_data(struct intel_sst_drv *sst, int addr)
115{
116 unsigned long long val = 0;
117
118 switch (sst->dev_id) {
119 case SST_MRFLD_PCI_ID:
120 case SST_BYT_ACPI_ID:
121 val = sst_shim_read64(sst->shim, addr);
122 break;
123 }
124 return val;
125}
126
127void write_shim_data(struct intel_sst_drv *sst, int addr,
128 unsigned long long data)
129{
130 switch (sst->dev_id) {
131 case SST_MRFLD_PCI_ID:
132 case SST_BYT_ACPI_ID:
133 sst_shim_write64(sst->shim, addr, (u64) data);
134 break;
135 }
136}
137
138/* 114/*
139 * sst_wait_timeout - wait on event for timeout 115 * sst_wait_timeout - wait on event for timeout
140 * 116 *
diff --git a/sound/soc/intel/sst/sst_stream.c b/sound/soc/intel/atom/sst/sst_stream.c
index dae2a41997aa..a74c64c7053c 100644
--- a/sound/soc/intel/sst/sst_stream.c
+++ b/sound/soc/intel/atom/sst/sst_stream.c
@@ -31,7 +31,7 @@
31#include <asm/platform_sst_audio.h> 31#include <asm/platform_sst_audio.h>
32#include "../sst-mfld-platform.h" 32#include "../sst-mfld-platform.h"
33#include "sst.h" 33#include "sst.h"
34#include "../sst-dsp.h" 34#include "../../common/sst-dsp.h"
35 35
36int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params) 36int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params)
37{ 37{
diff --git a/sound/soc/intel/baytrail/Makefile b/sound/soc/intel/baytrail/Makefile
new file mode 100644
index 000000000000..488408cadf6d
--- /dev/null
+++ b/sound/soc/intel/baytrail/Makefile
@@ -0,0 +1,4 @@
1snd-soc-sst-baytrail-pcm-objs := \
2 sst-baytrail-ipc.o sst-baytrail-pcm.o sst-baytrail-dsp.o
3
4obj-$(CONFIG_SND_SOC_INTEL_BAYTRAIL) += snd-soc-sst-baytrail-pcm.o
diff --git a/sound/soc/intel/sst-baytrail-dsp.c b/sound/soc/intel/baytrail/sst-baytrail-dsp.c
index 5a9e56700f31..01d023cc05dd 100644
--- a/sound/soc/intel/sst-baytrail-dsp.c
+++ b/sound/soc/intel/baytrail/sst-baytrail-dsp.c
@@ -22,8 +22,8 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/firmware.h> 23#include <linux/firmware.h>
24 24
25#include "sst-dsp.h" 25#include "../common/sst-dsp.h"
26#include "sst-dsp-priv.h" 26#include "../common/sst-dsp-priv.h"
27#include "sst-baytrail-ipc.h" 27#include "sst-baytrail-ipc.h"
28 28
29#define SST_BYT_FW_SIGNATURE_SIZE 4 29#define SST_BYT_FW_SIGNATURE_SIZE 4
diff --git a/sound/soc/intel/sst-baytrail-ipc.c b/sound/soc/intel/baytrail/sst-baytrail-ipc.c
index b4ad98c43e5c..1efb33b36303 100644
--- a/sound/soc/intel/sst-baytrail-ipc.c
+++ b/sound/soc/intel/baytrail/sst-baytrail-ipc.c
@@ -29,8 +29,9 @@
29#include <asm/div64.h> 29#include <asm/div64.h>
30 30
31#include "sst-baytrail-ipc.h" 31#include "sst-baytrail-ipc.h"
32#include "sst-dsp.h" 32#include "../common/sst-dsp.h"
33#include "sst-dsp-priv.h" 33#include "../common/sst-dsp-priv.h"
34#include "../common/sst-ipc.h"
34 35
35/* IPC message timeout */ 36/* IPC message timeout */
36#define IPC_TIMEOUT_MSECS 300 37#define IPC_TIMEOUT_MSECS 300
@@ -142,23 +143,6 @@ struct sst_byt_fw_init {
142 u8 debug_info; 143 u8 debug_info;
143} __packed; 144} __packed;
144 145
145/* driver internal IPC message structure */
146struct ipc_message {
147 struct list_head list;
148 u64 header;
149
150 /* direction wrt host CPU */
151 char tx_data[SST_BYT_IPC_MAX_PAYLOAD_SIZE];
152 size_t tx_size;
153 char rx_data[SST_BYT_IPC_MAX_PAYLOAD_SIZE];
154 size_t rx_size;
155
156 wait_queue_head_t waitq;
157 bool complete;
158 bool wait;
159 int errno;
160};
161
162struct sst_byt_stream; 146struct sst_byt_stream;
163struct sst_byt; 147struct sst_byt;
164 148
@@ -195,14 +179,7 @@ struct sst_byt {
195 struct sst_fw *fw; 179 struct sst_fw *fw;
196 180
197 /* IPC messaging */ 181 /* IPC messaging */
198 struct list_head tx_list; 182 struct sst_generic_ipc ipc;
199 struct list_head rx_list;
200 struct list_head empty_list;
201 wait_queue_head_t wait_txq;
202 struct task_struct *tx_thread;
203 struct kthread_worker kworker;
204 struct kthread_work kwork;
205 struct ipc_message *msg;
206}; 183};
207 184
208static inline u64 sst_byt_header(int msg_id, int data, bool large, int str_id) 185static inline u64 sst_byt_header(int msg_id, int data, bool large, int str_id)
@@ -246,209 +223,6 @@ static struct sst_byt_stream *sst_byt_get_stream(struct sst_byt *byt,
246 return NULL; 223 return NULL;
247} 224}
248 225
249static void sst_byt_ipc_shim_dbg(struct sst_byt *byt, const char *text)
250{
251 struct sst_dsp *sst = byt->dsp;
252 u64 isr, ipcd, imrx, ipcx;
253
254 ipcx = sst_dsp_shim_read64_unlocked(sst, SST_IPCX);
255 isr = sst_dsp_shim_read64_unlocked(sst, SST_ISRX);
256 ipcd = sst_dsp_shim_read64_unlocked(sst, SST_IPCD);
257 imrx = sst_dsp_shim_read64_unlocked(sst, SST_IMRX);
258
259 dev_err(byt->dev,
260 "ipc: --%s-- ipcx 0x%llx isr 0x%llx ipcd 0x%llx imrx 0x%llx\n",
261 text, ipcx, isr, ipcd, imrx);
262}
263
264/* locks held by caller */
265static struct ipc_message *sst_byt_msg_get_empty(struct sst_byt *byt)
266{
267 struct ipc_message *msg = NULL;
268
269 if (!list_empty(&byt->empty_list)) {
270 msg = list_first_entry(&byt->empty_list,
271 struct ipc_message, list);
272 list_del(&msg->list);
273 }
274
275 return msg;
276}
277
278static void sst_byt_ipc_tx_msgs(struct kthread_work *work)
279{
280 struct sst_byt *byt =
281 container_of(work, struct sst_byt, kwork);
282 struct ipc_message *msg;
283 u64 ipcx;
284 unsigned long flags;
285
286 spin_lock_irqsave(&byt->dsp->spinlock, flags);
287 if (list_empty(&byt->tx_list)) {
288 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
289 return;
290 }
291
292 /* if the DSP is busy we will TX messages after IRQ */
293 ipcx = sst_dsp_shim_read64_unlocked(byt->dsp, SST_IPCX);
294 if (ipcx & SST_BYT_IPCX_BUSY) {
295 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
296 return;
297 }
298
299 msg = list_first_entry(&byt->tx_list, struct ipc_message, list);
300
301 list_move(&msg->list, &byt->rx_list);
302
303 /* send the message */
304 if (msg->header & IPC_HEADER_LARGE(true))
305 sst_dsp_outbox_write(byt->dsp, msg->tx_data, msg->tx_size);
306 sst_dsp_shim_write64_unlocked(byt->dsp, SST_IPCX, msg->header);
307
308 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
309}
310
311static inline void sst_byt_tx_msg_reply_complete(struct sst_byt *byt,
312 struct ipc_message *msg)
313{
314 msg->complete = true;
315
316 if (!msg->wait)
317 list_add_tail(&msg->list, &byt->empty_list);
318 else
319 wake_up(&msg->waitq);
320}
321
322static void sst_byt_drop_all(struct sst_byt *byt)
323{
324 struct ipc_message *msg, *tmp;
325 unsigned long flags;
326
327 /* drop all TX and Rx messages before we stall + reset DSP */
328 spin_lock_irqsave(&byt->dsp->spinlock, flags);
329 list_for_each_entry_safe(msg, tmp, &byt->tx_list, list) {
330 list_move(&msg->list, &byt->empty_list);
331 }
332
333 list_for_each_entry_safe(msg, tmp, &byt->rx_list, list) {
334 list_move(&msg->list, &byt->empty_list);
335 }
336
337 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
338}
339
340static int sst_byt_tx_wait_done(struct sst_byt *byt, struct ipc_message *msg,
341 void *rx_data)
342{
343 unsigned long flags;
344 int ret;
345
346 /* wait for DSP completion */
347 ret = wait_event_timeout(msg->waitq, msg->complete,
348 msecs_to_jiffies(IPC_TIMEOUT_MSECS));
349
350 spin_lock_irqsave(&byt->dsp->spinlock, flags);
351 if (ret == 0) {
352 list_del(&msg->list);
353 sst_byt_ipc_shim_dbg(byt, "message timeout");
354
355 ret = -ETIMEDOUT;
356 } else {
357
358 /* copy the data returned from DSP */
359 if (msg->rx_size)
360 memcpy(rx_data, msg->rx_data, msg->rx_size);
361 ret = msg->errno;
362 }
363
364 list_add_tail(&msg->list, &byt->empty_list);
365 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
366 return ret;
367}
368
369static int sst_byt_ipc_tx_message(struct sst_byt *byt, u64 header,
370 void *tx_data, size_t tx_bytes,
371 void *rx_data, size_t rx_bytes, int wait)
372{
373 unsigned long flags;
374 struct ipc_message *msg;
375
376 spin_lock_irqsave(&byt->dsp->spinlock, flags);
377
378 msg = sst_byt_msg_get_empty(byt);
379 if (msg == NULL) {
380 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
381 return -EBUSY;
382 }
383
384 msg->header = header;
385 msg->tx_size = tx_bytes;
386 msg->rx_size = rx_bytes;
387 msg->wait = wait;
388 msg->errno = 0;
389 msg->complete = false;
390
391 if (tx_bytes) {
392 /* msg content = lower 32-bit of the header + data */
393 *(u32 *)msg->tx_data = (u32)(header & (u32)-1);
394 memcpy(msg->tx_data + sizeof(u32), tx_data, tx_bytes);
395 msg->tx_size += sizeof(u32);
396 }
397
398 list_add_tail(&msg->list, &byt->tx_list);
399 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
400
401 queue_kthread_work(&byt->kworker, &byt->kwork);
402
403 if (wait)
404 return sst_byt_tx_wait_done(byt, msg, rx_data);
405 else
406 return 0;
407}
408
409static inline int sst_byt_ipc_tx_msg_wait(struct sst_byt *byt, u64 header,
410 void *tx_data, size_t tx_bytes,
411 void *rx_data, size_t rx_bytes)
412{
413 return sst_byt_ipc_tx_message(byt, header, tx_data, tx_bytes,
414 rx_data, rx_bytes, 1);
415}
416
417static inline int sst_byt_ipc_tx_msg_nowait(struct sst_byt *byt, u64 header,
418 void *tx_data, size_t tx_bytes)
419{
420 return sst_byt_ipc_tx_message(byt, header, tx_data, tx_bytes,
421 NULL, 0, 0);
422}
423
424static struct ipc_message *sst_byt_reply_find_msg(struct sst_byt *byt,
425 u64 header)
426{
427 struct ipc_message *msg = NULL, *_msg;
428 u64 mask;
429
430 /* match reply to message sent based on msg and stream IDs */
431 mask = IPC_HEADER_MSG_ID_MASK |
432 IPC_HEADER_STR_ID_MASK << IPC_HEADER_STR_ID_SHIFT;
433 header &= mask;
434
435 if (list_empty(&byt->rx_list)) {
436 dev_err(byt->dev,
437 "ipc: rx list is empty but received 0x%llx\n", header);
438 goto out;
439 }
440
441 list_for_each_entry(_msg, &byt->rx_list, list) {
442 if ((_msg->header & mask) == header) {
443 msg = _msg;
444 break;
445 }
446 }
447
448out:
449 return msg;
450}
451
452static void sst_byt_stream_update(struct sst_byt *byt, struct ipc_message *msg) 226static void sst_byt_stream_update(struct sst_byt *byt, struct ipc_message *msg)
453{ 227{
454 struct sst_byt_stream *stream; 228 struct sst_byt_stream *stream;
@@ -477,7 +251,7 @@ static int sst_byt_process_reply(struct sst_byt *byt, u64 header)
477{ 251{
478 struct ipc_message *msg; 252 struct ipc_message *msg;
479 253
480 msg = sst_byt_reply_find_msg(byt, header); 254 msg = sst_ipc_reply_find_msg(&byt->ipc, header);
481 if (msg == NULL) 255 if (msg == NULL)
482 return 1; 256 return 1;
483 257
@@ -491,7 +265,7 @@ static int sst_byt_process_reply(struct sst_byt *byt, u64 header)
491 265
492 list_del(&msg->list); 266 list_del(&msg->list);
493 /* wake up */ 267 /* wake up */
494 sst_byt_tx_msg_reply_complete(byt, msg); 268 sst_ipc_tx_msg_reply_complete(&byt->ipc, msg);
495 269
496 return 1; 270 return 1;
497} 271}
@@ -538,6 +312,7 @@ static irqreturn_t sst_byt_irq_thread(int irq, void *context)
538{ 312{
539 struct sst_dsp *sst = (struct sst_dsp *) context; 313 struct sst_dsp *sst = (struct sst_dsp *) context;
540 struct sst_byt *byt = sst_dsp_get_thread_context(sst); 314 struct sst_byt *byt = sst_dsp_get_thread_context(sst);
315 struct sst_generic_ipc *ipc = &byt->ipc;
541 u64 header; 316 u64 header;
542 unsigned long flags; 317 unsigned long flags;
543 318
@@ -569,7 +344,7 @@ static irqreturn_t sst_byt_irq_thread(int irq, void *context)
569 spin_unlock_irqrestore(&sst->spinlock, flags); 344 spin_unlock_irqrestore(&sst->spinlock, flags);
570 345
571 /* continue to send any remaining messages... */ 346 /* continue to send any remaining messages... */
572 queue_kthread_work(&byt->kworker, &byt->kwork); 347 queue_kthread_work(&ipc->kworker, &ipc->kwork);
573 348
574 return IRQ_HANDLED; 349 return IRQ_HANDLED;
575} 350}
@@ -656,7 +431,8 @@ int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream)
656 header = sst_byt_header(IPC_IA_ALLOC_STREAM, 431 header = sst_byt_header(IPC_IA_ALLOC_STREAM,
657 sizeof(*str_req) + sizeof(u32), 432 sizeof(*str_req) + sizeof(u32),
658 true, stream->str_id); 433 true, stream->str_id);
659 ret = sst_byt_ipc_tx_msg_wait(byt, header, str_req, sizeof(*str_req), 434 ret = sst_ipc_tx_message_wait(&byt->ipc, header, str_req,
435 sizeof(*str_req),
660 reply, sizeof(*reply)); 436 reply, sizeof(*reply));
661 if (ret < 0) { 437 if (ret < 0) {
662 dev_err(byt->dev, "ipc: error stream commit failed\n"); 438 dev_err(byt->dev, "ipc: error stream commit failed\n");
@@ -679,7 +455,7 @@ int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream)
679 goto out; 455 goto out;
680 456
681 header = sst_byt_header(IPC_IA_FREE_STREAM, 0, false, stream->str_id); 457 header = sst_byt_header(IPC_IA_FREE_STREAM, 0, false, stream->str_id);
682 ret = sst_byt_ipc_tx_msg_wait(byt, header, NULL, 0, NULL, 0); 458 ret = sst_ipc_tx_message_wait(&byt->ipc, header, NULL, 0, NULL, 0);
683 if (ret < 0) { 459 if (ret < 0) {
684 dev_err(byt->dev, "ipc: free stream %d failed\n", 460 dev_err(byt->dev, "ipc: free stream %d failed\n",
685 stream->str_id); 461 stream->str_id);
@@ -703,9 +479,11 @@ static int sst_byt_stream_operations(struct sst_byt *byt, int type,
703 479
704 header = sst_byt_header(type, 0, false, stream_id); 480 header = sst_byt_header(type, 0, false, stream_id);
705 if (wait) 481 if (wait)
706 return sst_byt_ipc_tx_msg_wait(byt, header, NULL, 0, NULL, 0); 482 return sst_ipc_tx_message_wait(&byt->ipc, header, NULL,
483 0, NULL, 0);
707 else 484 else
708 return sst_byt_ipc_tx_msg_nowait(byt, header, NULL, 0); 485 return sst_ipc_tx_message_nowait(&byt->ipc, header,
486 NULL, 0);
709} 487}
710 488
711/* stream ALSA trigger operations */ 489/* stream ALSA trigger operations */
@@ -725,7 +503,7 @@ int sst_byt_stream_start(struct sst_byt *byt, struct sst_byt_stream *stream,
725 tx_msg = &start_stream; 503 tx_msg = &start_stream;
726 size = sizeof(start_stream); 504 size = sizeof(start_stream);
727 505
728 ret = sst_byt_ipc_tx_msg_nowait(byt, header, tx_msg, size); 506 ret = sst_ipc_tx_message_nowait(&byt->ipc, header, tx_msg, size);
729 if (ret < 0) 507 if (ret < 0)
730 dev_err(byt->dev, "ipc: error failed to start stream %d\n", 508 dev_err(byt->dev, "ipc: error failed to start stream %d\n",
731 stream->str_id); 509 stream->str_id);
@@ -790,23 +568,6 @@ int sst_byt_get_dsp_position(struct sst_byt *byt,
790 return do_div(fw_tstamp.ring_buffer_counter, buffer_size); 568 return do_div(fw_tstamp.ring_buffer_counter, buffer_size);
791} 569}
792 570
793static int msg_empty_list_init(struct sst_byt *byt)
794{
795 struct ipc_message *msg;
796 int i;
797
798 byt->msg = kzalloc(sizeof(*msg) * IPC_EMPTY_LIST_SIZE, GFP_KERNEL);
799 if (byt->msg == NULL)
800 return -ENOMEM;
801
802 for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
803 init_waitqueue_head(&byt->msg[i].waitq);
804 list_add(&byt->msg[i].list, &byt->empty_list);
805 }
806
807 return 0;
808}
809
810struct sst_dsp *sst_byt_get_dsp(struct sst_byt *byt) 571struct sst_dsp *sst_byt_get_dsp(struct sst_byt *byt)
811{ 572{
812 return byt->dsp; 573 return byt->dsp;
@@ -823,7 +584,7 @@ int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata)
823 584
824 dev_dbg(byt->dev, "dsp reset\n"); 585 dev_dbg(byt->dev, "dsp reset\n");
825 sst_dsp_reset(byt->dsp); 586 sst_dsp_reset(byt->dsp);
826 sst_byt_drop_all(byt); 587 sst_ipc_drop_all(&byt->ipc);
827 dev_dbg(byt->dev, "dsp in reset\n"); 588 dev_dbg(byt->dev, "dsp in reset\n");
828 589
829 dev_dbg(byt->dev, "free all blocks and unload fw\n"); 590 dev_dbg(byt->dev, "free all blocks and unload fw\n");
@@ -876,9 +637,52 @@ int sst_byt_dsp_wait_for_ready(struct device *dev, struct sst_pdata *pdata)
876} 637}
877EXPORT_SYMBOL_GPL(sst_byt_dsp_wait_for_ready); 638EXPORT_SYMBOL_GPL(sst_byt_dsp_wait_for_ready);
878 639
640static void byt_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
641{
642 if (msg->header & IPC_HEADER_LARGE(true))
643 sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size);
644
645 sst_dsp_shim_write64_unlocked(ipc->dsp, SST_IPCX, msg->header);
646}
647
648static void byt_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
649{
650 struct sst_dsp *sst = ipc->dsp;
651 u64 isr, ipcd, imrx, ipcx;
652
653 ipcx = sst_dsp_shim_read64_unlocked(sst, SST_IPCX);
654 isr = sst_dsp_shim_read64_unlocked(sst, SST_ISRX);
655 ipcd = sst_dsp_shim_read64_unlocked(sst, SST_IPCD);
656 imrx = sst_dsp_shim_read64_unlocked(sst, SST_IMRX);
657
658 dev_err(ipc->dev,
659 "ipc: --%s-- ipcx 0x%llx isr 0x%llx ipcd 0x%llx imrx 0x%llx\n",
660 text, ipcx, isr, ipcd, imrx);
661}
662
663static void byt_tx_data_copy(struct ipc_message *msg, char *tx_data,
664 size_t tx_size)
665{
666 /* msg content = lower 32-bit of the header + data */
667 *(u32 *)msg->tx_data = (u32)(msg->header & (u32)-1);
668 memcpy(msg->tx_data + sizeof(u32), tx_data, tx_size);
669 msg->tx_size += sizeof(u32);
670}
671
672static u64 byt_reply_msg_match(u64 header, u64 *mask)
673{
674 /* match reply to message sent based on msg and stream IDs */
675 *mask = IPC_HEADER_MSG_ID_MASK |
676 IPC_HEADER_STR_ID_MASK << IPC_HEADER_STR_ID_SHIFT;
677 header &= *mask;
678
679 return header;
680}
681
879int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata) 682int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata)
880{ 683{
881 struct sst_byt *byt; 684 struct sst_byt *byt;
685 struct sst_generic_ipc *ipc;
882 struct sst_fw *byt_sst_fw; 686 struct sst_fw *byt_sst_fw;
883 struct sst_byt_fw_init init; 687 struct sst_byt_fw_init init;
884 int err; 688 int err;
@@ -889,39 +693,30 @@ int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata)
889 if (byt == NULL) 693 if (byt == NULL)
890 return -ENOMEM; 694 return -ENOMEM;
891 695
892 byt->dev = dev; 696 ipc = &byt->ipc;
893 INIT_LIST_HEAD(&byt->stream_list); 697 ipc->dev = dev;
894 INIT_LIST_HEAD(&byt->tx_list); 698 ipc->ops.tx_msg = byt_tx_msg;
895 INIT_LIST_HEAD(&byt->rx_list); 699 ipc->ops.shim_dbg = byt_shim_dbg;
896 INIT_LIST_HEAD(&byt->empty_list); 700 ipc->ops.tx_data_copy = byt_tx_data_copy;
897 init_waitqueue_head(&byt->boot_wait); 701 ipc->ops.reply_msg_match = byt_reply_msg_match;
898 init_waitqueue_head(&byt->wait_txq);
899 702
900 err = msg_empty_list_init(byt); 703 err = sst_ipc_init(ipc);
901 if (err < 0) 704 if (err != 0)
902 return -ENOMEM; 705 goto ipc_init_err;
903
904 /* start the IPC message thread */
905 init_kthread_worker(&byt->kworker);
906 byt->tx_thread = kthread_run(kthread_worker_fn,
907 &byt->kworker, "%s",
908 dev_name(byt->dev));
909 if (IS_ERR(byt->tx_thread)) {
910 err = PTR_ERR(byt->tx_thread);
911 dev_err(byt->dev, "error failed to create message TX task\n");
912 goto err_free_msg;
913 }
914 init_kthread_work(&byt->kwork, sst_byt_ipc_tx_msgs);
915 706
707 INIT_LIST_HEAD(&byt->stream_list);
708 init_waitqueue_head(&byt->boot_wait);
916 byt_dev.thread_context = byt; 709 byt_dev.thread_context = byt;
917 710
918 /* init SST shim */ 711 /* init SST shim */
919 byt->dsp = sst_dsp_new(dev, &byt_dev, pdata); 712 byt->dsp = sst_dsp_new(dev, &byt_dev, pdata);
920 if (byt->dsp == NULL) { 713 if (byt->dsp == NULL) {
921 err = -ENODEV; 714 err = -ENODEV;
922 goto dsp_err; 715 goto dsp_new_err;
923 } 716 }
924 717
718 ipc->dsp = byt->dsp;
719
925 /* keep the DSP in reset state for base FW loading */ 720 /* keep the DSP in reset state for base FW loading */
926 sst_dsp_reset(byt->dsp); 721 sst_dsp_reset(byt->dsp);
927 722
@@ -961,10 +756,10 @@ boot_err:
961 sst_fw_free(byt_sst_fw); 756 sst_fw_free(byt_sst_fw);
962fw_err: 757fw_err:
963 sst_dsp_free(byt->dsp); 758 sst_dsp_free(byt->dsp);
964dsp_err: 759dsp_new_err:
965 kthread_stop(byt->tx_thread); 760 sst_ipc_fini(ipc);
966err_free_msg: 761ipc_init_err:
967 kfree(byt->msg); 762 kfree(byt);
968 763
969 return err; 764 return err;
970} 765}
@@ -977,7 +772,6 @@ void sst_byt_dsp_free(struct device *dev, struct sst_pdata *pdata)
977 sst_dsp_reset(byt->dsp); 772 sst_dsp_reset(byt->dsp);
978 sst_fw_free_all(byt->dsp); 773 sst_fw_free_all(byt->dsp);
979 sst_dsp_free(byt->dsp); 774 sst_dsp_free(byt->dsp);
980 kthread_stop(byt->tx_thread); 775 sst_ipc_fini(&byt->ipc);
981 kfree(byt->msg);
982} 776}
983EXPORT_SYMBOL_GPL(sst_byt_dsp_free); 777EXPORT_SYMBOL_GPL(sst_byt_dsp_free);
diff --git a/sound/soc/intel/sst-baytrail-ipc.h b/sound/soc/intel/baytrail/sst-baytrail-ipc.h
index 8faff6dcf25d..8faff6dcf25d 100644
--- a/sound/soc/intel/sst-baytrail-ipc.h
+++ b/sound/soc/intel/baytrail/sst-baytrail-ipc.h
diff --git a/sound/soc/intel/sst-baytrail-pcm.c b/sound/soc/intel/baytrail/sst-baytrail-pcm.c
index 224c49c9f135..79547bec558b 100644
--- a/sound/soc/intel/sst-baytrail-pcm.c
+++ b/sound/soc/intel/baytrail/sst-baytrail-pcm.c
@@ -20,8 +20,8 @@
20#include <sound/pcm_params.h> 20#include <sound/pcm_params.h>
21#include <sound/soc.h> 21#include <sound/soc.h>
22#include "sst-baytrail-ipc.h" 22#include "sst-baytrail-ipc.h"
23#include "sst-dsp-priv.h" 23#include "../common/sst-dsp-priv.h"
24#include "sst-dsp.h" 24#include "../common/sst-dsp.h"
25 25
26#define BYT_PCM_COUNT 2 26#define BYT_PCM_COUNT 2
27 27
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
new file mode 100644
index 000000000000..f8237f0044eb
--- /dev/null
+++ b/sound/soc/intel/boards/Makefile
@@ -0,0 +1,15 @@
1snd-soc-sst-haswell-objs := haswell.o
2snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o
3snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o
4snd-soc-sst-broadwell-objs := broadwell.o
5snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o
6snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
7snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o
8
9obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
10obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
11obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o
12obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o
13obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o
14obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
15obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o
diff --git a/sound/soc/intel/broadwell.c b/sound/soc/intel/boards/broadwell.c
index fc5542034b9b..8bafaf6ceab1 100644
--- a/sound/soc/intel/broadwell.c
+++ b/sound/soc/intel/boards/broadwell.c
@@ -22,10 +22,10 @@
22#include <sound/jack.h> 22#include <sound/jack.h>
23#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
24 24
25#include "sst-dsp.h" 25#include "../common/sst-dsp.h"
26#include "sst-haswell-ipc.h" 26#include "../haswell/sst-haswell-ipc.h"
27 27
28#include "../codecs/rt286.h" 28#include "../../codecs/rt286.h"
29 29
30static struct snd_soc_jack broadwell_headset; 30static struct snd_soc_jack broadwell_headset;
31/* Headset jack detection DAPM pins */ 31/* Headset jack detection DAPM pins */
@@ -219,6 +219,32 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = {
219 }, 219 },
220}; 220};
221 221
222static int broadwell_suspend(struct snd_soc_card *card){
223 struct snd_soc_codec *codec;
224
225 list_for_each_entry(codec, &card->codec_dev_list, card_list) {
226 if (!strcmp(codec->component.name, "i2c-INT343A:00")) {
227 dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n");
228 rt286_mic_detect(codec, NULL);
229 break;
230 }
231 }
232 return 0;
233}
234
235static int broadwell_resume(struct snd_soc_card *card){
236 struct snd_soc_codec *codec;
237
238 list_for_each_entry(codec, &card->codec_dev_list, card_list) {
239 if (!strcmp(codec->component.name, "i2c-INT343A:00")) {
240 dev_dbg(codec->dev, "enabling jack detect for resume.\n");
241 rt286_mic_detect(codec, &broadwell_headset);
242 break;
243 }
244 }
245 return 0;
246}
247
222/* broadwell audio machine driver for WPT + RT286S */ 248/* broadwell audio machine driver for WPT + RT286S */
223static struct snd_soc_card broadwell_rt286 = { 249static struct snd_soc_card broadwell_rt286 = {
224 .name = "broadwell-rt286", 250 .name = "broadwell-rt286",
@@ -232,6 +258,8 @@ static struct snd_soc_card broadwell_rt286 = {
232 .dapm_routes = broadwell_rt286_map, 258 .dapm_routes = broadwell_rt286_map,
233 .num_dapm_routes = ARRAY_SIZE(broadwell_rt286_map), 259 .num_dapm_routes = ARRAY_SIZE(broadwell_rt286_map),
234 .fully_routed = true, 260 .fully_routed = true,
261 .suspend_pre = broadwell_suspend,
262 .resume_post = broadwell_resume,
235}; 263};
236 264
237static int broadwell_audio_probe(struct platform_device *pdev) 265static int broadwell_audio_probe(struct platform_device *pdev)
diff --git a/sound/soc/intel/byt-max98090.c b/sound/soc/intel/boards/byt-max98090.c
index d8b1f038da1c..7ab8cc9fbfd5 100644
--- a/sound/soc/intel/byt-max98090.c
+++ b/sound/soc/intel/boards/byt-max98090.c
@@ -24,7 +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 <sound/jack.h> 26#include <sound/jack.h>
27#include "../codecs/max98090.h" 27#include "../../codecs/max98090.h"
28 28
29struct byt_max98090_private { 29struct byt_max98090_private {
30 struct snd_soc_jack jack; 30 struct snd_soc_jack jack;
diff --git a/sound/soc/intel/byt-rt5640.c b/sound/soc/intel/boards/byt-rt5640.c
index 354eaad886e1..ae89b9b966d9 100644
--- a/sound/soc/intel/byt-rt5640.c
+++ b/sound/soc/intel/boards/byt-rt5640.c
@@ -23,9 +23,9 @@
23#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include <sound/jack.h> 25#include <sound/jack.h>
26#include "../codecs/rt5640.h" 26#include "../../codecs/rt5640.h"
27 27
28#include "sst-dsp.h" 28#include "../common/sst-dsp.h"
29 29
30static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = { 30static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
31 SND_SOC_DAPM_HP("Headphone", NULL), 31 SND_SOC_DAPM_HP("Headphone", NULL),
diff --git a/sound/soc/intel/bytcr_dpcm_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 3b262d01c1b3..7f55d59024a8 100644
--- a/sound/soc/intel/bytcr_dpcm_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -26,8 +26,8 @@
26#include <sound/pcm.h> 26#include <sound/pcm.h>
27#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include "../codecs/rt5640.h" 29#include "../../codecs/rt5640.h"
30#include "sst-atom-controls.h" 30#include "../atom/sst-atom-controls.h"
31 31
32static const struct snd_soc_dapm_widget byt_dapm_widgets[] = { 32static const struct snd_soc_dapm_widget byt_dapm_widgets[] = {
33 SND_SOC_DAPM_HP("Headphone", NULL), 33 SND_SOC_DAPM_HP("Headphone", NULL),
diff --git a/sound/soc/intel/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c
index 012227997ed9..20a28b22e30f 100644
--- a/sound/soc/intel/cht_bsw_rt5645.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5645.c
@@ -27,8 +27,8 @@
27#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/jack.h> 29#include <sound/jack.h>
30#include "../codecs/rt5645.h" 30#include "../../codecs/rt5645.h"
31#include "sst-atom-controls.h" 31#include "../atom/sst-atom-controls.h"
32 32
33#define CHT_PLAT_CLK_3_HZ 19200000 33#define CHT_PLAT_CLK_3_HZ 19200000
34#define CHT_CODEC_DAI "rt5645-aif1" 34#define CHT_CODEC_DAI "rt5645-aif1"
diff --git a/sound/soc/intel/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c
index bc8dcacd5e6a..2c9cc5be439e 100644
--- a/sound/soc/intel/cht_bsw_rt5672.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5672.c
@@ -22,13 +22,28 @@
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include "../codecs/rt5670.h" 25#include <sound/jack.h>
26#include "sst-atom-controls.h" 26#include "../../codecs/rt5670.h"
27#include "../atom/sst-atom-controls.h"
27 28
28/* The platform clock #3 outputs 19.2Mhz clock to codec as I2S MCLK */ 29/* The platform clock #3 outputs 19.2Mhz clock to codec as I2S MCLK */
29#define CHT_PLAT_CLK_3_HZ 19200000 30#define CHT_PLAT_CLK_3_HZ 19200000
30#define CHT_CODEC_DAI "rt5670-aif1" 31#define CHT_CODEC_DAI "rt5670-aif1"
31 32
33static struct snd_soc_jack cht_bsw_headset;
34
35/* Headset jack detection DAPM pins */
36static struct snd_soc_jack_pin cht_bsw_headset_pins[] = {
37 {
38 .pin = "Headset Mic",
39 .mask = SND_JACK_MICROPHONE,
40 },
41 {
42 .pin = "Headphone",
43 .mask = SND_JACK_HEADPHONE,
44 },
45};
46
32static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) 47static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card)
33{ 48{
34 int i; 49 int i;
@@ -50,6 +65,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
50 struct snd_soc_dapm_context *dapm = w->dapm; 65 struct snd_soc_dapm_context *dapm = w->dapm;
51 struct snd_soc_card *card = dapm->card; 66 struct snd_soc_card *card = dapm->card;
52 struct snd_soc_dai *codec_dai; 67 struct snd_soc_dai *codec_dai;
68 int ret;
53 69
54 codec_dai = cht_get_codec_dai(card); 70 codec_dai = cht_get_codec_dai(card);
55 if (!codec_dai) { 71 if (!codec_dai) {
@@ -57,17 +73,31 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
57 return -EIO; 73 return -EIO;
58 } 74 }
59 75
60 if (!SND_SOC_DAPM_EVENT_OFF(event)) 76 if (SND_SOC_DAPM_EVENT_ON(event)) {
61 return 0; 77 /* set codec PLL source to the 19.2MHz platform clock (MCLK) */
62 78 ret = snd_soc_dai_set_pll(codec_dai, 0, RT5670_PLL1_S_MCLK,
63 /* Set codec sysclk source to its internal clock because codec PLL will 79 CHT_PLAT_CLK_3_HZ, 48000 * 512);
64 * be off when idle and MCLK will also be off by ACPI when codec is 80 if (ret < 0) {
65 * runtime suspended. Codec needs clock for jack detection and button 81 dev_err(card->dev, "can't set codec pll: %d\n", ret);
66 * press. 82 return ret;
67 */ 83 }
68 snd_soc_dai_set_sysclk(codec_dai, RT5670_SCLK_S_RCCLK, 84
69 0, SND_SOC_CLOCK_IN); 85 /* set codec sysclk source to PLL */
70 86 ret = snd_soc_dai_set_sysclk(codec_dai, RT5670_SCLK_S_PLL1,
87 48000 * 512, SND_SOC_CLOCK_IN);
88 if (ret < 0) {
89 dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
90 return ret;
91 }
92 } else {
93 /* Set codec sysclk source to its internal clock because codec
94 * PLL will be off when idle and MCLK will also be off by ACPI
95 * when codec is runtime suspended. Codec needs clock for jack
96 * detection and button press.
97 */
98 snd_soc_dai_set_sysclk(codec_dai, RT5670_SCLK_S_RCCLK,
99 48000 * 512, SND_SOC_CLOCK_IN);
100 }
71 return 0; 101 return 0;
72} 102}
73 103
@@ -77,7 +107,8 @@ static const struct snd_soc_dapm_widget cht_dapm_widgets[] = {
77 SND_SOC_DAPM_MIC("Int Mic", NULL), 107 SND_SOC_DAPM_MIC("Int Mic", NULL),
78 SND_SOC_DAPM_SPK("Ext Spk", NULL), 108 SND_SOC_DAPM_SPK("Ext Spk", NULL),
79 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, 109 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
80 platform_clock_control, SND_SOC_DAPM_POST_PMD), 110 platform_clock_control, SND_SOC_DAPM_PRE_PMU |
111 SND_SOC_DAPM_POST_PMD),
81}; 112};
82 113
83static const struct snd_soc_dapm_route cht_audio_map[] = { 114static const struct snd_soc_dapm_route cht_audio_map[] = {
@@ -162,6 +193,15 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
162 | RT5670_AD_MONO_L_FILTER 193 | RT5670_AD_MONO_L_FILTER
163 | RT5670_AD_MONO_R_FILTER, 194 | RT5670_AD_MONO_R_FILTER,
164 RT5670_CLK_SEL_I2S1_ASRC); 195 RT5670_CLK_SEL_I2S1_ASRC);
196
197 ret = snd_soc_card_jack_new(runtime->card, "Headset",
198 SND_JACK_HEADSET | SND_JACK_BTN_0 |
199 SND_JACK_BTN_1 | SND_JACK_BTN_2, &cht_bsw_headset,
200 cht_bsw_headset_pins, ARRAY_SIZE(cht_bsw_headset_pins));
201 if (ret)
202 return ret;
203
204 rt5670_set_jack_detect(codec, &cht_bsw_headset);
165 return 0; 205 return 0;
166} 206}
167 207
@@ -251,6 +291,35 @@ static struct snd_soc_dai_link cht_dailink[] = {
251 }, 291 },
252}; 292};
253 293
294static int cht_suspend_pre(struct snd_soc_card *card)
295{
296 struct snd_soc_codec *codec;
297
298 list_for_each_entry(codec, &card->codec_dev_list, card_list) {
299 if (!strcmp(codec->component.name, "i2c-10EC5670:00")) {
300 dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n");
301 rt5670_jack_suspend(codec);
302 break;
303 }
304 }
305 return 0;
306}
307
308static int cht_resume_post(struct snd_soc_card *card)
309{
310 struct snd_soc_codec *codec;
311
312 list_for_each_entry(codec, &card->codec_dev_list, card_list) {
313 if (!strcmp(codec->component.name, "i2c-10EC5670:00")) {
314 dev_dbg(codec->dev, "enabling jack detect for resume.\n");
315 rt5670_jack_resume(codec);
316 break;
317 }
318 }
319
320 return 0;
321}
322
254/* SoC card */ 323/* SoC card */
255static struct snd_soc_card snd_soc_card_cht = { 324static struct snd_soc_card snd_soc_card_cht = {
256 .name = "cherrytrailcraudio", 325 .name = "cherrytrailcraudio",
@@ -262,6 +331,8 @@ static struct snd_soc_card snd_soc_card_cht = {
262 .num_dapm_routes = ARRAY_SIZE(cht_audio_map), 331 .num_dapm_routes = ARRAY_SIZE(cht_audio_map),
263 .controls = cht_mc_controls, 332 .controls = cht_mc_controls,
264 .num_controls = ARRAY_SIZE(cht_mc_controls), 333 .num_controls = ARRAY_SIZE(cht_mc_controls),
334 .suspend_pre = cht_suspend_pre,
335 .resume_post = cht_resume_post,
265}; 336};
266 337
267static int snd_cht_mc_probe(struct platform_device *pdev) 338static int snd_cht_mc_probe(struct platform_device *pdev)
diff --git a/sound/soc/intel/haswell.c b/sound/soc/intel/boards/haswell.c
index 00fddd3f5dfb..22558572cb9c 100644
--- a/sound/soc/intel/haswell.c
+++ b/sound/soc/intel/boards/haswell.c
@@ -21,10 +21,10 @@
21#include <sound/soc.h> 21#include <sound/soc.h>
22#include <sound/pcm_params.h> 22#include <sound/pcm_params.h>
23 23
24#include "sst-dsp.h" 24#include "../common/sst-dsp.h"
25#include "sst-haswell-ipc.h" 25#include "../haswell/sst-haswell-ipc.h"
26 26
27#include "../codecs/rt5640.h" 27#include "../../codecs/rt5640.h"
28 28
29/* Haswell ULT platforms have a Headphone and Mic jack */ 29/* Haswell ULT platforms have a Headphone and Mic jack */
30static const struct snd_soc_dapm_widget haswell_widgets[] = { 30static const struct snd_soc_dapm_widget haswell_widgets[] = {
diff --git a/sound/soc/intel/mfld_machine.c b/sound/soc/intel/boards/mfld_machine.c
index 49c09a0add79..49c09a0add79 100644
--- a/sound/soc/intel/mfld_machine.c
+++ b/sound/soc/intel/boards/mfld_machine.c
diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile
new file mode 100644
index 000000000000..f24154ca4e98
--- /dev/null
+++ b/sound/soc/intel/common/Makefile
@@ -0,0 +1,7 @@
1snd-soc-sst-dsp-objs := sst-dsp.o sst-firmware.o
2snd-soc-sst-acpi-objs := sst-acpi.o
3snd-soc-sst-ipc-objs := sst-ipc.o
4
5obj-$(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
7
diff --git a/sound/soc/intel/sst-acpi.c b/sound/soc/intel/common/sst-acpi.c
index b3d84560fbb5..42f293f9c6e2 100644
--- a/sound/soc/intel/sst-acpi.c
+++ b/sound/soc/intel/common/sst-acpi.c
@@ -142,6 +142,7 @@ static int sst_acpi_probe(struct platform_device *pdev)
142 sst_acpi->desc = desc; 142 sst_acpi->desc = desc;
143 sst_acpi->mach = mach; 143 sst_acpi->mach = mach;
144 144
145 sst_pdata->resindex_dma_base = desc->resindex_dma_base;
145 if (desc->resindex_dma_base >= 0) { 146 if (desc->resindex_dma_base >= 0) {
146 sst_pdata->dma_engine = desc->dma_engine; 147 sst_pdata->dma_engine = desc->dma_engine;
147 sst_pdata->dma_base = desc->resindex_dma_base; 148 sst_pdata->dma_base = desc->resindex_dma_base;
diff --git a/sound/soc/intel/sst-dsp-priv.h b/sound/soc/intel/common/sst-dsp-priv.h
index b9da030e312d..396d54510350 100644
--- a/sound/soc/intel/sst-dsp-priv.h
+++ b/sound/soc/intel/common/sst-dsp-priv.h
@@ -173,6 +173,16 @@ struct sst_module_runtime_context {
173}; 173};
174 174
175/* 175/*
176 * Audio DSP Module State
177 */
178enum sst_module_state {
179 SST_MODULE_STATE_UNLOADED = 0, /* default state */
180 SST_MODULE_STATE_LOADED,
181 SST_MODULE_STATE_INITIALIZED, /* and inactive */
182 SST_MODULE_STATE_ACTIVE,
183};
184
185/*
176 * Audio DSP Generic Module. 186 * Audio DSP Generic Module.
177 * 187 *
178 * Each Firmware file can consist of 1..N modules. A module can span multiple 188 * Each Firmware file can consist of 1..N modules. A module can span multiple
@@ -203,6 +213,9 @@ struct sst_module {
203 struct list_head list; /* DSP list of modules */ 213 struct list_head list; /* DSP list of modules */
204 struct list_head list_fw; /* FW list of modules */ 214 struct list_head list_fw; /* FW list of modules */
205 struct list_head runtime_list; /* list of runtime module objects*/ 215 struct list_head runtime_list; /* list of runtime module objects*/
216
217 /* state */
218 enum sst_module_state state;
206}; 219};
207 220
208/* 221/*
diff --git a/sound/soc/intel/sst-dsp.c b/sound/soc/intel/common/sst-dsp.c
index 64e94212d2d2..64e94212d2d2 100644
--- a/sound/soc/intel/sst-dsp.c
+++ b/sound/soc/intel/common/sst-dsp.c
diff --git a/sound/soc/intel/sst-dsp.h b/sound/soc/intel/common/sst-dsp.h
index f291e32f0077..96aeb2556ad4 100644
--- a/sound/soc/intel/sst-dsp.h
+++ b/sound/soc/intel/common/sst-dsp.h
@@ -28,7 +28,6 @@
28 28
29/* Supported SST DMA Devices */ 29/* Supported SST DMA Devices */
30#define SST_DMA_TYPE_DW 1 30#define SST_DMA_TYPE_DW 1
31#define SST_DMA_TYPE_MID 2
32 31
33/* autosuspend delay 5s*/ 32/* autosuspend delay 5s*/
34#define SST_RUNTIME_SUSPEND_DELAY (5 * 1000) 33#define SST_RUNTIME_SUSPEND_DELAY (5 * 1000)
@@ -206,6 +205,7 @@ struct sst_pdata {
206 const struct firmware *fw; 205 const struct firmware *fw;
207 206
208 /* DMA */ 207 /* DMA */
208 int resindex_dma_base; /* other fields invalid if equals to -1 */
209 u32 dma_base; 209 u32 dma_base;
210 u32 dma_size; 210 u32 dma_size;
211 int dma_engine; 211 int dma_engine;
diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/common/sst-firmware.c
index 5f71ef607a57..ebcca6dc48d1 100644
--- a/sound/soc/intel/sst-firmware.c
+++ b/sound/soc/intel/common/sst-firmware.c
@@ -221,8 +221,6 @@ int sst_dsp_dma_get_channel(struct sst_dsp *dsp, int chan_id)
221 dma_cap_mask_t mask; 221 dma_cap_mask_t mask;
222 int ret; 222 int ret;
223 223
224 /* The Intel MID DMA engine driver needs the slave config set but
225 * Synopsis DMA engine driver safely ignores the slave config */
226 dma_cap_zero(mask); 224 dma_cap_zero(mask);
227 dma_cap_set(DMA_SLAVE, mask); 225 dma_cap_set(DMA_SLAVE, mask);
228 dma_cap_set(DMA_MEMCPY, mask); 226 dma_cap_set(DMA_MEMCPY, mask);
@@ -271,15 +269,16 @@ int sst_dma_new(struct sst_dsp *sst)
271 const char *dma_dev_name; 269 const char *dma_dev_name;
272 int ret = 0; 270 int ret = 0;
273 271
272 if (sst->pdata->resindex_dma_base == -1)
273 /* DMA is not used, return and squelsh error messages */
274 return 0;
275
274 /* configure the correct platform data for whatever DMA engine 276 /* configure the correct platform data for whatever DMA engine
275 * is attached to the ADSP IP. */ 277 * is attached to the ADSP IP. */
276 switch (sst->pdata->dma_engine) { 278 switch (sst->pdata->dma_engine) {
277 case SST_DMA_TYPE_DW: 279 case SST_DMA_TYPE_DW:
278 dma_dev_name = "dw_dmac"; 280 dma_dev_name = "dw_dmac";
279 break; 281 break;
280 case SST_DMA_TYPE_MID:
281 dma_dev_name = "Intel MID DMA";
282 break;
283 default: 282 default:
284 dev_err(sst->dev, "error: invalid DMA engine %d\n", 283 dev_err(sst->dev, "error: invalid DMA engine %d\n",
285 sst->pdata->dma_engine); 284 sst->pdata->dma_engine);
@@ -498,6 +497,7 @@ struct sst_module *sst_module_new(struct sst_fw *sst_fw,
498 sst_module->scratch_size = template->scratch_size; 497 sst_module->scratch_size = template->scratch_size;
499 sst_module->persistent_size = template->persistent_size; 498 sst_module->persistent_size = template->persistent_size;
500 sst_module->entry = template->entry; 499 sst_module->entry = template->entry;
500 sst_module->state = SST_MODULE_STATE_UNLOADED;
501 501
502 INIT_LIST_HEAD(&sst_module->block_list); 502 INIT_LIST_HEAD(&sst_module->block_list);
503 INIT_LIST_HEAD(&sst_module->runtime_list); 503 INIT_LIST_HEAD(&sst_module->runtime_list);
diff --git a/sound/soc/intel/common/sst-ipc.c b/sound/soc/intel/common/sst-ipc.c
new file mode 100644
index 000000000000..4b62a553823c
--- /dev/null
+++ b/sound/soc/intel/common/sst-ipc.c
@@ -0,0 +1,294 @@
1/*
2 * Intel SST generic IPC Support
3 *
4 * Copyright (C) 2015, Intel Corporation. All rights reserved.
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 version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/types.h>
18#include <linux/kernel.h>
19#include <linux/list.h>
20#include <linux/wait.h>
21#include <linux/module.h>
22#include <linux/spinlock.h>
23#include <linux/device.h>
24#include <linux/slab.h>
25#include <linux/workqueue.h>
26#include <linux/sched.h>
27#include <linux/delay.h>
28#include <linux/platform_device.h>
29#include <linux/kthread.h>
30#include <sound/asound.h>
31
32#include "sst-dsp.h"
33#include "sst-dsp-priv.h"
34#include "sst-ipc.h"
35
36/* IPC message timeout (msecs) */
37#define IPC_TIMEOUT_MSECS 300
38
39#define IPC_EMPTY_LIST_SIZE 8
40
41/* locks held by caller */
42static struct ipc_message *msg_get_empty(struct sst_generic_ipc *ipc)
43{
44 struct ipc_message *msg = NULL;
45
46 if (!list_empty(&ipc->empty_list)) {
47 msg = list_first_entry(&ipc->empty_list, struct ipc_message,
48 list);
49 list_del(&msg->list);
50 }
51
52 return msg;
53}
54
55static int tx_wait_done(struct sst_generic_ipc *ipc,
56 struct ipc_message *msg, void *rx_data)
57{
58 unsigned long flags;
59 int ret;
60
61 /* wait for DSP completion (in all cases atm inc pending) */
62 ret = wait_event_timeout(msg->waitq, msg->complete,
63 msecs_to_jiffies(IPC_TIMEOUT_MSECS));
64
65 spin_lock_irqsave(&ipc->dsp->spinlock, flags);
66 if (ret == 0) {
67 if (ipc->ops.shim_dbg != NULL)
68 ipc->ops.shim_dbg(ipc, "message timeout");
69
70 list_del(&msg->list);
71 ret = -ETIMEDOUT;
72 } else {
73
74 /* copy the data returned from DSP */
75 if (msg->rx_size)
76 memcpy(rx_data, msg->rx_data, msg->rx_size);
77 ret = msg->errno;
78 }
79
80 list_add_tail(&msg->list, &ipc->empty_list);
81 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
82 return ret;
83}
84
85static int ipc_tx_message(struct sst_generic_ipc *ipc, u64 header,
86 void *tx_data, size_t tx_bytes, void *rx_data,
87 size_t rx_bytes, int wait)
88{
89 struct ipc_message *msg;
90 unsigned long flags;
91
92 spin_lock_irqsave(&ipc->dsp->spinlock, flags);
93
94 msg = msg_get_empty(ipc);
95 if (msg == NULL) {
96 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
97 return -EBUSY;
98 }
99
100 msg->header = header;
101 msg->tx_size = tx_bytes;
102 msg->rx_size = rx_bytes;
103 msg->wait = wait;
104 msg->errno = 0;
105 msg->pending = false;
106 msg->complete = false;
107
108 if ((tx_bytes) && (ipc->ops.tx_data_copy != NULL))
109 ipc->ops.tx_data_copy(msg, tx_data, tx_bytes);
110
111 list_add_tail(&msg->list, &ipc->tx_list);
112 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
113
114 queue_kthread_work(&ipc->kworker, &ipc->kwork);
115
116 if (wait)
117 return tx_wait_done(ipc, msg, rx_data);
118 else
119 return 0;
120}
121
122static int msg_empty_list_init(struct sst_generic_ipc *ipc)
123{
124 int i;
125
126 ipc->msg = kzalloc(sizeof(struct ipc_message) *
127 IPC_EMPTY_LIST_SIZE, GFP_KERNEL);
128 if (ipc->msg == NULL)
129 return -ENOMEM;
130
131 for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
132 init_waitqueue_head(&ipc->msg[i].waitq);
133 list_add(&ipc->msg[i].list, &ipc->empty_list);
134 }
135
136 return 0;
137}
138
139static void ipc_tx_msgs(struct kthread_work *work)
140{
141 struct sst_generic_ipc *ipc =
142 container_of(work, struct sst_generic_ipc, kwork);
143 struct ipc_message *msg;
144 unsigned long flags;
145 u64 ipcx;
146
147 spin_lock_irqsave(&ipc->dsp->spinlock, flags);
148
149 if (list_empty(&ipc->tx_list) || ipc->pending) {
150 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
151 return;
152 }
153
154 /* if the DSP is busy, we will TX messages after IRQ.
155 * also postpone if we are in the middle of procesing completion irq*/
156 ipcx = sst_dsp_shim_read_unlocked(ipc->dsp, SST_IPCX);
157 if (ipcx & (SST_IPCX_BUSY | SST_IPCX_DONE)) {
158 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
159 return;
160 }
161
162 msg = list_first_entry(&ipc->tx_list, struct ipc_message, list);
163 list_move(&msg->list, &ipc->rx_list);
164
165 if (ipc->ops.tx_msg != NULL)
166 ipc->ops.tx_msg(ipc, msg);
167
168 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
169}
170
171int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header,
172 void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes)
173{
174 return ipc_tx_message(ipc, header, tx_data, tx_bytes,
175 rx_data, rx_bytes, 1);
176}
177EXPORT_SYMBOL_GPL(sst_ipc_tx_message_wait);
178
179int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, u64 header,
180 void *tx_data, size_t tx_bytes)
181{
182 return ipc_tx_message(ipc, header, tx_data, tx_bytes,
183 NULL, 0, 0);
184}
185EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nowait);
186
187struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc,
188 u64 header)
189{
190 struct ipc_message *msg;
191 u64 mask;
192
193 if (ipc->ops.reply_msg_match != NULL)
194 header = ipc->ops.reply_msg_match(header, &mask);
195
196 if (list_empty(&ipc->rx_list)) {
197 dev_err(ipc->dev, "error: rx list empty but received 0x%llx\n",
198 header);
199 return NULL;
200 }
201
202 list_for_each_entry(msg, &ipc->rx_list, list) {
203 if ((msg->header & mask) == header)
204 return msg;
205 }
206
207 return NULL;
208}
209EXPORT_SYMBOL_GPL(sst_ipc_reply_find_msg);
210
211/* locks held by caller */
212void sst_ipc_tx_msg_reply_complete(struct sst_generic_ipc *ipc,
213 struct ipc_message *msg)
214{
215 msg->complete = true;
216
217 if (!msg->wait)
218 list_add_tail(&msg->list, &ipc->empty_list);
219 else
220 wake_up(&msg->waitq);
221}
222EXPORT_SYMBOL_GPL(sst_ipc_tx_msg_reply_complete);
223
224void sst_ipc_drop_all(struct sst_generic_ipc *ipc)
225{
226 struct ipc_message *msg, *tmp;
227 unsigned long flags;
228 int tx_drop_cnt = 0, rx_drop_cnt = 0;
229
230 /* drop all TX and Rx messages before we stall + reset DSP */
231 spin_lock_irqsave(&ipc->dsp->spinlock, flags);
232
233 list_for_each_entry_safe(msg, tmp, &ipc->tx_list, list) {
234 list_move(&msg->list, &ipc->empty_list);
235 tx_drop_cnt++;
236 }
237
238 list_for_each_entry_safe(msg, tmp, &ipc->rx_list, list) {
239 list_move(&msg->list, &ipc->empty_list);
240 rx_drop_cnt++;
241 }
242
243 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
244
245 if (tx_drop_cnt || rx_drop_cnt)
246 dev_err(ipc->dev, "dropped IPC msg RX=%d, TX=%d\n",
247 tx_drop_cnt, rx_drop_cnt);
248}
249EXPORT_SYMBOL_GPL(sst_ipc_drop_all);
250
251int sst_ipc_init(struct sst_generic_ipc *ipc)
252{
253 int ret;
254
255 INIT_LIST_HEAD(&ipc->tx_list);
256 INIT_LIST_HEAD(&ipc->rx_list);
257 INIT_LIST_HEAD(&ipc->empty_list);
258 init_waitqueue_head(&ipc->wait_txq);
259
260 ret = msg_empty_list_init(ipc);
261 if (ret < 0)
262 return -ENOMEM;
263
264 /* start the IPC message thread */
265 init_kthread_worker(&ipc->kworker);
266 ipc->tx_thread = kthread_run(kthread_worker_fn,
267 &ipc->kworker, "%s",
268 dev_name(ipc->dev));
269 if (IS_ERR(ipc->tx_thread)) {
270 dev_err(ipc->dev, "error: failed to create message TX task\n");
271 ret = PTR_ERR(ipc->tx_thread);
272 kfree(ipc->msg);
273 return ret;
274 }
275
276 init_kthread_work(&ipc->kwork, ipc_tx_msgs);
277 return 0;
278}
279EXPORT_SYMBOL_GPL(sst_ipc_init);
280
281void sst_ipc_fini(struct sst_generic_ipc *ipc)
282{
283 if (ipc->tx_thread)
284 kthread_stop(ipc->tx_thread);
285
286 if (ipc->msg)
287 kfree(ipc->msg);
288}
289EXPORT_SYMBOL_GPL(sst_ipc_fini);
290
291/* Module information */
292MODULE_AUTHOR("Jin Yao");
293MODULE_DESCRIPTION("Intel SST IPC generic");
294MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/intel/common/sst-ipc.h b/sound/soc/intel/common/sst-ipc.h
new file mode 100644
index 000000000000..125ea451a373
--- /dev/null
+++ b/sound/soc/intel/common/sst-ipc.h
@@ -0,0 +1,91 @@
1/*
2 * Intel SST generic IPC Support
3 *
4 * Copyright (C) 2015, Intel Corporation. All rights reserved.
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 version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef __SST_GENERIC_IPC_H
18#define __SST_GENERIC_IPC_H
19
20#include <linux/types.h>
21#include <linux/kernel.h>
22#include <linux/wait.h>
23#include <linux/list.h>
24#include <linux/workqueue.h>
25#include <linux/sched.h>
26#include <linux/kthread.h>
27
28#define IPC_MAX_MAILBOX_BYTES 256
29
30struct ipc_message {
31 struct list_head list;
32 u64 header;
33
34 /* direction wrt host CPU */
35 char tx_data[IPC_MAX_MAILBOX_BYTES];
36 size_t tx_size;
37 char rx_data[IPC_MAX_MAILBOX_BYTES];
38 size_t rx_size;
39
40 wait_queue_head_t waitq;
41 bool pending;
42 bool complete;
43 bool wait;
44 int errno;
45};
46
47struct sst_generic_ipc;
48
49struct sst_plat_ipc_ops {
50 void (*tx_msg)(struct sst_generic_ipc *, struct ipc_message *);
51 void (*shim_dbg)(struct sst_generic_ipc *, const char *);
52 void (*tx_data_copy)(struct ipc_message *, char *, size_t);
53 u64 (*reply_msg_match)(u64 header, u64 *mask);
54};
55
56/* SST generic IPC data */
57struct sst_generic_ipc {
58 struct device *dev;
59 struct sst_dsp *dsp;
60
61 /* IPC messaging */
62 struct list_head tx_list;
63 struct list_head rx_list;
64 struct list_head empty_list;
65 wait_queue_head_t wait_txq;
66 struct task_struct *tx_thread;
67 struct kthread_worker kworker;
68 struct kthread_work kwork;
69 bool pending;
70 struct ipc_message *msg;
71
72 struct sst_plat_ipc_ops ops;
73};
74
75int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header,
76 void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes);
77
78int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, u64 header,
79 void *tx_data, size_t tx_bytes);
80
81struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc,
82 u64 header);
83
84void sst_ipc_tx_msg_reply_complete(struct sst_generic_ipc *ipc,
85 struct ipc_message *msg);
86
87void sst_ipc_drop_all(struct sst_generic_ipc *ipc);
88int sst_ipc_init(struct sst_generic_ipc *ipc);
89void sst_ipc_fini(struct sst_generic_ipc *ipc);
90
91#endif
diff --git a/sound/soc/intel/haswell/Makefile b/sound/soc/intel/haswell/Makefile
new file mode 100644
index 000000000000..9c1723112d22
--- /dev/null
+++ b/sound/soc/intel/haswell/Makefile
@@ -0,0 +1,4 @@
1snd-soc-sst-haswell-pcm-objs := \
2 sst-haswell-ipc.o sst-haswell-pcm.o sst-haswell-dsp.o
3
4obj-$(CONFIG_SND_SOC_INTEL_HASWELL) += snd-soc-sst-haswell-pcm.o
diff --git a/sound/soc/intel/sst-haswell-dsp.c b/sound/soc/intel/haswell/sst-haswell-dsp.c
index 402b728c0a06..7f94920c8a4d 100644
--- a/sound/soc/intel/sst-haswell-dsp.c
+++ b/sound/soc/intel/haswell/sst-haswell-dsp.c
@@ -28,9 +28,9 @@
28#include <linux/firmware.h> 28#include <linux/firmware.h>
29#include <linux/pm_runtime.h> 29#include <linux/pm_runtime.h>
30 30
31#include "sst-dsp.h" 31#include "../common/sst-dsp.h"
32#include "sst-dsp-priv.h" 32#include "../common/sst-dsp-priv.h"
33#include "sst-haswell-ipc.h" 33#include "../haswell/sst-haswell-ipc.h"
34 34
35#include <trace/events/hswadsp.h> 35#include <trace/events/hswadsp.h>
36 36
@@ -100,6 +100,7 @@ static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
100 && module->type != SST_HSW_MODULE_PCM 100 && module->type != SST_HSW_MODULE_PCM
101 && module->type != SST_HSW_MODULE_PCM_REFERENCE 101 && module->type != SST_HSW_MODULE_PCM_REFERENCE
102 && module->type != SST_HSW_MODULE_PCM_CAPTURE 102 && module->type != SST_HSW_MODULE_PCM_CAPTURE
103 && module->type != SST_HSW_MODULE_WAVES
103 && module->type != SST_HSW_MODULE_LPAL) 104 && module->type != SST_HSW_MODULE_LPAL)
104 return 0; 105 return 0;
105 106
@@ -139,6 +140,7 @@ static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
139 mod->type = SST_MEM_IRAM; 140 mod->type = SST_MEM_IRAM;
140 break; 141 break;
141 case SST_HSW_DRAM: 142 case SST_HSW_DRAM:
143 case SST_HSW_REGS:
142 ram = dsp->addr.lpe; 144 ram = dsp->addr.lpe;
143 mod->offset = block->ram_offset; 145 mod->offset = block->ram_offset;
144 mod->type = SST_MEM_DRAM; 146 mod->type = SST_MEM_DRAM;
@@ -169,6 +171,7 @@ static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
169 171
170 block = (void *)block + sizeof(*block) + block->size; 172 block = (void *)block + sizeof(*block) + block->size;
171 } 173 }
174 mod->state = SST_MODULE_STATE_LOADED;
172 175
173 return 0; 176 return 0;
174} 177}
diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/haswell/sst-haswell-ipc.c
index 863a9ca34b8e..344a1e9bbce5 100644
--- a/sound/soc/intel/sst-haswell-ipc.c
+++ b/sound/soc/intel/haswell/sst-haswell-ipc.c
@@ -34,8 +34,9 @@
34#include <sound/asound.h> 34#include <sound/asound.h>
35 35
36#include "sst-haswell-ipc.h" 36#include "sst-haswell-ipc.h"
37#include "sst-dsp.h" 37#include "../common/sst-dsp.h"
38#include "sst-dsp-priv.h" 38#include "../common/sst-dsp-priv.h"
39#include "../common/sst-ipc.h"
39 40
40/* Global Message - Generic */ 41/* Global Message - Generic */
41#define IPC_GLB_TYPE_SHIFT 24 42#define IPC_GLB_TYPE_SHIFT 24
@@ -79,6 +80,15 @@
79#define IPC_LOG_ID_MASK (0xf << IPC_LOG_ID_SHIFT) 80#define IPC_LOG_ID_MASK (0xf << IPC_LOG_ID_SHIFT)
80#define IPC_LOG_ID(x) (x << IPC_LOG_ID_SHIFT) 81#define IPC_LOG_ID(x) (x << IPC_LOG_ID_SHIFT)
81 82
83/* Module Message */
84#define IPC_MODULE_OPERATION_SHIFT 20
85#define IPC_MODULE_OPERATION_MASK (0xf << IPC_MODULE_OPERATION_SHIFT)
86#define IPC_MODULE_OPERATION(x) (x << IPC_MODULE_OPERATION_SHIFT)
87
88#define IPC_MODULE_ID_SHIFT 16
89#define IPC_MODULE_ID_MASK (0xf << IPC_MODULE_ID_SHIFT)
90#define IPC_MODULE_ID(x) (x << IPC_MODULE_ID_SHIFT)
91
82/* IPC message timeout (msecs) */ 92/* IPC message timeout (msecs) */
83#define IPC_TIMEOUT_MSECS 300 93#define IPC_TIMEOUT_MSECS 300
84#define IPC_BOOT_MSECS 200 94#define IPC_BOOT_MSECS 200
@@ -115,6 +125,7 @@ enum ipc_glb_type {
115 IPC_GLB_ENTER_DX_STATE = 12, 125 IPC_GLB_ENTER_DX_STATE = 12,
116 IPC_GLB_GET_MIXER_STREAM_INFO = 13, /* Request mixer stream params */ 126 IPC_GLB_GET_MIXER_STREAM_INFO = 13, /* Request mixer stream params */
117 IPC_GLB_DEBUG_LOG_MESSAGE = 14, /* Message to or from the debug logger. */ 127 IPC_GLB_DEBUG_LOG_MESSAGE = 14, /* Message to or from the debug logger. */
128 IPC_GLB_MODULE_OPERATION = 15, /* Message to loadable fw module */
118 IPC_GLB_REQUEST_TRANSFER = 16, /* < Request Transfer for host */ 129 IPC_GLB_REQUEST_TRANSFER = 16, /* < Request Transfer for host */
119 IPC_GLB_MAX_IPC_MESSAGE_TYPE = 17, /* Maximum message number */ 130 IPC_GLB_MAX_IPC_MESSAGE_TYPE = 17, /* Maximum message number */
120}; 131};
@@ -133,6 +144,16 @@ enum ipc_glb_reply {
133 IPC_GLB_REPLY_SOURCE_NOT_STARTED = 10, /* Source was not started. */ 144 IPC_GLB_REPLY_SOURCE_NOT_STARTED = 10, /* Source was not started. */
134}; 145};
135 146
147enum ipc_module_operation {
148 IPC_MODULE_NOTIFICATION = 0,
149 IPC_MODULE_ENABLE = 1,
150 IPC_MODULE_DISABLE = 2,
151 IPC_MODULE_GET_PARAMETER = 3,
152 IPC_MODULE_SET_PARAMETER = 4,
153 IPC_MODULE_GET_INFO = 5,
154 IPC_MODULE_MAX_MESSAGE
155};
156
136/* Stream Message - Types */ 157/* Stream Message - Types */
137enum ipc_str_operation { 158enum ipc_str_operation {
138 IPC_STR_RESET = 0, 159 IPC_STR_RESET = 0,
@@ -190,23 +211,6 @@ struct sst_hsw_ipc_fw_ready {
190 u8 fw_info[IPC_MAX_MAILBOX_BYTES - 5 * sizeof(u32)]; 211 u8 fw_info[IPC_MAX_MAILBOX_BYTES - 5 * sizeof(u32)];
191} __attribute__((packed)); 212} __attribute__((packed));
192 213
193struct ipc_message {
194 struct list_head list;
195 u32 header;
196
197 /* direction wrt host CPU */
198 char tx_data[IPC_MAX_MAILBOX_BYTES];
199 size_t tx_size;
200 char rx_data[IPC_MAX_MAILBOX_BYTES];
201 size_t rx_size;
202
203 wait_queue_head_t waitq;
204 bool pending;
205 bool complete;
206 bool wait;
207 int errno;
208};
209
210struct sst_hsw_stream; 214struct sst_hsw_stream;
211struct sst_hsw; 215struct sst_hsw;
212 216
@@ -305,18 +309,19 @@ struct sst_hsw {
305 bool shutdown; 309 bool shutdown;
306 310
307 /* IPC messaging */ 311 /* IPC messaging */
308 struct list_head tx_list; 312 struct sst_generic_ipc ipc;
309 struct list_head rx_list;
310 struct list_head empty_list;
311 wait_queue_head_t wait_txq;
312 struct task_struct *tx_thread;
313 struct kthread_worker kworker;
314 struct kthread_work kwork;
315 bool pending;
316 struct ipc_message *msg;
317 313
318 /* FW log stream */ 314 /* FW log stream */
319 struct sst_hsw_log_stream log_stream; 315 struct sst_hsw_log_stream log_stream;
316
317 /* flags bit field to track module state when resume from RTD3,
318 * each bit represent state (enabled/disabled) of single module */
319 u32 enabled_modules_rtd3;
320
321 /* buffer to store parameter lines */
322 u32 param_idx_w; /* write index */
323 u32 param_idx_r; /* read index */
324 u8 param_buf[WAVES_PARAM_LINES][WAVES_PARAM_COUNT];
320}; 325};
321 326
322#define CREATE_TRACE_POINTS 327#define CREATE_TRACE_POINTS
@@ -352,6 +357,16 @@ static inline u32 msg_get_notify_reason(u32 msg)
352 return (msg & IPC_STG_TYPE_MASK) >> IPC_STG_TYPE_SHIFT; 357 return (msg & IPC_STG_TYPE_MASK) >> IPC_STG_TYPE_SHIFT;
353} 358}
354 359
360static inline u32 msg_get_module_operation(u32 msg)
361{
362 return (msg & IPC_MODULE_OPERATION_MASK) >> IPC_MODULE_OPERATION_SHIFT;
363}
364
365static inline u32 msg_get_module_id(u32 msg)
366{
367 return (msg & IPC_MODULE_ID_MASK) >> IPC_MODULE_ID_SHIFT;
368}
369
355u32 create_channel_map(enum sst_hsw_channel_config config) 370u32 create_channel_map(enum sst_hsw_channel_config config)
356{ 371{
357 switch (config) { 372 switch (config) {
@@ -417,159 +432,6 @@ static struct sst_hsw_stream *get_stream_by_id(struct sst_hsw *hsw,
417 return NULL; 432 return NULL;
418} 433}
419 434
420static void ipc_shim_dbg(struct sst_hsw *hsw, const char *text)
421{
422 struct sst_dsp *sst = hsw->dsp;
423 u32 isr, ipcd, imrx, ipcx;
424
425 ipcx = sst_dsp_shim_read_unlocked(sst, SST_IPCX);
426 isr = sst_dsp_shim_read_unlocked(sst, SST_ISRX);
427 ipcd = sst_dsp_shim_read_unlocked(sst, SST_IPCD);
428 imrx = sst_dsp_shim_read_unlocked(sst, SST_IMRX);
429
430 dev_err(hsw->dev, "ipc: --%s-- ipcx 0x%8.8x isr 0x%8.8x ipcd 0x%8.8x imrx 0x%8.8x\n",
431 text, ipcx, isr, ipcd, imrx);
432}
433
434/* locks held by caller */
435static struct ipc_message *msg_get_empty(struct sst_hsw *hsw)
436{
437 struct ipc_message *msg = NULL;
438
439 if (!list_empty(&hsw->empty_list)) {
440 msg = list_first_entry(&hsw->empty_list, struct ipc_message,
441 list);
442 list_del(&msg->list);
443 }
444
445 return msg;
446}
447
448static void ipc_tx_msgs(struct kthread_work *work)
449{
450 struct sst_hsw *hsw =
451 container_of(work, struct sst_hsw, kwork);
452 struct ipc_message *msg;
453 unsigned long flags;
454 u32 ipcx;
455
456 spin_lock_irqsave(&hsw->dsp->spinlock, flags);
457
458 if (list_empty(&hsw->tx_list) || hsw->pending) {
459 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
460 return;
461 }
462
463 /* if the DSP is busy, we will TX messages after IRQ.
464 * also postpone if we are in the middle of procesing completion irq*/
465 ipcx = sst_dsp_shim_read_unlocked(hsw->dsp, SST_IPCX);
466 if (ipcx & (SST_IPCX_BUSY | SST_IPCX_DONE)) {
467 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
468 return;
469 }
470
471 msg = list_first_entry(&hsw->tx_list, struct ipc_message, list);
472
473 list_move(&msg->list, &hsw->rx_list);
474
475 /* send the message */
476 sst_dsp_outbox_write(hsw->dsp, msg->tx_data, msg->tx_size);
477 sst_dsp_ipc_msg_tx(hsw->dsp, msg->header | SST_IPCX_BUSY);
478
479 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
480}
481
482/* locks held by caller */
483static void tx_msg_reply_complete(struct sst_hsw *hsw, struct ipc_message *msg)
484{
485 msg->complete = true;
486 trace_ipc_reply("completed", msg->header);
487
488 if (!msg->wait)
489 list_add_tail(&msg->list, &hsw->empty_list);
490 else
491 wake_up(&msg->waitq);
492}
493
494static int tx_wait_done(struct sst_hsw *hsw, struct ipc_message *msg,
495 void *rx_data)
496{
497 unsigned long flags;
498 int ret;
499
500 /* wait for DSP completion (in all cases atm inc pending) */
501 ret = wait_event_timeout(msg->waitq, msg->complete,
502 msecs_to_jiffies(IPC_TIMEOUT_MSECS));
503
504 spin_lock_irqsave(&hsw->dsp->spinlock, flags);
505 if (ret == 0) {
506 ipc_shim_dbg(hsw, "message timeout");
507
508 trace_ipc_error("error message timeout for", msg->header);
509 list_del(&msg->list);
510 ret = -ETIMEDOUT;
511 } else {
512
513 /* copy the data returned from DSP */
514 if (msg->rx_size)
515 memcpy(rx_data, msg->rx_data, msg->rx_size);
516 ret = msg->errno;
517 }
518
519 list_add_tail(&msg->list, &hsw->empty_list);
520 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
521 return ret;
522}
523
524static int ipc_tx_message(struct sst_hsw *hsw, u32 header, void *tx_data,
525 size_t tx_bytes, void *rx_data, size_t rx_bytes, int wait)
526{
527 struct ipc_message *msg;
528 unsigned long flags;
529
530 spin_lock_irqsave(&hsw->dsp->spinlock, flags);
531
532 msg = msg_get_empty(hsw);
533 if (msg == NULL) {
534 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
535 return -EBUSY;
536 }
537
538 if (tx_bytes)
539 memcpy(msg->tx_data, tx_data, tx_bytes);
540
541 msg->header = header;
542 msg->tx_size = tx_bytes;
543 msg->rx_size = rx_bytes;
544 msg->wait = wait;
545 msg->errno = 0;
546 msg->pending = false;
547 msg->complete = false;
548
549 list_add_tail(&msg->list, &hsw->tx_list);
550 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
551
552 queue_kthread_work(&hsw->kworker, &hsw->kwork);
553
554 if (wait)
555 return tx_wait_done(hsw, msg, rx_data);
556 else
557 return 0;
558}
559
560static inline int ipc_tx_message_wait(struct sst_hsw *hsw, u32 header,
561 void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes)
562{
563 return ipc_tx_message(hsw, header, tx_data, tx_bytes, rx_data,
564 rx_bytes, 1);
565}
566
567static inline int ipc_tx_message_nowait(struct sst_hsw *hsw, u32 header,
568 void *tx_data, size_t tx_bytes)
569{
570 return ipc_tx_message(hsw, header, tx_data, tx_bytes, NULL, 0, 0);
571}
572
573static void hsw_fw_ready(struct sst_hsw *hsw, u32 header) 435static void hsw_fw_ready(struct sst_hsw *hsw, u32 header)
574{ 436{
575 struct sst_hsw_ipc_fw_ready fw_ready; 437 struct sst_hsw_ipc_fw_ready fw_ready;
@@ -604,7 +466,7 @@ static void hsw_fw_ready(struct sst_hsw *hsw, u32 header)
604 /* log the FW version info got from the mailbox here. */ 466 /* log the FW version info got from the mailbox here. */
605 memcpy(fw_info, fw_ready.fw_info, fw_ready.fw_info_size); 467 memcpy(fw_info, fw_ready.fw_info, fw_ready.fw_info_size);
606 pinfo = &fw_info[0]; 468 pinfo = &fw_info[0];
607 for (i = 0; i < sizeof(tmp) / sizeof(char *); i++) 469 for (i = 0; i < ARRAY_SIZE(tmp); i++)
608 tmp[i] = strsep(&pinfo, " "); 470 tmp[i] = strsep(&pinfo, " ");
609 dev_info(hsw->dev, "FW loaded, mailbox readback FW info: type %s, - " 471 dev_info(hsw->dev, "FW loaded, mailbox readback FW info: type %s, - "
610 "version: %s.%s, build %s, source commit id: %s\n", 472 "version: %s.%s, build %s, source commit id: %s\n",
@@ -657,27 +519,6 @@ static void hsw_notification_work(struct work_struct *work)
657 sst_dsp_shim_update_bits(hsw->dsp, SST_IMRX, SST_IMRX_BUSY, 0); 519 sst_dsp_shim_update_bits(hsw->dsp, SST_IMRX, SST_IMRX_BUSY, 0);
658} 520}
659 521
660static struct ipc_message *reply_find_msg(struct sst_hsw *hsw, u32 header)
661{
662 struct ipc_message *msg;
663
664 /* clear reply bits & status bits */
665 header &= ~(IPC_STATUS_MASK | IPC_GLB_REPLY_MASK);
666
667 if (list_empty(&hsw->rx_list)) {
668 dev_err(hsw->dev, "error: rx list empty but received 0x%x\n",
669 header);
670 return NULL;
671 }
672
673 list_for_each_entry(msg, &hsw->rx_list, list) {
674 if (msg->header == header)
675 return msg;
676 }
677
678 return NULL;
679}
680
681static void hsw_stream_update(struct sst_hsw *hsw, struct ipc_message *msg) 522static void hsw_stream_update(struct sst_hsw *hsw, struct ipc_message *msg)
682{ 523{
683 struct sst_hsw_stream *stream; 524 struct sst_hsw_stream *stream;
@@ -716,7 +557,7 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header)
716 557
717 trace_ipc_reply("processing -->", header); 558 trace_ipc_reply("processing -->", header);
718 559
719 msg = reply_find_msg(hsw, header); 560 msg = sst_ipc_reply_find_msg(&hsw->ipc, header);
720 if (msg == NULL) { 561 if (msg == NULL) {
721 trace_ipc_error("error: can't find message header", header); 562 trace_ipc_error("error: can't find message header", header);
722 return -EIO; 563 return -EIO;
@@ -727,14 +568,14 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header)
727 case IPC_GLB_REPLY_PENDING: 568 case IPC_GLB_REPLY_PENDING:
728 trace_ipc_pending_reply("received", header); 569 trace_ipc_pending_reply("received", header);
729 msg->pending = true; 570 msg->pending = true;
730 hsw->pending = true; 571 hsw->ipc.pending = true;
731 return 1; 572 return 1;
732 case IPC_GLB_REPLY_SUCCESS: 573 case IPC_GLB_REPLY_SUCCESS:
733 if (msg->pending) { 574 if (msg->pending) {
734 trace_ipc_pending_reply("completed", header); 575 trace_ipc_pending_reply("completed", header);
735 sst_dsp_inbox_read(hsw->dsp, msg->rx_data, 576 sst_dsp_inbox_read(hsw->dsp, msg->rx_data,
736 msg->rx_size); 577 msg->rx_size);
737 hsw->pending = false; 578 hsw->ipc.pending = false;
738 } else { 579 } else {
739 /* copy data from the DSP */ 580 /* copy data from the DSP */
740 sst_dsp_outbox_read(hsw->dsp, msg->rx_data, 581 sst_dsp_outbox_read(hsw->dsp, msg->rx_data,
@@ -790,11 +631,36 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header)
790 631
791 /* wake up and return the error if we have waiters on this message ? */ 632 /* wake up and return the error if we have waiters on this message ? */
792 list_del(&msg->list); 633 list_del(&msg->list);
793 tx_msg_reply_complete(hsw, msg); 634 sst_ipc_tx_msg_reply_complete(&hsw->ipc, msg);
794 635
795 return 1; 636 return 1;
796} 637}
797 638
639static int hsw_module_message(struct sst_hsw *hsw, u32 header)
640{
641 u32 operation, module_id;
642 int handled = 0;
643
644 operation = msg_get_module_operation(header);
645 module_id = msg_get_module_id(header);
646 dev_dbg(hsw->dev, "received module message header: 0x%8.8x\n",
647 header);
648 dev_dbg(hsw->dev, "operation: 0x%8.8x module_id: 0x%8.8x\n",
649 operation, module_id);
650
651 switch (operation) {
652 case IPC_MODULE_NOTIFICATION:
653 dev_dbg(hsw->dev, "module notification received");
654 handled = 1;
655 break;
656 default:
657 handled = hsw_process_reply(hsw, header);
658 break;
659 }
660
661 return handled;
662}
663
798static int hsw_stream_message(struct sst_hsw *hsw, u32 header) 664static int hsw_stream_message(struct sst_hsw *hsw, u32 header)
799{ 665{
800 u32 stream_msg, stream_id, stage_type; 666 u32 stream_msg, stream_id, stage_type;
@@ -890,6 +756,9 @@ static int hsw_process_notification(struct sst_hsw *hsw)
890 case IPC_GLB_DEBUG_LOG_MESSAGE: 756 case IPC_GLB_DEBUG_LOG_MESSAGE:
891 handled = hsw_log_message(hsw, header); 757 handled = hsw_log_message(hsw, header);
892 break; 758 break;
759 case IPC_GLB_MODULE_OPERATION:
760 handled = hsw_module_message(hsw, header);
761 break;
893 default: 762 default:
894 dev_err(hsw->dev, "error: unexpected type %d hdr 0x%8.8x\n", 763 dev_err(hsw->dev, "error: unexpected type %d hdr 0x%8.8x\n",
895 type, header); 764 type, header);
@@ -903,6 +772,7 @@ static irqreturn_t hsw_irq_thread(int irq, void *context)
903{ 772{
904 struct sst_dsp *sst = (struct sst_dsp *) context; 773 struct sst_dsp *sst = (struct sst_dsp *) context;
905 struct sst_hsw *hsw = sst_dsp_get_thread_context(sst); 774 struct sst_hsw *hsw = sst_dsp_get_thread_context(sst);
775 struct sst_generic_ipc *ipc = &hsw->ipc;
906 u32 ipcx, ipcd; 776 u32 ipcx, ipcd;
907 int handled; 777 int handled;
908 unsigned long flags; 778 unsigned long flags;
@@ -949,7 +819,7 @@ static irqreturn_t hsw_irq_thread(int irq, void *context)
949 spin_unlock_irqrestore(&sst->spinlock, flags); 819 spin_unlock_irqrestore(&sst->spinlock, flags);
950 820
951 /* continue to send any remaining messages... */ 821 /* continue to send any remaining messages... */
952 queue_kthread_work(&hsw->kworker, &hsw->kwork); 822 queue_kthread_work(&ipc->kworker, &ipc->kwork);
953 823
954 return IRQ_HANDLED; 824 return IRQ_HANDLED;
955} 825}
@@ -959,7 +829,8 @@ int sst_hsw_fw_get_version(struct sst_hsw *hsw,
959{ 829{
960 int ret; 830 int ret;
961 831
962 ret = ipc_tx_message_wait(hsw, IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION), 832 ret = sst_ipc_tx_message_wait(&hsw->ipc,
833 IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION),
963 NULL, 0, version, sizeof(*version)); 834 NULL, 0, version, sizeof(*version));
964 if (ret < 0) 835 if (ret < 0)
965 dev_err(hsw->dev, "error: get version failed\n"); 836 dev_err(hsw->dev, "error: get version failed\n");
@@ -1023,7 +894,8 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
1023 req->channel = channel; 894 req->channel = channel;
1024 } 895 }
1025 896
1026 ret = ipc_tx_message_wait(hsw, header, req, sizeof(*req), NULL, 0); 897 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, req,
898 sizeof(*req), NULL, 0);
1027 if (ret < 0) { 899 if (ret < 0) {
1028 dev_err(hsw->dev, "error: set stream volume failed\n"); 900 dev_err(hsw->dev, "error: set stream volume failed\n");
1029 return ret; 901 return ret;
@@ -1088,7 +960,8 @@ int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
1088 req.curve_type = hsw->curve_type; 960 req.curve_type = hsw->curve_type;
1089 req.target_volume = volume; 961 req.target_volume = volume;
1090 962
1091 ret = ipc_tx_message_wait(hsw, header, &req, sizeof(req), NULL, 0); 963 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &req,
964 sizeof(req), NULL, 0);
1092 if (ret < 0) { 965 if (ret < 0) {
1093 dev_err(hsw->dev, "error: set mixer volume failed\n"); 966 dev_err(hsw->dev, "error: set mixer volume failed\n");
1094 return ret; 967 return ret;
@@ -1146,7 +1019,7 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
1146 stream->free_req.stream_id = stream->reply.stream_hw_id; 1019 stream->free_req.stream_id = stream->reply.stream_hw_id;
1147 header = IPC_GLB_TYPE(IPC_GLB_FREE_STREAM); 1020 header = IPC_GLB_TYPE(IPC_GLB_FREE_STREAM);
1148 1021
1149 ret = ipc_tx_message_wait(hsw, header, &stream->free_req, 1022 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &stream->free_req,
1150 sizeof(stream->free_req), NULL, 0); 1023 sizeof(stream->free_req), NULL, 0);
1151 if (ret < 0) { 1024 if (ret < 0) {
1152 dev_err(hsw->dev, "error: free stream %d failed\n", 1025 dev_err(hsw->dev, "error: free stream %d failed\n",
@@ -1338,8 +1211,8 @@ int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
1338 1211
1339 header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM); 1212 header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM);
1340 1213
1341 ret = ipc_tx_message_wait(hsw, header, str_req, sizeof(*str_req), 1214 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, str_req,
1342 reply, sizeof(*reply)); 1215 sizeof(*str_req), reply, sizeof(*reply));
1343 if (ret < 0) { 1216 if (ret < 0) {
1344 dev_err(hsw->dev, "error: stream commit failed\n"); 1217 dev_err(hsw->dev, "error: stream commit failed\n");
1345 return ret; 1218 return ret;
@@ -1388,7 +1261,8 @@ int sst_hsw_mixer_get_info(struct sst_hsw *hsw)
1388 1261
1389 trace_ipc_request("get global mixer info", 0); 1262 trace_ipc_request("get global mixer info", 0);
1390 1263
1391 ret = ipc_tx_message_wait(hsw, header, NULL, 0, reply, sizeof(*reply)); 1264 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, NULL, 0,
1265 reply, sizeof(*reply));
1392 if (ret < 0) { 1266 if (ret < 0) {
1393 dev_err(hsw->dev, "error: get stream info failed\n"); 1267 dev_err(hsw->dev, "error: get stream info failed\n");
1394 return ret; 1268 return ret;
@@ -1409,9 +1283,10 @@ static int sst_hsw_stream_operations(struct sst_hsw *hsw, int type,
1409 header |= (stream_id << IPC_STR_ID_SHIFT); 1283 header |= (stream_id << IPC_STR_ID_SHIFT);
1410 1284
1411 if (wait) 1285 if (wait)
1412 return ipc_tx_message_wait(hsw, header, NULL, 0, NULL, 0); 1286 return sst_ipc_tx_message_wait(&hsw->ipc, header,
1287 NULL, 0, NULL, 0);
1413 else 1288 else
1414 return ipc_tx_message_nowait(hsw, header, NULL, 0); 1289 return sst_ipc_tx_message_nowait(&hsw->ipc, header, NULL, 0);
1415} 1290}
1416 1291
1417/* Stream ALSA trigger operations */ 1292/* Stream ALSA trigger operations */
@@ -1538,8 +1413,8 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw,
1538 1413
1539 header = IPC_GLB_TYPE(IPC_GLB_SET_DEVICE_FORMATS); 1414 header = IPC_GLB_TYPE(IPC_GLB_SET_DEVICE_FORMATS);
1540 1415
1541 ret = ipc_tx_message_wait(hsw, header, &config, sizeof(config), 1416 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &config,
1542 NULL, 0); 1417 sizeof(config), NULL, 0);
1543 if (ret < 0) 1418 if (ret < 0)
1544 dev_err(hsw->dev, "error: set device formats failed\n"); 1419 dev_err(hsw->dev, "error: set device formats failed\n");
1545 1420
@@ -1559,8 +1434,8 @@ int sst_hsw_dx_set_state(struct sst_hsw *hsw,
1559 1434
1560 trace_ipc_request("PM enter Dx state", state); 1435 trace_ipc_request("PM enter Dx state", state);
1561 1436
1562 ret = ipc_tx_message_wait(hsw, header, &state_, sizeof(state_), 1437 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &state_,
1563 dx, sizeof(*dx)); 1438 sizeof(state_), dx, sizeof(*dx));
1564 if (ret < 0) { 1439 if (ret < 0) {
1565 dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state); 1440 dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state);
1566 return ret; 1441 return ret;
@@ -1703,32 +1578,6 @@ static int sst_hsw_dx_state_restore(struct sst_hsw *hsw)
1703 return 0; 1578 return 0;
1704} 1579}
1705 1580
1706static void sst_hsw_drop_all(struct sst_hsw *hsw)
1707{
1708 struct ipc_message *msg, *tmp;
1709 unsigned long flags;
1710 int tx_drop_cnt = 0, rx_drop_cnt = 0;
1711
1712 /* drop all TX and Rx messages before we stall + reset DSP */
1713 spin_lock_irqsave(&hsw->dsp->spinlock, flags);
1714
1715 list_for_each_entry_safe(msg, tmp, &hsw->tx_list, list) {
1716 list_move(&msg->list, &hsw->empty_list);
1717 tx_drop_cnt++;
1718 }
1719
1720 list_for_each_entry_safe(msg, tmp, &hsw->rx_list, list) {
1721 list_move(&msg->list, &hsw->empty_list);
1722 rx_drop_cnt++;
1723 }
1724
1725 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
1726
1727 if (tx_drop_cnt || rx_drop_cnt)
1728 dev_err(hsw->dev, "dropped IPC msg RX=%d, TX=%d\n",
1729 tx_drop_cnt, rx_drop_cnt);
1730}
1731
1732int sst_hsw_dsp_load(struct sst_hsw *hsw) 1581int sst_hsw_dsp_load(struct sst_hsw *hsw)
1733{ 1582{
1734 struct sst_dsp *dsp = hsw->dsp; 1583 struct sst_dsp *dsp = hsw->dsp;
@@ -1808,7 +1657,7 @@ int sst_hsw_dsp_runtime_suspend(struct sst_hsw *hsw)
1808 if (ret < 0) 1657 if (ret < 0)
1809 return ret; 1658 return ret;
1810 1659
1811 sst_hsw_drop_all(hsw); 1660 sst_ipc_drop_all(&hsw->ipc);
1812 1661
1813 return 0; 1662 return 0;
1814} 1663}
@@ -1844,6 +1693,8 @@ int sst_hsw_dsp_runtime_resume(struct sst_hsw *hsw)
1844 if (ret < 0) 1693 if (ret < 0)
1845 dev_err(dev, "error: audio DSP boot failure\n"); 1694 dev_err(dev, "error: audio DSP boot failure\n");
1846 1695
1696 sst_hsw_init_module_state(hsw);
1697
1847 ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete, 1698 ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete,
1848 msecs_to_jiffies(IPC_BOOT_MSECS)); 1699 msecs_to_jiffies(IPC_BOOT_MSECS));
1849 if (ret == 0) { 1700 if (ret == 0) {
@@ -1864,26 +1715,345 @@ int sst_hsw_dsp_runtime_resume(struct sst_hsw *hsw)
1864} 1715}
1865#endif 1716#endif
1866 1717
1867static int msg_empty_list_init(struct sst_hsw *hsw) 1718struct sst_dsp *sst_hsw_get_dsp(struct sst_hsw *hsw)
1868{ 1719{
1869 int i; 1720 return hsw->dsp;
1721}
1870 1722
1871 hsw->msg = kzalloc(sizeof(struct ipc_message) * 1723void sst_hsw_init_module_state(struct sst_hsw *hsw)
1872 IPC_EMPTY_LIST_SIZE, GFP_KERNEL); 1724{
1873 if (hsw->msg == NULL) 1725 struct sst_module *module;
1874 return -ENOMEM; 1726 enum sst_hsw_module_id id;
1727
1728 /* the base fw contains several modules */
1729 for (id = SST_HSW_MODULE_BASE_FW; id < SST_HSW_MAX_MODULE_ID; id++) {
1730 module = sst_module_get_from_id(hsw->dsp, id);
1731 if (module) {
1732 /* module waves is active only after being enabled */
1733 if (id == SST_HSW_MODULE_WAVES)
1734 module->state = SST_MODULE_STATE_INITIALIZED;
1735 else
1736 module->state = SST_MODULE_STATE_ACTIVE;
1737 }
1738 }
1739}
1740
1741bool sst_hsw_is_module_loaded(struct sst_hsw *hsw, u32 module_id)
1742{
1743 struct sst_module *module;
1744
1745 module = sst_module_get_from_id(hsw->dsp, module_id);
1746 if (module == NULL || module->state == SST_MODULE_STATE_UNLOADED)
1747 return false;
1748 else
1749 return true;
1750}
1751
1752bool sst_hsw_is_module_active(struct sst_hsw *hsw, u32 module_id)
1753{
1754 struct sst_module *module;
1755
1756 module = sst_module_get_from_id(hsw->dsp, module_id);
1757 if (module != NULL && module->state == SST_MODULE_STATE_ACTIVE)
1758 return true;
1759 else
1760 return false;
1761}
1875 1762
1876 for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { 1763void sst_hsw_set_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id)
1877 init_waitqueue_head(&hsw->msg[i].waitq); 1764{
1878 list_add(&hsw->msg[i].list, &hsw->empty_list); 1765 hsw->enabled_modules_rtd3 |= (1 << module_id);
1766}
1767
1768void sst_hsw_set_module_disabled_rtd3(struct sst_hsw *hsw, u32 module_id)
1769{
1770 hsw->enabled_modules_rtd3 &= ~(1 << module_id);
1771}
1772
1773bool sst_hsw_is_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id)
1774{
1775 return hsw->enabled_modules_rtd3 & (1 << module_id);
1776}
1777
1778void sst_hsw_reset_param_buf(struct sst_hsw *hsw)
1779{
1780 hsw->param_idx_w = 0;
1781 hsw->param_idx_r = 0;
1782 memset((void *)hsw->param_buf, 0, sizeof(hsw->param_buf));
1783}
1784
1785int sst_hsw_store_param_line(struct sst_hsw *hsw, u8 *buf)
1786{
1787 /* save line to the first available position of param buffer */
1788 if (hsw->param_idx_w > WAVES_PARAM_LINES - 1) {
1789 dev_warn(hsw->dev, "warning: param buffer overflow!\n");
1790 return -EPERM;
1791 }
1792 memcpy(hsw->param_buf[hsw->param_idx_w], buf, WAVES_PARAM_COUNT);
1793 hsw->param_idx_w++;
1794 return 0;
1795}
1796
1797int sst_hsw_load_param_line(struct sst_hsw *hsw, u8 *buf)
1798{
1799 u8 id = 0;
1800
1801 /* read the first matching line from param buffer */
1802 while (hsw->param_idx_r < WAVES_PARAM_LINES) {
1803 id = hsw->param_buf[hsw->param_idx_r][0];
1804 hsw->param_idx_r++;
1805 if (buf[0] == id) {
1806 memcpy(buf, hsw->param_buf[hsw->param_idx_r],
1807 WAVES_PARAM_COUNT);
1808 break;
1809 }
1879 } 1810 }
1811 if (hsw->param_idx_r > WAVES_PARAM_LINES - 1) {
1812 dev_dbg(hsw->dev, "end of buffer, roll to the beginning\n");
1813 hsw->param_idx_r = 0;
1814 return 0;
1815 }
1816 return 0;
1817}
1818
1819int sst_hsw_launch_param_buf(struct sst_hsw *hsw)
1820{
1821 int ret, idx;
1880 1822
1823 if (!sst_hsw_is_module_active(hsw, SST_HSW_MODULE_WAVES)) {
1824 dev_dbg(hsw->dev, "module waves is not active\n");
1825 return 0;
1826 }
1827
1828 /* put all param lines to DSP through ipc */
1829 for (idx = 0; idx < hsw->param_idx_w; idx++) {
1830 ret = sst_hsw_module_set_param(hsw,
1831 SST_HSW_MODULE_WAVES, 0, hsw->param_buf[idx][0],
1832 WAVES_PARAM_COUNT, hsw->param_buf[idx]);
1833 if (ret < 0)
1834 return ret;
1835 }
1881 return 0; 1836 return 0;
1882} 1837}
1883 1838
1884struct sst_dsp *sst_hsw_get_dsp(struct sst_hsw *hsw) 1839int sst_hsw_module_load(struct sst_hsw *hsw,
1840 u32 module_id, u32 instance_id, char *name)
1885{ 1841{
1886 return hsw->dsp; 1842 int ret = 0;
1843 const struct firmware *fw = NULL;
1844 struct sst_fw *hsw_sst_fw;
1845 struct sst_module *module;
1846 struct device *dev = hsw->dev;
1847 struct sst_dsp *dsp = hsw->dsp;
1848
1849 dev_dbg(dev, "sst_hsw_module_load id=%d, name='%s'", module_id, name);
1850
1851 module = sst_module_get_from_id(dsp, module_id);
1852 if (module == NULL) {
1853 /* loading for the first time */
1854 if (module_id == SST_HSW_MODULE_BASE_FW) {
1855 /* for base module: use fw requested in acpi probe */
1856 fw = dsp->pdata->fw;
1857 if (!fw) {
1858 dev_err(dev, "request Base fw failed\n");
1859 return -ENODEV;
1860 }
1861 } else {
1862 /* try and load any other optional modules if they are
1863 * available. Use dev_info instead of dev_err in case
1864 * request firmware failed */
1865 ret = request_firmware(&fw, name, dev);
1866 if (ret) {
1867 dev_info(dev, "fw image %s not available(%d)\n",
1868 name, ret);
1869 return ret;
1870 }
1871 }
1872 hsw_sst_fw = sst_fw_new(dsp, fw, hsw);
1873 if (hsw_sst_fw == NULL) {
1874 dev_err(dev, "error: failed to load firmware\n");
1875 ret = -ENOMEM;
1876 goto out;
1877 }
1878 module = sst_module_get_from_id(dsp, module_id);
1879 if (module == NULL) {
1880 dev_err(dev, "error: no module %d in firmware %s\n",
1881 module_id, name);
1882 }
1883 } else
1884 dev_info(dev, "module %d (%s) already loaded\n",
1885 module_id, name);
1886out:
1887 /* release fw, but base fw should be released by acpi driver */
1888 if (fw && module_id != SST_HSW_MODULE_BASE_FW)
1889 release_firmware(fw);
1890
1891 return ret;
1892}
1893
1894int sst_hsw_module_enable(struct sst_hsw *hsw,
1895 u32 module_id, u32 instance_id)
1896{
1897 int ret;
1898 u32 header = 0;
1899 struct sst_hsw_ipc_module_config config;
1900 struct sst_module *module;
1901 struct sst_module_runtime *runtime;
1902 struct device *dev = hsw->dev;
1903 struct sst_dsp *dsp = hsw->dsp;
1904
1905 if (!sst_hsw_is_module_loaded(hsw, module_id)) {
1906 dev_dbg(dev, "module %d not loaded\n", module_id);
1907 return 0;
1908 }
1909
1910 if (sst_hsw_is_module_active(hsw, module_id)) {
1911 dev_info(dev, "module %d already enabled\n", module_id);
1912 return 0;
1913 }
1914
1915 module = sst_module_get_from_id(dsp, module_id);
1916 if (module == NULL) {
1917 dev_err(dev, "module %d not valid\n", module_id);
1918 return -ENXIO;
1919 }
1920
1921 runtime = sst_module_runtime_get_from_id(module, module_id);
1922 if (runtime == NULL) {
1923 dev_err(dev, "runtime %d not valid", module_id);
1924 return -ENXIO;
1925 }
1926
1927 header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
1928 IPC_MODULE_OPERATION(IPC_MODULE_ENABLE) |
1929 IPC_MODULE_ID(module_id);
1930 dev_dbg(dev, "module enable header: %x\n", header);
1931
1932 config.map.module_entries_count = 1;
1933 config.map.module_entries[0].module_id = module->id;
1934 config.map.module_entries[0].entry_point = module->entry;
1935
1936 config.persistent_mem.offset =
1937 sst_dsp_get_offset(dsp,
1938 runtime->persistent_offset, SST_MEM_DRAM);
1939 config.persistent_mem.size = module->persistent_size;
1940
1941 config.scratch_mem.offset =
1942 sst_dsp_get_offset(dsp,
1943 dsp->scratch_offset, SST_MEM_DRAM);
1944 config.scratch_mem.size = module->scratch_size;
1945 dev_dbg(dev, "mod %d enable p:%d @ %x, s:%d @ %x, ep: %x",
1946 config.map.module_entries[0].module_id,
1947 config.persistent_mem.size,
1948 config.persistent_mem.offset,
1949 config.scratch_mem.size, config.scratch_mem.offset,
1950 config.map.module_entries[0].entry_point);
1951
1952 ret = sst_ipc_tx_message_wait(&hsw->ipc, header,
1953 &config, sizeof(config), NULL, 0);
1954 if (ret < 0)
1955 dev_err(dev, "ipc: module enable failed - %d\n", ret);
1956 else
1957 module->state = SST_MODULE_STATE_ACTIVE;
1958
1959 return ret;
1960}
1961
1962int sst_hsw_module_disable(struct sst_hsw *hsw,
1963 u32 module_id, u32 instance_id)
1964{
1965 int ret;
1966 u32 header;
1967 struct sst_module *module;
1968 struct device *dev = hsw->dev;
1969 struct sst_dsp *dsp = hsw->dsp;
1970
1971 if (!sst_hsw_is_module_loaded(hsw, module_id)) {
1972 dev_dbg(dev, "module %d not loaded\n", module_id);
1973 return 0;
1974 }
1975
1976 if (!sst_hsw_is_module_active(hsw, module_id)) {
1977 dev_info(dev, "module %d already disabled\n", module_id);
1978 return 0;
1979 }
1980
1981 module = sst_module_get_from_id(dsp, module_id);
1982 if (module == NULL) {
1983 dev_err(dev, "module %d not valid\n", module_id);
1984 return -ENXIO;
1985 }
1986
1987 header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
1988 IPC_MODULE_OPERATION(IPC_MODULE_DISABLE) |
1989 IPC_MODULE_ID(module_id);
1990
1991 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, NULL, 0, NULL, 0);
1992 if (ret < 0)
1993 dev_err(dev, "module disable failed - %d\n", ret);
1994 else
1995 module->state = SST_MODULE_STATE_INITIALIZED;
1996
1997 return ret;
1998}
1999
2000int sst_hsw_module_set_param(struct sst_hsw *hsw,
2001 u32 module_id, u32 instance_id, u32 parameter_id,
2002 u32 param_size, char *param)
2003{
2004 int ret;
2005 unsigned char *data = NULL;
2006 u32 header = 0;
2007 u32 payload_size = 0, transfer_parameter_size = 0;
2008 dma_addr_t dma_addr = 0;
2009 struct sst_hsw_transfer_parameter *parameter;
2010 struct device *dev = hsw->dev;
2011
2012 header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
2013 IPC_MODULE_OPERATION(IPC_MODULE_SET_PARAMETER) |
2014 IPC_MODULE_ID(module_id);
2015 dev_dbg(dev, "sst_hsw_module_set_param header=%x\n", header);
2016
2017 payload_size = param_size +
2018 sizeof(struct sst_hsw_transfer_parameter) -
2019 sizeof(struct sst_hsw_transfer_list);
2020 dev_dbg(dev, "parameter size : %d\n", param_size);
2021 dev_dbg(dev, "payload size : %d\n", payload_size);
2022
2023 if (payload_size <= SST_HSW_IPC_MAX_SHORT_PARAMETER_SIZE) {
2024 /* short parameter, mailbox can contain data */
2025 dev_dbg(dev, "transfer parameter size : %d\n",
2026 transfer_parameter_size);
2027
2028 transfer_parameter_size = ALIGN(payload_size, 4);
2029 dev_dbg(dev, "transfer parameter aligned size : %d\n",
2030 transfer_parameter_size);
2031
2032 parameter = kzalloc(transfer_parameter_size, GFP_KERNEL);
2033 if (parameter == NULL)
2034 return -ENOMEM;
2035
2036 memcpy(parameter->data, param, param_size);
2037 } else {
2038 dev_warn(dev, "transfer parameter size too large!");
2039 return 0;
2040 }
2041
2042 parameter->parameter_id = parameter_id;
2043 parameter->data_size = param_size;
2044
2045 ret = sst_ipc_tx_message_wait(&hsw->ipc, header,
2046 parameter, transfer_parameter_size , NULL, 0);
2047 if (ret < 0)
2048 dev_err(dev, "ipc: module set parameter failed - %d\n", ret);
2049
2050 kfree(parameter);
2051
2052 if (data)
2053 dma_free_coherent(hsw->dsp->dma_dev,
2054 param_size, (void *)data, dma_addr);
2055
2056 return ret;
1887} 2057}
1888 2058
1889static struct sst_dsp_device hsw_dev = { 2059static struct sst_dsp_device hsw_dev = {
@@ -1891,10 +2061,48 @@ static struct sst_dsp_device hsw_dev = {
1891 .ops = &haswell_ops, 2061 .ops = &haswell_ops,
1892}; 2062};
1893 2063
2064static void hsw_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
2065{
2066 /* send the message */
2067 sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size);
2068 sst_dsp_ipc_msg_tx(ipc->dsp, msg->header);
2069}
2070
2071static void hsw_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
2072{
2073 struct sst_dsp *sst = ipc->dsp;
2074 u32 isr, ipcd, imrx, ipcx;
2075
2076 ipcx = sst_dsp_shim_read_unlocked(sst, SST_IPCX);
2077 isr = sst_dsp_shim_read_unlocked(sst, SST_ISRX);
2078 ipcd = sst_dsp_shim_read_unlocked(sst, SST_IPCD);
2079 imrx = sst_dsp_shim_read_unlocked(sst, SST_IMRX);
2080
2081 dev_err(ipc->dev,
2082 "ipc: --%s-- ipcx 0x%8.8x isr 0x%8.8x ipcd 0x%8.8x imrx 0x%8.8x\n",
2083 text, ipcx, isr, ipcd, imrx);
2084}
2085
2086static void hsw_tx_data_copy(struct ipc_message *msg, char *tx_data,
2087 size_t tx_size)
2088{
2089 memcpy(msg->tx_data, tx_data, tx_size);
2090}
2091
2092static u64 hsw_reply_msg_match(u64 header, u64 *mask)
2093{
2094 /* clear reply bits & status bits */
2095 header &= ~(IPC_STATUS_MASK | IPC_GLB_REPLY_MASK);
2096 *mask = (u64)-1;
2097
2098 return header;
2099}
2100
1894int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata) 2101int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
1895{ 2102{
1896 struct sst_hsw_ipc_fw_version version; 2103 struct sst_hsw_ipc_fw_version version;
1897 struct sst_hsw *hsw; 2104 struct sst_hsw *hsw;
2105 struct sst_generic_ipc *ipc;
1898 int ret; 2106 int ret;
1899 2107
1900 dev_dbg(dev, "initialising Audio DSP IPC\n"); 2108 dev_dbg(dev, "initialising Audio DSP IPC\n");
@@ -1903,39 +2111,30 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
1903 if (hsw == NULL) 2111 if (hsw == NULL)
1904 return -ENOMEM; 2112 return -ENOMEM;
1905 2113
1906 hsw->dev = dev; 2114 ipc = &hsw->ipc;
1907 INIT_LIST_HEAD(&hsw->stream_list); 2115 ipc->dev = dev;
1908 INIT_LIST_HEAD(&hsw->tx_list); 2116 ipc->ops.tx_msg = hsw_tx_msg;
1909 INIT_LIST_HEAD(&hsw->rx_list); 2117 ipc->ops.shim_dbg = hsw_shim_dbg;
1910 INIT_LIST_HEAD(&hsw->empty_list); 2118 ipc->ops.tx_data_copy = hsw_tx_data_copy;
1911 init_waitqueue_head(&hsw->boot_wait); 2119 ipc->ops.reply_msg_match = hsw_reply_msg_match;
1912 init_waitqueue_head(&hsw->wait_txq);
1913
1914 ret = msg_empty_list_init(hsw);
1915 if (ret < 0)
1916 return -ENOMEM;
1917 2120
1918 /* start the IPC message thread */ 2121 ret = sst_ipc_init(ipc);
1919 init_kthread_worker(&hsw->kworker); 2122 if (ret != 0)
1920 hsw->tx_thread = kthread_run(kthread_worker_fn, 2123 goto ipc_init_err;
1921 &hsw->kworker, "%s",
1922 dev_name(hsw->dev));
1923 if (IS_ERR(hsw->tx_thread)) {
1924 ret = PTR_ERR(hsw->tx_thread);
1925 dev_err(hsw->dev, "error: failed to create message TX task\n");
1926 goto err_free_msg;
1927 }
1928 init_kthread_work(&hsw->kwork, ipc_tx_msgs);
1929 2124
2125 INIT_LIST_HEAD(&hsw->stream_list);
2126 init_waitqueue_head(&hsw->boot_wait);
1930 hsw_dev.thread_context = hsw; 2127 hsw_dev.thread_context = hsw;
1931 2128
1932 /* init SST shim */ 2129 /* init SST shim */
1933 hsw->dsp = sst_dsp_new(dev, &hsw_dev, pdata); 2130 hsw->dsp = sst_dsp_new(dev, &hsw_dev, pdata);
1934 if (hsw->dsp == NULL) { 2131 if (hsw->dsp == NULL) {
1935 ret = -ENODEV; 2132 ret = -ENODEV;
1936 goto dsp_err; 2133 goto dsp_new_err;
1937 } 2134 }
1938 2135
2136 ipc->dsp = hsw->dsp;
2137
1939 /* allocate DMA buffer for context storage */ 2138 /* allocate DMA buffer for context storage */
1940 hsw->dx_context = dma_alloc_coherent(hsw->dsp->dma_dev, 2139 hsw->dx_context = dma_alloc_coherent(hsw->dsp->dma_dev,
1941 SST_HSW_DX_CONTEXT_SIZE, &hsw->dx_context_paddr, GFP_KERNEL); 2140 SST_HSW_DX_CONTEXT_SIZE, &hsw->dx_context_paddr, GFP_KERNEL);
@@ -1947,18 +2146,22 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
1947 /* keep the DSP in reset state for base FW loading */ 2146 /* keep the DSP in reset state for base FW loading */
1948 sst_dsp_reset(hsw->dsp); 2147 sst_dsp_reset(hsw->dsp);
1949 2148
1950 hsw->sst_fw = sst_fw_new(hsw->dsp, pdata->fw, hsw); 2149 /* load base module and other modules in base firmware image */
1951 if (hsw->sst_fw == NULL) { 2150 ret = sst_hsw_module_load(hsw, SST_HSW_MODULE_BASE_FW, 0, "Base");
1952 ret = -ENODEV; 2151 if (ret < 0)
1953 dev_err(dev, "error: failed to load firmware\n");
1954 goto fw_err; 2152 goto fw_err;
1955 } 2153
2154 /* try to load module waves */
2155 sst_hsw_module_load(hsw, SST_HSW_MODULE_WAVES, 0, "intel/IntcPP01.bin");
1956 2156
1957 /* allocate scratch mem regions */ 2157 /* allocate scratch mem regions */
1958 ret = sst_block_alloc_scratch(hsw->dsp); 2158 ret = sst_block_alloc_scratch(hsw->dsp);
1959 if (ret < 0) 2159 if (ret < 0)
1960 goto boot_err; 2160 goto boot_err;
1961 2161
2162 /* init param buffer */
2163 sst_hsw_reset_param_buf(hsw);
2164
1962 /* wait for DSP boot completion */ 2165 /* wait for DSP boot completion */
1963 sst_dsp_boot(hsw->dsp); 2166 sst_dsp_boot(hsw->dsp);
1964 ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete, 2167 ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete,
@@ -1971,6 +2174,9 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
1971 goto boot_err; 2174 goto boot_err;
1972 } 2175 }
1973 2176
2177 /* init module state after boot */
2178 sst_hsw_init_module_state(hsw);
2179
1974 /* get the FW version */ 2180 /* get the FW version */
1975 sst_hsw_fw_get_version(hsw, &version); 2181 sst_hsw_fw_get_version(hsw, &version);
1976 2182
@@ -1986,17 +2192,16 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
1986 2192
1987boot_err: 2193boot_err:
1988 sst_dsp_reset(hsw->dsp); 2194 sst_dsp_reset(hsw->dsp);
1989 sst_fw_free(hsw->sst_fw); 2195 sst_fw_free_all(hsw->dsp);
1990fw_err: 2196fw_err:
1991 dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE, 2197 dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE,
1992 hsw->dx_context, hsw->dx_context_paddr); 2198 hsw->dx_context, hsw->dx_context_paddr);
1993dma_err: 2199dma_err:
1994 sst_dsp_free(hsw->dsp); 2200 sst_dsp_free(hsw->dsp);
1995dsp_err: 2201dsp_new_err:
1996 kthread_stop(hsw->tx_thread); 2202 sst_ipc_fini(ipc);
1997err_free_msg: 2203ipc_init_err:
1998 kfree(hsw->msg); 2204 kfree(hsw);
1999
2000 return ret; 2205 return ret;
2001} 2206}
2002EXPORT_SYMBOL_GPL(sst_hsw_dsp_init); 2207EXPORT_SYMBOL_GPL(sst_hsw_dsp_init);
@@ -2010,7 +2215,6 @@ void sst_hsw_dsp_free(struct device *dev, struct sst_pdata *pdata)
2010 dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE, 2215 dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE,
2011 hsw->dx_context, hsw->dx_context_paddr); 2216 hsw->dx_context, hsw->dx_context_paddr);
2012 sst_dsp_free(hsw->dsp); 2217 sst_dsp_free(hsw->dsp);
2013 kthread_stop(hsw->tx_thread); 2218 sst_ipc_fini(&hsw->ipc);
2014 kfree(hsw->msg);
2015} 2219}
2016EXPORT_SYMBOL_GPL(sst_hsw_dsp_free); 2220EXPORT_SYMBOL_GPL(sst_hsw_dsp_free);
diff --git a/sound/soc/intel/sst-haswell-ipc.h b/sound/soc/intel/haswell/sst-haswell-ipc.h
index 858096041cb1..06d71aefa1fe 100644
--- a/sound/soc/intel/sst-haswell-ipc.h
+++ b/sound/soc/intel/haswell/sst-haswell-ipc.h
@@ -37,6 +37,9 @@
37#define SST_HSW_IPC_MAX_PAYLOAD_SIZE 400 37#define SST_HSW_IPC_MAX_PAYLOAD_SIZE 400
38#define SST_HSW_MAX_INFO_SIZE 64 38#define SST_HSW_MAX_INFO_SIZE 64
39#define SST_HSW_BUILD_HASH_LENGTH 40 39#define SST_HSW_BUILD_HASH_LENGTH 40
40#define SST_HSW_IPC_MAX_SHORT_PARAMETER_SIZE 500
41#define WAVES_PARAM_COUNT 128
42#define WAVES_PARAM_LINES 160
40 43
41struct sst_hsw; 44struct sst_hsw;
42struct sst_hsw_stream; 45struct sst_hsw_stream;
@@ -187,6 +190,28 @@ enum sst_hsw_performance_action {
187 SST_HSW_PERF_STOP = 1, 190 SST_HSW_PERF_STOP = 1,
188}; 191};
189 192
193struct sst_hsw_transfer_info {
194 uint32_t destination; /* destination address */
195 uint32_t reverse:1; /* if 1 data flows from destination */
196 uint32_t size:31; /* transfer size in bytes.*/
197 uint16_t first_page_offset; /* offset to data in the first page. */
198 uint8_t packed_pages; /* page addresses. Each occupies 20 bits */
199} __attribute__((packed));
200
201struct sst_hsw_transfer_list {
202 uint32_t transfers_count;
203 struct sst_hsw_transfer_info transfers;
204} __attribute__((packed));
205
206struct sst_hsw_transfer_parameter {
207 uint32_t parameter_id;
208 uint32_t data_size;
209 union {
210 uint8_t data[1];
211 struct sst_hsw_transfer_list transfer_list;
212 };
213} __attribute__((packed));
214
190/* SST firmware module info */ 215/* SST firmware module info */
191struct sst_hsw_module_info { 216struct sst_hsw_module_info {
192 u8 name[SST_HSW_MAX_INFO_SIZE]; 217 u8 name[SST_HSW_MAX_INFO_SIZE];
@@ -215,6 +240,12 @@ struct sst_hsw_fx_enable {
215 struct sst_hsw_memory_info persistent_mem; 240 struct sst_hsw_memory_info persistent_mem;
216} __attribute__((packed)); 241} __attribute__((packed));
217 242
243struct sst_hsw_ipc_module_config {
244 struct sst_hsw_module_map map;
245 struct sst_hsw_memory_info persistent_mem;
246 struct sst_hsw_memory_info scratch_mem;
247} __attribute__((packed));
248
218struct sst_hsw_get_fx_param { 249struct sst_hsw_get_fx_param {
219 u32 parameter_id; 250 u32 parameter_id;
220 u32 param_size; 251 u32 param_size;
@@ -467,6 +498,28 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata);
467void sst_hsw_dsp_free(struct device *dev, struct sst_pdata *pdata); 498void sst_hsw_dsp_free(struct device *dev, struct sst_pdata *pdata);
468struct sst_dsp *sst_hsw_get_dsp(struct sst_hsw *hsw); 499struct sst_dsp *sst_hsw_get_dsp(struct sst_hsw *hsw);
469 500
501/* fw module function */
502void sst_hsw_init_module_state(struct sst_hsw *hsw);
503bool sst_hsw_is_module_loaded(struct sst_hsw *hsw, u32 module_id);
504bool sst_hsw_is_module_active(struct sst_hsw *hsw, u32 module_id);
505void sst_hsw_set_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id);
506void sst_hsw_set_module_disabled_rtd3(struct sst_hsw *hsw, u32 module_id);
507bool sst_hsw_is_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id);
508void sst_hsw_reset_param_buf(struct sst_hsw *hsw);
509int sst_hsw_store_param_line(struct sst_hsw *hsw, u8 *buf);
510int sst_hsw_load_param_line(struct sst_hsw *hsw, u8 *buf);
511int sst_hsw_launch_param_buf(struct sst_hsw *hsw);
512
513int sst_hsw_module_load(struct sst_hsw *hsw,
514 u32 module_id, u32 instance_id, char *name);
515int sst_hsw_module_enable(struct sst_hsw *hsw,
516 u32 module_id, u32 instance_id);
517int sst_hsw_module_disable(struct sst_hsw *hsw,
518 u32 module_id, u32 instance_id);
519int sst_hsw_module_set_param(struct sst_hsw *hsw,
520 u32 module_id, u32 instance_id, u32 parameter_id,
521 u32 param_size, char *param);
522
470/* runtime module management */ 523/* runtime module management */
471struct sst_module_runtime *sst_hsw_runtime_module_create(struct sst_hsw *hsw, 524struct sst_module_runtime *sst_hsw_runtime_module_create(struct sst_hsw *hsw,
472 int mod_id, int offset); 525 int mod_id, int offset);
diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/haswell/sst-haswell-pcm.c
index 7e21e8f85885..23ae0400d6db 100644
--- a/sound/soc/intel/sst-haswell-pcm.c
+++ b/sound/soc/intel/haswell/sst-haswell-pcm.c
@@ -29,9 +29,9 @@
29#include <sound/tlv.h> 29#include <sound/tlv.h>
30#include <sound/compress_driver.h> 30#include <sound/compress_driver.h>
31 31
32#include "sst-haswell-ipc.h" 32#include "../haswell/sst-haswell-ipc.h"
33#include "sst-dsp-priv.h" 33#include "../common/sst-dsp-priv.h"
34#include "sst-dsp.h" 34#include "../common/sst-dsp.h"
35 35
36#define HSW_PCM_COUNT 6 36#define HSW_PCM_COUNT 6
37#define HSW_VOLUME_MAX 0x7FFFFFFF /* 0dB */ 37#define HSW_VOLUME_MAX 0x7FFFFFFF /* 0dB */
@@ -137,6 +137,7 @@ struct hsw_priv_data {
137 struct device *dev; 137 struct device *dev;
138 enum hsw_pm_state pm_state; 138 enum hsw_pm_state pm_state;
139 struct snd_soc_card *soc_card; 139 struct snd_soc_card *soc_card;
140 struct sst_module_runtime *runtime_waves; /* sound effect module */
140 141
141 /* page tables */ 142 /* page tables */
142 struct snd_dma_buffer dmab[HSW_PCM_COUNT][2]; 143 struct snd_dma_buffer dmab[HSW_PCM_COUNT][2];
@@ -318,6 +319,93 @@ static int hsw_volume_get(struct snd_kcontrol *kcontrol,
318 return 0; 319 return 0;
319} 320}
320 321
322static int hsw_waves_switch_get(struct snd_kcontrol *kcontrol,
323 struct snd_ctl_elem_value *ucontrol)
324{
325 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
326 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
327 struct sst_hsw *hsw = pdata->hsw;
328 enum sst_hsw_module_id id = SST_HSW_MODULE_WAVES;
329
330 ucontrol->value.integer.value[0] =
331 (sst_hsw_is_module_active(hsw, id) ||
332 sst_hsw_is_module_enabled_rtd3(hsw, id));
333 return 0;
334}
335
336static int hsw_waves_switch_put(struct snd_kcontrol *kcontrol,
337 struct snd_ctl_elem_value *ucontrol)
338{
339 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
340 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
341 struct sst_hsw *hsw = pdata->hsw;
342 int ret = 0;
343 enum sst_hsw_module_id id = SST_HSW_MODULE_WAVES;
344 bool switch_on = (bool)ucontrol->value.integer.value[0];
345
346 /* if module is in RAM on the DSP, apply user settings to module through
347 * ipc. If module is not in RAM on the DSP, store user setting for
348 * track */
349 if (sst_hsw_is_module_loaded(hsw, id)) {
350 if (switch_on == sst_hsw_is_module_active(hsw, id))
351 return 0;
352
353 if (switch_on)
354 ret = sst_hsw_module_enable(hsw, id, 0);
355 else
356 ret = sst_hsw_module_disable(hsw, id, 0);
357 } else {
358 if (switch_on == sst_hsw_is_module_enabled_rtd3(hsw, id))
359 return 0;
360
361 if (switch_on)
362 sst_hsw_set_module_enabled_rtd3(hsw, id);
363 else
364 sst_hsw_set_module_disabled_rtd3(hsw, id);
365 }
366
367 return ret;
368}
369
370static int hsw_waves_param_get(struct snd_kcontrol *kcontrol,
371 struct snd_ctl_elem_value *ucontrol)
372{
373 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
374 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
375 struct sst_hsw *hsw = pdata->hsw;
376
377 /* return a matching line from param buffer */
378 return sst_hsw_load_param_line(hsw, ucontrol->value.bytes.data);
379}
380
381static int hsw_waves_param_put(struct snd_kcontrol *kcontrol,
382 struct snd_ctl_elem_value *ucontrol)
383{
384 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
385 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
386 struct sst_hsw *hsw = pdata->hsw;
387 int ret;
388 enum sst_hsw_module_id id = SST_HSW_MODULE_WAVES;
389 int param_id = ucontrol->value.bytes.data[0];
390 int param_size = WAVES_PARAM_COUNT;
391
392 /* clear param buffer and reset buffer index */
393 if (param_id == 0xFF) {
394 sst_hsw_reset_param_buf(hsw);
395 return 0;
396 }
397
398 /* store params into buffer */
399 ret = sst_hsw_store_param_line(hsw, ucontrol->value.bytes.data);
400 if (ret < 0)
401 return ret;
402
403 if (sst_hsw_is_module_active(hsw, id))
404 ret = sst_hsw_module_set_param(hsw, id, 0, param_id,
405 param_size, ucontrol->value.bytes.data);
406 return ret;
407}
408
321/* TLV used by both global and stream volumes */ 409/* TLV used by both global and stream volumes */
322static const DECLARE_TLV_DB_SCALE(hsw_vol_tlv, -9000, 300, 1); 410static const DECLARE_TLV_DB_SCALE(hsw_vol_tlv, -9000, 300, 1);
323 411
@@ -339,6 +427,12 @@ static const struct snd_kcontrol_new hsw_volume_controls[] = {
339 SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 4, 0, 8, 427 SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 4, 0, 8,
340 ARRAY_SIZE(volume_map) - 1, 0, 428 ARRAY_SIZE(volume_map) - 1, 0,
341 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), 429 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
430 /* enable/disable module waves */
431 SOC_SINGLE_BOOL_EXT("Waves Switch", 0,
432 hsw_waves_switch_get, hsw_waves_switch_put),
433 /* set parameters to module waves */
434 SND_SOC_BYTES_EXT("Waves Set Param", WAVES_PARAM_COUNT,
435 hsw_waves_param_get, hsw_waves_param_put),
342}; 436};
343 437
344/* Create DMA buffer page table for DSP */ 438/* Create DMA buffer page table for DSP */
@@ -807,6 +901,14 @@ static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
807 pcm_data->runtime->persistent_offset; 901 pcm_data->runtime->persistent_offset;
808 } 902 }
809 903
904 /* create runtime blocks for module waves */
905 if (sst_hsw_is_module_loaded(hsw, SST_HSW_MODULE_WAVES)) {
906 pdata->runtime_waves = sst_hsw_runtime_module_create(hsw,
907 SST_HSW_MODULE_WAVES, 0);
908 if (pdata->runtime_waves == NULL)
909 goto err;
910 }
911
810 return 0; 912 return 0;
811 913
812err: 914err:
@@ -820,14 +922,17 @@ err:
820 922
821static void hsw_pcm_free_modules(struct hsw_priv_data *pdata) 923static void hsw_pcm_free_modules(struct hsw_priv_data *pdata)
822{ 924{
925 struct sst_hsw *hsw = pdata->hsw;
823 struct hsw_pcm_data *pcm_data; 926 struct hsw_pcm_data *pcm_data;
824 int i; 927 int i;
825 928
826 for (i = 0; i < ARRAY_SIZE(mod_map); i++) { 929 for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
827 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream]; 930 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
828
829 sst_hsw_runtime_module_free(pcm_data->runtime); 931 sst_hsw_runtime_module_free(pcm_data->runtime);
830 } 932 }
933 if (sst_hsw_is_module_loaded(hsw, SST_HSW_MODULE_WAVES)) {
934 sst_hsw_runtime_module_free(pdata->runtime_waves);
935 }
831} 936}
832 937
833static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd) 938static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
@@ -984,7 +1089,9 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
984 } 1089 }
985 1090
986 /* allocate runtime modules */ 1091 /* allocate runtime modules */
987 hsw_pcm_create_modules(priv_data); 1092 ret = hsw_pcm_create_modules(priv_data);
1093 if (ret < 0)
1094 goto err;
988 1095
989 /* enable runtime PM with auto suspend */ 1096 /* enable runtime PM with auto suspend */
990 pm_runtime_set_autosuspend_delay(platform->dev, 1097 pm_runtime_set_autosuspend_delay(platform->dev,
@@ -996,7 +1103,7 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
996 return 0; 1103 return 0;
997 1104
998err: 1105err:
999 for (;i >= 0; i--) { 1106 for (--i; i >= 0; i--) {
1000 if (hsw_dais[i].playback.channels_min) 1107 if (hsw_dais[i].playback.channels_min)
1001 snd_dma_free_pages(&priv_data->dmab[i][0]); 1108 snd_dma_free_pages(&priv_data->dmab[i][0]);
1002 if (hsw_dais[i].capture.channels_min) 1109 if (hsw_dais[i].capture.channels_min)
@@ -1101,10 +1208,18 @@ static int hsw_pcm_runtime_suspend(struct device *dev)
1101{ 1208{
1102 struct hsw_priv_data *pdata = dev_get_drvdata(dev); 1209 struct hsw_priv_data *pdata = dev_get_drvdata(dev);
1103 struct sst_hsw *hsw = pdata->hsw; 1210 struct sst_hsw *hsw = pdata->hsw;
1211 int ret;
1104 1212
1105 if (pdata->pm_state >= HSW_PM_STATE_RTD3) 1213 if (pdata->pm_state >= HSW_PM_STATE_RTD3)
1106 return 0; 1214 return 0;
1107 1215
1216 /* fw modules will be unloaded on RTD3, set flag to track */
1217 if (sst_hsw_is_module_active(hsw, SST_HSW_MODULE_WAVES)) {
1218 ret = sst_hsw_module_disable(hsw, SST_HSW_MODULE_WAVES, 0);
1219 if (ret < 0)
1220 return ret;
1221 sst_hsw_set_module_enabled_rtd3(hsw, SST_HSW_MODULE_WAVES);
1222 }
1108 sst_hsw_dsp_runtime_suspend(hsw); 1223 sst_hsw_dsp_runtime_suspend(hsw);
1109 sst_hsw_dsp_runtime_sleep(hsw); 1224 sst_hsw_dsp_runtime_sleep(hsw);
1110 pdata->pm_state = HSW_PM_STATE_RTD3; 1225 pdata->pm_state = HSW_PM_STATE_RTD3;
@@ -1139,6 +1254,19 @@ static int hsw_pcm_runtime_resume(struct device *dev)
1139 else if (ret == 1) /* no action required */ 1254 else if (ret == 1) /* no action required */
1140 return 0; 1255 return 0;
1141 1256
1257 /* check flag when resume */
1258 if (sst_hsw_is_module_enabled_rtd3(hsw, SST_HSW_MODULE_WAVES)) {
1259 ret = sst_hsw_module_enable(hsw, SST_HSW_MODULE_WAVES, 0);
1260 if (ret < 0)
1261 return ret;
1262 /* put parameters from buffer to dsp */
1263 ret = sst_hsw_launch_param_buf(hsw);
1264 if (ret < 0)
1265 return ret;
1266 /* unset flag */
1267 sst_hsw_set_module_disabled_rtd3(hsw, SST_HSW_MODULE_WAVES);
1268 }
1269
1142 pdata->pm_state = HSW_PM_STATE_D0; 1270 pdata->pm_state = HSW_PM_STATE_D0;
1143 return ret; 1271 return ret;
1144} 1272}
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 07f77815a586..b05fb1c1a848 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -58,6 +58,12 @@
58 58
59#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12 59#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12
60#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8 60#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8
61#define JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24
62#define JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16
63#define JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_MASK \
64 (0xf << JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET)
65#define JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_MASK \
66 (0x1f << JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET)
61 67
62#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19) 68#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19)
63#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16) 69#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16)
@@ -79,6 +85,7 @@
79#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET 16 85#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET 16
80 86
81#define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12) 87#define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12)
88#define JZ_AIC_I2S_FMT_DISABLE_BIT_ICLK BIT(13)
82#define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4) 89#define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4)
83#define JZ_AIC_I2S_FMT_MSB BIT(0) 90#define JZ_AIC_I2S_FMT_MSB BIT(0)
84 91
@@ -87,6 +94,13 @@
87#define JZ_AIC_CLK_DIV_MASK 0xf 94#define JZ_AIC_CLK_DIV_MASK 0xf
88#define I2SDIV_DV_SHIFT 8 95#define I2SDIV_DV_SHIFT 8
89#define I2SDIV_DV_MASK (0xf << I2SDIV_DV_SHIFT) 96#define I2SDIV_DV_MASK (0xf << I2SDIV_DV_SHIFT)
97#define I2SDIV_IDV_SHIFT 8
98#define I2SDIV_IDV_MASK (0xf << I2SDIV_IDV_SHIFT)
99
100enum jz47xx_i2s_version {
101 JZ_I2S_JZ4740,
102 JZ_I2S_JZ4780,
103};
90 104
91struct jz4740_i2s { 105struct jz4740_i2s {
92 struct resource *mem; 106 struct resource *mem;
@@ -98,6 +112,8 @@ struct jz4740_i2s {
98 112
99 struct snd_dmaengine_dai_dma_data playback_dma_data; 113 struct snd_dmaengine_dai_dma_data playback_dma_data;
100 struct snd_dmaengine_dai_dma_data capture_dma_data; 114 struct snd_dmaengine_dai_dma_data capture_dma_data;
115
116 enum jz47xx_i2s_version version;
101}; 117};
102 118
103static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s, 119static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s,
@@ -267,13 +283,22 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
267 ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO; 283 ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO;
268 else 284 else
269 ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO; 285 ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO;
286
287 div_reg &= ~I2SDIV_DV_MASK;
288 div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
270 } else { 289 } else {
271 ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK; 290 ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
272 ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET; 291 ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
292
293 if (i2s->version >= JZ_I2S_JZ4780) {
294 div_reg &= ~I2SDIV_IDV_MASK;
295 div_reg |= (div - 1) << I2SDIV_IDV_SHIFT;
296 } else {
297 div_reg &= ~I2SDIV_DV_MASK;
298 div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
299 }
273 } 300 }
274 301
275 div_reg &= ~I2SDIV_DV_MASK;
276 div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
277 jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl); 302 jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
278 jz4740_i2s_write(i2s, JZ_REG_AIC_CLK_DIV, div_reg); 303 jz4740_i2s_write(i2s, JZ_REG_AIC_CLK_DIV, div_reg);
279 304
@@ -369,11 +394,19 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
369 snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, 394 snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
370 &i2s->capture_dma_data); 395 &i2s->capture_dma_data);
371 396
372 conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) | 397 if (i2s->version >= JZ_I2S_JZ4780) {
373 (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) | 398 conf = (7 << JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
374 JZ_AIC_CONF_OVERFLOW_PLAY_LAST | 399 (8 << JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
375 JZ_AIC_CONF_I2S | 400 JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
376 JZ_AIC_CONF_INTERNAL_CODEC; 401 JZ_AIC_CONF_I2S |
402 JZ_AIC_CONF_INTERNAL_CODEC;
403 } else {
404 conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
405 (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
406 JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
407 JZ_AIC_CONF_I2S |
408 JZ_AIC_CONF_INTERNAL_CODEC;
409 }
377 410
378 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET); 411 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
379 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf); 412 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
@@ -422,13 +455,34 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = {
422 .resume = jz4740_i2s_resume, 455 .resume = jz4740_i2s_resume,
423}; 456};
424 457
458static struct snd_soc_dai_driver jz4780_i2s_dai = {
459 .probe = jz4740_i2s_dai_probe,
460 .remove = jz4740_i2s_dai_remove,
461 .playback = {
462 .channels_min = 1,
463 .channels_max = 2,
464 .rates = SNDRV_PCM_RATE_8000_48000,
465 .formats = JZ4740_I2S_FMTS,
466 },
467 .capture = {
468 .channels_min = 2,
469 .channels_max = 2,
470 .rates = SNDRV_PCM_RATE_8000_48000,
471 .formats = JZ4740_I2S_FMTS,
472 },
473 .ops = &jz4740_i2s_dai_ops,
474 .suspend = jz4740_i2s_suspend,
475 .resume = jz4740_i2s_resume,
476};
477
425static const struct snd_soc_component_driver jz4740_i2s_component = { 478static const struct snd_soc_component_driver jz4740_i2s_component = {
426 .name = "jz4740-i2s", 479 .name = "jz4740-i2s",
427}; 480};
428 481
429#ifdef CONFIG_OF 482#ifdef CONFIG_OF
430static const struct of_device_id jz4740_of_matches[] = { 483static const struct of_device_id jz4740_of_matches[] = {
431 { .compatible = "ingenic,jz4740-i2s" }, 484 { .compatible = "ingenic,jz4740-i2s", .data = (void *)JZ_I2S_JZ4740 },
485 { .compatible = "ingenic,jz4780-i2s", .data = (void *)JZ_I2S_JZ4780 },
432 { /* sentinel */ } 486 { /* sentinel */ }
433}; 487};
434#endif 488#endif
@@ -438,11 +492,16 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev)
438 struct jz4740_i2s *i2s; 492 struct jz4740_i2s *i2s;
439 struct resource *mem; 493 struct resource *mem;
440 int ret; 494 int ret;
495 const struct of_device_id *match;
441 496
442 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); 497 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
443 if (!i2s) 498 if (!i2s)
444 return -ENOMEM; 499 return -ENOMEM;
445 500
501 match = of_match_device(jz4740_of_matches, &pdev->dev);
502 if (match)
503 i2s->version = (enum jz47xx_i2s_version)match->data;
504
446 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 505 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
447 i2s->base = devm_ioremap_resource(&pdev->dev, mem); 506 i2s->base = devm_ioremap_resource(&pdev->dev, mem);
448 if (IS_ERR(i2s->base)) 507 if (IS_ERR(i2s->base))
@@ -460,8 +519,13 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev)
460 519
461 platform_set_drvdata(pdev, i2s); 520 platform_set_drvdata(pdev, i2s);
462 521
463 ret = devm_snd_soc_register_component(&pdev->dev, 522 if (i2s->version == JZ_I2S_JZ4780)
464 &jz4740_i2s_component, &jz4740_i2s_dai, 1); 523 ret = devm_snd_soc_register_component(&pdev->dev,
524 &jz4740_i2s_component, &jz4780_i2s_dai, 1);
525 else
526 ret = devm_snd_soc_register_component(&pdev->dev,
527 &jz4740_i2s_component, &jz4740_i2s_dai, 1);
528
465 if (ret) 529 if (ret)
466 return ret; 530 return ret;
467 531
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index d19483081f9b..3a36d60e1785 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -643,7 +643,7 @@ static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
643} 643}
644 644
645#ifdef CONFIG_OF 645#ifdef CONFIG_OF
646static struct of_device_id mvebu_audio_of_match[] = { 646static const struct of_device_id mvebu_audio_of_match[] = {
647 { .compatible = "marvell,kirkwood-audio" }, 647 { .compatible = "marvell,kirkwood-audio" },
648 { .compatible = "marvell,dove-audio" }, 648 { .compatible = "marvell,dove-audio" },
649 { .compatible = "marvell,armada370-audio" }, 649 { .compatible = "marvell,armada370-audio" },
diff --git a/sound/soc/nuc900/nuc900-audio.h b/sound/soc/nuc900/nuc900-audio.h
index 59f7e8ed1a68..d0b725705914 100644
--- a/sound/soc/nuc900/nuc900-audio.h
+++ b/sound/soc/nuc900/nuc900-audio.h
@@ -100,10 +100,7 @@
100struct nuc900_audio { 100struct nuc900_audio {
101 void __iomem *mmio; 101 void __iomem *mmio;
102 spinlock_t lock; 102 spinlock_t lock;
103 dma_addr_t dma_addr[2];
104 unsigned long buffersize[2];
105 unsigned long irq_num; 103 unsigned long irq_num;
106 struct snd_pcm_substream *substream;
107 struct resource *res; 104 struct resource *res;
108 struct clk *clk; 105 struct clk *clk;
109 struct device *dev; 106 struct device *dev;
diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c
index b809fa909e4d..5ae5ca15b6d6 100644
--- a/sound/soc/nuc900/nuc900-pcm.c
+++ b/sound/soc/nuc900/nuc900-pcm.c
@@ -42,29 +42,10 @@ static const struct snd_pcm_hardware nuc900_pcm_hardware = {
42static int nuc900_dma_hw_params(struct snd_pcm_substream *substream, 42static int nuc900_dma_hw_params(struct snd_pcm_substream *substream,
43 struct snd_pcm_hw_params *params) 43 struct snd_pcm_hw_params *params)
44{ 44{
45 struct snd_pcm_runtime *runtime = substream->runtime; 45 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
46 struct nuc900_audio *nuc900_audio = runtime->private_data;
47 unsigned long flags;
48 int ret = 0;
49
50 ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
51 if (ret < 0)
52 return ret;
53
54 spin_lock_irqsave(&nuc900_audio->lock, flags);
55
56 nuc900_audio->substream = substream;
57 nuc900_audio->dma_addr[substream->stream] = runtime->dma_addr;
58 nuc900_audio->buffersize[substream->stream] =
59 params_buffer_bytes(params);
60
61 spin_unlock_irqrestore(&nuc900_audio->lock, flags);
62
63 return ret;
64} 46}
65 47
66static void nuc900_update_dma_register(struct snd_pcm_substream *substream, 48static void nuc900_update_dma_register(struct snd_pcm_substream *substream)
67 dma_addr_t dma_addr, size_t count)
68{ 49{
69 struct snd_pcm_runtime *runtime = substream->runtime; 50 struct snd_pcm_runtime *runtime = substream->runtime;
70 struct nuc900_audio *nuc900_audio = runtime->private_data; 51 struct nuc900_audio *nuc900_audio = runtime->private_data;
@@ -78,8 +59,8 @@ static void nuc900_update_dma_register(struct snd_pcm_substream *substream,
78 mmio_len = nuc900_audio->mmio + ACTL_RDST_LENGTH; 59 mmio_len = nuc900_audio->mmio + ACTL_RDST_LENGTH;
79 } 60 }
80 61
81 AUDIO_WRITE(mmio_addr, dma_addr); 62 AUDIO_WRITE(mmio_addr, runtime->dma_addr);
82 AUDIO_WRITE(mmio_len, count); 63 AUDIO_WRITE(mmio_len, runtime->dma_bytes);
83} 64}
84 65
85static void nuc900_dma_start(struct snd_pcm_substream *substream) 66static void nuc900_dma_start(struct snd_pcm_substream *substream)
@@ -170,9 +151,7 @@ static int nuc900_dma_prepare(struct snd_pcm_substream *substream)
170 151
171 spin_lock_irqsave(&nuc900_audio->lock, flags); 152 spin_lock_irqsave(&nuc900_audio->lock, flags);
172 153
173 nuc900_update_dma_register(substream, 154 nuc900_update_dma_register(substream);
174 nuc900_audio->dma_addr[substream->stream],
175 nuc900_audio->buffersize[substream->stream]);
176 155
177 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET); 156 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
178 157
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index e7c78b0406b5..6768e4f7d7d0 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -105,7 +105,7 @@ config SND_OMAP_SOC_OMAP_ABE_TWL6040
105 select SND_OMAP_SOC_MCPDM 105 select SND_OMAP_SOC_MCPDM
106 select SND_SOC_TWL6040 106 select SND_SOC_TWL6040
107 select SND_SOC_DMIC 107 select SND_SOC_DMIC
108 select COMMON_CLK_PALMAS if SOC_OMAP5 108 select COMMON_CLK_PALMAS if MFD_PALMAS
109 help 109 help
110 Say Y if you want to add support for SoC audio on OMAP boards using 110 Say Y if you want to add support for SoC audio on OMAP boards using
111 ABE and twl6040 codec. This driver currently supports: 111 ABE and twl6040 codec. This driver currently supports:
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 5d7f9cebe041..dcb5336b5698 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -98,12 +98,11 @@ static int n810_startup(struct snd_pcm_substream *substream)
98{ 98{
99 struct snd_pcm_runtime *runtime = substream->runtime; 99 struct snd_pcm_runtime *runtime = substream->runtime;
100 struct snd_soc_pcm_runtime *rtd = substream->private_data; 100 struct snd_soc_pcm_runtime *rtd = substream->private_data;
101 struct snd_soc_codec *codec = rtd->codec;
102 101
103 snd_pcm_hw_constraint_minmax(runtime, 102 snd_pcm_hw_constraint_minmax(runtime,
104 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); 103 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
105 104
106 n810_ext_control(&codec->dapm); 105 n810_ext_control(&rtd->card->dapm);
107 return clk_prepare_enable(sys_clkout2); 106 return clk_prepare_enable(sys_clkout2);
108} 107}
109 108
@@ -255,24 +254,6 @@ static const struct snd_kcontrol_new aic33_n810_controls[] = {
255 n810_get_input, n810_set_input), 254 n810_get_input, n810_set_input),
256}; 255};
257 256
258static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd)
259{
260 struct snd_soc_codec *codec = rtd->codec;
261 struct snd_soc_dapm_context *dapm = &codec->dapm;
262
263 /* Not connected */
264 snd_soc_dapm_nc_pin(dapm, "MONO_LOUT");
265 snd_soc_dapm_nc_pin(dapm, "HPLCOM");
266 snd_soc_dapm_nc_pin(dapm, "HPRCOM");
267 snd_soc_dapm_nc_pin(dapm, "MIC3L");
268 snd_soc_dapm_nc_pin(dapm, "MIC3R");
269 snd_soc_dapm_nc_pin(dapm, "LINE1R");
270 snd_soc_dapm_nc_pin(dapm, "LINE2L");
271 snd_soc_dapm_nc_pin(dapm, "LINE2R");
272
273 return 0;
274}
275
276/* Digital audio interface glue - connects codec <--> CPU */ 257/* Digital audio interface glue - connects codec <--> CPU */
277static struct snd_soc_dai_link n810_dai = { 258static struct snd_soc_dai_link n810_dai = {
278 .name = "TLV320AIC33", 259 .name = "TLV320AIC33",
@@ -283,7 +264,6 @@ static struct snd_soc_dai_link n810_dai = {
283 .codec_dai_name = "tlv320aic3x-hifi", 264 .codec_dai_name = "tlv320aic3x-hifi",
284 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 265 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
285 SND_SOC_DAIFMT_CBM_CFM, 266 SND_SOC_DAIFMT_CBM_CFM,
286 .init = n810_aic33_init,
287 .ops = &n810_ops, 267 .ops = &n810_ops,
288}; 268};
289 269
@@ -300,6 +280,7 @@ static struct snd_soc_card snd_soc_n810 = {
300 .num_dapm_widgets = ARRAY_SIZE(aic33_dapm_widgets), 280 .num_dapm_widgets = ARRAY_SIZE(aic33_dapm_widgets),
301 .dapm_routes = audio_map, 281 .dapm_routes = audio_map,
302 .num_dapm_routes = ARRAY_SIZE(audio_map), 282 .num_dapm_routes = ARRAY_SIZE(audio_map),
283 .fully_routed = true,
303}; 284};
304 285
305static struct platform_device *n810_snd_device; 286static struct platform_device *n810_snd_device;
diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c
index f7eb42aa3f38..4775da4c4db5 100644
--- a/sound/soc/omap/omap-hdmi-audio.c
+++ b/sound/soc/omap/omap-hdmi-audio.c
@@ -142,8 +142,6 @@ static int hdmi_dai_hw_params(struct snd_pcm_substream *substream,
142 142
143 iec->status[0] |= IEC958_AES0_CON_EMPHASIS_NONE; 143 iec->status[0] |= IEC958_AES0_CON_EMPHASIS_NONE;
144 144
145 iec->status[0] |= IEC958_AES1_PRO_MODE_NOTID;
146
147 iec->status[1] = IEC958_AES1_CON_GENERAL; 145 iec->status[1] = IEC958_AES1_CON_GENERAL;
148 146
149 iec->status[2] |= IEC958_AES2_CON_SOURCE_UNSPEC; 147 iec->status[2] |= IEC958_AES2_CON_SOURCE_UNSPEC;
diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
new file mode 100644
index 000000000000..5f58e4f1bca9
--- /dev/null
+++ b/sound/soc/qcom/Kconfig
@@ -0,0 +1,25 @@
1config SND_SOC_QCOM
2 tristate "ASoC support for QCOM platforms"
3 help
4 Say Y or M if you want to add support to use audio devices
5 in Qualcomm Technologies SOC-based platforms.
6
7config SND_SOC_LPASS_CPU
8 tristate
9 depends on SND_SOC_QCOM
10 select REGMAP_MMIO
11
12config SND_SOC_LPASS_PLATFORM
13 tristate
14 depends on SND_SOC_QCOM
15 select REGMAP_MMIO
16
17config SND_SOC_STORM
18 tristate "ASoC I2S support for Storm boards"
19 depends on (ARCH_QCOM && SND_SOC_QCOM) || COMPILE_TEST
20 select SND_SOC_LPASS_CPU
21 select SND_SOC_LPASS_PLATFORM
22 select SND_SOC_MAX98357A
23 help
24 Say Y or M if you want add support for SoC audio on the
25 Qualcomm Technologies IPQ806X-based Storm board.
diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile
new file mode 100644
index 000000000000..c5ce96c761c4
--- /dev/null
+++ b/sound/soc/qcom/Makefile
@@ -0,0 +1,11 @@
1# Platform
2snd-soc-lpass-cpu-objs := lpass-cpu.o
3snd-soc-lpass-platform-objs := lpass-platform.o
4
5obj-$(CONFIG_SND_SOC_LPASS_CPU) += snd-soc-lpass-cpu.o
6obj-$(CONFIG_SND_SOC_LPASS_PLATFORM) += snd-soc-lpass-platform.o
7
8# Machine
9snd-soc-storm-objs := storm.o
10
11obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
new file mode 100644
index 000000000000..6698d058de29
--- /dev/null
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -0,0 +1,491 @@
1/*
2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * lpass-cpu.c -- ALSA SoC CPU DAI driver for QTi LPASS
14 */
15
16#include <linux/clk.h>
17#include <linux/compiler.h>
18#include <linux/device.h>
19#include <linux/err.h>
20#include <linux/ioport.h>
21#include <linux/kernel.h>
22#include <linux/mod_devicetable.h>
23#include <linux/module.h>
24#include <linux/of.h>
25#include <linux/platform_device.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <linux/regmap.h>
29#include <sound/soc.h>
30#include <sound/soc-dai.h>
31#include "lpass-lpaif-ipq806x.h"
32#include "lpass.h"
33
34static int lpass_cpu_daiops_set_sysclk(struct snd_soc_dai *dai, int clk_id,
35 unsigned int freq, int dir)
36{
37 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
38 int ret;
39
40 ret = clk_set_rate(drvdata->mi2s_osr_clk, freq);
41 if (ret)
42 dev_err(dai->dev, "%s() error setting mi2s osrclk to %u: %d\n",
43 __func__, freq, ret);
44
45 return ret;
46}
47
48static int lpass_cpu_daiops_startup(struct snd_pcm_substream *substream,
49 struct snd_soc_dai *dai)
50{
51 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
52 int ret;
53
54 ret = clk_prepare_enable(drvdata->mi2s_osr_clk);
55 if (ret) {
56 dev_err(dai->dev, "%s() error in enabling mi2s osr clk: %d\n",
57 __func__, ret);
58 return ret;
59 }
60
61 ret = clk_prepare_enable(drvdata->mi2s_bit_clk);
62 if (ret) {
63 dev_err(dai->dev, "%s() error in enabling mi2s bit clk: %d\n",
64 __func__, ret);
65 clk_disable_unprepare(drvdata->mi2s_osr_clk);
66 return ret;
67 }
68
69 return 0;
70}
71
72static void lpass_cpu_daiops_shutdown(struct snd_pcm_substream *substream,
73 struct snd_soc_dai *dai)
74{
75 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
76
77 clk_disable_unprepare(drvdata->mi2s_bit_clk);
78 clk_disable_unprepare(drvdata->mi2s_osr_clk);
79}
80
81static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
82 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
83{
84 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
85 snd_pcm_format_t format = params_format(params);
86 unsigned int channels = params_channels(params);
87 unsigned int rate = params_rate(params);
88 unsigned int regval;
89 int bitwidth, ret;
90
91 bitwidth = snd_pcm_format_width(format);
92 if (bitwidth < 0) {
93 dev_err(dai->dev, "%s() invalid bit width given: %d\n",
94 __func__, bitwidth);
95 return bitwidth;
96 }
97
98 regval = LPAIF_I2SCTL_LOOPBACK_DISABLE |
99 LPAIF_I2SCTL_WSSRC_INTERNAL;
100
101 switch (bitwidth) {
102 case 16:
103 regval |= LPAIF_I2SCTL_BITWIDTH_16;
104 break;
105 case 24:
106 regval |= LPAIF_I2SCTL_BITWIDTH_24;
107 break;
108 case 32:
109 regval |= LPAIF_I2SCTL_BITWIDTH_32;
110 break;
111 default:
112 dev_err(dai->dev, "%s() invalid bitwidth given: %d\n",
113 __func__, bitwidth);
114 return -EINVAL;
115 }
116
117 switch (channels) {
118 case 1:
119 regval |= LPAIF_I2SCTL_SPKMODE_SD0;
120 regval |= LPAIF_I2SCTL_SPKMONO_MONO;
121 break;
122 case 2:
123 regval |= LPAIF_I2SCTL_SPKMODE_SD0;
124 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
125 break;
126 case 4:
127 regval |= LPAIF_I2SCTL_SPKMODE_QUAD01;
128 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
129 break;
130 case 6:
131 regval |= LPAIF_I2SCTL_SPKMODE_6CH;
132 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
133 break;
134 case 8:
135 regval |= LPAIF_I2SCTL_SPKMODE_8CH;
136 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
137 break;
138 default:
139 dev_err(dai->dev, "%s() invalid channels given: %u\n",
140 __func__, channels);
141 return -EINVAL;
142 }
143
144 ret = regmap_write(drvdata->lpaif_map,
145 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S), regval);
146 if (ret) {
147 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
148 __func__, ret);
149 return ret;
150 }
151
152 ret = clk_set_rate(drvdata->mi2s_bit_clk, rate * bitwidth * 2);
153 if (ret) {
154 dev_err(dai->dev, "%s() error setting mi2s bitclk to %u: %d\n",
155 __func__, rate * bitwidth * 2, ret);
156 return ret;
157 }
158
159 return 0;
160}
161
162static int lpass_cpu_daiops_hw_free(struct snd_pcm_substream *substream,
163 struct snd_soc_dai *dai)
164{
165 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
166 int ret;
167
168 ret = regmap_write(drvdata->lpaif_map,
169 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S), 0);
170 if (ret)
171 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
172 __func__, ret);
173
174 return ret;
175}
176
177static int lpass_cpu_daiops_prepare(struct snd_pcm_substream *substream,
178 struct snd_soc_dai *dai)
179{
180 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
181 int ret;
182
183 ret = regmap_update_bits(drvdata->lpaif_map,
184 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S),
185 LPAIF_I2SCTL_SPKEN_MASK, LPAIF_I2SCTL_SPKEN_ENABLE);
186 if (ret)
187 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
188 __func__, ret);
189
190 return ret;
191}
192
193static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
194 int cmd, struct snd_soc_dai *dai)
195{
196 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
197 int ret;
198
199 switch (cmd) {
200 case SNDRV_PCM_TRIGGER_START:
201 case SNDRV_PCM_TRIGGER_RESUME:
202 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
203 ret = regmap_update_bits(drvdata->lpaif_map,
204 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S),
205 LPAIF_I2SCTL_SPKEN_MASK,
206 LPAIF_I2SCTL_SPKEN_ENABLE);
207 if (ret)
208 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
209 __func__, ret);
210 break;
211 case SNDRV_PCM_TRIGGER_STOP:
212 case SNDRV_PCM_TRIGGER_SUSPEND:
213 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
214 ret = regmap_update_bits(drvdata->lpaif_map,
215 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S),
216 LPAIF_I2SCTL_SPKEN_MASK,
217 LPAIF_I2SCTL_SPKEN_DISABLE);
218 if (ret)
219 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
220 __func__, ret);
221 break;
222 }
223
224 return ret;
225}
226
227static struct snd_soc_dai_ops lpass_cpu_dai_ops = {
228 .set_sysclk = lpass_cpu_daiops_set_sysclk,
229 .startup = lpass_cpu_daiops_startup,
230 .shutdown = lpass_cpu_daiops_shutdown,
231 .hw_params = lpass_cpu_daiops_hw_params,
232 .hw_free = lpass_cpu_daiops_hw_free,
233 .prepare = lpass_cpu_daiops_prepare,
234 .trigger = lpass_cpu_daiops_trigger,
235};
236
237static int lpass_cpu_dai_probe(struct snd_soc_dai *dai)
238{
239 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
240 int ret;
241
242 /* ensure audio hardware is disabled */
243 ret = regmap_write(drvdata->lpaif_map,
244 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S), 0);
245 if (ret)
246 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
247 __func__, ret);
248
249 return ret;
250}
251
252static struct snd_soc_dai_driver lpass_cpu_dai_driver = {
253 .playback = {
254 .stream_name = "lpass-cpu-playback",
255 .formats = SNDRV_PCM_FMTBIT_S16 |
256 SNDRV_PCM_FMTBIT_S24 |
257 SNDRV_PCM_FMTBIT_S32,
258 .rates = SNDRV_PCM_RATE_8000 |
259 SNDRV_PCM_RATE_16000 |
260 SNDRV_PCM_RATE_32000 |
261 SNDRV_PCM_RATE_48000 |
262 SNDRV_PCM_RATE_96000,
263 .rate_min = 8000,
264 .rate_max = 96000,
265 .channels_min = 1,
266 .channels_max = 8,
267 },
268 .probe = &lpass_cpu_dai_probe,
269 .ops = &lpass_cpu_dai_ops,
270};
271
272static const struct snd_soc_component_driver lpass_cpu_comp_driver = {
273 .name = "lpass-cpu",
274};
275
276static bool lpass_cpu_regmap_writeable(struct device *dev, unsigned int reg)
277{
278 int i;
279
280 for (i = 0; i < LPAIF_I2S_PORT_NUM; ++i)
281 if (reg == LPAIF_I2SCTL_REG(i))
282 return true;
283
284 for (i = 0; i < LPAIF_IRQ_PORT_NUM; ++i) {
285 if (reg == LPAIF_IRQEN_REG(i))
286 return true;
287 if (reg == LPAIF_IRQCLEAR_REG(i))
288 return true;
289 }
290
291 for (i = 0; i < LPAIF_RDMA_CHAN_NUM; ++i) {
292 if (reg == LPAIF_RDMACTL_REG(i))
293 return true;
294 if (reg == LPAIF_RDMABASE_REG(i))
295 return true;
296 if (reg == LPAIF_RDMABUFF_REG(i))
297 return true;
298 if (reg == LPAIF_RDMAPER_REG(i))
299 return true;
300 }
301
302 return false;
303}
304
305static bool lpass_cpu_regmap_readable(struct device *dev, unsigned int reg)
306{
307 int i;
308
309 for (i = 0; i < LPAIF_I2S_PORT_NUM; ++i)
310 if (reg == LPAIF_I2SCTL_REG(i))
311 return true;
312
313 for (i = 0; i < LPAIF_IRQ_PORT_NUM; ++i) {
314 if (reg == LPAIF_IRQEN_REG(i))
315 return true;
316 if (reg == LPAIF_IRQSTAT_REG(i))
317 return true;
318 }
319
320 for (i = 0; i < LPAIF_RDMA_CHAN_NUM; ++i) {
321 if (reg == LPAIF_RDMACTL_REG(i))
322 return true;
323 if (reg == LPAIF_RDMABASE_REG(i))
324 return true;
325 if (reg == LPAIF_RDMABUFF_REG(i))
326 return true;
327 if (reg == LPAIF_RDMACURR_REG(i))
328 return true;
329 if (reg == LPAIF_RDMAPER_REG(i))
330 return true;
331 }
332
333 return false;
334}
335
336static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg)
337{
338 int i;
339
340 for (i = 0; i < LPAIF_IRQ_PORT_NUM; ++i)
341 if (reg == LPAIF_IRQSTAT_REG(i))
342 return true;
343
344 for (i = 0; i < LPAIF_RDMA_CHAN_NUM; ++i)
345 if (reg == LPAIF_RDMACURR_REG(i))
346 return true;
347
348 return false;
349}
350
351static const struct regmap_config lpass_cpu_regmap_config = {
352 .reg_bits = 32,
353 .reg_stride = 4,
354 .val_bits = 32,
355 .max_register = LPAIF_RDMAPER_REG(LPAIF_RDMA_CHAN_MAX),
356 .writeable_reg = lpass_cpu_regmap_writeable,
357 .readable_reg = lpass_cpu_regmap_readable,
358 .volatile_reg = lpass_cpu_regmap_volatile,
359 .cache_type = REGCACHE_FLAT,
360};
361
362static int lpass_cpu_platform_probe(struct platform_device *pdev)
363{
364 struct lpass_data *drvdata;
365 struct device_node *dsp_of_node;
366 struct resource *res;
367 int ret;
368
369 dsp_of_node = of_parse_phandle(pdev->dev.of_node, "qcom,adsp", 0);
370 if (dsp_of_node) {
371 dev_err(&pdev->dev, "%s() DSP exists and holds audio resources\n",
372 __func__);
373 return -EBUSY;
374 }
375
376 drvdata = devm_kzalloc(&pdev->dev, sizeof(struct lpass_data),
377 GFP_KERNEL);
378 if (!drvdata)
379 return -ENOMEM;
380 platform_set_drvdata(pdev, drvdata);
381
382 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-lpaif");
383 if (!res) {
384 dev_err(&pdev->dev, "%s() error getting resource\n", __func__);
385 return -ENODEV;
386 }
387
388 drvdata->lpaif = devm_ioremap_resource(&pdev->dev, res);
389 if (IS_ERR((void const __force *)drvdata->lpaif)) {
390 dev_err(&pdev->dev, "%s() error mapping reg resource: %ld\n",
391 __func__,
392 PTR_ERR((void const __force *)drvdata->lpaif));
393 return PTR_ERR((void const __force *)drvdata->lpaif);
394 }
395
396 drvdata->lpaif_map = devm_regmap_init_mmio(&pdev->dev, drvdata->lpaif,
397 &lpass_cpu_regmap_config);
398 if (IS_ERR(drvdata->lpaif_map)) {
399 dev_err(&pdev->dev, "%s() error initializing regmap: %ld\n",
400 __func__, PTR_ERR(drvdata->lpaif_map));
401 return PTR_ERR(drvdata->lpaif_map);
402 }
403
404 drvdata->mi2s_osr_clk = devm_clk_get(&pdev->dev, "mi2s-osr-clk");
405 if (IS_ERR(drvdata->mi2s_osr_clk)) {
406 dev_err(&pdev->dev, "%s() error getting mi2s-osr-clk: %ld\n",
407 __func__, PTR_ERR(drvdata->mi2s_osr_clk));
408 return PTR_ERR(drvdata->mi2s_osr_clk);
409 }
410
411 drvdata->mi2s_bit_clk = devm_clk_get(&pdev->dev, "mi2s-bit-clk");
412 if (IS_ERR(drvdata->mi2s_bit_clk)) {
413 dev_err(&pdev->dev, "%s() error getting mi2s-bit-clk: %ld\n",
414 __func__, PTR_ERR(drvdata->mi2s_bit_clk));
415 return PTR_ERR(drvdata->mi2s_bit_clk);
416 }
417
418 drvdata->ahbix_clk = devm_clk_get(&pdev->dev, "ahbix-clk");
419 if (IS_ERR(drvdata->ahbix_clk)) {
420 dev_err(&pdev->dev, "%s() error getting ahbix-clk: %ld\n",
421 __func__, PTR_ERR(drvdata->ahbix_clk));
422 return PTR_ERR(drvdata->ahbix_clk);
423 }
424
425 ret = clk_set_rate(drvdata->ahbix_clk, LPASS_AHBIX_CLOCK_FREQUENCY);
426 if (ret) {
427 dev_err(&pdev->dev, "%s() error setting rate on ahbix_clk: %d\n",
428 __func__, ret);
429 return ret;
430 }
431 dev_dbg(&pdev->dev, "%s() set ahbix_clk rate to %lu\n", __func__,
432 clk_get_rate(drvdata->ahbix_clk));
433
434 ret = clk_prepare_enable(drvdata->ahbix_clk);
435 if (ret) {
436 dev_err(&pdev->dev, "%s() error enabling ahbix_clk: %d\n",
437 __func__, ret);
438 return ret;
439 }
440
441 ret = devm_snd_soc_register_component(&pdev->dev,
442 &lpass_cpu_comp_driver, &lpass_cpu_dai_driver, 1);
443 if (ret) {
444 dev_err(&pdev->dev, "%s() error registering cpu driver: %d\n",
445 __func__, ret);
446 goto err_clk;
447 }
448
449 ret = asoc_qcom_lpass_platform_register(pdev);
450 if (ret) {
451 dev_err(&pdev->dev, "%s() error registering platform driver: %d\n",
452 __func__, ret);
453 goto err_clk;
454 }
455
456 return 0;
457
458err_clk:
459 clk_disable_unprepare(drvdata->ahbix_clk);
460 return ret;
461}
462
463static int lpass_cpu_platform_remove(struct platform_device *pdev)
464{
465 struct lpass_data *drvdata = platform_get_drvdata(pdev);
466
467 clk_disable_unprepare(drvdata->ahbix_clk);
468
469 return 0;
470}
471
472#ifdef CONFIG_OF
473static const struct of_device_id lpass_cpu_device_id[] = {
474 { .compatible = "qcom,lpass-cpu" },
475 {}
476};
477MODULE_DEVICE_TABLE(of, lpass_cpu_device_id);
478#endif
479
480static struct platform_driver lpass_cpu_platform_driver = {
481 .driver = {
482 .name = "lpass-cpu",
483 .of_match_table = of_match_ptr(lpass_cpu_device_id),
484 },
485 .probe = lpass_cpu_platform_probe,
486 .remove = lpass_cpu_platform_remove,
487};
488module_platform_driver(lpass_cpu_platform_driver);
489
490MODULE_DESCRIPTION("QTi LPASS CPU Driver");
491MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/lpass-lpaif-ipq806x.h b/sound/soc/qcom/lpass-lpaif-ipq806x.h
new file mode 100644
index 000000000000..dc423b888842
--- /dev/null
+++ b/sound/soc/qcom/lpass-lpaif-ipq806x.h
@@ -0,0 +1,172 @@
1/*
2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * lpass-lpaif-ipq806x.h -- Definitions for the QTi LPAIF in the ipq806x LPASS
14 */
15
16#ifndef __LPASS_LPAIF_H__
17#define __LPASS_LPAIF_H__
18
19#define LPAIF_BANK_OFFSET 0x1000
20
21/* LPAIF I2S */
22
23#define LPAIF_I2SCTL_REG_BASE 0x0010
24#define LPAIF_I2SCTL_REG_STRIDE 0x4
25#define LPAIF_I2SCTL_REG_ADDR(addr, port) \
26 (LPAIF_I2SCTL_REG_BASE + (addr) + (LPAIF_I2SCTL_REG_STRIDE * (port)))
27
28enum lpaif_i2s_ports {
29 LPAIF_I2S_PORT_MIN = 0,
30
31 LPAIF_I2S_PORT_CODEC_SPK = 0,
32 LPAIF_I2S_PORT_CODEC_MIC = 1,
33 LPAIF_I2S_PORT_SEC_SPK = 2,
34 LPAIF_I2S_PORT_SEC_MIC = 3,
35 LPAIF_I2S_PORT_MI2S = 4,
36
37 LPAIF_I2S_PORT_MAX = 4,
38 LPAIF_I2S_PORT_NUM = 5,
39};
40
41#define LPAIF_I2SCTL_REG(port) LPAIF_I2SCTL_REG_ADDR(0x0, (port))
42
43#define LPAIF_I2SCTL_LOOPBACK_MASK 0x8000
44#define LPAIF_I2SCTL_LOOPBACK_SHIFT 15
45#define LPAIF_I2SCTL_LOOPBACK_DISABLE (0 << LPAIF_I2SCTL_LOOPBACK_SHIFT)
46#define LPAIF_I2SCTL_LOOPBACK_ENABLE (1 << LPAIF_I2SCTL_LOOPBACK_SHIFT)
47
48#define LPAIF_I2SCTL_SPKEN_MASK 0x4000
49#define LPAIF_I2SCTL_SPKEN_SHIFT 14
50#define LPAIF_I2SCTL_SPKEN_DISABLE (0 << LPAIF_I2SCTL_SPKEN_SHIFT)
51#define LPAIF_I2SCTL_SPKEN_ENABLE (1 << LPAIF_I2SCTL_SPKEN_SHIFT)
52
53#define LPAIF_I2SCTL_SPKMODE_MASK 0x3C00
54#define LPAIF_I2SCTL_SPKMODE_SHIFT 10
55#define LPAIF_I2SCTL_SPKMODE_NONE (0 << LPAIF_I2SCTL_SPKMODE_SHIFT)
56#define LPAIF_I2SCTL_SPKMODE_SD0 (1 << LPAIF_I2SCTL_SPKMODE_SHIFT)
57#define LPAIF_I2SCTL_SPKMODE_SD1 (2 << LPAIF_I2SCTL_SPKMODE_SHIFT)
58#define LPAIF_I2SCTL_SPKMODE_SD2 (3 << LPAIF_I2SCTL_SPKMODE_SHIFT)
59#define LPAIF_I2SCTL_SPKMODE_SD3 (4 << LPAIF_I2SCTL_SPKMODE_SHIFT)
60#define LPAIF_I2SCTL_SPKMODE_QUAD01 (5 << LPAIF_I2SCTL_SPKMODE_SHIFT)
61#define LPAIF_I2SCTL_SPKMODE_QUAD23 (6 << LPAIF_I2SCTL_SPKMODE_SHIFT)
62#define LPAIF_I2SCTL_SPKMODE_6CH (7 << LPAIF_I2SCTL_SPKMODE_SHIFT)
63#define LPAIF_I2SCTL_SPKMODE_8CH (8 << LPAIF_I2SCTL_SPKMODE_SHIFT)
64
65#define LPAIF_I2SCTL_SPKMONO_MASK 0x0200
66#define LPAIF_I2SCTL_SPKMONO_SHIFT 9
67#define LPAIF_I2SCTL_SPKMONO_STEREO (0 << LPAIF_I2SCTL_SPKMONO_SHIFT)
68#define LPAIF_I2SCTL_SPKMONO_MONO (1 << LPAIF_I2SCTL_SPKMONO_SHIFT)
69
70#define LPAIF_I2SCTL_WSSRC_MASK 0x0004
71#define LPAIF_I2SCTL_WSSRC_SHIFT 2
72#define LPAIF_I2SCTL_WSSRC_INTERNAL (0 << LPAIF_I2SCTL_WSSRC_SHIFT)
73#define LPAIF_I2SCTL_WSSRC_EXTERNAL (1 << LPAIF_I2SCTL_WSSRC_SHIFT)
74
75#define LPAIF_I2SCTL_BITWIDTH_MASK 0x0003
76#define LPAIF_I2SCTL_BITWIDTH_SHIFT 0
77#define LPAIF_I2SCTL_BITWIDTH_16 (0 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
78#define LPAIF_I2SCTL_BITWIDTH_24 (1 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
79#define LPAIF_I2SCTL_BITWIDTH_32 (2 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
80
81/* LPAIF IRQ */
82
83#define LPAIF_IRQ_REG_BASE 0x3000
84#define LPAIF_IRQ_REG_STRIDE 0x1000
85#define LPAIF_IRQ_REG_ADDR(addr, port) \
86 (LPAIF_IRQ_REG_BASE + (addr) + (LPAIF_IRQ_REG_STRIDE * (port)))
87
88enum lpaif_irq_ports {
89 LPAIF_IRQ_PORT_MIN = 0,
90
91 LPAIF_IRQ_PORT_HOST = 0,
92 LPAIF_IRQ_PORT_ADSP = 1,
93
94 LPAIF_IRQ_PORT_MAX = 2,
95 LPAIF_IRQ_PORT_NUM = 3,
96};
97
98#define LPAIF_IRQEN_REG(port) LPAIF_IRQ_REG_ADDR(0x0, (port))
99#define LPAIF_IRQSTAT_REG(port) LPAIF_IRQ_REG_ADDR(0x4, (port))
100#define LPAIF_IRQCLEAR_REG(port) LPAIF_IRQ_REG_ADDR(0xC, (port))
101
102#define LPAIF_IRQ_BITSTRIDE 3
103#define LPAIF_IRQ_PER(chan) (1 << (LPAIF_IRQ_BITSTRIDE * (chan)))
104#define LPAIF_IRQ_XRUN(chan) (2 << (LPAIF_IRQ_BITSTRIDE * (chan)))
105#define LPAIF_IRQ_ERR(chan) (4 << (LPAIF_IRQ_BITSTRIDE * (chan)))
106#define LPAIF_IRQ_ALL(chan) (7 << (LPAIF_IRQ_BITSTRIDE * (chan)))
107
108/* LPAIF DMA */
109
110#define LPAIF_RDMA_REG_BASE 0x6000
111#define LPAIF_RDMA_REG_STRIDE 0x1000
112#define LPAIF_RDMA_REG_ADDR(addr, chan) \
113 (LPAIF_RDMA_REG_BASE + (addr) + (LPAIF_RDMA_REG_STRIDE * (chan)))
114
115enum lpaif_dma_channels {
116 LPAIF_RDMA_CHAN_MIN = 0,
117
118 LPAIF_RDMA_CHAN_MI2S = 0,
119 LPAIF_RDMA_CHAN_PCM0 = 1,
120 LPAIF_RDMA_CHAN_PCM1 = 2,
121
122 LPAIF_RDMA_CHAN_MAX = 4,
123 LPAIF_RDMA_CHAN_NUM = 5,
124};
125
126#define LPAIF_RDMACTL_REG(chan) LPAIF_RDMA_REG_ADDR(0x00, (chan))
127#define LPAIF_RDMABASE_REG(chan) LPAIF_RDMA_REG_ADDR(0x04, (chan))
128#define LPAIF_RDMABUFF_REG(chan) LPAIF_RDMA_REG_ADDR(0x08, (chan))
129#define LPAIF_RDMACURR_REG(chan) LPAIF_RDMA_REG_ADDR(0x0C, (chan))
130#define LPAIF_RDMAPER_REG(chan) LPAIF_RDMA_REG_ADDR(0x10, (chan))
131
132#define LPAIF_RDMACTL_BURSTEN_MASK 0x800
133#define LPAIF_RDMACTL_BURSTEN_SHIFT 11
134#define LPAIF_RDMACTL_BURSTEN_SINGLE (0 << LPAIF_RDMACTL_BURSTEN_SHIFT)
135#define LPAIF_RDMACTL_BURSTEN_INCR4 (1 << LPAIF_RDMACTL_BURSTEN_SHIFT)
136
137#define LPAIF_RDMACTL_WPSCNT_MASK 0x700
138#define LPAIF_RDMACTL_WPSCNT_SHIFT 8
139#define LPAIF_RDMACTL_WPSCNT_ONE (0 << LPAIF_RDMACTL_WPSCNT_SHIFT)
140#define LPAIF_RDMACTL_WPSCNT_TWO (1 << LPAIF_RDMACTL_WPSCNT_SHIFT)
141#define LPAIF_RDMACTL_WPSCNT_THREE (2 << LPAIF_RDMACTL_WPSCNT_SHIFT)
142#define LPAIF_RDMACTL_WPSCNT_FOUR (3 << LPAIF_RDMACTL_WPSCNT_SHIFT)
143#define LPAIF_RDMACTL_WPSCNT_SIX (5 << LPAIF_RDMACTL_WPSCNT_SHIFT)
144#define LPAIF_RDMACTL_WPSCNT_EIGHT (7 << LPAIF_RDMACTL_WPSCNT_SHIFT)
145
146#define LPAIF_RDMACTL_AUDINTF_MASK 0x0F0
147#define LPAIF_RDMACTL_AUDINTF_SHIFT 4
148#define LPAIF_RDMACTL_AUDINTF_NONE (0 << LPAIF_RDMACTL_AUDINTF_SHIFT)
149#define LPAIF_RDMACTL_AUDINTF_CODEC (1 << LPAIF_RDMACTL_AUDINTF_SHIFT)
150#define LPAIF_RDMACTL_AUDINTF_PCM (2 << LPAIF_RDMACTL_AUDINTF_SHIFT)
151#define LPAIF_RDMACTL_AUDINTF_SEC_I2S (3 << LPAIF_RDMACTL_AUDINTF_SHIFT)
152#define LPAIF_RDMACTL_AUDINTF_MI2S (4 << LPAIF_RDMACTL_AUDINTF_SHIFT)
153#define LPAIF_RDMACTL_AUDINTF_HDMI (5 << LPAIF_RDMACTL_AUDINTF_SHIFT)
154#define LPAIF_RDMACTL_AUDINTF_SEC_PCM (7 << LPAIF_RDMACTL_AUDINTF_SHIFT)
155
156#define LPAIF_RDMACTL_FIFOWM_MASK 0x00E
157#define LPAIF_RDMACTL_FIFOWM_SHIFT 1
158#define LPAIF_RDMACTL_FIFOWM_1 (0 << LPAIF_RDMACTL_FIFOWM_SHIFT)
159#define LPAIF_RDMACTL_FIFOWM_2 (1 << LPAIF_RDMACTL_FIFOWM_SHIFT)
160#define LPAIF_RDMACTL_FIFOWM_3 (2 << LPAIF_RDMACTL_FIFOWM_SHIFT)
161#define LPAIF_RDMACTL_FIFOWM_4 (3 << LPAIF_RDMACTL_FIFOWM_SHIFT)
162#define LPAIF_RDMACTL_FIFOWM_5 (4 << LPAIF_RDMACTL_FIFOWM_SHIFT)
163#define LPAIF_RDMACTL_FIFOWM_6 (5 << LPAIF_RDMACTL_FIFOWM_SHIFT)
164#define LPAIF_RDMACTL_FIFOWM_7 (6 << LPAIF_RDMACTL_FIFOWM_SHIFT)
165#define LPAIF_RDMACTL_FIFOWM_8 (7 << LPAIF_RDMACTL_FIFOWM_SHIFT)
166
167#define LPAIF_RDMACTL_ENABLE_MASK 0x1
168#define LPAIF_RDMACTL_ENABLE_SHIFT 0
169#define LPAIF_RDMACTL_ENABLE_OFF (0 << LPAIF_RDMACTL_ENABLE_SHIFT)
170#define LPAIF_RDMACTL_ENABLE_ON (1 << LPAIF_RDMACTL_ENABLE_SHIFT)
171
172#endif /* __LPASS_LPAIF_H__ */
diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c
new file mode 100644
index 000000000000..2fa6280dfb23
--- /dev/null
+++ b/sound/soc/qcom/lpass-platform.c
@@ -0,0 +1,526 @@
1/*
2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * lpass-platform.c -- ALSA SoC platform driver for QTi LPASS
14 */
15
16#include <linux/compiler.h>
17#include <linux/device.h>
18#include <linux/dma-mapping.h>
19#include <linux/err.h>
20#include <linux/export.h>
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/io.h>
24#include <linux/platform_device.h>
25#include <sound/memalloc.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <linux/regmap.h>
29#include <sound/soc.h>
30#include "lpass-lpaif-ipq806x.h"
31#include "lpass.h"
32
33#define LPASS_PLATFORM_BUFFER_SIZE (16 * 1024)
34#define LPASS_PLATFORM_PERIODS 2
35
36static struct snd_pcm_hardware lpass_platform_pcm_hardware = {
37 .info = SNDRV_PCM_INFO_MMAP |
38 SNDRV_PCM_INFO_MMAP_VALID |
39 SNDRV_PCM_INFO_INTERLEAVED |
40 SNDRV_PCM_INFO_PAUSE |
41 SNDRV_PCM_INFO_RESUME,
42 .formats = SNDRV_PCM_FMTBIT_S16 |
43 SNDRV_PCM_FMTBIT_S24 |
44 SNDRV_PCM_FMTBIT_S32,
45 .rates = SNDRV_PCM_RATE_8000_192000,
46 .rate_min = 8000,
47 .rate_max = 192000,
48 .channels_min = 1,
49 .channels_max = 8,
50 .buffer_bytes_max = LPASS_PLATFORM_BUFFER_SIZE,
51 .period_bytes_max = LPASS_PLATFORM_BUFFER_SIZE /
52 LPASS_PLATFORM_PERIODS,
53 .period_bytes_min = LPASS_PLATFORM_BUFFER_SIZE /
54 LPASS_PLATFORM_PERIODS,
55 .periods_min = LPASS_PLATFORM_PERIODS,
56 .periods_max = LPASS_PLATFORM_PERIODS,
57 .fifo_size = 0,
58};
59
60static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream)
61{
62 struct snd_pcm_runtime *runtime = substream->runtime;
63 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
64 int ret;
65
66 snd_soc_set_runtime_hwparams(substream, &lpass_platform_pcm_hardware);
67
68 runtime->dma_bytes = lpass_platform_pcm_hardware.buffer_bytes_max;
69
70 ret = snd_pcm_hw_constraint_integer(runtime,
71 SNDRV_PCM_HW_PARAM_PERIODS);
72 if (ret < 0) {
73 dev_err(soc_runtime->dev, "%s() setting constraints failed: %d\n",
74 __func__, ret);
75 return -EINVAL;
76 }
77
78 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
79
80 return 0;
81}
82
83static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream,
84 struct snd_pcm_hw_params *params)
85{
86 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
87 struct lpass_data *drvdata =
88 snd_soc_platform_get_drvdata(soc_runtime->platform);
89 snd_pcm_format_t format = params_format(params);
90 unsigned int channels = params_channels(params);
91 unsigned int regval;
92 int bitwidth;
93 int ret;
94
95 bitwidth = snd_pcm_format_width(format);
96 if (bitwidth < 0) {
97 dev_err(soc_runtime->dev, "%s() invalid bit width given: %d\n",
98 __func__, bitwidth);
99 return bitwidth;
100 }
101
102 regval = LPAIF_RDMACTL_BURSTEN_INCR4 |
103 LPAIF_RDMACTL_AUDINTF_MI2S |
104 LPAIF_RDMACTL_FIFOWM_8;
105
106 switch (bitwidth) {
107 case 16:
108 switch (channels) {
109 case 1:
110 case 2:
111 regval |= LPAIF_RDMACTL_WPSCNT_ONE;
112 break;
113 case 4:
114 regval |= LPAIF_RDMACTL_WPSCNT_TWO;
115 break;
116 case 6:
117 regval |= LPAIF_RDMACTL_WPSCNT_THREE;
118 break;
119 case 8:
120 regval |= LPAIF_RDMACTL_WPSCNT_FOUR;
121 break;
122 default:
123 dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n",
124 __func__, bitwidth, channels);
125 return -EINVAL;
126 }
127 break;
128 case 24:
129 case 32:
130 switch (channels) {
131 case 1:
132 regval |= LPAIF_RDMACTL_WPSCNT_ONE;
133 break;
134 case 2:
135 regval |= LPAIF_RDMACTL_WPSCNT_TWO;
136 break;
137 case 4:
138 regval |= LPAIF_RDMACTL_WPSCNT_FOUR;
139 break;
140 case 6:
141 regval |= LPAIF_RDMACTL_WPSCNT_SIX;
142 break;
143 case 8:
144 regval |= LPAIF_RDMACTL_WPSCNT_EIGHT;
145 break;
146 default:
147 dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n",
148 __func__, bitwidth, channels);
149 return -EINVAL;
150 }
151 break;
152 default:
153 dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n",
154 __func__, bitwidth, channels);
155 return -EINVAL;
156 }
157
158 ret = regmap_write(drvdata->lpaif_map,
159 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), regval);
160 if (ret) {
161 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
162 __func__, ret);
163 return ret;
164 }
165
166 return 0;
167}
168
169static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream)
170{
171 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
172 struct lpass_data *drvdata =
173 snd_soc_platform_get_drvdata(soc_runtime->platform);
174 int ret;
175
176 ret = regmap_write(drvdata->lpaif_map,
177 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), 0);
178 if (ret)
179 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
180 __func__, ret);
181
182 return ret;
183}
184
185static int lpass_platform_pcmops_prepare(struct snd_pcm_substream *substream)
186{
187 struct snd_pcm_runtime *runtime = substream->runtime;
188 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
189 struct lpass_data *drvdata =
190 snd_soc_platform_get_drvdata(soc_runtime->platform);
191 int ret;
192
193 ret = regmap_write(drvdata->lpaif_map,
194 LPAIF_RDMABASE_REG(LPAIF_RDMA_CHAN_MI2S),
195 runtime->dma_addr);
196 if (ret) {
197 dev_err(soc_runtime->dev, "%s() error writing to rdmabase reg: %d\n",
198 __func__, ret);
199 return ret;
200 }
201
202 ret = regmap_write(drvdata->lpaif_map,
203 LPAIF_RDMABUFF_REG(LPAIF_RDMA_CHAN_MI2S),
204 (snd_pcm_lib_buffer_bytes(substream) >> 2) - 1);
205 if (ret) {
206 dev_err(soc_runtime->dev, "%s() error writing to rdmabuff reg: %d\n",
207 __func__, ret);
208 return ret;
209 }
210
211 ret = regmap_write(drvdata->lpaif_map,
212 LPAIF_RDMAPER_REG(LPAIF_RDMA_CHAN_MI2S),
213 (snd_pcm_lib_period_bytes(substream) >> 2) - 1);
214 if (ret) {
215 dev_err(soc_runtime->dev, "%s() error writing to rdmaper reg: %d\n",
216 __func__, ret);
217 return ret;
218 }
219
220 ret = regmap_update_bits(drvdata->lpaif_map,
221 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S),
222 LPAIF_RDMACTL_ENABLE_MASK, LPAIF_RDMACTL_ENABLE_ON);
223 if (ret) {
224 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
225 __func__, ret);
226 return ret;
227 }
228
229 return 0;
230}
231
232static int lpass_platform_pcmops_trigger(struct snd_pcm_substream *substream,
233 int cmd)
234{
235 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
236 struct lpass_data *drvdata =
237 snd_soc_platform_get_drvdata(soc_runtime->platform);
238 int ret;
239
240 switch (cmd) {
241 case SNDRV_PCM_TRIGGER_START:
242 case SNDRV_PCM_TRIGGER_RESUME:
243 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
244 /* clear status before enabling interrupts */
245 ret = regmap_write(drvdata->lpaif_map,
246 LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST),
247 LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S));
248 if (ret) {
249 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
250 __func__, ret);
251 return ret;
252 }
253
254 ret = regmap_update_bits(drvdata->lpaif_map,
255 LPAIF_IRQEN_REG(LPAIF_IRQ_PORT_HOST),
256 LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S),
257 LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S));
258 if (ret) {
259 dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n",
260 __func__, ret);
261 return ret;
262 }
263
264 ret = regmap_update_bits(drvdata->lpaif_map,
265 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S),
266 LPAIF_RDMACTL_ENABLE_MASK,
267 LPAIF_RDMACTL_ENABLE_ON);
268 if (ret) {
269 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
270 __func__, ret);
271 return ret;
272 }
273 break;
274 case SNDRV_PCM_TRIGGER_STOP:
275 case SNDRV_PCM_TRIGGER_SUSPEND:
276 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
277 ret = regmap_update_bits(drvdata->lpaif_map,
278 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S),
279 LPAIF_RDMACTL_ENABLE_MASK,
280 LPAIF_RDMACTL_ENABLE_OFF);
281 if (ret) {
282 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
283 __func__, ret);
284 return ret;
285 }
286
287 ret = regmap_update_bits(drvdata->lpaif_map,
288 LPAIF_IRQEN_REG(LPAIF_IRQ_PORT_HOST),
289 LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S), 0);
290 if (ret) {
291 dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n",
292 __func__, ret);
293 return ret;
294 }
295 break;
296 }
297
298 return 0;
299}
300
301static snd_pcm_uframes_t lpass_platform_pcmops_pointer(
302 struct snd_pcm_substream *substream)
303{
304 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
305 struct lpass_data *drvdata =
306 snd_soc_platform_get_drvdata(soc_runtime->platform);
307 unsigned int base_addr, curr_addr;
308 int ret;
309
310 ret = regmap_read(drvdata->lpaif_map,
311 LPAIF_RDMABASE_REG(LPAIF_RDMA_CHAN_MI2S), &base_addr);
312 if (ret) {
313 dev_err(soc_runtime->dev, "%s() error reading from rdmabase reg: %d\n",
314 __func__, ret);
315 return ret;
316 }
317
318 ret = regmap_read(drvdata->lpaif_map,
319 LPAIF_RDMACURR_REG(LPAIF_RDMA_CHAN_MI2S), &curr_addr);
320 if (ret) {
321 dev_err(soc_runtime->dev, "%s() error reading from rdmacurr reg: %d\n",
322 __func__, ret);
323 return ret;
324 }
325
326 return bytes_to_frames(substream->runtime, curr_addr - base_addr);
327}
328
329static int lpass_platform_pcmops_mmap(struct snd_pcm_substream *substream,
330 struct vm_area_struct *vma)
331{
332 struct snd_pcm_runtime *runtime = substream->runtime;
333
334 return dma_mmap_coherent(substream->pcm->card->dev, vma,
335 runtime->dma_area, runtime->dma_addr,
336 runtime->dma_bytes);
337}
338
339static struct snd_pcm_ops lpass_platform_pcm_ops = {
340 .open = lpass_platform_pcmops_open,
341 .ioctl = snd_pcm_lib_ioctl,
342 .hw_params = lpass_platform_pcmops_hw_params,
343 .hw_free = lpass_platform_pcmops_hw_free,
344 .prepare = lpass_platform_pcmops_prepare,
345 .trigger = lpass_platform_pcmops_trigger,
346 .pointer = lpass_platform_pcmops_pointer,
347 .mmap = lpass_platform_pcmops_mmap,
348};
349
350static irqreturn_t lpass_platform_lpaif_irq(int irq, void *data)
351{
352 struct snd_pcm_substream *substream = data;
353 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
354 struct lpass_data *drvdata =
355 snd_soc_platform_get_drvdata(soc_runtime->platform);
356 unsigned int interrupts;
357 irqreturn_t ret = IRQ_NONE;
358 int rv;
359
360 rv = regmap_read(drvdata->lpaif_map,
361 LPAIF_IRQSTAT_REG(LPAIF_IRQ_PORT_HOST), &interrupts);
362 if (rv) {
363 dev_err(soc_runtime->dev, "%s() error reading from irqstat reg: %d\n",
364 __func__, rv);
365 return IRQ_NONE;
366 }
367 interrupts &= LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S);
368
369 if (interrupts & LPAIF_IRQ_PER(LPAIF_RDMA_CHAN_MI2S)) {
370 rv = regmap_write(drvdata->lpaif_map,
371 LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST),
372 LPAIF_IRQ_PER(LPAIF_RDMA_CHAN_MI2S));
373 if (rv) {
374 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
375 __func__, rv);
376 return IRQ_NONE;
377 }
378 snd_pcm_period_elapsed(substream);
379 ret = IRQ_HANDLED;
380 }
381
382 if (interrupts & LPAIF_IRQ_XRUN(LPAIF_RDMA_CHAN_MI2S)) {
383 rv = regmap_write(drvdata->lpaif_map,
384 LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST),
385 LPAIF_IRQ_XRUN(LPAIF_RDMA_CHAN_MI2S));
386 if (rv) {
387 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
388 __func__, rv);
389 return IRQ_NONE;
390 }
391 dev_warn(soc_runtime->dev, "%s() xrun warning\n", __func__);
392 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
393 ret = IRQ_HANDLED;
394 }
395
396 if (interrupts & LPAIF_IRQ_ERR(LPAIF_RDMA_CHAN_MI2S)) {
397 rv = regmap_write(drvdata->lpaif_map,
398 LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST),
399 LPAIF_IRQ_ERR(LPAIF_RDMA_CHAN_MI2S));
400 if (rv) {
401 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
402 __func__, rv);
403 return IRQ_NONE;
404 }
405 dev_err(soc_runtime->dev, "%s() bus access error\n", __func__);
406 snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
407 ret = IRQ_HANDLED;
408 }
409
410 return ret;
411}
412
413static int lpass_platform_alloc_buffer(struct snd_pcm_substream *substream,
414 struct snd_soc_pcm_runtime *soc_runtime)
415{
416 struct snd_dma_buffer *buf = &substream->dma_buffer;
417 size_t size = lpass_platform_pcm_hardware.buffer_bytes_max;
418
419 buf->dev.type = SNDRV_DMA_TYPE_DEV;
420 buf->dev.dev = soc_runtime->dev;
421 buf->private_data = NULL;
422 buf->area = dma_alloc_coherent(soc_runtime->dev, size, &buf->addr,
423 GFP_KERNEL);
424 if (!buf->area) {
425 dev_err(soc_runtime->dev, "%s: Could not allocate DMA buffer\n",
426 __func__);
427 return -ENOMEM;
428 }
429 buf->bytes = size;
430
431 return 0;
432}
433
434static void lpass_platform_free_buffer(struct snd_pcm_substream *substream,
435 struct snd_soc_pcm_runtime *soc_runtime)
436{
437 struct snd_dma_buffer *buf = &substream->dma_buffer;
438
439 if (buf->area) {
440 dma_free_coherent(soc_runtime->dev, buf->bytes, buf->area,
441 buf->addr);
442 }
443 buf->area = NULL;
444}
445
446static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
447{
448 struct snd_pcm *pcm = soc_runtime->pcm;
449 struct snd_pcm_substream *substream =
450 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
451 struct lpass_data *drvdata =
452 snd_soc_platform_get_drvdata(soc_runtime->platform);
453 int ret;
454
455 soc_runtime->dev->coherent_dma_mask = DMA_BIT_MASK(32);
456 soc_runtime->dev->dma_mask = &soc_runtime->dev->coherent_dma_mask;
457
458 ret = lpass_platform_alloc_buffer(substream, soc_runtime);
459 if (ret)
460 return ret;
461
462 ret = devm_request_irq(soc_runtime->dev, drvdata->lpaif_irq,
463 lpass_platform_lpaif_irq, IRQF_TRIGGER_RISING,
464 "lpass-irq-lpaif", substream);
465 if (ret) {
466 dev_err(soc_runtime->dev, "%s() irq request failed: %d\n",
467 __func__, ret);
468 goto err_buf;
469 }
470
471 /* ensure audio hardware is disabled */
472 ret = regmap_write(drvdata->lpaif_map,
473 LPAIF_IRQEN_REG(LPAIF_IRQ_PORT_HOST), 0);
474 if (ret) {
475 dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n",
476 __func__, ret);
477 return ret;
478 }
479 ret = regmap_write(drvdata->lpaif_map,
480 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), 0);
481 if (ret) {
482 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
483 __func__, ret);
484 return ret;
485 }
486
487 return 0;
488
489err_buf:
490 lpass_platform_free_buffer(substream, soc_runtime);
491 return ret;
492}
493
494static void lpass_platform_pcm_free(struct snd_pcm *pcm)
495{
496 struct snd_pcm_substream *substream =
497 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
498 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
499
500 lpass_platform_free_buffer(substream, soc_runtime);
501}
502
503static struct snd_soc_platform_driver lpass_platform_driver = {
504 .pcm_new = lpass_platform_pcm_new,
505 .pcm_free = lpass_platform_pcm_free,
506 .ops = &lpass_platform_pcm_ops,
507};
508
509int asoc_qcom_lpass_platform_register(struct platform_device *pdev)
510{
511 struct lpass_data *drvdata = platform_get_drvdata(pdev);
512
513 drvdata->lpaif_irq = platform_get_irq_byname(pdev, "lpass-irq-lpaif");
514 if (drvdata->lpaif_irq < 0) {
515 dev_err(&pdev->dev, "%s() error getting irq handle: %d\n",
516 __func__, drvdata->lpaif_irq);
517 return -ENODEV;
518 }
519
520 return devm_snd_soc_register_platform(&pdev->dev,
521 &lpass_platform_driver);
522}
523EXPORT_SYMBOL_GPL(asoc_qcom_lpass_platform_register);
524
525MODULE_DESCRIPTION("QTi LPASS Platform Driver");
526MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
new file mode 100644
index 000000000000..5c99b3dace86
--- /dev/null
+++ b/sound/soc/qcom/lpass.h
@@ -0,0 +1,51 @@
1/*
2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * lpass.h - Definitions for the QTi LPASS
14 */
15
16#ifndef __LPASS_H__
17#define __LPASS_H__
18
19#include <linux/clk.h>
20#include <linux/compiler.h>
21#include <linux/platform_device.h>
22#include <linux/regmap.h>
23
24#define LPASS_AHBIX_CLOCK_FREQUENCY 131072000
25
26/* Both the CPU DAI and platform drivers will access this data */
27struct lpass_data {
28
29 /* AHB-I/X bus clocks inside the low-power audio subsystem (LPASS) */
30 struct clk *ahbix_clk;
31
32 /* MI2S system clock */
33 struct clk *mi2s_osr_clk;
34
35 /* MI2S bit clock (derived from system clock by a divider */
36 struct clk *mi2s_bit_clk;
37
38 /* low-power audio interface (LPAIF) registers */
39 void __iomem *lpaif;
40
41 /* regmap backed by the low-power audio interface (LPAIF) registers */
42 struct regmap *lpaif_map;
43
44 /* interrupts from the low-power audio interface (LPAIF) */
45 int lpaif_irq;
46};
47
48/* register the platform driver from the CPU DAI driver */
49int asoc_qcom_lpass_platform_register(struct platform_device *);
50
51#endif /* __LPASS_H__ */
diff --git a/sound/soc/qcom/storm.c b/sound/soc/qcom/storm.c
new file mode 100644
index 000000000000..b8bd296190ad
--- /dev/null
+++ b/sound/soc/qcom/storm.c
@@ -0,0 +1,162 @@
1/*
2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * storm.c -- ALSA SoC machine driver for QTi ipq806x-based Storm board
14 */
15
16#include <linux/device.h>
17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/mod_devicetable.h>
20#include <linux/platform_device.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24
25#define STORM_SYSCLK_MULT 4
26
27static int storm_ops_hw_params(struct snd_pcm_substream *substream,
28 struct snd_pcm_hw_params *params)
29{
30 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
31 struct snd_soc_card *card = soc_runtime->card;
32 snd_pcm_format_t format = params_format(params);
33 unsigned int rate = params_rate(params);
34 unsigned int sysclk_freq;
35 int bitwidth, ret;
36
37 bitwidth = snd_pcm_format_width(format);
38 if (bitwidth < 0) {
39 dev_err(card->dev, "%s() invalid bit width given: %d\n",
40 __func__, bitwidth);
41 return bitwidth;
42 }
43
44 /*
45 * as the CPU DAI is the I2S bus master and no system clock is needed by
46 * the MAX98357a DAC, simply set the system clock to be a constant
47 * multiple of the bit clock for the clock divider
48 */
49 sysclk_freq = rate * bitwidth * 2 * STORM_SYSCLK_MULT;
50
51 ret = snd_soc_dai_set_sysclk(soc_runtime->cpu_dai, 0, sysclk_freq, 0);
52 if (ret) {
53 dev_err(card->dev, "%s() error setting sysclk to %u: %d\n",
54 __func__, sysclk_freq, ret);
55 return ret;
56 }
57
58 return 0;
59}
60
61static struct snd_soc_ops storm_soc_ops = {
62 .hw_params = storm_ops_hw_params,
63};
64
65static struct snd_soc_dai_link storm_dai_link = {
66 .name = "Primary",
67 .stream_name = "Primary",
68 .codec_dai_name = "HiFi",
69 .ops = &storm_soc_ops,
70};
71
72static struct snd_soc_card storm_soc_card = {
73 .name = "ipq806x-storm",
74 .dev = NULL,
75};
76
77static int storm_parse_of(struct snd_soc_card *card)
78{
79 struct snd_soc_dai_link *dai_link = card->dai_link;
80 struct device_node *np = card->dev->of_node;
81
82 dai_link->cpu_of_node = of_parse_phandle(np, "cpu", 0);
83 if (!dai_link->cpu_of_node) {
84 dev_err(card->dev, "%s() error getting cpu phandle\n",
85 __func__);
86 return -EINVAL;
87 }
88 dai_link->platform_of_node = dai_link->cpu_of_node;
89
90 dai_link->codec_of_node = of_parse_phandle(np, "codec", 0);
91 if (!dai_link->codec_of_node) {
92 dev_err(card->dev, "%s() error getting codec phandle\n",
93 __func__);
94 return -EINVAL;
95 }
96
97 return 0;
98}
99
100static int storm_platform_probe(struct platform_device *pdev)
101{
102 struct snd_soc_card *card = &storm_soc_card;
103 int ret;
104
105 if (card->dev) {
106 dev_err(&pdev->dev, "%s() error, existing soundcard\n",
107 __func__);
108 return -ENODEV;
109 }
110 card->dev = &pdev->dev;
111 platform_set_drvdata(pdev, card);
112
113 ret = snd_soc_of_parse_card_name(card, "qcom,model");
114 if (ret) {
115 dev_err(&pdev->dev, "%s() error parsing card name: %d\n",
116 __func__, ret);
117 return ret;
118 }
119
120 card->dai_link = &storm_dai_link;
121 card->num_links = 1;
122
123 ret = storm_parse_of(card);
124 if (ret) {
125 dev_err(&pdev->dev, "%s() error resolving dai links: %d\n",
126 __func__, ret);
127 return ret;
128 }
129
130 ret = devm_snd_soc_register_card(&pdev->dev, card);
131 if (ret == -EPROBE_DEFER) {
132 card->dev = NULL;
133 return ret;
134 } else if (ret) {
135 dev_err(&pdev->dev, "%s() error registering soundcard: %d\n",
136 __func__, ret);
137 return ret;
138 }
139
140 return 0;
141}
142
143#ifdef CONFIG_OF
144static const struct of_device_id storm_device_id[] = {
145 { .compatible = "google,storm-audio" },
146 {},
147};
148MODULE_DEVICE_TABLE(of, storm_device_id);
149#endif
150
151static struct platform_driver storm_platform_driver = {
152 .driver = {
153 .name = "storm-audio",
154 .of_match_table =
155 of_match_ptr(storm_device_id),
156 },
157 .probe = storm_platform_probe,
158};
159module_platform_driver(storm_platform_driver);
160
161MODULE_DESCRIPTION("QTi IPQ806x-based Storm Machine Driver");
162MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 80245b6eebd6..07114b0b0dc1 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -36,11 +36,17 @@ config SND_SOC_SH4_SIU
36 36
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 select SND_SIMPLE_CARD 40 select SND_SIMPLE_CARD
40 select REGMAP_MMIO 41 select REGMAP_MMIO
41 help 42 help
42 This option enables R-Car SUR/SCU/SSIU/SSI sound support 43 This option enables R-Car SUR/SCU/SSIU/SSI sound support
43 44
45config SND_SOC_RSRC_CARD
46 tristate "Renesas Sampling Rate Convert Sound Card"
47 help
48 This option enables simple sound if you need sampling rate convert
49
44## 50##
45## Boards 51## Boards
46## 52##
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index b87b22e88e43..0c2af21b0b82 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -1876,7 +1876,40 @@ static void fsi_handler_init(struct fsi_priv *fsi,
1876 } 1876 }
1877} 1877}
1878 1878
1879static struct of_device_id fsi_of_match[]; 1879static const struct fsi_core fsi1_core = {
1880 .ver = 1,
1881
1882 /* Interrupt */
1883 .int_st = INT_ST,
1884 .iemsk = IEMSK,
1885 .imsk = IMSK,
1886};
1887
1888static const struct fsi_core fsi2_core = {
1889 .ver = 2,
1890
1891 /* Interrupt */
1892 .int_st = CPU_INT_ST,
1893 .iemsk = CPU_IEMSK,
1894 .imsk = CPU_IMSK,
1895 .a_mclk = A_MST_CTLR,
1896 .b_mclk = B_MST_CTLR,
1897};
1898
1899static const struct of_device_id fsi_of_match[] = {
1900 { .compatible = "renesas,sh_fsi", .data = &fsi1_core},
1901 { .compatible = "renesas,sh_fsi2", .data = &fsi2_core},
1902 {},
1903};
1904MODULE_DEVICE_TABLE(of, fsi_of_match);
1905
1906static const struct platform_device_id fsi_id_table[] = {
1907 { "sh_fsi", (kernel_ulong_t)&fsi1_core },
1908 { "sh_fsi2", (kernel_ulong_t)&fsi2_core },
1909 {},
1910};
1911MODULE_DEVICE_TABLE(platform, fsi_id_table);
1912
1880static int fsi_probe(struct platform_device *pdev) 1913static int fsi_probe(struct platform_device *pdev)
1881{ 1914{
1882 struct fsi_master *master; 1915 struct fsi_master *master;
@@ -2072,40 +2105,6 @@ static struct dev_pm_ops fsi_pm_ops = {
2072 .resume = fsi_resume, 2105 .resume = fsi_resume,
2073}; 2106};
2074 2107
2075static struct fsi_core fsi1_core = {
2076 .ver = 1,
2077
2078 /* Interrupt */
2079 .int_st = INT_ST,
2080 .iemsk = IEMSK,
2081 .imsk = IMSK,
2082};
2083
2084static struct fsi_core fsi2_core = {
2085 .ver = 2,
2086
2087 /* Interrupt */
2088 .int_st = CPU_INT_ST,
2089 .iemsk = CPU_IEMSK,
2090 .imsk = CPU_IMSK,
2091 .a_mclk = A_MST_CTLR,
2092 .b_mclk = B_MST_CTLR,
2093};
2094
2095static struct of_device_id fsi_of_match[] = {
2096 { .compatible = "renesas,sh_fsi", .data = &fsi1_core},
2097 { .compatible = "renesas,sh_fsi2", .data = &fsi2_core},
2098 {},
2099};
2100MODULE_DEVICE_TABLE(of, fsi_of_match);
2101
2102static struct platform_device_id fsi_id_table[] = {
2103 { "sh_fsi", (kernel_ulong_t)&fsi1_core },
2104 { "sh_fsi2", (kernel_ulong_t)&fsi2_core },
2105 {},
2106};
2107MODULE_DEVICE_TABLE(platform, fsi_id_table);
2108
2109static struct platform_driver fsi_driver = { 2108static struct platform_driver fsi_driver = {
2110 .driver = { 2109 .driver = {
2111 .name = "fsi-pcm-audio", 2110 .name = "fsi-pcm-audio",
@@ -2119,7 +2118,7 @@ static struct platform_driver fsi_driver = {
2119 2118
2120module_platform_driver(fsi_driver); 2119module_platform_driver(fsi_driver);
2121 2120
2122MODULE_LICENSE("GPL"); 2121MODULE_LICENSE("GPL v2");
2123MODULE_DESCRIPTION("SuperH onchip FSI audio driver"); 2122MODULE_DESCRIPTION("SuperH onchip FSI audio driver");
2124MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>"); 2123MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
2125MODULE_ALIAS("platform:fsi-pcm-audio"); 2124MODULE_ALIAS("platform:fsi-pcm-audio");
diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile
index 9ac536429800..f1b445173fba 100644
--- a/sound/soc/sh/rcar/Makefile
+++ b/sound/soc/sh/rcar/Makefile
@@ -1,2 +1,5 @@
1snd-soc-rcar-objs := core.o gen.o src.o adg.o ssi.o dvc.o 1snd-soc-rcar-objs := core.o gen.o dma.o src.o adg.o ssi.o dvc.o
2obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o \ No newline at end of file 2obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o
3
4snd-soc-rsrc-card-objs := rsrc-card.o
5obj-$(CONFIG_SND_SOC_RSRC_CARD) += snd-soc-rsrc-card.o
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 7ac35c9d1cb8..fefc881dbac2 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -183,6 +183,8 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
183 183
184 rsnd_mod_bset(mod, DIV_EN, en, en); 184 rsnd_mod_bset(mod, DIV_EN, en, en);
185 185
186 dev_dbg(dev, "convert rate %d <-> %d\n", src_rate, dst_rate);
187
186 return 0; 188 return 0;
187} 189}
188 190
@@ -432,7 +434,5 @@ int rsnd_adg_probe(struct platform_device *pdev,
432 434
433 priv->adg = adg; 435 priv->adg = adg;
434 436
435 dev_dbg(dev, "adg probed\n");
436
437 return 0; 437 return 0;
438} 438}
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 110577c52317..9f48d75fa992 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -94,21 +94,20 @@
94 * 94 *
95 */ 95 */
96#include <linux/pm_runtime.h> 96#include <linux/pm_runtime.h>
97#include <linux/shdma-base.h>
98#include "rsnd.h" 97#include "rsnd.h"
99 98
100#define RSND_RATES SNDRV_PCM_RATE_8000_96000 99#define RSND_RATES SNDRV_PCM_RATE_8000_96000
101#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 100#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
102 101
103static struct rsnd_of_data rsnd_of_data_gen1 = { 102static const struct rsnd_of_data rsnd_of_data_gen1 = {
104 .flags = RSND_GEN1, 103 .flags = RSND_GEN1,
105}; 104};
106 105
107static struct rsnd_of_data rsnd_of_data_gen2 = { 106static const struct rsnd_of_data rsnd_of_data_gen2 = {
108 .flags = RSND_GEN2, 107 .flags = RSND_GEN2,
109}; 108};
110 109
111static struct of_device_id rsnd_of_match[] = { 110static const struct of_device_id rsnd_of_match[] = {
112 { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 }, 111 { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 },
113 { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 }, 112 { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 },
114 {}, 113 {},
@@ -138,249 +137,37 @@ char *rsnd_mod_name(struct rsnd_mod *mod)
138 return mod->ops->name; 137 return mod->ops->name;
139} 138}
140 139
141char *rsnd_mod_dma_name(struct rsnd_mod *mod) 140struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod)
142{ 141{
143 if (!mod || !mod->ops) 142 if (!mod || !mod->ops || !mod->ops->dma_req)
144 return "unknown"; 143 return NULL;
145
146 if (!mod->ops->dma_name)
147 return mod->ops->name;
148 144
149 return mod->ops->dma_name(mod); 145 return mod->ops->dma_req(mod);
150} 146}
151 147
152void rsnd_mod_init(struct rsnd_mod *mod, 148int rsnd_mod_init(struct rsnd_mod *mod,
153 struct rsnd_mod_ops *ops, 149 struct rsnd_mod_ops *ops,
154 struct clk *clk, 150 struct clk *clk,
155 enum rsnd_mod_type type, 151 enum rsnd_mod_type type,
156 int id) 152 int id)
157{ 153{
154 int ret = clk_prepare(clk);
155
156 if (ret)
157 return ret;
158
158 mod->id = id; 159 mod->id = id;
159 mod->ops = ops; 160 mod->ops = ops;
160 mod->type = type; 161 mod->type = type;
161 mod->clk = clk; 162 mod->clk = clk;
162}
163
164/*
165 * rsnd_dma functions
166 */
167void rsnd_dma_stop(struct rsnd_dma *dma)
168{
169 dmaengine_terminate_all(dma->chan);
170}
171
172static void rsnd_dma_complete(void *data)
173{
174 struct rsnd_dma *dma = (struct rsnd_dma *)data;
175 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
176 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
177
178 /*
179 * Renesas sound Gen1 needs 1 DMAC,
180 * Gen2 needs 2 DMAC.
181 * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri.
182 * But, Audio-DMAC-peri-peri doesn't have interrupt,
183 * and this driver is assuming that here.
184 *
185 * If Audio-DMAC-peri-peri has interrpt,
186 * rsnd_dai_pointer_update() will be called twice,
187 * ant it will breaks io->byte_pos
188 */
189
190 rsnd_dai_pointer_update(io, io->byte_per_period);
191}
192
193void rsnd_dma_start(struct rsnd_dma *dma)
194{
195 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
196 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
197 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
198 struct snd_pcm_substream *substream = io->substream;
199 struct device *dev = rsnd_priv_to_dev(priv);
200 struct dma_async_tx_descriptor *desc;
201
202 desc = dmaengine_prep_dma_cyclic(dma->chan,
203 (dma->addr) ? dma->addr :
204 substream->runtime->dma_addr,
205 snd_pcm_lib_buffer_bytes(substream),
206 snd_pcm_lib_period_bytes(substream),
207 dma->dir,
208 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
209
210 if (!desc) {
211 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
212 return;
213 }
214
215 desc->callback = rsnd_dma_complete;
216 desc->callback_param = dma;
217
218 if (dmaengine_submit(desc) < 0) {
219 dev_err(dev, "dmaengine_submit() fail\n");
220 return;
221 }
222
223 dma_async_issue_pending(dma->chan);
224}
225
226int rsnd_dma_available(struct rsnd_dma *dma)
227{
228 return !!dma->chan;
229}
230
231#define DMA_NAME_SIZE 16
232#define MOD_MAX 4 /* MEM/SSI/SRC/DVC */
233static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod)
234{
235 if (mod)
236 return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d",
237 rsnd_mod_dma_name(mod), rsnd_mod_id(mod));
238 else
239 return snprintf(dma_name, DMA_NAME_SIZE / 2, "mem");
240
241}
242
243static void rsnd_dma_of_name(struct rsnd_mod *mod_from,
244 struct rsnd_mod *mod_to,
245 char *dma_name)
246{
247 int index = 0;
248
249 index = _rsnd_dma_of_name(dma_name + index, mod_from);
250 *(dma_name + index++) = '_';
251 index = _rsnd_dma_of_name(dma_name + index, mod_to);
252}
253
254static void rsnd_dma_of_path(struct rsnd_dma *dma,
255 int is_play,
256 struct rsnd_mod **mod_from,
257 struct rsnd_mod **mod_to)
258{
259 struct rsnd_mod *this = rsnd_dma_to_mod(dma);
260 struct rsnd_dai_stream *io = rsnd_mod_to_io(this);
261 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
262 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
263 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
264 struct rsnd_mod *mod[MOD_MAX];
265 int i, index;
266 163
267 164 return ret;
268 for (i = 0; i < MOD_MAX; i++)
269 mod[i] = NULL;
270
271 /*
272 * in play case...
273 *
274 * src -> dst
275 *
276 * mem -> SSI
277 * mem -> SRC -> SSI
278 * mem -> SRC -> DVC -> SSI
279 */
280 mod[0] = NULL; /* for "mem" */
281 index = 1;
282 for (i = 1; i < MOD_MAX; i++) {
283 if (!src) {
284 mod[i] = ssi;
285 } else if (!dvc) {
286 mod[i] = src;
287 src = NULL;
288 } else {
289 if ((!is_play) && (this == src))
290 this = dvc;
291
292 mod[i] = (is_play) ? src : dvc;
293 i++;
294 mod[i] = (is_play) ? dvc : src;
295 src = NULL;
296 dvc = NULL;
297 }
298
299 if (mod[i] == this)
300 index = i;
301
302 if (mod[i] == ssi)
303 break;
304 }
305
306 if (is_play) {
307 *mod_from = mod[index - 1];
308 *mod_to = mod[index];
309 } else {
310 *mod_from = mod[index];
311 *mod_to = mod[index - 1];
312 }
313}
314
315int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
316 int is_play, int id)
317{
318 struct device *dev = rsnd_priv_to_dev(priv);
319 struct dma_slave_config cfg;
320 struct rsnd_mod *mod_from;
321 struct rsnd_mod *mod_to;
322 char dma_name[DMA_NAME_SIZE];
323 dma_cap_mask_t mask;
324 int ret;
325
326 if (dma->chan) {
327 dev_err(dev, "it already has dma channel\n");
328 return -EIO;
329 }
330
331 dma_cap_zero(mask);
332 dma_cap_set(DMA_SLAVE, mask);
333
334 rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to);
335 rsnd_dma_of_name(mod_from, mod_to, dma_name);
336
337 cfg.slave_id = id;
338 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
339 cfg.src_addr = rsnd_gen_dma_addr(priv, mod_from, is_play, 1);
340 cfg.dst_addr = rsnd_gen_dma_addr(priv, mod_to, is_play, 0);
341 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
342 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
343
344 dev_dbg(dev, "dma : %s %pad -> %pad\n",
345 dma_name, &cfg.src_addr, &cfg.dst_addr);
346
347 dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter,
348 (void *)id, dev,
349 dma_name);
350 if (!dma->chan) {
351 dev_err(dev, "can't get dma channel\n");
352 goto rsnd_dma_channel_err;
353 }
354
355 ret = dmaengine_slave_config(dma->chan, &cfg);
356 if (ret < 0)
357 goto rsnd_dma_init_err;
358
359 dma->addr = is_play ? cfg.src_addr : cfg.dst_addr;
360 dma->dir = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
361
362 return 0;
363
364rsnd_dma_init_err:
365 rsnd_dma_quit(priv, dma);
366rsnd_dma_channel_err:
367
368 /*
369 * DMA failed. try to PIO mode
370 * see
371 * rsnd_ssi_fallback()
372 * rsnd_rdai_continuance_probe()
373 */
374 return -EAGAIN;
375} 165}
376 166
377void rsnd_dma_quit(struct rsnd_priv *priv, 167void rsnd_mod_quit(struct rsnd_mod *mod)
378 struct rsnd_dma *dma)
379{ 168{
380 if (dma->chan) 169 if (mod->clk)
381 dma_release_channel(dma->chan); 170 clk_unprepare(mod->clk);
382
383 dma->chan = NULL;
384} 171}
385 172
386/* 173/*
@@ -416,7 +203,7 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod)
416({ \ 203({ \
417 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ 204 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \
418 struct device *dev = rsnd_priv_to_dev(priv); \ 205 struct device *dev = rsnd_priv_to_dev(priv); \
419 u32 mask = 1 << __rsnd_mod_shift_##func; \ 206 u32 mask = (1 << __rsnd_mod_shift_##func) & ~(1 << 31); \
420 u32 call = __rsnd_mod_call_##func << __rsnd_mod_shift_##func; \ 207 u32 call = __rsnd_mod_call_##func << __rsnd_mod_shift_##func; \
421 int ret = 0; \ 208 int ret = 0; \
422 if ((mod->status & mask) == call) { \ 209 if ((mod->status & mask) == call) { \
@@ -458,7 +245,7 @@ static int rsnd_dai_connect(struct rsnd_mod *mod,
458 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 245 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
459 struct device *dev = rsnd_priv_to_dev(priv); 246 struct device *dev = rsnd_priv_to_dev(priv);
460 247
461 dev_err(dev, "%s%d is not empty\n", 248 dev_err(dev, "%s[%d] is not empty\n",
462 rsnd_mod_name(mod), 249 rsnd_mod_name(mod),
463 rsnd_mod_id(mod)); 250 rsnd_mod_id(mod));
464 return -EIO; 251 return -EIO;
@@ -874,20 +661,28 @@ static int rsnd_dai_probe(struct platform_device *pdev,
874 drv[i].name = rdai[i].name; 661 drv[i].name = rdai[i].name;
875 drv[i].ops = &rsnd_soc_dai_ops; 662 drv[i].ops = &rsnd_soc_dai_ops;
876 if (pmod) { 663 if (pmod) {
664 snprintf(rdai[i].playback.name, RSND_DAI_NAME_SIZE,
665 "DAI%d Playback", i);
666
877 drv[i].playback.rates = RSND_RATES; 667 drv[i].playback.rates = RSND_RATES;
878 drv[i].playback.formats = RSND_FMTS; 668 drv[i].playback.formats = RSND_FMTS;
879 drv[i].playback.channels_min = 2; 669 drv[i].playback.channels_min = 2;
880 drv[i].playback.channels_max = 2; 670 drv[i].playback.channels_max = 2;
671 drv[i].playback.stream_name = rdai[i].playback.name;
881 672
882 rdai[i].playback.info = &info->dai_info[i].playback; 673 rdai[i].playback.info = &info->dai_info[i].playback;
883 rdai[i].playback.rdai = rdai + i; 674 rdai[i].playback.rdai = rdai + i;
884 rsnd_path_init(priv, &rdai[i], &rdai[i].playback); 675 rsnd_path_init(priv, &rdai[i], &rdai[i].playback);
885 } 676 }
886 if (cmod) { 677 if (cmod) {
678 snprintf(rdai[i].capture.name, RSND_DAI_NAME_SIZE,
679 "DAI%d Capture", i);
680
887 drv[i].capture.rates = RSND_RATES; 681 drv[i].capture.rates = RSND_RATES;
888 drv[i].capture.formats = RSND_FMTS; 682 drv[i].capture.formats = RSND_FMTS;
889 drv[i].capture.channels_min = 2; 683 drv[i].capture.channels_min = 2;
890 drv[i].capture.channels_max = 2; 684 drv[i].capture.channels_max = 2;
685 drv[i].capture.stream_name = rdai[i].capture.name;
891 686
892 rdai[i].capture.info = &info->dai_info[i].capture; 687 rdai[i].capture.info = &info->dai_info[i].capture;
893 rdai[i].capture.rdai = rdai + i; 688 rdai[i].capture.rdai = rdai + i;
@@ -933,6 +728,15 @@ static int rsnd_pcm_open(struct snd_pcm_substream *substream)
933static int rsnd_hw_params(struct snd_pcm_substream *substream, 728static int rsnd_hw_params(struct snd_pcm_substream *substream,
934 struct snd_pcm_hw_params *hw_params) 729 struct snd_pcm_hw_params *hw_params)
935{ 730{
731 struct snd_soc_dai *dai = rsnd_substream_to_dai(substream);
732 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
733 struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
734 int ret;
735
736 ret = rsnd_dai_call(hw_params, io, substream, hw_params);
737 if (ret)
738 return ret;
739
936 return snd_pcm_lib_malloc_pages(substream, 740 return snd_pcm_lib_malloc_pages(substream,
937 params_buffer_bytes(hw_params)); 741 params_buffer_bytes(hw_params));
938} 742}
@@ -1197,6 +1001,7 @@ static int rsnd_probe(struct platform_device *pdev)
1197 const struct rsnd_of_data *of_data, 1001 const struct rsnd_of_data *of_data,
1198 struct rsnd_priv *priv) = { 1002 struct rsnd_priv *priv) = {
1199 rsnd_gen_probe, 1003 rsnd_gen_probe,
1004 rsnd_dma_probe,
1200 rsnd_ssi_probe, 1005 rsnd_ssi_probe,
1201 rsnd_src_probe, 1006 rsnd_src_probe,
1202 rsnd_dvc_probe, 1007 rsnd_dvc_probe,
@@ -1290,6 +1095,12 @@ static int rsnd_remove(struct platform_device *pdev)
1290{ 1095{
1291 struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev); 1096 struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev);
1292 struct rsnd_dai *rdai; 1097 struct rsnd_dai *rdai;
1098 void (*remove_func[])(struct platform_device *pdev,
1099 struct rsnd_priv *priv) = {
1100 rsnd_ssi_remove,
1101 rsnd_src_remove,
1102 rsnd_dvc_remove,
1103 };
1293 int ret = 0, i; 1104 int ret = 0, i;
1294 1105
1295 pm_runtime_disable(&pdev->dev); 1106 pm_runtime_disable(&pdev->dev);
@@ -1299,6 +1110,9 @@ static int rsnd_remove(struct platform_device *pdev)
1299 ret |= rsnd_dai_call(remove, &rdai->capture, priv); 1110 ret |= rsnd_dai_call(remove, &rdai->capture, priv);
1300 } 1111 }
1301 1112
1113 for (i = 0; i < ARRAY_SIZE(remove_func); i++)
1114 remove_func[i](pdev, priv);
1115
1302 snd_soc_unregister_component(&pdev->dev); 1116 snd_soc_unregister_component(&pdev->dev);
1303 snd_soc_unregister_platform(&pdev->dev); 1117 snd_soc_unregister_platform(&pdev->dev);
1304 1118
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
new file mode 100644
index 000000000000..ac3756f6af60
--- /dev/null
+++ b/sound/soc/sh/rcar/dma.c
@@ -0,0 +1,616 @@
1/*
2 * Renesas R-Car Audio DMAC support
3 *
4 * Copyright (C) 2015 Renesas Electronics Corp.
5 * Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/delay.h>
12#include <linux/of_dma.h>
13#include "rsnd.h"
14
15/*
16 * Audio DMAC peri peri register
17 */
18#define PDMASAR 0x00
19#define PDMADAR 0x04
20#define PDMACHCR 0x0c
21
22/* PDMACHCR */
23#define PDMACHCR_DE (1 << 0)
24
25struct rsnd_dma_ctrl {
26 void __iomem *base;
27 int dmapp_num;
28};
29
30#define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma)
31
32/*
33 * Audio DMAC
34 */
35static void rsnd_dmaen_complete(void *data)
36{
37 struct rsnd_dma *dma = (struct rsnd_dma *)data;
38 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
39 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
40
41 /*
42 * Renesas sound Gen1 needs 1 DMAC,
43 * Gen2 needs 2 DMAC.
44 * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri.
45 * But, Audio-DMAC-peri-peri doesn't have interrupt,
46 * and this driver is assuming that here.
47 *
48 * If Audio-DMAC-peri-peri has interrpt,
49 * rsnd_dai_pointer_update() will be called twice,
50 * ant it will breaks io->byte_pos
51 */
52
53 rsnd_dai_pointer_update(io, io->byte_per_period);
54}
55
56static void rsnd_dmaen_stop(struct rsnd_dma *dma)
57{
58 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
59
60 dmaengine_terminate_all(dmaen->chan);
61}
62
63static void rsnd_dmaen_start(struct rsnd_dma *dma)
64{
65 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
66 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
67 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
68 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
69 struct snd_pcm_substream *substream = io->substream;
70 struct device *dev = rsnd_priv_to_dev(priv);
71 struct dma_async_tx_descriptor *desc;
72 int is_play = rsnd_io_is_play(io);
73
74 desc = dmaengine_prep_dma_cyclic(dmaen->chan,
75 substream->runtime->dma_addr,
76 snd_pcm_lib_buffer_bytes(substream),
77 snd_pcm_lib_period_bytes(substream),
78 is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
79 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
80
81 if (!desc) {
82 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
83 return;
84 }
85
86 desc->callback = rsnd_dmaen_complete;
87 desc->callback_param = dma;
88
89 if (dmaengine_submit(desc) < 0) {
90 dev_err(dev, "dmaengine_submit() fail\n");
91 return;
92 }
93
94 dma_async_issue_pending(dmaen->chan);
95}
96
97struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
98 struct rsnd_mod *mod, char *name)
99{
100 struct dma_chan *chan;
101 struct device_node *np;
102 int i = 0;
103
104 for_each_child_of_node(of_node, np) {
105 if (i == rsnd_mod_id(mod))
106 break;
107 i++;
108 }
109
110 chan = of_dma_request_slave_channel(np, name);
111
112 of_node_put(np);
113 of_node_put(of_node);
114
115 return chan;
116}
117
118static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_mod *mod_from,
119 struct rsnd_mod *mod_to)
120{
121 if ((!mod_from && !mod_to) ||
122 (mod_from && mod_to))
123 return NULL;
124
125 if (mod_from)
126 return rsnd_mod_dma_req(mod_from);
127 else
128 return rsnd_mod_dma_req(mod_to);
129}
130
131static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
132 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
133{
134 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
135 struct device *dev = rsnd_priv_to_dev(priv);
136 struct dma_slave_config cfg = {};
137 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
138 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
139 int is_play = rsnd_io_is_play(io);
140 int ret;
141
142 if (dmaen->chan) {
143 dev_err(dev, "it already has dma channel\n");
144 return -EIO;
145 }
146
147 if (dev->of_node) {
148 dmaen->chan = rsnd_dmaen_request_channel(mod_from, mod_to);
149 } else {
150 dma_cap_mask_t mask;
151
152 dma_cap_zero(mask);
153 dma_cap_set(DMA_SLAVE, mask);
154
155 dmaen->chan = dma_request_channel(mask, shdma_chan_filter,
156 (void *)id);
157 }
158 if (IS_ERR_OR_NULL(dmaen->chan)) {
159 dev_err(dev, "can't get dma channel\n");
160 goto rsnd_dma_channel_err;
161 }
162
163 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
164 cfg.src_addr = dma->src_addr;
165 cfg.dst_addr = dma->dst_addr;
166 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
167 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
168
169 dev_dbg(dev, "dma : %pad -> %pad\n",
170 &cfg.src_addr, &cfg.dst_addr);
171
172 ret = dmaengine_slave_config(dmaen->chan, &cfg);
173 if (ret < 0)
174 goto rsnd_dma_init_err;
175
176 return 0;
177
178rsnd_dma_init_err:
179 rsnd_dma_quit(dma);
180rsnd_dma_channel_err:
181
182 /*
183 * DMA failed. try to PIO mode
184 * see
185 * rsnd_ssi_fallback()
186 * rsnd_rdai_continuance_probe()
187 */
188 return -EAGAIN;
189}
190
191static void rsnd_dmaen_quit(struct rsnd_dma *dma)
192{
193 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
194
195 if (dmaen->chan)
196 dma_release_channel(dmaen->chan);
197
198 dmaen->chan = NULL;
199}
200
201static struct rsnd_dma_ops rsnd_dmaen_ops = {
202 .start = rsnd_dmaen_start,
203 .stop = rsnd_dmaen_stop,
204 .init = rsnd_dmaen_init,
205 .quit = rsnd_dmaen_quit,
206};
207
208/*
209 * Audio DMAC peri peri
210 */
211static const u8 gen2_id_table_ssiu[] = {
212 0x00, /* SSI00 */
213 0x04, /* SSI10 */
214 0x08, /* SSI20 */
215 0x0c, /* SSI3 */
216 0x0d, /* SSI4 */
217 0x0e, /* SSI5 */
218 0x0f, /* SSI6 */
219 0x10, /* SSI7 */
220 0x11, /* SSI8 */
221 0x12, /* SSI90 */
222};
223static const u8 gen2_id_table_scu[] = {
224 0x2d, /* SCU_SRCI0 */
225 0x2e, /* SCU_SRCI1 */
226 0x2f, /* SCU_SRCI2 */
227 0x30, /* SCU_SRCI3 */
228 0x31, /* SCU_SRCI4 */
229 0x32, /* SCU_SRCI5 */
230 0x33, /* SCU_SRCI6 */
231 0x34, /* SCU_SRCI7 */
232 0x35, /* SCU_SRCI8 */
233 0x36, /* SCU_SRCI9 */
234};
235static const u8 gen2_id_table_cmd[] = {
236 0x37, /* SCU_CMD0 */
237 0x38, /* SCU_CMD1 */
238};
239
240static u32 rsnd_dmapp_get_id(struct rsnd_mod *mod)
241{
242 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
243 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
244 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
245 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
246 const u8 *entry = NULL;
247 int id = rsnd_mod_id(mod);
248 int size = 0;
249
250 if (mod == ssi) {
251 entry = gen2_id_table_ssiu;
252 size = ARRAY_SIZE(gen2_id_table_ssiu);
253 } else if (mod == src) {
254 entry = gen2_id_table_scu;
255 size = ARRAY_SIZE(gen2_id_table_scu);
256 } else if (mod == dvc) {
257 entry = gen2_id_table_cmd;
258 size = ARRAY_SIZE(gen2_id_table_cmd);
259 }
260
261 if (!entry)
262 return 0xFF;
263
264 if (size <= id)
265 return 0xFF;
266
267 return entry[id];
268}
269
270static u32 rsnd_dmapp_get_chcr(struct rsnd_mod *mod_from,
271 struct rsnd_mod *mod_to)
272{
273 return (rsnd_dmapp_get_id(mod_from) << 24) +
274 (rsnd_dmapp_get_id(mod_to) << 16);
275}
276
277#define rsnd_dmapp_addr(dmac, dma, reg) \
278 (dmac->base + 0x20 + reg + \
279 (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id))
280static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg)
281{
282 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
283 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
284 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
285 struct device *dev = rsnd_priv_to_dev(priv);
286
287 dev_dbg(dev, "w %p : %08x\n", rsnd_dmapp_addr(dmac, dma, reg), data);
288
289 iowrite32(data, rsnd_dmapp_addr(dmac, dma, reg));
290}
291
292static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg)
293{
294 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
295 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
296 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
297
298 return ioread32(rsnd_dmapp_addr(dmac, dma, reg));
299}
300
301static void rsnd_dmapp_stop(struct rsnd_dma *dma)
302{
303 int i;
304
305 rsnd_dmapp_write(dma, 0, PDMACHCR);
306
307 for (i = 0; i < 1024; i++) {
308 if (0 == rsnd_dmapp_read(dma, PDMACHCR))
309 return;
310 udelay(1);
311 }
312}
313
314static void rsnd_dmapp_start(struct rsnd_dma *dma)
315{
316 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
317
318 rsnd_dmapp_write(dma, dma->src_addr, PDMASAR);
319 rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR);
320 rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR);
321}
322
323static int rsnd_dmapp_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
324 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
325{
326 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
327 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
328 struct device *dev = rsnd_priv_to_dev(priv);
329
330 dmapp->dmapp_id = dmac->dmapp_num;
331 dmapp->chcr = rsnd_dmapp_get_chcr(mod_from, mod_to) | PDMACHCR_DE;
332
333 dmac->dmapp_num++;
334
335 rsnd_dmapp_stop(dma);
336
337 dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n",
338 dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr);
339
340 return 0;
341}
342
343static struct rsnd_dma_ops rsnd_dmapp_ops = {
344 .start = rsnd_dmapp_start,
345 .stop = rsnd_dmapp_stop,
346 .init = rsnd_dmapp_init,
347 .quit = rsnd_dmapp_stop,
348};
349
350/*
351 * Common DMAC Interface
352 */
353
354/*
355 * DMA read/write register offset
356 *
357 * RSND_xxx_I_N for Audio DMAC input
358 * RSND_xxx_O_N for Audio DMAC output
359 * RSND_xxx_I_P for Audio DMAC peri peri input
360 * RSND_xxx_O_P for Audio DMAC peri peri output
361 *
362 * ex) R-Car H2 case
363 * mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out
364 * SSI : 0xec541000 / 0xec241008 / 0xec24100c
365 * SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000
366 * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
367 * CMD : 0xec500000 / / 0xec008000 0xec308000
368 */
369#define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
370#define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
371
372#define RDMA_SSIU_I_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
373#define RDMA_SSIU_O_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
374
375#define RDMA_SSIU_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
376#define RDMA_SSIU_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
377
378#define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i))
379#define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i))
380
381#define RDMA_SRC_I_P(addr, i) (addr ##_reg - 0x00200000 + (0x400 * i))
382#define RDMA_SRC_O_P(addr, i) (addr ##_reg - 0x001fc000 + (0x400 * i))
383
384#define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i))
385#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i))
386
387static dma_addr_t
388rsnd_gen2_dma_addr(struct rsnd_priv *priv,
389 struct rsnd_mod *mod,
390 int is_play, int is_from)
391{
392 struct device *dev = rsnd_priv_to_dev(priv);
393 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
394 phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI);
395 phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU);
396 int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
397 int use_src = !!rsnd_io_to_mod_src(io);
398 int use_dvc = !!rsnd_io_to_mod_dvc(io);
399 int id = rsnd_mod_id(mod);
400 struct dma_addr {
401 dma_addr_t out_addr;
402 dma_addr_t in_addr;
403 } dma_addrs[3][2][3] = {
404 /* SRC */
405 {{{ 0, 0 },
406 /* Capture */
407 { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) },
408 { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } },
409 /* Playback */
410 {{ 0, 0, },
411 { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) },
412 { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) } }
413 },
414 /* SSI */
415 /* Capture */
416 {{{ RDMA_SSI_O_N(ssi, id), 0 },
417 { RDMA_SSIU_O_P(ssi, id), 0 },
418 { RDMA_SSIU_O_P(ssi, id), 0 } },
419 /* Playback */
420 {{ 0, RDMA_SSI_I_N(ssi, id) },
421 { 0, RDMA_SSIU_I_P(ssi, id) },
422 { 0, RDMA_SSIU_I_P(ssi, id) } }
423 },
424 /* SSIU */
425 /* Capture */
426 {{{ RDMA_SSIU_O_N(ssi, id), 0 },
427 { RDMA_SSIU_O_P(ssi, id), 0 },
428 { RDMA_SSIU_O_P(ssi, id), 0 } },
429 /* Playback */
430 {{ 0, RDMA_SSIU_I_N(ssi, id) },
431 { 0, RDMA_SSIU_I_P(ssi, id) },
432 { 0, RDMA_SSIU_I_P(ssi, id) } } },
433 };
434
435 /* it shouldn't happen */
436 if (use_dvc && !use_src)
437 dev_err(dev, "DVC is selected without SRC\n");
438
439 /* use SSIU or SSI ? */
440 if (is_ssi && rsnd_ssi_use_busif(mod))
441 is_ssi++;
442
443 return (is_from) ?
444 dma_addrs[is_ssi][is_play][use_src + use_dvc].out_addr :
445 dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr;
446}
447
448static dma_addr_t rsnd_dma_addr(struct rsnd_priv *priv,
449 struct rsnd_mod *mod,
450 int is_play, int is_from)
451{
452 /*
453 * gen1 uses default DMA addr
454 */
455 if (rsnd_is_gen1(priv))
456 return 0;
457
458 if (!mod)
459 return 0;
460
461 return rsnd_gen2_dma_addr(priv, mod, is_play, is_from);
462}
463
464#define MOD_MAX 4 /* MEM/SSI/SRC/DVC */
465static void rsnd_dma_of_path(struct rsnd_dma *dma,
466 int is_play,
467 struct rsnd_mod **mod_from,
468 struct rsnd_mod **mod_to)
469{
470 struct rsnd_mod *this = rsnd_dma_to_mod(dma);
471 struct rsnd_dai_stream *io = rsnd_mod_to_io(this);
472 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
473 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
474 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
475 struct rsnd_mod *mod[MOD_MAX];
476 int i, index;
477
478
479 for (i = 0; i < MOD_MAX; i++)
480 mod[i] = NULL;
481
482 /*
483 * in play case...
484 *
485 * src -> dst
486 *
487 * mem -> SSI
488 * mem -> SRC -> SSI
489 * mem -> SRC -> DVC -> SSI
490 */
491 mod[0] = NULL; /* for "mem" */
492 index = 1;
493 for (i = 1; i < MOD_MAX; i++) {
494 if (!src) {
495 mod[i] = ssi;
496 } else if (!dvc) {
497 mod[i] = src;
498 src = NULL;
499 } else {
500 if ((!is_play) && (this == src))
501 this = dvc;
502
503 mod[i] = (is_play) ? src : dvc;
504 i++;
505 mod[i] = (is_play) ? dvc : src;
506 src = NULL;
507 dvc = NULL;
508 }
509
510 if (mod[i] == this)
511 index = i;
512
513 if (mod[i] == ssi)
514 break;
515 }
516
517 if (is_play) {
518 *mod_from = mod[index - 1];
519 *mod_to = mod[index];
520 } else {
521 *mod_from = mod[index];
522 *mod_to = mod[index - 1];
523 }
524}
525
526void rsnd_dma_stop(struct rsnd_dma *dma)
527{
528 dma->ops->stop(dma);
529}
530
531void rsnd_dma_start(struct rsnd_dma *dma)
532{
533 dma->ops->start(dma);
534}
535
536void rsnd_dma_quit(struct rsnd_dma *dma)
537{
538 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
539 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
540 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
541
542 if (!dmac)
543 return;
544
545 dma->ops->quit(dma);
546}
547
548int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id)
549{
550 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
551 struct rsnd_mod *mod_from;
552 struct rsnd_mod *mod_to;
553 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
554 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
555 int is_play = rsnd_io_is_play(io);
556
557 /*
558 * DMA failed. try to PIO mode
559 * see
560 * rsnd_ssi_fallback()
561 * rsnd_rdai_continuance_probe()
562 */
563 if (!dmac)
564 return -EAGAIN;
565
566 rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to);
567
568 dma->src_addr = rsnd_dma_addr(priv, mod_from, is_play, 1);
569 dma->dst_addr = rsnd_dma_addr(priv, mod_to, is_play, 0);
570
571 /* for Gen2 */
572 if (mod_from && mod_to)
573 dma->ops = &rsnd_dmapp_ops;
574 else
575 dma->ops = &rsnd_dmaen_ops;
576
577 /* for Gen1, overwrite */
578 if (rsnd_is_gen1(priv))
579 dma->ops = &rsnd_dmaen_ops;
580
581 return dma->ops->init(priv, dma, id, mod_from, mod_to);
582}
583
584int rsnd_dma_probe(struct platform_device *pdev,
585 const struct rsnd_of_data *of_data,
586 struct rsnd_priv *priv)
587{
588 struct device *dev = rsnd_priv_to_dev(priv);
589 struct rsnd_dma_ctrl *dmac;
590 struct resource *res;
591
592 /*
593 * for Gen1
594 */
595 if (rsnd_is_gen1(priv))
596 return 0;
597
598 /*
599 * for Gen2
600 */
601 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audmapp");
602 dmac = devm_kzalloc(dev, sizeof(*dmac), GFP_KERNEL);
603 if (!dmac || !res) {
604 dev_err(dev, "dma allocate failed\n");
605 return 0; /* it will be PIO mode */
606 }
607
608 dmac->dmapp_num = 0;
609 dmac->base = devm_ioremap_resource(dev, res);
610 if (IS_ERR(dmac->base))
611 return PTR_ERR(dmac->base);
612
613 priv->dma = dmac;
614
615 return 0;
616}
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index d7f9ed959c4e..e5fcb062ad77 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -24,6 +24,9 @@ struct rsnd_dvc {
24 struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */ 24 struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */
25}; 25};
26 26
27#define rsnd_dvc_of_node(priv) \
28 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc")
29
27#define rsnd_mod_to_dvc(_mod) \ 30#define rsnd_mod_to_dvc(_mod) \
28 container_of((_mod), struct rsnd_dvc, mod) 31 container_of((_mod), struct rsnd_dvc, mod)
29 32
@@ -33,7 +36,7 @@ struct rsnd_dvc {
33 ((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \ 36 ((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \
34 i++) 37 i++)
35 38
36static const char const *dvc_ramp_rate[] = { 39static const char * const dvc_ramp_rate[] = {
37 "128 dB/1 step", /* 00000 */ 40 "128 dB/1 step", /* 00000 */
38 "64 dB/1 step", /* 00001 */ 41 "64 dB/1 step", /* 00001 */
39 "32 dB/1 step", /* 00010 */ 42 "32 dB/1 step", /* 00010 */
@@ -116,17 +119,6 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
116 rsnd_mod_write(mod, DVC_DVUER, 1); 119 rsnd_mod_write(mod, DVC_DVUER, 1);
117} 120}
118 121
119static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod,
120 struct rsnd_priv *priv)
121{
122 struct device *dev = rsnd_priv_to_dev(priv);
123
124 dev_dbg(dev, "%s[%d] (Gen2) is probed\n",
125 rsnd_mod_name(mod), rsnd_mod_id(mod));
126
127 return 0;
128}
129
130static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, 122static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod,
131 struct rsnd_priv *priv) 123 struct rsnd_priv *priv)
132{ 124{
@@ -269,9 +261,17 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
269 return 0; 261 return 0;
270} 262}
271 263
264static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_mod *mod)
265{
266 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
267
268 return rsnd_dma_request_channel(rsnd_dvc_of_node(priv),
269 mod, "tx");
270}
271
272static struct rsnd_mod_ops rsnd_dvc_ops = { 272static struct rsnd_mod_ops rsnd_dvc_ops = {
273 .name = DVC_NAME, 273 .name = DVC_NAME,
274 .probe = rsnd_dvc_probe_gen2, 274 .dma_req = rsnd_dvc_dma_req,
275 .remove = rsnd_dvc_remove_gen2, 275 .remove = rsnd_dvc_remove_gen2,
276 .init = rsnd_dvc_init, 276 .init = rsnd_dvc_init,
277 .quit = rsnd_dvc_quit, 277 .quit = rsnd_dvc_quit,
@@ -333,7 +333,7 @@ int rsnd_dvc_probe(struct platform_device *pdev,
333 struct rsnd_dvc *dvc; 333 struct rsnd_dvc *dvc;
334 struct clk *clk; 334 struct clk *clk;
335 char name[RSND_DVC_NAME_SIZE]; 335 char name[RSND_DVC_NAME_SIZE];
336 int i, nr; 336 int i, nr, ret;
337 337
338 rsnd_of_parse_dvc(pdev, of_data, priv); 338 rsnd_of_parse_dvc(pdev, of_data, priv);
339 339
@@ -366,11 +366,22 @@ int rsnd_dvc_probe(struct platform_device *pdev,
366 366
367 dvc->info = &info->dvc_info[i]; 367 dvc->info = &info->dvc_info[i];
368 368
369 rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops, 369 ret = rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops,
370 clk, RSND_MOD_DVC, i); 370 clk, RSND_MOD_DVC, i);
371 371 if (ret)
372 dev_dbg(dev, "CMD%d probed\n", i); 372 return ret;
373 } 373 }
374 374
375 return 0; 375 return 0;
376} 376}
377
378void rsnd_dvc_remove(struct platform_device *pdev,
379 struct rsnd_priv *priv)
380{
381 struct rsnd_dvc *dvc;
382 int i;
383
384 for_each_rsnd_dvc(dvc, priv, i) {
385 rsnd_mod_quit(&dvc->mod);
386 }
387}
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index de0685f2abae..8c7dc51b1c4f 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -28,6 +28,7 @@ struct rsnd_gen {
28 28
29 struct regmap *regmap[RSND_BASE_MAX]; 29 struct regmap *regmap[RSND_BASE_MAX];
30 struct regmap_field *regs[RSND_REG_MAX]; 30 struct regmap_field *regs[RSND_REG_MAX];
31 phys_addr_t res[RSND_REG_MAX];
31}; 32};
32 33
33#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) 34#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen)
@@ -118,11 +119,19 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
118 mask, data); 119 mask, data);
119} 120}
120 121
121#define rsnd_gen_regmap_init(priv, id_size, reg_id, conf) \ 122phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id)
122 _rsnd_gen_regmap_init(priv, id_size, reg_id, conf, ARRAY_SIZE(conf)) 123{
124 struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
125
126 return gen->res[reg_id];
127}
128
129#define rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf) \
130 _rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf, ARRAY_SIZE(conf))
123static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, 131static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
124 int id_size, 132 int id_size,
125 int reg_id, 133 int reg_id,
134 const char *name,
126 struct rsnd_regmap_field_conf *conf, 135 struct rsnd_regmap_field_conf *conf,
127 int conf_size) 136 int conf_size)
128{ 137{
@@ -141,8 +150,11 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
141 regc.reg_bits = 32; 150 regc.reg_bits = 32;
142 regc.val_bits = 32; 151 regc.val_bits = 32;
143 regc.reg_stride = 4; 152 regc.reg_stride = 4;
153 regc.name = name;
144 154
145 res = platform_get_resource(pdev, IORESOURCE_MEM, reg_id); 155 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
156 if (!res)
157 res = platform_get_resource(pdev, IORESOURCE_MEM, reg_id);
146 if (!res) 158 if (!res)
147 return -ENODEV; 159 return -ENODEV;
148 160
@@ -156,6 +168,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
156 168
157 gen->base[reg_id] = base; 169 gen->base[reg_id] = base;
158 gen->regmap[reg_id] = regmap; 170 gen->regmap[reg_id] = regmap;
171 gen->res[reg_id] = res->start;
159 172
160 for (i = 0; i < conf_size; i++) { 173 for (i = 0; i < conf_size; i++) {
161 174
@@ -176,125 +189,11 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
176} 189}
177 190
178/* 191/*
179 * DMA read/write register offset
180 *
181 * RSND_xxx_I_N for Audio DMAC input
182 * RSND_xxx_O_N for Audio DMAC output
183 * RSND_xxx_I_P for Audio DMAC peri peri input
184 * RSND_xxx_O_P for Audio DMAC peri peri output
185 *
186 * ex) R-Car H2 case
187 * mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out
188 * SSI : 0xec541000 / 0xec241008 / 0xec24100c
189 * SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000
190 * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
191 * CMD : 0xec500000 / / 0xec008000 0xec308000
192 */
193#define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
194#define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
195
196#define RDMA_SSIU_I_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
197#define RDMA_SSIU_O_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
198
199#define RDMA_SSIU_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
200#define RDMA_SSIU_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
201
202#define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i))
203#define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i))
204
205#define RDMA_SRC_I_P(addr, i) (addr ##_reg - 0x00200000 + (0x400 * i))
206#define RDMA_SRC_O_P(addr, i) (addr ##_reg - 0x001fc000 + (0x400 * i))
207
208#define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i))
209#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i))
210
211static dma_addr_t
212rsnd_gen2_dma_addr(struct rsnd_priv *priv,
213 struct rsnd_mod *mod,
214 int is_play, int is_from)
215{
216 struct platform_device *pdev = rsnd_priv_to_pdev(priv);
217 struct device *dev = rsnd_priv_to_dev(priv);
218 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
219 dma_addr_t ssi_reg = platform_get_resource(pdev,
220 IORESOURCE_MEM, RSND_GEN2_SSI)->start;
221 dma_addr_t src_reg = platform_get_resource(pdev,
222 IORESOURCE_MEM, RSND_GEN2_SCU)->start;
223 int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
224 int use_src = !!rsnd_io_to_mod_src(io);
225 int use_dvc = !!rsnd_io_to_mod_dvc(io);
226 int id = rsnd_mod_id(mod);
227 struct dma_addr {
228 dma_addr_t out_addr;
229 dma_addr_t in_addr;
230 } dma_addrs[3][2][3] = {
231 /* SRC */
232 {{{ 0, 0 },
233 /* Capture */
234 { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) },
235 { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } },
236 /* Playback */
237 {{ 0, 0, },
238 { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) },
239 { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) } }
240 },
241 /* SSI */
242 /* Capture */
243 {{{ RDMA_SSI_O_N(ssi, id), 0 },
244 { RDMA_SSIU_O_P(ssi, id), 0 },
245 { RDMA_SSIU_O_P(ssi, id), 0 } },
246 /* Playback */
247 {{ 0, RDMA_SSI_I_N(ssi, id) },
248 { 0, RDMA_SSIU_I_P(ssi, id) },
249 { 0, RDMA_SSIU_I_P(ssi, id) } }
250 },
251 /* SSIU */
252 /* Capture */
253 {{{ RDMA_SSIU_O_N(ssi, id), 0 },
254 { RDMA_SSIU_O_P(ssi, id), 0 },
255 { RDMA_SSIU_O_P(ssi, id), 0 } },
256 /* Playback */
257 {{ 0, RDMA_SSIU_I_N(ssi, id) },
258 { 0, RDMA_SSIU_I_P(ssi, id) },
259 { 0, RDMA_SSIU_I_P(ssi, id) } } },
260 };
261
262 /* it shouldn't happen */
263 if (use_dvc && !use_src)
264 dev_err(dev, "DVC is selected without SRC\n");
265
266 /* use SSIU or SSI ? */
267 if (is_ssi && (0 == strcmp(rsnd_mod_dma_name(mod), "ssiu")))
268 is_ssi++;
269
270 return (is_from) ?
271 dma_addrs[is_ssi][is_play][use_src + use_dvc].out_addr :
272 dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr;
273}
274
275dma_addr_t rsnd_gen_dma_addr(struct rsnd_priv *priv,
276 struct rsnd_mod *mod,
277 int is_play, int is_from)
278{
279 /*
280 * gen1 uses default DMA addr
281 */
282 if (rsnd_is_gen1(priv))
283 return 0;
284
285 if (!mod)
286 return 0;
287
288 return rsnd_gen2_dma_addr(priv, mod, is_play, is_from);
289}
290
291/*
292 * Gen2 192 * Gen2
293 */ 193 */
294static int rsnd_gen2_probe(struct platform_device *pdev, 194static int rsnd_gen2_probe(struct platform_device *pdev,
295 struct rsnd_priv *priv) 195 struct rsnd_priv *priv)
296{ 196{
297 struct device *dev = rsnd_priv_to_dev(priv);
298 struct rsnd_regmap_field_conf conf_ssiu[] = { 197 struct rsnd_regmap_field_conf conf_ssiu[] = {
299 RSND_GEN_S_REG(SSI_MODE0, 0x800), 198 RSND_GEN_S_REG(SSI_MODE0, 0x800),
300 RSND_GEN_S_REG(SSI_MODE1, 0x804), 199 RSND_GEN_S_REG(SSI_MODE1, 0x804),
@@ -368,18 +267,16 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
368 int ret_adg; 267 int ret_adg;
369 int ret_ssi; 268 int ret_ssi;
370 269
371 ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSIU, conf_ssiu); 270 ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSIU, "ssiu", conf_ssiu);
372 ret_scu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SCU, conf_scu); 271 ret_scu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SCU, "scu", conf_scu);
373 ret_adg = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_ADG, conf_adg); 272 ret_adg = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_ADG, "adg", conf_adg);
374 ret_ssi = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSI, conf_ssi); 273 ret_ssi = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSI, "ssi", conf_ssi);
375 if (ret_ssiu < 0 || 274 if (ret_ssiu < 0 ||
376 ret_scu < 0 || 275 ret_scu < 0 ||
377 ret_adg < 0 || 276 ret_adg < 0 ||
378 ret_ssi < 0) 277 ret_ssi < 0)
379 return ret_ssiu | ret_scu | ret_adg | ret_ssi; 278 return ret_ssiu | ret_scu | ret_adg | ret_ssi;
380 279
381 dev_dbg(dev, "Gen2 is probed\n");
382
383 return 0; 280 return 0;
384} 281}
385 282
@@ -390,7 +287,6 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
390static int rsnd_gen1_probe(struct platform_device *pdev, 287static int rsnd_gen1_probe(struct platform_device *pdev,
391 struct rsnd_priv *priv) 288 struct rsnd_priv *priv)
392{ 289{
393 struct device *dev = rsnd_priv_to_dev(priv);
394 struct rsnd_regmap_field_conf conf_sru[] = { 290 struct rsnd_regmap_field_conf conf_sru[] = {
395 RSND_GEN_S_REG(SRC_ROUTE_SEL, 0x00), 291 RSND_GEN_S_REG(SRC_ROUTE_SEL, 0x00),
396 RSND_GEN_S_REG(SRC_TMG_SEL0, 0x08), 292 RSND_GEN_S_REG(SRC_TMG_SEL0, 0x08),
@@ -440,16 +336,14 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
440 int ret_adg; 336 int ret_adg;
441 int ret_ssi; 337 int ret_ssi;
442 338
443 ret_sru = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SRU, conf_sru); 339 ret_sru = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SRU, "sru", conf_sru);
444 ret_adg = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, conf_adg); 340 ret_adg = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, "adg", conf_adg);
445 ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, conf_ssi); 341 ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, "ssi", conf_ssi);
446 if (ret_sru < 0 || 342 if (ret_sru < 0 ||
447 ret_adg < 0 || 343 ret_adg < 0 ||
448 ret_ssi < 0) 344 ret_ssi < 0)
449 return ret_sru | ret_adg | ret_ssi; 345 return ret_sru | ret_adg | ret_ssi;
450 346
451 dev_dbg(dev, "Gen1 is probed\n");
452
453 return 0; 347 return 0;
454} 348}
455 349
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index e7914bd610e2..4e6de6804cfb 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -170,21 +170,47 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod);
170/* 170/*
171 * R-Car DMA 171 * R-Car DMA
172 */ 172 */
173struct rsnd_dma { 173struct rsnd_dma;
174 struct sh_dmae_slave slave; 174struct rsnd_dma_ops {
175 void (*start)(struct rsnd_dma *dma);
176 void (*stop)(struct rsnd_dma *dma);
177 int (*init)(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
178 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to);
179 void (*quit)(struct rsnd_dma *dma);
180};
181
182struct rsnd_dmaen {
175 struct dma_chan *chan; 183 struct dma_chan *chan;
176 enum dma_transfer_direction dir;
177 dma_addr_t addr;
178}; 184};
179 185
186struct rsnd_dmapp {
187 int dmapp_id;
188 u32 chcr;
189};
190
191struct rsnd_dma {
192 struct rsnd_dma_ops *ops;
193 dma_addr_t src_addr;
194 dma_addr_t dst_addr;
195 union {
196 struct rsnd_dmaen en;
197 struct rsnd_dmapp pp;
198 } dma;
199};
200#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
201#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
202
180void rsnd_dma_start(struct rsnd_dma *dma); 203void rsnd_dma_start(struct rsnd_dma *dma);
181void rsnd_dma_stop(struct rsnd_dma *dma); 204void rsnd_dma_stop(struct rsnd_dma *dma);
182int rsnd_dma_available(struct rsnd_dma *dma); 205int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id);
183int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, 206void rsnd_dma_quit(struct rsnd_dma *dma);
184 int is_play, int id); 207int rsnd_dma_probe(struct platform_device *pdev,
185void rsnd_dma_quit(struct rsnd_priv *priv, 208 const struct rsnd_of_data *of_data,
186 struct rsnd_dma *dma); 209 struct rsnd_priv *priv);
210struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
211 struct rsnd_mod *mod, char *name);
187 212
213#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
188 214
189/* 215/*
190 * R-Car sound mod 216 * R-Car sound mod
@@ -198,7 +224,7 @@ enum rsnd_mod_type {
198 224
199struct rsnd_mod_ops { 225struct rsnd_mod_ops {
200 char *name; 226 char *name;
201 char* (*dma_name)(struct rsnd_mod *mod); 227 struct dma_chan* (*dma_req)(struct rsnd_mod *mod);
202 int (*probe)(struct rsnd_mod *mod, 228 int (*probe)(struct rsnd_mod *mod,
203 struct rsnd_priv *priv); 229 struct rsnd_priv *priv);
204 int (*remove)(struct rsnd_mod *mod, 230 int (*remove)(struct rsnd_mod *mod,
@@ -213,6 +239,9 @@ struct rsnd_mod_ops {
213 struct rsnd_priv *priv); 239 struct rsnd_priv *priv);
214 int (*pcm_new)(struct rsnd_mod *mod, 240 int (*pcm_new)(struct rsnd_mod *mod,
215 struct snd_soc_pcm_runtime *rtd); 241 struct snd_soc_pcm_runtime *rtd);
242 int (*hw_params)(struct rsnd_mod *mod,
243 struct snd_pcm_substream *substream,
244 struct snd_pcm_hw_params *hw_params);
216 int (*fallback)(struct rsnd_mod *mod, 245 int (*fallback)(struct rsnd_mod *mod,
217 struct rsnd_priv *priv); 246 struct rsnd_priv *priv);
218}; 247};
@@ -236,6 +265,9 @@ struct rsnd_mod {
236 * 2 0: start 1: stop 265 * 2 0: start 1: stop
237 * 3 0: pcm_new 266 * 3 0: pcm_new
238 * 4 0: fallback 267 * 4 0: fallback
268 *
269 * 31 bit is always called (see __rsnd_mod_call)
270 * 31 0: hw_params
239 */ 271 */
240#define __rsnd_mod_shift_probe 0 272#define __rsnd_mod_shift_probe 0
241#define __rsnd_mod_shift_remove 0 273#define __rsnd_mod_shift_remove 0
@@ -245,6 +277,7 @@ struct rsnd_mod {
245#define __rsnd_mod_shift_stop 2 277#define __rsnd_mod_shift_stop 2
246#define __rsnd_mod_shift_pcm_new 3 278#define __rsnd_mod_shift_pcm_new 3
247#define __rsnd_mod_shift_fallback 4 279#define __rsnd_mod_shift_fallback 4
280#define __rsnd_mod_shift_hw_params 31 /* always called */
248 281
249#define __rsnd_mod_call_probe 0 282#define __rsnd_mod_call_probe 0
250#define __rsnd_mod_call_remove 1 283#define __rsnd_mod_call_remove 1
@@ -254,28 +287,30 @@ struct rsnd_mod {
254#define __rsnd_mod_call_stop 1 287#define __rsnd_mod_call_stop 1
255#define __rsnd_mod_call_pcm_new 0 288#define __rsnd_mod_call_pcm_new 0
256#define __rsnd_mod_call_fallback 0 289#define __rsnd_mod_call_fallback 0
290#define __rsnd_mod_call_hw_params 0
257 291
258#define rsnd_mod_to_priv(mod) (rsnd_io_to_priv(rsnd_mod_to_io(mod))) 292#define rsnd_mod_to_priv(mod) (rsnd_io_to_priv(rsnd_mod_to_io(mod)))
259#define rsnd_mod_to_dma(mod) (&(mod)->dma) 293#define rsnd_mod_to_dma(mod) (&(mod)->dma)
260#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
261#define rsnd_mod_to_io(mod) ((mod)->io) 294#define rsnd_mod_to_io(mod) ((mod)->io)
262#define rsnd_mod_id(mod) ((mod)->id) 295#define rsnd_mod_id(mod) ((mod)->id)
263#define rsnd_mod_hw_start(mod) clk_prepare_enable((mod)->clk) 296#define rsnd_mod_hw_start(mod) clk_enable((mod)->clk)
264#define rsnd_mod_hw_stop(mod) clk_disable_unprepare((mod)->clk) 297#define rsnd_mod_hw_stop(mod) clk_disable((mod)->clk)
265 298
266void rsnd_mod_init(struct rsnd_mod *mod, 299int rsnd_mod_init(struct rsnd_mod *mod,
267 struct rsnd_mod_ops *ops, 300 struct rsnd_mod_ops *ops,
268 struct clk *clk, 301 struct clk *clk,
269 enum rsnd_mod_type type, 302 enum rsnd_mod_type type,
270 int id); 303 int id);
304void rsnd_mod_quit(struct rsnd_mod *mod);
271char *rsnd_mod_name(struct rsnd_mod *mod); 305char *rsnd_mod_name(struct rsnd_mod *mod);
272char *rsnd_mod_dma_name(struct rsnd_mod *mod); 306struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod);
273 307
274/* 308/*
275 * R-Car sound DAI 309 * R-Car sound DAI
276 */ 310 */
277#define RSND_DAI_NAME_SIZE 16 311#define RSND_DAI_NAME_SIZE 16
278struct rsnd_dai_stream { 312struct rsnd_dai_stream {
313 char name[RSND_DAI_NAME_SIZE];
279 struct snd_pcm_substream *substream; 314 struct snd_pcm_substream *substream;
280 struct rsnd_mod *mod[RSND_MOD_MAX]; 315 struct rsnd_mod *mod[RSND_MOD_MAX];
281 struct rsnd_dai_path_info *info; /* rcar_snd.h */ 316 struct rsnd_dai_path_info *info; /* rcar_snd.h */
@@ -331,9 +366,7 @@ int rsnd_gen_probe(struct platform_device *pdev,
331void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, 366void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
332 struct rsnd_mod *mod, 367 struct rsnd_mod *mod,
333 enum rsnd_reg reg); 368 enum rsnd_reg reg);
334dma_addr_t rsnd_gen_dma_addr(struct rsnd_priv *priv, 369phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id);
335 struct rsnd_mod *mod,
336 int is_play, int is_from);
337 370
338#define rsnd_is_gen1(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1) 371#define rsnd_is_gen1(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1)
339#define rsnd_is_gen2(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN2) 372#define rsnd_is_gen2(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN2)
@@ -389,6 +422,11 @@ struct rsnd_priv {
389 void *adg; 422 void *adg;
390 423
391 /* 424 /*
425 * below value will be filled on rsnd_dma_probe()
426 */
427 void *dma;
428
429 /*
392 * below value will be filled on rsnd_ssi_probe() 430 * below value will be filled on rsnd_ssi_probe()
393 */ 431 */
394 void *ssi; 432 void *ssi;
@@ -414,19 +452,6 @@ struct rsnd_priv {
414#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags) 452#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags)
415#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags) 453#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags)
416 454
417#define rsnd_info_is_playback(priv, type) \
418({ \
419 struct rcar_snd_info *info = rsnd_priv_to_info(priv); \
420 int i, is_play = 0; \
421 for (i = 0; i < info->dai_info_nr; i++) { \
422 if (info->dai_info[i].playback.type == (type)->info) { \
423 is_play = 1; \
424 break; \
425 } \
426 } \
427 is_play; \
428})
429
430/* 455/*
431 * rsnd_kctrl 456 * rsnd_kctrl
432 */ 457 */
@@ -480,6 +505,8 @@ int rsnd_kctrl_new_e(struct rsnd_mod *mod,
480int rsnd_src_probe(struct platform_device *pdev, 505int rsnd_src_probe(struct platform_device *pdev,
481 const struct rsnd_of_data *of_data, 506 const struct rsnd_of_data *of_data,
482 struct rsnd_priv *priv); 507 struct rsnd_priv *priv);
508void rsnd_src_remove(struct platform_device *pdev,
509 struct rsnd_priv *priv);
483struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id); 510struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id);
484unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, 511unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
485 struct rsnd_dai_stream *io, 512 struct rsnd_dai_stream *io,
@@ -498,9 +525,12 @@ int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod);
498int rsnd_ssi_probe(struct platform_device *pdev, 525int rsnd_ssi_probe(struct platform_device *pdev,
499 const struct rsnd_of_data *of_data, 526 const struct rsnd_of_data *of_data,
500 struct rsnd_priv *priv); 527 struct rsnd_priv *priv);
528void rsnd_ssi_remove(struct platform_device *pdev,
529 struct rsnd_priv *priv);
501struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); 530struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
502int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); 531int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
503int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); 532int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);
533int rsnd_ssi_use_busif(struct rsnd_mod *mod);
504 534
505/* 535/*
506 * R-Car DVC 536 * R-Car DVC
diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c
new file mode 100644
index 000000000000..a68517afe615
--- /dev/null
+++ b/sound/soc/sh/rcar/rsrc-card.c
@@ -0,0 +1,512 @@
1/*
2 * Renesas Sampling Rate Convert Sound Card for DPCM
3 *
4 * Copyright (C) 2015 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * based on ${LINUX}/sound/soc/generic/simple-card.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/clk.h>
14#include <linux/device.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/of_device.h>
18#include <linux/platform_device.h>
19#include <linux/string.h>
20#include <sound/jack.h>
21#include <sound/soc.h>
22#include <sound/soc-dai.h>
23
24struct rsrc_card_of_data {
25 const char *prefix;
26 const struct snd_soc_dapm_route *routes;
27 int num_routes;
28};
29
30static const struct snd_soc_dapm_route routes_ssi0_ak4642[] = {
31 {"ak4642 Playback", NULL, "DAI0 Playback"},
32 {"DAI0 Capture", NULL, "ak4642 Capture"},
33};
34
35static const struct rsrc_card_of_data routes_of_ssi0_ak4642 = {
36 .prefix = "ak4642",
37 .routes = routes_ssi0_ak4642,
38 .num_routes = ARRAY_SIZE(routes_ssi0_ak4642),
39};
40
41static const struct of_device_id rsrc_card_of_match[] = {
42 { .compatible = "renesas,rsrc-card,lager", .data = &routes_of_ssi0_ak4642 },
43 { .compatible = "renesas,rsrc-card,koelsch", .data = &routes_of_ssi0_ak4642 },
44 {},
45};
46MODULE_DEVICE_TABLE(of, rsrc_card_of_match);
47
48struct rsrc_card_dai {
49 const char *name;
50 unsigned int fmt;
51 unsigned int sysclk;
52 struct clk *clk;
53};
54
55#define RSRC_FB_NUM 2 /* FE/BE */
56#define IDX_CPU 0
57#define IDX_CODEC 1
58struct rsrc_card_priv {
59 struct snd_soc_card snd_card;
60 struct rsrc_card_dai_props {
61 struct rsrc_card_dai cpu_dai;
62 struct rsrc_card_dai codec_dai;
63 } dai_props[RSRC_FB_NUM];
64 struct snd_soc_codec_conf codec_conf;
65 struct snd_soc_dai_link dai_link[RSRC_FB_NUM];
66 u32 convert_rate;
67};
68
69#define rsrc_priv_to_dev(priv) ((priv)->snd_card.dev)
70#define rsrc_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i)
71#define rsrc_priv_to_props(priv, i) ((priv)->dai_props + i)
72#define rsrc_dev_to_of_data(dev) (of_match_device(rsrc_card_of_match, (dev))->data)
73
74static int rsrc_card_startup(struct snd_pcm_substream *substream)
75{
76 struct snd_soc_pcm_runtime *rtd = substream->private_data;
77 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
78 struct rsrc_card_dai_props *dai_props =
79 &priv->dai_props[rtd - rtd->card->rtd];
80 int ret;
81
82 ret = clk_prepare_enable(dai_props->cpu_dai.clk);
83 if (ret)
84 return ret;
85
86 ret = clk_prepare_enable(dai_props->codec_dai.clk);
87 if (ret)
88 clk_disable_unprepare(dai_props->cpu_dai.clk);
89
90 return ret;
91}
92
93static void rsrc_card_shutdown(struct snd_pcm_substream *substream)
94{
95 struct snd_soc_pcm_runtime *rtd = substream->private_data;
96 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
97 struct rsrc_card_dai_props *dai_props =
98 &priv->dai_props[rtd - rtd->card->rtd];
99
100 clk_disable_unprepare(dai_props->cpu_dai.clk);
101
102 clk_disable_unprepare(dai_props->codec_dai.clk);
103}
104
105static struct snd_soc_ops rsrc_card_ops = {
106 .startup = rsrc_card_startup,
107 .shutdown = rsrc_card_shutdown,
108};
109
110static int __rsrc_card_dai_init(struct snd_soc_dai *dai,
111 struct rsrc_card_dai *set)
112{
113 int ret;
114
115 if (set->fmt) {
116 ret = snd_soc_dai_set_fmt(dai, set->fmt);
117 if (ret && ret != -ENOTSUPP) {
118 dev_err(dai->dev, "set_fmt error\n");
119 goto err;
120 }
121 }
122
123 if (set->sysclk) {
124 ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0);
125 if (ret && ret != -ENOTSUPP) {
126 dev_err(dai->dev, "set_sysclk error\n");
127 goto err;
128 }
129 }
130
131 ret = 0;
132
133err:
134 return ret;
135}
136
137static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd)
138{
139 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
140 struct snd_soc_dai *codec = rtd->codec_dai;
141 struct snd_soc_dai *cpu = rtd->cpu_dai;
142 struct rsrc_card_dai_props *dai_props;
143 int num, ret;
144
145 num = rtd - rtd->card->rtd;
146 dai_props = &priv->dai_props[num];
147 ret = __rsrc_card_dai_init(codec, &dai_props->codec_dai);
148 if (ret < 0)
149 return ret;
150
151 ret = __rsrc_card_dai_init(cpu, &dai_props->cpu_dai);
152 if (ret < 0)
153 return ret;
154
155 return 0;
156}
157
158static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
159 struct snd_pcm_hw_params *params)
160{
161 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
162 struct snd_interval *rate = hw_param_interval(params,
163 SNDRV_PCM_HW_PARAM_RATE);
164
165 if (!priv->convert_rate)
166 return 0;
167
168 rate->min = rate->max = priv->convert_rate;
169
170 return 0;
171}
172
173static int
174rsrc_card_sub_parse_of(struct rsrc_card_priv *priv,
175 struct device_node *np,
176 struct rsrc_card_dai *dai,
177 struct snd_soc_dai_link *dai_link,
178 int *args_count)
179{
180 struct device *dev = rsrc_priv_to_dev(priv);
181 const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev);
182 struct of_phandle_args args;
183 struct device_node **p_node;
184 struct clk *clk;
185 const char **dai_name;
186 const char **name;
187 u32 val;
188 int ret;
189
190 if (args_count) {
191 p_node = &dai_link->cpu_of_node;
192 dai_name = &dai_link->cpu_dai_name;
193 name = &dai_link->cpu_name;
194 } else {
195 p_node = &dai_link->codec_of_node;
196 dai_name = &dai_link->codec_dai_name;
197 name = &dai_link->codec_name;
198 }
199
200 if (!np) {
201 /* use snd-soc-dummy */
202 *p_node = NULL;
203 *dai_name = "snd-soc-dummy-dai";
204 *name = "snd-soc-dummy";
205 return 0;
206 }
207
208 /*
209 * Get node via "sound-dai = <&phandle port>"
210 * it will be used as xxx_of_node on soc_bind_dai_link()
211 */
212 ret = of_parse_phandle_with_args(np, "sound-dai",
213 "#sound-dai-cells", 0, &args);
214 if (ret)
215 return ret;
216
217 *p_node = args.np;
218
219 /* Get dai->name */
220 ret = snd_soc_of_get_dai_name(np, dai_name);
221 if (ret < 0)
222 return ret;
223
224 /*
225 * FIXME
226 *
227 * rsrc assumes DPCM playback/capture
228 */
229 dai_link->dpcm_playback = 1;
230 dai_link->dpcm_capture = 1;
231
232 if (args_count) {
233 *args_count = args.args_count;
234 dai_link->dynamic = 1;
235 } else {
236 dai_link->no_pcm = 1;
237 priv->codec_conf.of_node = (*p_node);
238 priv->codec_conf.name_prefix = of_data->prefix;
239 }
240
241 /*
242 * Parse dai->sysclk come from "clocks = <&xxx>"
243 * (if system has common clock)
244 * or "system-clock-frequency = <xxx>"
245 * or device's module clock.
246 */
247 if (of_property_read_bool(np, "clocks")) {
248 clk = of_clk_get(np, 0);
249 if (IS_ERR(clk)) {
250 ret = PTR_ERR(clk);
251 return ret;
252 }
253
254 dai->sysclk = clk_get_rate(clk);
255 dai->clk = clk;
256 } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) {
257 dai->sysclk = val;
258 } else {
259 clk = of_clk_get(args.np, 0);
260 if (!IS_ERR(clk))
261 dai->sysclk = clk_get_rate(clk);
262 }
263
264 return 0;
265}
266
267static int rsrc_card_parse_daifmt(struct device_node *node,
268 struct rsrc_card_priv *priv,
269 struct device_node *codec,
270 int idx)
271{
272 struct device_node *bitclkmaster = NULL;
273 struct device_node *framemaster = NULL;
274 struct rsrc_card_dai_props *dai_props = rsrc_priv_to_props(priv, idx);
275 struct rsrc_card_dai *cpu_dai = &dai_props->cpu_dai;
276 struct rsrc_card_dai *codec_dai = &dai_props->codec_dai;
277 unsigned int daifmt;
278
279 daifmt = snd_soc_of_parse_daifmt(node, NULL,
280 &bitclkmaster, &framemaster);
281 daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
282
283 if (!bitclkmaster && !framemaster)
284 return -EINVAL;
285
286 if (codec == bitclkmaster)
287 daifmt |= (codec == framemaster) ?
288 SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
289 else
290 daifmt |= (codec == framemaster) ?
291 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
292
293 cpu_dai->fmt = daifmt;
294 codec_dai->fmt = daifmt;
295
296 of_node_put(bitclkmaster);
297 of_node_put(framemaster);
298
299 return 0;
300}
301
302static int rsrc_card_dai_link_of(struct device_node *node,
303 struct rsrc_card_priv *priv,
304 int idx)
305{
306 struct device *dev = rsrc_priv_to_dev(priv);
307 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
308 struct rsrc_card_dai_props *dai_props = rsrc_priv_to_props(priv, idx);
309 struct device_node *cpu = NULL;
310 struct device_node *codec = NULL;
311 char *name;
312 char prop[128];
313 int ret, cpu_args;
314
315 cpu = of_get_child_by_name(node, "cpu");
316 codec = of_get_child_by_name(node, "codec");
317
318 if (!cpu || !codec) {
319 ret = -EINVAL;
320 dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
321 goto dai_link_of_err;
322 }
323
324 ret = rsrc_card_parse_daifmt(node, priv, codec, idx);
325 if (ret < 0)
326 goto dai_link_of_err;
327
328 ret = rsrc_card_sub_parse_of(priv, (idx == IDX_CPU) ? cpu : NULL,
329 &dai_props->cpu_dai,
330 dai_link,
331 &cpu_args);
332 if (ret < 0)
333 goto dai_link_of_err;
334
335 ret = rsrc_card_sub_parse_of(priv, (idx == IDX_CODEC) ? codec : NULL,
336 &dai_props->codec_dai,
337 dai_link,
338 NULL);
339 if (ret < 0)
340 goto dai_link_of_err;
341
342 if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
343 ret = -EINVAL;
344 goto dai_link_of_err;
345 }
346
347 /* Simple Card assumes platform == cpu */
348 dai_link->platform_of_node = dai_link->cpu_of_node;
349
350 /* DAI link name is created from CPU/CODEC dai name */
351 name = devm_kzalloc(dev,
352 strlen(dai_link->cpu_dai_name) +
353 strlen(dai_link->codec_dai_name) + 2,
354 GFP_KERNEL);
355 if (!name) {
356 ret = -ENOMEM;
357 goto dai_link_of_err;
358 }
359
360 sprintf(name, "%s-%s", dai_link->cpu_dai_name,
361 dai_link->codec_dai_name);
362 dai_link->name = dai_link->stream_name = name;
363 dai_link->ops = &rsrc_card_ops;
364 dai_link->init = rsrc_card_dai_init;
365
366 if (idx == IDX_CODEC)
367 dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup;
368
369 dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
370 dev_dbg(dev, "\tcpu : %s / %04x / %d\n",
371 dai_link->cpu_dai_name,
372 dai_props->cpu_dai.fmt,
373 dai_props->cpu_dai.sysclk);
374 dev_dbg(dev, "\tcodec : %s / %04x / %d\n",
375 dai_link->codec_dai_name,
376 dai_props->codec_dai.fmt,
377 dai_props->codec_dai.sysclk);
378
379 /*
380 * In soc_bind_dai_link() will check cpu name after
381 * of_node matching if dai_link has cpu_dai_name.
382 * but, it will never match if name was created by
383 * fmt_single_name() remove cpu_dai_name if cpu_args
384 * was 0. See:
385 * fmt_single_name()
386 * fmt_multiple_name()
387 */
388 if (!cpu_args)
389 dai_link->cpu_dai_name = NULL;
390
391dai_link_of_err:
392 of_node_put(cpu);
393 of_node_put(codec);
394
395 return ret;
396}
397
398static int rsrc_card_parse_of(struct device_node *node,
399 struct rsrc_card_priv *priv)
400{
401 struct device *dev = rsrc_priv_to_dev(priv);
402 const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev);
403 int ret;
404 int i;
405
406 if (!node)
407 return -EINVAL;
408
409 /* Parse the card name from DT */
410 snd_soc_of_parse_card_name(&priv->snd_card, "card-name");
411
412 /* DAPM routes */
413 priv->snd_card.of_dapm_routes = of_data->routes;
414 priv->snd_card.num_of_dapm_routes = of_data->num_routes;
415
416 /* sampling rate convert */
417 of_property_read_u32(node, "convert-rate", &priv->convert_rate);
418
419 dev_dbg(dev, "New rsrc-audio-card: %s (%d)\n",
420 priv->snd_card.name ? priv->snd_card.name : "",
421 priv->convert_rate);
422
423 /* FE/BE */
424 for (i = 0; i < RSRC_FB_NUM; i++) {
425 ret = rsrc_card_dai_link_of(node, priv, i);
426 if (ret < 0)
427 return ret;
428 }
429
430 if (!priv->snd_card.name)
431 priv->snd_card.name = priv->snd_card.dai_link->name;
432
433 return 0;
434}
435
436/* Decrease the reference count of the device nodes */
437static int rsrc_card_unref(struct snd_soc_card *card)
438{
439 struct snd_soc_dai_link *dai_link;
440 int num_links;
441
442 for (num_links = 0, dai_link = card->dai_link;
443 num_links < card->num_links;
444 num_links++, dai_link++) {
445 of_node_put(dai_link->cpu_of_node);
446 of_node_put(dai_link->codec_of_node);
447 }
448 return 0;
449}
450
451static int rsrc_card_probe(struct platform_device *pdev)
452{
453 struct rsrc_card_priv *priv;
454 struct snd_soc_dai_link *dai_link;
455 struct device_node *np = pdev->dev.of_node;
456 struct device *dev = &pdev->dev;
457 int ret;
458
459 /* Allocate the private data */
460 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
461 if (!priv)
462 return -ENOMEM;
463
464 /* Init snd_soc_card */
465 priv->snd_card.owner = THIS_MODULE;
466 priv->snd_card.dev = dev;
467 dai_link = priv->dai_link;
468 priv->snd_card.dai_link = dai_link;
469 priv->snd_card.num_links = RSRC_FB_NUM;
470 priv->snd_card.codec_conf = &priv->codec_conf;
471 priv->snd_card.num_configs = 1;
472
473 ret = rsrc_card_parse_of(np, priv);
474 if (ret < 0) {
475 if (ret != -EPROBE_DEFER)
476 dev_err(dev, "parse error %d\n", ret);
477 goto err;
478 }
479
480 snd_soc_card_set_drvdata(&priv->snd_card, priv);
481
482 ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
483 if (ret >= 0)
484 return ret;
485err:
486 rsrc_card_unref(&priv->snd_card);
487
488 return ret;
489}
490
491static int rsrc_card_remove(struct platform_device *pdev)
492{
493 struct snd_soc_card *card = platform_get_drvdata(pdev);
494
495 return rsrc_card_unref(card);
496}
497
498static struct platform_driver rsrc_card = {
499 .driver = {
500 .name = "renesas-src-audio-card",
501 .of_match_table = rsrc_card_of_match,
502 },
503 .probe = rsrc_card_probe,
504 .remove = rsrc_card_remove,
505};
506
507module_platform_driver(rsrc_card);
508
509MODULE_ALIAS("platform:renesas-src-audio-card");
510MODULE_LICENSE("GPL");
511MODULE_DESCRIPTION("Renesas Sampling Rate Convert Sound Card");
512MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 81c182b4bad5..3beb32eb412a 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -22,16 +22,20 @@
22struct rsnd_src { 22struct rsnd_src {
23 struct rsnd_src_platform_info *info; /* rcar_snd.h */ 23 struct rsnd_src_platform_info *info; /* rcar_snd.h */
24 struct rsnd_mod mod; 24 struct rsnd_mod mod;
25 struct rsnd_kctrl_cfg_s sen; /* sync convert enable */
26 struct rsnd_kctrl_cfg_s sync; /* sync convert */
27 u32 convert_rate; /* sampling rate convert */
25 int err; 28 int err;
26}; 29};
27 30
28#define RSND_SRC_NAME_SIZE 16 31#define RSND_SRC_NAME_SIZE 16
29 32
30#define rsnd_src_convert_rate(p) ((p)->info->convert_rate) 33#define rsnd_enable_sync_convert(src) ((src)->sen.val)
34#define rsnd_src_of_node(priv) \
35 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src")
36
31#define rsnd_mod_to_src(_mod) \ 37#define rsnd_mod_to_src(_mod) \
32 container_of((_mod), struct rsnd_src, mod) 38 container_of((_mod), struct rsnd_src, mod)
33#define rsnd_src_dma_available(src) \
34 rsnd_dma_available(rsnd_mod_to_dma(&(src)->mod))
35 39
36#define for_each_rsnd_src(pos, priv, i) \ 40#define for_each_rsnd_src(pos, priv, i) \
37 for ((i) = 0; \ 41 for ((i) = 0; \
@@ -113,6 +117,17 @@ struct rsnd_src {
113/* 117/*
114 * Gen1/Gen2 common functions 118 * Gen1/Gen2 common functions
115 */ 119 */
120static struct dma_chan *rsnd_src_dma_req(struct rsnd_mod *mod)
121{
122 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
123 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
124 int is_play = rsnd_io_is_play(io);
125
126 return rsnd_dma_request_channel(rsnd_src_of_node(priv),
127 mod,
128 is_play ? "rx" : "tx");
129}
130
116int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, 131int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
117 int use_busif) 132 int use_busif)
118{ 133{
@@ -220,6 +235,30 @@ int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod)
220 return 0; 235 return 0;
221} 236}
222 237
238static u32 rsnd_src_convert_rate(struct rsnd_src *src)
239{
240 struct rsnd_mod *mod = &src->mod;
241 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
242 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
243 u32 convert_rate;
244
245 if (!runtime)
246 return 0;
247
248 if (!rsnd_enable_sync_convert(src))
249 return src->convert_rate;
250
251 convert_rate = src->sync.val;
252
253 if (!convert_rate)
254 convert_rate = src->convert_rate;
255
256 if (!convert_rate)
257 convert_rate = runtime->rate;
258
259 return convert_rate;
260}
261
223unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, 262unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
224 struct rsnd_dai_stream *io, 263 struct rsnd_dai_stream *io,
225 struct snd_pcm_runtime *runtime) 264 struct snd_pcm_runtime *runtime)
@@ -276,7 +315,43 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod)
276 return 0; 315 return 0;
277} 316}
278 317
279static int rsnd_src_init(struct rsnd_mod *mod) 318static int rsnd_src_hw_params(struct rsnd_mod *mod,
319 struct snd_pcm_substream *substream,
320 struct snd_pcm_hw_params *fe_params)
321{
322 struct rsnd_src *src = rsnd_mod_to_src(mod);
323 struct snd_soc_pcm_runtime *fe = substream->private_data;
324
325 /* default value (mainly for non-DT) */
326 src->convert_rate = src->info->convert_rate;
327
328 /*
329 * SRC assumes that it is used under DPCM if user want to use
330 * sampling rate convert. Then, SRC should be FE.
331 * And then, this function will be called *after* BE settings.
332 * this means, each BE already has fixuped hw_params.
333 * see
334 * dpcm_fe_dai_hw_params()
335 * dpcm_be_dai_hw_params()
336 */
337 if (fe->dai_link->dynamic) {
338 int stream = substream->stream;
339 struct snd_soc_dpcm *dpcm;
340 struct snd_pcm_hw_params *be_params;
341
342 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
343 be_params = &dpcm->hw_params;
344
345 if (params_rate(fe_params) != params_rate(be_params))
346 src->convert_rate = params_rate(be_params);
347 }
348 }
349
350 return 0;
351}
352
353static int rsnd_src_init(struct rsnd_mod *mod,
354 struct rsnd_priv *priv)
280{ 355{
281 struct rsnd_src *src = rsnd_mod_to_src(mod); 356 struct rsnd_src *src = rsnd_mod_to_src(mod);
282 357
@@ -284,6 +359,9 @@ static int rsnd_src_init(struct rsnd_mod *mod)
284 359
285 src->err = 0; 360 src->err = 0;
286 361
362 /* reset sync convert_rate */
363 src->sync.val = 0;
364
287 /* 365 /*
288 * Initialize the operation of the SRC internal circuits 366 * Initialize the operation of the SRC internal circuits
289 * see rsnd_src_start() 367 * see rsnd_src_start()
@@ -305,6 +383,11 @@ static int rsnd_src_quit(struct rsnd_mod *mod,
305 dev_warn(dev, "%s[%d] under/over flow err = %d\n", 383 dev_warn(dev, "%s[%d] under/over flow err = %d\n",
306 rsnd_mod_name(mod), rsnd_mod_id(mod), src->err); 384 rsnd_mod_name(mod), rsnd_mod_id(mod), src->err);
307 385
386 src->convert_rate = 0;
387
388 /* reset sync convert_rate */
389 src->sync.val = 0;
390
308 return 0; 391 return 0;
309} 392}
310 393
@@ -448,23 +531,12 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod)
448 return 0; 531 return 0;
449} 532}
450 533
451static int rsnd_src_probe_gen1(struct rsnd_mod *mod,
452 struct rsnd_priv *priv)
453{
454 struct device *dev = rsnd_priv_to_dev(priv);
455
456 dev_dbg(dev, "%s[%d] (Gen1) is probed\n",
457 rsnd_mod_name(mod), rsnd_mod_id(mod));
458
459 return 0;
460}
461
462static int rsnd_src_init_gen1(struct rsnd_mod *mod, 534static int rsnd_src_init_gen1(struct rsnd_mod *mod,
463 struct rsnd_priv *priv) 535 struct rsnd_priv *priv)
464{ 536{
465 int ret; 537 int ret;
466 538
467 ret = rsnd_src_init(mod); 539 ret = rsnd_src_init(mod, priv);
468 if (ret < 0) 540 if (ret < 0)
469 return ret; 541 return ret;
470 542
@@ -505,11 +577,12 @@ static int rsnd_src_stop_gen1(struct rsnd_mod *mod,
505 577
506static struct rsnd_mod_ops rsnd_src_gen1_ops = { 578static struct rsnd_mod_ops rsnd_src_gen1_ops = {
507 .name = SRC_NAME, 579 .name = SRC_NAME,
508 .probe = rsnd_src_probe_gen1, 580 .dma_req = rsnd_src_dma_req,
509 .init = rsnd_src_init_gen1, 581 .init = rsnd_src_init_gen1,
510 .quit = rsnd_src_quit, 582 .quit = rsnd_src_quit,
511 .start = rsnd_src_start_gen1, 583 .start = rsnd_src_start_gen1,
512 .stop = rsnd_src_stop_gen1, 584 .stop = rsnd_src_stop_gen1,
585 .hw_params = rsnd_src_hw_params,
513}; 586};
514 587
515/* 588/*
@@ -607,13 +680,17 @@ static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data)
607 680
608 if (rsnd_src_error_record_gen2(mod)) { 681 if (rsnd_src_error_record_gen2(mod)) {
609 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 682 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
683 struct rsnd_src *src = rsnd_mod_to_src(mod);
610 struct device *dev = rsnd_priv_to_dev(priv); 684 struct device *dev = rsnd_priv_to_dev(priv);
611 685
612 _rsnd_src_stop_gen2(mod);
613 _rsnd_src_start_gen2(mod);
614
615 dev_dbg(dev, "%s[%d] restart\n", 686 dev_dbg(dev, "%s[%d] restart\n",
616 rsnd_mod_name(mod), rsnd_mod_id(mod)); 687 rsnd_mod_name(mod), rsnd_mod_id(mod));
688
689 _rsnd_src_stop_gen2(mod);
690 if (src->err < 1024)
691 _rsnd_src_start_gen2(mod);
692 else
693 dev_warn(dev, "no more SRC restart\n");
617 } 694 }
618 695
619 return IRQ_HANDLED; 696 return IRQ_HANDLED;
@@ -627,6 +704,7 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod)
627 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 704 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
628 struct rsnd_src *src = rsnd_mod_to_src(mod); 705 struct rsnd_src *src = rsnd_mod_to_src(mod);
629 u32 convert_rate = rsnd_src_convert_rate(src); 706 u32 convert_rate = rsnd_src_convert_rate(src);
707 u32 cr, route;
630 uint ratio; 708 uint ratio;
631 int ret; 709 int ret;
632 710
@@ -647,13 +725,21 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod)
647 if (ret < 0) 725 if (ret < 0)
648 return ret; 726 return ret;
649 727
650 rsnd_mod_write(mod, SRC_SRCCR, 0x00011110); 728 cr = 0x00011110;
651 729 route = 0x0;
652 if (convert_rate) { 730 if (convert_rate) {
653 /* Gen1/Gen2 are not compatible */ 731 route = 0x1;
654 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); 732
733 if (rsnd_enable_sync_convert(src)) {
734 cr |= 0x1;
735 route |= rsnd_io_is_play(io) ?
736 (0x1 << 24) : (0x1 << 25);
737 }
655 } 738 }
656 739
740 rsnd_mod_write(mod, SRC_SRCCR, cr);
741 rsnd_mod_write(mod, SRC_ROUTE_MODE0, route);
742
657 switch (rsnd_mod_id(mod)) { 743 switch (rsnd_mod_id(mod)) {
658 case 5: 744 case 5:
659 case 6: 745 case 6:
@@ -708,24 +794,12 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
708 IRQF_SHARED, 794 IRQF_SHARED,
709 dev_name(dev), mod); 795 dev_name(dev), mod);
710 if (ret) 796 if (ret)
711 goto rsnd_src_probe_gen2_fail; 797 return ret;
712 } 798 }
713 799
714 ret = rsnd_dma_init(priv, 800 ret = rsnd_dma_init(priv,
715 rsnd_mod_to_dma(mod), 801 rsnd_mod_to_dma(mod),
716 rsnd_info_is_playback(priv, src),
717 src->info->dma_id); 802 src->info->dma_id);
718 if (ret)
719 goto rsnd_src_probe_gen2_fail;
720
721 dev_dbg(dev, "%s[%d] (Gen2) is probed\n",
722 rsnd_mod_name(mod), rsnd_mod_id(mod));
723
724 return ret;
725
726rsnd_src_probe_gen2_fail:
727 dev_err(dev, "%s[%d] (Gen2) failed\n",
728 rsnd_mod_name(mod), rsnd_mod_id(mod));
729 803
730 return ret; 804 return ret;
731} 805}
@@ -733,7 +807,7 @@ rsnd_src_probe_gen2_fail:
733static int rsnd_src_remove_gen2(struct rsnd_mod *mod, 807static int rsnd_src_remove_gen2(struct rsnd_mod *mod,
734 struct rsnd_priv *priv) 808 struct rsnd_priv *priv)
735{ 809{
736 rsnd_dma_quit(priv, rsnd_mod_to_dma(mod)); 810 rsnd_dma_quit(rsnd_mod_to_dma(mod));
737 811
738 return 0; 812 return 0;
739} 813}
@@ -743,7 +817,7 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod,
743{ 817{
744 int ret; 818 int ret;
745 819
746 ret = rsnd_src_init(mod); 820 ret = rsnd_src_init(mod, priv);
747 if (ret < 0) 821 if (ret < 0)
748 return ret; 822 return ret;
749 823
@@ -778,14 +852,91 @@ static int rsnd_src_stop_gen2(struct rsnd_mod *mod,
778 return ret; 852 return ret;
779} 853}
780 854
855static void rsnd_src_reconvert_update(struct rsnd_mod *mod)
856{
857 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
858 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
859 struct rsnd_src *src = rsnd_mod_to_src(mod);
860 u32 convert_rate = rsnd_src_convert_rate(src);
861 u32 fsrate;
862
863 if (!runtime)
864 return;
865
866 if (!convert_rate)
867 convert_rate = runtime->rate;
868
869 fsrate = 0x0400000 / convert_rate * runtime->rate;
870
871 /* update IFS */
872 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
873}
874
875static int rsnd_src_pcm_new(struct rsnd_mod *mod,
876 struct snd_soc_pcm_runtime *rtd)
877{
878 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
879 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
880 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
881 struct rsnd_src *src = rsnd_mod_to_src(mod);
882 int ret;
883
884 /*
885 * enable SRC sync convert if possible
886 */
887
888 /*
889 * Gen1 is not supported
890 */
891 if (rsnd_is_gen1(priv))
892 return 0;
893
894 /*
895 * SRC sync convert needs clock master
896 */
897 if (!rsnd_rdai_is_clk_master(rdai))
898 return 0;
899
900 /*
901 * We can't use SRC sync convert
902 * if it has DVC
903 */
904 if (rsnd_io_to_mod_dvc(io))
905 return 0;
906
907 /*
908 * enable sync convert
909 */
910 ret = rsnd_kctrl_new_s(mod, rtd,
911 rsnd_io_is_play(io) ?
912 "SRC Out Rate Switch" :
913 "SRC In Rate Switch",
914 rsnd_src_reconvert_update,
915 &src->sen, 1);
916 if (ret < 0)
917 return ret;
918
919 ret = rsnd_kctrl_new_s(mod, rtd,
920 rsnd_io_is_play(io) ?
921 "SRC Out Rate" :
922 "SRC In Rate",
923 rsnd_src_reconvert_update,
924 &src->sync, 192000);
925
926 return ret;
927}
928
781static struct rsnd_mod_ops rsnd_src_gen2_ops = { 929static struct rsnd_mod_ops rsnd_src_gen2_ops = {
782 .name = SRC_NAME, 930 .name = SRC_NAME,
931 .dma_req = rsnd_src_dma_req,
783 .probe = rsnd_src_probe_gen2, 932 .probe = rsnd_src_probe_gen2,
784 .remove = rsnd_src_remove_gen2, 933 .remove = rsnd_src_remove_gen2,
785 .init = rsnd_src_init_gen2, 934 .init = rsnd_src_init_gen2,
786 .quit = rsnd_src_quit, 935 .quit = rsnd_src_quit,
787 .start = rsnd_src_start_gen2, 936 .start = rsnd_src_start_gen2,
788 .stop = rsnd_src_stop_gen2, 937 .stop = rsnd_src_stop_gen2,
938 .hw_params = rsnd_src_hw_params,
939 .pcm_new = rsnd_src_pcm_new,
789}; 940};
790 941
791struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) 942struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
@@ -810,7 +961,7 @@ static void rsnd_of_parse_src(struct platform_device *pdev,
810 if (!of_data) 961 if (!of_data)
811 return; 962 return;
812 963
813 src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src"); 964 src_node = rsnd_src_of_node(priv);
814 if (!src_node) 965 if (!src_node)
815 return; 966 return;
816 967
@@ -850,7 +1001,7 @@ int rsnd_src_probe(struct platform_device *pdev,
850 struct rsnd_mod_ops *ops; 1001 struct rsnd_mod_ops *ops;
851 struct clk *clk; 1002 struct clk *clk;
852 char name[RSND_SRC_NAME_SIZE]; 1003 char name[RSND_SRC_NAME_SIZE];
853 int i, nr; 1004 int i, nr, ret;
854 1005
855 ops = NULL; 1006 ops = NULL;
856 if (rsnd_is_gen1(priv)) 1007 if (rsnd_is_gen1(priv))
@@ -890,10 +1041,21 @@ int rsnd_src_probe(struct platform_device *pdev,
890 1041
891 src->info = &info->src_info[i]; 1042 src->info = &info->src_info[i];
892 1043
893 rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i); 1044 ret = rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i);
894 1045 if (ret)
895 dev_dbg(dev, "SRC%d probed\n", i); 1046 return ret;
896 } 1047 }
897 1048
898 return 0; 1049 return 0;
899} 1050}
1051
1052void rsnd_src_remove(struct platform_device *pdev,
1053 struct rsnd_priv *priv)
1054{
1055 struct rsnd_src *src;
1056 int i;
1057
1058 for_each_rsnd_src(src, priv, i) {
1059 rsnd_mod_quit(&src->mod);
1060 }
1061}
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 9e7b627c08e2..7bb9c087f3dc 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -80,13 +80,13 @@ struct rsnd_ssi {
80#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) 80#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod)
81#define rsnd_dma_to_ssi(dma) rsnd_mod_to_ssi(rsnd_dma_to_mod(dma)) 81#define rsnd_dma_to_ssi(dma) rsnd_mod_to_ssi(rsnd_dma_to_mod(dma))
82#define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0) 82#define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0)
83#define rsnd_ssi_dma_available(ssi) \
84 rsnd_dma_available(rsnd_mod_to_dma(&(ssi)->mod))
85#define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent) 83#define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent)
86#define rsnd_ssi_mode_flags(p) ((p)->info->flags) 84#define rsnd_ssi_mode_flags(p) ((p)->info->flags)
87#define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id) 85#define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id)
86#define rsnd_ssi_of_node(priv) \
87 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi")
88 88
89static int rsnd_ssi_use_busif(struct rsnd_mod *mod) 89int rsnd_ssi_use_busif(struct rsnd_mod *mod)
90{ 90{
91 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 91 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
92 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 92 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
@@ -416,11 +416,14 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
416 /* 416 /*
417 * restart SSI 417 * restart SSI
418 */ 418 */
419 rsnd_ssi_stop(mod, priv);
420 rsnd_ssi_start(mod, priv);
421
422 dev_dbg(dev, "%s[%d] restart\n", 419 dev_dbg(dev, "%s[%d] restart\n",
423 rsnd_mod_name(mod), rsnd_mod_id(mod)); 420 rsnd_mod_name(mod), rsnd_mod_id(mod));
421
422 rsnd_ssi_stop(mod, priv);
423 if (ssi->err < 1024)
424 rsnd_ssi_start(mod, priv);
425 else
426 dev_warn(dev, "no more SSI restart\n");
424 } 427 }
425 428
426 rsnd_ssi_record_error(ssi, status); 429 rsnd_ssi_record_error(ssi, status);
@@ -442,12 +445,6 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
442 rsnd_ssi_interrupt, 445 rsnd_ssi_interrupt,
443 IRQF_SHARED, 446 IRQF_SHARED,
444 dev_name(dev), ssi); 447 dev_name(dev), ssi);
445 if (ret)
446 dev_err(dev, "%s[%d] (PIO) request interrupt failed\n",
447 rsnd_mod_name(mod), rsnd_mod_id(mod));
448 else
449 dev_dbg(dev, "%s[%d] (PIO) is probed\n",
450 rsnd_mod_name(mod), rsnd_mod_id(mod));
451 448
452 return ret; 449 return ret;
453} 450}
@@ -474,23 +471,11 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
474 IRQF_SHARED, 471 IRQF_SHARED,
475 dev_name(dev), ssi); 472 dev_name(dev), ssi);
476 if (ret) 473 if (ret)
477 goto rsnd_ssi_dma_probe_fail; 474 return ret;
478 475
479 ret = rsnd_dma_init( 476 ret = rsnd_dma_init(
480 priv, rsnd_mod_to_dma(mod), 477 priv, rsnd_mod_to_dma(mod),
481 rsnd_info_is_playback(priv, ssi),
482 dma_id); 478 dma_id);
483 if (ret)
484 goto rsnd_ssi_dma_probe_fail;
485
486 dev_dbg(dev, "%s[%d] (DMA) is probed\n",
487 rsnd_mod_name(mod), rsnd_mod_id(mod));
488
489 return ret;
490
491rsnd_ssi_dma_probe_fail:
492 dev_err(dev, "%s[%d] (DMA) is failed\n",
493 rsnd_mod_name(mod), rsnd_mod_id(mod));
494 479
495 return ret; 480 return ret;
496} 481}
@@ -502,7 +487,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
502 struct device *dev = rsnd_priv_to_dev(priv); 487 struct device *dev = rsnd_priv_to_dev(priv);
503 int irq = ssi->info->irq; 488 int irq = ssi->info->irq;
504 489
505 rsnd_dma_quit(priv, rsnd_mod_to_dma(mod)); 490 rsnd_dma_quit(rsnd_mod_to_dma(mod));
506 491
507 /* PIO will request IRQ again */ 492 /* PIO will request IRQ again */
508 devm_free_irq(dev, irq, ssi); 493 devm_free_irq(dev, irq, ssi);
@@ -554,14 +539,25 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,
554 return 0; 539 return 0;
555} 540}
556 541
557static char *rsnd_ssi_dma_name(struct rsnd_mod *mod) 542static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_mod *mod)
558{ 543{
559 return rsnd_ssi_use_busif(mod) ? "ssiu" : SSI_NAME; 544 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
545 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
546 int is_play = rsnd_io_is_play(io);
547 char *name;
548
549 if (rsnd_ssi_use_busif(mod))
550 name = is_play ? "rxu" : "txu";
551 else
552 name = is_play ? "rx" : "tx";
553
554 return rsnd_dma_request_channel(rsnd_ssi_of_node(priv),
555 mod, name);
560} 556}
561 557
562static struct rsnd_mod_ops rsnd_ssi_dma_ops = { 558static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
563 .name = SSI_NAME, 559 .name = SSI_NAME,
564 .dma_name = rsnd_ssi_dma_name, 560 .dma_req = rsnd_ssi_dma_req,
565 .probe = rsnd_ssi_dma_probe, 561 .probe = rsnd_ssi_dma_probe,
566 .remove = rsnd_ssi_dma_remove, 562 .remove = rsnd_ssi_dma_remove,
567 .init = rsnd_ssi_init, 563 .init = rsnd_ssi_init,
@@ -636,7 +632,7 @@ static void rsnd_of_parse_ssi(struct platform_device *pdev,
636 if (!of_data) 632 if (!of_data)
637 return; 633 return;
638 634
639 node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi"); 635 node = rsnd_ssi_of_node(priv);
640 if (!node) 636 if (!node)
641 return; 637 return;
642 638
@@ -697,7 +693,7 @@ int rsnd_ssi_probe(struct platform_device *pdev,
697 struct clk *clk; 693 struct clk *clk;
698 struct rsnd_ssi *ssi; 694 struct rsnd_ssi *ssi;
699 char name[RSND_SSI_NAME_SIZE]; 695 char name[RSND_SSI_NAME_SIZE];
700 int i, nr; 696 int i, nr, ret;
701 697
702 rsnd_of_parse_ssi(pdev, of_data, priv); 698 rsnd_of_parse_ssi(pdev, of_data, priv);
703 699
@@ -732,10 +728,23 @@ int rsnd_ssi_probe(struct platform_device *pdev,
732 else if (rsnd_ssi_pio_available(ssi)) 728 else if (rsnd_ssi_pio_available(ssi))
733 ops = &rsnd_ssi_pio_ops; 729 ops = &rsnd_ssi_pio_ops;
734 730
735 rsnd_mod_init(&ssi->mod, ops, clk, RSND_MOD_SSI, i); 731 ret = rsnd_mod_init(&ssi->mod, ops, clk, RSND_MOD_SSI, i);
732 if (ret)
733 return ret;
736 734
737 rsnd_ssi_parent_clk_setup(priv, ssi); 735 rsnd_ssi_parent_clk_setup(priv, ssi);
738 } 736 }
739 737
740 return 0; 738 return 0;
741} 739}
740
741void rsnd_ssi_remove(struct platform_device *pdev,
742 struct rsnd_priv *priv)
743{
744 struct rsnd_ssi *ssi;
745 int i;
746
747 for_each_rsnd_ssi(ssi, priv, i) {
748 rsnd_mod_quit(&ssi->mod);
749 }
750}
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 07aa54385ae0..12b7ff2426da 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -292,6 +292,9 @@ static const struct file_operations codec_reg_fops = {
292 292
293static void soc_init_component_debugfs(struct snd_soc_component *component) 293static void soc_init_component_debugfs(struct snd_soc_component *component)
294{ 294{
295 if (!component->card->debugfs_card_root)
296 return;
297
295 if (component->debugfs_prefix) { 298 if (component->debugfs_prefix) {
296 char *name; 299 char *name;
297 300
@@ -455,6 +458,9 @@ static const struct file_operations platform_list_fops = {
455 458
456static void soc_init_card_debugfs(struct snd_soc_card *card) 459static void soc_init_card_debugfs(struct snd_soc_card *card)
457{ 460{
461 if (!snd_soc_debugfs_root)
462 return;
463
458 card->debugfs_card_root = debugfs_create_dir(card->name, 464 card->debugfs_card_root = debugfs_create_dir(card->name,
459 snd_soc_debugfs_root); 465 snd_soc_debugfs_root);
460 if (!card->debugfs_card_root) { 466 if (!card->debugfs_card_root) {
@@ -476,6 +482,34 @@ static void soc_cleanup_card_debugfs(struct snd_soc_card *card)
476 debugfs_remove_recursive(card->debugfs_card_root); 482 debugfs_remove_recursive(card->debugfs_card_root);
477} 483}
478 484
485
486static void snd_soc_debugfs_init(void)
487{
488 snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL);
489 if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) {
490 pr_warn("ASoC: Failed to create debugfs directory\n");
491 snd_soc_debugfs_root = NULL;
492 return;
493 }
494
495 if (!debugfs_create_file("codecs", 0444, snd_soc_debugfs_root, NULL,
496 &codec_list_fops))
497 pr_warn("ASoC: Failed to create CODEC list debugfs file\n");
498
499 if (!debugfs_create_file("dais", 0444, snd_soc_debugfs_root, NULL,
500 &dai_list_fops))
501 pr_warn("ASoC: Failed to create DAI list debugfs file\n");
502
503 if (!debugfs_create_file("platforms", 0444, snd_soc_debugfs_root, NULL,
504 &platform_list_fops))
505 pr_warn("ASoC: Failed to create platform list debugfs file\n");
506}
507
508static void snd_soc_debugfs_exit(void)
509{
510 debugfs_remove_recursive(snd_soc_debugfs_root);
511}
512
479#else 513#else
480 514
481#define soc_init_codec_debugfs NULL 515#define soc_init_codec_debugfs NULL
@@ -497,6 +531,15 @@ static inline void soc_init_card_debugfs(struct snd_soc_card *card)
497static inline void soc_cleanup_card_debugfs(struct snd_soc_card *card) 531static inline void soc_cleanup_card_debugfs(struct snd_soc_card *card)
498{ 532{
499} 533}
534
535static inline void snd_soc_debugfs_init(void)
536{
537}
538
539static inline void snd_soc_debugfs_exit(void)
540{
541}
542
500#endif 543#endif
501 544
502struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, 545struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
@@ -595,15 +638,9 @@ int snd_soc_suspend(struct device *dev)
595 cpu_dai->driver->suspend(cpu_dai); 638 cpu_dai->driver->suspend(cpu_dai);
596 } 639 }
597 640
598 /* close any waiting streams and save state */ 641 /* close any waiting streams */
599 for (i = 0; i < card->num_rtd; i++) { 642 for (i = 0; i < card->num_rtd; i++)
600 struct snd_soc_dai **codec_dais = card->rtd[i].codec_dais;
601 flush_delayed_work(&card->rtd[i].delayed_work); 643 flush_delayed_work(&card->rtd[i].delayed_work);
602 for (j = 0; j < card->rtd[i].num_codecs; j++) {
603 codec_dais[j]->codec->dapm.suspend_bias_level =
604 codec_dais[j]->codec->dapm.bias_level;
605 }
606 }
607 644
608 for (i = 0; i < card->num_rtd; i++) { 645 for (i = 0; i < card->num_rtd; i++) {
609 646
@@ -1261,7 +1298,8 @@ static int soc_link_dai_widgets(struct snd_soc_card *card,
1261 capture_w = cpu_dai->capture_widget; 1298 capture_w = cpu_dai->capture_widget;
1262 if (play_w && capture_w) { 1299 if (play_w && capture_w) {
1263 ret = snd_soc_dapm_new_pcm(card, dai_link->params, 1300 ret = snd_soc_dapm_new_pcm(card, dai_link->params,
1264 capture_w, play_w); 1301 dai_link->num_params, capture_w,
1302 play_w);
1265 if (ret != 0) { 1303 if (ret != 0) {
1266 dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", 1304 dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n",
1267 play_w->name, capture_w->name, ret); 1305 play_w->name, capture_w->name, ret);
@@ -1273,7 +1311,8 @@ static int soc_link_dai_widgets(struct snd_soc_card *card,
1273 capture_w = codec_dai->capture_widget; 1311 capture_w = codec_dai->capture_widget;
1274 if (play_w && capture_w) { 1312 if (play_w && capture_w) {
1275 ret = snd_soc_dapm_new_pcm(card, dai_link->params, 1313 ret = snd_soc_dapm_new_pcm(card, dai_link->params,
1276 capture_w, play_w); 1314 dai_link->num_params, capture_w,
1315 play_w);
1277 if (ret != 0) { 1316 if (ret != 0) {
1278 dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", 1317 dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n",
1279 play_w->name, capture_w->name, ret); 1318 play_w->name, capture_w->name, ret);
@@ -1322,21 +1361,17 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1322 } 1361 }
1323 } 1362 }
1324 1363
1364 if (dai_link->dai_fmt)
1365 snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt);
1366
1325 ret = soc_post_component_init(rtd, dai_link->name); 1367 ret = soc_post_component_init(rtd, dai_link->name);
1326 if (ret) 1368 if (ret)
1327 return ret; 1369 return ret;
1328 1370
1329#ifdef CONFIG_DEBUG_FS 1371#ifdef CONFIG_DEBUG_FS
1330 /* add DPCM sysfs entries */ 1372 /* add DPCM sysfs entries */
1331 if (dai_link->dynamic) { 1373 if (dai_link->dynamic)
1332 ret = soc_dpcm_debugfs_add(rtd); 1374 soc_dpcm_debugfs_add(rtd);
1333 if (ret < 0) {
1334 dev_err(rtd->dev,
1335 "ASoC: failed to add dpcm sysfs entries: %d\n",
1336 ret);
1337 return ret;
1338 }
1339 }
1340#endif 1375#endif
1341 1376
1342 if (cpu_dai->driver->compress_dai) { 1377 if (cpu_dai->driver->compress_dai) {
@@ -1426,7 +1461,6 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
1426 1461
1427 /* unregister the rtd device */ 1462 /* unregister the rtd device */
1428 if (rtd->dev_registered) { 1463 if (rtd->dev_registered) {
1429 device_remove_file(rtd->dev, &dev_attr_codec_reg);
1430 device_unregister(rtd->dev); 1464 device_unregister(rtd->dev);
1431 rtd->dev_registered = 0; 1465 rtd->dev_registered = 0;
1432 } 1466 }
@@ -1560,6 +1594,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1560 goto base_error; 1594 goto base_error;
1561 } 1595 }
1562 1596
1597 soc_init_card_debugfs(card);
1598
1563 card->dapm.bias_level = SND_SOC_BIAS_OFF; 1599 card->dapm.bias_level = SND_SOC_BIAS_OFF;
1564 card->dapm.dev = card->dev; 1600 card->dapm.dev = card->dev;
1565 card->dapm.card = card; 1601 card->dapm.card = card;
@@ -1641,12 +1677,6 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1641 snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes, 1677 snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes,
1642 card->num_of_dapm_routes); 1678 card->num_of_dapm_routes);
1643 1679
1644 for (i = 0; i < card->num_links; i++) {
1645 if (card->dai_link[i].dai_fmt)
1646 snd_soc_runtime_set_dai_fmt(&card->rtd[i],
1647 card->dai_link[i].dai_fmt);
1648 }
1649
1650 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), 1680 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
1651 "%s", card->name); 1681 "%s", card->name);
1652 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), 1682 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
@@ -1702,6 +1732,7 @@ card_probe_error:
1702 if (card->remove) 1732 if (card->remove)
1703 card->remove(card); 1733 card->remove(card);
1704 1734
1735 soc_cleanup_card_debugfs(card);
1705 snd_card_free(card->snd_card); 1736 snd_card_free(card->snd_card);
1706 1737
1707base_error: 1738base_error:
@@ -2380,8 +2411,6 @@ int snd_soc_register_card(struct snd_soc_card *card)
2380 2411
2381 snd_soc_initialize_card_lists(card); 2412 snd_soc_initialize_card_lists(card);
2382 2413
2383 soc_init_card_debugfs(card);
2384
2385 card->rtd = devm_kzalloc(card->dev, 2414 card->rtd = devm_kzalloc(card->dev,
2386 sizeof(struct snd_soc_pcm_runtime) * 2415 sizeof(struct snd_soc_pcm_runtime) *
2387 (card->num_links + card->num_aux_devs), 2416 (card->num_links + card->num_aux_devs),
@@ -2412,7 +2441,7 @@ int snd_soc_register_card(struct snd_soc_card *card)
2412 2441
2413 ret = snd_soc_instantiate_card(card); 2442 ret = snd_soc_instantiate_card(card);
2414 if (ret != 0) 2443 if (ret != 0)
2415 soc_cleanup_card_debugfs(card); 2444 return ret;
2416 2445
2417 /* deactivate pins to sleep state */ 2446 /* deactivate pins to sleep state */
2418 for (i = 0; i < card->num_rtd; i++) { 2447 for (i = 0; i < card->num_rtd; i++) {
@@ -3595,26 +3624,7 @@ EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_codecs);
3595 3624
3596static int __init snd_soc_init(void) 3625static int __init snd_soc_init(void)
3597{ 3626{
3598#ifdef CONFIG_DEBUG_FS 3627 snd_soc_debugfs_init();
3599 snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL);
3600 if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) {
3601 pr_warn("ASoC: Failed to create debugfs directory\n");
3602 snd_soc_debugfs_root = NULL;
3603 }
3604
3605 if (!debugfs_create_file("codecs", 0444, snd_soc_debugfs_root, NULL,
3606 &codec_list_fops))
3607 pr_warn("ASoC: Failed to create CODEC list debugfs file\n");
3608
3609 if (!debugfs_create_file("dais", 0444, snd_soc_debugfs_root, NULL,
3610 &dai_list_fops))
3611 pr_warn("ASoC: Failed to create DAI list debugfs file\n");
3612
3613 if (!debugfs_create_file("platforms", 0444, snd_soc_debugfs_root, NULL,
3614 &platform_list_fops))
3615 pr_warn("ASoC: Failed to create platform list debugfs file\n");
3616#endif
3617
3618 snd_soc_util_init(); 3628 snd_soc_util_init();
3619 3629
3620 return platform_driver_register(&soc_driver); 3630 return platform_driver_register(&soc_driver);
@@ -3624,9 +3634,9 @@ module_init(snd_soc_init);
3624static void __exit snd_soc_exit(void) 3634static void __exit snd_soc_exit(void)
3625{ 3635{
3626 snd_soc_util_exit(); 3636 snd_soc_util_exit();
3637 snd_soc_debugfs_exit();
3627 3638
3628#ifdef CONFIG_DEBUG_FS 3639#ifdef CONFIG_DEBUG_FS
3629 debugfs_remove_recursive(snd_soc_debugfs_root);
3630#endif 3640#endif
3631 platform_driver_unregister(&soc_driver); 3641 platform_driver_unregister(&soc_driver);
3632} 3642}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index b6f88202b8c9..defe0f0082b5 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -473,16 +473,6 @@ struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
473} 473}
474EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_dapm); 474EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_dapm);
475 475
476/**
477 * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
478 * @kcontrol: The kcontrol
479 */
480struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(struct snd_kcontrol *kcontrol)
481{
482 return snd_soc_dapm_to_codec(snd_soc_dapm_kcontrol_dapm(kcontrol));
483}
484EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_codec);
485
486static void dapm_reset(struct snd_soc_card *card) 476static void dapm_reset(struct snd_soc_card *card)
487{ 477{
488 struct snd_soc_dapm_widget *w; 478 struct snd_soc_dapm_widget *w;
@@ -853,6 +843,36 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w)
853 return 0; 843 return 0;
854} 844}
855 845
846/* create new dapm dai link control */
847static int dapm_new_dai_link(struct snd_soc_dapm_widget *w)
848{
849 int i, ret;
850 struct snd_kcontrol *kcontrol;
851 struct snd_soc_dapm_context *dapm = w->dapm;
852 struct snd_card *card = dapm->card->snd_card;
853
854 /* create control for links with > 1 config */
855 if (w->num_params <= 1)
856 return 0;
857
858 /* add kcontrol */
859 for (i = 0; i < w->num_kcontrols; i++) {
860 kcontrol = snd_soc_cnew(&w->kcontrol_news[i], w,
861 w->name, NULL);
862 ret = snd_ctl_add(card, kcontrol);
863 if (ret < 0) {
864 dev_err(dapm->dev,
865 "ASoC: failed to add widget %s dapm kcontrol %s: %d\n",
866 w->name, w->kcontrol_news[i].name, ret);
867 return ret;
868 }
869 kcontrol->private_data = w;
870 w->kcontrols[i] = kcontrol;
871 }
872
873 return 0;
874}
875
856/* We implement power down on suspend by checking the power state of 876/* We implement power down on suspend by checking the power state of
857 * the ALSA card - when we are suspending the ALSA state for the card 877 * the ALSA card - when we are suspending the ALSA state for the card
858 * is set to D3. 878 * is set to D3.
@@ -1898,6 +1918,9 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
1898{ 1918{
1899 struct dentry *d; 1919 struct dentry *d;
1900 1920
1921 if (!parent)
1922 return;
1923
1901 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent); 1924 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent);
1902 1925
1903 if (!dapm->debugfs_dapm) { 1926 if (!dapm->debugfs_dapm) {
@@ -2719,6 +2742,9 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card)
2719 case snd_soc_dapm_out_drv: 2742 case snd_soc_dapm_out_drv:
2720 dapm_new_pga(w); 2743 dapm_new_pga(w);
2721 break; 2744 break;
2745 case snd_soc_dapm_dai_link:
2746 dapm_new_dai_link(w);
2747 break;
2722 default: 2748 default:
2723 break; 2749 break;
2724 } 2750 }
@@ -3193,7 +3219,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
3193{ 3219{
3194 struct snd_soc_dapm_path *source_p, *sink_p; 3220 struct snd_soc_dapm_path *source_p, *sink_p;
3195 struct snd_soc_dai *source, *sink; 3221 struct snd_soc_dai *source, *sink;
3196 const struct snd_soc_pcm_stream *config = w->params; 3222 const struct snd_soc_pcm_stream *config = w->params + w->params_select;
3197 struct snd_pcm_substream substream; 3223 struct snd_pcm_substream substream;
3198 struct snd_pcm_hw_params *params = NULL; 3224 struct snd_pcm_hw_params *params = NULL;
3199 u64 fmt; 3225 u64 fmt;
@@ -3285,22 +3311,97 @@ out:
3285 return ret; 3311 return ret;
3286} 3312}
3287 3313
3314static int snd_soc_dapm_dai_link_get(struct snd_kcontrol *kcontrol,
3315 struct snd_ctl_elem_value *ucontrol)
3316{
3317 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
3318
3319 ucontrol->value.integer.value[0] = w->params_select;
3320
3321 return 0;
3322}
3323
3324static int snd_soc_dapm_dai_link_put(struct snd_kcontrol *kcontrol,
3325 struct snd_ctl_elem_value *ucontrol)
3326{
3327 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
3328
3329 /* Can't change the config when widget is already powered */
3330 if (w->power)
3331 return -EBUSY;
3332
3333 if (ucontrol->value.integer.value[0] == w->params_select)
3334 return 0;
3335
3336 if (ucontrol->value.integer.value[0] >= w->num_params)
3337 return -EINVAL;
3338
3339 w->params_select = ucontrol->value.integer.value[0];
3340
3341 return 0;
3342}
3343
3288int snd_soc_dapm_new_pcm(struct snd_soc_card *card, 3344int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
3289 const struct snd_soc_pcm_stream *params, 3345 const struct snd_soc_pcm_stream *params,
3346 unsigned int num_params,
3290 struct snd_soc_dapm_widget *source, 3347 struct snd_soc_dapm_widget *source,
3291 struct snd_soc_dapm_widget *sink) 3348 struct snd_soc_dapm_widget *sink)
3292{ 3349{
3293 struct snd_soc_dapm_widget template; 3350 struct snd_soc_dapm_widget template;
3294 struct snd_soc_dapm_widget *w; 3351 struct snd_soc_dapm_widget *w;
3295 size_t len;
3296 char *link_name; 3352 char *link_name;
3297 int ret; 3353 int ret, count;
3298 3354 unsigned long private_value;
3299 len = strlen(source->name) + strlen(sink->name) + 2; 3355 const char **w_param_text;
3300 link_name = devm_kzalloc(card->dev, len, GFP_KERNEL); 3356 struct soc_enum w_param_enum[] = {
3301 if (!link_name) 3357 SOC_ENUM_SINGLE(0, 0, 0, NULL),
3358 };
3359 struct snd_kcontrol_new kcontrol_dai_link[] = {
3360 SOC_ENUM_EXT(NULL, w_param_enum[0],
3361 snd_soc_dapm_dai_link_get,
3362 snd_soc_dapm_dai_link_put),
3363 };
3364 const struct snd_soc_pcm_stream *config = params;
3365
3366 w_param_text = devm_kcalloc(card->dev, num_params,
3367 sizeof(char *), GFP_KERNEL);
3368 if (!w_param_text)
3302 return -ENOMEM; 3369 return -ENOMEM;
3303 snprintf(link_name, len, "%s-%s", source->name, sink->name); 3370
3371 link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s",
3372 source->name, sink->name);
3373 if (!link_name) {
3374 ret = -ENOMEM;
3375 goto outfree_w_param;
3376 }
3377
3378 for (count = 0 ; count < num_params; count++) {
3379 if (!config->stream_name) {
3380 dev_warn(card->dapm.dev,
3381 "ASoC: anonymous config %d for dai link %s\n",
3382 count, link_name);
3383 w_param_text[count] =
3384 devm_kasprintf(card->dev, GFP_KERNEL,
3385 "Anonymous Configuration %d",
3386 count);
3387 if (!w_param_text[count]) {
3388 ret = -ENOMEM;
3389 goto outfree_link_name;
3390 }
3391 } else {
3392 w_param_text[count] = devm_kmemdup(card->dev,
3393 config->stream_name,
3394 strlen(config->stream_name) + 1,
3395 GFP_KERNEL);
3396 if (!w_param_text[count]) {
3397 ret = -ENOMEM;
3398 goto outfree_link_name;
3399 }
3400 }
3401 config++;
3402 }
3403 w_param_enum[0].items = num_params;
3404 w_param_enum[0].texts = w_param_text;
3304 3405
3305 memset(&template, 0, sizeof(template)); 3406 memset(&template, 0, sizeof(template));
3306 template.reg = SND_SOC_NOPM; 3407 template.reg = SND_SOC_NOPM;
@@ -3309,6 +3410,30 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
3309 template.event = snd_soc_dai_link_event; 3410 template.event = snd_soc_dai_link_event;
3310 template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3411 template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3311 SND_SOC_DAPM_PRE_PMD; 3412 SND_SOC_DAPM_PRE_PMD;
3413 template.num_kcontrols = 1;
3414 /* duplicate w_param_enum on heap so that memory persists */
3415 private_value =
3416 (unsigned long) devm_kmemdup(card->dev,
3417 (void *)(kcontrol_dai_link[0].private_value),
3418 sizeof(struct soc_enum), GFP_KERNEL);
3419 if (!private_value) {
3420 dev_err(card->dev, "ASoC: Failed to create control for %s widget\n",
3421 link_name);
3422 ret = -ENOMEM;
3423 goto outfree_link_name;
3424 }
3425 kcontrol_dai_link[0].private_value = private_value;
3426 /* duplicate kcontrol_dai_link on heap so that memory persists */
3427 template.kcontrol_news =
3428 devm_kmemdup(card->dev, &kcontrol_dai_link[0],
3429 sizeof(struct snd_kcontrol_new),
3430 GFP_KERNEL);
3431 if (!template.kcontrol_news) {
3432 dev_err(card->dev, "ASoC: Failed to create control for %s widget\n",
3433 link_name);
3434 ret = -ENOMEM;
3435 goto outfree_private_value;
3436 }
3312 3437
3313 dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name); 3438 dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name);
3314 3439
@@ -3316,15 +3441,32 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
3316 if (!w) { 3441 if (!w) {
3317 dev_err(card->dev, "ASoC: Failed to create %s widget\n", 3442 dev_err(card->dev, "ASoC: Failed to create %s widget\n",
3318 link_name); 3443 link_name);
3319 return -ENOMEM; 3444 ret = -ENOMEM;
3445 goto outfree_kcontrol_news;
3320 } 3446 }
3321 3447
3322 w->params = params; 3448 w->params = params;
3449 w->num_params = num_params;
3323 3450
3324 ret = snd_soc_dapm_add_path(&card->dapm, source, w, NULL, NULL); 3451 ret = snd_soc_dapm_add_path(&card->dapm, source, w, NULL, NULL);
3325 if (ret) 3452 if (ret)
3326 return ret; 3453 goto outfree_w;
3327 return snd_soc_dapm_add_path(&card->dapm, w, sink, NULL, NULL); 3454 return snd_soc_dapm_add_path(&card->dapm, w, sink, NULL, NULL);
3455
3456outfree_w:
3457 devm_kfree(card->dev, w);
3458outfree_kcontrol_news:
3459 devm_kfree(card->dev, (void *)template.kcontrol_news);
3460outfree_private_value:
3461 devm_kfree(card->dev, (void *)private_value);
3462outfree_link_name:
3463 devm_kfree(card->dev, link_name);
3464outfree_w_param:
3465 for (count = 0 ; count < num_params; count++)
3466 devm_kfree(card->dev, (void *)w_param_text[count]);
3467 devm_kfree(card->dev, w_param_text);
3468
3469 return ret;
3328} 3470}
3329 3471
3330int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, 3472int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 6e3781e88f9a..35fe58f4fa86 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1097,8 +1097,9 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
1097 stream ? "<-" : "->", be->dai_link->name); 1097 stream ? "<-" : "->", be->dai_link->name);
1098 1098
1099#ifdef CONFIG_DEBUG_FS 1099#ifdef CONFIG_DEBUG_FS
1100 dpcm->debugfs_state = debugfs_create_u32(be->dai_link->name, 0644, 1100 if (fe->debugfs_dpcm_root)
1101 fe->debugfs_dpcm_root, &dpcm->state); 1101 dpcm->debugfs_state = debugfs_create_u32(be->dai_link->name, 0644,
1102 fe->debugfs_dpcm_root, &dpcm->state);
1102#endif 1103#endif
1103 return 1; 1104 return 1;
1104} 1105}
@@ -2803,10 +2804,13 @@ static const struct file_operations dpcm_state_fops = {
2803 .llseek = default_llseek, 2804 .llseek = default_llseek,
2804}; 2805};
2805 2806
2806int soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd) 2807void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd)
2807{ 2808{
2808 if (!rtd->dai_link) 2809 if (!rtd->dai_link)
2809 return 0; 2810 return;
2811
2812 if (!rtd->card->debugfs_card_root)
2813 return;
2810 2814
2811 rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name, 2815 rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name,
2812 rtd->card->debugfs_card_root); 2816 rtd->card->debugfs_card_root);
@@ -2814,13 +2818,11 @@ int soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd)
2814 dev_dbg(rtd->dev, 2818 dev_dbg(rtd->dev,
2815 "ASoC: Failed to create dpcm debugfs directory %s\n", 2819 "ASoC: Failed to create dpcm debugfs directory %s\n",
2816 rtd->dai_link->name); 2820 rtd->dai_link->name);
2817 return -EINVAL; 2821 return;
2818 } 2822 }
2819 2823
2820 rtd->debugfs_dpcm_state = debugfs_create_file("state", 0444, 2824 rtd->debugfs_dpcm_state = debugfs_create_file("state", 0444,
2821 rtd->debugfs_dpcm_root, 2825 rtd->debugfs_dpcm_root,
2822 rtd, &dpcm_state_fops); 2826 rtd, &dpcm_state_fops);
2823
2824 return 0;
2825} 2827}
2826#endif 2828#endif
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index 6dcd06a966c7..ba272e21a6fa 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -101,9 +101,6 @@ static const struct snd_kcontrol_new tegra_alc5632_controls[] = {
101 101
102static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) 102static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
103{ 103{
104 struct snd_soc_dai *codec_dai = rtd->codec_dai;
105 struct snd_soc_codec *codec = codec_dai->codec;
106 struct snd_soc_dapm_context *dapm = &codec->dapm;
107 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(rtd->card); 104 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(rtd->card);
108 105
109 snd_soc_card_jack_new(rtd->card, "Headset Jack", SND_JACK_HEADSET, 106 snd_soc_card_jack_new(rtd->card, "Headset Jack", SND_JACK_HEADSET,
@@ -118,7 +115,7 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
118 &tegra_alc5632_hp_jack_gpio); 115 &tegra_alc5632_hp_jack_gpio);
119 } 116 }
120 117
121 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); 118 snd_soc_dapm_force_enable_pin(&rtd->card->dapm, "MICBIAS1");
122 119
123 return 0; 120 return 0;
124} 121}
diff --git a/sound/soc/tegra/tegra_rt5677.c b/sound/soc/tegra/tegra_rt5677.c
index 68d8b67e79c1..1470873ecde6 100644
--- a/sound/soc/tegra/tegra_rt5677.c
+++ b/sound/soc/tegra/tegra_rt5677.c
@@ -141,9 +141,6 @@ static const struct snd_kcontrol_new tegra_rt5677_controls[] = {
141 141
142static int tegra_rt5677_asoc_init(struct snd_soc_pcm_runtime *rtd) 142static int tegra_rt5677_asoc_init(struct snd_soc_pcm_runtime *rtd)
143{ 143{
144 struct snd_soc_dai *codec_dai = rtd->codec_dai;
145 struct snd_soc_codec *codec = codec_dai->codec;
146 struct snd_soc_dapm_context *dapm = &codec->dapm;
147 struct tegra_rt5677 *machine = snd_soc_card_get_drvdata(rtd->card); 144 struct tegra_rt5677 *machine = snd_soc_card_get_drvdata(rtd->card);
148 145
149 snd_soc_card_jack_new(rtd->card, "Headphone Jack", SND_JACK_HEADPHONE, 146 snd_soc_card_jack_new(rtd->card, "Headphone Jack", SND_JACK_HEADPHONE,
@@ -167,7 +164,7 @@ static int tegra_rt5677_asoc_init(struct snd_soc_pcm_runtime *rtd)
167 &tegra_rt5677_mic_jack_gpio); 164 &tegra_rt5677_mic_jack_gpio);
168 } 165 }
169 166
170 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); 167 snd_soc_dapm_force_enable_pin(&rtd->card->dapm, "MICBIAS1");
171 168
172 return 0; 169 return 0;
173} 170}
@@ -329,7 +326,6 @@ static const struct of_device_id tegra_rt5677_of_match[] = {
329static struct platform_driver tegra_rt5677_driver = { 326static struct platform_driver tegra_rt5677_driver = {
330 .driver = { 327 .driver = {
331 .name = DRV_NAME, 328 .name = DRV_NAME,
332 .owner = THIS_MODULE,
333 .pm = &snd_soc_pm_ops, 329 .pm = &snd_soc_pm_ops,
334 .of_match_table = tegra_rt5677_of_match, 330 .of_match_table = tegra_rt5677_of_match,
335 }, 331 },
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index 4a95b70f0cf0..21604009bc1a 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -171,7 +171,6 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
171{ 171{
172 struct snd_soc_dai *codec_dai = rtd->codec_dai; 172 struct snd_soc_dai *codec_dai = rtd->codec_dai;
173 struct snd_soc_codec *codec = codec_dai->codec; 173 struct snd_soc_codec *codec = codec_dai->codec;
174 struct snd_soc_dapm_context *dapm = &codec->dapm;
175 struct snd_soc_card *card = rtd->card; 174 struct snd_soc_card *card = rtd->card;
176 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 175 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
177 176
@@ -193,7 +192,7 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
193 wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE, 192 wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE,
194 0); 193 0);
195 194
196 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS"); 195 snd_soc_dapm_force_enable_pin(&card->dapm, "MICBIAS");
197 196
198 return 0; 197 return 0;
199} 198}
diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c
index 2868b4839bc0..6492f8143ff1 100644
--- a/sound/soc/tegra/tegra_wm9712.c
+++ b/sound/soc/tegra/tegra_wm9712.c
@@ -46,11 +46,7 @@ static const struct snd_soc_dapm_widget tegra_wm9712_dapm_widgets[] = {
46 46
47static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd) 47static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd)
48{ 48{
49 struct snd_soc_dai *codec_dai = rtd->codec_dai; 49 return snd_soc_dapm_force_enable_pin(&rtd->card->dapm, "Mic Bias");
50 struct snd_soc_codec *codec = codec_dai->codec;
51 struct snd_soc_dapm_context *dapm = &codec->dapm;
52
53 return snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
54} 50}
55 51
56static struct snd_soc_dai_link tegra_wm9712_dai = { 52static struct snd_soc_dai_link tegra_wm9712_dai = {
diff --git a/sound/soc/ux500/mop500_ab8500.c b/sound/soc/ux500/mop500_ab8500.c
index aa65370db82a..b81a7a4c938b 100644
--- a/sound/soc/ux500/mop500_ab8500.c
+++ b/sound/soc/ux500/mop500_ab8500.c
@@ -362,7 +362,7 @@ struct snd_soc_ops mop500_ab8500_ops[] = {
362 362
363int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd) 363int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd)
364{ 364{
365 struct snd_soc_codec *codec = rtd->codec; 365 struct snd_soc_dapm_context *dapm = &rtd->card->dapm;
366 struct device *dev = rtd->card->dev; 366 struct device *dev = rtd->card->dev;
367 struct mop500_ab8500_drvdata *drvdata; 367 struct mop500_ab8500_drvdata *drvdata;
368 int ret; 368 int ret;
@@ -407,23 +407,23 @@ int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd)
407 return ret; 407 return ret;
408 } 408 }
409 409
410 ret = snd_soc_dapm_disable_pin(&codec->dapm, "Earpiece"); 410 ret = snd_soc_dapm_disable_pin(dapm, "Earpiece");
411 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Speaker Left"); 411 ret |= snd_soc_dapm_disable_pin(dapm, "Speaker Left");
412 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Speaker Right"); 412 ret |= snd_soc_dapm_disable_pin(dapm, "Speaker Right");
413 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineOut Left"); 413 ret |= snd_soc_dapm_disable_pin(dapm, "LineOut Left");
414 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineOut Right"); 414 ret |= snd_soc_dapm_disable_pin(dapm, "LineOut Right");
415 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Vibra 1"); 415 ret |= snd_soc_dapm_disable_pin(dapm, "Vibra 1");
416 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Vibra 2"); 416 ret |= snd_soc_dapm_disable_pin(dapm, "Vibra 2");
417 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Mic 1"); 417 ret |= snd_soc_dapm_disable_pin(dapm, "Mic 1");
418 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Mic 2"); 418 ret |= snd_soc_dapm_disable_pin(dapm, "Mic 2");
419 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineIn Left"); 419 ret |= snd_soc_dapm_disable_pin(dapm, "LineIn Left");
420 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineIn Right"); 420 ret |= snd_soc_dapm_disable_pin(dapm, "LineIn Right");
421 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 1"); 421 ret |= snd_soc_dapm_disable_pin(dapm, "DMic 1");
422 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 2"); 422 ret |= snd_soc_dapm_disable_pin(dapm, "DMic 2");
423 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 3"); 423 ret |= snd_soc_dapm_disable_pin(dapm, "DMic 3");
424 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 4"); 424 ret |= snd_soc_dapm_disable_pin(dapm, "DMic 4");
425 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 5"); 425 ret |= snd_soc_dapm_disable_pin(dapm, "DMic 5");
426 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 6"); 426 ret |= snd_soc_dapm_disable_pin(dapm, "DMic 6");
427 427
428 return ret; 428 return ret;
429} 429}