summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2018-12-18 08:59:56 -0500
committerTakashi Iwai <tiwai@suse.de>2018-12-18 08:59:56 -0500
commited49e839199e73966b9ff5946c3e87759827b40e (patch)
treedd1e6c755b2f6e747b99af9123e045b513553623 /sound
parent40906ebe3af6a48457151b3c6726b480f6a6cb13 (diff)
parenta7a850dba82498a1e050d8d153cae67ce0edb3b2 (diff)
Merge tag 'asoc-v4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next
ASoC: Updates for v4.21 Not much work on the core this time around but we've seen quite a bit of driver work, including on the generic DT drivers. There's also a large part of the diff from a merge of the DaVinci and OMAP directories, along with some active development there: - Preparatory work from Morimoto-san for merging the audio-graph and audio-graph-scu cards. - A merge of the TI OMAP and DaVinci directories, the OMAP product line has been merged into the DaVinci product line so there is now a lot of IP sharing which meant that the split directories just got in the way. This has pulled in a few architecture changes as well. - A big cleanup of the Maxim MAX9867 driver from Ladislav Michl. - Support for Asahi Kaesi AKM4118, AMD ACP3x, Intel platforms with RT5660, Meson AXG S/PDIF inputs, several Qualcomm IPs and Xilinx I2S controllers.
Diffstat (limited to 'sound')
-rw-r--r--sound/core/compress_offload.c18
-rw-r--r--sound/soc/Kconfig4
-rw-r--r--sound/soc/Makefile4
-rw-r--r--sound/soc/amd/Kconfig6
-rw-r--r--sound/soc/amd/Makefile1
-rw-r--r--sound/soc/amd/acp-da7219-max98357a.c2
-rw-r--r--sound/soc/amd/acp-pcm-dma.c22
-rw-r--r--sound/soc/amd/acp.h2
-rw-r--r--sound/soc/amd/raven/Makefile6
-rw-r--r--sound/soc/amd/raven/acp3x-pcm-dma.c777
-rw-r--r--sound/soc/amd/raven/acp3x.h58
-rw-r--r--sound/soc/amd/raven/chip_offset_byte.h639
-rw-r--r--sound/soc/amd/raven/pci-acp3x.c156
-rw-r--r--sound/soc/codecs/Kconfig6
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/ak4104.c22
-rw-r--r--sound/soc/codecs/ak4118.c438
-rw-r--r--sound/soc/codecs/ak4458.c2
-rw-r--r--sound/soc/codecs/ak5558.c19
-rw-r--r--sound/soc/codecs/cs4270.c23
-rw-r--r--sound/soc/codecs/dmic.c40
-rw-r--r--sound/soc/codecs/hdac_hda.c2
-rw-r--r--sound/soc/codecs/hdac_hdmi.c63
-rw-r--r--sound/soc/codecs/max98373.c35
-rw-r--r--sound/soc/codecs/max9867.c505
-rw-r--r--sound/soc/codecs/max9867.h41
-rw-r--r--sound/soc/codecs/nau8540.c2
-rw-r--r--sound/soc/codecs/nau8822.c26
-rw-r--r--sound/soc/codecs/nau8822.h9
-rw-r--r--sound/soc/codecs/nau8825.c4
-rw-r--r--sound/soc/codecs/pcm3060.c28
-rw-r--r--sound/soc/codecs/pcm3060.h3
-rw-r--r--sound/soc/codecs/pcm3168a.c40
-rw-r--r--sound/soc/codecs/pcm512x.c121
-rw-r--r--sound/soc/codecs/pcm512x.h2
-rw-r--r--sound/soc/codecs/rt5660.c1
-rw-r--r--sound/soc/codecs/rt5663.c75
-rw-r--r--sound/soc/codecs/simple-amplifier.c4
-rw-r--r--sound/soc/codecs/tas6424.c2
-rw-r--r--sound/soc/codecs/tlv320aic31xx.c2
-rw-r--r--sound/soc/codecs/tlv320aic3x.c10
-rw-r--r--sound/soc/codecs/tlv320dac33.c2
-rw-r--r--sound/soc/codecs/wm8998.c2
-rw-r--r--sound/soc/codecs/wm9705.c10
-rw-r--r--sound/soc/codecs/wm9712.c10
-rw-r--r--sound/soc/codecs/wm9713.c10
-rw-r--r--sound/soc/codecs/wm_adsp.c14
-rw-r--r--sound/soc/davinci/Kconfig106
-rw-r--r--sound/soc/davinci/Makefile16
-rw-r--r--sound/soc/fsl/Kconfig2
-rw-r--r--sound/soc/fsl/fsl-asoc-card.c6
-rw-r--r--sound/soc/fsl/fsl_ssi_dbg.c14
-rw-r--r--sound/soc/generic/Kconfig4
-rw-r--r--sound/soc/generic/audio-graph-card.c465
-rw-r--r--sound/soc/generic/audio-graph-scu-card.c262
-rw-r--r--sound/soc/generic/simple-card-utils.c45
-rw-r--r--sound/soc/generic/simple-card.c402
-rw-r--r--sound/soc/generic/simple-scu-card.c264
-rw-r--r--sound/soc/intel/Kconfig73
-rw-r--r--sound/soc/intel/atom/sst/sst_acpi.c4
-rw-r--r--sound/soc/intel/atom/sst/sst_loader.c8
-rw-r--r--sound/soc/intel/atom/sst/sst_pvt.c4
-rw-r--r--sound/soc/intel/boards/Kconfig26
-rw-r--r--sound/soc/intel/boards/Makefile2
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c33
-rw-r--r--sound/soc/intel/boards/bytcr_rt5651.c6
-rw-r--r--sound/soc/intel/boards/cht_bsw_max98090_ti.c14
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5645.c6
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5672.c2
-rw-r--r--sound/soc/intel/boards/glk_rt5682_max98357a.c2
-rw-r--r--sound/soc/intel/boards/kbl_da7219_max98927.c14
-rw-r--r--sound/soc/intel/boards/kbl_rt5660.c543
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_max98927.c14
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c10
-rw-r--r--sound/soc/intel/boards/skl_hda_dsp_generic.c22
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_max98357a.c14
-rw-r--r--sound/soc/intel/boards/skl_nau88l25_ssm4567.c14
-rw-r--r--sound/soc/intel/common/Makefile2
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-bxt-match.c36
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-icl-match.c32
-rw-r--r--sound/soc/intel/common/soc-acpi-intel-kbl-match.c10
-rw-r--r--sound/soc/intel/skylake/skl-messages.c8
-rw-r--r--sound/soc/intel/skylake/skl-nhlt.c3
-rw-r--r--sound/soc/intel/skylake/skl-sst-ipc.c50
-rw-r--r--sound/soc/intel/skylake/skl.c144
-rw-r--r--sound/soc/intel/skylake/skl.h3
-rw-r--r--sound/soc/mediatek/mt6797/mt6797-afe-pcm.c2
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-afe-pcm.c2
-rw-r--r--sound/soc/meson/Kconfig9
-rw-r--r--sound/soc/meson/Makefile2
-rw-r--r--sound/soc/meson/axg-fifo.h3
-rw-r--r--sound/soc/meson/axg-spdifin.c521
-rw-r--r--sound/soc/meson/axg-toddr.c15
-rw-r--r--sound/soc/omap/Kconfig129
-rw-r--r--sound/soc/omap/Makefile32
-rw-r--r--sound/soc/omap/am3517evm.c141
-rw-r--r--sound/soc/omap/mcbsp.c1104
-rw-r--r--sound/soc/pxa/Kconfig26
-rw-r--r--sound/soc/pxa/Makefile1
-rw-r--r--sound/soc/pxa/raumfeld.c318
-rw-r--r--sound/soc/qcom/Kconfig2
-rw-r--r--sound/soc/qcom/lpass-platform.c2
-rw-r--r--sound/soc/qcom/qdsp6/q6afe-dai.c30
-rw-r--r--sound/soc/qcom/qdsp6/q6afe.c4
-rw-r--r--sound/soc/qcom/qdsp6/q6asm-dai.c372
-rw-r--r--sound/soc/qcom/qdsp6/q6asm.c5
-rw-r--r--sound/soc/qcom/qdsp6/q6routing.c9
-rw-r--r--sound/soc/qcom/sdm845.c186
-rw-r--r--sound/soc/sh/rcar/adg.c38
-rw-r--r--sound/soc/sh/rcar/cmd.c11
-rw-r--r--sound/soc/sh/rcar/core.c256
-rw-r--r--sound/soc/sh/rcar/ctu.c138
-rw-r--r--sound/soc/sh/rcar/dma.c84
-rw-r--r--sound/soc/sh/rcar/dvc.c21
-rw-r--r--sound/soc/sh/rcar/gen.c49
-rw-r--r--sound/soc/sh/rcar/mix.c3
-rw-r--r--sound/soc/sh/rcar/rsnd.h382
-rw-r--r--sound/soc/sh/rcar/src.c67
-rw-r--r--sound/soc/sh/rcar/ssi.c269
-rw-r--r--sound/soc/sh/rcar/ssiu.c300
-rw-r--r--sound/soc/soc-core.c13
-rw-r--r--sound/soc/stm/stm32_sai.c8
-rw-r--r--sound/soc/stm/stm32_sai_sub.c3
-rw-r--r--sound/soc/sunxi/sun50i-codec-analog.c2
-rw-r--r--sound/soc/ti/Kconfig209
-rw-r--r--sound/soc/ti/Makefile44
-rw-r--r--sound/soc/ti/ams-delta.c (renamed from sound/soc/omap/ams-delta.c)0
-rw-r--r--sound/soc/ti/davinci-evm.c (renamed from sound/soc/davinci/davinci-evm.c)4
-rw-r--r--sound/soc/ti/davinci-i2s.c (renamed from sound/soc/davinci/davinci-i2s.c)0
-rw-r--r--sound/soc/ti/davinci-i2s.h (renamed from sound/soc/davinci/davinci-i2s.h)0
-rw-r--r--sound/soc/ti/davinci-mcasp.c (renamed from sound/soc/davinci/davinci-mcasp.c)123
-rw-r--r--sound/soc/ti/davinci-mcasp.h (renamed from sound/soc/davinci/davinci-mcasp.h)30
-rw-r--r--sound/soc/ti/davinci-vcif.c (renamed from sound/soc/davinci/davinci-vcif.c)0
-rw-r--r--sound/soc/ti/edma-pcm.c (renamed from sound/soc/davinci/edma-pcm.c)0
-rw-r--r--sound/soc/ti/edma-pcm.h (renamed from sound/soc/davinci/edma-pcm.h)4
-rw-r--r--sound/soc/ti/n810.c (renamed from sound/soc/omap/n810.c)0
-rw-r--r--sound/soc/ti/omap-abe-twl6040.c (renamed from sound/soc/omap/omap-abe-twl6040.c)0
-rw-r--r--sound/soc/ti/omap-dmic.c (renamed from sound/soc/omap/omap-dmic.c)0
-rw-r--r--sound/soc/ti/omap-dmic.h (renamed from sound/soc/omap/omap-dmic.h)0
-rw-r--r--sound/soc/ti/omap-hdmi.c (renamed from sound/soc/omap/omap-hdmi-audio.c)0
-rw-r--r--sound/soc/ti/omap-mcbsp-priv.h (renamed from sound/soc/omap/mcbsp.h)126
-rw-r--r--sound/soc/ti/omap-mcbsp-st.c516
-rw-r--r--sound/soc/ti/omap-mcbsp.c (renamed from sound/soc/omap/omap-mcbsp.c)857
-rw-r--r--sound/soc/ti/omap-mcbsp.h (renamed from sound/soc/omap/omap-mcbsp.h)8
-rw-r--r--sound/soc/ti/omap-mcpdm.c (renamed from sound/soc/omap/omap-mcpdm.c)0
-rw-r--r--sound/soc/ti/omap-mcpdm.h (renamed from sound/soc/omap/omap-mcpdm.h)0
-rw-r--r--sound/soc/ti/omap-twl4030.c (renamed from sound/soc/omap/omap-twl4030.c)0
-rw-r--r--sound/soc/ti/omap3pandora.c (renamed from sound/soc/omap/omap3pandora.c)0
-rw-r--r--sound/soc/ti/osk5912.c (renamed from sound/soc/omap/osk5912.c)0
-rw-r--r--sound/soc/ti/rx51.c (renamed from sound/soc/omap/rx51.c)0
-rw-r--r--sound/soc/ti/sdma-pcm.c (renamed from sound/soc/omap/sdma-pcm.c)0
-rw-r--r--sound/soc/ti/sdma-pcm.h (renamed from sound/soc/omap/sdma-pcm.h)4
-rw-r--r--sound/soc/xilinx/Kconfig8
-rw-r--r--sound/soc/xilinx/Makefile2
-rw-r--r--sound/soc/xilinx/xlnx_i2s.c185
155 files changed, 8807 insertions, 3827 deletions
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index 26b5e245b074..a5b09e75e787 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -171,7 +171,8 @@ static int snd_compr_free(struct inode *inode, struct file *f)
171 } 171 }
172 172
173 data->stream.ops->free(&data->stream); 173 data->stream.ops->free(&data->stream);
174 kfree(data->stream.runtime->buffer); 174 if (!data->stream.runtime->dma_buffer_p)
175 kfree(data->stream.runtime->buffer);
175 kfree(data->stream.runtime); 176 kfree(data->stream.runtime);
176 kfree(data); 177 kfree(data);
177 return 0; 178 return 0;
@@ -505,7 +506,7 @@ static int snd_compr_allocate_buffer(struct snd_compr_stream *stream,
505 struct snd_compr_params *params) 506 struct snd_compr_params *params)
506{ 507{
507 unsigned int buffer_size; 508 unsigned int buffer_size;
508 void *buffer; 509 void *buffer = NULL;
509 510
510 buffer_size = params->buffer.fragment_size * params->buffer.fragments; 511 buffer_size = params->buffer.fragment_size * params->buffer.fragments;
511 if (stream->ops->copy) { 512 if (stream->ops->copy) {
@@ -514,7 +515,18 @@ static int snd_compr_allocate_buffer(struct snd_compr_stream *stream,
514 * the data from core 515 * the data from core
515 */ 516 */
516 } else { 517 } else {
517 buffer = kmalloc(buffer_size, GFP_KERNEL); 518 if (stream->runtime->dma_buffer_p) {
519
520 if (buffer_size > stream->runtime->dma_buffer_p->bytes)
521 dev_err(&stream->device->dev,
522 "Not enough DMA buffer");
523 else
524 buffer = stream->runtime->dma_buffer_p->area;
525
526 } else {
527 buffer = kmalloc(buffer_size, GFP_KERNEL);
528 }
529
518 if (!buffer) 530 if (!buffer)
519 return -ENOMEM; 531 return -ENOMEM;
520 } 532 }
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 1cf11cf51e1d..6592a422a047 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -46,13 +46,11 @@ source "sound/soc/atmel/Kconfig"
46source "sound/soc/au1x/Kconfig" 46source "sound/soc/au1x/Kconfig"
47source "sound/soc/bcm/Kconfig" 47source "sound/soc/bcm/Kconfig"
48source "sound/soc/cirrus/Kconfig" 48source "sound/soc/cirrus/Kconfig"
49source "sound/soc/davinci/Kconfig"
50source "sound/soc/dwc/Kconfig" 49source "sound/soc/dwc/Kconfig"
51source "sound/soc/fsl/Kconfig" 50source "sound/soc/fsl/Kconfig"
52source "sound/soc/hisilicon/Kconfig" 51source "sound/soc/hisilicon/Kconfig"
53source "sound/soc/jz4740/Kconfig" 52source "sound/soc/jz4740/Kconfig"
54source "sound/soc/nuc900/Kconfig" 53source "sound/soc/nuc900/Kconfig"
55source "sound/soc/omap/Kconfig"
56source "sound/soc/kirkwood/Kconfig" 54source "sound/soc/kirkwood/Kconfig"
57source "sound/soc/img/Kconfig" 55source "sound/soc/img/Kconfig"
58source "sound/soc/intel/Kconfig" 56source "sound/soc/intel/Kconfig"
@@ -70,9 +68,11 @@ source "sound/soc/sti/Kconfig"
70source "sound/soc/stm/Kconfig" 68source "sound/soc/stm/Kconfig"
71source "sound/soc/sunxi/Kconfig" 69source "sound/soc/sunxi/Kconfig"
72source "sound/soc/tegra/Kconfig" 70source "sound/soc/tegra/Kconfig"
71source "sound/soc/ti/Kconfig"
73source "sound/soc/txx9/Kconfig" 72source "sound/soc/txx9/Kconfig"
74source "sound/soc/uniphier/Kconfig" 73source "sound/soc/uniphier/Kconfig"
75source "sound/soc/ux500/Kconfig" 74source "sound/soc/ux500/Kconfig"
75source "sound/soc/xilinx/Kconfig"
76source "sound/soc/xtensa/Kconfig" 76source "sound/soc/xtensa/Kconfig"
77source "sound/soc/zte/Kconfig" 77source "sound/soc/zte/Kconfig"
78 78
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 62a5f87c3cfc..48c48c1c893c 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -30,7 +30,6 @@ obj-$(CONFIG_SND_SOC) += atmel/
30obj-$(CONFIG_SND_SOC) += au1x/ 30obj-$(CONFIG_SND_SOC) += au1x/
31obj-$(CONFIG_SND_SOC) += bcm/ 31obj-$(CONFIG_SND_SOC) += bcm/
32obj-$(CONFIG_SND_SOC) += cirrus/ 32obj-$(CONFIG_SND_SOC) += cirrus/
33obj-$(CONFIG_SND_SOC) += davinci/
34obj-$(CONFIG_SND_SOC) += dwc/ 33obj-$(CONFIG_SND_SOC) += dwc/
35obj-$(CONFIG_SND_SOC) += fsl/ 34obj-$(CONFIG_SND_SOC) += fsl/
36obj-$(CONFIG_SND_SOC) += hisilicon/ 35obj-$(CONFIG_SND_SOC) += hisilicon/
@@ -41,7 +40,6 @@ obj-$(CONFIG_SND_SOC) += mediatek/
41obj-$(CONFIG_SND_SOC) += meson/ 40obj-$(CONFIG_SND_SOC) += meson/
42obj-$(CONFIG_SND_SOC) += mxs/ 41obj-$(CONFIG_SND_SOC) += mxs/
43obj-$(CONFIG_SND_SOC) += nuc900/ 42obj-$(CONFIG_SND_SOC) += nuc900/
44obj-$(CONFIG_SND_SOC) += omap/
45obj-$(CONFIG_SND_SOC) += kirkwood/ 43obj-$(CONFIG_SND_SOC) += kirkwood/
46obj-$(CONFIG_SND_SOC) += pxa/ 44obj-$(CONFIG_SND_SOC) += pxa/
47obj-$(CONFIG_SND_SOC) += qcom/ 45obj-$(CONFIG_SND_SOC) += qcom/
@@ -54,8 +52,10 @@ obj-$(CONFIG_SND_SOC) += sti/
54obj-$(CONFIG_SND_SOC) += stm/ 52obj-$(CONFIG_SND_SOC) += stm/
55obj-$(CONFIG_SND_SOC) += sunxi/ 53obj-$(CONFIG_SND_SOC) += sunxi/
56obj-$(CONFIG_SND_SOC) += tegra/ 54obj-$(CONFIG_SND_SOC) += tegra/
55obj-$(CONFIG_SND_SOC) += ti/
57obj-$(CONFIG_SND_SOC) += txx9/ 56obj-$(CONFIG_SND_SOC) += txx9/
58obj-$(CONFIG_SND_SOC) += uniphier/ 57obj-$(CONFIG_SND_SOC) += uniphier/
59obj-$(CONFIG_SND_SOC) += ux500/ 58obj-$(CONFIG_SND_SOC) += ux500/
59obj-$(CONFIG_SND_SOC) += xilinx/
60obj-$(CONFIG_SND_SOC) += xtensa/ 60obj-$(CONFIG_SND_SOC) += xtensa/
61obj-$(CONFIG_SND_SOC) += zte/ 61obj-$(CONFIG_SND_SOC) += zte/
diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig
index 58c1dcb4d255..33ebec990c2f 100644
--- a/sound/soc/amd/Kconfig
+++ b/sound/soc/amd/Kconfig
@@ -19,3 +19,9 @@ config SND_SOC_AMD_CZ_RT5645_MACH
19 depends on SND_SOC_AMD_ACP && I2C 19 depends on SND_SOC_AMD_ACP && I2C
20 help 20 help
21 This option enables machine driver for rt5645. 21 This option enables machine driver for rt5645.
22
23config SND_SOC_AMD_ACP3x
24 tristate "AMD Audio Coprocessor-v3.x support"
25 depends on X86 && PCI
26 help
27 This option enables ACP v3.x I2S support on AMD platform
diff --git a/sound/soc/amd/Makefile b/sound/soc/amd/Makefile
index 79b0622fa5d3..8e1c571c3161 100644
--- a/sound/soc/amd/Makefile
+++ b/sound/soc/amd/Makefile
@@ -5,3 +5,4 @@ snd-soc-acp-rt5645-mach-objs := acp-rt5645.o
5obj-$(CONFIG_SND_SOC_AMD_ACP) += acp_audio_dma.o 5obj-$(CONFIG_SND_SOC_AMD_ACP) += acp_audio_dma.o
6obj-$(CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH) += snd-soc-acp-da7219mx98357-mach.o 6obj-$(CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH) += snd-soc-acp-da7219mx98357-mach.o
7obj-$(CONFIG_SND_SOC_AMD_CZ_RT5645_MACH) += snd-soc-acp-rt5645-mach.o 7obj-$(CONFIG_SND_SOC_AMD_CZ_RT5645_MACH) += snd-soc-acp-rt5645-mach.o
8obj-$(CONFIG_SND_SOC_AMD_ACP3x) += raven/
diff --git a/sound/soc/amd/acp-da7219-max98357a.c b/sound/soc/amd/acp-da7219-max98357a.c
index 3f813ea5210a..a5daad973ce5 100644
--- a/sound/soc/amd/acp-da7219-max98357a.c
+++ b/sound/soc/amd/acp-da7219-max98357a.c
@@ -403,7 +403,7 @@ static struct regulator_config acp_da7219_cfg = {
403static struct regulator_ops acp_da7219_ops = { 403static struct regulator_ops acp_da7219_ops = {
404}; 404};
405 405
406static struct regulator_desc acp_da7219_desc = { 406static const struct regulator_desc acp_da7219_desc = {
407 .name = "reg-fixed-1.8V", 407 .name = "reg-fixed-1.8V",
408 .type = REGULATOR_VOLTAGE, 408 .type = REGULATOR_VOLTAGE,
409 .owner = THIS_MODULE, 409 .owner = THIS_MODULE,
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c
index cdebab2f8ce5..f4011bebc7ec 100644
--- a/sound/soc/amd/acp-pcm-dma.c
+++ b/sound/soc/amd/acp-pcm-dma.c
@@ -303,11 +303,10 @@ static void set_acp_to_i2s_dma_descriptors(void __iomem *acp_mmio, u32 size,
303} 303}
304 304
305/* Create page table entries in ACP SRAM for the allocated memory */ 305/* Create page table entries in ACP SRAM for the allocated memory */
306static void acp_pte_config(void __iomem *acp_mmio, struct page *pg, 306static void acp_pte_config(void __iomem *acp_mmio, dma_addr_t addr,
307 u16 num_of_pages, u32 pte_offset) 307 u16 num_of_pages, u32 pte_offset)
308{ 308{
309 u16 page_idx; 309 u16 page_idx;
310 u64 addr;
311 u32 low; 310 u32 low;
312 u32 high; 311 u32 high;
313 u32 offset; 312 u32 offset;
@@ -317,7 +316,6 @@ static void acp_pte_config(void __iomem *acp_mmio, struct page *pg,
317 /* Load the low address of page int ACP SRAM through SRBM */ 316 /* Load the low address of page int ACP SRAM through SRBM */
318 acp_reg_write((offset + (page_idx * 8)), 317 acp_reg_write((offset + (page_idx * 8)),
319 acp_mmio, mmACP_SRBM_Targ_Idx_Addr); 318 acp_mmio, mmACP_SRBM_Targ_Idx_Addr);
320 addr = page_to_phys(pg);
321 319
322 low = lower_32_bits(addr); 320 low = lower_32_bits(addr);
323 high = upper_32_bits(addr); 321 high = upper_32_bits(addr);
@@ -333,7 +331,7 @@ static void acp_pte_config(void __iomem *acp_mmio, struct page *pg,
333 acp_reg_write(high, acp_mmio, mmACP_SRBM_Targ_Idx_Data); 331 acp_reg_write(high, acp_mmio, mmACP_SRBM_Targ_Idx_Data);
334 332
335 /* Move to next physically contiguos page */ 333 /* Move to next physically contiguos page */
336 pg++; 334 addr += PAGE_SIZE;
337 } 335 }
338} 336}
339 337
@@ -343,7 +341,7 @@ static void config_acp_dma(void __iomem *acp_mmio,
343{ 341{
344 u16 ch_acp_sysmem, ch_acp_i2s; 342 u16 ch_acp_sysmem, ch_acp_i2s;
345 343
346 acp_pte_config(acp_mmio, rtd->pg, rtd->num_of_pages, 344 acp_pte_config(acp_mmio, rtd->dma_addr, rtd->num_of_pages,
347 rtd->pte_offset); 345 rtd->pte_offset);
348 346
349 if (rtd->direction == SNDRV_PCM_STREAM_PLAYBACK) { 347 if (rtd->direction == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -850,7 +848,6 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
850 int status; 848 int status;
851 uint64_t size; 849 uint64_t size;
852 u32 val = 0; 850 u32 val = 0;
853 struct page *pg;
854 struct snd_pcm_runtime *runtime; 851 struct snd_pcm_runtime *runtime;
855 struct audio_substream_data *rtd; 852 struct audio_substream_data *rtd;
856 struct snd_soc_pcm_runtime *prtd = substream->private_data; 853 struct snd_soc_pcm_runtime *prtd = substream->private_data;
@@ -986,16 +983,14 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
986 return status; 983 return status;
987 984
988 memset(substream->runtime->dma_area, 0, params_buffer_bytes(params)); 985 memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
989 pg = virt_to_page(substream->dma_buffer.area);
990 986
991 if (pg) { 987 if (substream->dma_buffer.area) {
992 acp_set_sram_bank_state(rtd->acp_mmio, 0, true); 988 acp_set_sram_bank_state(rtd->acp_mmio, 0, true);
993 /* Save for runtime private data */ 989 /* Save for runtime private data */
994 rtd->pg = pg; 990 rtd->dma_addr = substream->dma_buffer.addr;
995 rtd->order = get_order(size); 991 rtd->order = get_order(size);
996 992
997 /* Fill the page table entries in ACP SRAM */ 993 /* Fill the page table entries in ACP SRAM */
998 rtd->pg = pg;
999 rtd->size = size; 994 rtd->size = size;
1000 rtd->num_of_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; 995 rtd->num_of_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
1001 rtd->direction = substream->stream; 996 rtd->direction = substream->stream;
@@ -1151,18 +1146,21 @@ static int acp_dma_new(struct snd_soc_pcm_runtime *rtd)
1151 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, 1146 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd,
1152 DRV_NAME); 1147 DRV_NAME);
1153 struct audio_drv_data *adata = dev_get_drvdata(component->dev); 1148 struct audio_drv_data *adata = dev_get_drvdata(component->dev);
1149 struct device *parent = component->dev->parent;
1154 1150
1155 switch (adata->asic_type) { 1151 switch (adata->asic_type) {
1156 case CHIP_STONEY: 1152 case CHIP_STONEY:
1157 ret = snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, 1153 ret = snd_pcm_lib_preallocate_pages_for_all(rtd->pcm,
1158 SNDRV_DMA_TYPE_DEV, 1154 SNDRV_DMA_TYPE_DEV,
1159 NULL, ST_MIN_BUFFER, 1155 parent,
1156 ST_MIN_BUFFER,
1160 ST_MAX_BUFFER); 1157 ST_MAX_BUFFER);
1161 break; 1158 break;
1162 default: 1159 default:
1163 ret = snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, 1160 ret = snd_pcm_lib_preallocate_pages_for_all(rtd->pcm,
1164 SNDRV_DMA_TYPE_DEV, 1161 SNDRV_DMA_TYPE_DEV,
1165 NULL, MIN_BUFFER, 1162 parent,
1163 MIN_BUFFER,
1166 MAX_BUFFER); 1164 MAX_BUFFER);
1167 break; 1165 break;
1168 } 1166 }
diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h
index dbbb1a85638d..e5ab6c6040a6 100644
--- a/sound/soc/amd/acp.h
+++ b/sound/soc/amd/acp.h
@@ -123,7 +123,7 @@ enum acp_dma_priority_level {
123}; 123};
124 124
125struct audio_substream_data { 125struct audio_substream_data {
126 struct page *pg; 126 dma_addr_t dma_addr;
127 unsigned int order; 127 unsigned int order;
128 u16 num_of_pages; 128 u16 num_of_pages;
129 u16 i2s_instance; 129 u16 i2s_instance;
diff --git a/sound/soc/amd/raven/Makefile b/sound/soc/amd/raven/Makefile
new file mode 100644
index 000000000000..108d1acf189b
--- /dev/null
+++ b/sound/soc/amd/raven/Makefile
@@ -0,0 +1,6 @@
1# SPDX-License-Identifier: GPL-2.0+
2# Raven Ridge platform Support
3snd-pci-acp3x-objs := pci-acp3x.o
4snd-acp3x-pcm-dma-objs := acp3x-pcm-dma.o
5obj-$(CONFIG_SND_SOC_AMD_ACP3x) += snd-pci-acp3x.o
6obj-$(CONFIG_SND_SOC_AMD_ACP3x) += snd-acp3x-pcm-dma.o
diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c
new file mode 100644
index 000000000000..022a8912c8a2
--- /dev/null
+++ b/sound/soc/amd/raven/acp3x-pcm-dma.c
@@ -0,0 +1,777 @@
1// SPDX-License-Identifier: GPL-2.0+
2//
3// AMD ALSA SoC PCM Driver
4//
5//Copyright 2016 Advanced Micro Devices, Inc.
6
7#include <linux/platform_device.h>
8#include <linux/module.h>
9#include <linux/err.h>
10#include <linux/io.h>
11#include <linux/pm_runtime.h>
12#include <sound/pcm.h>
13#include <sound/pcm_params.h>
14#include <sound/soc.h>
15#include <sound/soc-dai.h>
16
17#include "acp3x.h"
18
19#define DRV_NAME "acp3x-i2s-audio"
20
21struct i2s_dev_data {
22 bool tdm_mode;
23 unsigned int i2s_irq;
24 u32 tdm_fmt;
25 void __iomem *acp3x_base;
26 struct snd_pcm_substream *play_stream;
27 struct snd_pcm_substream *capture_stream;
28};
29
30struct i2s_stream_instance {
31 u16 num_pages;
32 u16 channels;
33 u32 xfer_resolution;
34 struct page *pg;
35 void __iomem *acp3x_base;
36};
37
38static const struct snd_pcm_hardware acp3x_pcm_hardware_playback = {
39 .info = SNDRV_PCM_INFO_INTERLEAVED |
40 SNDRV_PCM_INFO_BLOCK_TRANSFER |
41 SNDRV_PCM_INFO_BATCH |
42 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
43 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
44 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE |
45 SNDRV_PCM_FMTBIT_S32_LE,
46 .channels_min = 2,
47 .channels_max = 8,
48 .rates = SNDRV_PCM_RATE_8000_96000,
49 .rate_min = 8000,
50 .rate_max = 96000,
51 .buffer_bytes_max = PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE,
52 .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE,
53 .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE,
54 .periods_min = PLAYBACK_MIN_NUM_PERIODS,
55 .periods_max = PLAYBACK_MAX_NUM_PERIODS,
56};
57
58static const struct snd_pcm_hardware acp3x_pcm_hardware_capture = {
59 .info = SNDRV_PCM_INFO_INTERLEAVED |
60 SNDRV_PCM_INFO_BLOCK_TRANSFER |
61 SNDRV_PCM_INFO_BATCH |
62 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
63 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
64 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE |
65 SNDRV_PCM_FMTBIT_S32_LE,
66 .channels_min = 2,
67 .channels_max = 2,
68 .rates = SNDRV_PCM_RATE_8000_48000,
69 .rate_min = 8000,
70 .rate_max = 48000,
71 .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
72 .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
73 .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
74 .periods_min = CAPTURE_MIN_NUM_PERIODS,
75 .periods_max = CAPTURE_MAX_NUM_PERIODS,
76};
77
78static int acp3x_power_on(void __iomem *acp3x_base, bool on)
79{
80 u16 val, mask;
81 u32 timeout;
82
83 if (on == true) {
84 val = 1;
85 mask = ACP3x_POWER_ON;
86 } else {
87 val = 0;
88 mask = ACP3x_POWER_OFF;
89 }
90
91 rv_writel(val, acp3x_base + mmACP_PGFSM_CONTROL);
92 timeout = 0;
93 while (true) {
94 val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS);
95 if ((val & ACP3x_POWER_OFF_IN_PROGRESS) == mask)
96 break;
97 if (timeout > 100) {
98 pr_err("ACP3x power state change failure\n");
99 return -ENODEV;
100 }
101 timeout++;
102 cpu_relax();
103 }
104 return 0;
105}
106
107static int acp3x_reset(void __iomem *acp3x_base)
108{
109 u32 val, timeout;
110
111 rv_writel(1, acp3x_base + mmACP_SOFT_RESET);
112 timeout = 0;
113 while (true) {
114 val = rv_readl(acp3x_base + mmACP_SOFT_RESET);
115 if ((val & ACP3x_SOFT_RESET__SoftResetAudDone_MASK) ||
116 timeout > 100) {
117 if (val & ACP3x_SOFT_RESET__SoftResetAudDone_MASK)
118 break;
119 return -ENODEV;
120 }
121 timeout++;
122 cpu_relax();
123 }
124
125 rv_writel(0, acp3x_base + mmACP_SOFT_RESET);
126 timeout = 0;
127 while (true) {
128 val = rv_readl(acp3x_base + mmACP_SOFT_RESET);
129 if (!val || timeout > 100) {
130 if (!val)
131 break;
132 return -ENODEV;
133 }
134 timeout++;
135 cpu_relax();
136 }
137 return 0;
138}
139
140static int acp3x_init(void __iomem *acp3x_base)
141{
142 int ret;
143
144 /* power on */
145 ret = acp3x_power_on(acp3x_base, true);
146 if (ret) {
147 pr_err("ACP3x power on failed\n");
148 return ret;
149 }
150 /* Reset */
151 ret = acp3x_reset(acp3x_base);
152 if (ret) {
153 pr_err("ACP3x reset failed\n");
154 return ret;
155 }
156 return 0;
157}
158
159static int acp3x_deinit(void __iomem *acp3x_base)
160{
161 int ret;
162
163 /* Reset */
164 ret = acp3x_reset(acp3x_base);
165 if (ret) {
166 pr_err("ACP3x reset failed\n");
167 return ret;
168 }
169 /* power off */
170 ret = acp3x_power_on(acp3x_base, false);
171 if (ret) {
172 pr_err("ACP3x power off failed\n");
173 return ret;
174 }
175 return 0;
176}
177
178static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
179{
180 u16 play_flag, cap_flag;
181 u32 val;
182 struct i2s_dev_data *rv_i2s_data = dev_id;
183
184 if (!rv_i2s_data)
185 return IRQ_NONE;
186
187 play_flag = 0;
188 cap_flag = 0;
189 val = rv_readl(rv_i2s_data->acp3x_base + mmACP_EXTERNAL_INTR_STAT);
190 if ((val & BIT(BT_TX_THRESHOLD)) && rv_i2s_data->play_stream) {
191 rv_writel(BIT(BT_TX_THRESHOLD), rv_i2s_data->acp3x_base +
192 mmACP_EXTERNAL_INTR_STAT);
193 snd_pcm_period_elapsed(rv_i2s_data->play_stream);
194 play_flag = 1;
195 }
196
197 if ((val & BIT(BT_RX_THRESHOLD)) && rv_i2s_data->capture_stream) {
198 rv_writel(BIT(BT_RX_THRESHOLD), rv_i2s_data->acp3x_base +
199 mmACP_EXTERNAL_INTR_STAT);
200 snd_pcm_period_elapsed(rv_i2s_data->capture_stream);
201 cap_flag = 1;
202 }
203
204 if (play_flag | cap_flag)
205 return IRQ_HANDLED;
206 else
207 return IRQ_NONE;
208}
209
210static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
211{
212 u16 page_idx;
213 u64 addr;
214 u32 low, high, val, acp_fifo_addr;
215 struct page *pg = rtd->pg;
216
217 /* 8 scratch registers used to map one 64 bit address */
218 if (direction == SNDRV_PCM_STREAM_PLAYBACK)
219 val = 0;
220 else
221 val = rtd->num_pages * 8;
222
223 /* Group Enable */
224 rv_writel(ACP_SRAM_PTE_OFFSET | BIT(31), rtd->acp3x_base +
225 mmACPAXI2AXI_ATU_BASE_ADDR_GRP_1);
226 rv_writel(PAGE_SIZE_4K_ENABLE, rtd->acp3x_base +
227 mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_1);
228
229 for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) {
230 /* Load the low address of page int ACP SRAM through SRBM */
231 addr = page_to_phys(pg);
232 low = lower_32_bits(addr);
233 high = upper_32_bits(addr);
234
235 rv_writel(low, rtd->acp3x_base + mmACP_SCRATCH_REG_0 + val);
236 high |= BIT(31);
237 rv_writel(high, rtd->acp3x_base + mmACP_SCRATCH_REG_0 + val
238 + 4);
239 /* Move to next physically contiguos page */
240 val += 8;
241 pg++;
242 }
243
244 if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
245 /* Config ringbuffer */
246 rv_writel(MEM_WINDOW_START, rtd->acp3x_base +
247 mmACP_BT_TX_RINGBUFADDR);
248 rv_writel(MAX_BUFFER, rtd->acp3x_base +
249 mmACP_BT_TX_RINGBUFSIZE);
250 rv_writel(DMA_SIZE, rtd->acp3x_base + mmACP_BT_TX_DMA_SIZE);
251
252 /* Config audio fifo */
253 acp_fifo_addr = ACP_SRAM_PTE_OFFSET + (rtd->num_pages * 8)
254 + PLAYBACK_FIFO_ADDR_OFFSET;
255 rv_writel(acp_fifo_addr, rtd->acp3x_base +
256 mmACP_BT_TX_FIFOADDR);
257 rv_writel(FIFO_SIZE, rtd->acp3x_base + mmACP_BT_TX_FIFOSIZE);
258 } else {
259 /* Config ringbuffer */
260 rv_writel(MEM_WINDOW_START + MAX_BUFFER, rtd->acp3x_base +
261 mmACP_BT_RX_RINGBUFADDR);
262 rv_writel(MAX_BUFFER, rtd->acp3x_base +
263 mmACP_BT_RX_RINGBUFSIZE);
264 rv_writel(DMA_SIZE, rtd->acp3x_base + mmACP_BT_RX_DMA_SIZE);
265
266 /* Config audio fifo */
267 acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
268 (rtd->num_pages * 8) + CAPTURE_FIFO_ADDR_OFFSET;
269 rv_writel(acp_fifo_addr, rtd->acp3x_base +
270 mmACP_BT_RX_FIFOADDR);
271 rv_writel(FIFO_SIZE, rtd->acp3x_base + mmACP_BT_RX_FIFOSIZE);
272 }
273
274 /* Enable watermark/period interrupt to host */
275 rv_writel(BIT(BT_TX_THRESHOLD) | BIT(BT_RX_THRESHOLD),
276 rtd->acp3x_base + mmACP_EXTERNAL_INTR_CNTL);
277}
278
279static int acp3x_dma_open(struct snd_pcm_substream *substream)
280{
281 int ret = 0;
282
283 struct snd_pcm_runtime *runtime = substream->runtime;
284 struct snd_soc_pcm_runtime *prtd = substream->private_data;
285 struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd,
286 DRV_NAME);
287 struct i2s_dev_data *adata = dev_get_drvdata(component->dev);
288
289 struct i2s_stream_instance *i2s_data = kzalloc(sizeof(struct i2s_stream_instance),
290 GFP_KERNEL);
291 if (!i2s_data)
292 return -EINVAL;
293
294 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
295 runtime->hw = acp3x_pcm_hardware_playback;
296 else
297 runtime->hw = acp3x_pcm_hardware_capture;
298
299 ret = snd_pcm_hw_constraint_integer(runtime,
300 SNDRV_PCM_HW_PARAM_PERIODS);
301 if (ret < 0) {
302 dev_err(component->dev, "set integer constraint failed\n");
303 kfree(i2s_data);
304 return ret;
305 }
306
307 if (!adata->play_stream && !adata->capture_stream)
308 rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB);
309
310 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
311 adata->play_stream = substream;
312 else
313 adata->capture_stream = substream;
314
315 i2s_data->acp3x_base = adata->acp3x_base;
316 runtime->private_data = i2s_data;
317 return 0;
318}
319
320static int acp3x_dma_hw_params(struct snd_pcm_substream *substream,
321 struct snd_pcm_hw_params *params)
322{
323 int status;
324 u64 size;
325 struct page *pg;
326 struct snd_pcm_runtime *runtime = substream->runtime;
327 struct i2s_stream_instance *rtd = runtime->private_data;
328
329 if (!rtd)
330 return -EINVAL;
331
332 size = params_buffer_bytes(params);
333 status = snd_pcm_lib_malloc_pages(substream, size);
334 if (status < 0)
335 return status;
336
337 memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
338 pg = virt_to_page(substream->dma_buffer.area);
339 if (pg) {
340 rtd->pg = pg;
341 rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
342 config_acp3x_dma(rtd, substream->stream);
343 status = 0;
344 } else {
345 status = -ENOMEM;
346 }
347 return status;
348}
349
350static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_pcm_substream *substream)
351{
352 u32 pos = 0;
353 struct i2s_stream_instance *rtd = substream->runtime->private_data;
354
355 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
356 pos = rv_readl(rtd->acp3x_base +
357 mmACP_BT_TX_LINKPOSITIONCNTR);
358 else
359 pos = rv_readl(rtd->acp3x_base +
360 mmACP_BT_RX_LINKPOSITIONCNTR);
361
362 if (pos >= MAX_BUFFER)
363 pos = 0;
364
365 return bytes_to_frames(substream->runtime, pos);
366}
367
368static int acp3x_dma_new(struct snd_soc_pcm_runtime *rtd)
369{
370 return snd_pcm_lib_preallocate_pages_for_all(rtd->pcm,
371 SNDRV_DMA_TYPE_DEV,
372 NULL, MIN_BUFFER,
373 MAX_BUFFER);
374}
375
376static int acp3x_dma_hw_free(struct snd_pcm_substream *substream)
377{
378 return snd_pcm_lib_free_pages(substream);
379}
380
381static int acp3x_dma_mmap(struct snd_pcm_substream *substream,
382 struct vm_area_struct *vma)
383{
384 return snd_pcm_lib_default_mmap(substream, vma);
385}
386
387static int acp3x_dma_close(struct snd_pcm_substream *substream)
388{
389 struct snd_soc_pcm_runtime *prtd = substream->private_data;
390 struct i2s_stream_instance *rtd = substream->runtime->private_data;
391 struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd,
392 DRV_NAME);
393 struct i2s_dev_data *adata = dev_get_drvdata(component->dev);
394
395 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
396 adata->play_stream = NULL;
397 else
398 adata->capture_stream = NULL;
399
400 /* Disable ACP irq, when the current stream is being closed and
401 * another stream is also not active.
402 */
403 if (!adata->play_stream && !adata->capture_stream)
404 rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB);
405 kfree(rtd);
406 return 0;
407}
408
409static struct snd_pcm_ops acp3x_dma_ops = {
410 .open = acp3x_dma_open,
411 .close = acp3x_dma_close,
412 .ioctl = snd_pcm_lib_ioctl,
413 .hw_params = acp3x_dma_hw_params,
414 .hw_free = acp3x_dma_hw_free,
415 .pointer = acp3x_dma_pointer,
416 .mmap = acp3x_dma_mmap,
417};
418
419
420static int acp3x_dai_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
421{
422
423 struct i2s_dev_data *adata = snd_soc_dai_get_drvdata(cpu_dai);
424
425 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
426 case SND_SOC_DAIFMT_I2S:
427 adata->tdm_mode = false;
428 break;
429 case SND_SOC_DAIFMT_DSP_A:
430 adata->tdm_mode = true;
431 break;
432 default:
433 return -EINVAL;
434 }
435
436 return 0;
437}
438
439static int acp3x_dai_set_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
440 u32 rx_mask, int slots, int slot_width)
441{
442 u32 val = 0;
443 u16 slot_len;
444
445 struct i2s_dev_data *adata = snd_soc_dai_get_drvdata(cpu_dai);
446
447 switch (slot_width) {
448 case SLOT_WIDTH_8:
449 slot_len = 8;
450 break;
451 case SLOT_WIDTH_16:
452 slot_len = 16;
453 break;
454 case SLOT_WIDTH_24:
455 slot_len = 24;
456 break;
457 case SLOT_WIDTH_32:
458 slot_len = 0;
459 break;
460 default:
461 return -EINVAL;
462 }
463
464 val = rv_readl(adata->acp3x_base + mmACP_BTTDM_ITER);
465 rv_writel((val | 0x2), adata->acp3x_base + mmACP_BTTDM_ITER);
466 val = rv_readl(adata->acp3x_base + mmACP_BTTDM_IRER);
467 rv_writel((val | 0x2), adata->acp3x_base + mmACP_BTTDM_IRER);
468
469 val = (FRM_LEN | (slots << 15) | (slot_len << 18));
470 rv_writel(val, adata->acp3x_base + mmACP_BTTDM_TXFRMT);
471 rv_writel(val, adata->acp3x_base + mmACP_BTTDM_RXFRMT);
472
473 adata->tdm_fmt = val;
474 return 0;
475}
476
477static int acp3x_dai_i2s_hwparams(struct snd_pcm_substream *substream,
478 struct snd_pcm_hw_params *params,
479 struct snd_soc_dai *dai)
480{
481 u32 val = 0;
482 struct i2s_stream_instance *rtd = substream->runtime->private_data;
483
484 switch (params_format(params)) {
485 case SNDRV_PCM_FORMAT_U8:
486 case SNDRV_PCM_FORMAT_S8:
487 rtd->xfer_resolution = 0x0;
488 break;
489 case SNDRV_PCM_FORMAT_S16_LE:
490 rtd->xfer_resolution = 0x02;
491 break;
492 case SNDRV_PCM_FORMAT_S24_LE:
493 rtd->xfer_resolution = 0x04;
494 break;
495 case SNDRV_PCM_FORMAT_S32_LE:
496 rtd->xfer_resolution = 0x05;
497 break;
498 default:
499 return -EINVAL;
500 }
501 val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER);
502 val = val | (rtd->xfer_resolution << 3);
503 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
504 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER);
505 else
506 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER);
507
508 return 0;
509}
510
511static int acp3x_dai_i2s_trigger(struct snd_pcm_substream *substream,
512 int cmd, struct snd_soc_dai *dai)
513{
514 int ret = 0;
515 struct i2s_stream_instance *rtd = substream->runtime->private_data;
516 u32 val, period_bytes;
517
518 period_bytes = frames_to_bytes(substream->runtime,
519 substream->runtime->period_size);
520 switch (cmd) {
521 case SNDRV_PCM_TRIGGER_START:
522 case SNDRV_PCM_TRIGGER_RESUME:
523 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
524 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
525 rv_writel(period_bytes, rtd->acp3x_base +
526 mmACP_BT_TX_INTR_WATERMARK_SIZE);
527 val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER);
528 val = val | BIT(0);
529 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER);
530 } else {
531 rv_writel(period_bytes, rtd->acp3x_base +
532 mmACP_BT_RX_INTR_WATERMARK_SIZE);
533 val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER);
534 val = val | BIT(0);
535 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER);
536 }
537 rv_writel(1, rtd->acp3x_base + mmACP_BTTDM_IER);
538 break;
539 case SNDRV_PCM_TRIGGER_STOP:
540 case SNDRV_PCM_TRIGGER_SUSPEND:
541 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
542 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
543 val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER);
544 val = val & ~BIT(0);
545 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER);
546 } else {
547 val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER);
548 val = val & ~BIT(0);
549 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER);
550 }
551 rv_writel(0, rtd->acp3x_base + mmACP_BTTDM_IER);
552 break;
553 default:
554 ret = -EINVAL;
555 break;
556 }
557
558 return ret;
559}
560
561struct snd_soc_dai_ops acp3x_dai_i2s_ops = {
562 .hw_params = acp3x_dai_i2s_hwparams,
563 .trigger = acp3x_dai_i2s_trigger,
564 .set_fmt = acp3x_dai_i2s_set_fmt,
565 .set_tdm_slot = acp3x_dai_set_tdm_slot,
566};
567
568static struct snd_soc_dai_driver acp3x_i2s_dai_driver = {
569 .playback = {
570 .rates = SNDRV_PCM_RATE_8000_96000,
571 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
572 SNDRV_PCM_FMTBIT_U8 |
573 SNDRV_PCM_FMTBIT_S24_LE |
574 SNDRV_PCM_FMTBIT_S32_LE,
575 .channels_min = 2,
576 .channels_max = 8,
577
578 .rate_min = 8000,
579 .rate_max = 96000,
580 },
581 .capture = {
582 .rates = SNDRV_PCM_RATE_8000_48000,
583 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 |
584 SNDRV_PCM_FMTBIT_U8 |
585 SNDRV_PCM_FMTBIT_S24_LE |
586 SNDRV_PCM_FMTBIT_S32_LE,
587 .channels_min = 2,
588 .channels_max = 2,
589 .rate_min = 8000,
590 .rate_max = 48000,
591 },
592 .ops = &acp3x_dai_i2s_ops,
593};
594
595static const struct snd_soc_component_driver acp3x_i2s_component = {
596 .name = DRV_NAME,
597 .ops = &acp3x_dma_ops,
598 .pcm_new = acp3x_dma_new,
599};
600
601static int acp3x_audio_probe(struct platform_device *pdev)
602{
603 int status;
604 struct resource *res;
605 struct i2s_dev_data *adata;
606 unsigned int irqflags;
607
608 if (!pdev->dev.platform_data) {
609 dev_err(&pdev->dev, "platform_data not retrieved\n");
610 return -ENODEV;
611 }
612 irqflags = *((unsigned int *)(pdev->dev.platform_data));
613
614 adata = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dev_data),
615 GFP_KERNEL);
616 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
617 if (!res) {
618 dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n");
619 return -ENODEV;
620 }
621
622 adata->acp3x_base = devm_ioremap(&pdev->dev, res->start,
623 resource_size(res));
624
625 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
626 if (!res) {
627 dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n");
628 return -ENODEV;
629 }
630
631 adata->i2s_irq = res->start;
632 adata->play_stream = NULL;
633 adata->capture_stream = NULL;
634
635 dev_set_drvdata(&pdev->dev, adata);
636 /* Initialize ACP */
637 status = acp3x_init(adata->acp3x_base);
638 if (status)
639 return -ENODEV;
640 status = devm_snd_soc_register_component(&pdev->dev,
641 &acp3x_i2s_component,
642 &acp3x_i2s_dai_driver, 1);
643 if (status) {
644 dev_err(&pdev->dev, "Fail to register acp i2s dai\n");
645 goto dev_err;
646 }
647 status = devm_request_irq(&pdev->dev, adata->i2s_irq, i2s_irq_handler,
648 irqflags, "ACP3x_I2S_IRQ", adata);
649 if (status) {
650 dev_err(&pdev->dev, "ACP3x I2S IRQ request failed\n");
651 goto dev_err;
652 }
653
654 pm_runtime_set_autosuspend_delay(&pdev->dev, 10000);
655 pm_runtime_use_autosuspend(&pdev->dev);
656 pm_runtime_enable(&pdev->dev);
657 return 0;
658dev_err:
659 status = acp3x_deinit(adata->acp3x_base);
660 if (status)
661 dev_err(&pdev->dev, "ACP de-init failed\n");
662 else
663 dev_info(&pdev->dev, "ACP de-initialized\n");
664 /*ignore device status and return driver probe error*/
665 return -ENODEV;
666}
667
668static int acp3x_audio_remove(struct platform_device *pdev)
669{
670 int ret;
671 struct i2s_dev_data *adata = dev_get_drvdata(&pdev->dev);
672
673 ret = acp3x_deinit(adata->acp3x_base);
674 if (ret)
675 dev_err(&pdev->dev, "ACP de-init failed\n");
676 else
677 dev_info(&pdev->dev, "ACP de-initialized\n");
678
679 pm_runtime_disable(&pdev->dev);
680 return 0;
681}
682
683static int acp3x_resume(struct device *dev)
684{
685 int status;
686 u32 val;
687 struct i2s_dev_data *adata = dev_get_drvdata(dev);
688
689 status = acp3x_init(adata->acp3x_base);
690 if (status)
691 return -ENODEV;
692
693 if (adata->play_stream && adata->play_stream->runtime) {
694 struct i2s_stream_instance *rtd =
695 adata->play_stream->runtime->private_data;
696 config_acp3x_dma(rtd, SNDRV_PCM_STREAM_PLAYBACK);
697 rv_writel((rtd->xfer_resolution << 3),
698 rtd->acp3x_base + mmACP_BTTDM_ITER);
699 if (adata->tdm_mode == true) {
700 rv_writel(adata->tdm_fmt, adata->acp3x_base +
701 mmACP_BTTDM_TXFRMT);
702 val = rv_readl(adata->acp3x_base + mmACP_BTTDM_ITER);
703 rv_writel((val | 0x2), adata->acp3x_base +
704 mmACP_BTTDM_ITER);
705 }
706 }
707
708 if (adata->capture_stream && adata->capture_stream->runtime) {
709 struct i2s_stream_instance *rtd =
710 adata->capture_stream->runtime->private_data;
711 config_acp3x_dma(rtd, SNDRV_PCM_STREAM_CAPTURE);
712 rv_writel((rtd->xfer_resolution << 3),
713 rtd->acp3x_base + mmACP_BTTDM_IRER);
714 if (adata->tdm_mode == true) {
715 rv_writel(adata->tdm_fmt, adata->acp3x_base +
716 mmACP_BTTDM_RXFRMT);
717 val = rv_readl(adata->acp3x_base + mmACP_BTTDM_IRER);
718 rv_writel((val | 0x2), adata->acp3x_base +
719 mmACP_BTTDM_IRER);
720 }
721 }
722
723 rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB);
724 return 0;
725}
726
727
728static int acp3x_pcm_runtime_suspend(struct device *dev)
729{
730 int status;
731 struct i2s_dev_data *adata = dev_get_drvdata(dev);
732
733 status = acp3x_deinit(adata->acp3x_base);
734 if (status)
735 dev_err(dev, "ACP de-init failed\n");
736 else
737 dev_info(dev, "ACP de-initialized\n");
738
739 rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB);
740
741 return 0;
742}
743
744static int acp3x_pcm_runtime_resume(struct device *dev)
745{
746 int status;
747 struct i2s_dev_data *adata = dev_get_drvdata(dev);
748
749 status = acp3x_init(adata->acp3x_base);
750 if (status)
751 return -ENODEV;
752 rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB);
753 return 0;
754}
755
756static const struct dev_pm_ops acp3x_pm_ops = {
757 .runtime_suspend = acp3x_pcm_runtime_suspend,
758 .runtime_resume = acp3x_pcm_runtime_resume,
759 .resume = acp3x_resume,
760};
761
762static struct platform_driver acp3x_dma_driver = {
763 .probe = acp3x_audio_probe,
764 .remove = acp3x_audio_remove,
765 .driver = {
766 .name = "acp3x_rv_i2s",
767 .pm = &acp3x_pm_ops,
768 },
769};
770
771module_platform_driver(acp3x_dma_driver);
772
773MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com");
774MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
775MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver");
776MODULE_LICENSE("GPL v2");
777MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/amd/raven/acp3x.h b/sound/soc/amd/raven/acp3x.h
new file mode 100644
index 000000000000..4f2cadd90a87
--- /dev/null
+++ b/sound/soc/amd/raven/acp3x.h
@@ -0,0 +1,58 @@
1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * AMD ALSA SoC PCM Driver
4 *
5 * Copyright 2016 Advanced Micro Devices, Inc.
6 */
7
8#include "chip_offset_byte.h"
9
10#define ACP3x_PHY_BASE_ADDRESS 0x1240000
11#define ACP3x_I2S_MODE 0
12#define ACP3x_REG_START 0x1240000
13#define ACP3x_REG_END 0x1250200
14#define I2S_MODE 0x04
15#define BT_TX_THRESHOLD 26
16#define BT_RX_THRESHOLD 25
17#define ACP3x_POWER_ON 0x00
18#define ACP3x_POWER_ON_IN_PROGRESS 0x01
19#define ACP3x_POWER_OFF 0x02
20#define ACP3x_POWER_OFF_IN_PROGRESS 0x03
21#define ACP3x_SOFT_RESET__SoftResetAudDone_MASK 0x00010001
22
23#define ACP_SRAM_PTE_OFFSET 0x02050000
24#define PAGE_SIZE_4K_ENABLE 0x2
25#define MEM_WINDOW_START 0x4000000
26#define PLAYBACK_FIFO_ADDR_OFFSET 0x400
27#define CAPTURE_FIFO_ADDR_OFFSET 0x500
28
29#define PLAYBACK_MIN_NUM_PERIODS 2
30#define PLAYBACK_MAX_NUM_PERIODS 8
31#define PLAYBACK_MAX_PERIOD_SIZE 16384
32#define PLAYBACK_MIN_PERIOD_SIZE 4096
33#define CAPTURE_MIN_NUM_PERIODS 2
34#define CAPTURE_MAX_NUM_PERIODS 8
35#define CAPTURE_MAX_PERIOD_SIZE 16384
36#define CAPTURE_MIN_PERIOD_SIZE 4096
37
38#define MAX_BUFFER (PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS)
39#define MIN_BUFFER MAX_BUFFER
40#define FIFO_SIZE 0x100
41#define DMA_SIZE 0x40
42#define FRM_LEN 0x100
43
44#define SLOT_WIDTH_8 0x08
45#define SLOT_WIDTH_16 0x10
46#define SLOT_WIDTH_24 0x18
47#define SLOT_WIDTH_32 0x20
48
49
50static inline u32 rv_readl(void __iomem *base_addr)
51{
52 return readl(base_addr - ACP3x_PHY_BASE_ADDRESS);
53}
54
55static inline void rv_writel(u32 val, void __iomem *base_addr)
56{
57 writel(val, base_addr - ACP3x_PHY_BASE_ADDRESS);
58}
diff --git a/sound/soc/amd/raven/chip_offset_byte.h b/sound/soc/amd/raven/chip_offset_byte.h
new file mode 100644
index 000000000000..9c1fac58fb2a
--- /dev/null
+++ b/sound/soc/amd/raven/chip_offset_byte.h
@@ -0,0 +1,639 @@
1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * AMD ACP 3.0 Register Documentation
4 *
5 * Copyright 2016 Advanced Micro Devices, Inc.
6 */
7
8#ifndef _acp_ip_OFFSET_HEADER
9#define _acp_ip_OFFSET_HEADER
10// Registers from ACP_DMA block
11
12#define mmACP_DMA_CNTL_0 0x1240000
13#define mmACP_DMA_CNTL_1 0x1240004
14#define mmACP_DMA_CNTL_2 0x1240008
15#define mmACP_DMA_CNTL_3 0x124000C
16#define mmACP_DMA_CNTL_4 0x1240010
17#define mmACP_DMA_CNTL_5 0x1240014
18#define mmACP_DMA_CNTL_6 0x1240018
19#define mmACP_DMA_CNTL_7 0x124001C
20#define mmACP_DMA_DSCR_STRT_IDX_0 0x1240020
21#define mmACP_DMA_DSCR_STRT_IDX_1 0x1240024
22#define mmACP_DMA_DSCR_STRT_IDX_2 0x1240028
23#define mmACP_DMA_DSCR_STRT_IDX_3 0x124002C
24#define mmACP_DMA_DSCR_STRT_IDX_4 0x1240030
25#define mmACP_DMA_DSCR_STRT_IDX_5 0x1240034
26#define mmACP_DMA_DSCR_STRT_IDX_6 0x1240038
27#define mmACP_DMA_DSCR_STRT_IDX_7 0x124003C
28#define mmACP_DMA_DSCR_CNT_0 0x1240040
29#define mmACP_DMA_DSCR_CNT_1 0x1240044
30#define mmACP_DMA_DSCR_CNT_2 0x1240048
31#define mmACP_DMA_DSCR_CNT_3 0x124004C
32#define mmACP_DMA_DSCR_CNT_4 0x1240050
33#define mmACP_DMA_DSCR_CNT_5 0x1240054
34#define mmACP_DMA_DSCR_CNT_6 0x1240058
35#define mmACP_DMA_DSCR_CNT_7 0x124005C
36#define mmACP_DMA_PRIO_0 0x1240060
37#define mmACP_DMA_PRIO_1 0x1240064
38#define mmACP_DMA_PRIO_2 0x1240068
39#define mmACP_DMA_PRIO_3 0x124006C
40#define mmACP_DMA_PRIO_4 0x1240070
41#define mmACP_DMA_PRIO_5 0x1240074
42#define mmACP_DMA_PRIO_6 0x1240078
43#define mmACP_DMA_PRIO_7 0x124007C
44#define mmACP_DMA_CUR_DSCR_0 0x1240080
45#define mmACP_DMA_CUR_DSCR_1 0x1240084
46#define mmACP_DMA_CUR_DSCR_2 0x1240088
47#define mmACP_DMA_CUR_DSCR_3 0x124008C
48#define mmACP_DMA_CUR_DSCR_4 0x1240090
49#define mmACP_DMA_CUR_DSCR_5 0x1240094
50#define mmACP_DMA_CUR_DSCR_6 0x1240098
51#define mmACP_DMA_CUR_DSCR_7 0x124009C
52#define mmACP_DMA_CUR_TRANS_CNT_0 0x12400A0
53#define mmACP_DMA_CUR_TRANS_CNT_1 0x12400A4
54#define mmACP_DMA_CUR_TRANS_CNT_2 0x12400A8
55#define mmACP_DMA_CUR_TRANS_CNT_3 0x12400AC
56#define mmACP_DMA_CUR_TRANS_CNT_4 0x12400B0
57#define mmACP_DMA_CUR_TRANS_CNT_5 0x12400B4
58#define mmACP_DMA_CUR_TRANS_CNT_6 0x12400B8
59#define mmACP_DMA_CUR_TRANS_CNT_7 0x12400BC
60#define mmACP_DMA_ERR_STS_0 0x12400C0
61#define mmACP_DMA_ERR_STS_1 0x12400C4
62#define mmACP_DMA_ERR_STS_2 0x12400C8
63#define mmACP_DMA_ERR_STS_3 0x12400CC
64#define mmACP_DMA_ERR_STS_4 0x12400D0
65#define mmACP_DMA_ERR_STS_5 0x12400D4
66#define mmACP_DMA_ERR_STS_6 0x12400D8
67#define mmACP_DMA_ERR_STS_7 0x12400DC
68#define mmACP_DMA_DESC_BASE_ADDR 0x12400E0
69#define mmACP_DMA_DESC_MAX_NUM_DSCR 0x12400E4
70#define mmACP_DMA_CH_STS 0x12400E8
71#define mmACP_DMA_CH_GROUP 0x12400EC
72#define mmACP_DMA_CH_RST_STS 0x12400F0
73
74
75// Registers from ACP_AXI2AXIATU block
76
77#define mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_1 0x1240C00
78#define mmACPAXI2AXI_ATU_BASE_ADDR_GRP_1 0x1240C04
79#define mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_2 0x1240C08
80#define mmACPAXI2AXI_ATU_BASE_ADDR_GRP_2 0x1240C0C
81#define mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_3 0x1240C10
82#define mmACPAXI2AXI_ATU_BASE_ADDR_GRP_3 0x1240C14
83#define mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_4 0x1240C18
84#define mmACPAXI2AXI_ATU_BASE_ADDR_GRP_4 0x1240C1C
85#define mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_5 0x1240C20
86#define mmACPAXI2AXI_ATU_BASE_ADDR_GRP_5 0x1240C24
87#define mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_6 0x1240C28
88#define mmACPAXI2AXI_ATU_BASE_ADDR_GRP_6 0x1240C2C
89#define mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_7 0x1240C30
90#define mmACPAXI2AXI_ATU_BASE_ADDR_GRP_7 0x1240C34
91#define mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_8 0x1240C38
92#define mmACPAXI2AXI_ATU_BASE_ADDR_GRP_8 0x1240C3C
93#define mmACPAXI2AXI_ATU_CTRL 0x1240C40
94
95
96// Registers from ACP_CLKRST block
97
98#define mmACP_SOFT_RESET 0x1241000
99#define mmACP_CONTROL 0x1241004
100#define mmACP_STATUS 0x1241008
101#define mmACP_DSP0_OCD_HALT_ON_RST 0x124100C
102#define mmACP_DYNAMIC_CG_MASTER_CONTROL 0x1241010
103
104
105// Registers from ACP_MISC block
106
107#define mmACP_EXTERNAL_INTR_ENB 0x1241800
108#define mmACP_EXTERNAL_INTR_CNTL 0x1241804
109#define mmACP_EXTERNAL_INTR_STAT 0x1241808
110#define mmACP_DSP0_INTR_CNTL 0x124180C
111#define mmACP_DSP0_INTR_STAT 0x1241810
112#define mmACP_DSP_SW_INTR_CNTL 0x1241814
113#define mmACP_DSP_SW_INTR_STAT 0x1241818
114#define mmACP_SW_INTR_TRIG 0x124181C
115#define mmACP_SMU_MAILBOX 0x1241820
116#define mmDSP_INTERRUPT_ROUTING_CTRL 0x1241824
117#define mmACP_DSP0_WATCHDOG_TIMER_CNTL 0x1241828
118#define mmACP_DSP0_EXT_TIMER1_CNTL 0x124182C
119#define mmACP_DSP0_EXT_TIMER2_CNTL 0x1241830
120#define mmACP_DSP0_EXT_TIMER3_CNTL 0x1241834
121#define mmACP_DSP0_EXT_TIMER4_CNTL 0x1241838
122#define mmACP_DSP0_EXT_TIMER5_CNTL 0x124183C
123#define mmACP_DSP0_EXT_TIMER6_CNTL 0x1241840
124#define mmACP_DSP0_EXT_TIMER1_CURR_VALUE 0x1241844
125#define mmACP_DSP0_EXT_TIMER2_CURR_VALUE 0x1241848
126#define mmACP_DSP0_EXT_TIMER3_CURR_VALUE 0x124184C
127#define mmACP_DSP0_EXT_TIMER4_CURR_VALUE 0x1241850
128#define mmACP_DSP0_EXT_TIMER5_CURR_VALUE 0x1241854
129#define mmACP_DSP0_EXT_TIMER6_CURR_VALUE 0x1241858
130#define mmACP_FW_STATUS 0x124185C
131#define mmACP_TIMER 0x1241874
132#define mmACP_TIMER_CNTL 0x1241878
133#define mmACP_PGMEM_CTRL 0x12418C0
134#define mmACP_ERROR_STATUS 0x12418C4
135#define mmACP_SW_I2S_ERROR_REASON 0x12418C8
136#define mmACP_MEM_PG_STS 0x12418CC
137
138
139// Registers from ACP_PGFSM block
140
141#define mmACP_I2S_PIN_CONFIG 0x1241400
142#define mmACP_PAD_PULLUP_PULLDOWN_CTRL 0x1241404
143#define mmACP_PAD_DRIVE_STRENGTH_CTRL 0x1241408
144#define mmACP_SW_PAD_KEEPER_EN 0x124140C
145#define mmACP_SW_WAKE_EN 0x1241410
146#define mmACP_I2S_WAKE_EN 0x1241414
147#define mmACP_PME_EN 0x1241418
148#define mmACP_PGFSM_CONTROL 0x124141C
149#define mmACP_PGFSM_STATUS 0x1241420
150
151
152// Registers from ACP_SCRATCH block
153
154#define mmACP_SCRATCH_REG_0 0x1250000
155#define mmACP_SCRATCH_REG_1 0x1250004
156#define mmACP_SCRATCH_REG_2 0x1250008
157#define mmACP_SCRATCH_REG_3 0x125000C
158#define mmACP_SCRATCH_REG_4 0x1250010
159#define mmACP_SCRATCH_REG_5 0x1250014
160#define mmACP_SCRATCH_REG_6 0x1250018
161#define mmACP_SCRATCH_REG_7 0x125001C
162#define mmACP_SCRATCH_REG_8 0x1250020
163#define mmACP_SCRATCH_REG_9 0x1250024
164#define mmACP_SCRATCH_REG_10 0x1250028
165#define mmACP_SCRATCH_REG_11 0x125002C
166#define mmACP_SCRATCH_REG_12 0x1250030
167#define mmACP_SCRATCH_REG_13 0x1250034
168#define mmACP_SCRATCH_REG_14 0x1250038
169#define mmACP_SCRATCH_REG_15 0x125003C
170#define mmACP_SCRATCH_REG_16 0x1250040
171#define mmACP_SCRATCH_REG_17 0x1250044
172#define mmACP_SCRATCH_REG_18 0x1250048
173#define mmACP_SCRATCH_REG_19 0x125004C
174#define mmACP_SCRATCH_REG_20 0x1250050
175#define mmACP_SCRATCH_REG_21 0x1250054
176#define mmACP_SCRATCH_REG_22 0x1250058
177#define mmACP_SCRATCH_REG_23 0x125005C
178#define mmACP_SCRATCH_REG_24 0x1250060
179#define mmACP_SCRATCH_REG_25 0x1250064
180#define mmACP_SCRATCH_REG_26 0x1250068
181#define mmACP_SCRATCH_REG_27 0x125006C
182#define mmACP_SCRATCH_REG_28 0x1250070
183#define mmACP_SCRATCH_REG_29 0x1250074
184#define mmACP_SCRATCH_REG_30 0x1250078
185#define mmACP_SCRATCH_REG_31 0x125007C
186#define mmACP_SCRATCH_REG_32 0x1250080
187#define mmACP_SCRATCH_REG_33 0x1250084
188#define mmACP_SCRATCH_REG_34 0x1250088
189#define mmACP_SCRATCH_REG_35 0x125008C
190#define mmACP_SCRATCH_REG_36 0x1250090
191#define mmACP_SCRATCH_REG_37 0x1250094
192#define mmACP_SCRATCH_REG_38 0x1250098
193#define mmACP_SCRATCH_REG_39 0x125009C
194#define mmACP_SCRATCH_REG_40 0x12500A0
195#define mmACP_SCRATCH_REG_41 0x12500A4
196#define mmACP_SCRATCH_REG_42 0x12500A8
197#define mmACP_SCRATCH_REG_43 0x12500AC
198#define mmACP_SCRATCH_REG_44 0x12500B0
199#define mmACP_SCRATCH_REG_45 0x12500B4
200#define mmACP_SCRATCH_REG_46 0x12500B8
201#define mmACP_SCRATCH_REG_47 0x12500BC
202#define mmACP_SCRATCH_REG_48 0x12500C0
203#define mmACP_SCRATCH_REG_49 0x12500C4
204#define mmACP_SCRATCH_REG_50 0x12500C8
205#define mmACP_SCRATCH_REG_51 0x12500CC
206#define mmACP_SCRATCH_REG_52 0x12500D0
207#define mmACP_SCRATCH_REG_53 0x12500D4
208#define mmACP_SCRATCH_REG_54 0x12500D8
209#define mmACP_SCRATCH_REG_55 0x12500DC
210#define mmACP_SCRATCH_REG_56 0x12500E0
211#define mmACP_SCRATCH_REG_57 0x12500E4
212#define mmACP_SCRATCH_REG_58 0x12500E8
213#define mmACP_SCRATCH_REG_59 0x12500EC
214#define mmACP_SCRATCH_REG_60 0x12500F0
215#define mmACP_SCRATCH_REG_61 0x12500F4
216#define mmACP_SCRATCH_REG_62 0x12500F8
217#define mmACP_SCRATCH_REG_63 0x12500FC
218#define mmACP_SCRATCH_REG_64 0x1250100
219#define mmACP_SCRATCH_REG_65 0x1250104
220#define mmACP_SCRATCH_REG_66 0x1250108
221#define mmACP_SCRATCH_REG_67 0x125010C
222#define mmACP_SCRATCH_REG_68 0x1250110
223#define mmACP_SCRATCH_REG_69 0x1250114
224#define mmACP_SCRATCH_REG_70 0x1250118
225#define mmACP_SCRATCH_REG_71 0x125011C
226#define mmACP_SCRATCH_REG_72 0x1250120
227#define mmACP_SCRATCH_REG_73 0x1250124
228#define mmACP_SCRATCH_REG_74 0x1250128
229#define mmACP_SCRATCH_REG_75 0x125012C
230#define mmACP_SCRATCH_REG_76 0x1250130
231#define mmACP_SCRATCH_REG_77 0x1250134
232#define mmACP_SCRATCH_REG_78 0x1250138
233#define mmACP_SCRATCH_REG_79 0x125013C
234#define mmACP_SCRATCH_REG_80 0x1250140
235#define mmACP_SCRATCH_REG_81 0x1250144
236#define mmACP_SCRATCH_REG_82 0x1250148
237#define mmACP_SCRATCH_REG_83 0x125014C
238#define mmACP_SCRATCH_REG_84 0x1250150
239#define mmACP_SCRATCH_REG_85 0x1250154
240#define mmACP_SCRATCH_REG_86 0x1250158
241#define mmACP_SCRATCH_REG_87 0x125015C
242#define mmACP_SCRATCH_REG_88 0x1250160
243#define mmACP_SCRATCH_REG_89 0x1250164
244#define mmACP_SCRATCH_REG_90 0x1250168
245#define mmACP_SCRATCH_REG_91 0x125016C
246#define mmACP_SCRATCH_REG_92 0x1250170
247#define mmACP_SCRATCH_REG_93 0x1250174
248#define mmACP_SCRATCH_REG_94 0x1250178
249#define mmACP_SCRATCH_REG_95 0x125017C
250#define mmACP_SCRATCH_REG_96 0x1250180
251#define mmACP_SCRATCH_REG_97 0x1250184
252#define mmACP_SCRATCH_REG_98 0x1250188
253#define mmACP_SCRATCH_REG_99 0x125018C
254#define mmACP_SCRATCH_REG_100 0x1250190
255#define mmACP_SCRATCH_REG_101 0x1250194
256#define mmACP_SCRATCH_REG_102 0x1250198
257#define mmACP_SCRATCH_REG_103 0x125019C
258#define mmACP_SCRATCH_REG_104 0x12501A0
259#define mmACP_SCRATCH_REG_105 0x12501A4
260#define mmACP_SCRATCH_REG_106 0x12501A8
261#define mmACP_SCRATCH_REG_107 0x12501AC
262#define mmACP_SCRATCH_REG_108 0x12501B0
263#define mmACP_SCRATCH_REG_109 0x12501B4
264#define mmACP_SCRATCH_REG_110 0x12501B8
265#define mmACP_SCRATCH_REG_111 0x12501BC
266#define mmACP_SCRATCH_REG_112 0x12501C0
267#define mmACP_SCRATCH_REG_113 0x12501C4
268#define mmACP_SCRATCH_REG_114 0x12501C8
269#define mmACP_SCRATCH_REG_115 0x12501CC
270#define mmACP_SCRATCH_REG_116 0x12501D0
271#define mmACP_SCRATCH_REG_117 0x12501D4
272#define mmACP_SCRATCH_REG_118 0x12501D8
273#define mmACP_SCRATCH_REG_119 0x12501DC
274#define mmACP_SCRATCH_REG_120 0x12501E0
275#define mmACP_SCRATCH_REG_121 0x12501E4
276#define mmACP_SCRATCH_REG_122 0x12501E8
277#define mmACP_SCRATCH_REG_123 0x12501EC
278#define mmACP_SCRATCH_REG_124 0x12501F0
279#define mmACP_SCRATCH_REG_125 0x12501F4
280#define mmACP_SCRATCH_REG_126 0x12501F8
281#define mmACP_SCRATCH_REG_127 0x12501FC
282#define mmACP_SCRATCH_REG_128 0x1250200
283
284
285// Registers from ACP_SW_ACLK block
286
287#define mmSW_CORB_Base_Address 0x1243200
288#define mmSW_CORB_Write_Pointer 0x1243204
289#define mmSW_CORB_Read_Pointer 0x1243208
290#define mmSW_CORB_Control 0x124320C
291#define mmSW_CORB_Size 0x1243214
292#define mmSW_RIRB_Base_Address 0x1243218
293#define mmSW_RIRB_Write_Pointer 0x124321C
294#define mmSW_RIRB_Response_Interrupt_Count 0x1243220
295#define mmSW_RIRB_Control 0x1243224
296#define mmSW_RIRB_Size 0x1243228
297#define mmSW_RIRB_FIFO_MIN_THDL 0x124322C
298#define mmSW_imm_cmd_UPPER_WORD 0x1243230
299#define mmSW_imm_cmd_LOWER_QWORD 0x1243234
300#define mmSW_imm_resp_UPPER_WORD 0x1243238
301#define mmSW_imm_resp_LOWER_QWORD 0x124323C
302#define mmSW_imm_cmd_sts 0x1243240
303#define mmSW_BRA_BASE_ADDRESS 0x1243244
304#define mmSW_BRA_TRANSFER_SIZE 0x1243248
305#define mmSW_BRA_DMA_BUSY 0x124324C
306#define mmSW_BRA_RESP 0x1243250
307#define mmSW_BRA_RESP_FRAME_ADDR 0x1243254
308#define mmSW_BRA_CURRENT_TRANSFER_SIZE 0x1243258
309#define mmSW_STATE_CHANGE_STATUS_0TO7 0x124325C
310#define mmSW_STATE_CHANGE_STATUS_8TO11 0x1243260
311#define mmSW_STATE_CHANGE_STATUS_MASK_0to7 0x1243264
312#define mmSW_STATE_CHANGE_STATUS_MASK_8to11 0x1243268
313#define mmSW_CLK_FREQUENCY_CTRL 0x124326C
314#define mmSW_ERROR_INTR_MASK 0x1243270
315#define mmSW_PHY_TEST_MODE_DATA_OFF 0x1243274
316
317
318// Registers from ACP_SW_SWCLK block
319
320#define mmACP_SW_EN 0x1243000
321#define mmACP_SW_EN_STATUS 0x1243004
322#define mmACP_SW_FRAMESIZE 0x1243008
323#define mmACP_SW_SSP_Counter 0x124300C
324#define mmACP_SW_Audio_TX_EN 0x1243010
325#define mmACP_SW_Audio_TX_EN_STATUS 0x1243014
326#define mmACP_SW_Audio_TX_Frame_Format 0x1243018
327#define mmACP_SW_Audio_TX_SampleInterval 0x124301C
328#define mmACP_SW_Audio_TX_Hctrl_DP0 0x1243020
329#define mmACP_SW_Audio_TX_Hctrl_DP1 0x1243024
330#define mmACP_SW_Audio_TX_Hctrl_DP2 0x1243028
331#define mmACP_SW_Audio_TX_Hctrl_DP3 0x124302C
332#define mmACP_SW_Audio_TX_offset_DP0 0x1243030
333#define mmACP_SW_Audio_TX_offset_DP1 0x1243034
334#define mmACP_SW_Audio_TX_offset_DP2 0x1243038
335#define mmACP_SW_Audio_TX_offset_DP3 0x124303C
336#define mmACP_SW_Audio_TX_Channel_Enable_DP0 0x1243040
337#define mmACP_SW_Audio_TX_Channel_Enable_DP1 0x1243044
338#define mmACP_SW_Audio_TX_Channel_Enable_DP2 0x1243048
339#define mmACP_SW_Audio_TX_Channel_Enable_DP3 0x124304C
340#define mmACP_SW_BT_TX_EN 0x1243050
341#define mmACP_SW_BT_TX_EN_STATUS 0x1243054
342#define mmACP_SW_BT_TX_Frame_Format 0x1243058
343#define mmACP_SW_BT_TX_SampleInterval 0x124305C
344#define mmACP_SW_BT_TX_Hctrl 0x1243060
345#define mmACP_SW_BT_TX_offset 0x1243064
346#define mmACP_SW_BT_TX_Channel_Enable_DP0 0x1243068
347#define mmACP_SW_Headset_TX_EN 0x124306C
348#define mmACP_SW_Headset_TX_EN_STATUS 0x1243070
349#define mmACP_SW_Headset_TX_Frame_Format 0x1243074
350#define mmACP_SW_Headset_TX_SampleInterval 0x1243078
351#define mmACP_SW_Headset_TX_Hctrl 0x124307C
352#define mmACP_SW_Headset_TX_offset 0x1243080
353#define mmACP_SW_Headset_TX_Channel_Enable_DP0 0x1243084
354#define mmACP_SW_Audio_RX_EN 0x1243088
355#define mmACP_SW_Audio_RX_EN_STATUS 0x124308C
356#define mmACP_SW_Audio_RX_Frame_Format 0x1243090
357#define mmACP_SW_Audio_RX_SampleInterval 0x1243094
358#define mmACP_SW_Audio_RX_Hctrl_DP0 0x1243098
359#define mmACP_SW_Audio_RX_Hctrl_DP1 0x124309C
360#define mmACP_SW_Audio_RX_Hctrl_DP2 0x1243100
361#define mmACP_SW_Audio_RX_Hctrl_DP3 0x1243104
362#define mmACP_SW_Audio_RX_offset_DP0 0x1243108
363#define mmACP_SW_Audio_RX_offset_DP1 0x124310C
364#define mmACP_SW_Audio_RX_offset_DP2 0x1243110
365#define mmACP_SW_Audio_RX_offset_DP3 0x1243114
366#define mmACP_SW_Audio_RX_Channel_Enable_DP0 0x1243118
367#define mmACP_SW_Audio_RX_Channel_Enable_DP1 0x124311C
368#define mmACP_SW_Audio_RX_Channel_Enable_DP2 0x1243120
369#define mmACP_SW_Audio_RX_Channel_Enable_DP3 0x1243124
370#define mmACP_SW_BT_RX_EN 0x1243128
371#define mmACP_SW_BT_RX_EN_STATUS 0x124312C
372#define mmACP_SW_BT_RX_Frame_Format 0x1243130
373#define mmACP_SW_BT_RX_SampleInterval 0x1243134
374#define mmACP_SW_BT_RX_Hctrl 0x1243138
375#define mmACP_SW_BT_RX_offset 0x124313C
376#define mmACP_SW_BT_RX_Channel_Enable_DP0 0x1243140
377#define mmACP_SW_Headset_RX_EN 0x1243144
378#define mmACP_SW_Headset_RX_EN_STATUS 0x1243148
379#define mmACP_SW_Headset_RX_Frame_Format 0x124314C
380#define mmACP_SW_Headset_RX_SampleInterval 0x1243150
381#define mmACP_SW_Headset_RX_Hctrl 0x1243154
382#define mmACP_SW_Headset_RX_offset 0x1243158
383#define mmACP_SW_Headset_RX_Channel_Enable_DP0 0x124315C
384#define mmACP_SW_BPT_PORT_EN 0x1243160
385#define mmACP_SW_BPT_PORT_EN_STATUS 0x1243164
386#define mmACP_SW_BPT_PORT_Frame_Format 0x1243168
387#define mmACP_SW_BPT_PORT_SampleInterval 0x124316C
388#define mmACP_SW_BPT_PORT_Hctrl 0x1243170
389#define mmACP_SW_BPT_PORT_offset 0x1243174
390#define mmACP_SW_BPT_PORT_Channel_Enable 0x1243178
391#define mmACP_SW_BPT_PORT_First_byte_addr 0x124317C
392#define mmACP_SW_CLK_RESUME_CTRL 0x1243180
393#define mmACP_SW_CLK_RESUME_Delay_Cntr 0x1243184
394#define mmACP_SW_BUS_RESET_CTRL 0x1243188
395#define mmACP_SW_PRBS_ERR_STATUS 0x124318C
396
397
398// Registers from ACP_AUDIO_BUFFERS block
399
400#define mmACP_I2S_RX_RINGBUFADDR 0x1242000
401#define mmACP_I2S_RX_RINGBUFSIZE 0x1242004
402#define mmACP_I2S_RX_LINKPOSITIONCNTR 0x1242008
403#define mmACP_I2S_RX_FIFOADDR 0x124200C
404#define mmACP_I2S_RX_FIFOSIZE 0x1242010
405#define mmACP_I2S_RX_DMA_SIZE 0x1242014
406#define mmACP_I2S_RX_LINEARPOSITIONCNTR_HIGH 0x1242018
407#define mmACP_I2S_RX_LINEARPOSITIONCNTR_LOW 0x124201C
408#define mmACP_I2S_RX_INTR_WATERMARK_SIZE 0x1242020
409#define mmACP_I2S_TX_RINGBUFADDR 0x1242024
410#define mmACP_I2S_TX_RINGBUFSIZE 0x1242028
411#define mmACP_I2S_TX_LINKPOSITIONCNTR 0x124202C
412#define mmACP_I2S_TX_FIFOADDR 0x1242030
413#define mmACP_I2S_TX_FIFOSIZE 0x1242034
414#define mmACP_I2S_TX_DMA_SIZE 0x1242038
415#define mmACP_I2S_TX_LINEARPOSITIONCNTR_HIGH 0x124203C
416#define mmACP_I2S_TX_LINEARPOSITIONCNTR_LOW 0x1242040
417#define mmACP_I2S_TX_INTR_WATERMARK_SIZE 0x1242044
418#define mmACP_BT_RX_RINGBUFADDR 0x1242048
419#define mmACP_BT_RX_RINGBUFSIZE 0x124204C
420#define mmACP_BT_RX_LINKPOSITIONCNTR 0x1242050
421#define mmACP_BT_RX_FIFOADDR 0x1242054
422#define mmACP_BT_RX_FIFOSIZE 0x1242058
423#define mmACP_BT_RX_DMA_SIZE 0x124205C
424#define mmACP_BT_RX_LINEARPOSITIONCNTR_HIGH 0x1242060
425#define mmACP_BT_RX_LINEARPOSITIONCNTR_LOW 0x1242064
426#define mmACP_BT_RX_INTR_WATERMARK_SIZE 0x1242068
427#define mmACP_BT_TX_RINGBUFADDR 0x124206C
428#define mmACP_BT_TX_RINGBUFSIZE 0x1242070
429#define mmACP_BT_TX_LINKPOSITIONCNTR 0x1242074
430#define mmACP_BT_TX_FIFOADDR 0x1242078
431#define mmACP_BT_TX_FIFOSIZE 0x124207C
432#define mmACP_BT_TX_DMA_SIZE 0x1242080
433#define mmACP_BT_TX_LINEARPOSITIONCNTR_HIGH 0x1242084
434#define mmACP_BT_TX_LINEARPOSITIONCNTR_LOW 0x1242088
435#define mmACP_BT_TX_INTR_WATERMARK_SIZE 0x124208C
436#define mmACP_HS_RX_RINGBUFADDR 0x1242090
437#define mmACP_HS_RX_RINGBUFSIZE 0x1242094
438#define mmACP_HS_RX_LINKPOSITIONCNTR 0x1242098
439#define mmACP_HS_RX_FIFOADDR 0x124209C
440#define mmACP_HS_RX_FIFOSIZE 0x12420A0
441#define mmACP_HS_RX_DMA_SIZE 0x12420A4
442#define mmACP_HS_RX_LINEARPOSITIONCNTR_HIGH 0x12420A8
443#define mmACP_HS_RX_LINEARPOSITIONCNTR_LOW 0x12420AC
444#define mmACP_HS_RX_INTR_WATERMARK_SIZE 0x12420B0
445#define mmACP_HS_TX_RINGBUFADDR 0x12420B4
446#define mmACP_HS_TX_RINGBUFSIZE 0x12420B8
447#define mmACP_HS_TX_LINKPOSITIONCNTR 0x12420BC
448#define mmACP_HS_TX_FIFOADDR 0x12420C0
449#define mmACP_HS_TX_FIFOSIZE 0x12420C4
450#define mmACP_HS_TX_DMA_SIZE 0x12420C8
451#define mmACP_HS_TX_LINEARPOSITIONCNTR_HIGH 0x12420CC
452#define mmACP_HS_TX_LINEARPOSITIONCNTR_LOW 0x12420D0
453#define mmACP_HS_TX_INTR_WATERMARK_SIZE 0x12420D4
454
455
456// Registers from ACP_I2S_TDM block
457
458#define mmACP_I2STDM_IER 0x1242400
459#define mmACP_I2STDM_IRER 0x1242404
460#define mmACP_I2STDM_RXFRMT 0x1242408
461#define mmACP_I2STDM_ITER 0x124240C
462#define mmACP_I2STDM_TXFRMT 0x1242410
463
464
465// Registers from ACP_BT_TDM block
466
467#define mmACP_BTTDM_IER 0x1242800
468#define mmACP_BTTDM_IRER 0x1242804
469#define mmACP_BTTDM_RXFRMT 0x1242808
470#define mmACP_BTTDM_ITER 0x124280C
471#define mmACP_BTTDM_TXFRMT 0x1242810
472
473
474// Registers from AZALIA_IP block
475
476#define mmAudio_Az_Global_Capabilities 0x1200000
477#define mmAudio_Az_Minor_Version 0x1200002
478#define mmAudio_Az_Major_Version 0x1200003
479#define mmAudio_Az_Output_Payload_Capability 0x1200004
480#define mmAudio_Az_Input_Payload_Capability 0x1200006
481#define mmAudio_Az_Global_Control 0x1200008
482#define mmAudio_Az_Wake_Enable 0x120000C
483#define mmAudio_Az_State_Change_Status 0x120000E
484#define mmAudio_Az_Global_Status 0x1200010
485#define mmAudio_Az_Linked_List_Capability_Header 0x1200014
486#define mmAudio_Az_Output_Stream_Payload_Capability 0x1200018
487#define mmAudio_Az_Input_Stream_Payload_Capability 0x120001A
488#define mmAudio_Az_Interrupt_Control 0x1200020
489#define mmAudio_Az_Interrupt_Status 0x1200024
490#define mmAudio_Az_Wall_Clock_Counter 0x1200030
491#define mmAudio_Az_Stream_Synchronization 0x1200038
492#define mmAudio_Az_CORB_Lower_Base_Address 0x1200040
493#define mmAudio_Az_CORB_Upper_Base_Address 0x1200044
494#define mmAudio_Az_CORB_Write_Pointer 0x1200048
495#define mmAudio_Az_CORB_Read_Pointer 0x120004A
496#define mmAudio_Az_CORB_Control 0x120004C
497#define mmAudio_Az_CORB_Status 0x120004D
498#define mmAudio_Az_CORB_Size 0x120004E
499#define mmAudio_Az_RIRB_Lower_Base_Address 0x1200050
500#define mmAudio_Az_RIRB_Upper_Base_Address 0x1200054
501#define mmAudio_Az_RIRB_Write_Pointer 0x1200058
502#define mmAudio_Az_RIRB_Response_Interrupt_Count 0x120005A
503#define mmAudio_Az_RIRB_Control 0x120005C
504#define mmAudio_Az_RIRB_Status 0x120005D
505#define mmAudio_Az_RIRB_Size 0x120005E
506#define mmAudio_Az_Immediate_Command_Output_Interface 0x1200060
507#define mmAudio_Az_Immediate_Response_Input_Interface 0x1200064
508#define mmAudio_Az_Immediate_Command_Status 0x1200068
509#define mmAudio_Az_DPLBASE 0x1200070
510#define mmAudio_Az_DPUBASE 0x1200074
511#define mmAudio_Az_Input_SD0CTL_and_STS 0x1200080
512#define mmAudio_Az_Input_SD0LPIB 0x1200084
513#define mmAudio_Az_Input_SD0CBL 0x1200088
514#define mmAudio_Az_Input_SD0LVI 0x120008C
515#define mmAudio_Az_Input_SD0FIFOS 0x1200090
516#define mmAudio_Az_Input_SD0FMT 0x1200092
517#define mmAudio_Az_Input_SD0BDPL 0x1200098
518#define mmAudio_Az_Input_SD0BDPU 0x120009C
519#define mmAudio_Az_Input_SD1CTL_and_STS 0x12000A0
520#define mmAudio_Az_Input_SD1LPIB 0x12000A4
521#define mmAudio_Az_Input_SD1CBL 0x12000A8
522#define mmAudio_Az_Input_SD1LVI 0x12000AC
523#define mmAudio_Az_Input_SD1FIFOS 0x12000B0
524#define mmAudio_Az_Input_SD1FMT 0x12000B2
525#define mmAudio_Az_Input_SD1BDPL 0x12000B8
526#define mmAudio_Az_Input_SD1BDPU 0x12000BC
527#define mmAudio_Az_Input_SD2CTL_and_STS 0x12000C0
528#define mmAudio_Az_Input_SD2LPIB 0x12000C4
529#define mmAudio_Az_Input_SD2CBL 0x12000C8
530#define mmAudio_Az_Input_SD2LVI 0x12000CC
531#define mmAudio_Az_Input_SD2FIFOS 0x12000D0
532#define mmAudio_Az_Input_SD2FMT 0x12000D2
533#define mmAudio_Az_Input_SD2BDPL 0x12000D8
534#define mmAudio_Az_Input_SD2BDPU 0x12000DC
535#define mmAudio_Az_Input_SD3CTL_and_STS 0x12000E0
536#define mmAudio_Az_Input_SD3LPIB 0x12000E4
537#define mmAudio_Az_Input_SD3CBL 0x12000E8
538#define mmAudio_Az_Input_SD3LVI 0x12000EC
539#define mmAudio_Az_Input_SD3FIFOS 0x12000F0
540#define mmAudio_Az_Input_SD3FMT 0x12000F2
541#define mmAudio_Az_Input_SD3BDPL 0x12000F8
542#define mmAudio_Az_Input_SD3BDPU 0x12000FC
543#define mmAudio_Az_Output_SD0CTL_and_STS 0x1200100
544#define mmAudio_Az_Output_SD0LPIB 0x1200104
545#define mmAudio_Az_Output_SD0CBL 0x1200108
546#define mmAudio_Az_Output_SD0LVI 0x120010C
547#define mmAudio_Az_Output_SD0FIFOS 0x1200110
548#define mmAudio_Az_Output_SD0FMT 0x1200112
549#define mmAudio_Az_Output_SD0BDPL 0x1200118
550#define mmAudio_Az_Output_SD0BDPU 0x120011C
551#define mmAudio_Az_Output_SD1CTL_and_STS 0x1200120
552#define mmAudio_Az_Output_SD1LPIB 0x1200124
553#define mmAudio_Az_Output_SD1CBL 0x1200128
554#define mmAudio_Az_Output_SD1LVI 0x120012C
555#define mmAudio_Az_Output_SD1FIFOS 0x1200130
556#define mmAudio_Az_Output_SD1FMT 0x1200132
557#define mmAudio_Az_Output_SD1BDPL 0x1200138
558#define mmAudio_Az_Output_SD1BDPU 0x120013C
559#define mmAudio_Az_Output_SD2CTL_and_STS 0x1200140
560#define mmAudio_Az_Output_SD2LPIB 0x1200144
561#define mmAudio_Az_Output_SD2CBL 0x1200148
562#define mmAudio_Az_Output_SD2LVI 0x120014C
563#define mmAudio_Az_Output_SD2FIFOS 0x1200150
564#define mmAudio_Az_Output_SD2FMT 0x1200152
565#define mmAudio_Az_Output_SD2BDPL 0x1200158
566#define mmAudio_Az_Output_SD2BDPU 0x120015C
567#define mmAudio_Az_Output_SD3CTL_and_STS 0x1200160
568#define mmAudio_Az_Output_SD3LPIB 0x1200164
569#define mmAudio_Az_Output_SD3CBL 0x1200168
570#define mmAudio_Az_Output_SD3LVI 0x120016C
571#define mmAudio_Az_Output_SD3FIFOS 0x1200170
572#define mmAudio_Az_Output_SD3FMT 0x1200172
573#define mmAudio_Az_Output_SD3BDPL 0x1200178
574#define mmAudio_Az_Output_SD3BDPU 0x120017C
575#define mmAudioAZ_Misc_Control_Register_1 0x1200180
576#define mmAudioAZ_Misc_Control_Register_2 0x1200182
577#define mmAudioAZ_Misc_Control_Register_3 0x1200183
578#define mmAudio_AZ_Multiple_Links_Capability_Header 0x1200200
579#define mmAudio_AZ_Multiple_Links_Capability_Declaration 0x1200204
580#define mmAudio_AZ_Link0_Capabilities 0x1200240
581#define mmAudio_AZ_Link0_Control 0x1200244
582#define mmAudio_AZ_Link0_Output_Stream_ID 0x1200248
583#define mmAudio_AZ_Link0_SDI_Identifier 0x120024C
584#define mmAudio_AZ_Link0_Per_Stream_Overhead 0x1200250
585#define mmAudio_AZ_Link0_Wall_Frame_Counter 0x1200258
586#define mmAudio_AZ_Link0_Output_Payload_Capability_L 0x1200260
587#define mmAudio_AZ_Link0_Output_Payload_Capability_U 0x1200264
588#define mmAudio_AZ_Link0_Input_Payload_Capability_L 0x1200270
589#define mmAudio_AZ_Link0_Input_Payload_Capability_U 0x1200274
590#define mmAudio_Az_Input_SD0LICBA 0x1202084
591#define mmAudio_Az_Input_SD1LICBA 0x12020A4
592#define mmAudio_Az_Input_SD2LICBA 0x12020C4
593#define mmAudio_Az_Input_SD3LICBA 0x12020E4
594#define mmAudio_Az_Output_SD0LICBA 0x1202104
595#define mmAudio_Az_Output_SD1LICBA 0x1202124
596#define mmAudio_Az_Output_SD2LICBA 0x1202144
597#define mmAudio_Az_Output_SD3LICBA 0x1202164
598#define mmAUDIO_AZ_POWER_MANAGEMENT_CONTROL 0x1204000
599#define mmAUDIO_AZ_IOC_SOFTRST_CONTROL 0x1204004
600#define mmAUDIO_AZ_IOC_CLKGATE_CONTROL 0x1204008
601
602
603// Registers from ACP_AZALIA block
604
605#define mmACP_AZ_PAGE0_LBASE_ADDR 0x1243800
606#define mmACP_AZ_PAGE0_UBASE_ADDR 0x1243804
607#define mmACP_AZ_PAGE0_PGEN_SIZE 0x1243808
608#define mmACP_AZ_PAGE0_OFFSET 0x124380C
609#define mmACP_AZ_PAGE1_LBASE_ADDR 0x1243810
610#define mmACP_AZ_PAGE1_UBASE_ADDR 0x1243814
611#define mmACP_AZ_PAGE1_PGEN_SIZE 0x1243818
612#define mmACP_AZ_PAGE1_OFFSET 0x124381C
613#define mmACP_AZ_PAGE2_LBASE_ADDR 0x1243820
614#define mmACP_AZ_PAGE2_UBASE_ADDR 0x1243824
615#define mmACP_AZ_PAGE2_PGEN_SIZE 0x1243828
616#define mmACP_AZ_PAGE2_OFFSET 0x124382C
617#define mmACP_AZ_PAGE3_LBASE_ADDR 0x1243830
618#define mmACP_AZ_PAGE3_UBASE_ADDR 0x1243834
619#define mmACP_AZ_PAGE3_PGEN_SIZE 0x1243838
620#define mmACP_AZ_PAGE3_OFFSET 0x124383C
621#define mmACP_AZ_PAGE4_LBASE_ADDR 0x1243840
622#define mmACP_AZ_PAGE4_UBASE_ADDR 0x1243844
623#define mmACP_AZ_PAGE4_PGEN_SIZE 0x1243848
624#define mmACP_AZ_PAGE4_OFFSET 0x124384C
625#define mmACP_AZ_PAGE5_LBASE_ADDR 0x1243850
626#define mmACP_AZ_PAGE5_UBASE_ADDR 0x1243854
627#define mmACP_AZ_PAGE5_PGEN_SIZE 0x1243858
628#define mmACP_AZ_PAGE5_OFFSET 0x124385C
629#define mmACP_AZ_PAGE6_LBASE_ADDR 0x1243860
630#define mmACP_AZ_PAGE6_UBASE_ADDR 0x1243864
631#define mmACP_AZ_PAGE6_PGEN_SIZE 0x1243868
632#define mmACP_AZ_PAGE6_OFFSET 0x124386C
633#define mmACP_AZ_PAGE7_LBASE_ADDR 0x1243870
634#define mmACP_AZ_PAGE7_UBASE_ADDR 0x1243874
635#define mmACP_AZ_PAGE7_PGEN_SIZE 0x1243878
636#define mmACP_AZ_PAGE7_OFFSET 0x124387C
637
638
639#endif
diff --git a/sound/soc/amd/raven/pci-acp3x.c b/sound/soc/amd/raven/pci-acp3x.c
new file mode 100644
index 000000000000..facec2472b34
--- /dev/null
+++ b/sound/soc/amd/raven/pci-acp3x.c
@@ -0,0 +1,156 @@
1// SPDX-License-Identifier: GPL-2.0+
2//
3// AMD ACP PCI Driver
4//
5//Copyright 2016 Advanced Micro Devices, Inc.
6
7#include <linux/pci.h>
8#include <linux/module.h>
9#include <linux/io.h>
10#include <linux/platform_device.h>
11#include <linux/interrupt.h>
12
13#include "acp3x.h"
14
15struct acp3x_dev_data {
16 void __iomem *acp3x_base;
17 bool acp3x_audio_mode;
18 struct resource *res;
19 struct platform_device *pdev;
20};
21
22static int snd_acp3x_probe(struct pci_dev *pci,
23 const struct pci_device_id *pci_id)
24{
25 int ret;
26 u32 addr, val;
27 struct acp3x_dev_data *adata;
28 struct platform_device_info pdevinfo;
29 unsigned int irqflags;
30
31 if (pci_enable_device(pci)) {
32 dev_err(&pci->dev, "pci_enable_device failed\n");
33 return -ENODEV;
34 }
35
36 ret = pci_request_regions(pci, "AMD ACP3x audio");
37 if (ret < 0) {
38 dev_err(&pci->dev, "pci_request_regions failed\n");
39 goto disable_pci;
40 }
41
42 adata = devm_kzalloc(&pci->dev, sizeof(struct acp3x_dev_data),
43 GFP_KERNEL);
44 if (!adata) {
45 ret = -ENOMEM;
46 goto release_regions;
47 }
48
49 /* check for msi interrupt support */
50 ret = pci_enable_msi(pci);
51 if (ret)
52 /* msi is not enabled */
53 irqflags = IRQF_SHARED;
54 else
55 /* msi is enabled */
56 irqflags = 0;
57
58 addr = pci_resource_start(pci, 0);
59 adata->acp3x_base = ioremap(addr, pci_resource_len(pci, 0));
60 if (!adata->acp3x_base) {
61 ret = -ENOMEM;
62 goto release_regions;
63 }
64 pci_set_master(pci);
65 pci_set_drvdata(pci, adata);
66
67 val = rv_readl(adata->acp3x_base + mmACP_I2S_PIN_CONFIG);
68 switch (val) {
69 case I2S_MODE:
70 adata->res = devm_kzalloc(&pci->dev,
71 sizeof(struct resource) * 2,
72 GFP_KERNEL);
73 if (!adata->res) {
74 ret = -ENOMEM;
75 goto unmap_mmio;
76 }
77
78 adata->res[0].name = "acp3x_i2s_iomem";
79 adata->res[0].flags = IORESOURCE_MEM;
80 adata->res[0].start = addr;
81 adata->res[0].end = addr + (ACP3x_REG_END - ACP3x_REG_START);
82
83 adata->res[1].name = "acp3x_i2s_irq";
84 adata->res[1].flags = IORESOURCE_IRQ;
85 adata->res[1].start = pci->irq;
86 adata->res[1].end = pci->irq;
87
88 adata->acp3x_audio_mode = ACP3x_I2S_MODE;
89
90 memset(&pdevinfo, 0, sizeof(pdevinfo));
91 pdevinfo.name = "acp3x_rv_i2s";
92 pdevinfo.id = 0;
93 pdevinfo.parent = &pci->dev;
94 pdevinfo.num_res = 2;
95 pdevinfo.res = adata->res;
96 pdevinfo.data = &irqflags;
97 pdevinfo.size_data = sizeof(irqflags);
98
99 adata->pdev = platform_device_register_full(&pdevinfo);
100 if (IS_ERR(adata->pdev)) {
101 dev_err(&pci->dev, "cannot register %s device\n",
102 pdevinfo.name);
103 ret = PTR_ERR(adata->pdev);
104 goto unmap_mmio;
105 }
106 break;
107 default:
108 dev_err(&pci->dev, "Invalid ACP audio mode : %d\n", val);
109 ret = -ENODEV;
110 goto unmap_mmio;
111 }
112 return 0;
113
114unmap_mmio:
115 pci_disable_msi(pci);
116 iounmap(adata->acp3x_base);
117release_regions:
118 pci_release_regions(pci);
119disable_pci:
120 pci_disable_device(pci);
121
122 return ret;
123}
124
125static void snd_acp3x_remove(struct pci_dev *pci)
126{
127 struct acp3x_dev_data *adata = pci_get_drvdata(pci);
128
129 platform_device_unregister(adata->pdev);
130 iounmap(adata->acp3x_base);
131
132 pci_disable_msi(pci);
133 pci_release_regions(pci);
134 pci_disable_device(pci);
135}
136
137static const struct pci_device_id snd_acp3x_ids[] = {
138 { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x15e2),
139 .class = PCI_CLASS_MULTIMEDIA_OTHER << 8,
140 .class_mask = 0xffffff },
141 { 0, },
142};
143MODULE_DEVICE_TABLE(pci, snd_acp3x_ids);
144
145static struct pci_driver acp3x_driver = {
146 .name = KBUILD_MODNAME,
147 .id_table = snd_acp3x_ids,
148 .probe = snd_acp3x_probe,
149 .remove = snd_acp3x_remove,
150};
151
152module_pci_driver(acp3x_driver);
153
154MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com");
155MODULE_DESCRIPTION("AMD ACP3x PCI driver");
156MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 9cc4f1848c9b..62bdb7e333b8 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -35,6 +35,7 @@ config SND_SOC_ALL_CODECS
35 select SND_SOC_ADAU7002 35 select SND_SOC_ADAU7002
36 select SND_SOC_ADS117X 36 select SND_SOC_ADS117X
37 select SND_SOC_AK4104 if SPI_MASTER 37 select SND_SOC_AK4104 if SPI_MASTER
38 select SND_SOC_AK4118 if I2C
38 select SND_SOC_AK4458 if I2C 39 select SND_SOC_AK4458 if I2C
39 select SND_SOC_AK4535 if I2C 40 select SND_SOC_AK4535 if I2C
40 select SND_SOC_AK4554 41 select SND_SOC_AK4554
@@ -392,6 +393,11 @@ config SND_SOC_AK4104
392 tristate "AKM AK4104 CODEC" 393 tristate "AKM AK4104 CODEC"
393 depends on SPI_MASTER 394 depends on SPI_MASTER
394 395
396config SND_SOC_AK4118
397 tristate "AKM AK4118 CODEC"
398 depends on I2C
399 select REGMAP_I2C
400
395config SND_SOC_AK4458 401config SND_SOC_AK4458
396 tristate "AKM AK4458 CODEC" 402 tristate "AKM AK4458 CODEC"
397 depends on I2C 403 depends on I2C
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 8ffab8c8dbfa..66f55d185620 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -27,6 +27,7 @@ snd-soc-adav801-objs := adav801.o
27snd-soc-adav803-objs := adav803.o 27snd-soc-adav803-objs := adav803.o
28snd-soc-ads117x-objs := ads117x.o 28snd-soc-ads117x-objs := ads117x.o
29snd-soc-ak4104-objs := ak4104.o 29snd-soc-ak4104-objs := ak4104.o
30snd-soc-ak4118-objs := ak4118.o
30snd-soc-ak4458-objs := ak4458.o 31snd-soc-ak4458-objs := ak4458.o
31snd-soc-ak4535-objs := ak4535.o 32snd-soc-ak4535-objs := ak4535.o
32snd-soc-ak4554-objs := ak4554.o 33snd-soc-ak4554-objs := ak4554.o
@@ -290,6 +291,7 @@ obj-$(CONFIG_SND_SOC_ADAV801) += snd-soc-adav801.o
290obj-$(CONFIG_SND_SOC_ADAV803) += snd-soc-adav803.o 291obj-$(CONFIG_SND_SOC_ADAV803) += snd-soc-adav803.o
291obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o 292obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
292obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o 293obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
294obj-$(CONFIG_SND_SOC_AK4118) += snd-soc-ak4118.o
293obj-$(CONFIG_SND_SOC_AK4458) += snd-soc-ak4458.o 295obj-$(CONFIG_SND_SOC_AK4458) += snd-soc-ak4458.o
294obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 296obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
295obj-$(CONFIG_SND_SOC_AK4554) += snd-soc-ak4554.o 297obj-$(CONFIG_SND_SOC_AK4554) += snd-soc-ak4554.o
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 32bc545c19cf..6dec8a65eafc 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -13,7 +13,7 @@
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/spi/spi.h> 14#include <linux/spi/spi.h>
15#include <linux/of_device.h> 15#include <linux/of_device.h>
16#include <linux/of_gpio.h> 16#include <linux/gpio/consumer.h>
17#include <linux/regulator/consumer.h> 17#include <linux/regulator/consumer.h>
18#include <sound/asoundef.h> 18#include <sound/asoundef.h>
19#include <sound/core.h> 19#include <sound/core.h>
@@ -268,8 +268,8 @@ static const struct regmap_config ak4104_regmap = {
268 268
269static int ak4104_spi_probe(struct spi_device *spi) 269static int ak4104_spi_probe(struct spi_device *spi)
270{ 270{
271 struct device_node *np = spi->dev.of_node;
272 struct ak4104_private *ak4104; 271 struct ak4104_private *ak4104;
272 struct gpio_desc *reset_gpiod;
273 unsigned int val; 273 unsigned int val;
274 int ret; 274 int ret;
275 275
@@ -297,19 +297,11 @@ static int ak4104_spi_probe(struct spi_device *spi)
297 return ret; 297 return ret;
298 } 298 }
299 299
300 if (np) { 300 reset_gpiod = devm_gpiod_get_optional(&spi->dev, "reset",
301 enum of_gpio_flags flags; 301 GPIOD_OUT_HIGH);
302 int gpio = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags); 302 if (IS_ERR(reset_gpiod) &&
303 303 PTR_ERR(reset_gpiod) == -EPROBE_DEFER)
304 if (gpio_is_valid(gpio)) { 304 return -EPROBE_DEFER;
305 ret = devm_gpio_request_one(&spi->dev, gpio,
306 flags & OF_GPIO_ACTIVE_LOW ?
307 GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH,
308 "ak4104 reset");
309 if (ret < 0)
310 return ret;
311 }
312 }
313 305
314 /* read the 'reserved' register - according to the datasheet, it 306 /* read the 'reserved' register - according to the datasheet, it
315 * should contain 0x5b. Not a good way to verify the presence of 307 * should contain 0x5b. Not a good way to verify the presence of
diff --git a/sound/soc/codecs/ak4118.c b/sound/soc/codecs/ak4118.c
new file mode 100644
index 000000000000..238ab29f2bf4
--- /dev/null
+++ b/sound/soc/codecs/ak4118.c
@@ -0,0 +1,438 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * ak4118.c -- Asahi Kasei ALSA Soc Audio driver
4 *
5 * Copyright 2018 DEVIALET
6 */
7
8#include <linux/i2c.h>
9#include <linux/module.h>
10#include <linux/of_device.h>
11#include <linux/of_gpio.h>
12#include <linux/regmap.h>
13#include <linux/slab.h>
14
15#include <sound/asoundef.h>
16#include <sound/core.h>
17#include <sound/initval.h>
18#include <sound/soc.h>
19
20#define AK4118_REG_CLK_PWR_CTL 0x00
21#define AK4118_REG_FORMAT_CTL 0x01
22#define AK4118_REG_IO_CTL0 0x02
23#define AK4118_REG_IO_CTL1 0x03
24#define AK4118_REG_INT0_MASK 0x04
25#define AK4118_REG_INT1_MASK 0x05
26#define AK4118_REG_RCV_STATUS0 0x06
27#define AK4118_REG_RCV_STATUS1 0x07
28#define AK4118_REG_RXCHAN_STATUS0 0x08
29#define AK4118_REG_RXCHAN_STATUS1 0x09
30#define AK4118_REG_RXCHAN_STATUS2 0x0a
31#define AK4118_REG_RXCHAN_STATUS3 0x0b
32#define AK4118_REG_RXCHAN_STATUS4 0x0c
33#define AK4118_REG_TXCHAN_STATUS0 0x0d
34#define AK4118_REG_TXCHAN_STATUS1 0x0e
35#define AK4118_REG_TXCHAN_STATUS2 0x0f
36#define AK4118_REG_TXCHAN_STATUS3 0x10
37#define AK4118_REG_TXCHAN_STATUS4 0x11
38#define AK4118_REG_BURST_PREAMB_PC0 0x12
39#define AK4118_REG_BURST_PREAMB_PC1 0x13
40#define AK4118_REG_BURST_PREAMB_PD0 0x14
41#define AK4118_REG_BURST_PREAMB_PD1 0x15
42#define AK4118_REG_QSUB_CTL 0x16
43#define AK4118_REG_QSUB_TRACK 0x17
44#define AK4118_REG_QSUB_INDEX 0x18
45#define AK4118_REG_QSUB_MIN 0x19
46#define AK4118_REG_QSUB_SEC 0x1a
47#define AK4118_REG_QSUB_FRAME 0x1b
48#define AK4118_REG_QSUB_ZERO 0x1c
49#define AK4118_REG_QSUB_ABS_MIN 0x1d
50#define AK4118_REG_QSUB_ABS_SEC 0x1e
51#define AK4118_REG_QSUB_ABS_FRAME 0x1f
52#define AK4118_REG_GPE 0x20
53#define AK4118_REG_GPDR 0x21
54#define AK4118_REG_GPSCR 0x22
55#define AK4118_REG_GPLR 0x23
56#define AK4118_REG_DAT_MASK_DTS 0x24
57#define AK4118_REG_RX_DETECT 0x25
58#define AK4118_REG_STC_DAT_DETECT 0x26
59#define AK4118_REG_RXCHAN_STATUS5 0x27
60#define AK4118_REG_TXCHAN_STATUS5 0x28
61#define AK4118_REG_MAX 0x29
62
63#define AK4118_REG_FORMAT_CTL_DIF0 (1 << 4)
64#define AK4118_REG_FORMAT_CTL_DIF1 (1 << 5)
65#define AK4118_REG_FORMAT_CTL_DIF2 (1 << 6)
66
67struct ak4118_priv {
68 struct regmap *regmap;
69 struct gpio_desc *reset;
70 struct gpio_desc *irq;
71 struct snd_soc_component *component;
72};
73
74static const struct reg_default ak4118_reg_defaults[] = {
75 {AK4118_REG_CLK_PWR_CTL, 0x43},
76 {AK4118_REG_FORMAT_CTL, 0x6a},
77 {AK4118_REG_IO_CTL0, 0x88},
78 {AK4118_REG_IO_CTL1, 0x48},
79 {AK4118_REG_INT0_MASK, 0xee},
80 {AK4118_REG_INT1_MASK, 0xb5},
81 {AK4118_REG_RCV_STATUS0, 0x00},
82 {AK4118_REG_RCV_STATUS1, 0x10},
83 {AK4118_REG_TXCHAN_STATUS0, 0x00},
84 {AK4118_REG_TXCHAN_STATUS1, 0x00},
85 {AK4118_REG_TXCHAN_STATUS2, 0x00},
86 {AK4118_REG_TXCHAN_STATUS3, 0x00},
87 {AK4118_REG_TXCHAN_STATUS4, 0x00},
88 {AK4118_REG_GPE, 0x77},
89 {AK4118_REG_GPDR, 0x00},
90 {AK4118_REG_GPSCR, 0x00},
91 {AK4118_REG_GPLR, 0x00},
92 {AK4118_REG_DAT_MASK_DTS, 0x3f},
93 {AK4118_REG_RX_DETECT, 0x00},
94 {AK4118_REG_STC_DAT_DETECT, 0x00},
95 {AK4118_REG_TXCHAN_STATUS5, 0x00},
96};
97
98static const char * const ak4118_input_select_txt[] = {
99 "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7",
100};
101static SOC_ENUM_SINGLE_DECL(ak4118_insel_enum, AK4118_REG_IO_CTL1, 0x0,
102 ak4118_input_select_txt);
103
104static const struct snd_kcontrol_new ak4118_input_mux_controls =
105 SOC_DAPM_ENUM("Input Select", ak4118_insel_enum);
106
107static const char * const ak4118_iec958_fs_txt[] = {
108 "44100", "48000", "32000", "22050", "11025", "24000", "16000", "88200",
109 "8000", "96000", "64000", "176400", "192000",
110};
111
112static const int ak4118_iec958_fs_val[] = {
113 0x0, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xE,
114};
115
116static SOC_VALUE_ENUM_SINGLE_DECL(ak4118_iec958_fs_enum, AK4118_REG_RCV_STATUS1,
117 0x4, 0x4, ak4118_iec958_fs_txt,
118 ak4118_iec958_fs_val);
119
120static struct snd_kcontrol_new ak4118_iec958_controls[] = {
121 SOC_SINGLE("IEC958 Parity Errors", AK4118_REG_RCV_STATUS0, 0, 1, 0),
122 SOC_SINGLE("IEC958 No Audio", AK4118_REG_RCV_STATUS0, 1, 1, 0),
123 SOC_SINGLE("IEC958 PLL Lock", AK4118_REG_RCV_STATUS0, 4, 1, 1),
124 SOC_SINGLE("IEC958 Non PCM", AK4118_REG_RCV_STATUS0, 6, 1, 0),
125 SOC_ENUM("IEC958 Sampling Freq", ak4118_iec958_fs_enum),
126};
127
128static const struct snd_soc_dapm_widget ak4118_dapm_widgets[] = {
129 SND_SOC_DAPM_INPUT("INRX0"),
130 SND_SOC_DAPM_INPUT("INRX1"),
131 SND_SOC_DAPM_INPUT("INRX2"),
132 SND_SOC_DAPM_INPUT("INRX3"),
133 SND_SOC_DAPM_INPUT("INRX4"),
134 SND_SOC_DAPM_INPUT("INRX5"),
135 SND_SOC_DAPM_INPUT("INRX6"),
136 SND_SOC_DAPM_INPUT("INRX7"),
137 SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0,
138 &ak4118_input_mux_controls),
139};
140
141static const struct snd_soc_dapm_route ak4118_dapm_routes[] = {
142 {"Input Mux", "RX0", "INRX0"},
143 {"Input Mux", "RX1", "INRX1"},
144 {"Input Mux", "RX2", "INRX2"},
145 {"Input Mux", "RX3", "INRX3"},
146 {"Input Mux", "RX4", "INRX4"},
147 {"Input Mux", "RX5", "INRX5"},
148 {"Input Mux", "RX6", "INRX6"},
149 {"Input Mux", "RX7", "INRX7"},
150};
151
152
153static int ak4118_set_dai_fmt_master(struct ak4118_priv *ak4118,
154 unsigned int format)
155{
156 int dif;
157
158 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
159 case SND_SOC_DAIFMT_I2S:
160 dif = AK4118_REG_FORMAT_CTL_DIF0 | AK4118_REG_FORMAT_CTL_DIF2;
161 break;
162 case SND_SOC_DAIFMT_RIGHT_J:
163 dif = AK4118_REG_FORMAT_CTL_DIF0 | AK4118_REG_FORMAT_CTL_DIF1;
164 break;
165 case SND_SOC_DAIFMT_LEFT_J:
166 dif = AK4118_REG_FORMAT_CTL_DIF2;
167 break;
168 default:
169 return -ENOTSUPP;
170 }
171
172 return dif;
173}
174
175static int ak4118_set_dai_fmt_slave(struct ak4118_priv *ak4118,
176 unsigned int format)
177{
178 int dif;
179
180 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
181 case SND_SOC_DAIFMT_I2S:
182 dif = AK4118_REG_FORMAT_CTL_DIF0 | AK4118_REG_FORMAT_CTL_DIF1 |
183 AK4118_REG_FORMAT_CTL_DIF2;
184 break;
185 case SND_SOC_DAIFMT_LEFT_J:
186 dif = AK4118_REG_FORMAT_CTL_DIF1 | AK4118_REG_FORMAT_CTL_DIF2;
187 break;
188 default:
189 return -ENOTSUPP;
190 }
191
192 return dif;
193}
194
195static int ak4118_set_dai_fmt(struct snd_soc_dai *dai,
196 unsigned int format)
197{
198 struct snd_soc_component *component = dai->component;
199 struct ak4118_priv *ak4118 = snd_soc_component_get_drvdata(component);
200 int dif;
201 int ret = 0;
202
203 switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
204 case SND_SOC_DAIFMT_CBM_CFM:
205 /* component is master */
206 dif = ak4118_set_dai_fmt_master(ak4118, format);
207 break;
208 case SND_SOC_DAIFMT_CBS_CFS:
209 /*component is slave */
210 dif = ak4118_set_dai_fmt_slave(ak4118, format);
211 break;
212 default:
213 ret = -ENOTSUPP;
214 goto exit;
215 }
216
217 /* format not supported */
218 if (dif < 0) {
219 ret = dif;
220 goto exit;
221 }
222
223 ret = regmap_update_bits(ak4118->regmap, AK4118_REG_FORMAT_CTL,
224 AK4118_REG_FORMAT_CTL_DIF0 |
225 AK4118_REG_FORMAT_CTL_DIF1 |
226 AK4118_REG_FORMAT_CTL_DIF2, dif);
227 if (ret < 0)
228 goto exit;
229
230exit:
231 return ret;
232}
233
234static int ak4118_hw_params(struct snd_pcm_substream *substream,
235 struct snd_pcm_hw_params *params,
236 struct snd_soc_dai *dai)
237{
238 return 0;
239}
240
241static const struct snd_soc_dai_ops ak4118_dai_ops = {
242 .hw_params = ak4118_hw_params,
243 .set_fmt = ak4118_set_dai_fmt,
244};
245
246static struct snd_soc_dai_driver ak4118_dai = {
247 .name = "ak4118-hifi",
248 .capture = {
249 .stream_name = "Capture",
250 .channels_min = 2,
251 .channels_max = 2,
252 .rates = SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
253 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
254 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
255 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
256 .formats = SNDRV_PCM_FMTBIT_S16_LE |
257 SNDRV_PCM_FMTBIT_S24_3LE |
258 SNDRV_PCM_FMTBIT_S24_LE
259 },
260 .ops = &ak4118_dai_ops,
261};
262
263static irqreturn_t ak4118_irq_handler(int irq, void *data)
264{
265 struct ak4118_priv *ak4118 = data;
266 struct snd_soc_component *component = ak4118->component;
267 struct snd_kcontrol_new *kctl_new;
268 struct snd_kcontrol *kctl;
269 struct snd_ctl_elem_id *id;
270 unsigned int i;
271
272 if (!component)
273 return IRQ_NONE;
274
275 for (i = 0; i < ARRAY_SIZE(ak4118_iec958_controls); i++) {
276 kctl_new = &ak4118_iec958_controls[i];
277 kctl = snd_soc_card_get_kcontrol(component->card,
278 kctl_new->name);
279 if (!kctl)
280 continue;
281 id = &kctl->id;
282 snd_ctl_notify(component->card->snd_card,
283 SNDRV_CTL_EVENT_MASK_VALUE, id);
284 }
285
286 return IRQ_HANDLED;
287}
288
289static int ak4118_probe(struct snd_soc_component *component)
290{
291 struct ak4118_priv *ak4118 = snd_soc_component_get_drvdata(component);
292 int ret = 0;
293
294 ak4118->component = component;
295
296 /* release reset */
297 gpiod_set_value(ak4118->reset, 0);
298
299 /* unmask all int1 sources */
300 ret = regmap_write(ak4118->regmap, AK4118_REG_INT1_MASK, 0x00);
301 if (ret < 0) {
302 dev_err(component->dev,
303 "failed to write regmap 0x%x 0x%x: %d\n",
304 AK4118_REG_INT1_MASK, 0x00, ret);
305 return ret;
306 }
307
308 /* rx detect enable on all channels */
309 ret = regmap_write(ak4118->regmap, AK4118_REG_RX_DETECT, 0xff);
310 if (ret < 0) {
311 dev_err(component->dev,
312 "failed to write regmap 0x%x 0x%x: %d\n",
313 AK4118_REG_RX_DETECT, 0xff, ret);
314 return ret;
315 }
316
317 ret = snd_soc_add_component_controls(component, ak4118_iec958_controls,
318 ARRAY_SIZE(ak4118_iec958_controls));
319 if (ret) {
320 dev_err(component->dev,
321 "failed to add component kcontrols: %d\n", ret);
322 return ret;
323 }
324
325 return 0;
326}
327
328static void ak4118_remove(struct snd_soc_component *component)
329{
330 struct ak4118_priv *ak4118 = snd_soc_component_get_drvdata(component);
331
332 /* hold reset */
333 gpiod_set_value(ak4118->reset, 1);
334}
335
336static const struct snd_soc_component_driver soc_component_drv_ak4118 = {
337 .probe = ak4118_probe,
338 .remove = ak4118_remove,
339 .dapm_widgets = ak4118_dapm_widgets,
340 .num_dapm_widgets = ARRAY_SIZE(ak4118_dapm_widgets),
341 .dapm_routes = ak4118_dapm_routes,
342 .num_dapm_routes = ARRAY_SIZE(ak4118_dapm_routes),
343 .idle_bias_on = 1,
344 .use_pmdown_time = 1,
345 .endianness = 1,
346 .non_legacy_dai_naming = 1,
347};
348
349static const struct regmap_config ak4118_regmap = {
350 .reg_bits = 8,
351 .val_bits = 8,
352
353 .reg_defaults = ak4118_reg_defaults,
354 .num_reg_defaults = ARRAY_SIZE(ak4118_reg_defaults),
355
356 .cache_type = REGCACHE_NONE,
357 .max_register = AK4118_REG_MAX - 1,
358};
359
360static int ak4118_i2c_probe(struct i2c_client *i2c,
361 const struct i2c_device_id *id)
362{
363 struct ak4118_priv *ak4118;
364 int ret;
365
366 ak4118 = devm_kzalloc(&i2c->dev, sizeof(struct ak4118_priv),
367 GFP_KERNEL);
368 if (ak4118 == NULL)
369 return -ENOMEM;
370
371 ak4118->regmap = devm_regmap_init_i2c(i2c, &ak4118_regmap);
372 if (IS_ERR(ak4118->regmap))
373 return PTR_ERR(ak4118->regmap);
374
375 i2c_set_clientdata(i2c, ak4118);
376
377 ak4118->reset = devm_gpiod_get(&i2c->dev, "reset", GPIOD_OUT_HIGH);
378 if (IS_ERR(ak4118->reset)) {
379 ret = PTR_ERR(ak4118->reset);
380 if (ret != -EPROBE_DEFER)
381 dev_err(&i2c->dev, "Failed to get reset: %d\n", ret);
382 return ret;
383 }
384
385 ak4118->irq = devm_gpiod_get(&i2c->dev, "irq", GPIOD_IN);
386 if (IS_ERR(ak4118->irq)) {
387 ret = PTR_ERR(ak4118->irq);
388 if (ret != -EPROBE_DEFER)
389 dev_err(&i2c->dev, "Failed to get IRQ: %d\n", ret);
390 return ret;
391 }
392
393 ret = devm_request_threaded_irq(&i2c->dev, gpiod_to_irq(ak4118->irq),
394 NULL, ak4118_irq_handler,
395 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
396 "ak4118-irq", ak4118);
397 if (ret < 0) {
398 dev_err(&i2c->dev, "Fail to request_irq: %d\n", ret);
399 return ret;
400 }
401
402 return snd_soc_register_component(&i2c->dev, &soc_component_drv_ak4118,
403 &ak4118_dai, 1);
404}
405
406static int ak4118_i2c_remove(struct i2c_client *i2c)
407{
408 snd_soc_unregister_component(&i2c->dev);
409 return 0;
410}
411
412static const struct of_device_id ak4118_of_match[] = {
413 { .compatible = "asahi-kasei,ak4118", },
414 {}
415};
416MODULE_DEVICE_TABLE(of, ak4118_of_match);
417
418static const struct i2c_device_id ak4118_id_table[] = {
419 { "ak4118", 0 },
420 {}
421};
422MODULE_DEVICE_TABLE(i2c, ak4118_id_table);
423
424static struct i2c_driver ak4118_i2c_driver = {
425 .driver = {
426 .name = "ak4118",
427 .of_match_table = of_match_ptr(ak4118_of_match),
428 },
429 .id_table = ak4118_id_table,
430 .probe = ak4118_i2c_probe,
431 .remove = ak4118_i2c_remove,
432};
433
434module_i2c_driver(ak4118_i2c_driver);
435
436MODULE_DESCRIPTION("Asahi Kasei AK4118 ALSA SoC driver");
437MODULE_AUTHOR("Adrien Charruel <adrien.charruel@devialet.com>");
438MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c
index 299ada4dfaa0..70d4c89bd6fc 100644
--- a/sound/soc/codecs/ak4458.c
+++ b/sound/soc/codecs/ak4458.c
@@ -456,7 +456,7 @@ static int ak4458_startup(struct snd_pcm_substream *substream,
456 return ret; 456 return ret;
457} 457}
458 458
459static struct snd_soc_dai_ops ak4458_dai_ops = { 459static const struct snd_soc_dai_ops ak4458_dai_ops = {
460 .startup = ak4458_startup, 460 .startup = ak4458_startup,
461 .hw_params = ak4458_hw_params, 461 .hw_params = ak4458_hw_params,
462 .set_fmt = ak4458_set_dai_fmt, 462 .set_fmt = ak4458_set_dai_fmt,
diff --git a/sound/soc/codecs/ak5558.c b/sound/soc/codecs/ak5558.c
index 448bb90c9c8e..8179512129d3 100644
--- a/sound/soc/codecs/ak5558.c
+++ b/sound/soc/codecs/ak5558.c
@@ -130,16 +130,12 @@ static int ak5558_hw_params(struct snd_pcm_substream *substream,
130 u8 bits; 130 u8 bits;
131 int pcm_width = max(params_physical_width(params), ak5558->slot_width); 131 int pcm_width = max(params_physical_width(params), ak5558->slot_width);
132 132
133 /* set master/slave audio interface */
134 bits = snd_soc_component_read32(component, AK5558_02_CONTROL1);
135 bits &= ~AK5558_BITS;
136
137 switch (pcm_width) { 133 switch (pcm_width) {
138 case 16: 134 case 16:
139 bits |= AK5558_DIF_24BIT_MODE; 135 bits = AK5558_DIF_24BIT_MODE;
140 break; 136 break;
141 case 32: 137 case 32:
142 bits |= AK5558_DIF_32BIT_MODE; 138 bits = AK5558_DIF_32BIT_MODE;
143 break; 139 break;
144 default: 140 default:
145 return -EINVAL; 141 return -EINVAL;
@@ -168,18 +164,15 @@ static int ak5558_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
168 } 164 }
169 165
170 /* set master/slave audio interface */ 166 /* set master/slave audio interface */
171 format = snd_soc_component_read32(component, AK5558_02_CONTROL1);
172 format &= ~AK5558_DIF;
173
174 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 167 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
175 case SND_SOC_DAIFMT_I2S: 168 case SND_SOC_DAIFMT_I2S:
176 format |= AK5558_DIF_I2S_MODE; 169 format = AK5558_DIF_I2S_MODE;
177 break; 170 break;
178 case SND_SOC_DAIFMT_LEFT_J: 171 case SND_SOC_DAIFMT_LEFT_J:
179 format |= AK5558_DIF_MSB_MODE; 172 format = AK5558_DIF_MSB_MODE;
180 break; 173 break;
181 case SND_SOC_DAIFMT_DSP_B: 174 case SND_SOC_DAIFMT_DSP_B:
182 format |= AK5558_DIF_MSB_MODE; 175 format = AK5558_DIF_MSB_MODE;
183 break; 176 break;
184 default: 177 default:
185 return -EINVAL; 178 return -EINVAL;
@@ -246,7 +239,7 @@ static int ak5558_startup(struct snd_pcm_substream *substream,
246 &ak5558_rate_constraints); 239 &ak5558_rate_constraints);
247} 240}
248 241
249static struct snd_soc_dai_ops ak5558_dai_ops = { 242static const struct snd_soc_dai_ops ak5558_dai_ops = {
250 .startup = ak5558_startup, 243 .startup = ak5558_startup,
251 .hw_params = ak5558_hw_params, 244 .hw_params = ak5558_hw_params,
252 245
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 3c266eeb89bf..33d74f163bd7 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -29,8 +29,8 @@
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/regulator/consumer.h> 31#include <linux/regulator/consumer.h>
32#include <linux/gpio/consumer.h>
32#include <linux/of_device.h> 33#include <linux/of_device.h>
33#include <linux/of_gpio.h>
34 34
35/* 35/*
36 * The codec isn't really big-endian or little-endian, since the I2S 36 * The codec isn't really big-endian or little-endian, since the I2S
@@ -658,8 +658,8 @@ static const struct regmap_config cs4270_regmap = {
658static int cs4270_i2c_probe(struct i2c_client *i2c_client, 658static int cs4270_i2c_probe(struct i2c_client *i2c_client,
659 const struct i2c_device_id *id) 659 const struct i2c_device_id *id)
660{ 660{
661 struct device_node *np = i2c_client->dev.of_node;
662 struct cs4270_private *cs4270; 661 struct cs4270_private *cs4270;
662 struct gpio_desc *reset_gpiod;
663 unsigned int val; 663 unsigned int val;
664 int ret, i; 664 int ret, i;
665 665
@@ -678,20 +678,11 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
678 if (ret < 0) 678 if (ret < 0)
679 return ret; 679 return ret;
680 680
681 /* See if we have a way to bring the codec out of reset */ 681 reset_gpiod = devm_gpiod_get_optional(&i2c_client->dev, "reset",
682 if (np) { 682 GPIOD_OUT_HIGH);
683 enum of_gpio_flags flags; 683 if (IS_ERR(reset_gpiod) &&
684 int gpio = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags); 684 PTR_ERR(reset_gpiod) == -EPROBE_DEFER)
685 685 return -EPROBE_DEFER;
686 if (gpio_is_valid(gpio)) {
687 ret = devm_gpio_request_one(&i2c_client->dev, gpio,
688 flags & OF_GPIO_ACTIVE_LOW ?
689 GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH,
690 "cs4270 reset");
691 if (ret < 0)
692 return ret;
693 }
694 }
695 686
696 cs4270->regmap = devm_regmap_init_i2c(i2c_client, &cs4270_regmap); 687 cs4270->regmap = devm_regmap_init_i2c(i2c_client, &cs4270_regmap);
697 if (IS_ERR(cs4270->regmap)) 688 if (IS_ERR(cs4270->regmap))
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
index 71322e0410ee..da921da50ef0 100644
--- a/sound/soc/codecs/dmic.c
+++ b/sound/soc/codecs/dmic.c
@@ -30,9 +30,39 @@
30#include <sound/soc.h> 30#include <sound/soc.h>
31#include <sound/soc-dapm.h> 31#include <sound/soc-dapm.h>
32 32
33#define MAX_MODESWITCH_DELAY 70
34static int modeswitch_delay;
35module_param(modeswitch_delay, uint, 0644);
36
37static int wakeup_delay;
38module_param(wakeup_delay, uint, 0644);
39
33struct dmic { 40struct dmic {
34 struct gpio_desc *gpio_en; 41 struct gpio_desc *gpio_en;
35 int wakeup_delay; 42 int wakeup_delay;
43 /* Delay after DMIC mode switch */
44 int modeswitch_delay;
45};
46
47int dmic_daiops_trigger(struct snd_pcm_substream *substream,
48 int cmd, struct snd_soc_dai *dai)
49{
50 struct snd_soc_component *component = dai->component;
51 struct dmic *dmic = snd_soc_component_get_drvdata(component);
52
53 switch (cmd) {
54 case SNDRV_PCM_TRIGGER_STOP:
55 if (dmic->modeswitch_delay)
56 mdelay(dmic->modeswitch_delay);
57
58 break;
59 }
60
61 return 0;
62}
63
64static const struct snd_soc_dai_ops dmic_dai_ops = {
65 .trigger = dmic_daiops_trigger,
36}; 66};
37 67
38static int dmic_aif_event(struct snd_soc_dapm_widget *w, 68static int dmic_aif_event(struct snd_soc_dapm_widget *w,
@@ -68,6 +98,7 @@ static struct snd_soc_dai_driver dmic_dai = {
68 | SNDRV_PCM_FMTBIT_S24_LE 98 | SNDRV_PCM_FMTBIT_S24_LE
69 | SNDRV_PCM_FMTBIT_S16_LE, 99 | SNDRV_PCM_FMTBIT_S16_LE,
70 }, 100 },
101 .ops = &dmic_dai_ops,
71}; 102};
72 103
73static int dmic_component_probe(struct snd_soc_component *component) 104static int dmic_component_probe(struct snd_soc_component *component)
@@ -85,6 +116,15 @@ static int dmic_component_probe(struct snd_soc_component *component)
85 116
86 device_property_read_u32(component->dev, "wakeup-delay-ms", 117 device_property_read_u32(component->dev, "wakeup-delay-ms",
87 &dmic->wakeup_delay); 118 &dmic->wakeup_delay);
119 device_property_read_u32(component->dev, "modeswitch-delay-ms",
120 &dmic->modeswitch_delay);
121 if (wakeup_delay)
122 dmic->wakeup_delay = wakeup_delay;
123 if (modeswitch_delay)
124 dmic->modeswitch_delay = modeswitch_delay;
125
126 if (dmic->modeswitch_delay > MAX_MODESWITCH_DELAY)
127 dmic->modeswitch_delay = MAX_MODESWITCH_DELAY;
88 128
89 snd_soc_component_set_drvdata(component, dmic); 129 snd_soc_component_set_drvdata(component, dmic);
90 130
diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c
index 2aaa83028e55..ffecdaaa8cf2 100644
--- a/sound/soc/codecs/hdac_hda.c
+++ b/sound/soc/codecs/hdac_hda.c
@@ -46,7 +46,7 @@ static int hdac_hda_dai_set_tdm_slot(struct snd_soc_dai *dai,
46static struct hda_pcm *snd_soc_find_pcm_from_dai(struct hdac_hda_priv *hda_pvt, 46static struct hda_pcm *snd_soc_find_pcm_from_dai(struct hdac_hda_priv *hda_pvt,
47 struct snd_soc_dai *dai); 47 struct snd_soc_dai *dai);
48 48
49static struct snd_soc_dai_ops hdac_hda_dai_ops = { 49static const struct snd_soc_dai_ops hdac_hda_dai_ops = {
50 .startup = hdac_hda_dai_open, 50 .startup = hdac_hda_dai_open,
51 .shutdown = hdac_hda_dai_close, 51 .shutdown = hdac_hda_dai_close,
52 .prepare = hdac_hda_dai_prepare, 52 .prepare = hdac_hda_dai_prepare,
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 6216e502cf7b..3ab2949c1dfa 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -121,8 +121,16 @@ struct hdac_hdmi_dai_port_map {
121 struct hdac_hdmi_cvt *cvt; 121 struct hdac_hdmi_cvt *cvt;
122}; 122};
123 123
124/*
125 * pin to port mapping table where the value indicate the pin number and
126 * the index indicate the port number with 1 base.
127 */
128static const int icl_pin2port_map[] = {0x4, 0x6, 0x8, 0xa, 0xb};
129
124struct hdac_hdmi_drv_data { 130struct hdac_hdmi_drv_data {
125 unsigned int vendor_nid; 131 unsigned int vendor_nid;
132 const int *port_map; /* pin to port mapping table */
133 int port_num;
126}; 134};
127 135
128struct hdac_hdmi_priv { 136struct hdac_hdmi_priv {
@@ -1329,11 +1337,12 @@ static int hdac_hdmi_add_pin(struct hdac_device *hdev, hda_nid_t nid)
1329 return 0; 1337 return 0;
1330} 1338}
1331 1339
1332#define INTEL_VENDOR_NID 0x08 1340#define INTEL_VENDOR_NID_0x2 0x02
1333#define INTEL_GLK_VENDOR_NID 0x0b 1341#define INTEL_VENDOR_NID_0x8 0x08
1342#define INTEL_VENDOR_NID_0xb 0x0b
1334#define INTEL_GET_VENDOR_VERB 0xf81 1343#define INTEL_GET_VENDOR_VERB 0xf81
1335#define INTEL_SET_VENDOR_VERB 0x781 1344#define INTEL_SET_VENDOR_VERB 0x781
1336#define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */ 1345#define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */
1337#define INTEL_EN_ALL_PIN_CVTS 0x01 /* enable 2nd & 3rd pins and convertors */ 1346#define INTEL_EN_ALL_PIN_CVTS 0x01 /* enable 2nd & 3rd pins and convertors */
1338 1347
1339static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdev) 1348static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdev)
@@ -1538,7 +1547,26 @@ free_widgets:
1538 1547
1539static int hdac_hdmi_pin2port(void *aptr, int pin) 1548static int hdac_hdmi_pin2port(void *aptr, int pin)
1540{ 1549{
1541 return pin - 4; /* map NID 0x05 -> port #1 */ 1550 struct hdac_device *hdev = aptr;
1551 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
1552 const int *map = hdmi->drv_data->port_map;
1553 int i;
1554
1555 if (!hdmi->drv_data->port_num)
1556 return pin - 4; /* map NID 0x05 -> port #1 */
1557
1558 /*
1559 * looking for the pin number in the mapping table and return
1560 * the index which indicate the port number
1561 */
1562 for (i = 0; i < hdmi->drv_data->port_num; i++) {
1563 if (pin == map[i])
1564 return i + 1;
1565 }
1566
1567 /* return -1 if pin number exceeds our expectation */
1568 dev_err(&hdev->dev, "Can't find the port for pin %d\n", pin);
1569 return -1;
1542} 1570}
1543 1571
1544static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe) 1572static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
@@ -1549,9 +1577,18 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
1549 struct hdac_hdmi_port *hport = NULL; 1577 struct hdac_hdmi_port *hport = NULL;
1550 struct snd_soc_component *component = hdmi->component; 1578 struct snd_soc_component *component = hdmi->component;
1551 int i; 1579 int i;
1552 1580 hda_nid_t pin_nid;
1553 /* Don't know how this mapping is derived */ 1581
1554 hda_nid_t pin_nid = port + 0x04; 1582 if (!hdmi->drv_data->port_num) {
1583 /* for legacy platforms */
1584 pin_nid = port + 0x04;
1585 } else if (port < hdmi->drv_data->port_num) {
1586 /* get pin number from the pin2port mapping table */
1587 pin_nid = hdmi->drv_data->port_map[port - 1];
1588 } else {
1589 dev_err(&hdev->dev, "Can't find the pin for port %d\n", port);
1590 return;
1591 }
1555 1592
1556 dev_dbg(&hdev->dev, "%s: for pin:%d port=%d\n", __func__, 1593 dev_dbg(&hdev->dev, "%s: for pin:%d port=%d\n", __func__,
1557 pin_nid, pipe); 1594 pin_nid, pipe);
@@ -1973,12 +2010,18 @@ static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdev, int pcm_idx)
1973 return port->eld.info.spk_alloc; 2010 return port->eld.info.spk_alloc;
1974} 2011}
1975 2012
2013static struct hdac_hdmi_drv_data intel_icl_drv_data = {
2014 .vendor_nid = INTEL_VENDOR_NID_0x2,
2015 .port_map = icl_pin2port_map,
2016 .port_num = ARRAY_SIZE(icl_pin2port_map),
2017};
2018
1976static struct hdac_hdmi_drv_data intel_glk_drv_data = { 2019static struct hdac_hdmi_drv_data intel_glk_drv_data = {
1977 .vendor_nid = INTEL_GLK_VENDOR_NID, 2020 .vendor_nid = INTEL_VENDOR_NID_0xb,
1978}; 2021};
1979 2022
1980static struct hdac_hdmi_drv_data intel_drv_data = { 2023static struct hdac_hdmi_drv_data intel_drv_data = {
1981 .vendor_nid = INTEL_VENDOR_NID, 2024 .vendor_nid = INTEL_VENDOR_NID_0x8,
1982}; 2025};
1983 2026
1984static int hdac_hdmi_dev_probe(struct hdac_device *hdev) 2027static int hdac_hdmi_dev_probe(struct hdac_device *hdev)
@@ -2246,6 +2289,8 @@ static const struct hda_device_id hdmi_list[] = {
2246 &intel_glk_drv_data), 2289 &intel_glk_drv_data),
2247 HDA_CODEC_EXT_ENTRY(0x8086280d, 0x100000, "Geminilake HDMI", 2290 HDA_CODEC_EXT_ENTRY(0x8086280d, 0x100000, "Geminilake HDMI",
2248 &intel_glk_drv_data), 2291 &intel_glk_drv_data),
2292 HDA_CODEC_EXT_ENTRY(0x8086280f, 0x100000, "Icelake HDMI",
2293 &intel_icl_drv_data),
2249 {} 2294 {}
2250}; 2295};
2251 2296
diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c
index a09d01318f79..9c8616a7b61c 100644
--- a/sound/soc/codecs/max98373.c
+++ b/sound/soc/codecs/max98373.c
@@ -724,14 +724,39 @@ static struct snd_soc_dai_driver max98373_dai[] = {
724 } 724 }
725}; 725};
726 726
727static void max98373_reset(struct max98373_priv *max98373, struct device *dev)
728{
729 int ret, reg, count;
730
731 /* Software Reset */
732 ret = regmap_update_bits(max98373->regmap,
733 MAX98373_R2000_SW_RESET,
734 MAX98373_SOFT_RESET,
735 MAX98373_SOFT_RESET);
736 if (ret)
737 dev_err(dev, "Reset command failed. (ret:%d)\n", ret);
738
739 count = 0;
740 while (count < 3) {
741 usleep_range(10000, 11000);
742 /* Software Reset Verification */
743 ret = regmap_read(max98373->regmap,
744 MAX98373_R21FF_REV_ID, &reg);
745 if (!ret) {
746 dev_info(dev, "Reset completed (retry:%d)\n", count);
747 return;
748 }
749 count++;
750 }
751 dev_err(dev, "Reset failed. (ret:%d)\n", ret);
752}
753
727static int max98373_probe(struct snd_soc_component *component) 754static int max98373_probe(struct snd_soc_component *component)
728{ 755{
729 struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component); 756 struct max98373_priv *max98373 = snd_soc_component_get_drvdata(component);
730 757
731 /* Software Reset */ 758 /* Software Reset */
732 regmap_write(max98373->regmap, 759 max98373_reset(max98373, component->dev);
733 MAX98373_R2000_SW_RESET, MAX98373_SOFT_RESET);
734 usleep_range(10000, 11000);
735 760
736 /* IV default slot configuration */ 761 /* IV default slot configuration */
737 regmap_write(max98373->regmap, 762 regmap_write(max98373->regmap,
@@ -818,9 +843,7 @@ static int max98373_resume(struct device *dev)
818{ 843{
819 struct max98373_priv *max98373 = dev_get_drvdata(dev); 844 struct max98373_priv *max98373 = dev_get_drvdata(dev);
820 845
821 regmap_write(max98373->regmap, 846 max98373_reset(max98373, dev);
822 MAX98373_R2000_SW_RESET, MAX98373_SOFT_RESET);
823 usleep_range(10000, 11000);
824 regcache_cache_only(max98373->regmap, false); 847 regcache_cache_only(max98373->regmap, false);
825 regcache_sync(max98373->regmap); 848 regcache_sync(max98373->regmap);
826 return 0; 849 return 0;
diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c
index 4ea3287162ad..8600c5439e1e 100644
--- a/sound/soc/codecs/max9867.c
+++ b/sound/soc/codecs/max9867.c
@@ -1,12 +1,10 @@
1/* 1// SPDX-License-Identifier: GPL-2.0
2 * max9867.c -- max9867 ALSA SoC Audio driver 2//
3 * 3// MAX9867 ALSA SoC codec driver
4 * Copyright 2013-15 Maxim Integrated Products 4//
5 * 5// Copyright 2013-2015 Maxim Integrated Products
6 * This program is free software; you can redistribute it and/or modify 6// Copyright 2018 Ladislav Michl <ladis@linux-mips.org>
7 * it under the terms of the GNU General Public License version 2 as 7//
8 * published by the Free Software Foundation.
9 */
10 8
11#include <linux/delay.h> 9#include <linux/delay.h>
12#include <linux/i2c.h> 10#include <linux/i2c.h>
@@ -23,254 +21,237 @@ static const char *const max9867_spmode[] = {
23 "Stereo Single", "Mono Single", 21 "Stereo Single", "Mono Single",
24 "Stereo Single Fast", "Mono Single Fast" 22 "Stereo Single Fast", "Mono Single Fast"
25}; 23};
26static const char *const max9867_sidetone_text[] = {
27 "None", "Left", "Right", "LeftRight", "LeftRightDiv2",
28};
29static const char *const max9867_filter_text[] = {"IIR", "FIR"}; 24static const char *const max9867_filter_text[] = {"IIR", "FIR"};
30 25
31static SOC_ENUM_SINGLE_DECL(max9867_filter, MAX9867_CODECFLTR, 7, 26static SOC_ENUM_SINGLE_DECL(max9867_filter, MAX9867_CODECFLTR, 7,
32 max9867_filter_text); 27 max9867_filter_text);
33static SOC_ENUM_SINGLE_DECL(max9867_spkmode, MAX9867_MODECONFIG, 0, 28static SOC_ENUM_SINGLE_DECL(max9867_spkmode, MAX9867_MODECONFIG, 0,
34 max9867_spmode); 29 max9867_spmode);
35static SOC_ENUM_SINGLE_DECL(max9867_sidetone, MAX9867_DACGAIN, 6, 30static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max9867_master_tlv,
36 max9867_sidetone_text); 31 0, 2, TLV_DB_SCALE_ITEM(-8600, 200, 1),
37static DECLARE_TLV_DB_SCALE(max9860_capture_tlv, -600, 200, 0); 32 3, 17, TLV_DB_SCALE_ITEM(-7800, 400, 0),
38static DECLARE_TLV_DB_SCALE(max9860_mic_tlv, 2000, 100, 1); 33 18, 25, TLV_DB_SCALE_ITEM(-2000, 200, 0),
39static DECLARE_TLV_DB_SCALE(max9860_adc_left_tlv, -1200, 100, 1); 34 26, 34, TLV_DB_SCALE_ITEM( -500, 100, 0),
40static DECLARE_TLV_DB_SCALE(max9860_adc_right_tlv, -1200, 100, 1); 35 35, 40, TLV_DB_SCALE_ITEM( 350, 50, 0),
41static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max98088_micboost_tlv, 36);
42 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0), 37static DECLARE_TLV_DB_SCALE(max9867_mic_tlv, 0, 100, 0);
43 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), 38static DECLARE_TLV_DB_SCALE(max9867_line_tlv, -600, 200, 0);
39static DECLARE_TLV_DB_SCALE(max9867_adc_tlv, -1200, 100, 0);
40static DECLARE_TLV_DB_SCALE(max9867_dac_tlv, -1500, 100, 0);
41static DECLARE_TLV_DB_SCALE(max9867_dacboost_tlv, 0, 600, 0);
42static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(max9867_micboost_tlv,
43 0, 2, TLV_DB_SCALE_ITEM(-2000, 2000, 1),
44 3, 3, TLV_DB_SCALE_ITEM(3000, 0, 0),
44); 45);
45 46
46static const struct snd_kcontrol_new max9867_snd_controls[] = { 47static const struct snd_kcontrol_new max9867_snd_controls[] = {
47 SOC_DOUBLE_R("Master Playback Volume", MAX9867_LEFTVOL, 48 SOC_DOUBLE_R_TLV("Master Playback Volume", MAX9867_LEFTVOL,
48 MAX9867_RIGHTVOL, 0, 63, 1), 49 MAX9867_RIGHTVOL, 0, 41, 1, max9867_master_tlv),
49 SOC_DOUBLE_R_TLV("Capture Volume", MAX9867_LEFTMICGAIN, 50 SOC_DOUBLE_R_TLV("Line Capture Volume", MAX9867_LEFTLINELVL,
50 MAX9867_RIGHTMICGAIN, 51 MAX9867_RIGHTLINELVL, 0, 15, 1, max9867_line_tlv),
51 0, 15, 1, max9860_capture_tlv), 52 SOC_DOUBLE_R_TLV("Mic Capture Volume", MAX9867_LEFTMICGAIN,
52 SOC_DOUBLE_R_TLV("Mic Volume", MAX9867_LEFTMICGAIN, 53 MAX9867_RIGHTMICGAIN, 0, 20, 1, max9867_mic_tlv),
53 MAX9867_RIGHTMICGAIN, 0, 31, 1, max9860_mic_tlv), 54 SOC_DOUBLE_R_TLV("Mic Boost Capture Volume", MAX9867_LEFTMICGAIN,
54 SOC_DOUBLE_R_TLV("Mic Boost Volume", MAX9867_LEFTMICGAIN, 55 MAX9867_RIGHTMICGAIN, 5, 4, 0, max9867_micboost_tlv),
55 MAX9867_RIGHTMICGAIN, 5, 3, 0, max98088_micboost_tlv), 56 SOC_SINGLE("Digital Sidetone Volume", MAX9867_SIDETONE, 0, 31, 1),
56 SOC_ENUM("Digital Sidetone Src", max9867_sidetone), 57 SOC_SINGLE_TLV("Digital Playback Volume", MAX9867_DACLEVEL, 0, 15, 1,
57 SOC_SINGLE("Sidetone Volume", MAX9867_DACGAIN, 0, 31, 1), 58 max9867_dac_tlv),
58 SOC_SINGLE("DAC Volume", MAX9867_DACLEVEL, 4, 3, 0), 59 SOC_SINGLE_TLV("Digital Boost Playback Volume", MAX9867_DACLEVEL, 4, 3, 0,
59 SOC_SINGLE("DAC Attenuation", MAX9867_DACLEVEL, 0, 15, 1), 60 max9867_dacboost_tlv),
60 SOC_SINGLE_TLV("ADC Left Volume", MAX9867_ADCLEVEL, 61 SOC_DOUBLE_TLV("Digital Capture Volume", MAX9867_ADCLEVEL, 0, 4, 15, 1,
61 4, 15, 1, max9860_adc_left_tlv), 62 max9867_adc_tlv),
62 SOC_SINGLE_TLV("ADC Right Volume", MAX9867_ADCLEVEL,
63 0, 15, 1, max9860_adc_right_tlv),
64 SOC_ENUM("Speaker Mode", max9867_spkmode), 63 SOC_ENUM("Speaker Mode", max9867_spkmode),
65 SOC_SINGLE("Volume Smoothing Switch", MAX9867_MODECONFIG, 6, 1, 0), 64 SOC_SINGLE("Volume Smoothing Switch", MAX9867_MODECONFIG, 6, 1, 0),
66 SOC_SINGLE("ZCD Switch", MAX9867_MODECONFIG, 5, 1, 0), 65 SOC_SINGLE("Line ZC Switch", MAX9867_MODECONFIG, 5, 1, 0),
67 SOC_ENUM("DSP Filter", max9867_filter), 66 SOC_ENUM("DSP Filter", max9867_filter),
68}; 67};
69 68
70static const char *const max9867_mux[] = {"None", "Mic", "Line", "Mic_Line"}; 69/* Input mixer */
70static const struct snd_kcontrol_new max9867_input_mixer_controls[] = {
71 SOC_DAPM_DOUBLE("Line Capture Switch", MAX9867_INPUTCONFIG, 7, 5, 1, 0),
72 SOC_DAPM_DOUBLE("Mic Capture Switch", MAX9867_INPUTCONFIG, 6, 4, 1, 0),
73};
74
75/* Output mixer */
76static const struct snd_kcontrol_new max9867_output_mixer_controls[] = {
77 SOC_DAPM_DOUBLE_R("Line Bypass Switch",
78 MAX9867_LEFTLINELVL, MAX9867_RIGHTLINELVL, 6, 1, 1),
79};
71 80
72static SOC_ENUM_SINGLE_DECL(max9867_mux_enum, 81/* Sidetone mixer */
73 MAX9867_INPUTCONFIG, MAX9867_INPUT_SHIFT, 82static const struct snd_kcontrol_new max9867_sidetone_mixer_controls[] = {
74 max9867_mux); 83 SOC_DAPM_DOUBLE("Sidetone Switch", MAX9867_SIDETONE, 6, 7, 1, 0),
84};
75 85
76static const struct snd_kcontrol_new max9867_dapm_mux_controls = 86/* Line out switch */
77 SOC_DAPM_ENUM("Route", max9867_mux_enum); 87static const struct snd_kcontrol_new max9867_line_out_control =
88 SOC_DAPM_DOUBLE_R("Switch",
89 MAX9867_LEFTVOL, MAX9867_RIGHTVOL, 6, 1, 1);
78 90
79static const struct snd_kcontrol_new max9867_left_dapm_control =
80 SOC_DAPM_SINGLE("Switch", MAX9867_PWRMAN, 6, 1, 0);
81static const struct snd_kcontrol_new max9867_right_dapm_control =
82 SOC_DAPM_SINGLE("Switch", MAX9867_PWRMAN, 5, 1, 0);
83static const struct snd_kcontrol_new max9867_line_dapm_control =
84 SOC_DAPM_SINGLE("Switch", MAX9867_LEFTLINELVL, 6, 1, 1);
85 91
86static const struct snd_soc_dapm_widget max9867_dapm_widgets[] = { 92static const struct snd_soc_dapm_widget max9867_dapm_widgets[] = {
87 SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0), 93 SND_SOC_DAPM_INPUT("MICL"),
88 SND_SOC_DAPM_DAC("Left DAC", NULL, MAX9867_PWRMAN, 3, 0), 94 SND_SOC_DAPM_INPUT("MICR"),
89 SND_SOC_DAPM_DAC("Right DAC", NULL, MAX9867_PWRMAN, 2, 0), 95 SND_SOC_DAPM_INPUT("LINL"),
90 SND_SOC_DAPM_MIXER("Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 96 SND_SOC_DAPM_INPUT("LINR"),
91 SND_SOC_DAPM_OUTPUT("HPOUT"), 97
92 98 SND_SOC_DAPM_PGA("Left Line Input", MAX9867_PWRMAN, 6, 0, NULL, 0),
93 SND_SOC_DAPM_AIF_IN("DAI_IN", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0), 99 SND_SOC_DAPM_PGA("Right Line Input", MAX9867_PWRMAN, 5, 0, NULL, 0),
94 SND_SOC_DAPM_ADC("Left ADC", "HiFi Capture", MAX9867_PWRMAN, 1, 0), 100 SND_SOC_DAPM_MIXER_NAMED_CTL("Input Mixer", SND_SOC_NOPM, 0, 0,
95 SND_SOC_DAPM_ADC("Right ADC", "HiFi Capture", MAX9867_PWRMAN, 0, 0), 101 max9867_input_mixer_controls,
96 SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, 102 ARRAY_SIZE(max9867_input_mixer_controls)),
97 &max9867_dapm_mux_controls), 103 SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", MAX9867_PWRMAN, 1, 0),
98 104 SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", MAX9867_PWRMAN, 0, 0),
99 SND_SOC_DAPM_MIXER("Input Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), 105
100 SND_SOC_DAPM_SWITCH("Left Line", MAX9867_LEFTLINELVL, 6, 1, 106 SND_SOC_DAPM_MIXER("Digital", SND_SOC_NOPM, 0, 0,
101 &max9867_left_dapm_control), 107 max9867_sidetone_mixer_controls,
102 SND_SOC_DAPM_SWITCH("Right Line", MAX9867_RIGTHLINELVL, 6, 1, 108 ARRAY_SIZE(max9867_sidetone_mixer_controls)),
103 &max9867_right_dapm_control), 109 SND_SOC_DAPM_MIXER_NAMED_CTL("Output Mixer", SND_SOC_NOPM, 0, 0,
104 SND_SOC_DAPM_SWITCH("Line Mixer", SND_SOC_NOPM, 0, 0, 110 max9867_output_mixer_controls,
105 &max9867_line_dapm_control), 111 ARRAY_SIZE(max9867_output_mixer_controls)),
106 SND_SOC_DAPM_INPUT("LINE_IN"), 112 SND_SOC_DAPM_DAC("DACL", "HiFi Playback", MAX9867_PWRMAN, 3, 0),
113 SND_SOC_DAPM_DAC("DACR", "HiFi Playback", MAX9867_PWRMAN, 2, 0),
114 SND_SOC_DAPM_SWITCH("Master Playback", SND_SOC_NOPM, 0, 0,
115 &max9867_line_out_control),
116 SND_SOC_DAPM_OUTPUT("LOUT"),
117 SND_SOC_DAPM_OUTPUT("ROUT"),
107}; 118};
108 119
109static const struct snd_soc_dapm_route max9867_audio_map[] = { 120static const struct snd_soc_dapm_route max9867_audio_map[] = {
110 {"Left DAC", NULL, "DAI_OUT"}, 121 {"Left Line Input", NULL, "LINL"},
111 {"Right DAC", NULL, "DAI_OUT"}, 122 {"Right Line Input", NULL, "LINR"},
112 {"Output Mixer", NULL, "Left DAC"}, 123 {"Input Mixer", "Mic Capture Switch", "MICL"},
113 {"Output Mixer", NULL, "Right DAC"}, 124 {"Input Mixer", "Mic Capture Switch", "MICR"},
114 {"HPOUT", NULL, "Output Mixer"}, 125 {"Input Mixer", "Line Capture Switch", "Left Line Input"},
115 126 {"Input Mixer", "Line Capture Switch", "Right Line Input"},
116 {"Left ADC", NULL, "DAI_IN"}, 127 {"ADCL", NULL, "Input Mixer"},
117 {"Right ADC", NULL, "DAI_IN"}, 128 {"ADCR", NULL, "Input Mixer"},
118 {"Input Mixer", NULL, "Left ADC"}, 129
119 {"Input Mixer", NULL, "Right ADC"}, 130 {"Digital", "Sidetone Switch", "ADCL"},
120 {"Input Mux", "Line", "Input Mixer"}, 131 {"Digital", "Sidetone Switch", "ADCR"},
121 {"Input Mux", "Mic", "Input Mixer"}, 132 {"DACL", NULL, "Digital"},
122 {"Input Mux", "Mic_Line", "Input Mixer"}, 133 {"DACR", NULL, "Digital"},
123 {"Right Line", "Switch", "Input Mux"}, 134
124 {"Left Line", "Switch", "Input Mux"}, 135 {"Output Mixer", "Line Bypass Switch", "Left Line Input"},
125 {"LINE_IN", NULL, "Left Line"}, 136 {"Output Mixer", "Line Bypass Switch", "Right Line Input"},
126 {"LINE_IN", NULL, "Right Line"}, 137 {"Output Mixer", NULL, "DACL"},
138 {"Output Mixer", NULL, "DACR"},
139 {"Master Playback", "Switch", "Output Mixer"},
140 {"LOUT", NULL, "Master Playback"},
141 {"ROUT", NULL, "Master Playback"},
142};
143
144static const unsigned int max9867_rates_44k1[] = {
145 11025, 22050, 44100,
146};
147
148static const struct snd_pcm_hw_constraint_list max9867_constraints_44k1 = {
149 .list = max9867_rates_44k1,
150 .count = ARRAY_SIZE(max9867_rates_44k1),
127}; 151};
128 152
129enum rates { 153static const unsigned int max9867_rates_48k[] = {
130 pcm_rate_8, pcm_rate_16, pcm_rate_24, 154 8000, 16000, 32000, 48000,
131 pcm_rate_32, pcm_rate_44,
132 pcm_rate_48, max_pcm_rate,
133}; 155};
134 156
135static const struct ni_div_rates { 157static const struct snd_pcm_hw_constraint_list max9867_constraints_48k = {
136 u32 mclk; 158 .list = max9867_rates_48k,
137 u16 ni[max_pcm_rate]; 159 .count = ARRAY_SIZE(max9867_rates_48k),
138} ni_div[] = {
139 {11289600, {0x116A, 0x22D4, 0x343F, 0x45A9, 0x6000, 0x687D} },
140 {12000000, {0x1062, 0x20C5, 0x3127, 0x4189, 0x5A51, 0x624E} },
141 {12288000, {0x1000, 0x2000, 0x3000, 0x4000, 0x5833, 0x6000} },
142 {13000000, {0x0F20, 0x1E3F, 0x2D5F, 0x3C7F, 0x535F, 0x5ABE} },
143 {19200000, {0x0A3D, 0x147B, 0x1EB8, 0x28F6, 0x3873, 0x3D71} },
144 {24000000, {0x1062, 0x20C5, 0x1893, 0x4189, 0x5A51, 0x624E} },
145 {26000000, {0x0F20, 0x1E3F, 0x16AF, 0x3C7F, 0x535F, 0x5ABE} },
146 {27000000, {0x0E90, 0x1D21, 0x15D8, 0x3A41, 0x5048, 0x5762} },
147}; 160};
148 161
149static inline int get_ni_value(int mclk, int rate) 162struct max9867_priv {
163 struct regmap *regmap;
164 const struct snd_pcm_hw_constraint_list *constraints;
165 unsigned int sysclk, pclk;
166 bool master, dsp_a;
167};
168
169static int max9867_startup(struct snd_pcm_substream *substream,
170 struct snd_soc_dai *dai)
150{ 171{
151 int i, ret = 0; 172 struct max9867_priv *max9867 =
173 snd_soc_component_get_drvdata(dai->component);
152 174
153 /* find the closest rate index*/ 175 if (max9867->constraints)
154 for (i = 0; i < ARRAY_SIZE(ni_div); i++) { 176 snd_pcm_hw_constraint_list(substream->runtime, 0,
155 if (ni_div[i].mclk >= mclk) 177 SNDRV_PCM_HW_PARAM_RATE, max9867->constraints);
156 break;
157 }
158 if (i == ARRAY_SIZE(ni_div))
159 return -EINVAL;
160 178
161 switch (rate) { 179 return 0;
162 case 8000:
163 return ni_div[i].ni[pcm_rate_8];
164 case 16000:
165 return ni_div[i].ni[pcm_rate_16];
166 case 32000:
167 return ni_div[i].ni[pcm_rate_32];
168 case 44100:
169 return ni_div[i].ni[pcm_rate_44];
170 case 48000:
171 return ni_div[i].ni[pcm_rate_48];
172 default:
173 pr_err("%s wrong rate %d\n", __func__, rate);
174 ret = -EINVAL;
175 }
176 return ret;
177} 180}
178 181
179static int max9867_dai_hw_params(struct snd_pcm_substream *substream, 182static int max9867_dai_hw_params(struct snd_pcm_substream *substream,
180 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 183 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
181{ 184{
185 int value;
186 unsigned long int rate, ratio;
182 struct snd_soc_component *component = dai->component; 187 struct snd_soc_component *component = dai->component;
183 struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component); 188 struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
184 unsigned int ni_h, ni_l; 189 unsigned int ni = DIV_ROUND_CLOSEST_ULL(96ULL * 0x10000 * params_rate(params),
185 int value; 190 max9867->pclk);
186 191
187 value = get_ni_value(max9867->sysclk, params_rate(params));
188 if (value < 0)
189 return value;
190
191 ni_h = (0xFF00 & value) >> 8;
192 ni_l = 0x00FF & value;
193 /* set up the ni value */ 192 /* set up the ni value */
194 regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKHIGH, 193 regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKHIGH,
195 MAX9867_NI_HIGH_MASK, ni_h); 194 MAX9867_NI_HIGH_MASK, (0xFF00 & ni) >> 8);
196 regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKLOW, 195 regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKLOW,
197 MAX9867_NI_LOW_MASK, ni_l); 196 MAX9867_NI_LOW_MASK, 0x00FF & ni);
198 if (!max9867->master) { 197 if (max9867->master) {
199 /* 198 if (max9867->dsp_a) {
200 * digital pll locks on to any externally supplied LRCLK signal 199 value = MAX9867_IFC1B_48X;
201 * and also enable rapid lock mode. 200 } else {
202 */ 201 rate = params_rate(params) * 2 * params_width(params);
203 regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKLOW, 202 ratio = max9867->pclk / rate;
204 MAX9867_RAPID_LOCK, MAX9867_RAPID_LOCK); 203 switch (params_width(params)) {
205 regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKHIGH,
206 MAX9867_PLL, MAX9867_PLL);
207 } else {
208 unsigned long int bclk_rate, pclk_bclk_ratio;
209 int bclk_value;
210
211 bclk_rate = params_rate(params) * 2 * params_width(params);
212 pclk_bclk_ratio = max9867->pclk/bclk_rate;
213 switch (params_width(params)) {
214 case 8:
215 case 16:
216 switch (pclk_bclk_ratio) {
217 case 2:
218 bclk_value = MAX9867_IFC1B_PCLK_2;
219 break;
220 case 4:
221 bclk_value = MAX9867_IFC1B_PCLK_4;
222 break;
223 case 8: 204 case 8:
224 bclk_value = MAX9867_IFC1B_PCLK_8;
225 break;
226 case 16: 205 case 16:
227 bclk_value = MAX9867_IFC1B_PCLK_16; 206 switch (ratio) {
207 case 2:
208 value = MAX9867_IFC1B_PCLK_2;
209 break;
210 case 4:
211 value = MAX9867_IFC1B_PCLK_4;
212 break;
213 case 8:
214 value = MAX9867_IFC1B_PCLK_8;
215 break;
216 case 16:
217 value = MAX9867_IFC1B_PCLK_16;
218 break;
219 default:
220 return -EINVAL;
221 }
222 break;
223 case 24:
224 value = MAX9867_IFC1B_48X;
225 break;
226 case 32:
227 value = MAX9867_IFC1B_64X;
228 break; 228 break;
229 default: 229 default:
230 dev_err(component->dev,
231 "unsupported sampling rate\n");
232 return -EINVAL; 230 return -EINVAL;
233 } 231 }
234 break;
235 case 24:
236 bclk_value = MAX9867_IFC1B_24BIT;
237 break;
238 case 32:
239 bclk_value = MAX9867_IFC1B_32BIT;
240 break;
241 default:
242 dev_err(component->dev, "unsupported sampling rate\n");
243 return -EINVAL;
244 } 232 }
245 regmap_update_bits(max9867->regmap, MAX9867_IFC1B, 233 regmap_update_bits(max9867->regmap, MAX9867_IFC1B,
246 MAX9867_IFC1B_BCLK_MASK, bclk_value); 234 MAX9867_IFC1B_BCLK_MASK, value);
235 } else {
236 /*
237 * digital pll locks on to any externally supplied LRCLK signal
238 * and also enable rapid lock mode.
239 */
240 regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKLOW,
241 MAX9867_RAPID_LOCK, MAX9867_RAPID_LOCK);
242 regmap_update_bits(max9867->regmap, MAX9867_AUDIOCLKHIGH,
243 MAX9867_PLL, MAX9867_PLL);
247 } 244 }
248 return 0; 245 return 0;
249} 246}
250 247
251static int max9867_prepare(struct snd_pcm_substream *substream,
252 struct snd_soc_dai *dai)
253{
254 struct snd_soc_component *component = dai->component;
255 struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
256
257 regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
258 MAX9867_SHTDOWN_MASK, MAX9867_SHTDOWN_MASK);
259 return 0;
260}
261
262static int max9867_mute(struct snd_soc_dai *dai, int mute) 248static int max9867_mute(struct snd_soc_dai *dai, int mute)
263{ 249{
264 struct snd_soc_component *component = dai->component; 250 struct snd_soc_component *component = dai->component;
265 struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component); 251 struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
266 252
267 if (mute) 253 return regmap_update_bits(max9867->regmap, MAX9867_DACLEVEL,
268 regmap_update_bits(max9867->regmap, MAX9867_DACLEVEL, 254 1 << 6, !!mute << 6);
269 MAX9867_DAC_MUTE_MASK, MAX9867_DAC_MUTE_MASK);
270 else
271 regmap_update_bits(max9867->regmap, MAX9867_DACLEVEL,
272 MAX9867_DAC_MUTE_MASK, 0);
273 return 0;
274} 255}
275 256
276static int max9867_set_dai_sysclk(struct snd_soc_dai *codec_dai, 257static int max9867_set_dai_sysclk(struct snd_soc_dai *codec_dai,
@@ -283,21 +264,29 @@ static int max9867_set_dai_sysclk(struct snd_soc_dai *codec_dai,
283 /* Set the prescaler based on the master clock frequency*/ 264 /* Set the prescaler based on the master clock frequency*/
284 if (freq >= 10000000 && freq <= 20000000) { 265 if (freq >= 10000000 && freq <= 20000000) {
285 value |= MAX9867_PSCLK_10_20; 266 value |= MAX9867_PSCLK_10_20;
286 max9867->pclk = freq; 267 max9867->pclk = freq;
287 } else if (freq >= 20000000 && freq <= 40000000) { 268 } else if (freq >= 20000000 && freq <= 40000000) {
288 value |= MAX9867_PSCLK_20_40; 269 value |= MAX9867_PSCLK_20_40;
289 max9867->pclk = freq/2; 270 max9867->pclk = freq / 2;
290 } else if (freq >= 40000000 && freq <= 60000000) { 271 } else if (freq >= 40000000 && freq <= 60000000) {
291 value |= MAX9867_PSCLK_40_60; 272 value |= MAX9867_PSCLK_40_60;
292 max9867->pclk = freq/4; 273 max9867->pclk = freq / 4;
293 } else { 274 } else {
294 dev_err(component->dev, 275 dev_err(component->dev,
295 "Invalid clock frequency %uHz (required 10-60MHz)\n", 276 "Invalid clock frequency %uHz (required 10-60MHz)\n",
296 freq); 277 freq);
297 return -EINVAL; 278 return -EINVAL;
298 } 279 }
299 value = value << MAX9867_PSCLK_SHIFT; 280 if (freq % 48000 == 0)
281 max9867->constraints = &max9867_constraints_48k;
282 else if (freq % 44100 == 0)
283 max9867->constraints = &max9867_constraints_44k1;
284 else
285 dev_warn(component->dev,
286 "Unable to set exact rate with %uHz clock frequency\n",
287 freq);
300 max9867->sysclk = freq; 288 max9867->sysclk = freq;
289 value = value << MAX9867_PSCLK_SHIFT;
301 /* exact integer mode is not supported */ 290 /* exact integer mode is not supported */
302 value &= ~MAX9867_FREQ_MASK; 291 value &= ~MAX9867_FREQ_MASK;
303 regmap_update_bits(max9867->regmap, MAX9867_SYSCLK, 292 regmap_update_bits(max9867->regmap, MAX9867_SYSCLK,
@@ -310,16 +299,17 @@ static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
310{ 299{
311 struct snd_soc_component *component = codec_dai->component; 300 struct snd_soc_component *component = codec_dai->component;
312 struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component); 301 struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
313 u8 iface1A = 0, iface1B = 0; 302 u8 iface1A, iface1B;
314 303
315 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 304 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
316 case SND_SOC_DAIFMT_CBM_CFM: 305 case SND_SOC_DAIFMT_CBM_CFM:
317 max9867->master = 1; 306 max9867->master = true;
318 iface1A |= MAX9867_MASTER; 307 iface1A = MAX9867_MASTER;
308 iface1B = MAX9867_IFC1B_48X;
319 break; 309 break;
320 case SND_SOC_DAIFMT_CBS_CFS: 310 case SND_SOC_DAIFMT_CBS_CFS:
321 max9867->master = 0; 311 max9867->master = false;
322 iface1A &= ~MAX9867_MASTER; 312 iface1A = iface1B = 0;
323 break; 313 break;
324 default: 314 default:
325 return -EINVAL; 315 return -EINVAL;
@@ -327,9 +317,11 @@ static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
327 317
328 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 318 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
329 case SND_SOC_DAIFMT_I2S: 319 case SND_SOC_DAIFMT_I2S:
320 max9867->dsp_a = false;
330 iface1A |= MAX9867_I2S_DLY; 321 iface1A |= MAX9867_I2S_DLY;
331 break; 322 break;
332 case SND_SOC_DAIFMT_DSP_A: 323 case SND_SOC_DAIFMT_DSP_A:
324 max9867->dsp_a = true;
333 iface1A |= MAX9867_TDM_MODE | MAX9867_SDOUT_HIZ; 325 iface1A |= MAX9867_TDM_MODE | MAX9867_SDOUT_HIZ;
334 break; 326 break;
335 default: 327 default:
@@ -355,21 +347,18 @@ static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
355 347
356 regmap_write(max9867->regmap, MAX9867_IFC1A, iface1A); 348 regmap_write(max9867->regmap, MAX9867_IFC1A, iface1A);
357 regmap_write(max9867->regmap, MAX9867_IFC1B, iface1B); 349 regmap_write(max9867->regmap, MAX9867_IFC1B, iface1B);
350
358 return 0; 351 return 0;
359} 352}
360 353
361static const struct snd_soc_dai_ops max9867_dai_ops = { 354static const struct snd_soc_dai_ops max9867_dai_ops = {
362 .set_fmt = max9867_dai_set_fmt,
363 .set_sysclk = max9867_set_dai_sysclk, 355 .set_sysclk = max9867_set_dai_sysclk,
364 .prepare = max9867_prepare, 356 .set_fmt = max9867_dai_set_fmt,
365 .digital_mute = max9867_mute, 357 .digital_mute = max9867_mute,
366 .hw_params = max9867_dai_hw_params, 358 .startup = max9867_startup,
359 .hw_params = max9867_dai_hw_params,
367}; 360};
368 361
369#define MAX9867_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
370 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
371#define MAX9867_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
372
373static struct snd_soc_dai_driver max9867_dai[] = { 362static struct snd_soc_dai_driver max9867_dai[] = {
374 { 363 {
375 .name = "max9867-aif1", 364 .name = "max9867-aif1",
@@ -377,42 +366,74 @@ static struct snd_soc_dai_driver max9867_dai[] = {
377 .stream_name = "HiFi Playback", 366 .stream_name = "HiFi Playback",
378 .channels_min = 2, 367 .channels_min = 2,
379 .channels_max = 2, 368 .channels_max = 2,
380 .rates = MAX9867_RATES, 369 .rates = SNDRV_PCM_RATE_8000_48000,
381 .formats = MAX9867_FORMATS, 370 .formats = SNDRV_PCM_FMTBIT_S16_LE,
382 }, 371 },
383 .capture = { 372 .capture = {
384 .stream_name = "HiFi Capture", 373 .stream_name = "HiFi Capture",
385 .channels_min = 2, 374 .channels_min = 2,
386 .channels_max = 2, 375 .channels_max = 2,
387 .rates = MAX9867_RATES, 376 .rates = SNDRV_PCM_RATE_8000_48000,
388 .formats = MAX9867_FORMATS, 377 .formats = SNDRV_PCM_FMTBIT_S16_LE,
389 }, 378 },
390 .ops = &max9867_dai_ops, 379 .ops = &max9867_dai_ops,
391 .symmetric_rates = 1, 380 .symmetric_rates = 1,
392 } 381 }
393}; 382};
394 383
395#ifdef CONFIG_PM_SLEEP 384#ifdef CONFIG_PM
396static int max9867_suspend(struct device *dev) 385static int max9867_suspend(struct snd_soc_component *component)
397{ 386{
398 struct max9867_priv *max9867 = dev_get_drvdata(dev); 387 snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
399 388
400 /* Drop down to power saving mode when system is suspended */
401 regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
402 MAX9867_SHTDOWN_MASK, ~MAX9867_SHTDOWN_MASK);
403 return 0; 389 return 0;
404} 390}
405 391
406static int max9867_resume(struct device *dev) 392static int max9867_resume(struct snd_soc_component *component)
407{ 393{
408 struct max9867_priv *max9867 = dev_get_drvdata(dev); 394 snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);
409 395
410 regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
411 MAX9867_SHTDOWN_MASK, MAX9867_SHTDOWN_MASK);
412 return 0; 396 return 0;
413} 397}
398#else
399#define max9867_suspend NULL
400#define max9867_resume NULL
414#endif 401#endif
415 402
403static int max9867_set_bias_level(struct snd_soc_component *component,
404 enum snd_soc_bias_level level)
405{
406 int err;
407 struct max9867_priv *max9867 = snd_soc_component_get_drvdata(component);
408
409 switch (level) {
410 case SND_SOC_BIAS_STANDBY:
411 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
412 err = regcache_sync(max9867->regmap);
413 if (err)
414 return err;
415
416 err = regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
417 MAX9867_SHTDOWN, MAX9867_SHTDOWN);
418 if (err)
419 return err;
420 }
421 break;
422 case SND_SOC_BIAS_OFF:
423 err = regmap_update_bits(max9867->regmap, MAX9867_PWRMAN,
424 MAX9867_SHTDOWN, 0);
425 if (err)
426 return err;
427
428 regcache_mark_dirty(max9867->regmap);
429 break;
430 default:
431 break;
432 }
433
434 return 0;
435}
436
416static const struct snd_soc_component_driver max9867_component = { 437static const struct snd_soc_component_driver max9867_component = {
417 .controls = max9867_snd_controls, 438 .controls = max9867_snd_controls,
418 .num_controls = ARRAY_SIZE(max9867_snd_controls), 439 .num_controls = ARRAY_SIZE(max9867_snd_controls),
@@ -420,6 +441,9 @@ static const struct snd_soc_component_driver max9867_component = {
420 .num_dapm_routes = ARRAY_SIZE(max9867_audio_map), 441 .num_dapm_routes = ARRAY_SIZE(max9867_audio_map),
421 .dapm_widgets = max9867_dapm_widgets, 442 .dapm_widgets = max9867_dapm_widgets,
422 .num_dapm_widgets = ARRAY_SIZE(max9867_dapm_widgets), 443 .num_dapm_widgets = ARRAY_SIZE(max9867_dapm_widgets),
444 .suspend = max9867_suspend,
445 .resume = max9867_resume,
446 .set_bias_level = max9867_set_bias_level,
423 .idle_bias_on = 1, 447 .idle_bias_on = 1,
424 .use_pmdown_time = 1, 448 .use_pmdown_time = 1,
425 .endianness = 1, 449 .endianness = 1,
@@ -450,8 +474,8 @@ static const struct reg_default max9867_reg[] = {
450 { 0x0B, 0x00 }, 474 { 0x0B, 0x00 },
451 { 0x0C, 0x00 }, 475 { 0x0C, 0x00 },
452 { 0x0D, 0x00 }, 476 { 0x0D, 0x00 },
453 { 0x0E, 0x00 }, 477 { 0x0E, 0x40 },
454 { 0x0F, 0x00 }, 478 { 0x0F, 0x40 },
455 { 0x10, 0x00 }, 479 { 0x10, 0x00 },
456 { 0x11, 0x00 }, 480 { 0x11, 0x00 },
457 { 0x12, 0x00 }, 481 { 0x12, 0x00 },
@@ -476,10 +500,9 @@ static int max9867_i2c_probe(struct i2c_client *i2c,
476 const struct i2c_device_id *id) 500 const struct i2c_device_id *id)
477{ 501{
478 struct max9867_priv *max9867; 502 struct max9867_priv *max9867;
479 int ret = 0, reg; 503 int ret, reg;
480 504
481 max9867 = devm_kzalloc(&i2c->dev, 505 max9867 = devm_kzalloc(&i2c->dev, sizeof(*max9867), GFP_KERNEL);
482 sizeof(*max9867), GFP_KERNEL);
483 if (!max9867) 506 if (!max9867)
484 return -ENOMEM; 507 return -ENOMEM;
485 508
@@ -490,8 +513,7 @@ static int max9867_i2c_probe(struct i2c_client *i2c,
490 dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); 513 dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
491 return ret; 514 return ret;
492 } 515 }
493 ret = regmap_read(max9867->regmap, 516 ret = regmap_read(max9867->regmap, MAX9867_REVISION, &reg);
494 MAX9867_REVISION, &reg);
495 if (ret < 0) { 517 if (ret < 0) {
496 dev_err(&i2c->dev, "Failed to read: %d\n", ret); 518 dev_err(&i2c->dev, "Failed to read: %d\n", ret);
497 return ret; 519 return ret;
@@ -499,10 +521,8 @@ static int max9867_i2c_probe(struct i2c_client *i2c,
499 dev_info(&i2c->dev, "device revision: %x\n", reg); 521 dev_info(&i2c->dev, "device revision: %x\n", reg);
500 ret = devm_snd_soc_register_component(&i2c->dev, &max9867_component, 522 ret = devm_snd_soc_register_component(&i2c->dev, &max9867_component,
501 max9867_dai, ARRAY_SIZE(max9867_dai)); 523 max9867_dai, ARRAY_SIZE(max9867_dai));
502 if (ret < 0) { 524 if (ret < 0)
503 dev_err(&i2c->dev, "Failed to register component: %d\n", ret); 525 dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
504 return ret;
505 }
506 return ret; 526 return ret;
507} 527}
508 528
@@ -518,15 +538,10 @@ static const struct of_device_id max9867_of_match[] = {
518}; 538};
519MODULE_DEVICE_TABLE(of, max9867_of_match); 539MODULE_DEVICE_TABLE(of, max9867_of_match);
520 540
521static const struct dev_pm_ops max9867_pm_ops = {
522 SET_SYSTEM_SLEEP_PM_OPS(max9867_suspend, max9867_resume)
523};
524
525static struct i2c_driver max9867_i2c_driver = { 541static struct i2c_driver max9867_i2c_driver = {
526 .driver = { 542 .driver = {
527 .name = "max9867", 543 .name = "max9867",
528 .of_match_table = of_match_ptr(max9867_of_match), 544 .of_match_table = of_match_ptr(max9867_of_match),
529 .pm = &max9867_pm_ops,
530 }, 545 },
531 .probe = max9867_i2c_probe, 546 .probe = max9867_i2c_probe,
532 .id_table = max9867_i2c_id, 547 .id_table = max9867_i2c_id,
@@ -534,6 +549,6 @@ static struct i2c_driver max9867_i2c_driver = {
534 549
535module_i2c_driver(max9867_i2c_driver); 550module_i2c_driver(max9867_i2c_driver);
536 551
537MODULE_AUTHOR("anish kumar <yesanishhere@gmail.com>"); 552MODULE_AUTHOR("Ladislav Michl <ladis@linux-mips.org>");
538MODULE_DESCRIPTION("ALSA SoC MAX9867 driver"); 553MODULE_DESCRIPTION("ASoC MAX9867 driver");
539MODULE_LICENSE("GPL"); 554MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max9867.h b/sound/soc/codecs/max9867.h
index 55cd9976ff47..2277798291a1 100644
--- a/sound/soc/codecs/max9867.h
+++ b/sound/soc/codecs/max9867.h
@@ -26,13 +26,11 @@
26#define MAX9867_PSCLK_10_20 0x1 26#define MAX9867_PSCLK_10_20 0x1
27#define MAX9867_PSCLK_20_40 0x2 27#define MAX9867_PSCLK_20_40 0x2
28#define MAX9867_PSCLK_40_60 0x3 28#define MAX9867_PSCLK_40_60 0x3
29#define MAX9867_AUDIOCLKHIGH 0x06 29#define MAX9867_AUDIOCLKHIGH 0x06
30#define MAX9867_NI_HIGH_WIDTH 0x7 30#define MAX9867_NI_HIGH_MASK 0x7F
31#define MAX9867_NI_HIGH_MASK 0x7F 31#define MAX9867_NI_LOW_MASK 0xFE
32#define MAX9867_NI_LOW_MASK 0x7F 32#define MAX9867_PLL (1<<7)
33#define MAX9867_NI_LOW_SHIFT 0x1 33#define MAX9867_AUDIOCLKLOW 0x07
34#define MAX9867_PLL (1<<7)
35#define MAX9867_AUDIOCLKLOW 0x07
36#define MAX9867_RAPID_LOCK 0x01 34#define MAX9867_RAPID_LOCK 0x01
37#define MAX9867_IFC1A 0x08 35#define MAX9867_IFC1A 0x08
38#define MAX9867_MASTER (1<<7) 36#define MAX9867_MASTER (1<<7)
@@ -43,40 +41,29 @@
43#define MAX9867_BCI_MODE (1<<5) 41#define MAX9867_BCI_MODE (1<<5)
44#define MAX9867_IFC1B 0x09 42#define MAX9867_IFC1B 0x09
45#define MAX9867_IFC1B_BCLK_MASK 7 43#define MAX9867_IFC1B_BCLK_MASK 7
46#define MAX9867_IFC1B_32BIT 0x01 44#define MAX9867_IFC1B_64X 0x01
47#define MAX9867_IFC1B_24BIT 0x02 45#define MAX9867_IFC1B_48X 0x02
48#define MAX9867_IFC1B_PCLK_2 4 46#define MAX9867_IFC1B_PCLK_2 0x04
49#define MAX9867_IFC1B_PCLK_4 5 47#define MAX9867_IFC1B_PCLK_4 0x05
50#define MAX9867_IFC1B_PCLK_8 6 48#define MAX9867_IFC1B_PCLK_8 0x06
51#define MAX9867_IFC1B_PCLK_16 7 49#define MAX9867_IFC1B_PCLK_16 0x07
52#define MAX9867_CODECFLTR 0x0a 50#define MAX9867_CODECFLTR 0x0a
53#define MAX9867_DACGAIN 0x0b 51#define MAX9867_SIDETONE 0x0b
54#define MAX9867_DACLEVEL 0x0c 52#define MAX9867_DACLEVEL 0x0c
55#define MAX9867_DAC_MUTE_SHIFT 0x6
56#define MAX9867_DAC_MUTE_WIDTH 0x1
57#define MAX9867_DAC_MUTE_MASK (0x1<<MAX9867_DAC_MUTE_SHIFT)
58#define MAX9867_ADCLEVEL 0x0d 53#define MAX9867_ADCLEVEL 0x0d
59#define MAX9867_LEFTLINELVL 0x0e 54#define MAX9867_LEFTLINELVL 0x0e
60#define MAX9867_RIGTHLINELVL 0x0f 55#define MAX9867_RIGHTLINELVL 0x0f
61#define MAX9867_LEFTVOL 0x10 56#define MAX9867_LEFTVOL 0x10
62#define MAX9867_RIGHTVOL 0x11 57#define MAX9867_RIGHTVOL 0x11
63#define MAX9867_LEFTMICGAIN 0x12 58#define MAX9867_LEFTMICGAIN 0x12
64#define MAX9867_RIGHTMICGAIN 0x13 59#define MAX9867_RIGHTMICGAIN 0x13
65#define MAX9867_INPUTCONFIG 0x14 60#define MAX9867_INPUTCONFIG 0x14
66#define MAX9867_INPUT_SHIFT 0x6
67#define MAX9867_MICCONFIG 0x15 61#define MAX9867_MICCONFIG 0x15
68#define MAX9867_MODECONFIG 0x16 62#define MAX9867_MODECONFIG 0x16
69#define MAX9867_PWRMAN 0x17 63#define MAX9867_PWRMAN 0x17
70#define MAX9867_SHTDOWN_MASK (1<<7) 64#define MAX9867_SHTDOWN 0x80
71#define MAX9867_REVISION 0xff 65#define MAX9867_REVISION 0xff
72 66
73#define MAX9867_CACHEREGNUM 10 67#define MAX9867_CACHEREGNUM 10
74 68
75/* codec private data */
76struct max9867_priv {
77 struct regmap *regmap;
78 unsigned int sysclk;
79 unsigned int pclk;
80 unsigned int master;
81};
82#endif 69#endif
diff --git a/sound/soc/codecs/nau8540.c b/sound/soc/codecs/nau8540.c
index e3c8cd17daf2..4dd1a609756b 100644
--- a/sound/soc/codecs/nau8540.c
+++ b/sound/soc/codecs/nau8540.c
@@ -585,7 +585,7 @@ static int nau8540_calc_fll_param(unsigned int fll_in,
585 fvco_max = 0; 585 fvco_max = 0;
586 fvco_sel = ARRAY_SIZE(mclk_src_scaling); 586 fvco_sel = ARRAY_SIZE(mclk_src_scaling);
587 for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) { 587 for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) {
588 fvco = 256 * fs * 2 * mclk_src_scaling[i].param; 588 fvco = 256ULL * fs * 2 * mclk_src_scaling[i].param;
589 if (fvco > NAU_FVCO_MIN && fvco < NAU_FVCO_MAX && 589 if (fvco > NAU_FVCO_MIN && fvco < NAU_FVCO_MAX &&
590 fvco_max < fvco) { 590 fvco_max < fvco) {
591 fvco_max = fvco; 591 fvco_max = fvco;
diff --git a/sound/soc/codecs/nau8822.c b/sound/soc/codecs/nau8822.c
index 622ce947f134..c6152a044416 100644
--- a/sound/soc/codecs/nau8822.c
+++ b/sound/soc/codecs/nau8822.c
@@ -1,18 +1,14 @@
1/* 1// SPDX-License-Identifier: GPL-2.0
2 * nau8822.c -- NAU8822 ALSA Soc Audio Codec driver 2//
3 * 3// nau8822.c -- NAU8822 ALSA Soc Audio driver
4 * Copyright 2017 Nuvoton Technology Corp. 4//
5 * 5// Copyright 2017 Nuvoton Technology Crop.
6 * Author: David Lin <ctlin0@nuvoton.com> 6//
7 * Co-author: John Hsu <kchsu0@nuvoton.com> 7// Author: David Lin <ctlin0@nuvoton.com>
8 * Co-author: Seven Li <wtli@nuvoton.com> 8// Co-author: John Hsu <kchsu0@nuvoton.com>
9 * 9// Co-author: Seven Li <wtli@nuvoton.com>
10 * Based on WM8974.c 10//
11 * 11// Based on WM8974.c
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16 12
17#include <linux/module.h> 13#include <linux/module.h>
18#include <linux/moduleparam.h> 14#include <linux/moduleparam.h>
diff --git a/sound/soc/codecs/nau8822.h b/sound/soc/codecs/nau8822.h
index aa79c969cd44..9c552983a293 100644
--- a/sound/soc/codecs/nau8822.h
+++ b/sound/soc/codecs/nau8822.h
@@ -1,13 +1,12 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * nau8822.h -- NAU8822 Soc Audio Codec driver 3 * nau8822.h -- NAU8822 ALSA SoC Audio driver
4 *
5 * Copyright 2017 Nuvoton Technology Crop.
3 * 6 *
4 * Author: David Lin <ctlin0@nuvoton.com> 7 * Author: David Lin <ctlin0@nuvoton.com>
5 * Co-author: John Hsu <kchsu0@nuvoton.com> 8 * Co-author: John Hsu <kchsu0@nuvoton.com>
6 * Co-author: Seven Li <wtli@nuvoton.com> 9 * Co-author: Seven Li <wtli@nuvoton.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */ 10 */
12 11
13#ifndef __NAU8822_H__ 12#ifndef __NAU8822_H__
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c
index b9fed99d8b5e..7bbcbf5f05c8 100644
--- a/sound/soc/codecs/nau8825.c
+++ b/sound/soc/codecs/nau8825.c
@@ -424,10 +424,8 @@ static u32 nau8825_xtalk_sidetone(u32 sig_org, u32 sig_cros)
424{ 424{
425 u32 gain, sidetone; 425 u32 gain, sidetone;
426 426
427 if (unlikely(sig_org == 0) || unlikely(sig_cros == 0)) { 427 if (WARN_ON(sig_org == 0 || sig_cros == 0))
428 WARN_ON(1);
429 return 0; 428 return 0;
430 }
431 429
432 sig_org = nau8825_intlog10_dec3(sig_org); 430 sig_org = nau8825_intlog10_dec3(sig_org);
433 sig_cros = nau8825_intlog10_dec3(sig_cros); 431 sig_cros = nau8825_intlog10_dec3(sig_cros);
diff --git a/sound/soc/codecs/pcm3060.c b/sound/soc/codecs/pcm3060.c
index 771b46e1974b..6714aa8d9026 100644
--- a/sound/soc/codecs/pcm3060.c
+++ b/sound/soc/codecs/pcm3060.c
@@ -198,19 +198,25 @@ static const struct snd_kcontrol_new pcm3060_dapm_controls[] = {
198}; 198};
199 199
200static const struct snd_soc_dapm_widget pcm3060_dapm_widgets[] = { 200static const struct snd_soc_dapm_widget pcm3060_dapm_widgets[] = {
201 SND_SOC_DAPM_DAC("DAC", "Playback", PCM3060_REG64,
202 PCM3060_REG_SHIFT_DAPSV, 1),
203
201 SND_SOC_DAPM_OUTPUT("OUTL"), 204 SND_SOC_DAPM_OUTPUT("OUTL"),
202 SND_SOC_DAPM_OUTPUT("OUTR"), 205 SND_SOC_DAPM_OUTPUT("OUTR"),
203 206
204 SND_SOC_DAPM_INPUT("INL"), 207 SND_SOC_DAPM_INPUT("INL"),
205 SND_SOC_DAPM_INPUT("INR"), 208 SND_SOC_DAPM_INPUT("INR"),
209
210 SND_SOC_DAPM_ADC("ADC", "Capture", PCM3060_REG64,
211 PCM3060_REG_SHIFT_ADPSV, 1),
206}; 212};
207 213
208static const struct snd_soc_dapm_route pcm3060_dapm_map[] = { 214static const struct snd_soc_dapm_route pcm3060_dapm_map[] = {
209 { "OUTL", NULL, "Playback" }, 215 { "OUTL", NULL, "DAC" },
210 { "OUTR", NULL, "Playback" }, 216 { "OUTR", NULL, "DAC" },
211 217
212 { "Capture", NULL, "INL" }, 218 { "ADC", NULL, "INL" },
213 { "Capture", NULL, "INR" }, 219 { "ADC", NULL, "INR" },
214}; 220};
215 221
216/* soc component */ 222/* soc component */
@@ -270,9 +276,23 @@ EXPORT_SYMBOL(pcm3060_regmap);
270 276
271/* device */ 277/* device */
272 278
279static void pcm3060_parse_dt(const struct device_node *np,
280 struct pcm3060_priv *priv)
281{
282 priv->out_se = of_property_read_bool(np, "ti,out-single-ended");
283}
284
273int pcm3060_probe(struct device *dev) 285int pcm3060_probe(struct device *dev)
274{ 286{
275 int rc; 287 int rc;
288 struct pcm3060_priv *priv = dev_get_drvdata(dev);
289
290 if (dev->of_node)
291 pcm3060_parse_dt(dev->of_node, priv);
292
293 if (priv->out_se)
294 regmap_update_bits(priv->regmap, PCM3060_REG64,
295 PCM3060_REG_SE, PCM3060_REG_SE);
276 296
277 rc = devm_snd_soc_register_component(dev, &pcm3060_soc_comp_driver, 297 rc = devm_snd_soc_register_component(dev, &pcm3060_soc_comp_driver,
278 pcm3060_dai, 298 pcm3060_dai,
diff --git a/sound/soc/codecs/pcm3060.h b/sound/soc/codecs/pcm3060.h
index fd89a68aa8a7..6a027b4a845d 100644
--- a/sound/soc/codecs/pcm3060.h
+++ b/sound/soc/codecs/pcm3060.h
@@ -25,6 +25,7 @@ struct pcm3060_priv_dai {
25struct pcm3060_priv { 25struct pcm3060_priv {
26 struct regmap *regmap; 26 struct regmap *regmap;
27 struct pcm3060_priv_dai dai[PCM3060_DAI_IDS_NUM]; 27 struct pcm3060_priv_dai dai[PCM3060_DAI_IDS_NUM];
28 u8 out_se: 1;
28}; 29};
29 30
30int pcm3060_probe(struct device *dev); 31int pcm3060_probe(struct device *dev);
@@ -36,7 +37,9 @@ int pcm3060_remove(struct device *dev);
36#define PCM3060_REG_MRST 0x80 37#define PCM3060_REG_MRST 0x80
37#define PCM3060_REG_SRST 0x40 38#define PCM3060_REG_SRST 0x40
38#define PCM3060_REG_ADPSV 0x20 39#define PCM3060_REG_ADPSV 0x20
40#define PCM3060_REG_SHIFT_ADPSV 0x05
39#define PCM3060_REG_DAPSV 0x10 41#define PCM3060_REG_DAPSV 0x10
42#define PCM3060_REG_SHIFT_DAPSV 0x04
40#define PCM3060_REG_SE 0x01 43#define PCM3060_REG_SE 0x01
41 44
42#define PCM3060_REG65 0x41 45#define PCM3060_REG65 0x41
diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c
index 52cc950c9fd1..08d3fe192e65 100644
--- a/sound/soc/codecs/pcm3168a.c
+++ b/sound/soc/codecs/pcm3168a.c
@@ -133,10 +133,6 @@ static const struct snd_kcontrol_new pcm3168a_snd_controls[] = {
133 SOC_DOUBLE("DAC2 Invert Switch", PCM3168A_DAC_INV, 2, 3, 1, 0), 133 SOC_DOUBLE("DAC2 Invert Switch", PCM3168A_DAC_INV, 2, 3, 1, 0),
134 SOC_DOUBLE("DAC3 Invert Switch", PCM3168A_DAC_INV, 4, 5, 1, 0), 134 SOC_DOUBLE("DAC3 Invert Switch", PCM3168A_DAC_INV, 4, 5, 1, 0),
135 SOC_DOUBLE("DAC4 Invert Switch", PCM3168A_DAC_INV, 6, 7, 1, 0), 135 SOC_DOUBLE("DAC4 Invert Switch", PCM3168A_DAC_INV, 6, 7, 1, 0),
136 SOC_DOUBLE_STS("DAC1 Zero Flag", PCM3168A_DAC_ZERO, 0, 1, 1, 0),
137 SOC_DOUBLE_STS("DAC2 Zero Flag", PCM3168A_DAC_ZERO, 2, 3, 1, 0),
138 SOC_DOUBLE_STS("DAC3 Zero Flag", PCM3168A_DAC_ZERO, 4, 5, 1, 0),
139 SOC_DOUBLE_STS("DAC4 Zero Flag", PCM3168A_DAC_ZERO, 6, 7, 1, 0),
140 SOC_ENUM("DAC Volume Control Type", pcm3168a_dac_volume_type), 136 SOC_ENUM("DAC Volume Control Type", pcm3168a_dac_volume_type),
141 SOC_ENUM("DAC Volume Rate Multiplier", pcm3168a_dac_att_mult), 137 SOC_ENUM("DAC Volume Rate Multiplier", pcm3168a_dac_att_mult),
142 SOC_ENUM("DAC De-Emphasis", pcm3168a_dac_demp), 138 SOC_ENUM("DAC De-Emphasis", pcm3168a_dac_demp),
@@ -176,9 +172,6 @@ static const struct snd_kcontrol_new pcm3168a_snd_controls[] = {
176 SOC_DOUBLE("ADC1 Mute Switch", PCM3168A_ADC_MUTE, 0, 1, 1, 0), 172 SOC_DOUBLE("ADC1 Mute Switch", PCM3168A_ADC_MUTE, 0, 1, 1, 0),
177 SOC_DOUBLE("ADC2 Mute Switch", PCM3168A_ADC_MUTE, 2, 3, 1, 0), 173 SOC_DOUBLE("ADC2 Mute Switch", PCM3168A_ADC_MUTE, 2, 3, 1, 0),
178 SOC_DOUBLE("ADC3 Mute Switch", PCM3168A_ADC_MUTE, 4, 5, 1, 0), 174 SOC_DOUBLE("ADC3 Mute Switch", PCM3168A_ADC_MUTE, 4, 5, 1, 0),
179 SOC_DOUBLE_STS("ADC1 Overflow Flag", PCM3168A_ADC_OV, 0, 1, 1, 0),
180 SOC_DOUBLE_STS("ADC2 Overflow Flag", PCM3168A_ADC_OV, 2, 3, 1, 0),
181 SOC_DOUBLE_STS("ADC3 Overflow Flag", PCM3168A_ADC_OV, 4, 5, 1, 0),
182 SOC_ENUM("ADC Volume Control Type", pcm3168a_adc_volume_type), 175 SOC_ENUM("ADC Volume Control Type", pcm3168a_adc_volume_type),
183 SOC_ENUM("ADC Volume Rate Multiplier", pcm3168a_adc_att_mult), 176 SOC_ENUM("ADC Volume Rate Multiplier", pcm3168a_adc_att_mult),
184 SOC_ENUM("ADC Overflow Flag Polarity", pcm3168a_adc_ov_pol), 177 SOC_ENUM("ADC Overflow Flag Polarity", pcm3168a_adc_ov_pol),
@@ -504,6 +497,10 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream,
504 unsigned int fmt; 497 unsigned int fmt;
505 unsigned int sample_min; 498 unsigned int sample_min;
506 unsigned int channel_max; 499 unsigned int channel_max;
500 unsigned int channel_maxs[] = {
501 6, /* rx */
502 8 /* tx */
503 };
507 504
508 if (tx) 505 if (tx)
509 fmt = pcm3168a->dac_fmt; 506 fmt = pcm3168a->dac_fmt;
@@ -528,18 +525,9 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream,
528 channel_max = 2; 525 channel_max = 2;
529 break; 526 break;
530 case PCM3168A_FMT_LEFT_J: 527 case PCM3168A_FMT_LEFT_J:
531 sample_min = 24;
532 if (tx)
533 channel_max = 8;
534 else
535 channel_max = 6;
536 break;
537 case PCM3168A_FMT_I2S: 528 case PCM3168A_FMT_I2S:
538 sample_min = 24; 529 sample_min = 24;
539 if (tx) 530 channel_max = channel_maxs[tx];
540 channel_max = 8;
541 else
542 channel_max = 6;
543 break; 531 break;
544 default: 532 default:
545 sample_min = 24; 533 sample_min = 24;
@@ -770,15 +758,22 @@ err_clk:
770} 758}
771EXPORT_SYMBOL_GPL(pcm3168a_probe); 759EXPORT_SYMBOL_GPL(pcm3168a_probe);
772 760
773void pcm3168a_remove(struct device *dev) 761static void pcm3168a_disable(struct device *dev)
774{ 762{
775 struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev); 763 struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev);
776 764
777 pm_runtime_disable(dev);
778 regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies), 765 regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies),
779 pcm3168a->supplies); 766 pcm3168a->supplies);
780 clk_disable_unprepare(pcm3168a->scki); 767 clk_disable_unprepare(pcm3168a->scki);
781} 768}
769
770void pcm3168a_remove(struct device *dev)
771{
772 pm_runtime_disable(dev);
773#ifndef CONFIG_PM
774 pcm3168a_disable(dev);
775#endif
776}
782EXPORT_SYMBOL_GPL(pcm3168a_remove); 777EXPORT_SYMBOL_GPL(pcm3168a_remove);
783 778
784#ifdef CONFIG_PM 779#ifdef CONFIG_PM
@@ -833,10 +828,7 @@ static int pcm3168a_rt_suspend(struct device *dev)
833 828
834 regcache_cache_only(pcm3168a->regmap, true); 829 regcache_cache_only(pcm3168a->regmap, true);
835 830
836 regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies), 831 pcm3168a_disable(dev);
837 pcm3168a->supplies);
838
839 clk_disable_unprepare(pcm3168a->scki);
840 832
841 return 0; 833 return 0;
842} 834}
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
index f0f2d4fd3769..6cb1653be804 100644
--- a/sound/soc/codecs/pcm512x.c
+++ b/sound/soc/codecs/pcm512x.c
@@ -53,6 +53,8 @@ struct pcm512x_priv {
53 unsigned long overclock_pll; 53 unsigned long overclock_pll;
54 unsigned long overclock_dac; 54 unsigned long overclock_dac;
55 unsigned long overclock_dsp; 55 unsigned long overclock_dsp;
56 int mute;
57 struct mutex mutex;
56}; 58};
57 59
58/* 60/*
@@ -384,6 +386,61 @@ static const struct soc_enum pcm512x_veds =
384 SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDS_SHIFT, 4, 386 SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDS_SHIFT, 4,
385 pcm512x_ramp_step_text); 387 pcm512x_ramp_step_text);
386 388
389static int pcm512x_update_mute(struct pcm512x_priv *pcm512x)
390{
391 return regmap_update_bits(
392 pcm512x->regmap, PCM512x_MUTE, PCM512x_RQML | PCM512x_RQMR,
393 (!!(pcm512x->mute & 0x5) << PCM512x_RQML_SHIFT)
394 | (!!(pcm512x->mute & 0x3) << PCM512x_RQMR_SHIFT));
395}
396
397static int pcm512x_digital_playback_switch_get(struct snd_kcontrol *kcontrol,
398 struct snd_ctl_elem_value *ucontrol)
399{
400 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
401 struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
402
403 mutex_lock(&pcm512x->mutex);
404 ucontrol->value.integer.value[0] = !(pcm512x->mute & 0x4);
405 ucontrol->value.integer.value[1] = !(pcm512x->mute & 0x2);
406 mutex_unlock(&pcm512x->mutex);
407
408 return 0;
409}
410
411static int pcm512x_digital_playback_switch_put(struct snd_kcontrol *kcontrol,
412 struct snd_ctl_elem_value *ucontrol)
413{
414 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
415 struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
416 int ret, changed = 0;
417
418 mutex_lock(&pcm512x->mutex);
419
420 if ((pcm512x->mute & 0x4) == (ucontrol->value.integer.value[0] << 2)) {
421 pcm512x->mute ^= 0x4;
422 changed = 1;
423 }
424 if ((pcm512x->mute & 0x2) == (ucontrol->value.integer.value[1] << 1)) {
425 pcm512x->mute ^= 0x2;
426 changed = 1;
427 }
428
429 if (changed) {
430 ret = pcm512x_update_mute(pcm512x);
431 if (ret != 0) {
432 dev_err(component->dev,
433 "Failed to update digital mute: %d\n", ret);
434 mutex_unlock(&pcm512x->mutex);
435 return ret;
436 }
437 }
438
439 mutex_unlock(&pcm512x->mutex);
440
441 return changed;
442}
443
387static const struct snd_kcontrol_new pcm512x_controls[] = { 444static const struct snd_kcontrol_new pcm512x_controls[] = {
388SOC_DOUBLE_R_TLV("Digital Playback Volume", PCM512x_DIGITAL_VOLUME_2, 445SOC_DOUBLE_R_TLV("Digital Playback Volume", PCM512x_DIGITAL_VOLUME_2,
389 PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv), 446 PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv),
@@ -391,8 +448,15 @@ SOC_DOUBLE_TLV("Analogue Playback Volume", PCM512x_ANALOG_GAIN_CTRL,
391 PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv), 448 PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv),
392SOC_DOUBLE_TLV("Analogue Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST, 449SOC_DOUBLE_TLV("Analogue Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST,
393 PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv), 450 PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv),
394SOC_DOUBLE("Digital Playback Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT, 451{
395 PCM512x_RQMR_SHIFT, 1, 1), 452 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
453 .name = "Digital Playback Switch",
454 .index = 0,
455 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
456 .info = snd_ctl_boolean_stereo_info,
457 .get = pcm512x_digital_playback_switch_get,
458 .put = pcm512x_digital_playback_switch_put
459},
396 460
397SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1), 461SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1),
398SOC_ENUM("DSP Program", pcm512x_dsp_program), 462SOC_ENUM("DSP Program", pcm512x_dsp_program),
@@ -1319,10 +1383,61 @@ static int pcm512x_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1319 return 0; 1383 return 0;
1320} 1384}
1321 1385
1386static int pcm512x_digital_mute(struct snd_soc_dai *dai, int mute)
1387{
1388 struct snd_soc_component *component = dai->component;
1389 struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
1390 int ret;
1391 unsigned int mute_det;
1392
1393 mutex_lock(&pcm512x->mutex);
1394
1395 if (mute) {
1396 pcm512x->mute |= 0x1;
1397 ret = regmap_update_bits(pcm512x->regmap, PCM512x_MUTE,
1398 PCM512x_RQML | PCM512x_RQMR,
1399 PCM512x_RQML | PCM512x_RQMR);
1400 if (ret != 0) {
1401 dev_err(component->dev,
1402 "Failed to set digital mute: %d\n", ret);
1403 mutex_unlock(&pcm512x->mutex);
1404 return ret;
1405 }
1406
1407 regmap_read_poll_timeout(pcm512x->regmap,
1408 PCM512x_ANALOG_MUTE_DET,
1409 mute_det, (mute_det & 0x3) == 0,
1410 200, 10000);
1411
1412 mutex_unlock(&pcm512x->mutex);
1413 } else {
1414 pcm512x->mute &= ~0x1;
1415 ret = pcm512x_update_mute(pcm512x);
1416 if (ret != 0) {
1417 dev_err(component->dev,
1418 "Failed to update digital mute: %d\n", ret);
1419 mutex_unlock(&pcm512x->mutex);
1420 return ret;
1421 }
1422
1423 regmap_read_poll_timeout(pcm512x->regmap,
1424 PCM512x_ANALOG_MUTE_DET,
1425 mute_det,
1426 (mute_det & 0x3)
1427 == ((~pcm512x->mute >> 1) & 0x3),
1428 200, 10000);
1429 }
1430
1431 mutex_unlock(&pcm512x->mutex);
1432
1433 return 0;
1434}
1435
1322static const struct snd_soc_dai_ops pcm512x_dai_ops = { 1436static const struct snd_soc_dai_ops pcm512x_dai_ops = {
1323 .startup = pcm512x_dai_startup, 1437 .startup = pcm512x_dai_startup,
1324 .hw_params = pcm512x_hw_params, 1438 .hw_params = pcm512x_hw_params,
1325 .set_fmt = pcm512x_set_fmt, 1439 .set_fmt = pcm512x_set_fmt,
1440 .digital_mute = pcm512x_digital_mute,
1326}; 1441};
1327 1442
1328static struct snd_soc_dai_driver pcm512x_dai = { 1443static struct snd_soc_dai_driver pcm512x_dai = {
@@ -1388,6 +1503,8 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap)
1388 if (!pcm512x) 1503 if (!pcm512x)
1389 return -ENOMEM; 1504 return -ENOMEM;
1390 1505
1506 mutex_init(&pcm512x->mutex);
1507
1391 dev_set_drvdata(dev, pcm512x); 1508 dev_set_drvdata(dev, pcm512x);
1392 pcm512x->regmap = regmap; 1509 pcm512x->regmap = regmap;
1393 1510
diff --git a/sound/soc/codecs/pcm512x.h b/sound/soc/codecs/pcm512x.h
index d70d9c0c2088..9dda8693498e 100644
--- a/sound/soc/codecs/pcm512x.h
+++ b/sound/soc/codecs/pcm512x.h
@@ -112,7 +112,9 @@
112#define PCM512x_RQST_SHIFT 4 112#define PCM512x_RQST_SHIFT 4
113 113
114/* Page 0, Register 3 - mute */ 114/* Page 0, Register 3 - mute */
115#define PCM512x_RQMR (1 << 0)
115#define PCM512x_RQMR_SHIFT 0 116#define PCM512x_RQMR_SHIFT 0
117#define PCM512x_RQML (1 << 4)
116#define PCM512x_RQML_SHIFT 4 118#define PCM512x_RQML_SHIFT 4
117 119
118/* Page 0, Register 4 - PLL */ 120/* Page 0, Register 4 - PLL */
diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c
index 27f7445b2432..e74b2e8cd423 100644
--- a/sound/soc/codecs/rt5660.c
+++ b/sound/soc/codecs/rt5660.c
@@ -1246,6 +1246,7 @@ MODULE_DEVICE_TABLE(of, rt5660_of_match);
1246 1246
1247static const struct acpi_device_id rt5660_acpi_match[] = { 1247static const struct acpi_device_id rt5660_acpi_match[] = {
1248 { "10EC5660", 0 }, 1248 { "10EC5660", 0 },
1249 { "10EC3277", 0 },
1249 { }, 1250 { },
1250}; 1251};
1251MODULE_DEVICE_TABLE(acpi, rt5660_acpi_match); 1252MODULE_DEVICE_TABLE(acpi, rt5660_acpi_match);
diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c
index 7eb2cbd39d6e..da6647015708 100644
--- a/sound/soc/codecs/rt5663.c
+++ b/sound/soc/codecs/rt5663.c
@@ -17,6 +17,7 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/spi/spi.h> 18#include <linux/spi/spi.h>
19#include <linux/acpi.h> 19#include <linux/acpi.h>
20#include <linux/regulator/consumer.h>
20#include <linux/workqueue.h> 21#include <linux/workqueue.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
@@ -33,6 +34,9 @@
33#define RT5663_DEVICE_ID_2 0x6451 34#define RT5663_DEVICE_ID_2 0x6451
34#define RT5663_DEVICE_ID_1 0x6406 35#define RT5663_DEVICE_ID_1 0x6406
35 36
37#define RT5663_POWER_ON_DELAY_MS 300
38#define RT5663_SUPPLY_CURRENT_UA 500000
39
36enum { 40enum {
37 CODEC_VER_1, 41 CODEC_VER_1,
38 CODEC_VER_0, 42 CODEC_VER_0,
@@ -48,6 +52,11 @@ struct impedance_mapping_table {
48 unsigned int dc_offset_r_manual_mic; 52 unsigned int dc_offset_r_manual_mic;
49}; 53};
50 54
55static const char *const rt5663_supply_names[] = {
56 "avdd",
57 "cpvdd",
58};
59
51struct rt5663_priv { 60struct rt5663_priv {
52 struct snd_soc_component *component; 61 struct snd_soc_component *component;
53 struct rt5663_platform_data pdata; 62 struct rt5663_platform_data pdata;
@@ -56,6 +65,7 @@ struct rt5663_priv {
56 struct snd_soc_jack *hs_jack; 65 struct snd_soc_jack *hs_jack;
57 struct timer_list btn_check_timer; 66 struct timer_list btn_check_timer;
58 struct impedance_mapping_table *imp_table; 67 struct impedance_mapping_table *imp_table;
68 struct regulator_bulk_data supplies[ARRAY_SIZE(rt5663_supply_names)];
59 69
60 int codec_ver; 70 int codec_ver;
61 int sysclk; 71 int sysclk;
@@ -3483,7 +3493,7 @@ static int rt5663_i2c_probe(struct i2c_client *i2c,
3483{ 3493{
3484 struct rt5663_platform_data *pdata = dev_get_platdata(&i2c->dev); 3494 struct rt5663_platform_data *pdata = dev_get_platdata(&i2c->dev);
3485 struct rt5663_priv *rt5663; 3495 struct rt5663_priv *rt5663;
3486 int ret; 3496 int ret, i;
3487 unsigned int val; 3497 unsigned int val;
3488 struct regmap *regmap; 3498 struct regmap *regmap;
3489 3499
@@ -3500,12 +3510,44 @@ static int rt5663_i2c_probe(struct i2c_client *i2c,
3500 else 3510 else
3501 rt5663_parse_dp(rt5663, &i2c->dev); 3511 rt5663_parse_dp(rt5663, &i2c->dev);
3502 3512
3513 for (i = 0; i < ARRAY_SIZE(rt5663->supplies); i++)
3514 rt5663->supplies[i].supply = rt5663_supply_names[i];
3515
3516 ret = devm_regulator_bulk_get(&i2c->dev,
3517 ARRAY_SIZE(rt5663->supplies),
3518 rt5663->supplies);
3519 if (ret) {
3520 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
3521 return ret;
3522 }
3523
3524 /* Set load for regulator. */
3525 for (i = 0; i < ARRAY_SIZE(rt5663->supplies); i++) {
3526 ret = regulator_set_load(rt5663->supplies[i].consumer,
3527 RT5663_SUPPLY_CURRENT_UA);
3528 if (ret < 0) {
3529 dev_err(&i2c->dev,
3530 "Failed to set regulator load on %s, ret: %d\n",
3531 rt5663->supplies[i].supply, ret);
3532 return ret;
3533 }
3534 }
3535
3536 ret = regulator_bulk_enable(ARRAY_SIZE(rt5663->supplies),
3537 rt5663->supplies);
3538
3539 if (ret) {
3540 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
3541 return ret;
3542 }
3543 msleep(RT5663_POWER_ON_DELAY_MS);
3544
3503 regmap = devm_regmap_init_i2c(i2c, &temp_regmap); 3545 regmap = devm_regmap_init_i2c(i2c, &temp_regmap);
3504 if (IS_ERR(regmap)) { 3546 if (IS_ERR(regmap)) {
3505 ret = PTR_ERR(regmap); 3547 ret = PTR_ERR(regmap);
3506 dev_err(&i2c->dev, "Failed to allocate temp register map: %d\n", 3548 dev_err(&i2c->dev, "Failed to allocate temp register map: %d\n",
3507 ret); 3549 ret);
3508 return ret; 3550 goto err_enable;
3509 } 3551 }
3510 3552
3511 ret = regmap_read(regmap, RT5663_VENDOR_ID_2, &val); 3553 ret = regmap_read(regmap, RT5663_VENDOR_ID_2, &val);
@@ -3530,14 +3572,15 @@ static int rt5663_i2c_probe(struct i2c_client *i2c,
3530 dev_err(&i2c->dev, 3572 dev_err(&i2c->dev,
3531 "Device with ID register %#x is not rt5663\n", 3573 "Device with ID register %#x is not rt5663\n",
3532 val); 3574 val);
3533 return -ENODEV; 3575 ret = -ENODEV;
3576 goto err_enable;
3534 } 3577 }
3535 3578
3536 if (IS_ERR(rt5663->regmap)) { 3579 if (IS_ERR(rt5663->regmap)) {
3537 ret = PTR_ERR(rt5663->regmap); 3580 ret = PTR_ERR(rt5663->regmap);
3538 dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 3581 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
3539 ret); 3582 ret);
3540 return ret; 3583 goto err_enable;
3541 } 3584 }
3542 3585
3543 /* reset and calibrate */ 3586 /* reset and calibrate */
@@ -3635,20 +3678,32 @@ static int rt5663_i2c_probe(struct i2c_client *i2c,
3635 ret = request_irq(i2c->irq, rt5663_irq, 3678 ret = request_irq(i2c->irq, rt5663_irq,
3636 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING 3679 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
3637 | IRQF_ONESHOT, "rt5663", rt5663); 3680 | IRQF_ONESHOT, "rt5663", rt5663);
3638 if (ret) 3681 if (ret) {
3639 dev_err(&i2c->dev, "%s Failed to reguest IRQ: %d\n", 3682 dev_err(&i2c->dev, "%s Failed to reguest IRQ: %d\n",
3640 __func__, ret); 3683 __func__, ret);
3684 goto err_enable;
3685 }
3641 } 3686 }
3642 3687
3643 ret = devm_snd_soc_register_component(&i2c->dev, 3688 ret = devm_snd_soc_register_component(&i2c->dev,
3644 &soc_component_dev_rt5663, 3689 &soc_component_dev_rt5663,
3645 rt5663_dai, ARRAY_SIZE(rt5663_dai)); 3690 rt5663_dai, ARRAY_SIZE(rt5663_dai));
3646 3691
3647 if (ret) { 3692 if (ret)
3648 if (i2c->irq) 3693 goto err_enable;
3649 free_irq(i2c->irq, rt5663);
3650 }
3651 3694
3695 return 0;
3696
3697
3698 /*
3699 * Error after enabling regulators should goto err_enable
3700 * to disable regulators.
3701 */
3702err_enable:
3703 if (i2c->irq)
3704 free_irq(i2c->irq, rt5663);
3705
3706 regulator_bulk_disable(ARRAY_SIZE(rt5663->supplies), rt5663->supplies);
3652 return ret; 3707 return ret;
3653} 3708}
3654 3709
@@ -3659,6 +3714,8 @@ static int rt5663_i2c_remove(struct i2c_client *i2c)
3659 if (i2c->irq) 3714 if (i2c->irq)
3660 free_irq(i2c->irq, rt5663); 3715 free_irq(i2c->irq, rt5663);
3661 3716
3717 regulator_bulk_disable(ARRAY_SIZE(rt5663->supplies), rt5663->supplies);
3718
3662 return 0; 3719 return 0;
3663} 3720}
3664 3721
diff --git a/sound/soc/codecs/simple-amplifier.c b/sound/soc/codecs/simple-amplifier.c
index 85524acf3e9c..c07e8a80b4b7 100644
--- a/sound/soc/codecs/simple-amplifier.c
+++ b/sound/soc/codecs/simple-amplifier.c
@@ -19,6 +19,7 @@
19 19
20#include <linux/gpio/consumer.h> 20#include <linux/gpio/consumer.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/regulator/consumer.h>
22#include <sound/soc.h> 23#include <sound/soc.h>
23 24
24#define DRV_NAME "simple-amplifier" 25#define DRV_NAME "simple-amplifier"
@@ -58,11 +59,14 @@ static const struct snd_soc_dapm_widget simple_amp_dapm_widgets[] = {
58 (SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)), 59 (SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)),
59 SND_SOC_DAPM_OUTPUT("OUTL"), 60 SND_SOC_DAPM_OUTPUT("OUTL"),
60 SND_SOC_DAPM_OUTPUT("OUTR"), 61 SND_SOC_DAPM_OUTPUT("OUTR"),
62 SND_SOC_DAPM_REGULATOR_SUPPLY("VCC", 20, 0),
61}; 63};
62 64
63static const struct snd_soc_dapm_route simple_amp_dapm_routes[] = { 65static const struct snd_soc_dapm_route simple_amp_dapm_routes[] = {
64 { "DRV", NULL, "INL" }, 66 { "DRV", NULL, "INL" },
65 { "DRV", NULL, "INR" }, 67 { "DRV", NULL, "INR" },
68 { "OUTL", NULL, "VCC" },
69 { "OUTR", NULL, "VCC" },
66 { "OUTL", NULL, "DRV" }, 70 { "OUTL", NULL, "DRV" },
67 { "OUTR", NULL, "DRV" }, 71 { "OUTR", NULL, "DRV" },
68}; 72};
diff --git a/sound/soc/codecs/tas6424.c b/sound/soc/codecs/tas6424.c
index 36aebdb8f55c..aaba39295079 100644
--- a/sound/soc/codecs/tas6424.c
+++ b/sound/soc/codecs/tas6424.c
@@ -378,7 +378,7 @@ static struct snd_soc_component_driver soc_codec_dev_tas6424 = {
378 .non_legacy_dai_naming = 1, 378 .non_legacy_dai_naming = 1,
379}; 379};
380 380
381static struct snd_soc_dai_ops tas6424_speaker_dai_ops = { 381static const struct snd_soc_dai_ops tas6424_speaker_dai_ops = {
382 .hw_params = tas6424_hw_params, 382 .hw_params = tas6424_hw_params,
383 .set_fmt = tas6424_set_dai_fmt, 383 .set_fmt = tas6424_set_dai_fmt,
384 .set_tdm_slot = tas6424_set_dai_tdm_slot, 384 .set_tdm_slot = tas6424_set_dai_tdm_slot,
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
index 608ad49ad978..c6048d95c6d3 100644
--- a/sound/soc/codecs/tlv320aic31xx.c
+++ b/sound/soc/codecs/tlv320aic31xx.c
@@ -1095,7 +1095,7 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1095 if (freq/i > 20000000) { 1095 if (freq/i > 20000000) {
1096 dev_err(aic31xx->dev, "%s: Too high mclk frequency %u\n", 1096 dev_err(aic31xx->dev, "%s: Too high mclk frequency %u\n",
1097 __func__, freq); 1097 __func__, freq);
1098 return -EINVAL; 1098 return -EINVAL;
1099 } 1099 }
1100 aic31xx->p_div = i; 1100 aic31xx->p_div = i;
1101 1101
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 6a271e6e6b8f..6aa0edf8c5ef 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -1260,6 +1260,16 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
1260 aic3x->master = 0; 1260 aic3x->master = 0;
1261 iface_areg &= ~(BIT_CLK_MASTER | WORD_CLK_MASTER); 1261 iface_areg &= ~(BIT_CLK_MASTER | WORD_CLK_MASTER);
1262 break; 1262 break;
1263 case SND_SOC_DAIFMT_CBM_CFS:
1264 aic3x->master = 1;
1265 iface_areg |= BIT_CLK_MASTER;
1266 iface_areg &= ~WORD_CLK_MASTER;
1267 break;
1268 case SND_SOC_DAIFMT_CBS_CFM:
1269 aic3x->master = 1;
1270 iface_areg |= WORD_CLK_MASTER;
1271 iface_areg &= ~BIT_CLK_MASTER;
1272 break;
1263 default: 1273 default:
1264 return -EINVAL; 1274 return -EINVAL;
1265 } 1275 }
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index a957eaeb7bc1..32907b1e20cf 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -394,7 +394,7 @@ static int dac33_hard_power(struct snd_soc_component *component, int power)
394 if (ret != 0) { 394 if (ret != 0) {
395 dev_err(component->dev, 395 dev_err(component->dev,
396 "Failed to enable supplies: %d\n", ret); 396 "Failed to enable supplies: %d\n", ret);
397 goto exit; 397 goto exit;
398 } 398 }
399 399
400 if (dac33->power_gpio >= 0) 400 if (dac33->power_gpio >= 0)
diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c
index 61294c787f27..409bed30a4e4 100644
--- a/sound/soc/codecs/wm8998.c
+++ b/sound/soc/codecs/wm8998.c
@@ -60,7 +60,7 @@ static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w,
60 dev_warn(component->dev, 60 dev_warn(component->dev,
61 "Unsupported ASRC rate1 (%s)\n", 61 "Unsupported ASRC rate1 (%s)\n",
62 arizona_sample_rate_val_to_name(val)); 62 arizona_sample_rate_val_to_name(val));
63 return -EINVAL; 63 return -EINVAL;
64 } 64 }
65 break; 65 break;
66 default: 66 default:
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index ccdf088461b7..54c306707c02 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -325,8 +325,7 @@ static int wm9705_soc_probe(struct snd_soc_component *component)
325 if (wm9705->mfd_pdata) { 325 if (wm9705->mfd_pdata) {
326 wm9705->ac97 = wm9705->mfd_pdata->ac97; 326 wm9705->ac97 = wm9705->mfd_pdata->ac97;
327 regmap = wm9705->mfd_pdata->regmap; 327 regmap = wm9705->mfd_pdata->regmap;
328 } else { 328 } else if (IS_ENABLED(CONFIG_SND_SOC_AC97_BUS)) {
329#ifdef CONFIG_SND_SOC_AC97_BUS
330 wm9705->ac97 = snd_soc_new_ac97_component(component, WM9705_VENDOR_ID, 329 wm9705->ac97 = snd_soc_new_ac97_component(component, WM9705_VENDOR_ID,
331 WM9705_VENDOR_ID_MASK); 330 WM9705_VENDOR_ID_MASK);
332 if (IS_ERR(wm9705->ac97)) { 331 if (IS_ERR(wm9705->ac97)) {
@@ -339,7 +338,8 @@ static int wm9705_soc_probe(struct snd_soc_component *component)
339 snd_soc_free_ac97_component(wm9705->ac97); 338 snd_soc_free_ac97_component(wm9705->ac97);
340 return PTR_ERR(regmap); 339 return PTR_ERR(regmap);
341 } 340 }
342#endif 341 } else {
342 return -ENXIO;
343 } 343 }
344 344
345 snd_soc_component_set_drvdata(component, wm9705->ac97); 345 snd_soc_component_set_drvdata(component, wm9705->ac97);
@@ -350,14 +350,12 @@ static int wm9705_soc_probe(struct snd_soc_component *component)
350 350
351static void wm9705_soc_remove(struct snd_soc_component *component) 351static void wm9705_soc_remove(struct snd_soc_component *component)
352{ 352{
353#ifdef CONFIG_SND_SOC_AC97_BUS
354 struct wm9705_priv *wm9705 = snd_soc_component_get_drvdata(component); 353 struct wm9705_priv *wm9705 = snd_soc_component_get_drvdata(component);
355 354
356 if (!wm9705->mfd_pdata) { 355 if (IS_ENABLED(CONFIG_SND_SOC_AC97_BUS) && !wm9705->mfd_pdata) {
357 snd_soc_component_exit_regmap(component); 356 snd_soc_component_exit_regmap(component);
358 snd_soc_free_ac97_component(wm9705->ac97); 357 snd_soc_free_ac97_component(wm9705->ac97);
359 } 358 }
360#endif
361} 359}
362 360
363static const struct snd_soc_component_driver soc_component_dev_wm9705 = { 361static const struct snd_soc_component_driver soc_component_dev_wm9705 = {
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index e873baa9e778..01949eaba4fd 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -642,8 +642,7 @@ static int wm9712_soc_probe(struct snd_soc_component *component)
642 if (wm9712->mfd_pdata) { 642 if (wm9712->mfd_pdata) {
643 wm9712->ac97 = wm9712->mfd_pdata->ac97; 643 wm9712->ac97 = wm9712->mfd_pdata->ac97;
644 regmap = wm9712->mfd_pdata->regmap; 644 regmap = wm9712->mfd_pdata->regmap;
645 } else { 645 } else if (IS_ENABLED(CONFIG_SND_SOC_AC97_BUS)) {
646#ifdef CONFIG_SND_SOC_AC97_BUS
647 int ret; 646 int ret;
648 647
649 wm9712->ac97 = snd_soc_new_ac97_component(component, WM9712_VENDOR_ID, 648 wm9712->ac97 = snd_soc_new_ac97_component(component, WM9712_VENDOR_ID,
@@ -660,7 +659,8 @@ static int wm9712_soc_probe(struct snd_soc_component *component)
660 snd_soc_free_ac97_component(wm9712->ac97); 659 snd_soc_free_ac97_component(wm9712->ac97);
661 return PTR_ERR(regmap); 660 return PTR_ERR(regmap);
662 } 661 }
663#endif 662 } else {
663 return -ENXIO;
664 } 664 }
665 665
666 snd_soc_component_init_regmap(component, regmap); 666 snd_soc_component_init_regmap(component, regmap);
@@ -673,14 +673,12 @@ static int wm9712_soc_probe(struct snd_soc_component *component)
673 673
674static void wm9712_soc_remove(struct snd_soc_component *component) 674static void wm9712_soc_remove(struct snd_soc_component *component)
675{ 675{
676#ifdef CONFIG_SND_SOC_AC97_BUS
677 struct wm9712_priv *wm9712 = snd_soc_component_get_drvdata(component); 676 struct wm9712_priv *wm9712 = snd_soc_component_get_drvdata(component);
678 677
679 if (!wm9712->mfd_pdata) { 678 if (IS_ENABLED(CONFIG_SND_SOC_AC97_BUS) && !wm9712->mfd_pdata) {
680 snd_soc_component_exit_regmap(component); 679 snd_soc_component_exit_regmap(component);
681 snd_soc_free_ac97_component(wm9712->ac97); 680 snd_soc_free_ac97_component(wm9712->ac97);
682 } 681 }
683#endif
684} 682}
685 683
686static const struct snd_soc_component_driver soc_component_dev_wm9712 = { 684static const struct snd_soc_component_driver soc_component_dev_wm9712 = {
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 643863bb32e0..5a2fdf4f69bf 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -1214,8 +1214,7 @@ static int wm9713_soc_probe(struct snd_soc_component *component)
1214 if (wm9713->mfd_pdata) { 1214 if (wm9713->mfd_pdata) {
1215 wm9713->ac97 = wm9713->mfd_pdata->ac97; 1215 wm9713->ac97 = wm9713->mfd_pdata->ac97;
1216 regmap = wm9713->mfd_pdata->regmap; 1216 regmap = wm9713->mfd_pdata->regmap;
1217 } else { 1217 } else if (IS_ENABLED(CONFIG_SND_SOC_AC97_BUS)) {
1218#ifdef CONFIG_SND_SOC_AC97_BUS
1219 wm9713->ac97 = snd_soc_new_ac97_component(component, WM9713_VENDOR_ID, 1218 wm9713->ac97 = snd_soc_new_ac97_component(component, WM9713_VENDOR_ID,
1220 WM9713_VENDOR_ID_MASK); 1219 WM9713_VENDOR_ID_MASK);
1221 if (IS_ERR(wm9713->ac97)) 1220 if (IS_ERR(wm9713->ac97))
@@ -1225,7 +1224,8 @@ static int wm9713_soc_probe(struct snd_soc_component *component)
1225 snd_soc_free_ac97_component(wm9713->ac97); 1224 snd_soc_free_ac97_component(wm9713->ac97);
1226 return PTR_ERR(regmap); 1225 return PTR_ERR(regmap);
1227 } 1226 }
1228#endif 1227 } else {
1228 return -ENXIO;
1229 } 1229 }
1230 1230
1231 snd_soc_component_init_regmap(component, regmap); 1231 snd_soc_component_init_regmap(component, regmap);
@@ -1238,14 +1238,12 @@ static int wm9713_soc_probe(struct snd_soc_component *component)
1238 1238
1239static void wm9713_soc_remove(struct snd_soc_component *component) 1239static void wm9713_soc_remove(struct snd_soc_component *component)
1240{ 1240{
1241#ifdef CONFIG_SND_SOC_AC97_BUS
1242 struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component); 1241 struct wm9713_priv *wm9713 = snd_soc_component_get_drvdata(component);
1243 1242
1244 if (!wm9713->mfd_pdata) { 1243 if (IS_ENABLED(CONFIG_SND_SOC_AC97_BUS) && !wm9713->mfd_pdata) {
1245 snd_soc_component_exit_regmap(component); 1244 snd_soc_component_exit_regmap(component);
1246 snd_soc_free_ac97_component(wm9713->ac97); 1245 snd_soc_free_ac97_component(wm9713->ac97);
1247 } 1246 }
1248#endif
1249} 1247}
1250 1248
1251static const struct snd_soc_component_driver soc_component_dev_wm9713 = { 1249static const struct snd_soc_component_driver soc_component_dev_wm9713 = {
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 66501b8dc46f..1dd291cebe67 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -2419,7 +2419,7 @@ static int wm_adsp_create_name(struct wm_adsp *dsp)
2419 return 0; 2419 return 0;
2420} 2420}
2421 2421
2422int wm_adsp1_init(struct wm_adsp *dsp) 2422static int wm_adsp_common_init(struct wm_adsp *dsp)
2423{ 2423{
2424 int ret; 2424 int ret;
2425 2425
@@ -2428,11 +2428,17 @@ int wm_adsp1_init(struct wm_adsp *dsp)
2428 return ret; 2428 return ret;
2429 2429
2430 INIT_LIST_HEAD(&dsp->alg_regions); 2430 INIT_LIST_HEAD(&dsp->alg_regions);
2431 INIT_LIST_HEAD(&dsp->ctl_list);
2431 2432
2432 mutex_init(&dsp->pwr_lock); 2433 mutex_init(&dsp->pwr_lock);
2433 2434
2434 return 0; 2435 return 0;
2435} 2436}
2437
2438int wm_adsp1_init(struct wm_adsp *dsp)
2439{
2440 return wm_adsp_common_init(dsp);
2441}
2436EXPORT_SYMBOL_GPL(wm_adsp1_init); 2442EXPORT_SYMBOL_GPL(wm_adsp1_init);
2437 2443
2438int wm_adsp1_event(struct snd_soc_dapm_widget *w, 2444int wm_adsp1_event(struct snd_soc_dapm_widget *w,
@@ -2917,7 +2923,7 @@ int wm_adsp2_init(struct wm_adsp *dsp)
2917{ 2923{
2918 int ret; 2924 int ret;
2919 2925
2920 ret = wm_adsp_create_name(dsp); 2926 ret = wm_adsp_common_init(dsp);
2921 if (ret) 2927 if (ret)
2922 return ret; 2928 return ret;
2923 2929
@@ -2939,12 +2945,8 @@ int wm_adsp2_init(struct wm_adsp *dsp)
2939 break; 2945 break;
2940 } 2946 }
2941 2947
2942 INIT_LIST_HEAD(&dsp->alg_regions);
2943 INIT_LIST_HEAD(&dsp->ctl_list);
2944 INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work); 2948 INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work);
2945 2949
2946 mutex_init(&dsp->pwr_lock);
2947
2948 return 0; 2950 return 0;
2949} 2951}
2950EXPORT_SYMBOL_GPL(wm_adsp2_init); 2952EXPORT_SYMBOL_GPL(wm_adsp2_init);
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
deleted file mode 100644
index 778faff28e0e..000000000000
--- a/sound/soc/davinci/Kconfig
+++ /dev/null
@@ -1,106 +0,0 @@
1config SND_DAVINCI_SOC
2 tristate
3 depends on ARCH_DAVINCI
4 select SND_EDMA_SOC
5
6config SND_EDMA_SOC
7 tristate "SoC Audio for Texas Instruments chips using eDMA"
8 depends on TI_EDMA
9 select SND_SOC_GENERIC_DMAENGINE_PCM
10 help
11 Say Y or M here if you want audio support for TI SoC which uses eDMA.
12 The following line of SoCs are supported by this platform driver:
13 - daVinci devices
14 - AM335x
15 - AM437x/AM438x
16 - DRA7xx family
17
18config SND_DAVINCI_SOC_I2S
19 tristate "DaVinci Multichannel Buffered Serial Port (McBSP) support"
20 depends on SND_EDMA_SOC
21 help
22 Say Y or M here if you want to have support for McBSP IP found in
23 Texas Instruments DaVinci DA850 SoCs.
24
25config SND_DAVINCI_SOC_MCASP
26 tristate "Multichannel Audio Serial Port (McASP) support"
27 depends on SND_SDMA_SOC || SND_EDMA_SOC
28 help
29 Say Y or M here if you want to have support for McASP IP found in
30 various Texas Instruments SoCs like:
31 - daVinci devices
32 - Sitara line of SoCs (AM335x, AM438x, etc)
33 - DRA7x devices
34
35config SND_DAVINCI_SOC_VCIF
36 tristate
37
38config SND_DAVINCI_SOC_GENERIC_EVM
39 tristate
40 select SND_SOC_TLV320AIC3X
41 select SND_DAVINCI_SOC_MCASP
42
43config SND_AM33XX_SOC_EVM
44 tristate "SoC Audio for the AM33XX chip based boards"
45 depends on SND_EDMA_SOC && SOC_AM33XX && I2C
46 select SND_DAVINCI_SOC_GENERIC_EVM
47 help
48 Say Y or M if you want to add support for SoC audio on AM33XX
49 boards using McASP and TLV320AIC3X codec. For example AM335X-EVM,
50 AM335X-EVMSK, and BeagelBone with AudioCape boards have this
51 setup.
52
53config SND_DAVINCI_SOC_EVM
54 tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM"
55 depends on SND_EDMA_SOC && I2C
56 depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM
57 select SND_DAVINCI_SOC_GENERIC_EVM
58 help
59 Say Y if you want to add support for SoC audio on TI
60 DaVinci DM6446, DM355 or DM365 EVM platforms.
61
62choice
63 prompt "DM365 codec select"
64 depends on SND_DAVINCI_SOC_EVM
65 depends on MACH_DAVINCI_DM365_EVM
66
67config SND_DM365_AIC3X_CODEC
68 tristate "Audio Codec - AIC3101"
69 help
70 Say Y if you want to add support for AIC3101 audio codec
71
72config SND_DM365_VOICE_CODEC
73 tristate "Voice Codec - CQ93VC"
74 select MFD_DAVINCI_VOICECODEC
75 select SND_DAVINCI_SOC_VCIF
76 select SND_SOC_CQ0093VC
77 help
78 Say Y if you want to add support for SoC On-chip voice codec
79endchoice
80
81config SND_DM6467_SOC_EVM
82 tristate "SoC Audio support for DaVinci DM6467 EVM"
83 depends on SND_EDMA_SOC && MACH_DAVINCI_DM6467_EVM && I2C
84 select SND_DAVINCI_SOC_GENERIC_EVM
85 select SND_SOC_SPDIF
86
87 help
88 Say Y if you want to add support for SoC audio on TI
89
90config SND_DA830_SOC_EVM
91 tristate "SoC Audio support for DA830/OMAP-L137 EVM"
92 depends on SND_EDMA_SOC && MACH_DAVINCI_DA830_EVM && I2C
93 select SND_DAVINCI_SOC_GENERIC_EVM
94
95 help
96 Say Y if you want to add support for SoC audio on TI
97 DA830/OMAP-L137 EVM
98
99config SND_DA850_SOC_EVM
100 tristate "SoC Audio support for DA850/OMAP-L138 EVM"
101 depends on SND_EDMA_SOC && MACH_DAVINCI_DA850_EVM && I2C
102 select SND_DAVINCI_SOC_GENERIC_EVM
103 help
104 Say Y if you want to add support for SoC audio on TI
105 DA850/OMAP-L138 EVM
106
diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile
deleted file mode 100644
index 23c6592eb31a..000000000000
--- a/sound/soc/davinci/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
1# SPDX-License-Identifier: GPL-2.0
2# DAVINCI Platform Support
3snd-soc-edma-objs := edma-pcm.o
4snd-soc-davinci-i2s-objs := davinci-i2s.o
5snd-soc-davinci-mcasp-objs:= davinci-mcasp.o
6snd-soc-davinci-vcif-objs:= davinci-vcif.o
7
8obj-$(CONFIG_SND_EDMA_SOC) += snd-soc-edma.o
9obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o
10obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o
11obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o
12
13# Generic DAVINCI/AM33xx Machine Support
14snd-soc-evm-objs := davinci-evm.o
15
16obj-$(CONFIG_SND_DAVINCI_SOC_GENERIC_EVM) += snd-soc-evm.o
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 6ec19fb4a934..2e75b5bc5f1d 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -221,7 +221,7 @@ config SND_SOC_PHYCORE_AC97
221 221
222config SND_SOC_EUKREA_TLV320 222config SND_SOC_EUKREA_TLV320
223 tristate "Eukrea TLV320" 223 tristate "Eukrea TLV320"
224 depends on ARCH_MXC && I2C 224 depends on ARCH_MXC && !ARM64 && I2C
225 select SND_SOC_TLV320AIC23_I2C 225 select SND_SOC_TLV320AIC23_I2C
226 select SND_SOC_IMX_AUDMUX 226 select SND_SOC_IMX_AUDMUX
227 select SND_SOC_IMX_SSI 227 select SND_SOC_IMX_SSI
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 44433b20435c..81f2fe2c6d23 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -571,17 +571,17 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
571 } 571 }
572 572
573 /* Common settings for corresponding Freescale CPU DAI driver */ 573 /* Common settings for corresponding Freescale CPU DAI driver */
574 if (strstr(cpu_np->name, "ssi")) { 574 if (of_node_name_eq(cpu_np, "ssi")) {
575 /* Only SSI needs to configure AUDMUX */ 575 /* Only SSI needs to configure AUDMUX */
576 ret = fsl_asoc_card_audmux_init(np, priv); 576 ret = fsl_asoc_card_audmux_init(np, priv);
577 if (ret) { 577 if (ret) {
578 dev_err(&pdev->dev, "failed to init audmux\n"); 578 dev_err(&pdev->dev, "failed to init audmux\n");
579 goto asrc_fail; 579 goto asrc_fail;
580 } 580 }
581 } else if (strstr(cpu_np->name, "esai")) { 581 } else if (of_node_name_eq(cpu_np, "esai")) {
582 priv->cpu_priv.sysclk_id[1] = ESAI_HCKT_EXTAL; 582 priv->cpu_priv.sysclk_id[1] = ESAI_HCKT_EXTAL;
583 priv->cpu_priv.sysclk_id[0] = ESAI_HCKR_EXTAL; 583 priv->cpu_priv.sysclk_id[0] = ESAI_HCKR_EXTAL;
584 } else if (strstr(cpu_np->name, "sai")) { 584 } else if (of_node_name_eq(cpu_np, "sai")) {
585 priv->cpu_priv.sysclk_id[1] = FSL_SAI_CLK_MAST1; 585 priv->cpu_priv.sysclk_id[1] = FSL_SAI_CLK_MAST1;
586 priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1; 586 priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
587 } 587 }
diff --git a/sound/soc/fsl/fsl_ssi_dbg.c b/sound/soc/fsl/fsl_ssi_dbg.c
index 1255dfe19eef..6f6294149476 100644
--- a/sound/soc/fsl/fsl_ssi_dbg.c
+++ b/sound/soc/fsl/fsl_ssi_dbg.c
@@ -124,17 +124,7 @@ static int fsl_ssi_stats_show(struct seq_file *s, void *unused)
124 return 0; 124 return 0;
125} 125}
126 126
127static int fsl_ssi_stats_open(struct inode *inode, struct file *file) 127DEFINE_SHOW_ATTRIBUTE(fsl_ssi_stats);
128{
129 return single_open(file, fsl_ssi_stats_show, inode->i_private);
130}
131
132static const struct file_operations fsl_ssi_stats_ops = {
133 .open = fsl_ssi_stats_open,
134 .read = seq_read,
135 .llseek = seq_lseek,
136 .release = single_release,
137};
138 128
139int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev) 129int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev)
140{ 130{
@@ -144,7 +134,7 @@ int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev)
144 134
145 ssi_dbg->dbg_stats = debugfs_create_file("stats", 0444, 135 ssi_dbg->dbg_stats = debugfs_create_file("stats", 0444,
146 ssi_dbg->dbg_dir, ssi_dbg, 136 ssi_dbg->dbg_dir, ssi_dbg,
147 &fsl_ssi_stats_ops); 137 &fsl_ssi_stats_fops);
148 if (!ssi_dbg->dbg_stats) { 138 if (!ssi_dbg->dbg_stats) {
149 debugfs_remove(ssi_dbg->dbg_dir); 139 debugfs_remove(ssi_dbg->dbg_dir);
150 return -ENOMEM; 140 return -ENOMEM;
diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig
index c954be0a0f96..92c2cf06f40a 100644
--- a/sound/soc/generic/Kconfig
+++ b/sound/soc/generic/Kconfig
@@ -6,6 +6,7 @@ config SND_SIMPLE_CARD
6 select SND_SIMPLE_CARD_UTILS 6 select SND_SIMPLE_CARD_UTILS
7 help 7 help
8 This option enables generic simple sound card support 8 This option enables generic simple sound card support
9 It also support DPCM of multi CPU single Codec ststem.
9 10
10config SND_SIMPLE_SCU_CARD 11config SND_SIMPLE_SCU_CARD
11 tristate "ASoC Simple SCU sound card support" 12 tristate "ASoC Simple SCU sound card support"
@@ -20,8 +21,9 @@ config SND_AUDIO_GRAPH_CARD
20 depends on OF 21 depends on OF
21 select SND_SIMPLE_CARD_UTILS 22 select SND_SIMPLE_CARD_UTILS
22 help 23 help
23 This option enables generic simple simple sound card support 24 This option enables generic simple sound card support
24 with OF-graph DT bindings. 25 with OF-graph DT bindings.
26 It also support DPCM of multi CPU single Codec ststem.
25 27
26config SND_AUDIO_GRAPH_SCU_CARD 28config SND_AUDIO_GRAPH_SCU_CARD
27 tristate "ASoC Audio Graph SCU sound card support" 29 tristate "ASoC Audio Graph SCU sound card support"
diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
index 25c819e402e1..0d6144560a1e 100644
--- a/sound/soc/generic/audio-graph-card.c
+++ b/sound/soc/generic/audio-graph-card.c
@@ -23,19 +23,29 @@
23struct graph_card_data { 23struct graph_card_data {
24 struct snd_soc_card snd_card; 24 struct snd_soc_card snd_card;
25 struct graph_dai_props { 25 struct graph_dai_props {
26 struct asoc_simple_dai cpu_dai; 26 struct asoc_simple_dai *cpu_dai;
27 struct asoc_simple_dai codec_dai; 27 struct asoc_simple_dai *codec_dai;
28 struct snd_soc_dai_link_component codecs; /* single codec */ 28 struct snd_soc_dai_link_component codecs; /* single codec */
29 struct snd_soc_dai_link_component platform; 29 struct snd_soc_dai_link_component platform;
30 struct asoc_simple_card_data adata;
31 struct snd_soc_codec_conf *codec_conf;
30 unsigned int mclk_fs; 32 unsigned int mclk_fs;
31 } *dai_props; 33 } *dai_props;
32 unsigned int mclk_fs;
33 struct asoc_simple_jack hp_jack; 34 struct asoc_simple_jack hp_jack;
34 struct asoc_simple_jack mic_jack; 35 struct asoc_simple_jack mic_jack;
35 struct snd_soc_dai_link *dai_link; 36 struct snd_soc_dai_link *dai_link;
37 struct asoc_simple_dai *dais;
38 struct snd_soc_codec_conf *codec_conf;
36 struct gpio_desc *pa_gpio; 39 struct gpio_desc *pa_gpio;
37}; 40};
38 41
42#define graph_priv_to_card(priv) (&(priv)->snd_card)
43#define graph_priv_to_props(priv, i) ((priv)->dai_props + (i))
44#define graph_priv_to_dev(priv) (graph_priv_to_card(priv)->dev)
45#define graph_priv_to_link(priv, i) (graph_priv_to_card(priv)->dai_link + (i))
46
47#define PREFIX "audio-graph-card,"
48
39static int asoc_graph_card_outdrv_event(struct snd_soc_dapm_widget *w, 49static int asoc_graph_card_outdrv_event(struct snd_soc_dapm_widget *w,
40 struct snd_kcontrol *kcontrol, 50 struct snd_kcontrol *kcontrol,
41 int event) 51 int event)
@@ -63,11 +73,6 @@ static const struct snd_soc_dapm_widget asoc_graph_card_dapm_widgets[] = {
63 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 73 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
64}; 74};
65 75
66#define graph_priv_to_card(priv) (&(priv)->snd_card)
67#define graph_priv_to_props(priv, i) ((priv)->dai_props + (i))
68#define graph_priv_to_dev(priv) (graph_priv_to_card(priv)->dev)
69#define graph_priv_to_link(priv, i) (graph_priv_to_card(priv)->dai_link + (i))
70
71static int asoc_graph_card_startup(struct snd_pcm_substream *substream) 76static int asoc_graph_card_startup(struct snd_pcm_substream *substream)
72{ 77{
73 struct snd_soc_pcm_runtime *rtd = substream->private_data; 78 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -75,13 +80,13 @@ static int asoc_graph_card_startup(struct snd_pcm_substream *substream)
75 struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num); 80 struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num);
76 int ret; 81 int ret;
77 82
78 ret = asoc_simple_card_clk_enable(&dai_props->cpu_dai); 83 ret = asoc_simple_card_clk_enable(dai_props->cpu_dai);
79 if (ret) 84 if (ret)
80 return ret; 85 return ret;
81 86
82 ret = asoc_simple_card_clk_enable(&dai_props->codec_dai); 87 ret = asoc_simple_card_clk_enable(dai_props->codec_dai);
83 if (ret) 88 if (ret)
84 asoc_simple_card_clk_disable(&dai_props->cpu_dai); 89 asoc_simple_card_clk_disable(dai_props->cpu_dai);
85 90
86 return ret; 91 return ret;
87} 92}
@@ -92,9 +97,9 @@ static void asoc_graph_card_shutdown(struct snd_pcm_substream *substream)
92 struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 97 struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
93 struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num); 98 struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num);
94 99
95 asoc_simple_card_clk_disable(&dai_props->cpu_dai); 100 asoc_simple_card_clk_disable(dai_props->cpu_dai);
96 101
97 asoc_simple_card_clk_disable(&dai_props->codec_dai); 102 asoc_simple_card_clk_disable(dai_props->codec_dai);
98} 103}
99 104
100static int asoc_graph_card_hw_params(struct snd_pcm_substream *substream, 105static int asoc_graph_card_hw_params(struct snd_pcm_substream *substream,
@@ -108,9 +113,7 @@ static int asoc_graph_card_hw_params(struct snd_pcm_substream *substream,
108 unsigned int mclk, mclk_fs = 0; 113 unsigned int mclk, mclk_fs = 0;
109 int ret = 0; 114 int ret = 0;
110 115
111 if (priv->mclk_fs) 116 if (dai_props->mclk_fs)
112 mclk_fs = priv->mclk_fs;
113 else if (dai_props->mclk_fs)
114 mclk_fs = dai_props->mclk_fs; 117 mclk_fs = dai_props->mclk_fs;
115 118
116 if (mclk_fs) { 119 if (mclk_fs) {
@@ -139,86 +142,238 @@ static const struct snd_soc_ops asoc_graph_card_ops = {
139static int asoc_graph_card_dai_init(struct snd_soc_pcm_runtime *rtd) 142static int asoc_graph_card_dai_init(struct snd_soc_pcm_runtime *rtd)
140{ 143{
141 struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 144 struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
142 struct snd_soc_dai *codec = rtd->codec_dai; 145 struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num);
143 struct snd_soc_dai *cpu = rtd->cpu_dai; 146 int ret = 0;
144 struct graph_dai_props *dai_props =
145 graph_priv_to_props(priv, rtd->num);
146 int ret;
147 147
148 ret = asoc_simple_card_init_dai(codec, &dai_props->codec_dai); 148 ret = asoc_simple_card_init_dai(rtd->codec_dai,
149 dai_props->codec_dai);
149 if (ret < 0) 150 if (ret < 0)
150 return ret; 151 return ret;
151 152
152 ret = asoc_simple_card_init_dai(cpu, &dai_props->cpu_dai); 153 ret = asoc_simple_card_init_dai(rtd->cpu_dai,
154 dai_props->cpu_dai);
153 if (ret < 0) 155 if (ret < 0)
154 return ret; 156 return ret;
155 157
156 return 0; 158 return 0;
157} 159}
158 160
159static int asoc_graph_card_dai_link_of(struct device_node *cpu_port, 161static int asoc_graph_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
160 struct graph_card_data *priv, 162 struct snd_pcm_hw_params *params)
161 int idx) 163{
164 struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
165 struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num);
166
167 asoc_simple_card_convert_fixup(&dai_props->adata, params);
168
169 return 0;
170}
171
172static int asoc_graph_card_dai_link_of_dpcm(struct device_node *top,
173 struct device_node *cpu_ep,
174 struct device_node *codec_ep,
175 struct graph_card_data *priv,
176 int *dai_idx, int link_idx,
177 int *conf_idx, int is_cpu)
162{ 178{
163 struct device *dev = graph_priv_to_dev(priv); 179 struct device *dev = graph_priv_to_dev(priv);
164 struct snd_soc_dai_link *dai_link = graph_priv_to_link(priv, idx); 180 struct snd_soc_dai_link *dai_link = graph_priv_to_link(priv, link_idx);
165 struct graph_dai_props *dai_props = graph_priv_to_props(priv, idx); 181 struct graph_dai_props *dai_props = graph_priv_to_props(priv, link_idx);
166 struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai; 182 struct device_node *ep = is_cpu ? cpu_ep : codec_ep;
167 struct asoc_simple_dai *codec_dai = &dai_props->codec_dai; 183 struct device_node *port = of_get_parent(ep);
168 struct device_node *cpu_ep = of_get_next_child(cpu_port, NULL); 184 struct device_node *ports = of_get_parent(port);
169 struct device_node *codec_ep = of_graph_get_remote_endpoint(cpu_ep); 185 struct device_node *node = of_graph_get_port_parent(ep);
170 struct device_node *rcpu_ep = of_graph_get_remote_endpoint(codec_ep); 186 struct asoc_simple_dai *dai;
187 struct snd_soc_dai_link_component *codecs = dai_link->codecs;
171 int ret; 188 int ret;
172 189
173 if (rcpu_ep != cpu_ep) { 190 dev_dbg(dev, "link_of DPCM (for %s)\n", is_cpu ? "CPU" : "Codec");
174 dev_err(dev, "remote-endpoint mismatch (%s/%s/%s)\n", 191
175 cpu_ep->name, codec_ep->name, rcpu_ep->name); 192 of_property_read_u32(top, "mclk-fs", &dai_props->mclk_fs);
176 ret = -EINVAL; 193 of_property_read_u32(ports, "mclk-fs", &dai_props->mclk_fs);
177 goto dai_link_of_err; 194 of_property_read_u32(port, "mclk-fs", &dai_props->mclk_fs);
195 of_property_read_u32(ep, "mclk-fs", &dai_props->mclk_fs);
196
197 asoc_simple_card_parse_convert(dev, top, NULL, &dai_props->adata);
198 asoc_simple_card_parse_convert(dev, node, PREFIX, &dai_props->adata);
199 asoc_simple_card_parse_convert(dev, ports, NULL, &dai_props->adata);
200 asoc_simple_card_parse_convert(dev, port, NULL, &dai_props->adata);
201 asoc_simple_card_parse_convert(dev, ep, NULL, &dai_props->adata);
202
203 of_node_put(ports);
204 of_node_put(port);
205
206 if (is_cpu) {
207
208 /* BE is dummy */
209 codecs->of_node = NULL;
210 codecs->dai_name = "snd-soc-dummy-dai";
211 codecs->name = "snd-soc-dummy";
212
213 /* FE settings */
214 dai_link->dynamic = 1;
215 dai_link->dpcm_merged_format = 1;
216
217 dai =
218 dai_props->cpu_dai = &priv->dais[(*dai_idx)++];
219
220 ret = asoc_simple_card_parse_graph_cpu(ep, dai_link);
221 if (ret)
222 return ret;
223
224 ret = asoc_simple_card_parse_clk_cpu(dev, ep, dai_link, dai);
225 if (ret < 0)
226 return ret;
227
228 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
229 "fe.%s",
230 dai_link->cpu_dai_name);
231 if (ret < 0)
232 return ret;
233
234 /* card->num_links includes Codec */
235 asoc_simple_card_canonicalize_cpu(dai_link,
236 of_graph_get_endpoint_count(dai_link->cpu_of_node) == 1);
237 } else {
238 struct snd_soc_codec_conf *cconf;
239
240 /* FE is dummy */
241 dai_link->cpu_of_node = NULL;
242 dai_link->cpu_dai_name = "snd-soc-dummy-dai";
243 dai_link->cpu_name = "snd-soc-dummy";
244
245 /* BE settings */
246 dai_link->no_pcm = 1;
247 dai_link->be_hw_params_fixup = asoc_graph_card_be_hw_params_fixup;
248
249 dai =
250 dai_props->codec_dai = &priv->dais[(*dai_idx)++];
251
252 cconf =
253 dai_props->codec_conf = &priv->codec_conf[(*conf_idx)++];
254
255 ret = asoc_simple_card_parse_graph_codec(ep, dai_link);
256 if (ret < 0)
257 return ret;
258
259 ret = asoc_simple_card_parse_clk_codec(dev, ep, dai_link, dai);
260 if (ret < 0)
261 return ret;
262
263 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
264 "be.%s",
265 codecs->dai_name);
266 if (ret < 0)
267 return ret;
268
269 /* check "prefix" from top node */
270 snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node,
271 "prefix");
272 snd_soc_of_parse_node_prefix(node, cconf, codecs->of_node,
273 PREFIX "prefix");
274 snd_soc_of_parse_node_prefix(ports, cconf, codecs->of_node,
275 "prefix");
276 snd_soc_of_parse_node_prefix(port, cconf, codecs->of_node,
277 "prefix");
178 } 278 }
179 279
280 ret = asoc_simple_card_of_parse_tdm(ep, dai);
281 if (ret)
282 return ret;
283
284 ret = asoc_simple_card_canonicalize_dailink(dai_link);
285 if (ret < 0)
286 return ret;
287
180 ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep, 288 ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep,
181 NULL, &dai_link->dai_fmt); 289 NULL, &dai_link->dai_fmt);
182 if (ret < 0) 290 if (ret < 0)
183 goto dai_link_of_err; 291 return ret;
292
293 dai_link->dpcm_playback = 1;
294 dai_link->dpcm_capture = 1;
295 dai_link->ops = &asoc_graph_card_ops;
296 dai_link->init = asoc_graph_card_dai_init;
297
298 return 0;
299}
300
301static int asoc_graph_card_dai_link_of(struct device_node *top,
302 struct device_node *cpu_ep,
303 struct device_node *codec_ep,
304 struct graph_card_data *priv,
305 int *dai_idx, int link_idx)
306{
307 struct device *dev = graph_priv_to_dev(priv);
308 struct snd_soc_dai_link *dai_link = graph_priv_to_link(priv, link_idx);
309 struct graph_dai_props *dai_props = graph_priv_to_props(priv, link_idx);
310 struct device_node *cpu_port = of_get_parent(cpu_ep);
311 struct device_node *codec_port = of_get_parent(codec_ep);
312 struct device_node *cpu_ports = of_get_parent(cpu_port);
313 struct device_node *codec_ports = of_get_parent(codec_port);
314 struct asoc_simple_dai *cpu_dai;
315 struct asoc_simple_dai *codec_dai;
316 int ret;
317
318 dev_dbg(dev, "link_of\n");
319
320 cpu_dai =
321 dai_props->cpu_dai = &priv->dais[(*dai_idx)++];
322 codec_dai =
323 dai_props->codec_dai = &priv->dais[(*dai_idx)++];
184 324
185 of_property_read_u32(cpu_ep, "mclk-fs", &dai_props->mclk_fs); 325 /* Factor to mclk, used in hw_params() */
186 of_property_read_u32(codec_ep, "mclk-fs", &dai_props->mclk_fs); 326 of_property_read_u32(top, "mclk-fs", &dai_props->mclk_fs);
327 of_property_read_u32(cpu_ports, "mclk-fs", &dai_props->mclk_fs);
328 of_property_read_u32(codec_ports, "mclk-fs", &dai_props->mclk_fs);
329 of_property_read_u32(cpu_port, "mclk-fs", &dai_props->mclk_fs);
330 of_property_read_u32(codec_port, "mclk-fs", &dai_props->mclk_fs);
331 of_property_read_u32(cpu_ep, "mclk-fs", &dai_props->mclk_fs);
332 of_property_read_u32(codec_ep, "mclk-fs", &dai_props->mclk_fs);
333 of_node_put(cpu_port);
334 of_node_put(cpu_ports);
335 of_node_put(codec_port);
336 of_node_put(codec_ports);
337
338 ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep,
339 NULL, &dai_link->dai_fmt);
340 if (ret < 0)
341 return ret;
187 342
188 ret = asoc_simple_card_parse_graph_cpu(cpu_ep, dai_link); 343 ret = asoc_simple_card_parse_graph_cpu(cpu_ep, dai_link);
189 if (ret < 0) 344 if (ret < 0)
190 goto dai_link_of_err; 345 return ret;
191 346
192 ret = asoc_simple_card_parse_graph_codec(codec_ep, dai_link); 347 ret = asoc_simple_card_parse_graph_codec(codec_ep, dai_link);
193 if (ret < 0) 348 if (ret < 0)
194 goto dai_link_of_err; 349 return ret;
195 350
196 ret = asoc_simple_card_of_parse_tdm(cpu_ep, cpu_dai); 351 ret = asoc_simple_card_of_parse_tdm(cpu_ep, cpu_dai);
197 if (ret < 0) 352 if (ret < 0)
198 goto dai_link_of_err; 353 return ret;
199 354
200 ret = asoc_simple_card_of_parse_tdm(codec_ep, codec_dai); 355 ret = asoc_simple_card_of_parse_tdm(codec_ep, codec_dai);
201 if (ret < 0) 356 if (ret < 0)
202 goto dai_link_of_err; 357 return ret;
203 358
204 ret = asoc_simple_card_parse_clk_cpu(dev, cpu_ep, dai_link, cpu_dai); 359 ret = asoc_simple_card_parse_clk_cpu(dev, cpu_ep, dai_link, cpu_dai);
205 if (ret < 0) 360 if (ret < 0)
206 goto dai_link_of_err; 361 return ret;
207 362
208 ret = asoc_simple_card_parse_clk_codec(dev, codec_ep, dai_link, codec_dai); 363 ret = asoc_simple_card_parse_clk_codec(dev, codec_ep, dai_link, codec_dai);
209 if (ret < 0) 364 if (ret < 0)
210 goto dai_link_of_err; 365 return ret;
211 366
212 ret = asoc_simple_card_canonicalize_dailink(dai_link); 367 ret = asoc_simple_card_canonicalize_dailink(dai_link);
213 if (ret < 0) 368 if (ret < 0)
214 goto dai_link_of_err; 369 return ret;
215 370
216 ret = asoc_simple_card_set_dailink_name(dev, dai_link, 371 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
217 "%s-%s", 372 "%s-%s",
218 dai_link->cpu_dai_name, 373 dai_link->cpu_dai_name,
219 dai_link->codecs->dai_name); 374 dai_link->codecs->dai_name);
220 if (ret < 0) 375 if (ret < 0)
221 goto dai_link_of_err; 376 return ret;
222 377
223 dai_link->ops = &asoc_graph_card_ops; 378 dai_link->ops = &asoc_graph_card_ops;
224 dai_link->init = asoc_graph_card_dai_init; 379 dai_link->init = asoc_graph_card_dai_init;
@@ -226,12 +381,7 @@ static int asoc_graph_card_dai_link_of(struct device_node *cpu_port,
226 asoc_simple_card_canonicalize_cpu(dai_link, 381 asoc_simple_card_canonicalize_cpu(dai_link,
227 of_graph_get_endpoint_count(dai_link->cpu_of_node) == 1); 382 of_graph_get_endpoint_count(dai_link->cpu_of_node) == 1);
228 383
229dai_link_of_err: 384 return 0;
230 of_node_put(cpu_ep);
231 of_node_put(rcpu_ep);
232 of_node_put(codec_ep);
233
234 return ret;
235} 385}
236 386
237static int asoc_graph_card_parse_of(struct graph_card_data *priv) 387static int asoc_graph_card_parse_of(struct graph_card_data *priv)
@@ -239,44 +389,173 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
239 struct of_phandle_iterator it; 389 struct of_phandle_iterator it;
240 struct device *dev = graph_priv_to_dev(priv); 390 struct device *dev = graph_priv_to_dev(priv);
241 struct snd_soc_card *card = graph_priv_to_card(priv); 391 struct snd_soc_card *card = graph_priv_to_card(priv);
242 struct device_node *node = dev->of_node; 392 struct device_node *top = dev->of_node;
243 int rc, idx = 0; 393 struct device_node *node = top;
244 int ret; 394 struct device_node *cpu_port;
395 struct device_node *cpu_ep = NULL;
396 struct device_node *codec_ep = NULL;
397 struct device_node *codec_port = NULL;
398 struct device_node *codec_port_old = NULL;
399 int rc, ret;
400 int link_idx, dai_idx, conf_idx;
401 int cpu;
245 402
246 ret = asoc_simple_card_of_parse_widgets(card, NULL); 403 ret = asoc_simple_card_of_parse_widgets(card, NULL);
247 if (ret < 0) 404 if (ret < 0)
248 return ret; 405 return ret;
249 406
250 ret = asoc_simple_card_of_parse_routing(card, NULL, 1); 407 ret = asoc_simple_card_of_parse_routing(card, NULL);
251 if (ret < 0) 408 if (ret < 0)
252 return ret; 409 return ret;
253 410
254 /* Factor to mclk, used in hw_params() */ 411 link_idx = 0;
255 of_property_read_u32(node, "mclk-fs", &priv->mclk_fs); 412 dai_idx = 0;
256 413 conf_idx = 0;
257 of_for_each_phandle(&it, rc, node, "dais", NULL, 0) { 414 codec_port_old = NULL;
258 ret = asoc_graph_card_dai_link_of(it.node, priv, idx++); 415 for (cpu = 1; cpu >= 0; cpu--) {
259 if (ret < 0) { 416 /*
260 of_node_put(it.node); 417 * Detect all CPU first, and Detect all Codec 2nd.
261 418 *
262 return ret; 419 * In Normal sound case, all DAIs are detected
420 * as "CPU-Codec".
421 *
422 * In DPCM sound case,
423 * all CPUs are detected as "CPU-dummy", and
424 * all Codecs are detected as "dummy-Codec".
425 * To avoid random sub-device numbering,
426 * detect "dummy-Codec" in last;
427 */
428 of_for_each_phandle(&it, rc, node, "dais", NULL, 0) {
429 cpu_port = it.node;
430 cpu_ep = NULL;
431 while (1) {
432 cpu_ep = of_get_next_child(cpu_port, cpu_ep);
433 if (!cpu_ep)
434 break;
435
436 codec_ep = of_graph_get_remote_endpoint(cpu_ep);
437 codec_port = of_get_parent(codec_ep);
438
439 of_node_put(codec_ep);
440 of_node_put(codec_port);
441
442 dev_dbg(dev, "%pOFf <-> %pOFf\n", cpu_ep, codec_ep);
443
444 if (of_get_child_count(codec_port) > 1) {
445 /*
446 * for DPCM sound
447 */
448 if (!cpu) {
449 if (codec_port_old == codec_port)
450 continue;
451 codec_port_old = codec_port;
452 }
453 ret = asoc_graph_card_dai_link_of_dpcm(
454 top, cpu_ep, codec_ep, priv,
455 &dai_idx, link_idx++,
456 &conf_idx, cpu);
457 } else if (cpu) {
458 /*
459 * for Normal sound
460 */
461 ret = asoc_graph_card_dai_link_of(
462 top, cpu_ep, codec_ep, priv,
463 &dai_idx, link_idx++);
464 }
465 if (ret < 0)
466 return ret;
467 }
263 } 468 }
264 } 469 }
265 470
266 return asoc_simple_card_parse_card_name(card, NULL); 471 return asoc_simple_card_parse_card_name(card, NULL);
267} 472}
268 473
269static int asoc_graph_get_dais_count(struct device *dev) 474static void asoc_graph_get_dais_count(struct device *dev,
475 int *link_num,
476 int *dais_num,
477 int *ccnf_num)
270{ 478{
271 struct of_phandle_iterator it; 479 struct of_phandle_iterator it;
272 struct device_node *node = dev->of_node; 480 struct device_node *node = dev->of_node;
273 int count = 0; 481 struct device_node *cpu_port;
482 struct device_node *cpu_ep;
483 struct device_node *codec_ep;
484 struct device_node *codec_port;
485 struct device_node *codec_port_old;
486 struct device_node *codec_port_old2;
274 int rc; 487 int rc;
275 488
276 of_for_each_phandle(&it, rc, node, "dais", NULL, 0) 489 /*
277 count++; 490 * link_num : number of links.
278 491 * CPU-Codec / CPU-dummy / dummy-Codec
279 return count; 492 * dais_num : number of DAIs
493 * ccnf_num : number of codec_conf
494 * same number for "dummy-Codec"
495 *
496 * ex1)
497 * CPU0 --- Codec0 link : 5
498 * CPU1 --- Codec1 dais : 7
499 * CPU2 -/ ccnf : 1
500 * CPU3 --- Codec2
501 *
502 * => 5 links = 2xCPU-Codec + 2xCPU-dummy + 1xdummy-Codec
503 * => 7 DAIs = 4xCPU + 3xCodec
504 * => 1 ccnf = 1xdummy-Codec
505 *
506 * ex2)
507 * CPU0 --- Codec0 link : 5
508 * CPU1 --- Codec1 dais : 6
509 * CPU2 -/ ccnf : 1
510 * CPU3 -/
511 *
512 * => 5 links = 1xCPU-Codec + 3xCPU-dummy + 1xdummy-Codec
513 * => 6 DAIs = 4xCPU + 2xCodec
514 * => 1 ccnf = 1xdummy-Codec
515 *
516 * ex3)
517 * CPU0 --- Codec0 link : 6
518 * CPU1 -/ dais : 6
519 * CPU2 --- Codec1 ccnf : 2
520 * CPU3 -/
521 *
522 * => 6 links = 0xCPU-Codec + 4xCPU-dummy + 2xdummy-Codec
523 * => 6 DAIs = 4xCPU + 2xCodec
524 * => 2 ccnf = 2xdummy-Codec
525 */
526 codec_port_old = NULL;
527 codec_port_old2 = NULL;
528 of_for_each_phandle(&it, rc, node, "dais", NULL, 0) {
529 cpu_port = it.node;
530 cpu_ep = NULL;
531 while (1) {
532 cpu_ep = of_get_next_child(cpu_port, cpu_ep);
533 if (!cpu_ep)
534 break;
535
536 codec_ep = of_graph_get_remote_endpoint(cpu_ep);
537 codec_port = of_get_parent(codec_ep);
538
539 of_node_put(codec_ep);
540 of_node_put(codec_port);
541
542 (*link_num)++;
543 (*dais_num)++;
544
545 if (codec_port_old == codec_port) {
546 if (codec_port_old2 != codec_port_old) {
547 (*link_num)++;
548 (*ccnf_num)++;
549 }
550
551 codec_port_old2 = codec_port_old;
552 continue;
553 }
554
555 (*dais_num)++;
556 codec_port_old = codec_port;
557 }
558 }
280} 559}
281 560
282static int asoc_graph_soc_card_probe(struct snd_soc_card *card) 561static int asoc_graph_soc_card_probe(struct snd_soc_card *card)
@@ -300,22 +579,27 @@ static int asoc_graph_card_probe(struct platform_device *pdev)
300 struct graph_card_data *priv; 579 struct graph_card_data *priv;
301 struct snd_soc_dai_link *dai_link; 580 struct snd_soc_dai_link *dai_link;
302 struct graph_dai_props *dai_props; 581 struct graph_dai_props *dai_props;
582 struct asoc_simple_dai *dais;
303 struct device *dev = &pdev->dev; 583 struct device *dev = &pdev->dev;
304 struct snd_soc_card *card; 584 struct snd_soc_card *card;
305 int num, ret, i; 585 struct snd_soc_codec_conf *cconf;
586 int lnum = 0, dnum = 0, cnum = 0;
587 int ret, i;
306 588
307 /* Allocate the private data and the DAI link array */ 589 /* Allocate the private data and the DAI link array */
308 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 590 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
309 if (!priv) 591 if (!priv)
310 return -ENOMEM; 592 return -ENOMEM;
311 593
312 num = asoc_graph_get_dais_count(dev); 594 asoc_graph_get_dais_count(dev, &lnum, &dnum, &cnum);
313 if (num == 0) 595 if (!lnum || !dnum)
314 return -EINVAL; 596 return -EINVAL;
315 597
316 dai_props = devm_kcalloc(dev, num, sizeof(*dai_props), GFP_KERNEL); 598 dai_props = devm_kcalloc(dev, lnum, sizeof(*dai_props), GFP_KERNEL);
317 dai_link = devm_kcalloc(dev, num, sizeof(*dai_link), GFP_KERNEL); 599 dai_link = devm_kcalloc(dev, lnum, sizeof(*dai_link), GFP_KERNEL);
318 if (!dai_props || !dai_link) 600 dais = devm_kcalloc(dev, dnum, sizeof(*dais), GFP_KERNEL);
601 cconf = devm_kcalloc(dev, cnum, sizeof(*cconf), GFP_KERNEL);
602 if (!dai_props || !dai_link || !dais)
319 return -ENOMEM; 603 return -ENOMEM;
320 604
321 /* 605 /*
@@ -324,7 +608,7 @@ static int asoc_graph_card_probe(struct platform_device *pdev)
324 * see 608 * see
325 * soc-core.c :: snd_soc_init_multicodec() 609 * soc-core.c :: snd_soc_init_multicodec()
326 */ 610 */
327 for (i = 0; i < num; i++) { 611 for (i = 0; i < lnum; i++) {
328 dai_link[i].codecs = &dai_props[i].codecs; 612 dai_link[i].codecs = &dai_props[i].codecs;
329 dai_link[i].num_codecs = 1; 613 dai_link[i].num_codecs = 1;
330 dai_link[i].platform = &dai_props[i].platform; 614 dai_link[i].platform = &dai_props[i].platform;
@@ -339,16 +623,20 @@ static int asoc_graph_card_probe(struct platform_device *pdev)
339 623
340 priv->dai_props = dai_props; 624 priv->dai_props = dai_props;
341 priv->dai_link = dai_link; 625 priv->dai_link = dai_link;
626 priv->dais = dais;
627 priv->codec_conf = cconf;
342 628
343 /* Init snd_soc_card */ 629 /* Init snd_soc_card */
344 card = graph_priv_to_card(priv); 630 card = graph_priv_to_card(priv);
345 card->owner = THIS_MODULE; 631 card->owner = THIS_MODULE;
346 card->dev = dev; 632 card->dev = dev;
347 card->dai_link = dai_link; 633 card->dai_link = dai_link;
348 card->num_links = num; 634 card->num_links = lnum;
349 card->dapm_widgets = asoc_graph_card_dapm_widgets; 635 card->dapm_widgets = asoc_graph_card_dapm_widgets;
350 card->num_dapm_widgets = ARRAY_SIZE(asoc_graph_card_dapm_widgets); 636 card->num_dapm_widgets = ARRAY_SIZE(asoc_graph_card_dapm_widgets);
351 card->probe = asoc_graph_soc_card_probe; 637 card->probe = asoc_graph_soc_card_probe;
638 card->codec_conf = cconf;
639 card->num_configs = cnum;
352 640
353 ret = asoc_graph_card_parse_of(priv); 641 ret = asoc_graph_card_parse_of(priv);
354 if (ret < 0) { 642 if (ret < 0) {
@@ -379,6 +667,7 @@ static int asoc_graph_card_remove(struct platform_device *pdev)
379 667
380static const struct of_device_id asoc_graph_of_match[] = { 668static const struct of_device_id asoc_graph_of_match[] = {
381 { .compatible = "audio-graph-card", }, 669 { .compatible = "audio-graph-card", },
670 { .compatible = "audio-graph-scu-card", },
382 {}, 671 {},
383}; 672};
384MODULE_DEVICE_TABLE(of, asoc_graph_of_match); 673MODULE_DEVICE_TABLE(of, asoc_graph_of_match);
diff --git a/sound/soc/generic/audio-graph-scu-card.c b/sound/soc/generic/audio-graph-scu-card.c
index b83bb31021a9..e1b192ea147b 100644
--- a/sound/soc/generic/audio-graph-scu-card.c
+++ b/sound/soc/generic/audio-graph-scu-card.c
@@ -24,14 +24,18 @@
24 24
25struct graph_card_data { 25struct graph_card_data {
26 struct snd_soc_card snd_card; 26 struct snd_soc_card snd_card;
27 struct snd_soc_codec_conf codec_conf;
28 struct graph_dai_props { 27 struct graph_dai_props {
29 struct asoc_simple_dai dai; 28 struct asoc_simple_dai *cpu_dai;
29 struct asoc_simple_dai *codec_dai;
30 struct snd_soc_dai_link_component codecs; 30 struct snd_soc_dai_link_component codecs;
31 struct snd_soc_dai_link_component platform; 31 struct snd_soc_dai_link_component platform;
32 struct asoc_simple_card_data adata;
33 struct snd_soc_codec_conf *codec_conf;
32 } *dai_props; 34 } *dai_props;
33 struct snd_soc_dai_link *dai_link; 35 struct snd_soc_dai_link *dai_link;
36 struct asoc_simple_dai *dais;
34 struct asoc_simple_card_data adata; 37 struct asoc_simple_card_data adata;
38 struct snd_soc_codec_conf *codec_conf;
35}; 39};
36 40
37#define graph_priv_to_card(priv) (&(priv)->snd_card) 41#define graph_priv_to_card(priv) (&(priv)->snd_card)
@@ -39,13 +43,24 @@ struct graph_card_data {
39#define graph_priv_to_dev(priv) (graph_priv_to_card(priv)->dev) 43#define graph_priv_to_dev(priv) (graph_priv_to_card(priv)->dev)
40#define graph_priv_to_link(priv, i) (graph_priv_to_card(priv)->dai_link + (i)) 44#define graph_priv_to_link(priv, i) (graph_priv_to_card(priv)->dai_link + (i))
41 45
46#define PREFIX "audio-graph-card,"
47
42static int asoc_graph_card_startup(struct snd_pcm_substream *substream) 48static int asoc_graph_card_startup(struct snd_pcm_substream *substream)
43{ 49{
44 struct snd_soc_pcm_runtime *rtd = substream->private_data; 50 struct snd_soc_pcm_runtime *rtd = substream->private_data;
45 struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 51 struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
46 struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num); 52 struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num);
53 int ret = 0;
54
55 ret = asoc_simple_card_clk_enable(dai_props->cpu_dai);
56 if (ret)
57 return ret;
47 58
48 return asoc_simple_card_clk_enable(&dai_props->dai); 59 ret = asoc_simple_card_clk_enable(dai_props->codec_dai);
60 if (ret)
61 asoc_simple_card_clk_disable(dai_props->cpu_dai);
62
63 return ret;
49} 64}
50 65
51static void asoc_graph_card_shutdown(struct snd_pcm_substream *substream) 66static void asoc_graph_card_shutdown(struct snd_pcm_substream *substream)
@@ -54,7 +69,9 @@ static void asoc_graph_card_shutdown(struct snd_pcm_substream *substream)
54 struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 69 struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
55 struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num); 70 struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num);
56 71
57 asoc_simple_card_clk_disable(&dai_props->dai); 72 asoc_simple_card_clk_disable(dai_props->cpu_dai);
73
74 asoc_simple_card_clk_disable(dai_props->codec_dai);
58} 75}
59 76
60static const struct snd_soc_ops asoc_graph_card_ops = { 77static const struct snd_soc_ops asoc_graph_card_ops = {
@@ -65,39 +82,49 @@ static const struct snd_soc_ops asoc_graph_card_ops = {
65static int asoc_graph_card_dai_init(struct snd_soc_pcm_runtime *rtd) 82static int asoc_graph_card_dai_init(struct snd_soc_pcm_runtime *rtd)
66{ 83{
67 struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 84 struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
68 struct snd_soc_dai *dai; 85 struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num);
69 struct snd_soc_dai_link *dai_link; 86 int ret = 0;
70 struct graph_dai_props *dai_props;
71 int num = rtd->num;
72 87
73 dai_link = graph_priv_to_link(priv, num); 88 ret = asoc_simple_card_init_dai(rtd->codec_dai,
74 dai_props = graph_priv_to_props(priv, num); 89 dai_props->codec_dai);
75 dai = dai_link->dynamic ? 90 if (ret < 0)
76 rtd->cpu_dai : 91 return ret;
77 rtd->codec_dai;
78 92
79 return asoc_simple_card_init_dai(dai, &dai_props->dai); 93 ret = asoc_simple_card_init_dai(rtd->cpu_dai,
94 dai_props->cpu_dai);
95 if (ret < 0)
96 return ret;
97
98 return 0;
80} 99}
81 100
82static int asoc_graph_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 101static int asoc_graph_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
83 struct snd_pcm_hw_params *params) 102 struct snd_pcm_hw_params *params)
84{ 103{
85 struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 104 struct graph_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
105 struct graph_dai_props *dai_props = graph_priv_to_props(priv, rtd->num);
106
107 asoc_simple_card_convert_fixup(&dai_props->adata, params);
86 108
109 /* overwrite by top level adata if exist */
87 asoc_simple_card_convert_fixup(&priv->adata, params); 110 asoc_simple_card_convert_fixup(&priv->adata, params);
88 111
89 return 0; 112 return 0;
90} 113}
91 114
92static int asoc_graph_card_dai_link_of(struct device_node *ep, 115static int asoc_graph_card_dai_link_of(struct device_node *cpu_ep,
116 struct device_node *codec_ep,
93 struct graph_card_data *priv, 117 struct graph_card_data *priv,
94 unsigned int daifmt, 118 int *dai_idx, int link_idx,
95 int idx, int is_fe) 119 int *conf_idx, int is_fe)
96{ 120{
97 struct device *dev = graph_priv_to_dev(priv); 121 struct device *dev = graph_priv_to_dev(priv);
98 struct snd_soc_dai_link *dai_link = graph_priv_to_link(priv, idx); 122 struct snd_soc_dai_link *dai_link = graph_priv_to_link(priv, link_idx);
99 struct graph_dai_props *dai_props = graph_priv_to_props(priv, idx); 123 struct graph_dai_props *dai_props = graph_priv_to_props(priv, link_idx);
100 struct snd_soc_card *card = graph_priv_to_card(priv); 124 struct snd_soc_card *card = graph_priv_to_card(priv);
125 struct device_node *ep = is_fe ? cpu_ep : codec_ep;
126 struct device_node *node = of_graph_get_port_parent(ep);
127 struct asoc_simple_dai *dai;
101 int ret; 128 int ret;
102 129
103 if (is_fe) { 130 if (is_fe) {
@@ -113,11 +140,14 @@ static int asoc_graph_card_dai_link_of(struct device_node *ep,
113 dai_link->dynamic = 1; 140 dai_link->dynamic = 1;
114 dai_link->dpcm_merged_format = 1; 141 dai_link->dpcm_merged_format = 1;
115 142
143 dai =
144 dai_props->cpu_dai = &priv->dais[(*dai_idx)++];
145
116 ret = asoc_simple_card_parse_graph_cpu(ep, dai_link); 146 ret = asoc_simple_card_parse_graph_cpu(ep, dai_link);
117 if (ret) 147 if (ret)
118 return ret; 148 return ret;
119 149
120 ret = asoc_simple_card_parse_clk_cpu(dev, ep, dai_link, &dai_props->dai); 150 ret = asoc_simple_card_parse_clk_cpu(dev, ep, dai_link, dai);
121 if (ret < 0) 151 if (ret < 0)
122 return ret; 152 return ret;
123 153
@@ -131,6 +161,8 @@ static int asoc_graph_card_dai_link_of(struct device_node *ep,
131 asoc_simple_card_canonicalize_cpu(dai_link, 161 asoc_simple_card_canonicalize_cpu(dai_link,
132 of_graph_get_endpoint_count(dai_link->cpu_of_node) == 1); 162 of_graph_get_endpoint_count(dai_link->cpu_of_node) == 1);
133 } else { 163 } else {
164 struct snd_soc_codec_conf *cconf;
165
134 /* FE is dummy */ 166 /* FE is dummy */
135 dai_link->cpu_of_node = NULL; 167 dai_link->cpu_of_node = NULL;
136 dai_link->cpu_dai_name = "snd-soc-dummy-dai"; 168 dai_link->cpu_dai_name = "snd-soc-dummy-dai";
@@ -140,11 +172,17 @@ static int asoc_graph_card_dai_link_of(struct device_node *ep,
140 dai_link->no_pcm = 1; 172 dai_link->no_pcm = 1;
141 dai_link->be_hw_params_fixup = asoc_graph_card_be_hw_params_fixup; 173 dai_link->be_hw_params_fixup = asoc_graph_card_be_hw_params_fixup;
142 174
175 dai =
176 dai_props->codec_dai = &priv->dais[(*dai_idx)++];
177
178 cconf =
179 dai_props->codec_conf = &priv->codec_conf[(*conf_idx)++];
180
143 ret = asoc_simple_card_parse_graph_codec(ep, dai_link); 181 ret = asoc_simple_card_parse_graph_codec(ep, dai_link);
144 if (ret < 0) 182 if (ret < 0)
145 return ret; 183 return ret;
146 184
147 ret = asoc_simple_card_parse_clk_codec(dev, ep, dai_link, &dai_props->dai); 185 ret = asoc_simple_card_parse_clk_codec(dev, ep, dai_link, dai);
148 if (ret < 0) 186 if (ret < 0)
149 return ret; 187 return ret;
150 188
@@ -154,13 +192,20 @@ static int asoc_graph_card_dai_link_of(struct device_node *ep,
154 if (ret < 0) 192 if (ret < 0)
155 return ret; 193 return ret;
156 194
157 snd_soc_of_parse_audio_prefix(card, 195 /* check "prefix" from top node */
158 &priv->codec_conf, 196 snd_soc_of_parse_audio_prefix(card, cconf,
159 dai_link->codecs->of_node, 197 dai_link->codecs->of_node,
160 "prefix"); 198 "prefix");
199 /* check "prefix" from each node if top doesn't have */
200 if (!cconf->of_node)
201 snd_soc_of_parse_node_prefix(node, cconf,
202 dai_link->codecs->of_node,
203 PREFIX "prefix");
161 } 204 }
162 205
163 ret = asoc_simple_card_of_parse_tdm(ep, &dai_props->dai); 206 asoc_simple_card_parse_convert(dev, node, PREFIX, &dai_props->adata);
207
208 ret = asoc_simple_card_of_parse_tdm(ep, dai);
164 if (ret) 209 if (ret)
165 return ret; 210 return ret;
166 211
@@ -168,7 +213,11 @@ static int asoc_graph_card_dai_link_of(struct device_node *ep,
168 if (ret < 0) 213 if (ret < 0)
169 return ret; 214 return ret;
170 215
171 dai_link->dai_fmt = daifmt; 216 ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep,
217 NULL, &dai_link->dai_fmt);
218 if (ret < 0)
219 return ret;
220
172 dai_link->dpcm_playback = 1; 221 dai_link->dpcm_playback = 1;
173 dai_link->dpcm_capture = 1; 222 dai_link->dpcm_capture = 1;
174 dai_link->ops = &asoc_graph_card_ops; 223 dai_link->ops = &asoc_graph_card_ops;
@@ -186,11 +235,9 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
186 struct device_node *cpu_port; 235 struct device_node *cpu_port;
187 struct device_node *cpu_ep; 236 struct device_node *cpu_ep;
188 struct device_node *codec_ep; 237 struct device_node *codec_ep;
189 struct device_node *rcpu_ep;
190 struct device_node *codec_port; 238 struct device_node *codec_port;
191 struct device_node *codec_port_old; 239 struct device_node *codec_port_old;
192 unsigned int daifmt = 0; 240 int dai_idx, link_idx, conf_idx, ret;
193 int dai_idx, ret;
194 int rc, codec; 241 int rc, codec;
195 242
196 if (!node) 243 if (!node)
@@ -201,47 +248,20 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
201 * see simple-card 248 * see simple-card
202 */ 249 */
203 250
204 ret = asoc_simple_card_of_parse_routing(card, NULL, 0); 251 ret = asoc_simple_card_of_parse_routing(card, NULL);
205 if (ret < 0) 252 if (ret < 0)
206 return ret; 253 return ret;
207 254
208 asoc_simple_card_parse_convert(dev, NULL, &priv->adata); 255 asoc_simple_card_parse_convert(dev, node, NULL, &priv->adata);
209 256
210 /* 257 /*
211 * it supports multi CPU, single CODEC only here 258 * it supports multi CPU, single CODEC only here
212 * see asoc_graph_get_dais_count 259 * see asoc_graph_get_dais_count
213 */ 260 */
214 261
215 /* find 1st codec */ 262 link_idx = 0;
216 of_for_each_phandle(&it, rc, node, "dais", NULL, 0) {
217 cpu_port = it.node;
218 cpu_ep = of_get_next_child(cpu_port, NULL);
219 codec_ep = of_graph_get_remote_endpoint(cpu_ep);
220 rcpu_ep = of_graph_get_remote_endpoint(codec_ep);
221
222 of_node_put(cpu_ep);
223 of_node_put(codec_ep);
224 of_node_put(rcpu_ep);
225
226 if (!codec_ep)
227 continue;
228
229 if (rcpu_ep != cpu_ep) {
230 dev_err(dev, "remote-endpoint missmatch (%s/%s/%s)\n",
231 cpu_ep->name, codec_ep->name, rcpu_ep->name);
232 ret = -EINVAL;
233 goto parse_of_err;
234 }
235
236 ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep,
237 NULL, &daifmt);
238 if (ret < 0) {
239 of_node_put(cpu_port);
240 goto parse_of_err;
241 }
242 }
243
244 dai_idx = 0; 263 dai_idx = 0;
264 conf_idx = 0;
245 codec_port_old = NULL; 265 codec_port_old = NULL;
246 for (codec = 0; codec < 2; codec++) { 266 for (codec = 0; codec < 2; codec++) {
247 /* 267 /*
@@ -257,31 +277,23 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
257 277
258 of_node_put(cpu_ep); 278 of_node_put(cpu_ep);
259 of_node_put(codec_ep); 279 of_node_put(codec_ep);
280 of_node_put(cpu_port);
260 of_node_put(codec_port); 281 of_node_put(codec_port);
282 it.node = NULL;
261 283
262 if (codec) { 284 if (codec) {
263 if (!codec_port)
264 continue;
265
266 if (codec_port_old == codec_port) 285 if (codec_port_old == codec_port)
267 continue; 286 continue;
268 287
269 codec_port_old = codec_port; 288 codec_port_old = codec_port;
270
271 /* Back-End (= Codec) */
272 ret = asoc_graph_card_dai_link_of(codec_ep, priv, daifmt, dai_idx++, 0);
273 if (ret < 0) {
274 of_node_put(cpu_port);
275 goto parse_of_err;
276 }
277 } else {
278 /* Front-End (= CPU) */
279 ret = asoc_graph_card_dai_link_of(cpu_ep, priv, daifmt, dai_idx++, 1);
280 if (ret < 0) {
281 of_node_put(cpu_port);
282 goto parse_of_err;
283 }
284 } 289 }
290
291 ret = asoc_graph_card_dai_link_of(cpu_ep, codec_ep,
292 priv, &dai_idx,
293 link_idx++, &conf_idx,
294 !codec);
295 if (ret < 0)
296 goto parse_of_err;
285 } 297 }
286 } 298 }
287 299
@@ -289,13 +301,24 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv)
289 if (ret) 301 if (ret)
290 goto parse_of_err; 302 goto parse_of_err;
291 303
304 if ((card->num_links != link_idx) ||
305 (card->num_configs != conf_idx)) {
306 dev_err(dev, "dai_link or codec_config wrong (%d/%d, %d/%d)\n",
307 card->num_links, link_idx, card->num_configs, conf_idx);
308 ret = -EINVAL;
309 goto parse_of_err;
310 }
311
292 ret = 0; 312 ret = 0;
293 313
294parse_of_err: 314parse_of_err:
295 return ret; 315 return ret;
296} 316}
297 317
298static int asoc_graph_get_dais_count(struct device *dev) 318static void asoc_graph_get_dais_count(struct device *dev,
319 int *link_num,
320 int *dais_num,
321 int *ccnf_num)
299{ 322{
300 struct of_phandle_iterator it; 323 struct of_phandle_iterator it;
301 struct device_node *node = dev->of_node; 324 struct device_node *node = dev->of_node;
@@ -304,10 +327,48 @@ static int asoc_graph_get_dais_count(struct device *dev)
304 struct device_node *codec_ep; 327 struct device_node *codec_ep;
305 struct device_node *codec_port; 328 struct device_node *codec_port;
306 struct device_node *codec_port_old; 329 struct device_node *codec_port_old;
307 int count = 0; 330 struct device_node *codec_port_old2;
308 int rc; 331 int rc;
309 332
333 /*
334 * link_num : number of links.
335 * CPU-Codec / CPU-dummy / dummy-Codec
336 * dais_num : number of DAIs
337 * ccnf_num : number of codec_conf
338 * same number for dummy-Codec
339 *
340 * ex1)
341 * CPU0 --- Codec0 link : 5
342 * CPU1 --- Codec1 dais : 7
343 * CPU2 -/ ccnf : 1
344 * CPU3 --- Codec2
345 *
346 * => 5 links = 2xCPU-Codec + 2xCPU-dummy + 1xdummy-Codec
347 * => 7 DAIs = 4xCPU + 3xCodec
348 * => 1 ccnf = 1xdummy-Codec
349 *
350 * ex2)
351 * CPU0 --- Codec0 link : 5
352 * CPU1 --- Codec1 dais : 6
353 * CPU2 -/ ccnf : 1
354 * CPU3 -/
355 *
356 * => 5 links = 1xCPU-Codec + 3xCPU-dummy + 1xdummy-Codec
357 * => 6 DAIs = 4xCPU + 2xCodec
358 * => 1 ccnf = 1xdummy-Codec
359 *
360 * ex3)
361 * CPU0 --- Codec0 link : 6
362 * CPU1 -/ dais : 6
363 * CPU2 --- Codec1 ccnf : 2
364 * CPU3 -/
365 *
366 * => 6 links = 0xCPU-Codec + 4xCPU-dummy + 2xdummy-Codec
367 * => 6 DAIs = 4xCPU + 2xCodec
368 * => 2 ccnf = 2xdummy-Codec
369 */
310 codec_port_old = NULL; 370 codec_port_old = NULL;
371 codec_port_old2 = NULL;
311 of_for_each_phandle(&it, rc, node, "dais", NULL, 0) { 372 of_for_each_phandle(&it, rc, node, "dais", NULL, 0) {
312 cpu_port = it.node; 373 cpu_port = it.node;
313 cpu_ep = of_get_next_child(cpu_port, NULL); 374 cpu_ep = of_get_next_child(cpu_port, NULL);
@@ -318,20 +379,22 @@ static int asoc_graph_get_dais_count(struct device *dev)
318 of_node_put(codec_ep); 379 of_node_put(codec_ep);
319 of_node_put(codec_port); 380 of_node_put(codec_port);
320 381
321 if (cpu_ep) 382 (*link_num)++;
322 count++; 383 (*dais_num)++;
323 384
324 if (!codec_port) 385 if (codec_port_old == codec_port) {
325 continue; 386 if (codec_port_old2 != codec_port_old) {
387 (*link_num)++;
388 (*ccnf_num)++;
389 }
326 390
327 if (codec_port_old == codec_port) 391 codec_port_old2 = codec_port_old;
328 continue; 392 continue;
393 }
329 394
330 count++; 395 (*dais_num)++;
331 codec_port_old = codec_port; 396 codec_port_old = codec_port;
332 } 397 }
333
334 return count;
335} 398}
336 399
337static int asoc_graph_card_probe(struct platform_device *pdev) 400static int asoc_graph_card_probe(struct platform_device *pdev)
@@ -339,22 +402,27 @@ static int asoc_graph_card_probe(struct platform_device *pdev)
339 struct graph_card_data *priv; 402 struct graph_card_data *priv;
340 struct snd_soc_dai_link *dai_link; 403 struct snd_soc_dai_link *dai_link;
341 struct graph_dai_props *dai_props; 404 struct graph_dai_props *dai_props;
405 struct asoc_simple_dai *dais;
342 struct device *dev = &pdev->dev; 406 struct device *dev = &pdev->dev;
343 struct snd_soc_card *card; 407 struct snd_soc_card *card;
344 int num, ret, i; 408 struct snd_soc_codec_conf *cconf;
409 int lnum = 0, dnum = 0, cnum = 0;
410 int ret, i;
345 411
346 /* Allocate the private data and the DAI link array */ 412 /* Allocate the private data and the DAI link array */
347 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 413 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
348 if (!priv) 414 if (!priv)
349 return -ENOMEM; 415 return -ENOMEM;
350 416
351 num = asoc_graph_get_dais_count(dev); 417 asoc_graph_get_dais_count(dev, &lnum, &dnum, &cnum);
352 if (num == 0) 418 if (!lnum || !dnum)
353 return -EINVAL; 419 return -EINVAL;
354 420
355 dai_props = devm_kcalloc(dev, num, sizeof(*dai_props), GFP_KERNEL); 421 dai_props = devm_kcalloc(dev, lnum, sizeof(*dai_props), GFP_KERNEL);
356 dai_link = devm_kcalloc(dev, num, sizeof(*dai_link), GFP_KERNEL); 422 dai_link = devm_kcalloc(dev, lnum, sizeof(*dai_link), GFP_KERNEL);
357 if (!dai_props || !dai_link) 423 dais = devm_kcalloc(dev, dnum, sizeof(*dais), GFP_KERNEL);
424 cconf = devm_kcalloc(dev, cnum, sizeof(*cconf), GFP_KERNEL);
425 if (!dai_props || !dai_link || !dais)
358 return -ENOMEM; 426 return -ENOMEM;
359 427
360 /* 428 /*
@@ -363,7 +431,7 @@ static int asoc_graph_card_probe(struct platform_device *pdev)
363 * see 431 * see
364 * soc-core.c :: snd_soc_init_multicodec() 432 * soc-core.c :: snd_soc_init_multicodec()
365 */ 433 */
366 for (i = 0; i < num; i++) { 434 for (i = 0; i < lnum; i++) {
367 dai_link[i].codecs = &dai_props[i].codecs; 435 dai_link[i].codecs = &dai_props[i].codecs;
368 dai_link[i].num_codecs = 1; 436 dai_link[i].num_codecs = 1;
369 dai_link[i].platform = &dai_props[i].platform; 437 dai_link[i].platform = &dai_props[i].platform;
@@ -371,15 +439,17 @@ static int asoc_graph_card_probe(struct platform_device *pdev)
371 439
372 priv->dai_props = dai_props; 440 priv->dai_props = dai_props;
373 priv->dai_link = dai_link; 441 priv->dai_link = dai_link;
442 priv->dais = dais;
443 priv->codec_conf = cconf;
374 444
375 /* Init snd_soc_card */ 445 /* Init snd_soc_card */
376 card = graph_priv_to_card(priv); 446 card = graph_priv_to_card(priv);
377 card->owner = THIS_MODULE; 447 card->owner = THIS_MODULE;
378 card->dev = dev; 448 card->dev = dev;
379 card->dai_link = priv->dai_link; 449 card->dai_link = priv->dai_link;
380 card->num_links = num; 450 card->num_links = lnum;
381 card->codec_conf = &priv->codec_conf; 451 card->codec_conf = cconf;
382 card->num_configs = 1; 452 card->num_configs = cnum;
383 453
384 ret = asoc_graph_card_parse_of(priv); 454 ret = asoc_graph_card_parse_of(priv);
385 if (ret < 0) { 455 if (ret < 0) {
diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index f34cc6cddfa2..b807a47515eb 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -32,10 +32,11 @@ void asoc_simple_card_convert_fixup(struct asoc_simple_card_data *data,
32} 32}
33EXPORT_SYMBOL_GPL(asoc_simple_card_convert_fixup); 33EXPORT_SYMBOL_GPL(asoc_simple_card_convert_fixup);
34 34
35void asoc_simple_card_parse_convert(struct device *dev, char *prefix, 35void asoc_simple_card_parse_convert(struct device *dev,
36 struct device_node *np,
37 char *prefix,
36 struct asoc_simple_card_data *data) 38 struct asoc_simple_card_data *data)
37{ 39{
38 struct device_node *np = dev->of_node;
39 char prop[128]; 40 char prop[128];
40 41
41 if (!prefix) 42 if (!prefix)
@@ -151,21 +152,19 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
151} 152}
152EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name); 153EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name);
153 154
154static void asoc_simple_card_clk_register(struct asoc_simple_dai *dai,
155 struct clk *clk)
156{
157 dai->clk = clk;
158}
159
160int asoc_simple_card_clk_enable(struct asoc_simple_dai *dai) 155int asoc_simple_card_clk_enable(struct asoc_simple_dai *dai)
161{ 156{
162 return clk_prepare_enable(dai->clk); 157 if (dai)
158 return clk_prepare_enable(dai->clk);
159
160 return 0;
163} 161}
164EXPORT_SYMBOL_GPL(asoc_simple_card_clk_enable); 162EXPORT_SYMBOL_GPL(asoc_simple_card_clk_enable);
165 163
166void asoc_simple_card_clk_disable(struct asoc_simple_dai *dai) 164void asoc_simple_card_clk_disable(struct asoc_simple_dai *dai)
167{ 165{
168 clk_disable_unprepare(dai->clk); 166 if (dai)
167 clk_disable_unprepare(dai->clk);
169} 168}
170EXPORT_SYMBOL_GPL(asoc_simple_card_clk_disable); 169EXPORT_SYMBOL_GPL(asoc_simple_card_clk_disable);
171 170
@@ -200,7 +199,7 @@ int asoc_simple_card_parse_clk(struct device *dev,
200 if (!IS_ERR(clk)) { 199 if (!IS_ERR(clk)) {
201 simple_dai->sysclk = clk_get_rate(clk); 200 simple_dai->sysclk = clk_get_rate(clk);
202 201
203 asoc_simple_card_clk_register(simple_dai, clk); 202 simple_dai->clk = clk;
204 } else if (!of_property_read_u32(node, "system-clock-frequency", &val)) { 203 } else if (!of_property_read_u32(node, "system-clock-frequency", &val)) {
205 simple_dai->sysclk = val; 204 simple_dai->sysclk = val;
206 } else { 205 } else {
@@ -272,13 +271,24 @@ static int asoc_simple_card_get_dai_id(struct device_node *ep)
272{ 271{
273 struct device_node *node; 272 struct device_node *node;
274 struct device_node *endpoint; 273 struct device_node *endpoint;
274 struct of_endpoint info;
275 int i, id; 275 int i, id;
276 int ret; 276 int ret;
277 277
278 /* use driver specified DAI ID if exist */
278 ret = snd_soc_get_dai_id(ep); 279 ret = snd_soc_get_dai_id(ep);
279 if (ret != -ENOTSUPP) 280 if (ret != -ENOTSUPP)
280 return ret; 281 return ret;
281 282
283 /* use endpoint/port reg if exist */
284 ret = of_graph_parse_endpoint(ep, &info);
285 if (ret == 0) {
286 if (info.id)
287 return info.id;
288 if (info.port)
289 return info.port;
290 }
291
282 node = of_graph_get_port_parent(ep); 292 node = of_graph_get_port_parent(ep);
283 293
284 /* 294 /*
@@ -348,6 +358,9 @@ int asoc_simple_card_init_dai(struct snd_soc_dai *dai,
348{ 358{
349 int ret; 359 int ret;
350 360
361 if (!simple_dai)
362 return 0;
363
351 if (simple_dai->sysclk) { 364 if (simple_dai->sysclk) {
352 ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk, 365 ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk,
353 simple_dai->clk_direction); 366 simple_dai->clk_direction);
@@ -415,8 +428,7 @@ int asoc_simple_card_clean_reference(struct snd_soc_card *card)
415EXPORT_SYMBOL_GPL(asoc_simple_card_clean_reference); 428EXPORT_SYMBOL_GPL(asoc_simple_card_clean_reference);
416 429
417int asoc_simple_card_of_parse_routing(struct snd_soc_card *card, 430int asoc_simple_card_of_parse_routing(struct snd_soc_card *card,
418 char *prefix, 431 char *prefix)
419 int optional)
420{ 432{
421 struct device_node *node = card->dev->of_node; 433 struct device_node *node = card->dev->of_node;
422 char prop[128]; 434 char prop[128];
@@ -426,11 +438,8 @@ int asoc_simple_card_of_parse_routing(struct snd_soc_card *card,
426 438
427 snprintf(prop, sizeof(prop), "%s%s", prefix, "routing"); 439 snprintf(prop, sizeof(prop), "%s%s", prefix, "routing");
428 440
429 if (!of_property_read_bool(node, prop)) { 441 if (!of_property_read_bool(node, prop))
430 if (optional) 442 return 0;
431 return 0;
432 return -EINVAL;
433 }
434 443
435 return snd_soc_of_parse_audio_routing(card, prop); 444 return snd_soc_of_parse_audio_routing(card, prop);
436} 445}
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 5a3f59aa4ba5..37e001cf9cd1 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -18,16 +18,19 @@
18struct simple_card_data { 18struct simple_card_data {
19 struct snd_soc_card snd_card; 19 struct snd_soc_card snd_card;
20 struct simple_dai_props { 20 struct simple_dai_props {
21 struct asoc_simple_dai cpu_dai; 21 struct asoc_simple_dai *cpu_dai;
22 struct asoc_simple_dai codec_dai; 22 struct asoc_simple_dai *codec_dai;
23 struct snd_soc_dai_link_component codecs; /* single codec */ 23 struct snd_soc_dai_link_component codecs; /* single codec */
24 struct snd_soc_dai_link_component platform; 24 struct snd_soc_dai_link_component platform;
25 struct asoc_simple_card_data adata;
26 struct snd_soc_codec_conf *codec_conf;
25 unsigned int mclk_fs; 27 unsigned int mclk_fs;
26 } *dai_props; 28 } *dai_props;
27 unsigned int mclk_fs;
28 struct asoc_simple_jack hp_jack; 29 struct asoc_simple_jack hp_jack;
29 struct asoc_simple_jack mic_jack; 30 struct asoc_simple_jack mic_jack;
30 struct snd_soc_dai_link *dai_link; 31 struct snd_soc_dai_link *dai_link;
32 struct asoc_simple_dai *dais;
33 struct snd_soc_codec_conf *codec_conf;
31}; 34};
32 35
33#define simple_priv_to_card(priv) (&(priv)->snd_card) 36#define simple_priv_to_card(priv) (&(priv)->snd_card)
@@ -47,13 +50,13 @@ static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
47 simple_priv_to_props(priv, rtd->num); 50 simple_priv_to_props(priv, rtd->num);
48 int ret; 51 int ret;
49 52
50 ret = asoc_simple_card_clk_enable(&dai_props->cpu_dai); 53 ret = asoc_simple_card_clk_enable(dai_props->cpu_dai);
51 if (ret) 54 if (ret)
52 return ret; 55 return ret;
53 56
54 ret = asoc_simple_card_clk_enable(&dai_props->codec_dai); 57 ret = asoc_simple_card_clk_enable(dai_props->codec_dai);
55 if (ret) 58 if (ret)
56 asoc_simple_card_clk_disable(&dai_props->cpu_dai); 59 asoc_simple_card_clk_disable(dai_props->cpu_dai);
57 60
58 return ret; 61 return ret;
59} 62}
@@ -65,14 +68,17 @@ static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
65 struct simple_dai_props *dai_props = 68 struct simple_dai_props *dai_props =
66 simple_priv_to_props(priv, rtd->num); 69 simple_priv_to_props(priv, rtd->num);
67 70
68 asoc_simple_card_clk_disable(&dai_props->cpu_dai); 71 asoc_simple_card_clk_disable(dai_props->cpu_dai);
69 72
70 asoc_simple_card_clk_disable(&dai_props->codec_dai); 73 asoc_simple_card_clk_disable(dai_props->codec_dai);
71} 74}
72 75
73static int asoc_simple_set_clk_rate(struct asoc_simple_dai *simple_dai, 76static int asoc_simple_set_clk_rate(struct asoc_simple_dai *simple_dai,
74 unsigned long rate) 77 unsigned long rate)
75{ 78{
79 if (!simple_dai)
80 return 0;
81
76 if (!simple_dai->clk) 82 if (!simple_dai->clk)
77 return 0; 83 return 0;
78 84
@@ -94,19 +100,17 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
94 unsigned int mclk, mclk_fs = 0; 100 unsigned int mclk, mclk_fs = 0;
95 int ret = 0; 101 int ret = 0;
96 102
97 if (priv->mclk_fs) 103 if (dai_props->mclk_fs)
98 mclk_fs = priv->mclk_fs;
99 else if (dai_props->mclk_fs)
100 mclk_fs = dai_props->mclk_fs; 104 mclk_fs = dai_props->mclk_fs;
101 105
102 if (mclk_fs) { 106 if (mclk_fs) {
103 mclk = params_rate(params) * mclk_fs; 107 mclk = params_rate(params) * mclk_fs;
104 108
105 ret = asoc_simple_set_clk_rate(&dai_props->codec_dai, mclk); 109 ret = asoc_simple_set_clk_rate(dai_props->codec_dai, mclk);
106 if (ret < 0) 110 if (ret < 0)
107 return ret; 111 return ret;
108 112
109 ret = asoc_simple_set_clk_rate(&dai_props->cpu_dai, mclk); 113 ret = asoc_simple_set_clk_rate(dai_props->cpu_dai, mclk);
110 if (ret < 0) 114 if (ret < 0)
111 return ret; 115 return ret;
112 116
@@ -134,33 +138,169 @@ static const struct snd_soc_ops asoc_simple_card_ops = {
134static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) 138static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
135{ 139{
136 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 140 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
137 struct snd_soc_dai *codec = rtd->codec_dai; 141 struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num);
138 struct snd_soc_dai *cpu = rtd->cpu_dai;
139 struct simple_dai_props *dai_props =
140 simple_priv_to_props(priv, rtd->num);
141 int ret; 142 int ret;
142 143
143 ret = asoc_simple_card_init_dai(codec, &dai_props->codec_dai); 144 ret = asoc_simple_card_init_dai(rtd->codec_dai,
145 dai_props->codec_dai);
144 if (ret < 0) 146 if (ret < 0)
145 return ret; 147 return ret;
146 148
147 ret = asoc_simple_card_init_dai(cpu, &dai_props->cpu_dai); 149 ret = asoc_simple_card_init_dai(rtd->cpu_dai,
150 dai_props->cpu_dai);
148 if (ret < 0) 151 if (ret < 0)
149 return ret; 152 return ret;
150 153
151 return 0; 154 return 0;
152} 155}
153 156
154static int asoc_simple_card_dai_link_of(struct device_node *node, 157static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
158 struct snd_pcm_hw_params *params)
159{
160 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
161 struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num);
162
163 asoc_simple_card_convert_fixup(&dai_props->adata, params);
164
165 return 0;
166}
167
168static int asoc_simple_card_dai_link_of_dpcm(struct device_node *top,
169 struct device_node *node,
170 struct device_node *np,
171 struct device_node *codec,
172 struct simple_card_data *priv,
173 int *dai_idx, int link_idx,
174 int *conf_idx, int is_fe,
175 bool is_top_level_node)
176{
177 struct device *dev = simple_priv_to_dev(priv);
178 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, link_idx);
179 struct simple_dai_props *dai_props = simple_priv_to_props(priv, link_idx);
180 struct asoc_simple_dai *dai;
181 struct snd_soc_dai_link_component *codecs = dai_link->codecs;
182
183 char prop[128];
184 char *prefix = "";
185 int ret;
186
187 /* For single DAI link & old style of DT node */
188 if (is_top_level_node)
189 prefix = PREFIX;
190
191 if (is_fe) {
192 int is_single_links = 0;
193
194 /* BE is dummy */
195 codecs->of_node = NULL;
196 codecs->dai_name = "snd-soc-dummy-dai";
197 codecs->name = "snd-soc-dummy";
198
199 /* FE settings */
200 dai_link->dynamic = 1;
201 dai_link->dpcm_merged_format = 1;
202
203 dai =
204 dai_props->cpu_dai = &priv->dais[(*dai_idx)++];
205
206 ret = asoc_simple_card_parse_cpu(np, dai_link, DAI, CELL,
207 &is_single_links);
208 if (ret)
209 return ret;
210
211 ret = asoc_simple_card_parse_clk_cpu(dev, np, dai_link, dai);
212 if (ret < 0)
213 return ret;
214
215 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
216 "fe.%s",
217 dai_link->cpu_dai_name);
218 if (ret < 0)
219 return ret;
220
221 asoc_simple_card_canonicalize_cpu(dai_link, is_single_links);
222 } else {
223 struct snd_soc_codec_conf *cconf;
224
225 /* FE is dummy */
226 dai_link->cpu_of_node = NULL;
227 dai_link->cpu_dai_name = "snd-soc-dummy-dai";
228 dai_link->cpu_name = "snd-soc-dummy";
229
230 /* BE settings */
231 dai_link->no_pcm = 1;
232 dai_link->be_hw_params_fixup = asoc_simple_card_be_hw_params_fixup;
233
234 dai =
235 dai_props->codec_dai = &priv->dais[(*dai_idx)++];
236
237 cconf =
238 dai_props->codec_conf = &priv->codec_conf[(*conf_idx)++];
239
240 ret = asoc_simple_card_parse_codec(np, dai_link, DAI, CELL);
241 if (ret < 0)
242 return ret;
243
244 ret = asoc_simple_card_parse_clk_codec(dev, np, dai_link, dai);
245 if (ret < 0)
246 return ret;
247
248 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
249 "be.%s",
250 codecs->dai_name);
251 if (ret < 0)
252 return ret;
253
254 /* check "prefix" from top node */
255 snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node,
256 PREFIX "prefix");
257 snd_soc_of_parse_node_prefix(node, cconf, codecs->of_node,
258 "prefix");
259 snd_soc_of_parse_node_prefix(np, cconf, codecs->of_node,
260 "prefix");
261 }
262
263 asoc_simple_card_parse_convert(dev, top, PREFIX, &dai_props->adata);
264 asoc_simple_card_parse_convert(dev, node, prefix, &dai_props->adata);
265 asoc_simple_card_parse_convert(dev, np, NULL, &dai_props->adata);
266
267 ret = asoc_simple_card_of_parse_tdm(np, dai);
268 if (ret)
269 return ret;
270
271 ret = asoc_simple_card_canonicalize_dailink(dai_link);
272 if (ret < 0)
273 return ret;
274
275 snprintf(prop, sizeof(prop), "%smclk-fs", prefix);
276 of_property_read_u32(top, PREFIX "mclk-fs", &dai_props->mclk_fs);
277 of_property_read_u32(node, prop, &dai_props->mclk_fs);
278 of_property_read_u32(np, prop, &dai_props->mclk_fs);
279
280 ret = asoc_simple_card_parse_daifmt(dev, node, codec,
281 prefix, &dai_link->dai_fmt);
282 if (ret < 0)
283 return ret;
284
285 dai_link->dpcm_playback = 1;
286 dai_link->dpcm_capture = 1;
287 dai_link->ops = &asoc_simple_card_ops;
288 dai_link->init = asoc_simple_card_dai_init;
289
290 return 0;
291}
292
293static int asoc_simple_card_dai_link_of(struct device_node *top,
294 struct device_node *node,
155 struct simple_card_data *priv, 295 struct simple_card_data *priv,
156 int idx, 296 int *dai_idx, int link_idx,
157 bool is_top_level_node) 297 bool is_top_level_node)
158{ 298{
159 struct device *dev = simple_priv_to_dev(priv); 299 struct device *dev = simple_priv_to_dev(priv);
160 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx); 300 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, link_idx);
161 struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx); 301 struct simple_dai_props *dai_props = simple_priv_to_props(priv, link_idx);
162 struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai; 302 struct asoc_simple_dai *cpu_dai;
163 struct asoc_simple_dai *codec_dai = &dai_props->codec_dai; 303 struct asoc_simple_dai *codec_dai;
164 struct device_node *cpu = NULL; 304 struct device_node *cpu = NULL;
165 struct device_node *plat = NULL; 305 struct device_node *plat = NULL;
166 struct device_node *codec = NULL; 306 struct device_node *codec = NULL;
@@ -193,12 +333,21 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
193 goto dai_link_of_err; 333 goto dai_link_of_err;
194 } 334 }
195 335
336 cpu_dai =
337 dai_props->cpu_dai = &priv->dais[(*dai_idx)++];
338 codec_dai =
339 dai_props->codec_dai = &priv->dais[(*dai_idx)++];
340
196 ret = asoc_simple_card_parse_daifmt(dev, node, codec, 341 ret = asoc_simple_card_parse_daifmt(dev, node, codec,
197 prefix, &dai_link->dai_fmt); 342 prefix, &dai_link->dai_fmt);
198 if (ret < 0) 343 if (ret < 0)
199 goto dai_link_of_err; 344 goto dai_link_of_err;
200 345
201 of_property_read_u32(node, "mclk-fs", &dai_props->mclk_fs); 346 snprintf(prop, sizeof(prop), "%smclk-fs", prefix);
347 of_property_read_u32(top, PREFIX "mclk-fs", &dai_props->mclk_fs);
348 of_property_read_u32(node, prop, &dai_props->mclk_fs);
349 of_property_read_u32(cpu, prop, &dai_props->mclk_fs);
350 of_property_read_u32(codec, prop, &dai_props->mclk_fs);
202 351
203 ret = asoc_simple_card_parse_cpu(cpu, dai_link, 352 ret = asoc_simple_card_parse_cpu(cpu, dai_link,
204 DAI, CELL, &single_cpu); 353 DAI, CELL, &single_cpu);
@@ -286,61 +435,148 @@ static int asoc_simple_card_parse_aux_devs(struct device_node *node,
286static int asoc_simple_card_parse_of(struct simple_card_data *priv) 435static int asoc_simple_card_parse_of(struct simple_card_data *priv)
287{ 436{
288 struct device *dev = simple_priv_to_dev(priv); 437 struct device *dev = simple_priv_to_dev(priv);
438 struct device_node *top = dev->of_node;
289 struct snd_soc_card *card = simple_priv_to_card(priv); 439 struct snd_soc_card *card = simple_priv_to_card(priv);
290 struct device_node *dai_link; 440 struct device_node *node;
291 struct device_node *node = dev->of_node; 441 struct device_node *np;
292 int ret; 442 struct device_node *codec;
293 443 bool is_fe;
294 if (!node) 444 int ret, loop;
445 int dai_idx, link_idx, conf_idx;
446
447 if (!top)
295 return -EINVAL; 448 return -EINVAL;
296 449
297 dai_link = of_get_child_by_name(node, PREFIX "dai-link");
298
299 ret = asoc_simple_card_of_parse_widgets(card, PREFIX); 450 ret = asoc_simple_card_of_parse_widgets(card, PREFIX);
300 if (ret < 0) 451 if (ret < 0)
301 goto card_parse_end; 452 return ret;
302 453
303 ret = asoc_simple_card_of_parse_routing(card, PREFIX, 1); 454 ret = asoc_simple_card_of_parse_routing(card, PREFIX);
304 if (ret < 0) 455 if (ret < 0)
305 goto card_parse_end; 456 return ret;
306
307 /* Factor to mclk, used in hw_params() */
308 of_property_read_u32(node, PREFIX "mclk-fs", &priv->mclk_fs);
309 457
310 /* Single/Muti DAI link(s) & New style of DT node */ 458 /* Single/Muti DAI link(s) & New style of DT node */
311 if (dai_link) { 459 loop = 1;
312 struct device_node *np = NULL; 460 link_idx = 0;
313 int i = 0; 461 dai_idx = 0;
314 462 conf_idx = 0;
315 for_each_child_of_node(node, np) { 463 node = of_get_child_by_name(top, PREFIX "dai-link");
316 dev_dbg(dev, "\tlink %d:\n", i); 464 if (!node) {
317 ret = asoc_simple_card_dai_link_of(np, priv, 465 node = dev->of_node;
318 i, false); 466 loop = 0;
319 if (ret < 0) { 467 }
320 of_node_put(np); 468
321 goto card_parse_end; 469 do {
470 /* DPCM */
471 if (of_get_child_count(node) > 2) {
472 for_each_child_of_node(node, np) {
473 codec = of_get_child_by_name(node,
474 loop ? "codec" :
475 PREFIX "codec");
476 if (!codec)
477 return -ENODEV;
478
479 is_fe = (np != codec);
480
481 ret = asoc_simple_card_dai_link_of_dpcm(
482 top, node, np, codec, priv,
483 &dai_idx, link_idx++, &conf_idx,
484 is_fe, !loop);
322 } 485 }
323 i++; 486 } else {
487 ret = asoc_simple_card_dai_link_of(
488 top, node, priv,
489 &dai_idx, link_idx++, !loop);
324 } 490 }
325 } else {
326 /* For single DAI link & old style of DT node */
327 ret = asoc_simple_card_dai_link_of(node, priv, 0, true);
328 if (ret < 0) 491 if (ret < 0)
329 goto card_parse_end; 492 return ret;
330 } 493
494 node = of_get_next_child(top, node);
495 } while (loop && node);
331 496
332 ret = asoc_simple_card_parse_card_name(card, PREFIX); 497 ret = asoc_simple_card_parse_card_name(card, PREFIX);
333 if (ret < 0) 498 if (ret < 0)
334 goto card_parse_end; 499 return ret;
335
336 ret = asoc_simple_card_parse_aux_devs(node, priv);
337 500
338card_parse_end: 501 ret = asoc_simple_card_parse_aux_devs(top, priv);
339 of_node_put(dai_link);
340 502
341 return ret; 503 return ret;
342} 504}
343 505
506static void asoc_simple_card_get_dais_count(struct device *dev,
507 int *link_num,
508 int *dais_num,
509 int *ccnf_num)
510{
511 struct device_node *top = dev->of_node;
512 struct device_node *node;
513 int loop;
514 int num;
515
516 /*
517 * link_num : number of links.
518 * CPU-Codec / CPU-dummy / dummy-Codec
519 * dais_num : number of DAIs
520 * ccnf_num : number of codec_conf
521 * same number for "dummy-Codec"
522 *
523 * ex1)
524 * CPU0 --- Codec0 link : 5
525 * CPU1 --- Codec1 dais : 7
526 * CPU2 -/ ccnf : 1
527 * CPU3 --- Codec2
528 *
529 * => 5 links = 2xCPU-Codec + 2xCPU-dummy + 1xdummy-Codec
530 * => 7 DAIs = 4xCPU + 3xCodec
531 * => 1 ccnf = 1xdummy-Codec
532 *
533 * ex2)
534 * CPU0 --- Codec0 link : 5
535 * CPU1 --- Codec1 dais : 6
536 * CPU2 -/ ccnf : 1
537 * CPU3 -/
538 *
539 * => 5 links = 1xCPU-Codec + 3xCPU-dummy + 1xdummy-Codec
540 * => 6 DAIs = 4xCPU + 2xCodec
541 * => 1 ccnf = 1xdummy-Codec
542 *
543 * ex3)
544 * CPU0 --- Codec0 link : 6
545 * CPU1 -/ dais : 6
546 * CPU2 --- Codec1 ccnf : 2
547 * CPU3 -/
548 *
549 * => 6 links = 0xCPU-Codec + 4xCPU-dummy + 2xdummy-Codec
550 * => 6 DAIs = 4xCPU + 2xCodec
551 * => 2 ccnf = 2xdummy-Codec
552 */
553 if (!top) {
554 (*link_num) = 1;
555 (*dais_num) = 2;
556 (*ccnf_num) = 0;
557 return;
558 }
559
560 loop = 1;
561 node = of_get_child_by_name(top, PREFIX "dai-link");
562 if (!node) {
563 node = top;
564 loop = 0;
565 }
566
567 do {
568 num = of_get_child_count(node);
569 (*dais_num) += num;
570 if (num > 2) {
571 (*link_num) += num;
572 (*ccnf_num)++;
573 } else {
574 (*link_num)++;
575 }
576 node = of_get_next_child(top, node);
577 } while (loop && node);
578}
579
344static int asoc_simple_soc_card_probe(struct snd_soc_card *card) 580static int asoc_simple_soc_card_probe(struct snd_soc_card *card)
345{ 581{
346 struct simple_card_data *priv = snd_soc_card_get_drvdata(card); 582 struct simple_card_data *priv = snd_soc_card_get_drvdata(card);
@@ -362,25 +598,28 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
362 struct simple_card_data *priv; 598 struct simple_card_data *priv;
363 struct snd_soc_dai_link *dai_link; 599 struct snd_soc_dai_link *dai_link;
364 struct simple_dai_props *dai_props; 600 struct simple_dai_props *dai_props;
601 struct asoc_simple_dai *dais;
365 struct device *dev = &pdev->dev; 602 struct device *dev = &pdev->dev;
366 struct device_node *np = dev->of_node; 603 struct device_node *np = dev->of_node;
367 struct snd_soc_card *card; 604 struct snd_soc_card *card;
368 int num, ret, i; 605 struct snd_soc_codec_conf *cconf;
369 606 int lnum = 0, dnum = 0, cnum = 0;
370 /* Get the number of DAI links */ 607 int ret, i;
371 if (np && of_get_child_by_name(np, PREFIX "dai-link"))
372 num = of_get_child_count(np);
373 else
374 num = 1;
375 608
376 /* Allocate the private data and the DAI link array */ 609 /* Allocate the private data and the DAI link array */
377 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 610 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
378 if (!priv) 611 if (!priv)
379 return -ENOMEM; 612 return -ENOMEM;
380 613
381 dai_props = devm_kcalloc(dev, num, sizeof(*dai_props), GFP_KERNEL); 614 asoc_simple_card_get_dais_count(dev, &lnum, &dnum, &cnum);
382 dai_link = devm_kcalloc(dev, num, sizeof(*dai_link), GFP_KERNEL); 615 if (!lnum || !dnum)
383 if (!dai_props || !dai_link) 616 return -EINVAL;
617
618 dai_props = devm_kcalloc(dev, lnum, sizeof(*dai_props), GFP_KERNEL);
619 dai_link = devm_kcalloc(dev, lnum, sizeof(*dai_link), GFP_KERNEL);
620 dais = devm_kcalloc(dev, dnum, sizeof(*dais), GFP_KERNEL);
621 cconf = devm_kcalloc(dev, cnum, sizeof(*cconf), GFP_KERNEL);
622 if (!dai_props || !dai_link || !dais)
384 return -ENOMEM; 623 return -ENOMEM;
385 624
386 /* 625 /*
@@ -389,7 +628,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
389 * see 628 * see
390 * soc-core.c :: snd_soc_init_multicodec() 629 * soc-core.c :: snd_soc_init_multicodec()
391 */ 630 */
392 for (i = 0; i < num; i++) { 631 for (i = 0; i < lnum; i++) {
393 dai_link[i].codecs = &dai_props[i].codecs; 632 dai_link[i].codecs = &dai_props[i].codecs;
394 dai_link[i].num_codecs = 1; 633 dai_link[i].num_codecs = 1;
395 dai_link[i].platform = &dai_props[i].platform; 634 dai_link[i].platform = &dai_props[i].platform;
@@ -397,13 +636,17 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
397 636
398 priv->dai_props = dai_props; 637 priv->dai_props = dai_props;
399 priv->dai_link = dai_link; 638 priv->dai_link = dai_link;
639 priv->dais = dais;
640 priv->codec_conf = cconf;
400 641
401 /* Init snd_soc_card */ 642 /* Init snd_soc_card */
402 card = simple_priv_to_card(priv); 643 card = simple_priv_to_card(priv);
403 card->owner = THIS_MODULE; 644 card->owner = THIS_MODULE;
404 card->dev = dev; 645 card->dev = dev;
405 card->dai_link = priv->dai_link; 646 card->dai_link = priv->dai_link;
406 card->num_links = num; 647 card->num_links = lnum;
648 card->codec_conf = cconf;
649 card->num_configs = cnum;
407 card->probe = asoc_simple_soc_card_probe; 650 card->probe = asoc_simple_soc_card_probe;
408 651
409 if (np && of_device_is_available(np)) { 652 if (np && of_device_is_available(np)) {
@@ -419,6 +662,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
419 struct asoc_simple_card_info *cinfo; 662 struct asoc_simple_card_info *cinfo;
420 struct snd_soc_dai_link_component *codecs; 663 struct snd_soc_dai_link_component *codecs;
421 struct snd_soc_dai_link_component *platform; 664 struct snd_soc_dai_link_component *platform;
665 int dai_idx = 0;
422 666
423 cinfo = dev->platform_data; 667 cinfo = dev->platform_data;
424 if (!cinfo) { 668 if (!cinfo) {
@@ -435,6 +679,9 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
435 return -EINVAL; 679 return -EINVAL;
436 } 680 }
437 681
682 dai_props->cpu_dai = &priv->dais[dai_idx++];
683 dai_props->codec_dai = &priv->dais[dai_idx++];
684
438 codecs = dai_link->codecs; 685 codecs = dai_link->codecs;
439 codecs->name = cinfo->codec; 686 codecs->name = cinfo->codec;
440 codecs->dai_name = cinfo->codec_dai.name; 687 codecs->dai_name = cinfo->codec_dai.name;
@@ -448,10 +695,10 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
448 dai_link->cpu_dai_name = cinfo->cpu_dai.name; 695 dai_link->cpu_dai_name = cinfo->cpu_dai.name;
449 dai_link->dai_fmt = cinfo->daifmt; 696 dai_link->dai_fmt = cinfo->daifmt;
450 dai_link->init = asoc_simple_card_dai_init; 697 dai_link->init = asoc_simple_card_dai_init;
451 memcpy(&priv->dai_props->cpu_dai, &cinfo->cpu_dai, 698 memcpy(priv->dai_props->cpu_dai, &cinfo->cpu_dai,
452 sizeof(priv->dai_props->cpu_dai)); 699 sizeof(*priv->dai_props->cpu_dai));
453 memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai, 700 memcpy(priv->dai_props->codec_dai, &cinfo->codec_dai,
454 sizeof(priv->dai_props->codec_dai)); 701 sizeof(*priv->dai_props->codec_dai));
455 } 702 }
456 703
457 snd_soc_card_set_drvdata(card, priv); 704 snd_soc_card_set_drvdata(card, priv);
@@ -476,6 +723,7 @@ static int asoc_simple_card_remove(struct platform_device *pdev)
476 723
477static const struct of_device_id asoc_simple_of_match[] = { 724static const struct of_device_id asoc_simple_of_match[] = {
478 { .compatible = "simple-audio-card", }, 725 { .compatible = "simple-audio-card", },
726 { .compatible = "simple-scu-audio-card", },
479 {}, 727 {},
480}; 728};
481MODULE_DEVICE_TABLE(of, asoc_simple_of_match); 729MODULE_DEVICE_TABLE(of, asoc_simple_of_match);
diff --git a/sound/soc/generic/simple-scu-card.c b/sound/soc/generic/simple-scu-card.c
index 85b46f0eae0f..9d7299d536a8 100644
--- a/sound/soc/generic/simple-scu-card.c
+++ b/sound/soc/generic/simple-scu-card.c
@@ -21,14 +21,18 @@
21 21
22struct simple_card_data { 22struct simple_card_data {
23 struct snd_soc_card snd_card; 23 struct snd_soc_card snd_card;
24 struct snd_soc_codec_conf codec_conf;
25 struct simple_dai_props { 24 struct simple_dai_props {
26 struct asoc_simple_dai dai; 25 struct asoc_simple_dai *cpu_dai;
26 struct asoc_simple_dai *codec_dai;
27 struct snd_soc_dai_link_component codecs; 27 struct snd_soc_dai_link_component codecs;
28 struct snd_soc_dai_link_component platform; 28 struct snd_soc_dai_link_component platform;
29 struct asoc_simple_card_data adata;
30 struct snd_soc_codec_conf *codec_conf;
29 } *dai_props; 31 } *dai_props;
30 struct snd_soc_dai_link *dai_link; 32 struct snd_soc_dai_link *dai_link;
33 struct asoc_simple_dai *dais;
31 struct asoc_simple_card_data adata; 34 struct asoc_simple_card_data adata;
35 struct snd_soc_codec_conf *codec_conf;
32}; 36};
33 37
34#define simple_priv_to_card(priv) (&(priv)->snd_card) 38#define simple_priv_to_card(priv) (&(priv)->snd_card)
@@ -46,8 +50,17 @@ static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
46 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 50 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
47 struct simple_dai_props *dai_props = 51 struct simple_dai_props *dai_props =
48 simple_priv_to_props(priv, rtd->num); 52 simple_priv_to_props(priv, rtd->num);
53 int ret;
54
55 ret = asoc_simple_card_clk_enable(dai_props->cpu_dai);
56 if (ret)
57 return ret;
58
59 ret = asoc_simple_card_clk_enable(dai_props->codec_dai);
60 if (ret)
61 asoc_simple_card_clk_disable(dai_props->cpu_dai);
49 62
50 return asoc_simple_card_clk_enable(&dai_props->dai); 63 return ret;
51} 64}
52 65
53static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream) 66static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
@@ -57,7 +70,9 @@ static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
57 struct simple_dai_props *dai_props = 70 struct simple_dai_props *dai_props =
58 simple_priv_to_props(priv, rtd->num); 71 simple_priv_to_props(priv, rtd->num);
59 72
60 asoc_simple_card_clk_disable(&dai_props->dai); 73 asoc_simple_card_clk_disable(dai_props->cpu_dai);
74
75 asoc_simple_card_clk_disable(dai_props->codec_dai);
61} 76}
62 77
63static const struct snd_soc_ops asoc_simple_card_ops = { 78static const struct snd_soc_ops asoc_simple_card_ops = {
@@ -67,42 +82,57 @@ static const struct snd_soc_ops asoc_simple_card_ops = {
67 82
68static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) 83static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
69{ 84{
70 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 85 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
71 struct snd_soc_dai *dai; 86 struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num);
72 struct snd_soc_dai_link *dai_link; 87 int ret;
73 struct simple_dai_props *dai_props; 88
74 int num = rtd->num; 89 ret = asoc_simple_card_init_dai(rtd->codec_dai,
90 dai_props->codec_dai);
91 if (ret < 0)
92 return ret;
75 93
76 dai_link = simple_priv_to_link(priv, num); 94 ret = asoc_simple_card_init_dai(rtd->cpu_dai,
77 dai_props = simple_priv_to_props(priv, num); 95 dai_props->cpu_dai);
78 dai = dai_link->dynamic ? 96 if (ret < 0)
79 rtd->cpu_dai : 97 return ret;
80 rtd->codec_dai;
81 98
82 return asoc_simple_card_init_dai(dai, &dai_props->dai); 99 return 0;
83} 100}
84 101
85static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 102static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
86 struct snd_pcm_hw_params *params) 103 struct snd_pcm_hw_params *params)
87{ 104{
88 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); 105 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
106 struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num);
107
108 asoc_simple_card_convert_fixup(&dai_props->adata, params);
89 109
110 /* overwrite by top level adata if exist */
90 asoc_simple_card_convert_fixup(&priv->adata, params); 111 asoc_simple_card_convert_fixup(&priv->adata, params);
91 112
92 return 0; 113 return 0;
93} 114}
94 115
95static int asoc_simple_card_dai_link_of(struct device_node *np, 116static int asoc_simple_card_dai_link_of(struct device_node *link,
117 struct device_node *np,
118 struct device_node *codec,
96 struct simple_card_data *priv, 119 struct simple_card_data *priv,
97 unsigned int daifmt, 120 int *dai_idx, int link_idx,
98 int idx, bool is_fe) 121 int *conf_idx, int is_fe,
122 bool is_top_level_node)
99{ 123{
100 struct device *dev = simple_priv_to_dev(priv); 124 struct device *dev = simple_priv_to_dev(priv);
101 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx); 125 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, link_idx);
102 struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx); 126 struct simple_dai_props *dai_props = simple_priv_to_props(priv, link_idx);
103 struct snd_soc_card *card = simple_priv_to_card(priv); 127 struct snd_soc_card *card = simple_priv_to_card(priv);
128 struct asoc_simple_dai *dai;
129 char *prefix = "";
104 int ret; 130 int ret;
105 131
132 /* For single DAI link & old style of DT node */
133 if (is_top_level_node)
134 prefix = PREFIX;
135
106 if (is_fe) { 136 if (is_fe) {
107 int is_single_links = 0; 137 int is_single_links = 0;
108 struct snd_soc_dai_link_component *codecs; 138 struct snd_soc_dai_link_component *codecs;
@@ -117,12 +147,15 @@ static int asoc_simple_card_dai_link_of(struct device_node *np,
117 dai_link->dynamic = 1; 147 dai_link->dynamic = 1;
118 dai_link->dpcm_merged_format = 1; 148 dai_link->dpcm_merged_format = 1;
119 149
150 dai =
151 dai_props->cpu_dai = &priv->dais[(*dai_idx)++];
152
120 ret = asoc_simple_card_parse_cpu(np, dai_link, DAI, CELL, 153 ret = asoc_simple_card_parse_cpu(np, dai_link, DAI, CELL,
121 &is_single_links); 154 &is_single_links);
122 if (ret) 155 if (ret)
123 return ret; 156 return ret;
124 157
125 ret = asoc_simple_card_parse_clk_cpu(dev, np, dai_link, &dai_props->dai); 158 ret = asoc_simple_card_parse_clk_cpu(dev, np, dai_link, dai);
126 if (ret < 0) 159 if (ret < 0)
127 return ret; 160 return ret;
128 161
@@ -134,6 +167,8 @@ static int asoc_simple_card_dai_link_of(struct device_node *np,
134 167
135 asoc_simple_card_canonicalize_cpu(dai_link, is_single_links); 168 asoc_simple_card_canonicalize_cpu(dai_link, is_single_links);
136 } else { 169 } else {
170 struct snd_soc_codec_conf *cconf;
171
137 /* FE is dummy */ 172 /* FE is dummy */
138 dai_link->cpu_of_node = NULL; 173 dai_link->cpu_of_node = NULL;
139 dai_link->cpu_dai_name = "snd-soc-dummy-dai"; 174 dai_link->cpu_dai_name = "snd-soc-dummy-dai";
@@ -143,11 +178,17 @@ static int asoc_simple_card_dai_link_of(struct device_node *np,
143 dai_link->no_pcm = 1; 178 dai_link->no_pcm = 1;
144 dai_link->be_hw_params_fixup = asoc_simple_card_be_hw_params_fixup; 179 dai_link->be_hw_params_fixup = asoc_simple_card_be_hw_params_fixup;
145 180
181 dai =
182 dai_props->codec_dai = &priv->dais[(*dai_idx)++];
183
184 cconf =
185 dai_props->codec_conf = &priv->codec_conf[(*conf_idx)++];
186
146 ret = asoc_simple_card_parse_codec(np, dai_link, DAI, CELL); 187 ret = asoc_simple_card_parse_codec(np, dai_link, DAI, CELL);
147 if (ret < 0) 188 if (ret < 0)
148 return ret; 189 return ret;
149 190
150 ret = asoc_simple_card_parse_clk_codec(dev, np, dai_link, &dai_props->dai); 191 ret = asoc_simple_card_parse_clk_codec(dev, np, dai_link, dai);
151 if (ret < 0) 192 if (ret < 0)
152 return ret; 193 return ret;
153 194
@@ -157,13 +198,20 @@ static int asoc_simple_card_dai_link_of(struct device_node *np,
157 if (ret < 0) 198 if (ret < 0)
158 return ret; 199 return ret;
159 200
160 snd_soc_of_parse_audio_prefix(card, 201 /* check "prefix" from top node */
161 &priv->codec_conf, 202 snd_soc_of_parse_audio_prefix(card, cconf,
162 dai_link->codecs->of_node, 203 dai_link->codecs->of_node,
163 PREFIX "prefix"); 204 PREFIX "prefix");
205 /* check "prefix" from each node if top doesn't have */
206 if (!cconf->of_node)
207 snd_soc_of_parse_node_prefix(np, cconf,
208 dai_link->codecs->of_node,
209 "prefix");
164 } 210 }
165 211
166 ret = asoc_simple_card_of_parse_tdm(np, &dai_props->dai); 212 asoc_simple_card_parse_convert(dev, link, prefix, &dai_props->adata);
213
214 ret = asoc_simple_card_of_parse_tdm(np, dai);
167 if (ret) 215 if (ret)
168 return ret; 216 return ret;
169 217
@@ -171,7 +219,11 @@ static int asoc_simple_card_dai_link_of(struct device_node *np,
171 if (ret < 0) 219 if (ret < 0)
172 return ret; 220 return ret;
173 221
174 dai_link->dai_fmt = daifmt; 222 ret = asoc_simple_card_parse_daifmt(dev, link, codec,
223 prefix, &dai_link->dai_fmt);
224 if (ret < 0)
225 return ret;
226
175 dai_link->dpcm_playback = 1; 227 dai_link->dpcm_playback = 1;
176 dai_link->dpcm_capture = 1; 228 dai_link->dpcm_capture = 1;
177 dai_link->ops = &asoc_simple_card_ops; 229 dai_link->ops = &asoc_simple_card_ops;
@@ -184,52 +236,136 @@ static int asoc_simple_card_parse_of(struct simple_card_data *priv)
184 236
185{ 237{
186 struct device *dev = simple_priv_to_dev(priv); 238 struct device *dev = simple_priv_to_dev(priv);
239 struct device_node *top = dev->of_node;
240 struct device_node *node;
187 struct device_node *np; 241 struct device_node *np;
242 struct device_node *codec;
188 struct snd_soc_card *card = simple_priv_to_card(priv); 243 struct snd_soc_card *card = simple_priv_to_card(priv);
189 struct device_node *node = dev->of_node;
190 unsigned int daifmt = 0;
191 bool is_fe; 244 bool is_fe;
192 int ret, i; 245 int ret, loop;
246 int dai_idx, link_idx, conf_idx;
193 247
194 if (!node) 248 if (!top)
195 return -EINVAL; 249 return -EINVAL;
196 250
197 ret = asoc_simple_card_of_parse_widgets(card, PREFIX); 251 ret = asoc_simple_card_of_parse_widgets(card, PREFIX);
198 if (ret < 0) 252 if (ret < 0)
199 return ret; 253 return ret;
200 254
201 ret = asoc_simple_card_of_parse_routing(card, PREFIX, 0); 255 ret = asoc_simple_card_of_parse_routing(card, PREFIX);
202 if (ret < 0) 256 if (ret < 0)
203 return ret; 257 return ret;
204 258
205 asoc_simple_card_parse_convert(dev, PREFIX, &priv->adata); 259 asoc_simple_card_parse_convert(dev, top, PREFIX, &priv->adata);
206 260
207 /* find 1st codec */ 261 loop = 1;
208 np = of_get_child_by_name(node, PREFIX "codec"); 262 link_idx = 0;
209 if (!np) 263 dai_idx = 0;
210 return -ENODEV; 264 conf_idx = 0;
265 node = of_get_child_by_name(top, PREFIX "dai-link");
266 if (!node) {
267 node = dev->of_node;
268 loop = 0;
269 }
270
271 do {
272 codec = of_get_child_by_name(node,
273 loop ? "codec" : PREFIX "codec");
274 if (!codec)
275 return -ENODEV;
276
277 for_each_child_of_node(node, np) {
278 is_fe = (np != codec);
279
280 ret = asoc_simple_card_dai_link_of(node, np, codec, priv,
281 &dai_idx, link_idx++,
282 &conf_idx,
283 is_fe, !loop);
284 if (ret < 0)
285 return ret;
286 }
287 node = of_get_next_child(top, node);
288 } while (loop && node);
211 289
212 ret = asoc_simple_card_parse_daifmt(dev, node, np, PREFIX, &daifmt); 290 ret = asoc_simple_card_parse_card_name(card, PREFIX);
213 if (ret < 0) 291 if (ret < 0)
214 return ret; 292 return ret;
215 293
216 i = 0; 294 return 0;
217 for_each_child_of_node(node, np) { 295}
218 is_fe = false;
219 if (strcmp(np->name, PREFIX "cpu") == 0)
220 is_fe = true;
221 296
222 ret = asoc_simple_card_dai_link_of(np, priv, daifmt, i, is_fe); 297static void asoc_simple_card_get_dais_count(struct device *dev,
223 if (ret < 0) 298 int *link_num,
224 return ret; 299 int *dais_num,
225 i++; 300 int *ccnf_num)
301{
302 struct device_node *top = dev->of_node;
303 struct device_node *node;
304 int loop;
305 int num;
306
307 /*
308 * link_num : number of links.
309 * CPU-Codec / CPU-dummy / dummy-Codec
310 * dais_num : number of DAIs
311 * ccnf_num : number of codec_conf
312 * same number for "dummy-Codec"
313 *
314 * ex1)
315 * CPU0 --- Codec0 link : 5
316 * CPU1 --- Codec1 dais : 7
317 * CPU2 -/ ccnf : 1
318 * CPU3 --- Codec2
319 *
320 * => 5 links = 2xCPU-Codec + 2xCPU-dummy + 1xdummy-Codec
321 * => 7 DAIs = 4xCPU + 3xCodec
322 * => 1 ccnf = 1xdummy-Codec
323 *
324 * ex2)
325 * CPU0 --- Codec0 link : 5
326 * CPU1 --- Codec1 dais : 6
327 * CPU2 -/ ccnf : 1
328 * CPU3 -/
329 *
330 * => 5 links = 1xCPU-Codec + 3xCPU-dummy + 1xdummy-Codec
331 * => 6 DAIs = 4xCPU + 2xCodec
332 * => 1 ccnf = 1xdummy-Codec
333 *
334 * ex3)
335 * CPU0 --- Codec0 link : 6
336 * CPU1 -/ dais : 6
337 * CPU2 --- Codec1 ccnf : 2
338 * CPU3 -/
339 *
340 * => 6 links = 0xCPU-Codec + 4xCPU-dummy + 2xdummy-Codec
341 * => 6 DAIs = 4xCPU + 2xCodec
342 * => 2 ccnf = 2xdummy-Codec
343 */
344 if (!top) {
345 (*link_num) = 1;
346 (*dais_num) = 2;
347 (*ccnf_num) = 0;
348 return;
226 } 349 }
227 350
228 ret = asoc_simple_card_parse_card_name(card, PREFIX); 351 loop = 1;
229 if (ret < 0) 352 node = of_get_child_by_name(top, PREFIX "dai-link");
230 return ret; 353 if (!node) {
354 node = top;
355 loop = 0;
356 }
231 357
232 return 0; 358 do {
359 num = of_get_child_count(node);
360 (*dais_num) += num;
361 if (num > 2) {
362 (*link_num) += num;
363 (*ccnf_num)++;
364 } else {
365 (*link_num)++;
366 }
367 node = of_get_next_child(top, node);
368 } while (loop && node);
233} 369}
234 370
235static int asoc_simple_card_probe(struct platform_device *pdev) 371static int asoc_simple_card_probe(struct platform_device *pdev)
@@ -237,21 +373,27 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
237 struct simple_card_data *priv; 373 struct simple_card_data *priv;
238 struct snd_soc_dai_link *dai_link; 374 struct snd_soc_dai_link *dai_link;
239 struct simple_dai_props *dai_props; 375 struct simple_dai_props *dai_props;
376 struct asoc_simple_dai *dais;
240 struct snd_soc_card *card; 377 struct snd_soc_card *card;
378 struct snd_soc_codec_conf *cconf;
241 struct device *dev = &pdev->dev; 379 struct device *dev = &pdev->dev;
242 struct device_node *np = dev->of_node; 380 int ret, i;
243 int num, ret, i; 381 int lnum = 0, dnum = 0, cnum = 0;
244 382
245 /* Allocate the private data */ 383 /* Allocate the private data */
246 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 384 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
247 if (!priv) 385 if (!priv)
248 return -ENOMEM; 386 return -ENOMEM;
249 387
250 num = of_get_child_count(np); 388 asoc_simple_card_get_dais_count(dev, &lnum, &dnum, &cnum);
389 if (!lnum || !dnum)
390 return -EINVAL;
251 391
252 dai_props = devm_kcalloc(dev, num, sizeof(*dai_props), GFP_KERNEL); 392 dai_props = devm_kcalloc(dev, lnum, sizeof(*dai_props), GFP_KERNEL);
253 dai_link = devm_kcalloc(dev, num, sizeof(*dai_link), GFP_KERNEL); 393 dai_link = devm_kcalloc(dev, lnum, sizeof(*dai_link), GFP_KERNEL);
254 if (!dai_props || !dai_link) 394 dais = devm_kcalloc(dev, dnum, sizeof(*dais), GFP_KERNEL);
395 cconf = devm_kcalloc(dev, cnum, sizeof(*cconf), GFP_KERNEL);
396 if (!dai_props || !dai_link || !dais)
255 return -ENOMEM; 397 return -ENOMEM;
256 398
257 /* 399 /*
@@ -260,7 +402,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
260 * see 402 * see
261 * soc-core.c :: snd_soc_init_multicodec() 403 * soc-core.c :: snd_soc_init_multicodec()
262 */ 404 */
263 for (i = 0; i < num; i++) { 405 for (i = 0; i < lnum; i++) {
264 dai_link[i].codecs = &dai_props[i].codecs; 406 dai_link[i].codecs = &dai_props[i].codecs;
265 dai_link[i].num_codecs = 1; 407 dai_link[i].num_codecs = 1;
266 dai_link[i].platform = &dai_props[i].platform; 408 dai_link[i].platform = &dai_props[i].platform;
@@ -268,15 +410,17 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
268 410
269 priv->dai_props = dai_props; 411 priv->dai_props = dai_props;
270 priv->dai_link = dai_link; 412 priv->dai_link = dai_link;
413 priv->dais = dais;
414 priv->codec_conf = cconf;
271 415
272 /* Init snd_soc_card */ 416 /* Init snd_soc_card */
273 card = simple_priv_to_card(priv); 417 card = simple_priv_to_card(priv);
274 card->owner = THIS_MODULE; 418 card->owner = THIS_MODULE;
275 card->dev = dev; 419 card->dev = dev;
276 card->dai_link = priv->dai_link; 420 card->dai_link = priv->dai_link;
277 card->num_links = num; 421 card->num_links = lnum;
278 card->codec_conf = &priv->codec_conf; 422 card->codec_conf = cconf;
279 card->num_configs = 1; 423 card->num_configs = cnum;
280 424
281 ret = asoc_simple_card_parse_of(priv); 425 ret = asoc_simple_card_parse_of(priv);
282 if (ret < 0) { 426 if (ret < 0) {
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index 18e717703685..99a62ba409df 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -102,15 +102,74 @@ config SND_SST_ATOM_HIFI2_PLATFORM_ACPI
102 recommended option 102 recommended option
103 103
104config SND_SOC_INTEL_SKYLAKE 104config SND_SOC_INTEL_SKYLAKE
105 tristate "SKL/BXT/KBL/GLK/CNL... Platforms" 105 tristate "All Skylake/SST Platforms"
106 depends on PCI && ACPI 106 depends on PCI && ACPI
107 select SND_SOC_INTEL_SKYLAKE_COMMON 107 select SND_SOC_INTEL_SKL
108 select SND_SOC_INTEL_APL
109 select SND_SOC_INTEL_KBL
110 select SND_SOC_INTEL_GLK
111 select SND_SOC_INTEL_CNL
112 select SND_SOC_INTEL_CFL
108 help 113 help
109 If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/ 114 This is a backwards-compatible option to select all devices
110 GeminiLake or CannonLake platform with the DSP enabled in the BIOS 115 supported by the Intel SST/Skylake driver. This option is no
111 then enable this option by saying Y or m. 116 longer recommended and will be deprecated when the SOF
117 driver is introduced. Distributions should explicitly
118 select which platform uses this driver.
119
120config SND_SOC_INTEL_SKL
121 tristate "Skylake Platforms"
122 depends on PCI && ACPI
123 select SND_SOC_INTEL_SKYLAKE_FAMILY
124 help
125 If you have a Intel Skylake platform with the DSP enabled
126 in the BIOS then enable this option by saying Y or m.
127
128config SND_SOC_INTEL_APL
129 tristate "Broxton/ApolloLake Platforms"
130 depends on PCI && ACPI
131 select SND_SOC_INTEL_SKYLAKE_FAMILY
132 help
133 If you have a Intel Broxton/ApolloLake platform with the DSP
134 enabled in the BIOS then enable this option by saying Y or m.
135
136config SND_SOC_INTEL_KBL
137 tristate "Kabylake Platforms"
138 depends on PCI && ACPI
139 select SND_SOC_INTEL_SKYLAKE_FAMILY
140 help
141 If you have a Intel Kabylake platform with the DSP
142 enabled in the BIOS then enable this option by saying Y or m.
143
144config SND_SOC_INTEL_GLK
145 tristate "GeminiLake Platforms"
146 depends on PCI && ACPI
147 select SND_SOC_INTEL_SKYLAKE_FAMILY
148 help
149 If you have a Intel GeminiLake platform with the DSP
150 enabled in the BIOS then enable this option by saying Y or m.
151
152config SND_SOC_INTEL_CNL
153 tristate "CannonLake/WhiskyLake Platforms"
154 depends on PCI && ACPI
155 select SND_SOC_INTEL_SKYLAKE_FAMILY
156 help
157 If you have a Intel CNL/WHL platform with the DSP
158 enabled in the BIOS then enable this option by saying Y or m.
159
160config SND_SOC_INTEL_CFL
161 tristate "CoffeeLake Platforms"
162 depends on PCI && ACPI
163 select SND_SOC_INTEL_SKYLAKE_FAMILY
164 help
165 If you have a Intel CoffeeLake platform with the DSP
166 enabled in the BIOS then enable this option by saying Y or m.
167
168config SND_SOC_INTEL_SKYLAKE_FAMILY
169 tristate
170 select SND_SOC_INTEL_SKYLAKE_COMMON
112 171
113if SND_SOC_INTEL_SKYLAKE 172if SND_SOC_INTEL_SKYLAKE_FAMILY
114 173
115config SND_SOC_INTEL_SKYLAKE_SSP_CLK 174config SND_SOC_INTEL_SKYLAKE_SSP_CLK
116 tristate 175 tristate
@@ -135,7 +194,7 @@ config SND_SOC_INTEL_SKYLAKE_COMMON
135 GeminiLake or CannonLake platform with the DSP enabled in the BIOS 194 GeminiLake or CannonLake platform with the DSP enabled in the BIOS
136 then enable this option by saying Y or m. 195 then enable this option by saying Y or m.
137 196
138endif ## SND_SOC_INTEL_SKYLAKE 197endif ## SND_SOC_INTEL_SKYLAKE_FAMILY
139 198
140config SND_SOC_ACPI_INTEL_MATCH 199config SND_SOC_ACPI_INTEL_MATCH
141 tristate 200 tristate
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
index c90b04cc071d..ac542535b9d5 100644
--- a/sound/soc/intel/atom/sst/sst_acpi.c
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
@@ -341,6 +341,10 @@ static int sst_acpi_probe(struct platform_device *pdev)
341 byt_rvp_platform_data.res_info = &bytcr_res_info; 341 byt_rvp_platform_data.res_info = &bytcr_res_info;
342 } 342 }
343 343
344 /* update machine parameters */
345 mach->mach_params.acpi_ipc_irq_index =
346 pdata->res_info->acpi_ipc_irq_index;
347
344 plat_dev = platform_device_register_data(dev, pdata->platform, -1, 348 plat_dev = platform_device_register_data(dev, pdata->platform, -1,
345 NULL, 0); 349 NULL, 0);
346 if (IS_ERR(plat_dev)) { 350 if (IS_ERR(plat_dev)) {
diff --git a/sound/soc/intel/atom/sst/sst_loader.c b/sound/soc/intel/atom/sst/sst_loader.c
index 27413ebae956..b8c456753f01 100644
--- a/sound/soc/intel/atom/sst/sst_loader.c
+++ b/sound/soc/intel/atom/sst/sst_loader.c
@@ -354,14 +354,14 @@ static int sst_request_fw(struct intel_sst_drv *sst)
354 const struct firmware *fw; 354 const struct firmware *fw;
355 355
356 retval = request_firmware(&fw, sst->firmware_name, sst->dev); 356 retval = request_firmware(&fw, sst->firmware_name, sst->dev);
357 if (fw == NULL) {
358 dev_err(sst->dev, "fw is returning as null\n");
359 return -EINVAL;
360 }
361 if (retval) { 357 if (retval) {
362 dev_err(sst->dev, "request fw failed %d\n", retval); 358 dev_err(sst->dev, "request fw failed %d\n", retval);
363 return retval; 359 return retval;
364 } 360 }
361 if (fw == NULL) {
362 dev_err(sst->dev, "fw is returning as null\n");
363 return -EINVAL;
364 }
365 mutex_lock(&sst->sst_lock); 365 mutex_lock(&sst->sst_lock);
366 retval = sst_cache_and_parse_fw(sst, fw); 366 retval = sst_cache_and_parse_fw(sst, fw);
367 mutex_unlock(&sst->sst_lock); 367 mutex_unlock(&sst->sst_lock);
diff --git a/sound/soc/intel/atom/sst/sst_pvt.c b/sound/soc/intel/atom/sst/sst_pvt.c
index af93244b4868..00a37a09dc9b 100644
--- a/sound/soc/intel/atom/sst/sst_pvt.c
+++ b/sound/soc/intel/atom/sst/sst_pvt.c
@@ -166,11 +166,11 @@ int sst_create_ipc_msg(struct ipc_post **arg, bool large)
166{ 166{
167 struct ipc_post *msg; 167 struct ipc_post *msg;
168 168
169 msg = kzalloc(sizeof(struct ipc_post), GFP_ATOMIC); 169 msg = kzalloc(sizeof(*msg), GFP_KERNEL);
170 if (!msg) 170 if (!msg)
171 return -ENOMEM; 171 return -ENOMEM;
172 if (large) { 172 if (large) {
173 msg->mailbox_data = kzalloc(SST_MAILBOX_SIZE, GFP_ATOMIC); 173 msg->mailbox_data = kzalloc(SST_MAILBOX_SIZE, GFP_KERNEL);
174 if (!msg->mailbox_data) { 174 if (!msg->mailbox_data) {
175 kfree(msg); 175 kfree(msg);
176 return -ENOMEM; 176 return -ENOMEM;
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig
index b177db2a0dbb..0a7e40d06395 100644
--- a/sound/soc/intel/boards/Kconfig
+++ b/sound/soc/intel/boards/Kconfig
@@ -172,7 +172,7 @@ config SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH
172 172
173endif ## SND_SST_ATOM_HIFI2_PLATFORM 173endif ## SND_SST_ATOM_HIFI2_PLATFORM
174 174
175if SND_SOC_INTEL_SKYLAKE 175if SND_SOC_INTEL_SKL
176 176
177config SND_SOC_INTEL_SKL_RT286_MACH 177config SND_SOC_INTEL_SKL_RT286_MACH
178 tristate "SKL with RT286 I2S mode" 178 tristate "SKL with RT286 I2S mode"
@@ -212,6 +212,10 @@ config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH
212 Say Y or m if you have such a device. This is a recommended option. 212 Say Y or m if you have such a device. This is a recommended option.
213 If unsure select "N". 213 If unsure select "N".
214 214
215endif ## SND_SOC_INTEL_SKL
216
217if SND_SOC_INTEL_APL
218
215config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH 219config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH
216 tristate "Broxton with DA7219 and MAX98357A in I2S Mode" 220 tristate "Broxton with DA7219 and MAX98357A in I2S Mode"
217 depends on MFD_INTEL_LPSS && I2C && ACPI 221 depends on MFD_INTEL_LPSS && I2C && ACPI
@@ -239,6 +243,10 @@ config SND_SOC_INTEL_BXT_RT298_MACH
239 Say Y or m if you have such a device. This is a recommended option. 243 Say Y or m if you have such a device. This is a recommended option.
240 If unsure select "N". 244 If unsure select "N".
241 245
246endif ## SND_SOC_INTEL_APL
247
248if SND_SOC_INTEL_KBL
249
242config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH 250config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH
243 tristate "KBL with RT5663 and MAX98927 in I2S Mode" 251 tristate "KBL with RT5663 and MAX98927 in I2S Mode"
244 depends on MFD_INTEL_LPSS && I2C && ACPI 252 depends on MFD_INTEL_LPSS && I2C && ACPI
@@ -293,6 +301,20 @@ config SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH
293 Say Y if you have such a device. 301 Say Y if you have such a device.
294 If unsure select "N". 302 If unsure select "N".
295 303
304config SND_SOC_INTEL_KBL_RT5660_MACH
305 tristate "KBL with RT5660 in I2S Mode"
306 depends on MFD_INTEL_LPSS && I2C && ACPI
307 select SND_SOC_RT5660
308 select SND_SOC_HDAC_HDMI
309 help
310 This adds support for ASoC Onboard Codec I2S machine driver. This will
311 create an alsa sound card for RT5660 I2S audio codec.
312 Say Y if you have such a device.
313
314endif ## SND_SOC_INTEL_KBL
315
316if SND_SOC_INTEL_GLK
317
296config SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH 318config SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH
297 tristate "GLK with RT5682 and MAX98357A in I2S Mode" 319 tristate "GLK with RT5682 and MAX98357A in I2S Mode"
298 depends on MFD_INTEL_LPSS && I2C && ACPI 320 depends on MFD_INTEL_LPSS && I2C && ACPI
@@ -307,7 +329,7 @@ config SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH
307 Say Y if you have such a device. 329 Say Y if you have such a device.
308 If unsure select "N". 330 If unsure select "N".
309 331
310endif ## SND_SOC_INTEL_SKYLAKE 332endif ## SND_SOC_INTEL_GLK
311 333
312if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC 334if SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC
313 335
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index 5381e27df9cc..bf072ea299b7 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -20,6 +20,7 @@ snd-soc-kbl_da7219_max98357a-objs := kbl_da7219_max98357a.o
20snd-soc-kbl_da7219_max98927-objs := kbl_da7219_max98927.o 20snd-soc-kbl_da7219_max98927-objs := kbl_da7219_max98927.o
21snd-soc-kbl_rt5663_max98927-objs := kbl_rt5663_max98927.o 21snd-soc-kbl_rt5663_max98927-objs := kbl_rt5663_max98927.o
22snd-soc-kbl_rt5663_rt5514_max98927-objs := kbl_rt5663_rt5514_max98927.o 22snd-soc-kbl_rt5663_rt5514_max98927-objs := kbl_rt5663_rt5514_max98927.o
23snd-soc-kbl_rt5660-objs := kbl_rt5660.o
23snd-soc-skl_rt286-objs := skl_rt286.o 24snd-soc-skl_rt286-objs := skl_rt286.o
24snd-soc-skl_hda_dsp-objs := skl_hda_dsp_generic.o skl_hda_dsp_common.o 25snd-soc-skl_hda_dsp-objs := skl_hda_dsp_generic.o skl_hda_dsp_common.o
25snd-skl_nau88l25_max98357a-objs := skl_nau88l25_max98357a.o 26snd-skl_nau88l25_max98357a-objs := skl_nau88l25_max98357a.o
@@ -46,6 +47,7 @@ obj-$(CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH) += snd-soc-kbl_da7219_max9
46obj-$(CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH) += snd-soc-kbl_da7219_max98927.o 47obj-$(CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH) += snd-soc-kbl_da7219_max98927.o
47obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH) += snd-soc-kbl_rt5663_max98927.o 48obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH) += snd-soc-kbl_rt5663_max98927.o
48obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH) += snd-soc-kbl_rt5663_rt5514_max98927.o 49obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH) += snd-soc-kbl_rt5663_rt5514_max98927.o
50obj-$(CONFIG_SND_SOC_INTEL_KBL_RT5660_MACH) += snd-soc-kbl_rt5660.o
49obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o 51obj-$(CONFIG_SND_SOC_INTEL_SKL_RT286_MACH) += snd-soc-skl_rt286.o
50obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH) += snd-skl_nau88l25_max98357a.o 52obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH) += snd-skl_nau88l25_max98357a.o
51obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH) += snd-soc-skl_nau88l25_ssm4567.o 53obj-$(CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH) += snd-soc-skl_nau88l25_ssm4567.o
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 8587bd3d1cc1..a22366ce33c4 100644
--- a/sound/soc/intel/boards/bytcr_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -29,7 +29,6 @@
29#include <linux/input.h> 29#include <linux/input.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <asm/cpu_device_id.h> 31#include <asm/cpu_device_id.h>
32#include <asm/platform_sst_audio.h>
33#include <sound/pcm.h> 32#include <sound/pcm.h>
34#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
35#include <sound/soc.h> 34#include <sound/soc.h>
@@ -674,6 +673,33 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
674 BYT_RT5640_SSP0_AIF2 | 673 BYT_RT5640_SSP0_AIF2 |
675 BYT_RT5640_MCLK_EN), 674 BYT_RT5640_MCLK_EN),
676 }, 675 },
676 { /* Point of View Mobii TAB-P1005W-232 (V2.0) */
677 .matches = {
678 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "POV"),
679 DMI_EXACT_MATCH(DMI_BOARD_NAME, "I102A"),
680 },
681 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
682 BYT_RT5640_JD_SRC_JD2_IN4N |
683 BYT_RT5640_OVCD_TH_2000UA |
684 BYT_RT5640_OVCD_SF_0P75 |
685 BYT_RT5640_DIFF_MIC |
686 BYT_RT5640_SSP0_AIF1 |
687 BYT_RT5640_MCLK_EN),
688 },
689 {
690 /* Prowise PT301 */
691 .matches = {
692 DMI_MATCH(DMI_SYS_VENDOR, "Prowise"),
693 DMI_MATCH(DMI_PRODUCT_NAME, "PT301"),
694 },
695 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
696 BYT_RT5640_JD_SRC_JD2_IN4N |
697 BYT_RT5640_OVCD_TH_2000UA |
698 BYT_RT5640_OVCD_SF_0P75 |
699 BYT_RT5640_DIFF_MIC |
700 BYT_RT5640_SSP0_AIF1 |
701 BYT_RT5640_MCLK_EN),
702 },
677 { 703 {
678 .matches = { 704 .matches = {
679 DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), 705 DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
@@ -1152,10 +1178,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
1152 * (will be overridden if DMI quirk is detected) 1178 * (will be overridden if DMI quirk is detected)
1153 */ 1179 */
1154 if (is_valleyview()) { 1180 if (is_valleyview()) {
1155 struct sst_platform_info *p_info = mach->pdata; 1181 if (mach->mach_params.acpi_ipc_irq_index == 0)
1156 const struct sst_res_info *res_info = p_info->res_info;
1157
1158 if (res_info->acpi_ipc_irq_index == 0)
1159 is_bytcr = true; 1182 is_bytcr = true;
1160 } 1183 }
1161 1184
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c
index c44298130720..e528995668b7 100644
--- a/sound/soc/intel/boards/bytcr_rt5651.c
+++ b/sound/soc/intel/boards/bytcr_rt5651.c
@@ -32,7 +32,6 @@
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <asm/cpu_device_id.h> 33#include <asm/cpu_device_id.h>
34#include <asm/intel-family.h> 34#include <asm/intel-family.h>
35#include <asm/platform_sst_audio.h>
36#include <sound/pcm.h> 35#include <sound/pcm.h>
37#include <sound/pcm_params.h> 36#include <sound/pcm_params.h>
38#include <sound/soc.h> 37#include <sound/soc.h>
@@ -920,10 +919,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
920 * (will be overridden if DMI quirk is detected) 919 * (will be overridden if DMI quirk is detected)
921 */ 920 */
922 if (x86_match_cpu(baytrail_cpu_ids)) { 921 if (x86_match_cpu(baytrail_cpu_ids)) {
923 struct sst_platform_info *p_info = mach->pdata; 922 if (mach->mach_params.acpi_ipc_irq_index == 0)
924 const struct sst_res_info *res_info = p_info->res_info;
925
926 if (res_info->acpi_ipc_irq_index == 0)
927 is_bytcr = true; 923 is_bytcr = true;
928 } 924 }
929 925
diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
index 9d9f6e41d81c..08a5152e635a 100644
--- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c
+++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
@@ -390,6 +390,20 @@ static struct snd_soc_card snd_soc_card_cht = {
390 390
391static const struct dmi_system_id cht_max98090_quirk_table[] = { 391static const struct dmi_system_id cht_max98090_quirk_table[] = {
392 { 392 {
393 /* Clapper model Chromebook */
394 .matches = {
395 DMI_MATCH(DMI_PRODUCT_NAME, "Clapper"),
396 },
397 .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
398 },
399 {
400 /* Gnawty model Chromebook (Acer Chromebook CB3-111) */
401 .matches = {
402 DMI_MATCH(DMI_PRODUCT_NAME, "Gnawty"),
403 },
404 .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
405 },
406 {
393 /* Swanky model Chromebook (Toshiba Chromebook 2) */ 407 /* Swanky model Chromebook (Toshiba Chromebook 2) */
394 .matches = { 408 .matches = {
395 DMI_MATCH(DMI_PRODUCT_NAME, "Swanky"), 409 DMI_MATCH(DMI_PRODUCT_NAME, "Swanky"),
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c
index f5a5ea6a093c..250a356a0cbf 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5645.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5645.c
@@ -27,7 +27,6 @@
27#include <linux/dmi.h> 27#include <linux/dmi.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <asm/cpu_device_id.h> 29#include <asm/cpu_device_id.h>
30#include <asm/platform_sst_audio.h>
31#include <sound/pcm.h> 30#include <sound/pcm.h>
32#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
33#include <sound/soc.h> 32#include <sound/soc.h>
@@ -585,10 +584,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
585 * (will be overridden if DMI quirk is detected) 584 * (will be overridden if DMI quirk is detected)
586 */ 585 */
587 if (is_valleyview()) { 586 if (is_valleyview()) {
588 struct sst_platform_info *p_info = mach->pdata; 587 if (mach->mach_params.acpi_ipc_irq_index == 0)
589 const struct sst_res_info *res_info = p_info->res_info;
590
591 if (res_info->acpi_ipc_irq_index == 0)
592 is_bytcr = true; 588 is_bytcr = true;
593 } 589 }
594 590
diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c
index 51f0d45d6f8f..9de64f447e7b 100644
--- a/sound/soc/intel/boards/cht_bsw_rt5672.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5672.c
@@ -403,7 +403,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
403 const char *i2c_name; 403 const char *i2c_name;
404 int i; 404 int i;
405 405
406 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_ATOMIC); 406 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
407 if (!drv) 407 if (!drv)
408 return -ENOMEM; 408 return -ENOMEM;
409 409
diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c b/sound/soc/intel/boards/glk_rt5682_max98357a.c
index c4b94e2617c5..c74c4f17316f 100644
--- a/sound/soc/intel/boards/glk_rt5682_max98357a.c
+++ b/sound/soc/intel/boards/glk_rt5682_max98357a.c
@@ -603,7 +603,7 @@ static int geminilake_audio_probe(struct platform_device *pdev)
603{ 603{
604 struct glk_card_private *ctx; 604 struct glk_card_private *ctx;
605 605
606 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 606 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
607 if (!ctx) 607 if (!ctx)
608 return -ENOMEM; 608 return -ENOMEM;
609 609
diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c b/sound/soc/intel/boards/kbl_da7219_max98927.c
index 3fa1c3ca6d37..723a4935ed76 100644
--- a/sound/soc/intel/boards/kbl_da7219_max98927.c
+++ b/sound/soc/intel/boards/kbl_da7219_max98927.c
@@ -262,9 +262,9 @@ static int kabylake_da7219_codec_init(struct snd_soc_pcm_runtime *rtd)
262 262
263 jack = &ctx->kabylake_headset; 263 jack = &ctx->kabylake_headset;
264 snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); 264 snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
265 snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); 265 snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
266 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); 266 snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
267 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); 267 snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
268 268
269 da7219_aad_jack_det(component, &ctx->kabylake_headset); 269 da7219_aad_jack_det(component, &ctx->kabylake_headset);
270 270
@@ -441,7 +441,7 @@ static int kabylake_refcap_startup(struct snd_pcm_substream *substream)
441} 441}
442 442
443 443
444static struct snd_soc_ops skylaye_refcap_ops = { 444static struct snd_soc_ops skylake_refcap_ops = {
445 .startup = kabylake_refcap_startup, 445 .startup = kabylake_refcap_startup,
446}; 446};
447 447
@@ -525,7 +525,7 @@ static struct snd_soc_dai_link kabylake_dais[] = {
525 .dpcm_capture = 1, 525 .dpcm_capture = 1,
526 .nonatomic = 1, 526 .nonatomic = 1,
527 .dynamic = 1, 527 .dynamic = 1,
528 .ops = &skylaye_refcap_ops, 528 .ops = &skylake_refcap_ops,
529 }, 529 },
530 [KBL_DPCM_AUDIO_DMIC_CP] = { 530 [KBL_DPCM_AUDIO_DMIC_CP] = {
531 .name = "Kbl Audio DMIC cap", 531 .name = "Kbl Audio DMIC cap",
@@ -736,7 +736,7 @@ static struct snd_soc_dai_link kabylake_max98927_dais[] = {
736 .dpcm_capture = 1, 736 .dpcm_capture = 1,
737 .nonatomic = 1, 737 .nonatomic = 1,
738 .dynamic = 1, 738 .dynamic = 1,
739 .ops = &skylaye_refcap_ops, 739 .ops = &skylake_refcap_ops,
740 }, 740 },
741 [KBL_DPCM_AUDIO_DMIC_CP] = { 741 [KBL_DPCM_AUDIO_DMIC_CP] = {
742 .name = "Kbl Audio DMIC cap", 742 .name = "Kbl Audio DMIC cap",
@@ -935,7 +935,7 @@ static int kabylake_audio_probe(struct platform_device *pdev)
935{ 935{
936 struct kbl_codec_private *ctx; 936 struct kbl_codec_private *ctx;
937 937
938 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 938 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
939 if (!ctx) 939 if (!ctx)
940 return -ENOMEM; 940 return -ENOMEM;
941 941
diff --git a/sound/soc/intel/boards/kbl_rt5660.c b/sound/soc/intel/boards/kbl_rt5660.c
new file mode 100644
index 000000000000..3255e0029276
--- /dev/null
+++ b/sound/soc/intel/boards/kbl_rt5660.c
@@ -0,0 +1,543 @@
1// SPDX-License-Identifier: GPL-2.0
2// Copyright(c) 2018-19 Canonical Corporation.
3
4/*
5 * Intel Kabylake I2S Machine Driver with RT5660 Codec
6 *
7 * Modified from:
8 * Intel Kabylake I2S Machine driver supporting MAXIM98357a and
9 * DA7219 codecs
10 * Also referred to:
11 * Intel Broadwell I2S Machine driver supporting RT5677 codec
12 */
13
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/gpio/consumer.h>
17#include <linux/acpi.h>
18#include <sound/core.h>
19#include <sound/jack.h>
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include <sound/soc.h>
23
24#include "../../codecs/hdac_hdmi.h"
25#include "../../codecs/rt5660.h"
26
27#define KBL_RT5660_CODEC_DAI "rt5660-aif1"
28#define DUAL_CHANNEL 2
29
30static struct snd_soc_card *kabylake_audio_card;
31static struct snd_soc_jack skylake_hdmi[3];
32static struct snd_soc_jack lineout_jack;
33static struct snd_soc_jack mic_jack;
34
35struct kbl_hdmi_pcm {
36 struct list_head head;
37 struct snd_soc_dai *codec_dai;
38 int device;
39};
40
41struct kbl_codec_private {
42 struct gpio_desc *gpio_lo_mute;
43 struct list_head hdmi_pcm_list;
44};
45
46enum {
47 KBL_DPCM_AUDIO_PB = 0,
48 KBL_DPCM_AUDIO_CP,
49 KBL_DPCM_AUDIO_HDMI1_PB,
50 KBL_DPCM_AUDIO_HDMI2_PB,
51 KBL_DPCM_AUDIO_HDMI3_PB,
52};
53
54#define GPIO_LINEOUT_MUTE_INDEX 0
55#define GPIO_LINEOUT_DET_INDEX 3
56#define GPIO_LINEIN_DET_INDEX 4
57
58static const struct acpi_gpio_params lineout_mute_gpio = { GPIO_LINEOUT_MUTE_INDEX, 0, true };
59static const struct acpi_gpio_params lineout_det_gpio = { GPIO_LINEOUT_DET_INDEX, 0, false };
60static const struct acpi_gpio_params mic_det_gpio = { GPIO_LINEIN_DET_INDEX, 0, false };
61
62
63static const struct acpi_gpio_mapping acpi_rt5660_gpios[] = {
64 { "lineout-mute-gpios", &lineout_mute_gpio, 1 },
65 { "lineout-det-gpios", &lineout_det_gpio, 1 },
66 { "mic-det-gpios", &mic_det_gpio, 1 },
67 { NULL },
68};
69
70static struct snd_soc_jack_pin lineout_jack_pin = {
71 .pin = "Line Out",
72 .mask = SND_JACK_LINEOUT,
73};
74
75static struct snd_soc_jack_pin mic_jack_pin = {
76 .pin = "Line In",
77 .mask = SND_JACK_MICROPHONE,
78};
79
80static struct snd_soc_jack_gpio lineout_jack_gpio = {
81 .name = "lineout-det",
82 .report = SND_JACK_LINEOUT,
83 .debounce_time = 200,
84};
85
86static struct snd_soc_jack_gpio mic_jack_gpio = {
87 .name = "mic-det",
88 .report = SND_JACK_MICROPHONE,
89 .debounce_time = 200,
90};
91
92static int kabylake_5660_event_lineout(struct snd_soc_dapm_widget *w,
93 struct snd_kcontrol *k, int event)
94{
95 struct snd_soc_dapm_context *dapm = w->dapm;
96 struct kbl_codec_private *priv = snd_soc_card_get_drvdata(dapm->card);
97
98 gpiod_set_value_cansleep(priv->gpio_lo_mute,
99 !(SND_SOC_DAPM_EVENT_ON(event)));
100
101 return 0;
102}
103
104static const struct snd_kcontrol_new kabylake_rt5660_controls[] = {
105 SOC_DAPM_PIN_SWITCH("Line In"),
106 SOC_DAPM_PIN_SWITCH("Line Out"),
107};
108
109static const struct snd_soc_dapm_widget kabylake_rt5660_widgets[] = {
110 SND_SOC_DAPM_MIC("Line In", NULL),
111 SND_SOC_DAPM_LINE("Line Out", kabylake_5660_event_lineout),
112};
113
114static const struct snd_soc_dapm_route kabylake_rt5660_map[] = {
115 /* other jacks */
116 {"IN1P", NULL, "Line In"},
117 {"IN2P", NULL, "Line In"},
118 {"Line Out", NULL, "LOUTR"},
119 {"Line Out", NULL, "LOUTL"},
120
121 /* CODEC BE connections */
122 { "AIF1 Playback", NULL, "ssp0 Tx"},
123 { "ssp0 Tx", NULL, "codec0_out"},
124
125 { "codec0_in", NULL, "ssp0 Rx" },
126 { "ssp0 Rx", NULL, "AIF1 Capture" },
127
128 { "hifi1", NULL, "iDisp1 Tx"},
129 { "iDisp1 Tx", NULL, "iDisp1_out"},
130 { "hifi2", NULL, "iDisp2 Tx"},
131 { "iDisp2 Tx", NULL, "iDisp2_out"},
132 { "hifi3", NULL, "iDisp3 Tx"},
133 { "iDisp3 Tx", NULL, "iDisp3_out"},
134};
135
136static int kabylake_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
137 struct snd_pcm_hw_params *params)
138{
139 struct snd_interval *rate = hw_param_interval(params,
140 SNDRV_PCM_HW_PARAM_RATE);
141 struct snd_interval *channels = hw_param_interval(params,
142 SNDRV_PCM_HW_PARAM_CHANNELS);
143 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
144
145 /* The ADSP will convert the FE rate to 48k, stereo */
146 rate->min = rate->max = 48000;
147 channels->min = channels->max = DUAL_CHANNEL;
148
149 /* set SSP0 to 24 bit */
150 snd_mask_none(fmt);
151 snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);
152
153 return 0;
154}
155
156static int kabylake_rt5660_codec_init(struct snd_soc_pcm_runtime *rtd)
157{
158 int ret;
159 struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
160 struct snd_soc_component *component = rtd->codec_dai->component;
161 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
162
163 ret = devm_acpi_dev_add_driver_gpios(component->dev, acpi_rt5660_gpios);
164 if (ret)
165 dev_warn(component->dev, "Failed to add driver gpios\n");
166
167 /* Request rt5660 GPIO for lineout mute control, return if fails */
168 ctx->gpio_lo_mute = devm_gpiod_get(component->dev, "lineout-mute",
169 GPIOD_OUT_HIGH);
170 if (IS_ERR(ctx->gpio_lo_mute)) {
171 dev_err(component->dev, "Can't find GPIO_MUTE# gpio\n");
172 return PTR_ERR(ctx->gpio_lo_mute);
173 }
174
175 /* Create and initialize headphone jack, this jack is not mandatory, don't return if fails */
176 ret = snd_soc_card_jack_new(rtd->card, "Lineout Jack",
177 SND_JACK_LINEOUT, &lineout_jack,
178 &lineout_jack_pin, 1);
179 if (ret)
180 dev_warn(component->dev, "Can't create Lineout jack\n");
181 else {
182 lineout_jack_gpio.gpiod_dev = component->dev;
183 ret = snd_soc_jack_add_gpios(&lineout_jack, 1,
184 &lineout_jack_gpio);
185 if (ret)
186 dev_warn(component->dev, "Can't add Lineout jack gpio\n");
187 }
188
189 /* Create and initialize mic jack, this jack is not mandatory, don't return if fails */
190 ret = snd_soc_card_jack_new(rtd->card, "Mic Jack",
191 SND_JACK_MICROPHONE, &mic_jack,
192 &mic_jack_pin, 1);
193 if (ret)
194 dev_warn(component->dev, "Can't create mic jack\n");
195 else {
196 mic_jack_gpio.gpiod_dev = component->dev;
197 ret = snd_soc_jack_add_gpios(&mic_jack, 1, &mic_jack_gpio);
198 if (ret)
199 dev_warn(component->dev, "Can't add mic jack gpio\n");
200 }
201
202 /* Here we enable some dapms in advance to reduce the pop noise for recording via line-in */
203 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
204 snd_soc_dapm_force_enable_pin(dapm, "BST1");
205 snd_soc_dapm_force_enable_pin(dapm, "BST2");
206
207 return 0;
208}
209
210static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device)
211{
212 struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card);
213 struct snd_soc_dai *dai = rtd->codec_dai;
214 struct kbl_hdmi_pcm *pcm;
215
216 pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
217 if (!pcm)
218 return -ENOMEM;
219
220 pcm->device = device;
221 pcm->codec_dai = dai;
222
223 list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
224
225 return 0;
226}
227
228static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd)
229{
230 return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI1_PB);
231}
232
233static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd)
234{
235 return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI2_PB);
236}
237
238static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd)
239{
240 return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI3_PB);
241}
242
243static int kabylake_rt5660_hw_params(struct snd_pcm_substream *substream,
244 struct snd_pcm_hw_params *params)
245{
246 struct snd_soc_pcm_runtime *rtd = substream->private_data;
247 struct snd_soc_dai *codec_dai = rtd->codec_dai;
248 int ret;
249
250 ret = snd_soc_dai_set_sysclk(codec_dai,
251 RT5660_SCLK_S_PLL1, params_rate(params) * 512,
252 SND_SOC_CLOCK_IN);
253 if (ret < 0) {
254 dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
255 return ret;
256 }
257
258 ret = snd_soc_dai_set_pll(codec_dai, 0,
259 RT5660_PLL1_S_BCLK,
260 params_rate(params) * 50,
261 params_rate(params) * 512);
262 if (ret < 0)
263 dev_err(codec_dai->dev, "can't set codec pll: %d\n", ret);
264
265 return ret;
266}
267
268static struct snd_soc_ops kabylake_rt5660_ops = {
269 .hw_params = kabylake_rt5660_hw_params,
270};
271
272static const unsigned int rates[] = {
273 48000,
274};
275
276static const struct snd_pcm_hw_constraint_list constraints_rates = {
277 .count = ARRAY_SIZE(rates),
278 .list = rates,
279 .mask = 0,
280};
281
282static const unsigned int channels[] = {
283 DUAL_CHANNEL,
284};
285
286static const struct snd_pcm_hw_constraint_list constraints_channels = {
287 .count = ARRAY_SIZE(channels),
288 .list = channels,
289 .mask = 0,
290};
291
292static int kbl_fe_startup(struct snd_pcm_substream *substream)
293{
294 struct snd_pcm_runtime *runtime = substream->runtime;
295
296 /*
297 * On this platform for PCM device we support,
298 * 48Khz
299 * stereo
300 * 16 bit audio
301 */
302
303 runtime->hw.channels_max = DUAL_CHANNEL;
304 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
305 &constraints_channels);
306
307 runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
308 snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
309
310 snd_pcm_hw_constraint_list(runtime, 0,
311 SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
312
313 return 0;
314}
315
316static const struct snd_soc_ops kabylake_rt5660_fe_ops = {
317 .startup = kbl_fe_startup,
318};
319
320/* kabylake digital audio interface glue - connects rt5660 codec <--> CPU */
321static struct snd_soc_dai_link kabylake_rt5660_dais[] = {
322 /* Front End DAI links */
323 [KBL_DPCM_AUDIO_PB] = {
324 .name = "Kbl Audio Port",
325 .stream_name = "Audio",
326 .cpu_dai_name = "System Pin",
327 .platform_name = "0000:00:1f.3",
328 .dynamic = 1,
329 .codec_name = "snd-soc-dummy",
330 .codec_dai_name = "snd-soc-dummy-dai",
331 .nonatomic = 1,
332 .trigger = {
333 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
334 .dpcm_playback = 1,
335 .ops = &kabylake_rt5660_fe_ops,
336 },
337 [KBL_DPCM_AUDIO_CP] = {
338 .name = "Kbl Audio Capture Port",
339 .stream_name = "Audio Record",
340 .cpu_dai_name = "System Pin",
341 .platform_name = "0000:00:1f.3",
342 .dynamic = 1,
343 .codec_name = "snd-soc-dummy",
344 .codec_dai_name = "snd-soc-dummy-dai",
345 .nonatomic = 1,
346 .trigger = {
347 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
348 .dpcm_capture = 1,
349 .ops = &kabylake_rt5660_fe_ops,
350 },
351 [KBL_DPCM_AUDIO_HDMI1_PB] = {
352 .name = "Kbl HDMI Port1",
353 .stream_name = "Hdmi1",
354 .cpu_dai_name = "HDMI1 Pin",
355 .codec_name = "snd-soc-dummy",
356 .codec_dai_name = "snd-soc-dummy-dai",
357 .platform_name = "0000:00:1f.3",
358 .dpcm_playback = 1,
359 .init = NULL,
360 .trigger = {
361 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
362 .nonatomic = 1,
363 .dynamic = 1,
364 },
365 [KBL_DPCM_AUDIO_HDMI2_PB] = {
366 .name = "Kbl HDMI Port2",
367 .stream_name = "Hdmi2",
368 .cpu_dai_name = "HDMI2 Pin",
369 .codec_name = "snd-soc-dummy",
370 .codec_dai_name = "snd-soc-dummy-dai",
371 .platform_name = "0000:00:1f.3",
372 .dpcm_playback = 1,
373 .init = NULL,
374 .trigger = {
375 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
376 .nonatomic = 1,
377 .dynamic = 1,
378 },
379 [KBL_DPCM_AUDIO_HDMI3_PB] = {
380 .name = "Kbl HDMI Port3",
381 .stream_name = "Hdmi3",
382 .cpu_dai_name = "HDMI3 Pin",
383 .codec_name = "snd-soc-dummy",
384 .codec_dai_name = "snd-soc-dummy-dai",
385 .platform_name = "0000:00:1f.3",
386 .trigger = {
387 SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
388 .dpcm_playback = 1,
389 .init = NULL,
390 .nonatomic = 1,
391 .dynamic = 1,
392 },
393
394 /* Back End DAI links */
395 {
396 /* SSP0 - Codec */
397 .name = "SSP0-Codec",
398 .id = 0,
399 .cpu_dai_name = "SSP0 Pin",
400 .platform_name = "0000:00:1f.3",
401 .no_pcm = 1,
402 .codec_name = "i2c-10EC3277:00",
403 .codec_dai_name = KBL_RT5660_CODEC_DAI,
404 .init = kabylake_rt5660_codec_init,
405 .dai_fmt = SND_SOC_DAIFMT_I2S |
406 SND_SOC_DAIFMT_NB_NF |
407 SND_SOC_DAIFMT_CBS_CFS,
408 .ignore_pmdown_time = 1,
409 .be_hw_params_fixup = kabylake_ssp0_fixup,
410 .ops = &kabylake_rt5660_ops,
411 .dpcm_playback = 1,
412 .dpcm_capture = 1,
413 },
414 {
415 .name = "iDisp1",
416 .id = 1,
417 .cpu_dai_name = "iDisp1 Pin",
418 .codec_name = "ehdaudio0D2",
419 .codec_dai_name = "intel-hdmi-hifi1",
420 .platform_name = "0000:00:1f.3",
421 .dpcm_playback = 1,
422 .init = kabylake_hdmi1_init,
423 .no_pcm = 1,
424 },
425 {
426 .name = "iDisp2",
427 .id = 2,
428 .cpu_dai_name = "iDisp2 Pin",
429 .codec_name = "ehdaudio0D2",
430 .codec_dai_name = "intel-hdmi-hifi2",
431 .platform_name = "0000:00:1f.3",
432 .init = kabylake_hdmi2_init,
433 .dpcm_playback = 1,
434 .no_pcm = 1,
435 },
436 {
437 .name = "iDisp3",
438 .id = 3,
439 .cpu_dai_name = "iDisp3 Pin",
440 .codec_name = "ehdaudio0D2",
441 .codec_dai_name = "intel-hdmi-hifi3",
442 .platform_name = "0000:00:1f.3",
443 .init = kabylake_hdmi3_init,
444 .dpcm_playback = 1,
445 .no_pcm = 1,
446 },
447};
448
449
450#define NAME_SIZE 32
451static int kabylake_card_late_probe(struct snd_soc_card *card)
452{
453 struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
454 struct kbl_hdmi_pcm *pcm;
455 struct snd_soc_component *component = NULL;
456 int err, i = 0;
457 char jack_name[NAME_SIZE];
458
459 list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
460 component = pcm->codec_dai->component;
461 snprintf(jack_name, sizeof(jack_name),
462 "HDMI/DP, pcm=%d Jack", pcm->device);
463 err = snd_soc_card_jack_new(card, jack_name,
464 SND_JACK_AVOUT, &skylake_hdmi[i],
465 NULL, 0);
466
467 if (err)
468 return err;
469
470 err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
471 &skylake_hdmi[i]);
472 if (err < 0)
473 return err;
474
475 i++;
476
477 }
478
479 if (!component)
480 return -EINVAL;
481
482 return hdac_hdmi_jack_port_init(component, &card->dapm);
483}
484
485/* kabylake audio machine driver for rt5660 */
486static struct snd_soc_card kabylake_audio_card_rt5660 = {
487 .name = "kblrt5660",
488 .owner = THIS_MODULE,
489 .dai_link = kabylake_rt5660_dais,
490 .num_links = ARRAY_SIZE(kabylake_rt5660_dais),
491 .controls = kabylake_rt5660_controls,
492 .num_controls = ARRAY_SIZE(kabylake_rt5660_controls),
493 .dapm_widgets = kabylake_rt5660_widgets,
494 .num_dapm_widgets = ARRAY_SIZE(kabylake_rt5660_widgets),
495 .dapm_routes = kabylake_rt5660_map,
496 .num_dapm_routes = ARRAY_SIZE(kabylake_rt5660_map),
497 .fully_routed = true,
498 .late_probe = kabylake_card_late_probe,
499};
500
501static int kabylake_audio_probe(struct platform_device *pdev)
502{
503 struct kbl_codec_private *ctx;
504
505 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
506 if (!ctx)
507 return -ENOMEM;
508
509 INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
510
511 kabylake_audio_card =
512 (struct snd_soc_card *)pdev->id_entry->driver_data;
513
514 kabylake_audio_card->dev = &pdev->dev;
515 snd_soc_card_set_drvdata(kabylake_audio_card, ctx);
516 return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card);
517}
518
519static const struct platform_device_id kbl_board_ids[] = {
520 {
521 .name = "kbl_rt5660",
522 .driver_data =
523 (kernel_ulong_t)&kabylake_audio_card_rt5660,
524 },
525 { }
526};
527
528static struct platform_driver kabylake_audio = {
529 .probe = kabylake_audio_probe,
530 .driver = {
531 .name = "kbl_rt5660",
532 .pm = &snd_soc_pm_ops,
533 },
534 .id_table = kbl_board_ids,
535};
536
537module_platform_driver(kabylake_audio)
538
539/* Module information */
540MODULE_DESCRIPTION("Audio Machine driver-RT5660 in I2S mode");
541MODULE_AUTHOR("Hui Wang <hui.wang@canonical.com>");
542MODULE_LICENSE("GPL v2");
543MODULE_ALIAS("platform:kbl_rt5660");
diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c
index 99e1320c485f..d71475200b08 100644
--- a/sound/soc/intel/boards/kbl_rt5663_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c
@@ -25,9 +25,9 @@
25#include <sound/pcm.h> 25#include <sound/pcm.h>
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <sound/soc-acpi.h>
28#include "../../codecs/rt5663.h" 29#include "../../codecs/rt5663.h"
29#include "../../codecs/hdac_hdmi.h" 30#include "../../codecs/hdac_hdmi.h"
30#include "../skylake/skl.h"
31#include <linux/clk.h> 31#include <linux/clk.h>
32#include <linux/clk-provider.h> 32#include <linux/clk-provider.h>
33#include <linux/clkdev.h> 33#include <linux/clkdev.h>
@@ -586,7 +586,7 @@ static int kabylake_refcap_startup(struct snd_pcm_substream *substream)
586 &constraints_16000); 586 &constraints_16000);
587} 587}
588 588
589static struct snd_soc_ops skylaye_refcap_ops = { 589static struct snd_soc_ops skylake_refcap_ops = {
590 .startup = kabylake_refcap_startup, 590 .startup = kabylake_refcap_startup,
591}; 591};
592 592
@@ -655,7 +655,7 @@ static struct snd_soc_dai_link kabylake_dais[] = {
655 .dpcm_capture = 1, 655 .dpcm_capture = 1,
656 .nonatomic = 1, 656 .nonatomic = 1,
657 .dynamic = 1, 657 .dynamic = 1,
658 .ops = &skylaye_refcap_ops, 658 .ops = &skylake_refcap_ops,
659 }, 659 },
660 [KBL_DPCM_AUDIO_DMIC_CP] = { 660 [KBL_DPCM_AUDIO_DMIC_CP] = {
661 .name = "Kbl Audio DMIC cap", 661 .name = "Kbl Audio DMIC cap",
@@ -969,7 +969,7 @@ static struct snd_soc_card kabylake_audio_card_rt5663 = {
969static int kabylake_audio_probe(struct platform_device *pdev) 969static int kabylake_audio_probe(struct platform_device *pdev)
970{ 970{
971 struct kbl_rt5663_private *ctx; 971 struct kbl_rt5663_private *ctx;
972 struct skl_machine_pdata *pdata; 972 struct snd_soc_acpi_mach *mach;
973 int ret; 973 int ret;
974 974
975 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 975 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
@@ -984,9 +984,9 @@ static int kabylake_audio_probe(struct platform_device *pdev)
984 kabylake_audio_card->dev = &pdev->dev; 984 kabylake_audio_card->dev = &pdev->dev;
985 snd_soc_card_set_drvdata(kabylake_audio_card, ctx); 985 snd_soc_card_set_drvdata(kabylake_audio_card, ctx);
986 986
987 pdata = dev_get_drvdata(&pdev->dev); 987 mach = (&pdev->dev)->platform_data;
988 if (pdata) 988 if (mach)
989 dmic_constraints = pdata->dmic_num == 2 ? 989 dmic_constraints = mach->mach_params.dmic_num == 2 ?
990 &constraints_dmic_2ch : &constraints_dmic_channels; 990 &constraints_dmic_2ch : &constraints_dmic_channels;
991 991
992 ctx->mclk = devm_clk_get(&pdev->dev, "ssp1_mclk"); 992 ctx->mclk = devm_clk_get(&pdev->dev, "ssp1_mclk");
diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
index a737c915d46a..7044d8c2b187 100644
--- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
@@ -26,10 +26,10 @@
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 <sound/soc-acpi.h>
29#include "../../codecs/rt5514.h" 30#include "../../codecs/rt5514.h"
30#include "../../codecs/rt5663.h" 31#include "../../codecs/rt5663.h"
31#include "../../codecs/hdac_hdmi.h" 32#include "../../codecs/hdac_hdmi.h"
32#include "../skylake/skl.h"
33 33
34#define KBL_REALTEK_CODEC_DAI "rt5663-aif" 34#define KBL_REALTEK_CODEC_DAI "rt5663-aif"
35#define KBL_REALTEK_DMIC_CODEC_DAI "rt5514-aif1" 35#define KBL_REALTEK_DMIC_CODEC_DAI "rt5514-aif1"
@@ -648,7 +648,7 @@ static struct snd_soc_card kabylake_audio_card = {
648static int kabylake_audio_probe(struct platform_device *pdev) 648static int kabylake_audio_probe(struct platform_device *pdev)
649{ 649{
650 struct kbl_codec_private *ctx; 650 struct kbl_codec_private *ctx;
651 struct skl_machine_pdata *pdata; 651 struct snd_soc_acpi_mach *mach;
652 652
653 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 653 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
654 if (!ctx) 654 if (!ctx)
@@ -659,9 +659,9 @@ static int kabylake_audio_probe(struct platform_device *pdev)
659 kabylake_audio_card.dev = &pdev->dev; 659 kabylake_audio_card.dev = &pdev->dev;
660 snd_soc_card_set_drvdata(&kabylake_audio_card, ctx); 660 snd_soc_card_set_drvdata(&kabylake_audio_card, ctx);
661 661
662 pdata = dev_get_drvdata(&pdev->dev); 662 mach = (&pdev->dev)->platform_data;
663 if (pdata) 663 if (mach)
664 dmic_constraints = pdata->dmic_num == 2 ? 664 dmic_constraints = mach->mach_params.dmic_num == 2 ?
665 &constraints_dmic_2ch : &constraints_dmic_channels; 665 &constraints_dmic_2ch : &constraints_dmic_channels;
666 666
667 return devm_snd_soc_register_card(&pdev->dev, &kabylake_audio_card); 667 return devm_snd_soc_register_card(&pdev->dev, &kabylake_audio_card);
diff --git a/sound/soc/intel/boards/skl_hda_dsp_generic.c b/sound/soc/intel/boards/skl_hda_dsp_generic.c
index b415dd4c85f5..b9a21e64ead2 100644
--- a/sound/soc/intel/boards/skl_hda_dsp_generic.c
+++ b/sound/soc/intel/boards/skl_hda_dsp_generic.c
@@ -12,8 +12,8 @@
12#include <sound/pcm.h> 12#include <sound/pcm.h>
13#include <sound/pcm_params.h> 13#include <sound/pcm_params.h>
14#include <sound/soc.h> 14#include <sound/soc.h>
15#include <sound/soc-acpi.h>
15#include "../../codecs/hdac_hdmi.h" 16#include "../../codecs/hdac_hdmi.h"
16#include "../skylake/skl.h"
17#include "skl_hda_dsp_common.h" 17#include "skl_hda_dsp_common.h"
18 18
19static const struct snd_soc_dapm_widget skl_hda_widgets[] = { 19static const struct snd_soc_dapm_widget skl_hda_widgets[] = {
@@ -101,17 +101,17 @@ static struct snd_soc_card hda_soc_card = {
101#define IDISP_ROUTE_COUNT (IDISP_DAI_COUNT * 2) 101#define IDISP_ROUTE_COUNT (IDISP_DAI_COUNT * 2)
102#define IDISP_CODEC_MASK 0x4 102#define IDISP_CODEC_MASK 0x4
103 103
104static int skl_hda_fill_card_info(struct skl_machine_pdata *pdata) 104static int skl_hda_fill_card_info(struct snd_soc_acpi_mach_params *mach_params)
105{ 105{
106 struct snd_soc_card *card = &hda_soc_card; 106 struct snd_soc_card *card = &hda_soc_card;
107 struct snd_soc_dai_link *dai_link; 107 struct snd_soc_dai_link *dai_link;
108 u32 codec_count, codec_mask; 108 u32 codec_count, codec_mask;
109 int i, num_links, num_route; 109 int i, num_links, num_route;
110 110
111 codec_mask = pdata->codec_mask; 111 codec_mask = mach_params->codec_mask;
112 codec_count = hweight_long(codec_mask); 112 codec_count = hweight_long(codec_mask);
113 113
114 if (codec_count == 1 && pdata->codec_mask & IDISP_CODEC_MASK) { 114 if (codec_count == 1 && codec_mask & IDISP_CODEC_MASK) {
115 num_links = IDISP_DAI_COUNT; 115 num_links = IDISP_DAI_COUNT;
116 num_route = IDISP_ROUTE_COUNT; 116 num_route = IDISP_ROUTE_COUNT;
117 } else if (codec_count == 2 && codec_mask & IDISP_CODEC_MASK) { 117 } else if (codec_count == 2 && codec_mask & IDISP_CODEC_MASK) {
@@ -127,30 +127,30 @@ static int skl_hda_fill_card_info(struct skl_machine_pdata *pdata)
127 card->num_dapm_routes = num_route; 127 card->num_dapm_routes = num_route;
128 128
129 for_each_card_prelinks(card, i, dai_link) 129 for_each_card_prelinks(card, i, dai_link)
130 dai_link->platform_name = pdata->platform; 130 dai_link->platform_name = mach_params->platform;
131 131
132 return 0; 132 return 0;
133} 133}
134 134
135static int skl_hda_audio_probe(struct platform_device *pdev) 135static int skl_hda_audio_probe(struct platform_device *pdev)
136{ 136{
137 struct skl_machine_pdata *pdata; 137 struct snd_soc_acpi_mach *mach;
138 struct skl_hda_private *ctx; 138 struct skl_hda_private *ctx;
139 int ret; 139 int ret;
140 140
141 dev_dbg(&pdev->dev, "%s: entry\n", __func__); 141 dev_dbg(&pdev->dev, "%s: entry\n", __func__);
142 142
143 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); 143 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
144 if (!ctx) 144 if (!ctx)
145 return -ENOMEM; 145 return -ENOMEM;
146 146
147 INIT_LIST_HEAD(&ctx->hdmi_pcm_list); 147 INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
148 148
149 pdata = dev_get_drvdata(&pdev->dev); 149 mach = (&pdev->dev)->platform_data;
150 if (!pdata) 150 if (!mach)
151 return -EINVAL; 151 return -EINVAL;
152 152
153 ret = skl_hda_fill_card_info(pdata); 153 ret = skl_hda_fill_card_info(&mach->mach_params);
154 if (ret < 0) { 154 if (ret < 0) {
155 dev_err(&pdev->dev, "Unsupported HDAudio/iDisp configuration found\n"); 155 dev_err(&pdev->dev, "Unsupported HDAudio/iDisp configuration found\n");
156 return ret; 156 return ret;
@@ -158,7 +158,7 @@ static int skl_hda_audio_probe(struct platform_device *pdev)
158 158
159 ctx->pcm_count = hda_soc_card.num_links; 159 ctx->pcm_count = hda_soc_card.num_links;
160 ctx->dai_index = 1; /* hdmi codec dai name starts from index 1 */ 160 ctx->dai_index = 1; /* hdmi codec dai name starts from index 1 */
161 ctx->platform_name = pdata->platform; 161 ctx->platform_name = mach->mach_params.platform;
162 162
163 hda_soc_card.dev = &pdev->dev; 163 hda_soc_card.dev = &pdev->dev;
164 snd_soc_card_set_drvdata(&hda_soc_card, ctx); 164 snd_soc_card_set_drvdata(&hda_soc_card, ctx);
diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
index d31482b8c9bb..0922106bd323 100644
--- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
+++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
@@ -21,9 +21,9 @@
21#include <sound/pcm.h> 21#include <sound/pcm.h>
22#include <sound/pcm_params.h> 22#include <sound/pcm_params.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/soc-acpi.h>
24#include "../../codecs/nau8825.h" 25#include "../../codecs/nau8825.h"
25#include "../../codecs/hdac_hdmi.h" 26#include "../../codecs/hdac_hdmi.h"
26#include "../skylake/skl.h"
27 27
28#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi" 28#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi"
29#define SKL_MAXIM_CODEC_DAI "HiFi" 29#define SKL_MAXIM_CODEC_DAI "HiFi"
@@ -400,7 +400,7 @@ static int skylake_refcap_startup(struct snd_pcm_substream *substream)
400 &constraints_16000); 400 &constraints_16000);
401} 401}
402 402
403static const struct snd_soc_ops skylaye_refcap_ops = { 403static const struct snd_soc_ops skylake_refcap_ops = {
404 .startup = skylake_refcap_startup, 404 .startup = skylake_refcap_startup,
405}; 405};
406 406
@@ -447,7 +447,7 @@ static struct snd_soc_dai_link skylake_dais[] = {
447 .dpcm_capture = 1, 447 .dpcm_capture = 1,
448 .nonatomic = 1, 448 .nonatomic = 1,
449 .dynamic = 1, 449 .dynamic = 1,
450 .ops = &skylaye_refcap_ops, 450 .ops = &skylake_refcap_ops,
451 }, 451 },
452 [SKL_DPCM_AUDIO_DMIC_CP] = { 452 [SKL_DPCM_AUDIO_DMIC_CP] = {
453 .name = "Skl Audio DMIC cap", 453 .name = "Skl Audio DMIC cap",
@@ -641,7 +641,7 @@ static struct snd_soc_card skylake_audio_card = {
641static int skylake_audio_probe(struct platform_device *pdev) 641static int skylake_audio_probe(struct platform_device *pdev)
642{ 642{
643 struct skl_nau8825_private *ctx; 643 struct skl_nau8825_private *ctx;
644 struct skl_machine_pdata *pdata; 644 struct snd_soc_acpi_mach *mach;
645 645
646 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 646 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
647 if (!ctx) 647 if (!ctx)
@@ -652,9 +652,9 @@ static int skylake_audio_probe(struct platform_device *pdev)
652 skylake_audio_card.dev = &pdev->dev; 652 skylake_audio_card.dev = &pdev->dev;
653 snd_soc_card_set_drvdata(&skylake_audio_card, ctx); 653 snd_soc_card_set_drvdata(&skylake_audio_card, ctx);
654 654
655 pdata = dev_get_drvdata(&pdev->dev); 655 mach = (&pdev->dev)->platform_data;
656 if (pdata) 656 if (mach)
657 dmic_constraints = pdata->dmic_num == 2 ? 657 dmic_constraints = mach->mach_params.dmic_num == 2 ?
658 &constraints_dmic_2ch : &constraints_dmic_channels; 658 &constraints_dmic_2ch : &constraints_dmic_channels;
659 659
660 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card); 660 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card);
diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
index e877bb60beb1..8433c521d39f 100644
--- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
+++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
@@ -23,11 +23,11 @@
23#include <sound/core.h> 23#include <sound/core.h>
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-acpi.h>
26#include <sound/jack.h> 27#include <sound/jack.h>
27#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
28#include "../../codecs/nau8825.h" 29#include "../../codecs/nau8825.h"
29#include "../../codecs/hdac_hdmi.h" 30#include "../../codecs/hdac_hdmi.h"
30#include "../skylake/skl.h"
31 31
32#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi" 32#define SKL_NUVOTON_CODEC_DAI "nau8825-hifi"
33#define SKL_SSM_CODEC_DAI "ssm4567-hifi" 33#define SKL_SSM_CODEC_DAI "ssm4567-hifi"
@@ -449,7 +449,7 @@ static int skylake_refcap_startup(struct snd_pcm_substream *substream)
449 &constraints_16000); 449 &constraints_16000);
450} 450}
451 451
452static const struct snd_soc_ops skylaye_refcap_ops = { 452static const struct snd_soc_ops skylake_refcap_ops = {
453 .startup = skylake_refcap_startup, 453 .startup = skylake_refcap_startup,
454}; 454};
455 455
@@ -496,7 +496,7 @@ static struct snd_soc_dai_link skylake_dais[] = {
496 .dpcm_capture = 1, 496 .dpcm_capture = 1,
497 .nonatomic = 1, 497 .nonatomic = 1,
498 .dynamic = 1, 498 .dynamic = 1,
499 .ops = &skylaye_refcap_ops, 499 .ops = &skylake_refcap_ops,
500 }, 500 },
501 [SKL_DPCM_AUDIO_DMIC_CP] = { 501 [SKL_DPCM_AUDIO_DMIC_CP] = {
502 .name = "Skl Audio DMIC cap", 502 .name = "Skl Audio DMIC cap",
@@ -694,7 +694,7 @@ static struct snd_soc_card skylake_audio_card = {
694static int skylake_audio_probe(struct platform_device *pdev) 694static int skylake_audio_probe(struct platform_device *pdev)
695{ 695{
696 struct skl_nau88125_private *ctx; 696 struct skl_nau88125_private *ctx;
697 struct skl_machine_pdata *pdata; 697 struct snd_soc_acpi_mach *mach;
698 698
699 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 699 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
700 if (!ctx) 700 if (!ctx)
@@ -705,9 +705,9 @@ static int skylake_audio_probe(struct platform_device *pdev)
705 skylake_audio_card.dev = &pdev->dev; 705 skylake_audio_card.dev = &pdev->dev;
706 snd_soc_card_set_drvdata(&skylake_audio_card, ctx); 706 snd_soc_card_set_drvdata(&skylake_audio_card, ctx);
707 707
708 pdata = dev_get_drvdata(&pdev->dev); 708 mach = (&pdev->dev)->platform_data;
709 if (pdata) 709 if (mach)
710 dmic_constraints = pdata->dmic_num == 2 ? 710 dmic_constraints = mach->mach_params.dmic_num == 2 ?
711 &constraints_dmic_2ch : &constraints_dmic_channels; 711 &constraints_dmic_2ch : &constraints_dmic_channels;
712 712
713 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card); 713 return devm_snd_soc_register_card(&pdev->dev, &skylake_audio_card);
diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile
index c1f50a079d34..56c81e20b5bf 100644
--- a/sound/soc/intel/common/Makefile
+++ b/sound/soc/intel/common/Makefile
@@ -7,7 +7,7 @@ snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-m
7 soc-acpi-intel-hsw-bdw-match.o \ 7 soc-acpi-intel-hsw-bdw-match.o \
8 soc-acpi-intel-skl-match.o soc-acpi-intel-kbl-match.o \ 8 soc-acpi-intel-skl-match.o soc-acpi-intel-kbl-match.o \
9 soc-acpi-intel-bxt-match.o soc-acpi-intel-glk-match.o \ 9 soc-acpi-intel-bxt-match.o soc-acpi-intel-glk-match.o \
10 soc-acpi-intel-cnl-match.o \ 10 soc-acpi-intel-cnl-match.o soc-acpi-intel-icl-match.o \
11 soc-acpi-intel-hda-match.o 11 soc-acpi-intel-hda-match.o
12 12
13obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o 13obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o
diff --git a/sound/soc/intel/common/soc-acpi-intel-bxt-match.c b/sound/soc/intel/common/soc-acpi-intel-bxt-match.c
index f39386e540d3..61dedc103b19 100644
--- a/sound/soc/intel/common/soc-acpi-intel-bxt-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-bxt-match.c
@@ -6,9 +6,41 @@
6 * 6 *
7 */ 7 */
8 8
9#include <linux/dmi.h>
9#include <sound/soc-acpi.h> 10#include <sound/soc-acpi.h>
10#include <sound/soc-acpi-intel-match.h> 11#include <sound/soc-acpi-intel-match.h>
11 12
13enum {
14 APL_RVP,
15};
16
17static const struct dmi_system_id apl_table[] = {
18 {
19 .matches = {
20 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
21 DMI_MATCH(DMI_BOARD_NAME, "Apollolake RVP1A"),
22 },
23 .driver_data = (void *)(APL_RVP),
24 },
25 {}
26};
27
28static struct snd_soc_acpi_mach *apl_quirk(void *arg)
29{
30 struct snd_soc_acpi_mach *mach = arg;
31 const struct dmi_system_id *dmi_id;
32 unsigned long apl_machine_id;
33
34 dmi_id = dmi_first_match(apl_table);
35 if (dmi_id) {
36 apl_machine_id = (unsigned long)dmi_id->driver_data;
37 if (apl_machine_id == APL_RVP)
38 return NULL;
39 }
40
41 return mach;
42}
43
12static struct snd_soc_acpi_codecs bxt_codecs = { 44static struct snd_soc_acpi_codecs bxt_codecs = {
13 .num_codecs = 1, 45 .num_codecs = 1,
14 .codecs = {"MX98357A"} 46 .codecs = {"MX98357A"}
@@ -19,6 +51,9 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_bxt_machines[] = {
19 .id = "INT343A", 51 .id = "INT343A",
20 .drv_name = "bxt_alc298s_i2s", 52 .drv_name = "bxt_alc298s_i2s",
21 .fw_filename = "intel/dsp_fw_bxtn.bin", 53 .fw_filename = "intel/dsp_fw_bxtn.bin",
54 .sof_fw_filename = "intel/sof-apl.ri",
55 .sof_tplg_filename = "intel/sof-apl-rt298.tplg",
56 .asoc_plat_name = "0000:00:0e.0",
22 }, 57 },
23 { 58 {
24 .id = "DLGS7219", 59 .id = "DLGS7219",
@@ -47,6 +82,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_bxt_machines[] = {
47 { 82 {
48 .id = "INT34C3", 83 .id = "INT34C3",
49 .drv_name = "bxt_tdf8532", 84 .drv_name = "bxt_tdf8532",
85 .machine_quirk = apl_quirk,
50 .sof_fw_filename = "intel/sof-apl.ri", 86 .sof_fw_filename = "intel/sof-apl.ri",
51 .sof_tplg_filename = "intel/sof-apl-tdf8532.tplg", 87 .sof_tplg_filename = "intel/sof-apl-tdf8532.tplg",
52 .asoc_plat_name = "0000:00:0e.0", 88 .asoc_plat_name = "0000:00:0e.0",
diff --git a/sound/soc/intel/common/soc-acpi-intel-icl-match.c b/sound/soc/intel/common/soc-acpi-intel-icl-match.c
new file mode 100644
index 000000000000..33b441dca4d3
--- /dev/null
+++ b/sound/soc/intel/common/soc-acpi-intel-icl-match.c
@@ -0,0 +1,32 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * soc-apci-intel-icl-match.c - tables and support for ICL ACPI enumeration.
4 *
5 * Copyright (c) 2018, Intel Corporation.
6 *
7 */
8
9#include <sound/soc-acpi.h>
10#include <sound/soc-acpi-intel-match.h>
11#include "../skylake/skl.h"
12
13static struct skl_machine_pdata icl_pdata = {
14 .use_tplg_pcm = true,
15};
16
17struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[] = {
18 {
19 .id = "INT34C2",
20 .drv_name = "icl_rt274",
21 .fw_filename = "intel/dsp_fw_icl.bin",
22 .pdata = &icl_pdata,
23 .sof_fw_filename = "intel/sof-icl.ri",
24 .sof_tplg_filename = "intel/sof-icl-rt274.tplg",
25 .asoc_plat_name = "0000:00:1f.3",
26 },
27 {},
28};
29EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_machines);
30
31MODULE_LICENSE("GPL v2");
32MODULE_DESCRIPTION("Intel Common ACPI Match module");
diff --git a/sound/soc/intel/common/soc-acpi-intel-kbl-match.c b/sound/soc/intel/common/soc-acpi-intel-kbl-match.c
index a317b7790fce..e6fa6f470526 100644
--- a/sound/soc/intel/common/soc-acpi-intel-kbl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-kbl-match.c
@@ -96,6 +96,16 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_kbl_machines[] = {
96 .quirk_data = &kbl_7219_98927_codecs, 96 .quirk_data = &kbl_7219_98927_codecs,
97 .pdata = &skl_dmic_data 97 .pdata = &skl_dmic_data
98 }, 98 },
99 {
100 .id = "10EC5660",
101 .drv_name = "kbl_rt5660",
102 .fw_filename = "intel/dsp_fw_kbl.bin",
103 },
104 {
105 .id = "10EC3277",
106 .drv_name = "kbl_rt5660",
107 .fw_filename = "intel/dsp_fw_kbl.bin",
108 },
99 {}, 109 {},
100}; 110};
101EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_kbl_machines); 111EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_kbl_machines);
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 8bfb8b0fa3d5..b0e6fb93eaf8 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -247,6 +247,14 @@ static const struct skl_dsp_ops dsp_ops[] = {
247 .init_fw = cnl_sst_init_fw, 247 .init_fw = cnl_sst_init_fw,
248 .cleanup = cnl_sst_dsp_cleanup 248 .cleanup = cnl_sst_dsp_cleanup
249 }, 249 },
250 {
251 .id = 0xa348,
252 .num_cores = 4,
253 .loader_ops = bxt_get_loader_ops,
254 .init = cnl_sst_dsp_init,
255 .init_fw = cnl_sst_init_fw,
256 .cleanup = cnl_sst_dsp_cleanup
257 },
250}; 258};
251 259
252const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id) 260const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id)
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
index 01a050cf8775..5d125a3df527 100644
--- a/sound/soc/intel/skylake/skl-nhlt.c
+++ b/sound/soc/intel/skylake/skl-nhlt.c
@@ -180,6 +180,9 @@ int skl_get_dmic_geo(struct skl *skl)
180 unsigned int dmic_geo = 0; 180 unsigned int dmic_geo = 0;
181 u8 j; 181 u8 j;
182 182
183 if (!nhlt)
184 return 0;
185
183 epnt = (struct nhlt_endpoint *)nhlt->desc; 186 epnt = (struct nhlt_endpoint *)nhlt->desc;
184 187
185 for (j = 0; j < nhlt->endpoint_count; j++) { 188 for (j = 0; j < nhlt->endpoint_count; j++) {
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
index 5234fafb758a..9f3ce73593ae 100644
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
@@ -249,6 +249,8 @@ enum skl_ipc_glb_reply {
249 IPC_GLB_REPLY_INVALID_CONFIG_DATA_LEN = 121, 249 IPC_GLB_REPLY_INVALID_CONFIG_DATA_LEN = 121,
250 IPC_GLB_REPLY_GATEWAY_NOT_INITIALIZED = 140, 250 IPC_GLB_REPLY_GATEWAY_NOT_INITIALIZED = 140,
251 IPC_GLB_REPLY_GATEWAY_NOT_EXIST = 141, 251 IPC_GLB_REPLY_GATEWAY_NOT_EXIST = 141,
252 IPC_GLB_REPLY_SCLK_ALREADY_RUNNING = 150,
253 IPC_GLB_REPLY_MCLK_ALREADY_RUNNING = 151,
252 254
253 IPC_GLB_REPLY_PPL_NOT_INITIALIZED = 160, 255 IPC_GLB_REPLY_PPL_NOT_INITIALIZED = 160,
254 IPC_GLB_REPLY_PPL_NOT_EXIST = 161, 256 IPC_GLB_REPLY_PPL_NOT_EXIST = 161,
@@ -392,18 +394,47 @@ int skl_ipc_process_notification(struct sst_generic_ipc *ipc,
392 return 0; 394 return 0;
393} 395}
394 396
395static int skl_ipc_set_reply_error_code(u32 reply) 397struct skl_ipc_err_map {
398 const char *msg;
399 enum skl_ipc_glb_reply reply;
400 int err;
401};
402
403static struct skl_ipc_err_map skl_err_map[] = {
404 {"DSP out of memory", IPC_GLB_REPLY_OUT_OF_MEMORY, -ENOMEM},
405 {"DSP busy", IPC_GLB_REPLY_BUSY, -EBUSY},
406 {"SCLK already running", IPC_GLB_REPLY_SCLK_ALREADY_RUNNING,
407 IPC_GLB_REPLY_SCLK_ALREADY_RUNNING},
408 {"MCLK already running", IPC_GLB_REPLY_MCLK_ALREADY_RUNNING,
409 IPC_GLB_REPLY_MCLK_ALREADY_RUNNING},
410};
411
412static int skl_ipc_set_reply_error_code(struct sst_generic_ipc *ipc, u32 reply)
396{ 413{
397 switch (reply) { 414 int i;
398 case IPC_GLB_REPLY_OUT_OF_MEMORY:
399 return -ENOMEM;
400 415
401 case IPC_GLB_REPLY_BUSY: 416 for (i = 0; i < ARRAY_SIZE(skl_err_map); i++) {
402 return -EBUSY; 417 if (skl_err_map[i].reply == reply)
418 break;
419 }
403 420
404 default: 421 if (i == ARRAY_SIZE(skl_err_map)) {
422 dev_err(ipc->dev, "ipc FW reply: %d FW Error Code: %u\n",
423 reply,
424 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
405 return -EINVAL; 425 return -EINVAL;
406 } 426 }
427
428 if (skl_err_map[i].err < 0)
429 dev_err(ipc->dev, "ipc FW reply: %s FW Error Code: %u\n",
430 skl_err_map[i].msg,
431 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
432 else
433 dev_info(ipc->dev, "ipc FW reply: %s FW Error Code: %u\n",
434 skl_err_map[i].msg,
435 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
436
437 return skl_err_map[i].err;
407} 438}
408 439
409void skl_ipc_process_reply(struct sst_generic_ipc *ipc, 440void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
@@ -441,10 +472,7 @@ void skl_ipc_process_reply(struct sst_generic_ipc *ipc,
441 472
442 } 473 }
443 } else { 474 } else {
444 msg->errno = skl_ipc_set_reply_error_code(reply); 475 msg->errno = skl_ipc_set_reply_error_code(ipc, reply);
445 dev_err(ipc->dev, "ipc FW reply: reply=%d\n", reply);
446 dev_err(ipc->dev, "FW Error Code: %u\n",
447 ipc->dsp->fw_ops.get_fw_errcode(ipc->dsp));
448 switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) { 476 switch (IPC_GLB_NOTIFY_MSG_TYPE(header.primary)) {
449 case IPC_GLB_LOAD_MULTIPLE_MODS: 477 case IPC_GLB_LOAD_MULTIPLE_MODS:
450 case IPC_GLB_LOAD_LIBRARY: 478 case IPC_GLB_LOAD_LIBRARY:
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
index 5c224a0e1c7a..29d9b0eb83ea 100644
--- a/sound/soc/intel/skylake/skl.c
+++ b/sound/soc/intel/skylake/skl.c
@@ -507,7 +507,7 @@ static int skl_find_machine(struct skl *skl, void *driver_data)
507 507
508 if (pdata) { 508 if (pdata) {
509 skl->use_tplg_pcm = pdata->use_tplg_pcm; 509 skl->use_tplg_pcm = pdata->use_tplg_pcm;
510 pdata->dmic_num = skl_get_dmic_geo(skl); 510 mach->mach_params.dmic_num = skl_get_dmic_geo(skl);
511 } 511 }
512 512
513 return 0; 513 return 0;
@@ -517,7 +517,6 @@ static int skl_machine_device_register(struct skl *skl)
517{ 517{
518 struct snd_soc_acpi_mach *mach = skl->mach; 518 struct snd_soc_acpi_mach *mach = skl->mach;
519 struct hdac_bus *bus = skl_to_bus(skl); 519 struct hdac_bus *bus = skl_to_bus(skl);
520 struct skl_machine_pdata *pdata;
521 struct platform_device *pdev; 520 struct platform_device *pdev;
522 int ret; 521 int ret;
523 522
@@ -527,6 +526,16 @@ static int skl_machine_device_register(struct skl *skl)
527 return -EIO; 526 return -EIO;
528 } 527 }
529 528
529 mach->mach_params.platform = dev_name(bus->dev);
530 mach->mach_params.codec_mask = bus->codec_mask;
531
532 ret = platform_device_add_data(pdev, (const void *)mach, sizeof(*mach));
533 if (ret) {
534 dev_err(bus->dev, "failed to add machine device platform data\n");
535 platform_device_put(pdev);
536 return ret;
537 }
538
530 ret = platform_device_add(pdev); 539 ret = platform_device_add(pdev);
531 if (ret) { 540 if (ret) {
532 dev_err(bus->dev, "failed to add machine device\n"); 541 dev_err(bus->dev, "failed to add machine device\n");
@@ -534,12 +543,6 @@ static int skl_machine_device_register(struct skl *skl)
534 return -EIO; 543 return -EIO;
535 } 544 }
536 545
537 if (mach->pdata) {
538 pdata = (struct skl_machine_pdata *)mach->pdata;
539 pdata->platform = dev_name(bus->dev);
540 pdata->codec_mask = bus->codec_mask;
541 dev_set_drvdata(&pdev->dev, mach->pdata);
542 }
543 546
544 skl->i2s_dev = pdev; 547 skl->i2s_dev = pdev;
545 548
@@ -811,12 +814,10 @@ static void skl_probe_work(struct work_struct *work)
811 return; 814 return;
812 } 815 }
813 816
814 if (bus->ppcap) { 817 err = skl_machine_device_register(skl);
815 err = skl_machine_device_register(skl); 818 if (err < 0) {
816 if (err < 0) { 819 dev_err(bus->dev, "machine register failed: %d\n", err);
817 dev_err(bus->dev, "machine register failed: %d\n", err); 820 goto out_err;
818 goto out_err;
819 }
820 } 821 }
821 822
822 /* 823 /*
@@ -895,6 +896,21 @@ static int skl_first_init(struct hdac_bus *bus)
895 unsigned short gcap; 896 unsigned short gcap;
896 int cp_streams, pb_streams, start_idx; 897 int cp_streams, pb_streams, start_idx;
897 898
899 /*
900 * detect DSP by checking class/subclass/prog-id information
901 * class=04 subclass 03 prog-if 00: no DSP, legacy driver needs to be used
902 * class=04 subclass 01 prog-if 00: DSP is present (and may be required e.g. for DMIC or SSP support)
903 * class=04 subclass 03 prog-if 80: either of DSP or legacy mode can be used
904 */
905 if (pci->class == 0x040300) {
906 dev_err(bus->dev, "The DSP is not enabled on this platform, aborting probe\n");
907 return -ENODEV;
908 } else if (pci->class != 0x040100 && pci->class != 0x040380) {
909 dev_err(bus->dev, "Unknown PCI class/subclass/prog-if information (0x%06x) found, aborting probe\n", pci->class);
910 return -ENODEV;
911 }
912 dev_info(bus->dev, "DSP detected with PCI class/subclass/prog-if info 0x%06x\n", pci->class);
913
898 err = pci_request_regions(pci, "Skylake HD audio"); 914 err = pci_request_regions(pci, "Skylake HD audio");
899 if (err < 0) 915 if (err < 0)
900 return err; 916 return err;
@@ -910,6 +926,12 @@ static int skl_first_init(struct hdac_bus *bus)
910 926
911 snd_hdac_bus_parse_capabilities(bus); 927 snd_hdac_bus_parse_capabilities(bus);
912 928
929 /* check if PPCAP exists */
930 if (!bus->ppcap) {
931 dev_err(bus->dev, "bus ppcap not set, HDaudio or DSP not present?\n");
932 return -ENODEV;
933 }
934
913 if (skl_acquire_irq(bus, 0) < 0) 935 if (skl_acquire_irq(bus, 0) < 0)
914 return -EBUSY; 936 return -EBUSY;
915 937
@@ -919,23 +941,25 @@ static int skl_first_init(struct hdac_bus *bus)
919 gcap = snd_hdac_chip_readw(bus, GCAP); 941 gcap = snd_hdac_chip_readw(bus, GCAP);
920 dev_dbg(bus->dev, "chipset global capabilities = 0x%x\n", gcap); 942 dev_dbg(bus->dev, "chipset global capabilities = 0x%x\n", gcap);
921 943
922 /* allow 64bit DMA address if supported by H/W */
923 if (!dma_set_mask(bus->dev, DMA_BIT_MASK(64))) {
924 dma_set_coherent_mask(bus->dev, DMA_BIT_MASK(64));
925 } else {
926 dma_set_mask(bus->dev, DMA_BIT_MASK(32));
927 dma_set_coherent_mask(bus->dev, DMA_BIT_MASK(32));
928 }
929
930 /* read number of streams from GCAP register */ 944 /* read number of streams from GCAP register */
931 cp_streams = (gcap >> 8) & 0x0f; 945 cp_streams = (gcap >> 8) & 0x0f;
932 pb_streams = (gcap >> 12) & 0x0f; 946 pb_streams = (gcap >> 12) & 0x0f;
933 947
934 if (!pb_streams && !cp_streams) 948 if (!pb_streams && !cp_streams) {
949 dev_err(bus->dev, "no streams found in GCAP definitions?\n");
935 return -EIO; 950 return -EIO;
951 }
936 952
937 bus->num_streams = cp_streams + pb_streams; 953 bus->num_streams = cp_streams + pb_streams;
938 954
955 /* allow 64bit DMA address if supported by H/W */
956 if (!dma_set_mask(bus->dev, DMA_BIT_MASK(64))) {
957 dma_set_coherent_mask(bus->dev, DMA_BIT_MASK(64));
958 } else {
959 dma_set_mask(bus->dev, DMA_BIT_MASK(32));
960 dma_set_coherent_mask(bus->dev, DMA_BIT_MASK(32));
961 }
962
939 /* initialize streams */ 963 /* initialize streams */
940 snd_hdac_ext_stream_init_all 964 snd_hdac_ext_stream_init_all
941 (bus, 0, cp_streams, SNDRV_PCM_STREAM_CAPTURE); 965 (bus, 0, cp_streams, SNDRV_PCM_STREAM_CAPTURE);
@@ -968,8 +992,10 @@ static int skl_probe(struct pci_dev *pci,
968 bus = skl_to_bus(skl); 992 bus = skl_to_bus(skl);
969 993
970 err = skl_first_init(bus); 994 err = skl_first_init(bus);
971 if (err < 0) 995 if (err < 0) {
996 dev_err(bus->dev, "skl_first_init failed with err: %d\n", err);
972 goto out_free; 997 goto out_free;
998 }
973 999
974 skl->pci_id = pci->device; 1000 skl->pci_id = pci->device;
975 1001
@@ -978,37 +1004,48 @@ static int skl_probe(struct pci_dev *pci,
978 skl->nhlt = skl_nhlt_init(bus->dev); 1004 skl->nhlt = skl_nhlt_init(bus->dev);
979 1005
980 if (skl->nhlt == NULL) { 1006 if (skl->nhlt == NULL) {
1007#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC)
1008 dev_err(bus->dev, "no nhlt info found\n");
981 err = -ENODEV; 1009 err = -ENODEV;
982 goto out_free; 1010 goto out_free;
983 } 1011#else
984 1012 dev_warn(bus->dev, "no nhlt info found, continuing to try to enable HDaudio codec\n");
985 err = skl_nhlt_create_sysfs(skl); 1013#endif
986 if (err < 0) 1014 } else {
987 goto out_nhlt_free;
988 1015
989 skl_nhlt_update_topology_bin(skl); 1016 err = skl_nhlt_create_sysfs(skl);
1017 if (err < 0) {
1018 dev_err(bus->dev, "skl_nhlt_create_sysfs failed with err: %d\n", err);
1019 goto out_nhlt_free;
1020 }
990 1021
991 pci_set_drvdata(skl->pci, bus); 1022 skl_nhlt_update_topology_bin(skl);
992 1023
993 /* check if dsp is there */
994 if (bus->ppcap) {
995 /* create device for dsp clk */ 1024 /* create device for dsp clk */
996 err = skl_clock_device_register(skl); 1025 err = skl_clock_device_register(skl);
997 if (err < 0) 1026 if (err < 0) {
1027 dev_err(bus->dev, "skl_clock_device_register failed with err: %d\n", err);
998 goto out_clk_free; 1028 goto out_clk_free;
1029 }
1030 }
999 1031
1000 err = skl_find_machine(skl, (void *)pci_id->driver_data); 1032 pci_set_drvdata(skl->pci, bus);
1001 if (err < 0)
1002 goto out_nhlt_free;
1003 1033
1004 err = skl_init_dsp(skl); 1034
1005 if (err < 0) { 1035 err = skl_find_machine(skl, (void *)pci_id->driver_data);
1006 dev_dbg(bus->dev, "error failed to register dsp\n"); 1036 if (err < 0) {
1007 goto out_nhlt_free; 1037 dev_err(bus->dev, "skl_find_machine failed with err: %d\n", err);
1008 } 1038 goto out_nhlt_free;
1009 skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge; 1039 }
1010 skl->skl_sst->clock_power_gating = skl_clock_power_gating; 1040
1041 err = skl_init_dsp(skl);
1042 if (err < 0) {
1043 dev_dbg(bus->dev, "error failed to register dsp\n");
1044 goto out_nhlt_free;
1011 } 1045 }
1046 skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge;
1047 skl->skl_sst->clock_power_gating = skl_clock_power_gating;
1048
1012 if (bus->mlcap) 1049 if (bus->mlcap)
1013 snd_hdac_ext_bus_get_ml_capabilities(bus); 1050 snd_hdac_ext_bus_get_ml_capabilities(bus);
1014 1051
@@ -1016,8 +1053,10 @@ static int skl_probe(struct pci_dev *pci,
1016 1053
1017 /* create device for soc dmic */ 1054 /* create device for soc dmic */
1018 err = skl_dmic_device_register(skl); 1055 err = skl_dmic_device_register(skl);
1019 if (err < 0) 1056 if (err < 0) {
1057 dev_err(bus->dev, "skl_dmic_device_register failed with err: %d\n", err);
1020 goto out_dsp_free; 1058 goto out_dsp_free;
1059 }
1021 1060
1022 schedule_work(&skl->probe_work); 1061 schedule_work(&skl->probe_work);
1023 1062
@@ -1085,21 +1124,36 @@ static void skl_remove(struct pci_dev *pci)
1085 1124
1086/* PCI IDs */ 1125/* PCI IDs */
1087static const struct pci_device_id skl_ids[] = { 1126static const struct pci_device_id skl_ids[] = {
1127#if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKL)
1088 /* Sunrise Point-LP */ 1128 /* Sunrise Point-LP */
1089 { PCI_DEVICE(0x8086, 0x9d70), 1129 { PCI_DEVICE(0x8086, 0x9d70),
1090 .driver_data = (unsigned long)&snd_soc_acpi_intel_skl_machines}, 1130 .driver_data = (unsigned long)&snd_soc_acpi_intel_skl_machines},
1131#endif
1132#if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL)
1091 /* BXT-P */ 1133 /* BXT-P */
1092 { PCI_DEVICE(0x8086, 0x5a98), 1134 { PCI_DEVICE(0x8086, 0x5a98),
1093 .driver_data = (unsigned long)&snd_soc_acpi_intel_bxt_machines}, 1135 .driver_data = (unsigned long)&snd_soc_acpi_intel_bxt_machines},
1136#endif
1137#if IS_ENABLED(CONFIG_SND_SOC_INTEL_KBL)
1094 /* KBL */ 1138 /* KBL */
1095 { PCI_DEVICE(0x8086, 0x9D71), 1139 { PCI_DEVICE(0x8086, 0x9D71),
1096 .driver_data = (unsigned long)&snd_soc_acpi_intel_kbl_machines}, 1140 .driver_data = (unsigned long)&snd_soc_acpi_intel_kbl_machines},
1141#endif
1142#if IS_ENABLED(CONFIG_SND_SOC_INTEL_GLK)
1097 /* GLK */ 1143 /* GLK */
1098 { PCI_DEVICE(0x8086, 0x3198), 1144 { PCI_DEVICE(0x8086, 0x3198),
1099 .driver_data = (unsigned long)&snd_soc_acpi_intel_glk_machines}, 1145 .driver_data = (unsigned long)&snd_soc_acpi_intel_glk_machines},
1146#endif
1147#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CNL)
1100 /* CNL */ 1148 /* CNL */
1101 { PCI_DEVICE(0x8086, 0x9dc8), 1149 { PCI_DEVICE(0x8086, 0x9dc8),
1102 .driver_data = (unsigned long)&snd_soc_acpi_intel_cnl_machines}, 1150 .driver_data = (unsigned long)&snd_soc_acpi_intel_cnl_machines},
1151#endif
1152#if IS_ENABLED(CONFIG_SND_SOC_INTEL_CFL)
1153 /* CFL */
1154 { PCI_DEVICE(0x8086, 0xa348),
1155 .driver_data = (unsigned long)&snd_soc_acpi_intel_cnl_machines},
1156#endif
1103 { 0, } 1157 { 0, }
1104}; 1158};
1105MODULE_DEVICE_TABLE(pci, skl_ids); 1159MODULE_DEVICE_TABLE(pci, skl_ids);
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index 8d48cd7c56c8..85f8bb6687dc 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -119,10 +119,7 @@ struct skl_dma_params {
119}; 119};
120 120
121struct skl_machine_pdata { 121struct skl_machine_pdata {
122 u32 dmic_num;
123 bool use_tplg_pcm; /* use dais and dai links from topology */ 122 bool use_tplg_pcm; /* use dais and dai links from topology */
124 const char *platform;
125 u32 codec_mask;
126}; 123};
127 124
128struct skl_dsp_ops { 125struct skl_dsp_ops {
diff --git a/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c b/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c
index 192f4d7b37b6..bff7d71d0742 100644
--- a/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c
+++ b/sound/soc/mediatek/mt6797/mt6797-afe-pcm.c
@@ -828,7 +828,7 @@ static int mt6797_afe_pcm_dev_probe(struct platform_device *pdev)
828 /* request irq */ 828 /* request irq */
829 irq_id = platform_get_irq(pdev, 0); 829 irq_id = platform_get_irq(pdev, 0);
830 if (!irq_id) { 830 if (!irq_id) {
831 dev_err(dev, "%s no irq found\n", dev->of_node->name); 831 dev_err(dev, "%pOFn no irq found\n", dev->of_node);
832 return -ENXIO; 832 return -ENXIO;
833 } 833 }
834 ret = devm_request_irq(dev, irq_id, mt6797_afe_irq_handler, 834 ret = devm_request_irq(dev, irq_id, mt6797_afe_irq_handler,
diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
index c0b6697503fd..166aed28330d 100644
--- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
+++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
@@ -1092,7 +1092,7 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
1092 1092
1093 irq_id = platform_get_irq(pdev, 0); 1093 irq_id = platform_get_irq(pdev, 0);
1094 if (irq_id <= 0) { 1094 if (irq_id <= 0) {
1095 dev_err(afe->dev, "np %s no irq\n", afe->dev->of_node->name); 1095 dev_err(afe->dev, "np %pOFn no irq\n", afe->dev->of_node);
1096 return irq_id < 0 ? irq_id : -ENXIO; 1096 return irq_id < 0 ? irq_id : -ENXIO;
1097 } 1097 }
1098 ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler, 1098 ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler,
diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig
index 8b8426ed2363..8779fe23671d 100644
--- a/sound/soc/meson/Kconfig
+++ b/sound/soc/meson/Kconfig
@@ -54,6 +54,7 @@ config SND_MESON_AXG_SOUND_CARD
54 imply SND_MESON_AXG_TDMIN 54 imply SND_MESON_AXG_TDMIN
55 imply SND_MESON_AXG_TDMOUT 55 imply SND_MESON_AXG_TDMOUT
56 imply SND_MESON_AXG_SPDIFOUT 56 imply SND_MESON_AXG_SPDIFOUT
57 imply SND_MESON_AXG_SPDIFIN
57 imply SND_MESON_AXG_PDM 58 imply SND_MESON_AXG_PDM
58 help 59 help
59 Select Y or M to add support for the AXG SoC sound card 60 Select Y or M to add support for the AXG SoC sound card
@@ -67,6 +68,13 @@ config SND_MESON_AXG_SPDIFOUT
67 Select Y or M to add support for SPDIF output serializer embedded 68 Select Y or M to add support for SPDIF output serializer embedded
68 in the Amlogic AXG SoC family 69 in the Amlogic AXG SoC family
69 70
71config SND_MESON_AXG_SPDIFIN
72 tristate "Amlogic AXG SPDIF Input Support"
73 imply SND_SOC_SPDIF
74 help
75 Select Y or M to add support for SPDIF input embedded
76 in the Amlogic AXG SoC family
77
70config SND_MESON_AXG_PDM 78config SND_MESON_AXG_PDM
71 tristate "Amlogic AXG PDM Input Support" 79 tristate "Amlogic AXG PDM Input Support"
72 imply SND_SOC_DMIC 80 imply SND_SOC_DMIC
@@ -74,5 +82,4 @@ config SND_MESON_AXG_PDM
74 help 82 help
75 Select Y or M to add support for PDM input embedded 83 Select Y or M to add support for PDM input embedded
76 in the Amlogic AXG SoC family 84 in the Amlogic AXG SoC family
77
78endmenu 85endmenu
diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile
index 4cd25104029d..b45dfb9e2f88 100644
--- a/sound/soc/meson/Makefile
+++ b/sound/soc/meson/Makefile
@@ -8,6 +8,7 @@ snd-soc-meson-axg-tdm-interface-objs := axg-tdm-interface.o
8snd-soc-meson-axg-tdmin-objs := axg-tdmin.o 8snd-soc-meson-axg-tdmin-objs := axg-tdmin.o
9snd-soc-meson-axg-tdmout-objs := axg-tdmout.o 9snd-soc-meson-axg-tdmout-objs := axg-tdmout.o
10snd-soc-meson-axg-sound-card-objs := axg-card.o 10snd-soc-meson-axg-sound-card-objs := axg-card.o
11snd-soc-meson-axg-spdifin-objs := axg-spdifin.o
11snd-soc-meson-axg-spdifout-objs := axg-spdifout.o 12snd-soc-meson-axg-spdifout-objs := axg-spdifout.o
12snd-soc-meson-axg-pdm-objs := axg-pdm.o 13snd-soc-meson-axg-pdm-objs := axg-pdm.o
13 14
@@ -19,5 +20,6 @@ obj-$(CONFIG_SND_MESON_AXG_TDM_INTERFACE) += snd-soc-meson-axg-tdm-interface.o
19obj-$(CONFIG_SND_MESON_AXG_TDMIN) += snd-soc-meson-axg-tdmin.o 20obj-$(CONFIG_SND_MESON_AXG_TDMIN) += snd-soc-meson-axg-tdmin.o
20obj-$(CONFIG_SND_MESON_AXG_TDMOUT) += snd-soc-meson-axg-tdmout.o 21obj-$(CONFIG_SND_MESON_AXG_TDMOUT) += snd-soc-meson-axg-tdmout.o
21obj-$(CONFIG_SND_MESON_AXG_SOUND_CARD) += snd-soc-meson-axg-sound-card.o 22obj-$(CONFIG_SND_MESON_AXG_SOUND_CARD) += snd-soc-meson-axg-sound-card.o
23obj-$(CONFIG_SND_MESON_AXG_SPDIFIN) += snd-soc-meson-axg-spdifin.o
22obj-$(CONFIG_SND_MESON_AXG_SPDIFOUT) += snd-soc-meson-axg-spdifout.o 24obj-$(CONFIG_SND_MESON_AXG_SPDIFOUT) += snd-soc-meson-axg-spdifout.o
23obj-$(CONFIG_SND_MESON_AXG_PDM) += snd-soc-meson-axg-pdm.o 25obj-$(CONFIG_SND_MESON_AXG_PDM) += snd-soc-meson-axg-pdm.o
diff --git a/sound/soc/meson/axg-fifo.h b/sound/soc/meson/axg-fifo.h
index cb6c4013ca33..d9f516cfbeda 100644
--- a/sound/soc/meson/axg-fifo.h
+++ b/sound/soc/meson/axg-fifo.h
@@ -25,7 +25,8 @@ struct snd_soc_pcm_runtime;
25 SNDRV_PCM_FMTBIT_S16_LE | \ 25 SNDRV_PCM_FMTBIT_S16_LE | \
26 SNDRV_PCM_FMTBIT_S20_LE | \ 26 SNDRV_PCM_FMTBIT_S20_LE | \
27 SNDRV_PCM_FMTBIT_S24_LE | \ 27 SNDRV_PCM_FMTBIT_S24_LE | \
28 SNDRV_PCM_FMTBIT_S32_LE) 28 SNDRV_PCM_FMTBIT_S32_LE | \
29 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
29 30
30#define AXG_FIFO_BURST 8 31#define AXG_FIFO_BURST 8
31#define AXG_FIFO_MIN_CNT 64 32#define AXG_FIFO_MIN_CNT 64
diff --git a/sound/soc/meson/axg-spdifin.c b/sound/soc/meson/axg-spdifin.c
new file mode 100644
index 000000000000..01b2035fa841
--- /dev/null
+++ b/sound/soc/meson/axg-spdifin.c
@@ -0,0 +1,521 @@
1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2//
3// Copyright (c) 2018 BayLibre, SAS.
4// Author: Jerome Brunet <jbrunet@baylibre.com>
5
6#include <linux/bitfield.h>
7#include <linux/clk.h>
8#include <linux/module.h>
9#include <linux/of_platform.h>
10#include <linux/regmap.h>
11#include <sound/soc.h>
12#include <sound/soc-dai.h>
13#include <sound/pcm_params.h>
14
15#define SPDIFIN_CTRL0 0x00
16#define SPDIFIN_CTRL0_EN BIT(31)
17#define SPDIFIN_CTRL0_RST_OUT BIT(29)
18#define SPDIFIN_CTRL0_RST_IN BIT(28)
19#define SPDIFIN_CTRL0_WIDTH_SEL BIT(24)
20#define SPDIFIN_CTRL0_STATUS_CH_SHIFT 11
21#define SPDIFIN_CTRL0_STATUS_SEL GENMASK(10, 8)
22#define SPDIFIN_CTRL0_SRC_SEL GENMASK(5, 4)
23#define SPDIFIN_CTRL0_CHK_VALID BIT(3)
24#define SPDIFIN_CTRL1 0x04
25#define SPDIFIN_CTRL1_BASE_TIMER GENMASK(19, 0)
26#define SPDIFIN_CTRL1_IRQ_MASK GENMASK(27, 20)
27#define SPDIFIN_CTRL2 0x08
28#define SPDIFIN_THRES_PER_REG 3
29#define SPDIFIN_THRES_WIDTH 10
30#define SPDIFIN_CTRL3 0x0c
31#define SPDIFIN_CTRL4 0x10
32#define SPDIFIN_TIMER_PER_REG 4
33#define SPDIFIN_TIMER_WIDTH 8
34#define SPDIFIN_CTRL5 0x14
35#define SPDIFIN_CTRL6 0x18
36#define SPDIFIN_STAT0 0x1c
37#define SPDIFIN_STAT0_MODE GENMASK(30, 28)
38#define SPDIFIN_STAT0_MAXW GENMASK(17, 8)
39#define SPDIFIN_STAT0_IRQ GENMASK(7, 0)
40#define SPDIFIN_IRQ_MODE_CHANGED BIT(2)
41#define SPDIFIN_STAT1 0x20
42#define SPDIFIN_STAT2 0x24
43#define SPDIFIN_MUTE_VAL 0x28
44
45#define SPDIFIN_MODE_NUM 7
46
47struct axg_spdifin_cfg {
48 const unsigned int *mode_rates;
49 unsigned int ref_rate;
50};
51
52struct axg_spdifin {
53 const struct axg_spdifin_cfg *conf;
54 struct regmap *map;
55 struct clk *refclk;
56 struct clk *pclk;
57};
58
59/*
60 * TODO:
61 * It would have been nice to check the actual rate against the sample rate
62 * requested in hw_params(). Unfortunately, I was not able to make the mode
63 * detection and IRQ work reliably:
64 *
65 * 1. IRQs are generated on mode change only, so there is no notification
66 * on transition between no signal and mode 0 (32kHz).
67 * 2. Mode detection very often has glitches, and may detects the
68 * lowest or the highest mode before zeroing in on the actual mode.
69 *
70 * This makes calling snd_pcm_stop() difficult to get right. Even notifying
71 * the kcontrol would be very unreliable at this point.
72 * Let's keep things simple until the magic spell that makes this work is
73 * found.
74 */
75
76static unsigned int axg_spdifin_get_rate(struct axg_spdifin *priv)
77{
78 unsigned int stat, mode, rate = 0;
79
80 regmap_read(priv->map, SPDIFIN_STAT0, &stat);
81 mode = FIELD_GET(SPDIFIN_STAT0_MODE, stat);
82
83 /*
84 * If max width is zero, we are not capturing anything.
85 * Also Sometimes, when the capture is on but there is no data,
86 * mode is SPDIFIN_MODE_NUM, but not always ...
87 */
88 if (FIELD_GET(SPDIFIN_STAT0_MAXW, stat) &&
89 mode < SPDIFIN_MODE_NUM)
90 rate = priv->conf->mode_rates[mode];
91
92 return rate;
93}
94
95static int axg_spdifin_prepare(struct snd_pcm_substream *substream,
96 struct snd_soc_dai *dai)
97{
98 struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai);
99
100 /* Apply both reset */
101 regmap_update_bits(priv->map, SPDIFIN_CTRL0,
102 SPDIFIN_CTRL0_RST_OUT |
103 SPDIFIN_CTRL0_RST_IN,
104 0);
105
106 /* Clear out reset before in reset */
107 regmap_update_bits(priv->map, SPDIFIN_CTRL0,
108 SPDIFIN_CTRL0_RST_OUT, SPDIFIN_CTRL0_RST_OUT);
109 regmap_update_bits(priv->map, SPDIFIN_CTRL0,
110 SPDIFIN_CTRL0_RST_IN, SPDIFIN_CTRL0_RST_IN);
111
112 return 0;
113}
114
115static int axg_spdifin_startup(struct snd_pcm_substream *substream,
116 struct snd_soc_dai *dai)
117{
118 struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai);
119 int ret;
120
121 ret = clk_prepare_enable(priv->refclk);
122 if (ret) {
123 dev_err(dai->dev,
124 "failed to enable spdifin reference clock\n");
125 return ret;
126 }
127
128 regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN,
129 SPDIFIN_CTRL0_EN);
130
131 return 0;
132}
133
134static void axg_spdifin_shutdown(struct snd_pcm_substream *substream,
135 struct snd_soc_dai *dai)
136{
137 struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai);
138
139 regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, 0);
140 clk_disable_unprepare(priv->refclk);
141}
142
143static void axg_spdifin_write_mode_param(struct regmap *map, int mode,
144 unsigned int val,
145 unsigned int num_per_reg,
146 unsigned int base_reg,
147 unsigned int width)
148{
149 uint64_t offset = mode;
150 unsigned int reg, shift, rem;
151
152 rem = do_div(offset, num_per_reg);
153
154 reg = offset * regmap_get_reg_stride(map) + base_reg;
155 shift = width * (num_per_reg - 1 - rem);
156
157 regmap_update_bits(map, reg, GENMASK(width - 1, 0) << shift,
158 val << shift);
159}
160
161static void axg_spdifin_write_timer(struct regmap *map, int mode,
162 unsigned int val)
163{
164 axg_spdifin_write_mode_param(map, mode, val, SPDIFIN_TIMER_PER_REG,
165 SPDIFIN_CTRL4, SPDIFIN_TIMER_WIDTH);
166}
167
168static void axg_spdifin_write_threshold(struct regmap *map, int mode,
169 unsigned int val)
170{
171 axg_spdifin_write_mode_param(map, mode, val, SPDIFIN_THRES_PER_REG,
172 SPDIFIN_CTRL2, SPDIFIN_THRES_WIDTH);
173}
174
175static unsigned int axg_spdifin_mode_timer(struct axg_spdifin *priv,
176 int mode,
177 unsigned int rate)
178{
179 /*
180 * Number of period of the reference clock during a period of the
181 * input signal reference clock
182 */
183 return rate / (128 * priv->conf->mode_rates[mode]);
184}
185
186static int axg_spdifin_sample_mode_config(struct snd_soc_dai *dai,
187 struct axg_spdifin *priv)
188{
189 unsigned int rate, t_next;
190 int ret, i = SPDIFIN_MODE_NUM - 1;
191
192 /* Set spdif input reference clock */
193 ret = clk_set_rate(priv->refclk, priv->conf->ref_rate);
194 if (ret) {
195 dev_err(dai->dev, "reference clock rate set failed\n");
196 return ret;
197 }
198
199 /*
200 * The rate actually set might be slightly different, get
201 * the actual rate for the following mode calculation
202 */
203 rate = clk_get_rate(priv->refclk);
204
205 /* HW will update mode every 1ms */
206 regmap_update_bits(priv->map, SPDIFIN_CTRL1,
207 SPDIFIN_CTRL1_BASE_TIMER,
208 FIELD_PREP(SPDIFIN_CTRL1_BASE_TIMER, rate / 1000));
209
210 /* Threshold based on the minimum width between two edges */
211 regmap_update_bits(priv->map, SPDIFIN_CTRL0,
212 SPDIFIN_CTRL0_WIDTH_SEL, SPDIFIN_CTRL0_WIDTH_SEL);
213
214 /* Calculate the last timer which has no threshold */
215 t_next = axg_spdifin_mode_timer(priv, i, rate);
216 axg_spdifin_write_timer(priv->map, i, t_next);
217
218 do {
219 unsigned int t;
220
221 i -= 1;
222
223 /* Calculate the timer */
224 t = axg_spdifin_mode_timer(priv, i, rate);
225
226 /* Set the timer value */
227 axg_spdifin_write_timer(priv->map, i, t);
228
229 /* Set the threshold value */
230 axg_spdifin_write_threshold(priv->map, i, t + t_next);
231
232 /* Save the current timer for the next threshold calculation */
233 t_next = t;
234
235 } while (i > 0);
236
237 return 0;
238}
239
240static int axg_spdifin_dai_probe(struct snd_soc_dai *dai)
241{
242 struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai);
243 int ret;
244
245 ret = clk_prepare_enable(priv->pclk);
246 if (ret) {
247 dev_err(dai->dev, "failed to enable pclk\n");
248 return ret;
249 }
250
251 ret = axg_spdifin_sample_mode_config(dai, priv);
252 if (ret) {
253 dev_err(dai->dev, "mode configuration failed\n");
254 clk_disable_unprepare(priv->pclk);
255 return ret;
256 }
257
258 return 0;
259}
260
261static int axg_spdifin_dai_remove(struct snd_soc_dai *dai)
262{
263 struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai);
264
265 clk_disable_unprepare(priv->pclk);
266 return 0;
267}
268
269static const struct snd_soc_dai_ops axg_spdifin_ops = {
270 .prepare = axg_spdifin_prepare,
271 .startup = axg_spdifin_startup,
272 .shutdown = axg_spdifin_shutdown,
273};
274
275static int axg_spdifin_iec958_info(struct snd_kcontrol *kcontrol,
276 struct snd_ctl_elem_info *uinfo)
277{
278 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
279 uinfo->count = 1;
280
281 return 0;
282}
283
284static int axg_spdifin_get_status_mask(struct snd_kcontrol *kcontrol,
285 struct snd_ctl_elem_value *ucontrol)
286{
287 int i;
288
289 for (i = 0; i < 24; i++)
290 ucontrol->value.iec958.status[i] = 0xff;
291
292 return 0;
293}
294
295static int axg_spdifin_get_status(struct snd_kcontrol *kcontrol,
296 struct snd_ctl_elem_value *ucontrol)
297{
298 struct snd_soc_component *c = snd_kcontrol_chip(kcontrol);
299 struct axg_spdifin *priv = snd_soc_component_get_drvdata(c);
300 int i, j;
301
302 for (i = 0; i < 6; i++) {
303 unsigned int val;
304
305 regmap_update_bits(priv->map, SPDIFIN_CTRL0,
306 SPDIFIN_CTRL0_STATUS_SEL,
307 FIELD_PREP(SPDIFIN_CTRL0_STATUS_SEL, i));
308
309 regmap_read(priv->map, SPDIFIN_STAT1, &val);
310
311 for (j = 0; j < 4; j++) {
312 unsigned int offset = i * 4 + j;
313
314 ucontrol->value.iec958.status[offset] =
315 (val >> (j * 8)) & 0xff;
316 }
317 }
318
319 return 0;
320}
321
322#define AXG_SPDIFIN_IEC958_MASK \
323 { \
324 .access = SNDRV_CTL_ELEM_ACCESS_READ, \
325 .iface = SNDRV_CTL_ELEM_IFACE_PCM, \
326 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK), \
327 .info = axg_spdifin_iec958_info, \
328 .get = axg_spdifin_get_status_mask, \
329 }
330
331#define AXG_SPDIFIN_IEC958_STATUS \
332 { \
333 .access = (SNDRV_CTL_ELEM_ACCESS_READ | \
334 SNDRV_CTL_ELEM_ACCESS_VOLATILE), \
335 .iface = SNDRV_CTL_ELEM_IFACE_PCM, \
336 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE), \
337 .info = axg_spdifin_iec958_info, \
338 .get = axg_spdifin_get_status, \
339 }
340
341static const char * const spdifin_chsts_src_texts[] = {
342 "A", "B",
343};
344
345static SOC_ENUM_SINGLE_DECL(axg_spdifin_chsts_src_enum, SPDIFIN_CTRL0,
346 SPDIFIN_CTRL0_STATUS_CH_SHIFT,
347 spdifin_chsts_src_texts);
348
349static int axg_spdifin_rate_lock_info(struct snd_kcontrol *kcontrol,
350 struct snd_ctl_elem_info *uinfo)
351{
352 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
353 uinfo->count = 1;
354 uinfo->value.integer.min = 0;
355 uinfo->value.integer.max = 192000;
356
357 return 0;
358}
359
360static int axg_spdifin_rate_lock_get(struct snd_kcontrol *kcontrol,
361 struct snd_ctl_elem_value *ucontrol)
362{
363 struct snd_soc_component *c = snd_kcontrol_chip(kcontrol);
364 struct axg_spdifin *priv = snd_soc_component_get_drvdata(c);
365
366 ucontrol->value.integer.value[0] = axg_spdifin_get_rate(priv);
367
368 return 0;
369}
370
371#define AXG_SPDIFIN_LOCK_RATE(xname) \
372 { \
373 .iface = SNDRV_CTL_ELEM_IFACE_PCM, \
374 .access = (SNDRV_CTL_ELEM_ACCESS_READ | \
375 SNDRV_CTL_ELEM_ACCESS_VOLATILE), \
376 .get = axg_spdifin_rate_lock_get, \
377 .info = axg_spdifin_rate_lock_info, \
378 .name = xname, \
379 }
380
381static const struct snd_kcontrol_new axg_spdifin_controls[] = {
382 AXG_SPDIFIN_LOCK_RATE("Capture Rate Lock"),
383 SOC_DOUBLE("Capture Switch", SPDIFIN_CTRL0, 7, 6, 1, 1),
384 SOC_ENUM(SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Src",
385 axg_spdifin_chsts_src_enum),
386 AXG_SPDIFIN_IEC958_MASK,
387 AXG_SPDIFIN_IEC958_STATUS,
388};
389
390static const struct snd_soc_component_driver axg_spdifin_component_drv = {
391 .controls = axg_spdifin_controls,
392 .num_controls = ARRAY_SIZE(axg_spdifin_controls),
393};
394
395static const struct regmap_config axg_spdifin_regmap_cfg = {
396 .reg_bits = 32,
397 .val_bits = 32,
398 .reg_stride = 4,
399 .max_register = SPDIFIN_MUTE_VAL,
400};
401
402static const unsigned int axg_spdifin_mode_rates[SPDIFIN_MODE_NUM] = {
403 32000, 44100, 48000, 88200, 96000, 176400, 192000,
404};
405
406static const struct axg_spdifin_cfg axg_cfg = {
407 .mode_rates = axg_spdifin_mode_rates,
408 .ref_rate = 333333333,
409};
410
411static const struct of_device_id axg_spdifin_of_match[] = {
412 {
413 .compatible = "amlogic,axg-spdifin",
414 .data = &axg_cfg,
415 }, {}
416};
417MODULE_DEVICE_TABLE(of, axg_spdifin_of_match);
418
419static struct snd_soc_dai_driver *
420axg_spdifin_get_dai_drv(struct device *dev, struct axg_spdifin *priv)
421{
422 struct snd_soc_dai_driver *drv;
423 int i;
424
425 drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
426 if (!drv)
427 return ERR_PTR(-ENOMEM);
428
429 drv->name = "SPDIF Input";
430 drv->ops = &axg_spdifin_ops;
431 drv->probe = axg_spdifin_dai_probe;
432 drv->remove = axg_spdifin_dai_remove;
433 drv->capture.stream_name = "Capture";
434 drv->capture.channels_min = 1;
435 drv->capture.channels_max = 2;
436 drv->capture.formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
437
438 for (i = 0; i < SPDIFIN_MODE_NUM; i++) {
439 unsigned int rb =
440 snd_pcm_rate_to_rate_bit(priv->conf->mode_rates[i]);
441
442 if (rb == SNDRV_PCM_RATE_KNOT)
443 return ERR_PTR(-EINVAL);
444
445 drv->capture.rates |= rb;
446 }
447
448 return drv;
449}
450
451static int axg_spdifin_probe(struct platform_device *pdev)
452{
453 struct device *dev = &pdev->dev;
454 struct axg_spdifin *priv;
455 struct snd_soc_dai_driver *dai_drv;
456 struct resource *res;
457 void __iomem *regs;
458 int ret;
459
460 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
461 if (!priv)
462 return -ENOMEM;
463 platform_set_drvdata(pdev, priv);
464
465 priv->conf = of_device_get_match_data(dev);
466 if (!priv->conf) {
467 dev_err(dev, "failed to match device\n");
468 return -ENODEV;
469 }
470
471 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
472 regs = devm_ioremap_resource(dev, res);
473 if (IS_ERR(regs))
474 return PTR_ERR(regs);
475
476 priv->map = devm_regmap_init_mmio(dev, regs, &axg_spdifin_regmap_cfg);
477 if (IS_ERR(priv->map)) {
478 dev_err(dev, "failed to init regmap: %ld\n",
479 PTR_ERR(priv->map));
480 return PTR_ERR(priv->map);
481 }
482
483 priv->pclk = devm_clk_get(dev, "pclk");
484 if (IS_ERR(priv->pclk)) {
485 ret = PTR_ERR(priv->pclk);
486 if (ret != -EPROBE_DEFER)
487 dev_err(dev, "failed to get pclk: %d\n", ret);
488 return ret;
489 }
490
491 priv->refclk = devm_clk_get(dev, "refclk");
492 if (IS_ERR(priv->refclk)) {
493 ret = PTR_ERR(priv->refclk);
494 if (ret != -EPROBE_DEFER)
495 dev_err(dev, "failed to get mclk: %d\n", ret);
496 return ret;
497 }
498
499 dai_drv = axg_spdifin_get_dai_drv(dev, priv);
500 if (IS_ERR(dai_drv)) {
501 dev_err(dev, "failed to get dai driver: %ld\n",
502 PTR_ERR(dai_drv));
503 return PTR_ERR(dai_drv);
504 }
505
506 return devm_snd_soc_register_component(dev, &axg_spdifin_component_drv,
507 dai_drv, 1);
508}
509
510static struct platform_driver axg_spdifin_pdrv = {
511 .probe = axg_spdifin_probe,
512 .driver = {
513 .name = "axg-spdifin",
514 .of_match_table = axg_spdifin_of_match,
515 },
516};
517module_platform_driver(axg_spdifin_pdrv);
518
519MODULE_DESCRIPTION("Amlogic AXG SPDIF Input driver");
520MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
521MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/meson/axg-toddr.c b/sound/soc/meson/axg-toddr.c
index c2c9bb312586..0e9ca3882ae5 100644
--- a/sound/soc/meson/axg-toddr.c
+++ b/sound/soc/meson/axg-toddr.c
@@ -25,6 +25,8 @@
25#define CTRL0_TODDR_LSB_POS_MASK GENMASK(7, 3) 25#define CTRL0_TODDR_LSB_POS_MASK GENMASK(7, 3)
26#define CTRL0_TODDR_LSB_POS(x) ((x) << 3) 26#define CTRL0_TODDR_LSB_POS(x) ((x) << 3)
27 27
28#define TODDR_MSB_POS 31
29
28static int axg_toddr_pcm_new(struct snd_soc_pcm_runtime *rtd, 30static int axg_toddr_pcm_new(struct snd_soc_pcm_runtime *rtd,
29 struct snd_soc_dai *dai) 31 struct snd_soc_dai *dai)
30{ 32{
@@ -36,14 +38,7 @@ static int axg_toddr_dai_hw_params(struct snd_pcm_substream *substream,
36 struct snd_soc_dai *dai) 38 struct snd_soc_dai *dai)
37{ 39{
38 struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai); 40 struct axg_fifo *fifo = snd_soc_dai_get_drvdata(dai);
39 unsigned int type, width, msb = 31; 41 unsigned int type, width;
40
41 /*
42 * NOTE:
43 * Almost all backend will place the MSB at bit 31, except SPDIF Input
44 * which will put it at index 28. When adding support for the SPDIF
45 * Input, we'll need to find which type of backend we are connected to.
46 */
47 42
48 switch (params_physical_width(params)) { 43 switch (params_physical_width(params)) {
49 case 8: 44 case 8:
@@ -66,8 +61,8 @@ static int axg_toddr_dai_hw_params(struct snd_pcm_substream *substream,
66 CTRL0_TODDR_MSB_POS_MASK | 61 CTRL0_TODDR_MSB_POS_MASK |
67 CTRL0_TODDR_LSB_POS_MASK, 62 CTRL0_TODDR_LSB_POS_MASK,
68 CTRL0_TODDR_TYPE(type) | 63 CTRL0_TODDR_TYPE(type) |
69 CTRL0_TODDR_MSB_POS(msb) | 64 CTRL0_TODDR_MSB_POS(TODDR_MSB_POS) |
70 CTRL0_TODDR_LSB_POS(msb - (width - 1))); 65 CTRL0_TODDR_LSB_POS(TODDR_MSB_POS - (width - 1)));
71 66
72 return 0; 67 return 0;
73} 68}
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
deleted file mode 100644
index 6dccea6fdaeb..000000000000
--- a/sound/soc/omap/Kconfig
+++ /dev/null
@@ -1,129 +0,0 @@
1config SND_OMAP_SOC
2 tristate "SoC Audio for Texas Instruments OMAP chips (deprecated)"
3 depends on (ARCH_OMAP && DMA_OMAP) || (ARM && COMPILE_TEST)
4 select SND_SDMA_SOC
5
6config SND_SDMA_SOC
7 tristate "SoC Audio for Texas Instruments chips using sDMA"
8 depends on DMA_OMAP || COMPILE_TEST
9 select SND_SOC_GENERIC_DMAENGINE_PCM
10
11config SND_OMAP_SOC_DMIC
12 tristate
13
14config SND_OMAP_SOC_MCBSP
15 tristate
16
17config SND_OMAP_SOC_MCPDM
18 tristate
19
20config SND_OMAP_SOC_HDMI_AUDIO
21 tristate "HDMI audio support for OMAP4+ based SoCs"
22 depends on SND_SDMA_SOC
23 help
24 For HDMI audio to work OMAPDSS HDMI support should be
25 enabled.
26 The hdmi audio driver implements cpu-dai component using the
27 callbacks provided by OMAPDSS and registers the component
28 under DSS HDMI device. Omap-pcm is registered for platform
29 component also under DSS HDMI device. Dummy codec is used as
30 as codec component. The hdmi audio driver implements also
31 the card and registers it under its own platform device.
32 The device for the driver is registered by OMAPDSS hdmi
33 driver.
34
35config SND_OMAP_SOC_N810
36 tristate "SoC Audio support for Nokia N810"
37 depends on SND_SDMA_SOC && MACH_NOKIA_N810 && I2C
38 select SND_OMAP_SOC_MCBSP
39 select SND_SOC_TLV320AIC3X
40 help
41 Say Y if you want to add support for SoC audio on Nokia N810.
42
43config SND_OMAP_SOC_RX51
44 tristate "SoC Audio support for Nokia N900 (RX-51)"
45 depends on SND_SDMA_SOC && ARM && I2C
46 select SND_OMAP_SOC_MCBSP
47 select SND_SOC_TLV320AIC3X
48 select SND_SOC_TPA6130A2
49 depends on GPIOLIB
50 help
51 Say Y if you want to add support for SoC audio on Nokia N900
52 cellphone.
53
54config SND_OMAP_SOC_AMS_DELTA
55 tristate "SoC Audio support for Amstrad E3 (Delta) videophone"
56 depends on SND_SDMA_SOC && MACH_AMS_DELTA && TTY
57 select SND_OMAP_SOC_MCBSP
58 select SND_SOC_CX20442
59 help
60 Say Y if you want to add support for SoC audio device connected to
61 a handset and a speakerphone found on Amstrad E3 (Delta) videophone.
62
63 Note that in order to get those devices fully supported, you have to
64 build the kernel with standard serial port driver included and
65 configured for at least 4 ports. Then, from userspace, you must load
66 a line discipline #19 on the modem (ttyS3) serial line. The simplest
67 way to achieve this is to install util-linux-ng and use the included
68 ldattach utility. This can be started automatically from udev,
69 a simple rule like this one should do the trick (it does for me):
70 ACTION=="add", KERNEL=="controlC0", \
71 RUN+="/usr/sbin/ldattach 19 /dev/ttyS3"
72
73config SND_OMAP_SOC_OSK5912
74 tristate "SoC Audio support for omap osk5912"
75 depends on SND_SDMA_SOC && MACH_OMAP_OSK && I2C
76 select SND_OMAP_SOC_MCBSP
77 select SND_SOC_TLV320AIC23_I2C
78 help
79 Say Y if you want to add support for SoC audio on osk5912.
80
81config SND_OMAP_SOC_AM3517EVM
82 tristate "SoC Audio support for OMAP3517 / AM3517 EVM"
83 depends on SND_SDMA_SOC && MACH_OMAP3517EVM && I2C
84 select SND_OMAP_SOC_MCBSP
85 select SND_SOC_TLV320AIC23_I2C
86 help
87 Say Y if you want to add support for SoC audio on the OMAP3517 / AM3517
88 EVM.
89
90config SND_OMAP_SOC_OMAP_TWL4030
91 tristate "SoC Audio support for TI SoC based boards with twl4030 codec"
92 depends on TWL4030_CORE && SND_SDMA_SOC
93 select SND_OMAP_SOC_MCBSP
94 select SND_SOC_TWL4030
95 help
96 Say Y if you want to add support for SoC audio on TI SoC based boards
97 using twl4030 as c codec. This driver currently supports:
98 - Beagleboard or Devkit8000
99 - Gumstix Overo or CompuLab CM-T35/CM-T3730
100 - IGEP v2
101 - OMAP3EVM
102 - SDP3430
103 - Zoom2
104
105config SND_OMAP_SOC_OMAP_ABE_TWL6040
106 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
107 depends on TWL6040_CORE && SND_SDMA_SOC && COMMON_CLK
108 depends on ARCH_OMAP4 || (SOC_OMAP5 && MFD_PALMAS) || COMPILE_TEST
109 select SND_OMAP_SOC_DMIC
110 select SND_OMAP_SOC_MCPDM
111 select SND_SOC_TWL6040
112 select SND_SOC_DMIC
113 select COMMON_CLK_PALMAS if (SOC_OMAP5 && MFD_PALMAS)
114 select CLK_TWL6040
115 help
116 Say Y if you want to add support for SoC audio on OMAP boards using
117 ABE and twl6040 codec. This driver currently supports:
118 - SDP4430/Blaze boards
119 - PandaBoard (4430)
120 - PandaBoardES (4460)
121 - omap5-uevm (5432)
122
123config SND_OMAP_SOC_OMAP3_PANDORA
124 tristate "SoC Audio support for OMAP3 Pandora"
125 depends on TWL4030_CORE && SND_SDMA_SOC && MACH_OMAP3_PANDORA
126 select SND_OMAP_SOC_MCBSP
127 select SND_SOC_TWL4030
128 help
129 Say Y if you want to add support for SoC audio on the OMAP3 Pandora.
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
deleted file mode 100644
index 53eba3413485..000000000000
--- a/sound/soc/omap/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
1# SPDX-License-Identifier: GPL-2.0
2# OMAP Platform Support
3snd-soc-sdma-objs := sdma-pcm.o
4snd-soc-omap-dmic-objs := omap-dmic.o
5snd-soc-omap-mcbsp-objs := omap-mcbsp.o mcbsp.o
6snd-soc-omap-mcpdm-objs := omap-mcpdm.o
7snd-soc-omap-hdmi-audio-objs := omap-hdmi-audio.o
8
9obj-$(CONFIG_SND_SDMA_SOC) += snd-soc-sdma.o
10obj-$(CONFIG_SND_OMAP_SOC_DMIC) += snd-soc-omap-dmic.o
11obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
12obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o
13obj-$(CONFIG_SND_OMAP_SOC_HDMI_AUDIO) += snd-soc-omap-hdmi-audio.o
14
15# OMAP Machine Support
16snd-soc-n810-objs := n810.o
17snd-soc-rx51-objs := rx51.o
18snd-soc-ams-delta-objs := ams-delta.o
19snd-soc-osk5912-objs := osk5912.o
20snd-soc-am3517evm-objs := am3517evm.o
21snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o
22snd-soc-omap-twl4030-objs := omap-twl4030.o
23snd-soc-omap3pandora-objs := omap3pandora.o
24
25obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
26obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o
27obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
28obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
29obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o
30obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o
31obj-$(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) += snd-soc-omap-twl4030.o
32obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
deleted file mode 100644
index d5651026ec10..000000000000
--- a/sound/soc/omap/am3517evm.c
+++ /dev/null
@@ -1,141 +0,0 @@
1/*
2 * am3517evm.c -- ALSA SoC support for OMAP3517 / AM3517 EVM
3 *
4 * Author: Anuj Aggarwal <anuj.aggarwal@ti.com>
5 *
6 * Based on sound/soc/omap/beagle.c by Steve Sakoman
7 *
8 * Copyright (C) 2009 Texas Instruments Incorporated
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation version 2.
13 *
14 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
15 * whether express or implied; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 */
19
20#include <linux/clk.h>
21#include <linux/platform_device.h>
22#include <linux/module.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/soc.h>
26
27#include <asm/mach-types.h>
28#include <linux/platform_data/asoc-ti-mcbsp.h>
29
30#include "omap-mcbsp.h"
31
32#include "../codecs/tlv320aic23.h"
33
34#define CODEC_CLOCK 12000000
35
36static int am3517evm_hw_params(struct snd_pcm_substream *substream,
37 struct snd_pcm_hw_params *params)
38{
39 struct snd_soc_pcm_runtime *rtd = substream->private_data;
40 struct snd_soc_dai *codec_dai = rtd->codec_dai;
41 int ret;
42
43 /* Set the codec system clock for DAC and ADC */
44 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
45 CODEC_CLOCK, SND_SOC_CLOCK_IN);
46 if (ret < 0)
47 printk(KERN_ERR "can't set codec system clock\n");
48
49 return ret;
50}
51
52static const struct snd_soc_ops am3517evm_ops = {
53 .hw_params = am3517evm_hw_params,
54};
55
56/* am3517evm machine dapm widgets */
57static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
58 SND_SOC_DAPM_HP("Line Out", NULL),
59 SND_SOC_DAPM_LINE("Line In", NULL),
60 SND_SOC_DAPM_MIC("Mic In", NULL),
61};
62
63static const struct snd_soc_dapm_route audio_map[] = {
64 /* Line Out connected to LLOUT, RLOUT */
65 {"Line Out", NULL, "LOUT"},
66 {"Line Out", NULL, "ROUT"},
67
68 {"LLINEIN", NULL, "Line In"},
69 {"RLINEIN", NULL, "Line In"},
70
71 {"MICIN", NULL, "Mic In"},
72};
73
74/* Digital audio interface glue - connects codec <--> CPU */
75static struct snd_soc_dai_link am3517evm_dai = {
76 .name = "TLV320AIC23",
77 .stream_name = "AIC23",
78 .cpu_dai_name = "omap-mcbsp.1",
79 .codec_dai_name = "tlv320aic23-hifi",
80 .platform_name = "omap-mcbsp.1",
81 .codec_name = "tlv320aic23-codec.2-001a",
82 .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
83 SND_SOC_DAIFMT_CBM_CFM,
84 .ops = &am3517evm_ops,
85};
86
87/* Audio machine driver */
88static struct snd_soc_card snd_soc_am3517evm = {
89 .name = "am3517evm",
90 .owner = THIS_MODULE,
91 .dai_link = &am3517evm_dai,
92 .num_links = 1,
93
94 .dapm_widgets = tlv320aic23_dapm_widgets,
95 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
96 .dapm_routes = audio_map,
97 .num_dapm_routes = ARRAY_SIZE(audio_map),
98};
99
100static struct platform_device *am3517evm_snd_device;
101
102static int __init am3517evm_soc_init(void)
103{
104 int ret;
105
106 if (!machine_is_omap3517evm())
107 return -ENODEV;
108 pr_info("OMAP3517 / AM3517 EVM SoC init\n");
109
110 am3517evm_snd_device = platform_device_alloc("soc-audio", -1);
111 if (!am3517evm_snd_device) {
112 printk(KERN_ERR "Platform device allocation failed\n");
113 return -ENOMEM;
114 }
115
116 platform_set_drvdata(am3517evm_snd_device, &snd_soc_am3517evm);
117
118 ret = platform_device_add(am3517evm_snd_device);
119 if (ret)
120 goto err1;
121
122 return 0;
123
124err1:
125 printk(KERN_ERR "Unable to add platform device\n");
126 platform_device_put(am3517evm_snd_device);
127
128 return ret;
129}
130
131static void __exit am3517evm_soc_exit(void)
132{
133 platform_device_unregister(am3517evm_snd_device);
134}
135
136module_init(am3517evm_soc_init);
137module_exit(am3517evm_soc_exit);
138
139MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>");
140MODULE_DESCRIPTION("ALSA SoC OMAP3517 / AM3517 EVM");
141MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c
deleted file mode 100644
index 79d4dc785e5c..000000000000
--- a/sound/soc/omap/mcbsp.c
+++ /dev/null
@@ -1,1104 +0,0 @@
1/*
2 * sound/soc/omap/mcbsp.c
3 *
4 * Copyright (C) 2004 Nokia Corporation
5 * Author: Samuel Ortiz <samuel.ortiz@nokia.com>
6 *
7 * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
8 * Peter Ujfalusi <peter.ujfalusi@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * Multichannel mode not supported.
15 */
16
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/device.h>
20#include <linux/platform_device.h>
21#include <linux/interrupt.h>
22#include <linux/err.h>
23#include <linux/clk.h>
24#include <linux/delay.h>
25#include <linux/io.h>
26#include <linux/slab.h>
27#include <linux/pm_runtime.h>
28
29#include <linux/platform_data/asoc-ti-mcbsp.h>
30
31#include "mcbsp.h"
32
33static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
34{
35 void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step;
36
37 if (mcbsp->pdata->reg_size == 2) {
38 ((u16 *)mcbsp->reg_cache)[reg] = (u16)val;
39 writew_relaxed((u16)val, addr);
40 } else {
41 ((u32 *)mcbsp->reg_cache)[reg] = val;
42 writel_relaxed(val, addr);
43 }
44}
45
46static int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg, bool from_cache)
47{
48 void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step;
49
50 if (mcbsp->pdata->reg_size == 2) {
51 return !from_cache ? readw_relaxed(addr) :
52 ((u16 *)mcbsp->reg_cache)[reg];
53 } else {
54 return !from_cache ? readl_relaxed(addr) :
55 ((u32 *)mcbsp->reg_cache)[reg];
56 }
57}
58
59static void omap_mcbsp_st_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
60{
61 writel_relaxed(val, mcbsp->st_data->io_base_st + reg);
62}
63
64static int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
65{
66 return readl_relaxed(mcbsp->st_data->io_base_st + reg);
67}
68
69#define MCBSP_READ(mcbsp, reg) \
70 omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 0)
71#define MCBSP_WRITE(mcbsp, reg, val) \
72 omap_mcbsp_write(mcbsp, OMAP_MCBSP_REG_##reg, val)
73#define MCBSP_READ_CACHE(mcbsp, reg) \
74 omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1)
75
76#define MCBSP_ST_READ(mcbsp, reg) \
77 omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg)
78#define MCBSP_ST_WRITE(mcbsp, reg, val) \
79 omap_mcbsp_st_write(mcbsp, OMAP_ST_REG_##reg, val)
80
81static void omap_mcbsp_dump_reg(struct omap_mcbsp *mcbsp)
82{
83 dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id);
84 dev_dbg(mcbsp->dev, "DRR2: 0x%04x\n",
85 MCBSP_READ(mcbsp, DRR2));
86 dev_dbg(mcbsp->dev, "DRR1: 0x%04x\n",
87 MCBSP_READ(mcbsp, DRR1));
88 dev_dbg(mcbsp->dev, "DXR2: 0x%04x\n",
89 MCBSP_READ(mcbsp, DXR2));
90 dev_dbg(mcbsp->dev, "DXR1: 0x%04x\n",
91 MCBSP_READ(mcbsp, DXR1));
92 dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n",
93 MCBSP_READ(mcbsp, SPCR2));
94 dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n",
95 MCBSP_READ(mcbsp, SPCR1));
96 dev_dbg(mcbsp->dev, "RCR2: 0x%04x\n",
97 MCBSP_READ(mcbsp, RCR2));
98 dev_dbg(mcbsp->dev, "RCR1: 0x%04x\n",
99 MCBSP_READ(mcbsp, RCR1));
100 dev_dbg(mcbsp->dev, "XCR2: 0x%04x\n",
101 MCBSP_READ(mcbsp, XCR2));
102 dev_dbg(mcbsp->dev, "XCR1: 0x%04x\n",
103 MCBSP_READ(mcbsp, XCR1));
104 dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n",
105 MCBSP_READ(mcbsp, SRGR2));
106 dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n",
107 MCBSP_READ(mcbsp, SRGR1));
108 dev_dbg(mcbsp->dev, "PCR0: 0x%04x\n",
109 MCBSP_READ(mcbsp, PCR0));
110 dev_dbg(mcbsp->dev, "***********************\n");
111}
112
113static irqreturn_t omap_mcbsp_irq_handler(int irq, void *dev_id)
114{
115 struct omap_mcbsp *mcbsp = dev_id;
116 u16 irqst;
117
118 irqst = MCBSP_READ(mcbsp, IRQST);
119 dev_dbg(mcbsp->dev, "IRQ callback : 0x%x\n", irqst);
120
121 if (irqst & RSYNCERREN)
122 dev_err(mcbsp->dev, "RX Frame Sync Error!\n");
123 if (irqst & RFSREN)
124 dev_dbg(mcbsp->dev, "RX Frame Sync\n");
125 if (irqst & REOFEN)
126 dev_dbg(mcbsp->dev, "RX End Of Frame\n");
127 if (irqst & RRDYEN)
128 dev_dbg(mcbsp->dev, "RX Buffer Threshold Reached\n");
129 if (irqst & RUNDFLEN)
130 dev_err(mcbsp->dev, "RX Buffer Underflow!\n");
131 if (irqst & ROVFLEN)
132 dev_err(mcbsp->dev, "RX Buffer Overflow!\n");
133
134 if (irqst & XSYNCERREN)
135 dev_err(mcbsp->dev, "TX Frame Sync Error!\n");
136 if (irqst & XFSXEN)
137 dev_dbg(mcbsp->dev, "TX Frame Sync\n");
138 if (irqst & XEOFEN)
139 dev_dbg(mcbsp->dev, "TX End Of Frame\n");
140 if (irqst & XRDYEN)
141 dev_dbg(mcbsp->dev, "TX Buffer threshold Reached\n");
142 if (irqst & XUNDFLEN)
143 dev_err(mcbsp->dev, "TX Buffer Underflow!\n");
144 if (irqst & XOVFLEN)
145 dev_err(mcbsp->dev, "TX Buffer Overflow!\n");
146 if (irqst & XEMPTYEOFEN)
147 dev_dbg(mcbsp->dev, "TX Buffer empty at end of frame\n");
148
149 MCBSP_WRITE(mcbsp, IRQST, irqst);
150
151 return IRQ_HANDLED;
152}
153
154static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
155{
156 struct omap_mcbsp *mcbsp_tx = dev_id;
157 u16 irqst_spcr2;
158
159 irqst_spcr2 = MCBSP_READ(mcbsp_tx, SPCR2);
160 dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", irqst_spcr2);
161
162 if (irqst_spcr2 & XSYNC_ERR) {
163 dev_err(mcbsp_tx->dev, "TX Frame Sync Error! : 0x%x\n",
164 irqst_spcr2);
165 /* Writing zero to XSYNC_ERR clears the IRQ */
166 MCBSP_WRITE(mcbsp_tx, SPCR2, MCBSP_READ_CACHE(mcbsp_tx, SPCR2));
167 }
168
169 return IRQ_HANDLED;
170}
171
172static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
173{
174 struct omap_mcbsp *mcbsp_rx = dev_id;
175 u16 irqst_spcr1;
176
177 irqst_spcr1 = MCBSP_READ(mcbsp_rx, SPCR1);
178 dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", irqst_spcr1);
179
180 if (irqst_spcr1 & RSYNC_ERR) {
181 dev_err(mcbsp_rx->dev, "RX Frame Sync Error! : 0x%x\n",
182 irqst_spcr1);
183 /* Writing zero to RSYNC_ERR clears the IRQ */
184 MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1));
185 }
186
187 return IRQ_HANDLED;
188}
189
190/*
191 * omap_mcbsp_config simply write a config to the
192 * appropriate McBSP.
193 * You either call this function or set the McBSP registers
194 * by yourself before calling omap_mcbsp_start().
195 */
196void omap_mcbsp_config(struct omap_mcbsp *mcbsp,
197 const struct omap_mcbsp_reg_cfg *config)
198{
199 dev_dbg(mcbsp->dev, "Configuring McBSP%d phys_base: 0x%08lx\n",
200 mcbsp->id, mcbsp->phys_base);
201
202 /* We write the given config */
203 MCBSP_WRITE(mcbsp, SPCR2, config->spcr2);
204 MCBSP_WRITE(mcbsp, SPCR1, config->spcr1);
205 MCBSP_WRITE(mcbsp, RCR2, config->rcr2);
206 MCBSP_WRITE(mcbsp, RCR1, config->rcr1);
207 MCBSP_WRITE(mcbsp, XCR2, config->xcr2);
208 MCBSP_WRITE(mcbsp, XCR1, config->xcr1);
209 MCBSP_WRITE(mcbsp, SRGR2, config->srgr2);
210 MCBSP_WRITE(mcbsp, SRGR1, config->srgr1);
211 MCBSP_WRITE(mcbsp, MCR2, config->mcr2);
212 MCBSP_WRITE(mcbsp, MCR1, config->mcr1);
213 MCBSP_WRITE(mcbsp, PCR0, config->pcr0);
214 if (mcbsp->pdata->has_ccr) {
215 MCBSP_WRITE(mcbsp, XCCR, config->xccr);
216 MCBSP_WRITE(mcbsp, RCCR, config->rccr);
217 }
218 /* Enable wakeup behavior */
219 if (mcbsp->pdata->has_wakeup)
220 MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
221
222 /* Enable TX/RX sync error interrupts by default */
223 if (mcbsp->irq)
224 MCBSP_WRITE(mcbsp, IRQEN, RSYNCERREN | XSYNCERREN |
225 RUNDFLEN | ROVFLEN | XUNDFLEN | XOVFLEN);
226}
227
228/**
229 * omap_mcbsp_dma_reg_params - returns the address of mcbsp data register
230 * @id - mcbsp id
231 * @stream - indicates the direction of data flow (rx or tx)
232 *
233 * Returns the address of mcbsp data transmit register or data receive register
234 * to be used by DMA for transferring/receiving data based on the value of
235 * @stream for the requested mcbsp given by @id
236 */
237static int omap_mcbsp_dma_reg_params(struct omap_mcbsp *mcbsp,
238 unsigned int stream)
239{
240 int data_reg;
241
242 if (mcbsp->pdata->reg_size == 2) {
243 if (stream)
244 data_reg = OMAP_MCBSP_REG_DRR1;
245 else
246 data_reg = OMAP_MCBSP_REG_DXR1;
247 } else {
248 if (stream)
249 data_reg = OMAP_MCBSP_REG_DRR;
250 else
251 data_reg = OMAP_MCBSP_REG_DXR;
252 }
253
254 return mcbsp->phys_dma_base + data_reg * mcbsp->pdata->reg_step;
255}
256
257static void omap_st_on(struct omap_mcbsp *mcbsp)
258{
259 unsigned int w;
260
261 if (mcbsp->pdata->force_ick_on)
262 mcbsp->pdata->force_ick_on(mcbsp->st_data->mcbsp_iclk, true);
263
264 /* Disable Sidetone clock auto-gating for normal operation */
265 w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
266 MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w & ~(ST_AUTOIDLE));
267
268 /* Enable McBSP Sidetone */
269 w = MCBSP_READ(mcbsp, SSELCR);
270 MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN);
271
272 /* Enable Sidetone from Sidetone Core */
273 w = MCBSP_ST_READ(mcbsp, SSELCR);
274 MCBSP_ST_WRITE(mcbsp, SSELCR, w | ST_SIDETONEEN);
275}
276
277static void omap_st_off(struct omap_mcbsp *mcbsp)
278{
279 unsigned int w;
280
281 w = MCBSP_ST_READ(mcbsp, SSELCR);
282 MCBSP_ST_WRITE(mcbsp, SSELCR, w & ~(ST_SIDETONEEN));
283
284 w = MCBSP_READ(mcbsp, SSELCR);
285 MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN));
286
287 /* Enable Sidetone clock auto-gating to reduce power consumption */
288 w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
289 MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w | ST_AUTOIDLE);
290
291 if (mcbsp->pdata->force_ick_on)
292 mcbsp->pdata->force_ick_on(mcbsp->st_data->mcbsp_iclk, false);
293}
294
295static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
296{
297 u16 val, i;
298
299 val = MCBSP_ST_READ(mcbsp, SSELCR);
300
301 if (val & ST_COEFFWREN)
302 MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));
303
304 MCBSP_ST_WRITE(mcbsp, SSELCR, val | ST_COEFFWREN);
305
306 for (i = 0; i < 128; i++)
307 MCBSP_ST_WRITE(mcbsp, SFIRCR, fir[i]);
308
309 i = 0;
310
311 val = MCBSP_ST_READ(mcbsp, SSELCR);
312 while (!(val & ST_COEFFWRDONE) && (++i < 1000))
313 val = MCBSP_ST_READ(mcbsp, SSELCR);
314
315 MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));
316
317 if (i == 1000)
318 dev_err(mcbsp->dev, "McBSP FIR load error!\n");
319}
320
321static void omap_st_chgain(struct omap_mcbsp *mcbsp)
322{
323 u16 w;
324 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
325
326 w = MCBSP_ST_READ(mcbsp, SSELCR);
327
328 MCBSP_ST_WRITE(mcbsp, SGAINCR, ST_CH0GAIN(st_data->ch0gain) | \
329 ST_CH1GAIN(st_data->ch1gain));
330}
331
332int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain)
333{
334 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
335 int ret = 0;
336
337 if (!st_data)
338 return -ENOENT;
339
340 spin_lock_irq(&mcbsp->lock);
341 if (channel == 0)
342 st_data->ch0gain = chgain;
343 else if (channel == 1)
344 st_data->ch1gain = chgain;
345 else
346 ret = -EINVAL;
347
348 if (st_data->enabled)
349 omap_st_chgain(mcbsp);
350 spin_unlock_irq(&mcbsp->lock);
351
352 return ret;
353}
354
355int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain)
356{
357 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
358 int ret = 0;
359
360 if (!st_data)
361 return -ENOENT;
362
363 spin_lock_irq(&mcbsp->lock);
364 if (channel == 0)
365 *chgain = st_data->ch0gain;
366 else if (channel == 1)
367 *chgain = st_data->ch1gain;
368 else
369 ret = -EINVAL;
370 spin_unlock_irq(&mcbsp->lock);
371
372 return ret;
373}
374
375static int omap_st_start(struct omap_mcbsp *mcbsp)
376{
377 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
378
379 if (st_data->enabled && !st_data->running) {
380 omap_st_fir_write(mcbsp, st_data->taps);
381 omap_st_chgain(mcbsp);
382
383 if (!mcbsp->free) {
384 omap_st_on(mcbsp);
385 st_data->running = 1;
386 }
387 }
388
389 return 0;
390}
391
392int omap_st_enable(struct omap_mcbsp *mcbsp)
393{
394 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
395
396 if (!st_data)
397 return -ENODEV;
398
399 spin_lock_irq(&mcbsp->lock);
400 st_data->enabled = 1;
401 omap_st_start(mcbsp);
402 spin_unlock_irq(&mcbsp->lock);
403
404 return 0;
405}
406
407static int omap_st_stop(struct omap_mcbsp *mcbsp)
408{
409 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
410
411 if (st_data->running) {
412 if (!mcbsp->free) {
413 omap_st_off(mcbsp);
414 st_data->running = 0;
415 }
416 }
417
418 return 0;
419}
420
421int omap_st_disable(struct omap_mcbsp *mcbsp)
422{
423 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
424 int ret = 0;
425
426 if (!st_data)
427 return -ENODEV;
428
429 spin_lock_irq(&mcbsp->lock);
430 omap_st_stop(mcbsp);
431 st_data->enabled = 0;
432 spin_unlock_irq(&mcbsp->lock);
433
434 return ret;
435}
436
437int omap_st_is_enabled(struct omap_mcbsp *mcbsp)
438{
439 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
440
441 if (!st_data)
442 return -ENODEV;
443
444 return st_data->enabled;
445}
446
447/*
448 * omap_mcbsp_set_rx_threshold configures the transmit threshold in words.
449 * The threshold parameter is 1 based, and it is converted (threshold - 1)
450 * for the THRSH2 register.
451 */
452void omap_mcbsp_set_tx_threshold(struct omap_mcbsp *mcbsp, u16 threshold)
453{
454 if (mcbsp->pdata->buffer_size == 0)
455 return;
456
457 if (threshold && threshold <= mcbsp->max_tx_thres)
458 MCBSP_WRITE(mcbsp, THRSH2, threshold - 1);
459}
460
461/*
462 * omap_mcbsp_set_rx_threshold configures the receive threshold in words.
463 * The threshold parameter is 1 based, and it is converted (threshold - 1)
464 * for the THRSH1 register.
465 */
466void omap_mcbsp_set_rx_threshold(struct omap_mcbsp *mcbsp, u16 threshold)
467{
468 if (mcbsp->pdata->buffer_size == 0)
469 return;
470
471 if (threshold && threshold <= mcbsp->max_rx_thres)
472 MCBSP_WRITE(mcbsp, THRSH1, threshold - 1);
473}
474
475/*
476 * omap_mcbsp_get_tx_delay returns the number of used slots in the McBSP FIFO
477 */
478u16 omap_mcbsp_get_tx_delay(struct omap_mcbsp *mcbsp)
479{
480 u16 buffstat;
481
482 if (mcbsp->pdata->buffer_size == 0)
483 return 0;
484
485 /* Returns the number of free locations in the buffer */
486 buffstat = MCBSP_READ(mcbsp, XBUFFSTAT);
487
488 /* Number of slots are different in McBSP ports */
489 return mcbsp->pdata->buffer_size - buffstat;
490}
491
492/*
493 * omap_mcbsp_get_rx_delay returns the number of free slots in the McBSP FIFO
494 * to reach the threshold value (when the DMA will be triggered to read it)
495 */
496u16 omap_mcbsp_get_rx_delay(struct omap_mcbsp *mcbsp)
497{
498 u16 buffstat, threshold;
499
500 if (mcbsp->pdata->buffer_size == 0)
501 return 0;
502
503 /* Returns the number of used locations in the buffer */
504 buffstat = MCBSP_READ(mcbsp, RBUFFSTAT);
505 /* RX threshold */
506 threshold = MCBSP_READ(mcbsp, THRSH1);
507
508 /* Return the number of location till we reach the threshold limit */
509 if (threshold <= buffstat)
510 return 0;
511 else
512 return threshold - buffstat;
513}
514
515int omap_mcbsp_request(struct omap_mcbsp *mcbsp)
516{
517 void *reg_cache;
518 int err;
519
520 reg_cache = kzalloc(mcbsp->reg_cache_size, GFP_KERNEL);
521 if (!reg_cache) {
522 return -ENOMEM;
523 }
524
525 spin_lock(&mcbsp->lock);
526 if (!mcbsp->free) {
527 dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
528 mcbsp->id);
529 err = -EBUSY;
530 goto err_kfree;
531 }
532
533 mcbsp->free = false;
534 mcbsp->reg_cache = reg_cache;
535 spin_unlock(&mcbsp->lock);
536
537 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
538 mcbsp->pdata->ops->request(mcbsp->id - 1);
539
540 /*
541 * Make sure that transmitter, receiver and sample-rate generator are
542 * not running before activating IRQs.
543 */
544 MCBSP_WRITE(mcbsp, SPCR1, 0);
545 MCBSP_WRITE(mcbsp, SPCR2, 0);
546
547 if (mcbsp->irq) {
548 err = request_irq(mcbsp->irq, omap_mcbsp_irq_handler, 0,
549 "McBSP", (void *)mcbsp);
550 if (err != 0) {
551 dev_err(mcbsp->dev, "Unable to request IRQ\n");
552 goto err_clk_disable;
553 }
554 } else {
555 err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler, 0,
556 "McBSP TX", (void *)mcbsp);
557 if (err != 0) {
558 dev_err(mcbsp->dev, "Unable to request TX IRQ\n");
559 goto err_clk_disable;
560 }
561
562 err = request_irq(mcbsp->rx_irq, omap_mcbsp_rx_irq_handler, 0,
563 "McBSP RX", (void *)mcbsp);
564 if (err != 0) {
565 dev_err(mcbsp->dev, "Unable to request RX IRQ\n");
566 goto err_free_irq;
567 }
568 }
569
570 return 0;
571err_free_irq:
572 free_irq(mcbsp->tx_irq, (void *)mcbsp);
573err_clk_disable:
574 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
575 mcbsp->pdata->ops->free(mcbsp->id - 1);
576
577 /* Disable wakeup behavior */
578 if (mcbsp->pdata->has_wakeup)
579 MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
580
581 spin_lock(&mcbsp->lock);
582 mcbsp->free = true;
583 mcbsp->reg_cache = NULL;
584err_kfree:
585 spin_unlock(&mcbsp->lock);
586 kfree(reg_cache);
587
588 return err;
589}
590
591void omap_mcbsp_free(struct omap_mcbsp *mcbsp)
592{
593 void *reg_cache;
594
595 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
596 mcbsp->pdata->ops->free(mcbsp->id - 1);
597
598 /* Disable wakeup behavior */
599 if (mcbsp->pdata->has_wakeup)
600 MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
601
602 /* Disable interrupt requests */
603 if (mcbsp->irq)
604 MCBSP_WRITE(mcbsp, IRQEN, 0);
605
606 if (mcbsp->irq) {
607 free_irq(mcbsp->irq, (void *)mcbsp);
608 } else {
609 free_irq(mcbsp->rx_irq, (void *)mcbsp);
610 free_irq(mcbsp->tx_irq, (void *)mcbsp);
611 }
612
613 reg_cache = mcbsp->reg_cache;
614
615 /*
616 * Select CLKS source from internal source unconditionally before
617 * marking the McBSP port as free.
618 * If the external clock source via MCBSP_CLKS pin has been selected the
619 * system will refuse to enter idle if the CLKS pin source is not reset
620 * back to internal source.
621 */
622 if (!mcbsp_omap1())
623 omap2_mcbsp_set_clks_src(mcbsp, MCBSP_CLKS_PRCM_SRC);
624
625 spin_lock(&mcbsp->lock);
626 if (mcbsp->free)
627 dev_err(mcbsp->dev, "McBSP%d was not reserved\n", mcbsp->id);
628 else
629 mcbsp->free = true;
630 mcbsp->reg_cache = NULL;
631 spin_unlock(&mcbsp->lock);
632
633 kfree(reg_cache);
634}
635
636/*
637 * Here we start the McBSP, by enabling transmitter, receiver or both.
638 * If no transmitter or receiver is active prior calling, then sample-rate
639 * generator and frame sync are started.
640 */
641void omap_mcbsp_start(struct omap_mcbsp *mcbsp, int tx, int rx)
642{
643 int enable_srg = 0;
644 u16 w;
645
646 if (mcbsp->st_data)
647 omap_st_start(mcbsp);
648
649 /* Only enable SRG, if McBSP is master */
650 w = MCBSP_READ_CACHE(mcbsp, PCR0);
651 if (w & (FSXM | FSRM | CLKXM | CLKRM))
652 enable_srg = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
653 MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
654
655 if (enable_srg) {
656 /* Start the sample generator */
657 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
658 MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 6));
659 }
660
661 /* Enable transmitter and receiver */
662 tx &= 1;
663 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
664 MCBSP_WRITE(mcbsp, SPCR2, w | tx);
665
666 rx &= 1;
667 w = MCBSP_READ_CACHE(mcbsp, SPCR1);
668 MCBSP_WRITE(mcbsp, SPCR1, w | rx);
669
670 /*
671 * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec
672 * REVISIT: 100us may give enough time for two CLKSRG, however
673 * due to some unknown PM related, clock gating etc. reason it
674 * is now at 500us.
675 */
676 udelay(500);
677
678 if (enable_srg) {
679 /* Start frame sync */
680 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
681 MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7));
682 }
683
684 if (mcbsp->pdata->has_ccr) {
685 /* Release the transmitter and receiver */
686 w = MCBSP_READ_CACHE(mcbsp, XCCR);
687 w &= ~(tx ? XDISABLE : 0);
688 MCBSP_WRITE(mcbsp, XCCR, w);
689 w = MCBSP_READ_CACHE(mcbsp, RCCR);
690 w &= ~(rx ? RDISABLE : 0);
691 MCBSP_WRITE(mcbsp, RCCR, w);
692 }
693
694 /* Dump McBSP Regs */
695 omap_mcbsp_dump_reg(mcbsp);
696}
697
698void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx)
699{
700 int idle;
701 u16 w;
702
703 /* Reset transmitter */
704 tx &= 1;
705 if (mcbsp->pdata->has_ccr) {
706 w = MCBSP_READ_CACHE(mcbsp, XCCR);
707 w |= (tx ? XDISABLE : 0);
708 MCBSP_WRITE(mcbsp, XCCR, w);
709 }
710 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
711 MCBSP_WRITE(mcbsp, SPCR2, w & ~tx);
712
713 /* Reset receiver */
714 rx &= 1;
715 if (mcbsp->pdata->has_ccr) {
716 w = MCBSP_READ_CACHE(mcbsp, RCCR);
717 w |= (rx ? RDISABLE : 0);
718 MCBSP_WRITE(mcbsp, RCCR, w);
719 }
720 w = MCBSP_READ_CACHE(mcbsp, SPCR1);
721 MCBSP_WRITE(mcbsp, SPCR1, w & ~rx);
722
723 idle = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
724 MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
725
726 if (idle) {
727 /* Reset the sample rate generator */
728 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
729 MCBSP_WRITE(mcbsp, SPCR2, w & ~(1 << 6));
730 }
731
732 if (mcbsp->st_data)
733 omap_st_stop(mcbsp);
734}
735
736int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id)
737{
738 struct clk *fck_src;
739 const char *src;
740 int r;
741
742 if (fck_src_id == MCBSP_CLKS_PAD_SRC)
743 src = "pad_fck";
744 else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
745 src = "prcm_fck";
746 else
747 return -EINVAL;
748
749 fck_src = clk_get(mcbsp->dev, src);
750 if (IS_ERR(fck_src)) {
751 dev_err(mcbsp->dev, "CLKS: could not clk_get() %s\n", src);
752 return -EINVAL;
753 }
754
755 pm_runtime_put_sync(mcbsp->dev);
756
757 r = clk_set_parent(mcbsp->fclk, fck_src);
758 if (r) {
759 dev_err(mcbsp->dev, "CLKS: could not clk_set_parent() to %s\n",
760 src);
761 clk_put(fck_src);
762 return r;
763 }
764
765 pm_runtime_get_sync(mcbsp->dev);
766
767 clk_put(fck_src);
768
769 return 0;
770
771}
772
773#define max_thres(m) (mcbsp->pdata->buffer_size)
774#define valid_threshold(m, val) ((val) <= max_thres(m))
775#define THRESHOLD_PROP_BUILDER(prop) \
776static ssize_t prop##_show(struct device *dev, \
777 struct device_attribute *attr, char *buf) \
778{ \
779 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
780 \
781 return sprintf(buf, "%u\n", mcbsp->prop); \
782} \
783 \
784static ssize_t prop##_store(struct device *dev, \
785 struct device_attribute *attr, \
786 const char *buf, size_t size) \
787{ \
788 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
789 unsigned long val; \
790 int status; \
791 \
792 status = kstrtoul(buf, 0, &val); \
793 if (status) \
794 return status; \
795 \
796 if (!valid_threshold(mcbsp, val)) \
797 return -EDOM; \
798 \
799 mcbsp->prop = val; \
800 return size; \
801} \
802 \
803static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store);
804
805THRESHOLD_PROP_BUILDER(max_tx_thres);
806THRESHOLD_PROP_BUILDER(max_rx_thres);
807
808static const char *dma_op_modes[] = {
809 "element", "threshold",
810};
811
812static ssize_t dma_op_mode_show(struct device *dev,
813 struct device_attribute *attr, char *buf)
814{
815 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
816 int dma_op_mode, i = 0;
817 ssize_t len = 0;
818 const char * const *s;
819
820 dma_op_mode = mcbsp->dma_op_mode;
821
822 for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) {
823 if (dma_op_mode == i)
824 len += sprintf(buf + len, "[%s] ", *s);
825 else
826 len += sprintf(buf + len, "%s ", *s);
827 }
828 len += sprintf(buf + len, "\n");
829
830 return len;
831}
832
833static ssize_t dma_op_mode_store(struct device *dev,
834 struct device_attribute *attr,
835 const char *buf, size_t size)
836{
837 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
838 int i;
839
840 i = sysfs_match_string(dma_op_modes, buf);
841 if (i < 0)
842 return i;
843
844 spin_lock_irq(&mcbsp->lock);
845 if (!mcbsp->free) {
846 size = -EBUSY;
847 goto unlock;
848 }
849 mcbsp->dma_op_mode = i;
850
851unlock:
852 spin_unlock_irq(&mcbsp->lock);
853
854 return size;
855}
856
857static DEVICE_ATTR_RW(dma_op_mode);
858
859static const struct attribute *additional_attrs[] = {
860 &dev_attr_max_tx_thres.attr,
861 &dev_attr_max_rx_thres.attr,
862 &dev_attr_dma_op_mode.attr,
863 NULL,
864};
865
866static const struct attribute_group additional_attr_group = {
867 .attrs = (struct attribute **)additional_attrs,
868};
869
870static ssize_t st_taps_show(struct device *dev,
871 struct device_attribute *attr, char *buf)
872{
873 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
874 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
875 ssize_t status = 0;
876 int i;
877
878 spin_lock_irq(&mcbsp->lock);
879 for (i = 0; i < st_data->nr_taps; i++)
880 status += sprintf(&buf[status], (i ? ", %d" : "%d"),
881 st_data->taps[i]);
882 if (i)
883 status += sprintf(&buf[status], "\n");
884 spin_unlock_irq(&mcbsp->lock);
885
886 return status;
887}
888
889static ssize_t st_taps_store(struct device *dev,
890 struct device_attribute *attr,
891 const char *buf, size_t size)
892{
893 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
894 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
895 int val, tmp, status, i = 0;
896
897 spin_lock_irq(&mcbsp->lock);
898 memset(st_data->taps, 0, sizeof(st_data->taps));
899 st_data->nr_taps = 0;
900
901 do {
902 status = sscanf(buf, "%d%n", &val, &tmp);
903 if (status < 0 || status == 0) {
904 size = -EINVAL;
905 goto out;
906 }
907 if (val < -32768 || val > 32767) {
908 size = -EINVAL;
909 goto out;
910 }
911 st_data->taps[i++] = val;
912 buf += tmp;
913 if (*buf != ',')
914 break;
915 buf++;
916 } while (1);
917
918 st_data->nr_taps = i;
919
920out:
921 spin_unlock_irq(&mcbsp->lock);
922
923 return size;
924}
925
926static DEVICE_ATTR_RW(st_taps);
927
928static const struct attribute *sidetone_attrs[] = {
929 &dev_attr_st_taps.attr,
930 NULL,
931};
932
933static const struct attribute_group sidetone_attr_group = {
934 .attrs = (struct attribute **)sidetone_attrs,
935};
936
937static int omap_st_add(struct omap_mcbsp *mcbsp, struct resource *res)
938{
939 struct omap_mcbsp_st_data *st_data;
940 int err;
941
942 st_data = devm_kzalloc(mcbsp->dev, sizeof(*mcbsp->st_data), GFP_KERNEL);
943 if (!st_data)
944 return -ENOMEM;
945
946 st_data->mcbsp_iclk = clk_get(mcbsp->dev, "ick");
947 if (IS_ERR(st_data->mcbsp_iclk)) {
948 dev_warn(mcbsp->dev,
949 "Failed to get ick, sidetone might be broken\n");
950 st_data->mcbsp_iclk = NULL;
951 }
952
953 st_data->io_base_st = devm_ioremap(mcbsp->dev, res->start,
954 resource_size(res));
955 if (!st_data->io_base_st)
956 return -ENOMEM;
957
958 err = sysfs_create_group(&mcbsp->dev->kobj, &sidetone_attr_group);
959 if (err)
960 return err;
961
962 mcbsp->st_data = st_data;
963 return 0;
964}
965
966/*
967 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
968 * 730 has only 2 McBSP, and both of them are MPU peripherals.
969 */
970int omap_mcbsp_init(struct platform_device *pdev)
971{
972 struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
973 struct resource *res;
974 int ret = 0;
975
976 spin_lock_init(&mcbsp->lock);
977 mcbsp->free = true;
978
979 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
980 if (!res)
981 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
982
983 mcbsp->io_base = devm_ioremap_resource(&pdev->dev, res);
984 if (IS_ERR(mcbsp->io_base))
985 return PTR_ERR(mcbsp->io_base);
986
987 mcbsp->phys_base = res->start;
988 mcbsp->reg_cache_size = resource_size(res);
989
990 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma");
991 if (!res)
992 mcbsp->phys_dma_base = mcbsp->phys_base;
993 else
994 mcbsp->phys_dma_base = res->start;
995
996 /*
997 * OMAP1, 2 uses two interrupt lines: TX, RX
998 * OMAP2430, OMAP3 SoC have combined IRQ line as well.
999 * OMAP4 and newer SoC only have the combined IRQ line.
1000 * Use the combined IRQ if available since it gives better debugging
1001 * possibilities.
1002 */
1003 mcbsp->irq = platform_get_irq_byname(pdev, "common");
1004 if (mcbsp->irq == -ENXIO) {
1005 mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx");
1006
1007 if (mcbsp->tx_irq == -ENXIO) {
1008 mcbsp->irq = platform_get_irq(pdev, 0);
1009 mcbsp->tx_irq = 0;
1010 } else {
1011 mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx");
1012 mcbsp->irq = 0;
1013 }
1014 }
1015
1016 if (!pdev->dev.of_node) {
1017 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
1018 if (!res) {
1019 dev_err(&pdev->dev, "invalid tx DMA channel\n");
1020 return -ENODEV;
1021 }
1022 mcbsp->dma_req[0] = res->start;
1023 mcbsp->dma_data[0].filter_data = &mcbsp->dma_req[0];
1024
1025 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
1026 if (!res) {
1027 dev_err(&pdev->dev, "invalid rx DMA channel\n");
1028 return -ENODEV;
1029 }
1030 mcbsp->dma_req[1] = res->start;
1031 mcbsp->dma_data[1].filter_data = &mcbsp->dma_req[1];
1032 } else {
1033 mcbsp->dma_data[0].filter_data = "tx";
1034 mcbsp->dma_data[1].filter_data = "rx";
1035 }
1036
1037 mcbsp->dma_data[0].addr = omap_mcbsp_dma_reg_params(mcbsp, 0);
1038 mcbsp->dma_data[0].maxburst = 4;
1039
1040 mcbsp->dma_data[1].addr = omap_mcbsp_dma_reg_params(mcbsp, 1);
1041 mcbsp->dma_data[1].maxburst = 4;
1042
1043 mcbsp->fclk = clk_get(&pdev->dev, "fck");
1044 if (IS_ERR(mcbsp->fclk)) {
1045 ret = PTR_ERR(mcbsp->fclk);
1046 dev_err(mcbsp->dev, "unable to get fck: %d\n", ret);
1047 return ret;
1048 }
1049
1050 mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
1051 if (mcbsp->pdata->buffer_size) {
1052 /*
1053 * Initially configure the maximum thresholds to a safe value.
1054 * The McBSP FIFO usage with these values should not go under
1055 * 16 locations.
1056 * If the whole FIFO without safety buffer is used, than there
1057 * is a possibility that the DMA will be not able to push the
1058 * new data on time, causing channel shifts in runtime.
1059 */
1060 mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10;
1061 mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10;
1062
1063 ret = sysfs_create_group(&mcbsp->dev->kobj,
1064 &additional_attr_group);
1065 if (ret) {
1066 dev_err(mcbsp->dev,
1067 "Unable to create additional controls\n");
1068 goto err_thres;
1069 }
1070 } else {
1071 mcbsp->max_tx_thres = -EINVAL;
1072 mcbsp->max_rx_thres = -EINVAL;
1073 }
1074
1075 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sidetone");
1076 if (res) {
1077 ret = omap_st_add(mcbsp, res);
1078 if (ret) {
1079 dev_err(mcbsp->dev,
1080 "Unable to create sidetone controls\n");
1081 goto err_st;
1082 }
1083 }
1084
1085 return 0;
1086
1087err_st:
1088 if (mcbsp->pdata->buffer_size)
1089 sysfs_remove_group(&mcbsp->dev->kobj, &additional_attr_group);
1090err_thres:
1091 clk_put(mcbsp->fclk);
1092 return ret;
1093}
1094
1095void omap_mcbsp_cleanup(struct omap_mcbsp *mcbsp)
1096{
1097 if (mcbsp->pdata->buffer_size)
1098 sysfs_remove_group(&mcbsp->dev->kobj, &additional_attr_group);
1099
1100 if (mcbsp->st_data) {
1101 sysfs_remove_group(&mcbsp->dev->kobj, &sidetone_attr_group);
1102 clk_put(mcbsp->st_data->mcbsp_iclk);
1103 }
1104}
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 943b44de1464..67159a6b90a8 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -79,7 +79,7 @@ config SND_PXA2XX_SOC_TOSA
79 tristate "SoC AC97 Audio support for Tosa" 79 tristate "SoC AC97 Audio support for Tosa"
80 depends on SND_PXA2XX_SOC && MACH_TOSA 80 depends on SND_PXA2XX_SOC && MACH_TOSA
81 depends on MFD_TC6393XB 81 depends on MFD_TC6393XB
82 depends on !AC97_BUS 82 depends on AC97_BUS=n
83 select SND_PXA2XX_SOC_AC97 83 select SND_PXA2XX_SOC_AC97
84 select SND_SOC_WM9712 84 select SND_SOC_WM9712
85 help 85 help
@@ -89,7 +89,7 @@ config SND_PXA2XX_SOC_TOSA
89config SND_PXA2XX_SOC_E740 89config SND_PXA2XX_SOC_E740
90 tristate "SoC AC97 Audio support for e740" 90 tristate "SoC AC97 Audio support for e740"
91 depends on SND_PXA2XX_SOC && MACH_E740 91 depends on SND_PXA2XX_SOC && MACH_E740
92 depends on !AC97_BUS 92 depends on AC97_BUS=n
93 select SND_SOC_WM9705 93 select SND_SOC_WM9705
94 select SND_PXA2XX_SOC_AC97 94 select SND_PXA2XX_SOC_AC97
95 help 95 help
@@ -99,7 +99,7 @@ config SND_PXA2XX_SOC_E740
99config SND_PXA2XX_SOC_E750 99config SND_PXA2XX_SOC_E750
100 tristate "SoC AC97 Audio support for e750" 100 tristate "SoC AC97 Audio support for e750"
101 depends on SND_PXA2XX_SOC && MACH_E750 101 depends on SND_PXA2XX_SOC && MACH_E750
102 depends on !AC97_BUS 102 depends on AC97_BUS=n
103 select SND_SOC_WM9705 103 select SND_SOC_WM9705
104 select SND_PXA2XX_SOC_AC97 104 select SND_PXA2XX_SOC_AC97
105 help 105 help
@@ -109,7 +109,7 @@ config SND_PXA2XX_SOC_E750
109config SND_PXA2XX_SOC_E800 109config SND_PXA2XX_SOC_E800
110 tristate "SoC AC97 Audio support for e800" 110 tristate "SoC AC97 Audio support for e800"
111 depends on SND_PXA2XX_SOC && MACH_E800 111 depends on SND_PXA2XX_SOC && MACH_E800
112 depends on !AC97_BUS 112 depends on AC97_BUS=n
113 select SND_SOC_WM9712 113 select SND_SOC_WM9712
114 select SND_PXA2XX_SOC_AC97 114 select SND_PXA2XX_SOC_AC97
115 help 115 help
@@ -120,7 +120,7 @@ config SND_PXA2XX_SOC_EM_X270
120 tristate "SoC Audio support for CompuLab EM-x270, eXeda and CM-X300" 120 tristate "SoC Audio support for CompuLab EM-x270, eXeda and CM-X300"
121 depends on SND_PXA2XX_SOC && (MACH_EM_X270 || MACH_EXEDA || \ 121 depends on SND_PXA2XX_SOC && (MACH_EM_X270 || MACH_EXEDA || \
122 MACH_CM_X300) 122 MACH_CM_X300)
123 depends on !AC97_BUS 123 depends on AC97_BUS=n
124 select SND_PXA2XX_SOC_AC97 124 select SND_PXA2XX_SOC_AC97
125 select SND_SOC_WM9712 125 select SND_SOC_WM9712
126 help 126 help
@@ -131,7 +131,7 @@ config SND_PXA2XX_SOC_PALM27X
131 bool "SoC Audio support for Palm T|X, T5, E2 and LifeDrive" 131 bool "SoC Audio support for Palm T|X, T5, E2 and LifeDrive"
132 depends on SND_PXA2XX_SOC && (MACH_PALMLD || MACH_PALMTX || \ 132 depends on SND_PXA2XX_SOC && (MACH_PALMLD || MACH_PALMTX || \
133 MACH_PALMT5 || MACH_PALMTE2) 133 MACH_PALMT5 || MACH_PALMTE2)
134 depends on !AC97_BUS 134 depends on AC97_BUS=n
135 select SND_PXA2XX_SOC_AC97 135 select SND_PXA2XX_SOC_AC97
136 select SND_SOC_WM9712 136 select SND_SOC_WM9712
137 help 137 help
@@ -161,7 +161,7 @@ config SND_SOC_TTC_DKB
161config SND_SOC_ZYLONITE 161config SND_SOC_ZYLONITE
162 tristate "SoC Audio support for Marvell Zylonite" 162 tristate "SoC Audio support for Marvell Zylonite"
163 depends on SND_PXA2XX_SOC && MACH_ZYLONITE 163 depends on SND_PXA2XX_SOC && MACH_ZYLONITE
164 depends on !AC97_BUS 164 depends on AC97_BUS=n
165 select SND_PXA2XX_SOC_AC97 165 select SND_PXA2XX_SOC_AC97
166 select SND_PXA_SOC_SSP 166 select SND_PXA_SOC_SSP
167 select SND_SOC_WM9713 167 select SND_SOC_WM9713
@@ -169,16 +169,6 @@ config SND_SOC_ZYLONITE
169 Say Y if you want to add support for SoC audio on the 169 Say Y if you want to add support for SoC audio on the
170 Marvell Zylonite reference platform. 170 Marvell Zylonite reference platform.
171 171
172config SND_SOC_RAUMFELD
173 tristate "SoC Audio support Raumfeld audio adapter"
174 depends on SND_PXA2XX_SOC && (MACH_RAUMFELD_SPEAKER || MACH_RAUMFELD_CONNECTOR)
175 depends on I2C && SPI_MASTER
176 select SND_PXA_SOC_SSP
177 select SND_SOC_CS4270
178 select SND_SOC_AK4104
179 help
180 Say Y if you want to add support for SoC audio on Raumfeld devices
181
182config SND_PXA2XX_SOC_HX4700 172config SND_PXA2XX_SOC_HX4700
183 tristate "SoC Audio support for HP iPAQ hx4700" 173 tristate "SoC Audio support for HP iPAQ hx4700"
184 depends on SND_PXA2XX_SOC && MACH_H4700 && I2C 174 depends on SND_PXA2XX_SOC && MACH_H4700 && I2C
@@ -201,7 +191,7 @@ config SND_PXA2XX_SOC_MAGICIAN
201config SND_PXA2XX_SOC_MIOA701 191config SND_PXA2XX_SOC_MIOA701
202 tristate "SoC Audio support for MIO A701" 192 tristate "SoC Audio support for MIO A701"
203 depends on SND_PXA2XX_SOC && MACH_MIOA701 193 depends on SND_PXA2XX_SOC && MACH_MIOA701
204 depends on !AC97_BUS 194 depends on AC97_BUS=n
205 select SND_PXA2XX_SOC_AC97 195 select SND_PXA2XX_SOC_AC97
206 select SND_SOC_WM9713 196 select SND_SOC_WM9713
207 help 197 help
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 5b265662f04f..0ab2a9dcb720 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -49,6 +49,5 @@ obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
49obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o 49obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o
50obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o 50obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
51obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o 51obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o
52obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o
53obj-$(CONFIG_SND_MMP_SOC_BROWNSTONE) += snd-soc-brownstone.o 52obj-$(CONFIG_SND_MMP_SOC_BROWNSTONE) += snd-soc-brownstone.o
54obj-$(CONFIG_SND_SOC_TTC_DKB) += snd-soc-ttc-dkb.o 53obj-$(CONFIG_SND_SOC_TTC_DKB) += snd-soc-ttc-dkb.o
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
deleted file mode 100644
index 111a907c4eb9..000000000000
--- a/sound/soc/pxa/raumfeld.c
+++ /dev/null
@@ -1,318 +0,0 @@
1/*
2 * raumfeld_audio.c -- SoC audio for Raumfeld audio devices
3 *
4 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
5 *
6 * based on code from:
7 *
8 * Wolfson Microelectronics PLC.
9 * Openedhand Ltd.
10 * Liam Girdwood <lrg@slimlogic.co.uk>
11 * Richard Purdie <richard@openedhand.com>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 */
18
19#include <linux/module.h>
20#include <linux/i2c.h>
21#include <linux/delay.h>
22#include <linux/gpio.h>
23#include <sound/pcm.h>
24#include <sound/soc.h>
25
26#include <asm/mach-types.h>
27
28#include "pxa-ssp.h"
29
30#define GPIO_SPDIF_RESET (38)
31#define GPIO_MCLK_RESET (111)
32#define GPIO_CODEC_RESET (120)
33
34static struct i2c_client *max9486_client;
35static struct i2c_board_info max9486_hwmon_info = {
36 I2C_BOARD_INFO("max9485", 0x63),
37};
38
39#define MAX9485_MCLK_FREQ_112896 0x22
40#define MAX9485_MCLK_FREQ_122880 0x23
41#define MAX9485_MCLK_FREQ_225792 0x32
42#define MAX9485_MCLK_FREQ_245760 0x33
43
44static void set_max9485_clk(char clk)
45{
46 i2c_master_send(max9486_client, &clk, 1);
47}
48
49static void raumfeld_enable_audio(bool en)
50{
51 if (en) {
52 gpio_set_value(GPIO_MCLK_RESET, 1);
53
54 /* wait some time to let the clocks become stable */
55 msleep(100);
56
57 gpio_set_value(GPIO_SPDIF_RESET, 1);
58 gpio_set_value(GPIO_CODEC_RESET, 1);
59 } else {
60 gpio_set_value(GPIO_MCLK_RESET, 0);
61 gpio_set_value(GPIO_SPDIF_RESET, 0);
62 gpio_set_value(GPIO_CODEC_RESET, 0);
63 }
64}
65
66/* CS4270 */
67static int raumfeld_cs4270_startup(struct snd_pcm_substream *substream)
68{
69 struct snd_soc_pcm_runtime *rtd = substream->private_data;
70 struct snd_soc_dai *codec_dai = rtd->codec_dai;
71
72 /* set freq to 0 to enable all possible codec sample rates */
73 return snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
74}
75
76static void raumfeld_cs4270_shutdown(struct snd_pcm_substream *substream)
77{
78 struct snd_soc_pcm_runtime *rtd = substream->private_data;
79 struct snd_soc_dai *codec_dai = rtd->codec_dai;
80
81 /* set freq to 0 to enable all possible codec sample rates */
82 snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
83}
84
85static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
86 struct snd_pcm_hw_params *params)
87{
88 struct snd_soc_pcm_runtime *rtd = substream->private_data;
89 struct snd_soc_dai *codec_dai = rtd->codec_dai;
90 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
91 unsigned int clk = 0;
92 int ret = 0;
93
94 switch (params_rate(params)) {
95 case 44100:
96 set_max9485_clk(MAX9485_MCLK_FREQ_112896);
97 clk = 11289600;
98 break;
99 case 48000:
100 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
101 clk = 12288000;
102 break;
103 case 88200:
104 set_max9485_clk(MAX9485_MCLK_FREQ_225792);
105 clk = 22579200;
106 break;
107 case 96000:
108 set_max9485_clk(MAX9485_MCLK_FREQ_245760);
109 clk = 24576000;
110 break;
111 default:
112 return -EINVAL;
113 }
114
115 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, 0);
116 if (ret < 0)
117 return ret;
118
119 /* setup the CPU DAI */
120 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, clk);
121 if (ret < 0)
122 return ret;
123
124 ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4);
125 if (ret < 0)
126 return ret;
127
128 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
129 if (ret < 0)
130 return ret;
131
132 return 0;
133}
134
135static const struct snd_soc_ops raumfeld_cs4270_ops = {
136 .startup = raumfeld_cs4270_startup,
137 .shutdown = raumfeld_cs4270_shutdown,
138 .hw_params = raumfeld_cs4270_hw_params,
139};
140
141static int raumfeld_analog_suspend(struct snd_soc_card *card)
142{
143 raumfeld_enable_audio(false);
144 return 0;
145}
146
147static int raumfeld_analog_resume(struct snd_soc_card *card)
148{
149 raumfeld_enable_audio(true);
150 return 0;
151}
152
153/* AK4104 */
154
155static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream,
156 struct snd_pcm_hw_params *params)
157{
158 struct snd_soc_pcm_runtime *rtd = substream->private_data;
159 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
160 int ret = 0, clk = 0;
161
162 switch (params_rate(params)) {
163 case 44100:
164 set_max9485_clk(MAX9485_MCLK_FREQ_112896);
165 clk = 11289600;
166 break;
167 case 48000:
168 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
169 clk = 12288000;
170 break;
171 case 88200:
172 set_max9485_clk(MAX9485_MCLK_FREQ_225792);
173 clk = 22579200;
174 break;
175 case 96000:
176 set_max9485_clk(MAX9485_MCLK_FREQ_245760);
177 clk = 24576000;
178 break;
179 default:
180 return -EINVAL;
181 }
182
183 /* setup the CPU DAI */
184 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, clk);
185 if (ret < 0)
186 return ret;
187
188 ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4);
189 if (ret < 0)
190 return ret;
191
192 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
193 if (ret < 0)
194 return ret;
195
196 return 0;
197}
198
199static struct snd_soc_ops raumfeld_ak4104_ops = {
200 .hw_params = raumfeld_ak4104_hw_params,
201};
202
203#define DAI_LINK_CS4270 \
204{ \
205 .name = "CS4270", \
206 .stream_name = "CS4270", \
207 .cpu_dai_name = "pxa-ssp-dai.0", \
208 .platform_name = "pxa-pcm-audio", \
209 .codec_dai_name = "cs4270-hifi", \
210 .codec_name = "cs4270.0-0048", \
211 .dai_fmt = SND_SOC_DAIFMT_I2S | \
212 SND_SOC_DAIFMT_NB_NF | \
213 SND_SOC_DAIFMT_CBS_CFS, \
214 .ops = &raumfeld_cs4270_ops, \
215}
216
217#define DAI_LINK_AK4104 \
218{ \
219 .name = "ak4104", \
220 .stream_name = "Playback", \
221 .cpu_dai_name = "pxa-ssp-dai.1", \
222 .codec_dai_name = "ak4104-hifi", \
223 .platform_name = "pxa-pcm-audio", \
224 .dai_fmt = SND_SOC_DAIFMT_I2S | \
225 SND_SOC_DAIFMT_NB_NF | \
226 SND_SOC_DAIFMT_CBS_CFS, \
227 .ops = &raumfeld_ak4104_ops, \
228 .codec_name = "spi0.0", \
229}
230
231static struct snd_soc_dai_link snd_soc_raumfeld_connector_dai[] = {
232 DAI_LINK_CS4270,
233 DAI_LINK_AK4104,
234};
235
236static struct snd_soc_dai_link snd_soc_raumfeld_speaker_dai[] = {
237 DAI_LINK_CS4270,
238};
239
240static struct snd_soc_card snd_soc_raumfeld_connector = {
241 .name = "Raumfeld Connector",
242 .owner = THIS_MODULE,
243 .dai_link = snd_soc_raumfeld_connector_dai,
244 .num_links = ARRAY_SIZE(snd_soc_raumfeld_connector_dai),
245 .suspend_post = raumfeld_analog_suspend,
246 .resume_pre = raumfeld_analog_resume,
247};
248
249static struct snd_soc_card snd_soc_raumfeld_speaker = {
250 .name = "Raumfeld Speaker",
251 .owner = THIS_MODULE,
252 .dai_link = snd_soc_raumfeld_speaker_dai,
253 .num_links = ARRAY_SIZE(snd_soc_raumfeld_speaker_dai),
254 .suspend_post = raumfeld_analog_suspend,
255 .resume_pre = raumfeld_analog_resume,
256};
257
258static struct platform_device *raumfeld_audio_device;
259
260static int __init raumfeld_audio_init(void)
261{
262 int ret;
263
264 if (!machine_is_raumfeld_speaker() &&
265 !machine_is_raumfeld_connector())
266 return 0;
267
268 max9486_client = i2c_new_device(i2c_get_adapter(0),
269 &max9486_hwmon_info);
270
271 if (!max9486_client)
272 return -ENOMEM;
273
274 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
275
276 /* Register analog device */
277 raumfeld_audio_device = platform_device_alloc("soc-audio", 0);
278 if (!raumfeld_audio_device)
279 return -ENOMEM;
280
281 if (machine_is_raumfeld_speaker())
282 platform_set_drvdata(raumfeld_audio_device,
283 &snd_soc_raumfeld_speaker);
284
285 if (machine_is_raumfeld_connector())
286 platform_set_drvdata(raumfeld_audio_device,
287 &snd_soc_raumfeld_connector);
288
289 ret = platform_device_add(raumfeld_audio_device);
290 if (ret < 0) {
291 platform_device_put(raumfeld_audio_device);
292 return ret;
293 }
294
295 raumfeld_enable_audio(true);
296 return 0;
297}
298
299static void __exit raumfeld_audio_exit(void)
300{
301 raumfeld_enable_audio(false);
302
303 platform_device_unregister(raumfeld_audio_device);
304
305 i2c_unregister_device(max9486_client);
306
307 gpio_free(GPIO_MCLK_RESET);
308 gpio_free(GPIO_CODEC_RESET);
309 gpio_free(GPIO_SPDIF_RESET);
310}
311
312module_init(raumfeld_audio_init);
313module_exit(raumfeld_audio_exit);
314
315/* Module information */
316MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
317MODULE_DESCRIPTION("Raumfeld audio SoC");
318MODULE_LICENSE("GPL");
diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index 2a4c912d1e48..804ae0d93058 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -66,6 +66,7 @@ config SND_SOC_QDSP6_ASM
66 tristate 66 tristate
67 67
68config SND_SOC_QDSP6_ASM_DAI 68config SND_SOC_QDSP6_ASM_DAI
69 select SND_SOC_COMPRESS
69 tristate 70 tristate
70 71
71config SND_SOC_QDSP6 72config SND_SOC_QDSP6
@@ -100,6 +101,7 @@ config SND_SOC_SDM845
100 depends on QCOM_APR 101 depends on QCOM_APR
101 select SND_SOC_QDSP6 102 select SND_SOC_QDSP6
102 select SND_SOC_QCOM_COMMON 103 select SND_SOC_QCOM_COMMON
104 select SND_SOC_RT5663
103 help 105 help
104 To add support for audio on Qualcomm Technologies Inc. 106 To add support for audio on Qualcomm Technologies Inc.
105 SDM845 SoC-based systems. 107 SDM845 SoC-based systems.
diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c
index d07271ea4c45..028bce671cbc 100644
--- a/sound/soc/qcom/lpass-platform.c
+++ b/sound/soc/qcom/lpass-platform.c
@@ -91,7 +91,7 @@ static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream)
91 if (ret) { 91 if (ret) {
92 dev_err(soc_runtime->dev, 92 dev_err(soc_runtime->dev,
93 "error writing to rdmactl reg: %d\n", ret); 93 "error writing to rdmactl reg: %d\n", ret);
94 return ret; 94 return ret;
95 } 95 }
96 96
97 data->dma_ch = dma_ch; 97 data->dma_ch = dma_ch;
diff --git a/sound/soc/qcom/qdsp6/q6afe-dai.c b/sound/soc/qcom/qdsp6/q6afe-dai.c
index 8f6c8fc073a9..dc645ba4d8d0 100644
--- a/sound/soc/qcom/qdsp6/q6afe-dai.c
+++ b/sound/soc/qcom/qdsp6/q6afe-dai.c
@@ -341,6 +341,7 @@ static int q6afe_dai_prepare(struct snd_pcm_substream *substream,
341 341
342 switch (dai->id) { 342 switch (dai->id) {
343 case HDMI_RX: 343 case HDMI_RX:
344 case DISPLAY_PORT_RX:
344 q6afe_hdmi_port_prepare(dai_data->port[dai->id], 345 q6afe_hdmi_port_prepare(dai_data->port[dai->id],
345 &dai_data->port_config[dai->id].hdmi); 346 &dai_data->port_config[dai->id].hdmi);
346 break; 347 break;
@@ -445,6 +446,7 @@ static int q6afe_mi2s_set_sysclk(struct snd_soc_dai *dai,
445 446
446static const struct snd_soc_dapm_route q6afe_dapm_routes[] = { 447static const struct snd_soc_dapm_route q6afe_dapm_routes[] = {
447 {"HDMI Playback", NULL, "HDMI_RX"}, 448 {"HDMI Playback", NULL, "HDMI_RX"},
449 {"Display Port Playback", NULL, "DISPLAY_PORT_RX"},
448 {"Slimbus1 Playback", NULL, "SLIMBUS_1_RX"}, 450 {"Slimbus1 Playback", NULL, "SLIMBUS_1_RX"},
449 {"Slimbus2 Playback", NULL, "SLIMBUS_2_RX"}, 451 {"Slimbus2 Playback", NULL, "SLIMBUS_2_RX"},
450 {"Slimbus3 Playback", NULL, "SLIMBUS_3_RX"}, 452 {"Slimbus3 Playback", NULL, "SLIMBUS_3_RX"},
@@ -561,13 +563,13 @@ static const struct snd_soc_dapm_route q6afe_dapm_routes[] = {
561 {"QUAT_MI2S_TX", NULL, "Quaternary MI2S Capture"}, 563 {"QUAT_MI2S_TX", NULL, "Quaternary MI2S Capture"},
562}; 564};
563 565
564static struct snd_soc_dai_ops q6hdmi_ops = { 566static const struct snd_soc_dai_ops q6hdmi_ops = {
565 .prepare = q6afe_dai_prepare, 567 .prepare = q6afe_dai_prepare,
566 .hw_params = q6hdmi_hw_params, 568 .hw_params = q6hdmi_hw_params,
567 .shutdown = q6afe_dai_shutdown, 569 .shutdown = q6afe_dai_shutdown,
568}; 570};
569 571
570static struct snd_soc_dai_ops q6i2s_ops = { 572static const struct snd_soc_dai_ops q6i2s_ops = {
571 .prepare = q6afe_dai_prepare, 573 .prepare = q6afe_dai_prepare,
572 .hw_params = q6i2s_hw_params, 574 .hw_params = q6i2s_hw_params,
573 .set_fmt = q6i2s_set_fmt, 575 .set_fmt = q6i2s_set_fmt,
@@ -575,14 +577,14 @@ static struct snd_soc_dai_ops q6i2s_ops = {
575 .set_sysclk = q6afe_mi2s_set_sysclk, 577 .set_sysclk = q6afe_mi2s_set_sysclk,
576}; 578};
577 579
578static struct snd_soc_dai_ops q6slim_ops = { 580static const struct snd_soc_dai_ops q6slim_ops = {
579 .prepare = q6afe_dai_prepare, 581 .prepare = q6afe_dai_prepare,
580 .hw_params = q6slim_hw_params, 582 .hw_params = q6slim_hw_params,
581 .shutdown = q6afe_dai_shutdown, 583 .shutdown = q6afe_dai_shutdown,
582 .set_channel_map = q6slim_set_channel_map, 584 .set_channel_map = q6slim_set_channel_map,
583}; 585};
584 586
585static struct snd_soc_dai_ops q6tdm_ops = { 587static const struct snd_soc_dai_ops q6tdm_ops = {
586 .prepare = q6afe_dai_prepare, 588 .prepare = q6afe_dai_prepare,
587 .shutdown = q6afe_dai_shutdown, 589 .shutdown = q6afe_dai_shutdown,
588 .set_sysclk = q6afe_mi2s_set_sysclk, 590 .set_sysclk = q6afe_mi2s_set_sysclk,
@@ -1090,6 +1092,25 @@ static struct snd_soc_dai_driver q6afe_dais[] = {
1090 Q6AFE_TDM_CAP_DAI("Quinary", 5, QUINARY_TDM_TX_5), 1092 Q6AFE_TDM_CAP_DAI("Quinary", 5, QUINARY_TDM_TX_5),
1091 Q6AFE_TDM_CAP_DAI("Quinary", 6, QUINARY_TDM_TX_6), 1093 Q6AFE_TDM_CAP_DAI("Quinary", 6, QUINARY_TDM_TX_6),
1092 Q6AFE_TDM_CAP_DAI("Quinary", 7, QUINARY_TDM_TX_7), 1094 Q6AFE_TDM_CAP_DAI("Quinary", 7, QUINARY_TDM_TX_7),
1095 {
1096 .playback = {
1097 .stream_name = "Display Port Playback",
1098 .rates = SNDRV_PCM_RATE_48000 |
1099 SNDRV_PCM_RATE_96000 |
1100 SNDRV_PCM_RATE_192000,
1101 .formats = SNDRV_PCM_FMTBIT_S16_LE |
1102 SNDRV_PCM_FMTBIT_S24_LE,
1103 .channels_min = 2,
1104 .channels_max = 8,
1105 .rate_max = 192000,
1106 .rate_min = 48000,
1107 },
1108 .ops = &q6hdmi_ops,
1109 .id = DISPLAY_PORT_RX,
1110 .name = "DISPLAY_PORT",
1111 .probe = msm_dai_q6_dai_probe,
1112 .remove = msm_dai_q6_dai_remove,
1113 },
1093}; 1114};
1094 1115
1095static int q6afe_of_xlate_dai_name(struct snd_soc_component *component, 1116static int q6afe_of_xlate_dai_name(struct snd_soc_component *component,
@@ -1311,6 +1332,7 @@ static const struct snd_soc_dapm_widget q6afe_dai_widgets[] = {
1311 0, 0, 0, 0), 1332 0, 0, 0, 0),
1312 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_7", NULL, 1333 SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_7", NULL,
1313 0, 0, 0, 0), 1334 0, 0, 0, 0),
1335 SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT_RX", "NULL", 0, 0, 0, 0),
1314}; 1336};
1315 1337
1316static const struct snd_soc_component_driver q6afe_dai_component = { 1338static const struct snd_soc_component_driver q6afe_dai_component = {
diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c
index 829b5e987b2a..e0945f7a58c8 100644
--- a/sound/soc/qcom/qdsp6/q6afe.c
+++ b/sound/soc/qcom/qdsp6/q6afe.c
@@ -71,6 +71,7 @@
71/* Port IDs */ 71/* Port IDs */
72#define AFE_API_VERSION_HDMI_CONFIG 0x1 72#define AFE_API_VERSION_HDMI_CONFIG 0x1
73#define AFE_PORT_ID_MULTICHAN_HDMI_RX 0x100E 73#define AFE_PORT_ID_MULTICHAN_HDMI_RX 0x100E
74#define AFE_PORT_ID_HDMI_OVER_DP_RX 0x6020
74 75
75#define AFE_API_VERSION_SLIMBUS_CONFIG 0x1 76#define AFE_API_VERSION_SLIMBUS_CONFIG 0x1
76/* Clock set API version */ 77/* Clock set API version */
@@ -704,6 +705,8 @@ static struct afe_port_map port_maps[AFE_PORT_MAX] = {
704 QUINARY_TDM_RX_7, 1, 1}, 705 QUINARY_TDM_RX_7, 1, 1},
705 [QUINARY_TDM_TX_7] = { AFE_PORT_ID_QUINARY_TDM_TX_7, 706 [QUINARY_TDM_TX_7] = { AFE_PORT_ID_QUINARY_TDM_TX_7,
706 QUINARY_TDM_TX_7, 0, 1}, 707 QUINARY_TDM_TX_7, 0, 1},
708 [DISPLAY_PORT_RX] = { AFE_PORT_ID_HDMI_OVER_DP_RX,
709 DISPLAY_PORT_RX, 1, 1},
707}; 710};
708 711
709static void q6afe_port_free(struct kref *ref) 712static void q6afe_port_free(struct kref *ref)
@@ -1384,6 +1387,7 @@ struct q6afe_port *q6afe_port_get_from_id(struct device *dev, int id)
1384 1387
1385 switch (port_id) { 1388 switch (port_id) {
1386 case AFE_PORT_ID_MULTICHAN_HDMI_RX: 1389 case AFE_PORT_ID_MULTICHAN_HDMI_RX:
1390 case AFE_PORT_ID_HDMI_OVER_DP_RX:
1387 cfg_type = AFE_PARAM_ID_HDMI_CONFIG; 1391 cfg_type = AFE_PARAM_ID_HDMI_CONFIG;
1388 break; 1392 break;
1389 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX: 1393 case AFE_PORT_ID_SLIMBUS_MULTI_CHAN_0_TX:
diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c
index 86115de5c1b2..5b986b74dd36 100644
--- a/sound/soc/qcom/qdsp6/q6asm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6asm-dai.c
@@ -10,6 +10,8 @@
10#include <sound/soc.h> 10#include <sound/soc.h>
11#include <sound/soc-dapm.h> 11#include <sound/soc-dapm.h>
12#include <sound/pcm.h> 12#include <sound/pcm.h>
13#include <linux/spinlock.h>
14#include <sound/compress_driver.h>
13#include <asm/dma.h> 15#include <asm/dma.h>
14#include <linux/dma-mapping.h> 16#include <linux/dma-mapping.h>
15#include <linux/of_device.h> 17#include <linux/of_device.h>
@@ -30,6 +32,15 @@
30#define CAPTURE_MIN_PERIOD_SIZE 320 32#define CAPTURE_MIN_PERIOD_SIZE 320
31#define SID_MASK_DEFAULT 0xF 33#define SID_MASK_DEFAULT 0xF
32 34
35/* Default values used if user space does not set */
36#define COMPR_PLAYBACK_MIN_FRAGMENT_SIZE (8 * 1024)
37#define COMPR_PLAYBACK_MAX_FRAGMENT_SIZE (128 * 1024)
38#define COMPR_PLAYBACK_MIN_NUM_FRAGMENTS (4)
39#define COMPR_PLAYBACK_MAX_NUM_FRAGMENTS (16 * 4)
40#define Q6ASM_DAI_TX_RX 0
41#define Q6ASM_DAI_TX 1
42#define Q6ASM_DAI_RX 2
43
33enum stream_state { 44enum stream_state {
34 Q6ASM_STREAM_IDLE = 0, 45 Q6ASM_STREAM_IDLE = 0,
35 Q6ASM_STREAM_STOPPED, 46 Q6ASM_STREAM_STOPPED,
@@ -38,11 +49,18 @@ enum stream_state {
38 49
39struct q6asm_dai_rtd { 50struct q6asm_dai_rtd {
40 struct snd_pcm_substream *substream; 51 struct snd_pcm_substream *substream;
52 struct snd_compr_stream *cstream;
53 struct snd_compr_params codec_param;
54 struct snd_dma_buffer dma_buffer;
55 spinlock_t lock;
41 phys_addr_t phys; 56 phys_addr_t phys;
42 unsigned int pcm_size; 57 unsigned int pcm_size;
43 unsigned int pcm_count; 58 unsigned int pcm_count;
44 unsigned int pcm_irq_pos; /* IRQ position */ 59 unsigned int pcm_irq_pos; /* IRQ position */
45 unsigned int periods; 60 unsigned int periods;
61 unsigned int bytes_sent;
62 unsigned int bytes_received;
63 unsigned int copied_total;
46 uint16_t bits_per_sample; 64 uint16_t bits_per_sample;
47 uint16_t source; /* Encoding source bit mask */ 65 uint16_t source; /* Encoding source bit mask */
48 struct audio_client *audio_client; 66 struct audio_client *audio_client;
@@ -137,6 +155,21 @@ static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
137 .mask = 0, 155 .mask = 0,
138}; 156};
139 157
158static const struct snd_compr_codec_caps q6asm_compr_caps = {
159 .num_descriptors = 1,
160 .descriptor[0].max_ch = 2,
161 .descriptor[0].sample_rates = { 8000, 11025, 12000, 16000, 22050,
162 24000, 32000, 44100, 48000, 88200,
163 96000, 176400, 192000 },
164 .descriptor[0].num_sample_rates = 13,
165 .descriptor[0].bit_rate[0] = 320,
166 .descriptor[0].bit_rate[1] = 128,
167 .descriptor[0].num_bitrates = 2,
168 .descriptor[0].profiles = 0,
169 .descriptor[0].modes = SND_AUDIOCHANMODE_MP3_STEREO,
170 .descriptor[0].formats = 0,
171};
172
140static void event_handler(uint32_t opcode, uint32_t token, 173static void event_handler(uint32_t opcode, uint32_t token,
141 uint32_t *payload, void *priv) 174 uint32_t *payload, void *priv)
142{ 175{
@@ -460,6 +493,306 @@ static struct snd_pcm_ops q6asm_dai_ops = {
460 .mmap = q6asm_dai_mmap, 493 .mmap = q6asm_dai_mmap,
461}; 494};
462 495
496static void compress_event_handler(uint32_t opcode, uint32_t token,
497 uint32_t *payload, void *priv)
498{
499 struct q6asm_dai_rtd *prtd = priv;
500 struct snd_compr_stream *substream = prtd->cstream;
501 unsigned long flags;
502 uint64_t avail;
503
504 switch (opcode) {
505 case ASM_CLIENT_EVENT_CMD_RUN_DONE:
506 spin_lock_irqsave(&prtd->lock, flags);
507 if (!prtd->bytes_sent) {
508 q6asm_write_async(prtd->audio_client, prtd->pcm_count,
509 0, 0, NO_TIMESTAMP);
510 prtd->bytes_sent += prtd->pcm_count;
511 }
512
513 spin_unlock_irqrestore(&prtd->lock, flags);
514 break;
515
516 case ASM_CLIENT_EVENT_CMD_EOS_DONE:
517 prtd->state = Q6ASM_STREAM_STOPPED;
518 break;
519
520 case ASM_CLIENT_EVENT_DATA_WRITE_DONE:
521 spin_lock_irqsave(&prtd->lock, flags);
522
523 prtd->copied_total += prtd->pcm_count;
524 snd_compr_fragment_elapsed(substream);
525
526 if (prtd->state != Q6ASM_STREAM_RUNNING) {
527 spin_unlock_irqrestore(&prtd->lock, flags);
528 break;
529 }
530
531 avail = prtd->bytes_received - prtd->bytes_sent;
532
533 if (avail >= prtd->pcm_count) {
534 q6asm_write_async(prtd->audio_client,
535 prtd->pcm_count, 0, 0, NO_TIMESTAMP);
536 prtd->bytes_sent += prtd->pcm_count;
537 }
538
539 spin_unlock_irqrestore(&prtd->lock, flags);
540 break;
541
542 default:
543 break;
544 }
545}
546
547static int q6asm_dai_compr_open(struct snd_compr_stream *stream)
548{
549 struct snd_soc_pcm_runtime *rtd = stream->private_data;
550 struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
551 struct snd_compr_runtime *runtime = stream->runtime;
552 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
553 struct q6asm_dai_data *pdata;
554 struct device *dev = c->dev;
555 struct q6asm_dai_rtd *prtd;
556 int stream_id, size, ret;
557
558 stream_id = cpu_dai->driver->id;
559 pdata = snd_soc_component_get_drvdata(c);
560 if (!pdata) {
561 dev_err(dev, "Drv data not found ..\n");
562 return -EINVAL;
563 }
564
565 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
566 if (!prtd)
567 return -ENOMEM;
568
569 prtd->cstream = stream;
570 prtd->audio_client = q6asm_audio_client_alloc(dev,
571 (q6asm_cb)compress_event_handler,
572 prtd, stream_id, LEGACY_PCM_MODE);
573 if (!prtd->audio_client) {
574 dev_err(dev, "Could not allocate memory\n");
575 kfree(prtd);
576 return -ENOMEM;
577 }
578
579 size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE *
580 COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;
581 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size,
582 &prtd->dma_buffer);
583 if (ret) {
584 dev_err(dev, "Cannot allocate buffer(s)\n");
585 return ret;
586 }
587
588 if (pdata->sid < 0)
589 prtd->phys = prtd->dma_buffer.addr;
590 else
591 prtd->phys = prtd->dma_buffer.addr | (pdata->sid << 32);
592
593 snd_compr_set_runtime_buffer(stream, &prtd->dma_buffer);
594 spin_lock_init(&prtd->lock);
595 runtime->private_data = prtd;
596
597 return 0;
598}
599
600static int q6asm_dai_compr_free(struct snd_compr_stream *stream)
601{
602 struct snd_compr_runtime *runtime = stream->runtime;
603 struct q6asm_dai_rtd *prtd = runtime->private_data;
604 struct snd_soc_pcm_runtime *rtd = stream->private_data;
605
606 if (prtd->audio_client) {
607 if (prtd->state)
608 q6asm_cmd(prtd->audio_client, CMD_CLOSE);
609
610 snd_dma_free_pages(&prtd->dma_buffer);
611 q6asm_unmap_memory_regions(stream->direction,
612 prtd->audio_client);
613 q6asm_audio_client_free(prtd->audio_client);
614 prtd->audio_client = NULL;
615 }
616 q6routing_stream_close(rtd->dai_link->id, stream->direction);
617 kfree(prtd);
618
619 return 0;
620}
621
622static int q6asm_dai_compr_set_params(struct snd_compr_stream *stream,
623 struct snd_compr_params *params)
624{
625 struct snd_compr_runtime *runtime = stream->runtime;
626 struct q6asm_dai_rtd *prtd = runtime->private_data;
627 struct snd_soc_pcm_runtime *rtd = stream->private_data;
628 struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
629 int dir = stream->direction;
630 struct q6asm_dai_data *pdata;
631 struct device *dev = c->dev;
632 int ret;
633
634 memcpy(&prtd->codec_param, params, sizeof(*params));
635
636 pdata = snd_soc_component_get_drvdata(c);
637 if (!pdata)
638 return -EINVAL;
639
640 if (!prtd || !prtd->audio_client) {
641 dev_err(dev, "private data null or audio client freed\n");
642 return -EINVAL;
643 }
644
645 prtd->periods = runtime->fragments;
646 prtd->pcm_count = runtime->fragment_size;
647 prtd->pcm_size = runtime->fragments * runtime->fragment_size;
648 prtd->bits_per_sample = 16;
649 if (dir == SND_COMPRESS_PLAYBACK) {
650 ret = q6asm_open_write(prtd->audio_client, params->codec.id,
651 prtd->bits_per_sample);
652
653 if (ret < 0) {
654 dev_err(dev, "q6asm_open_write failed\n");
655 q6asm_audio_client_free(prtd->audio_client);
656 prtd->audio_client = NULL;
657 return ret;
658 }
659 }
660
661 prtd->session_id = q6asm_get_session_id(prtd->audio_client);
662 ret = q6routing_stream_open(rtd->dai_link->id, LEGACY_PCM_MODE,
663 prtd->session_id, dir);
664 if (ret) {
665 dev_err(dev, "Stream reg failed ret:%d\n", ret);
666 return ret;
667 }
668
669 ret = q6asm_map_memory_regions(dir, prtd->audio_client, prtd->phys,
670 (prtd->pcm_size / prtd->periods),
671 prtd->periods);
672
673 if (ret < 0) {
674 dev_err(dev, "Buffer Mapping failed ret:%d\n", ret);
675 return -ENOMEM;
676 }
677
678 prtd->state = Q6ASM_STREAM_RUNNING;
679
680 return 0;
681}
682
683static int q6asm_dai_compr_trigger(struct snd_compr_stream *stream, int cmd)
684{
685 struct snd_compr_runtime *runtime = stream->runtime;
686 struct q6asm_dai_rtd *prtd = runtime->private_data;
687 int ret = 0;
688
689 switch (cmd) {
690 case SNDRV_PCM_TRIGGER_START:
691 case SNDRV_PCM_TRIGGER_RESUME:
692 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
693 ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0);
694 break;
695 case SNDRV_PCM_TRIGGER_STOP:
696 prtd->state = Q6ASM_STREAM_STOPPED;
697 ret = q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
698 break;
699 case SNDRV_PCM_TRIGGER_SUSPEND:
700 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
701 ret = q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE);
702 break;
703 default:
704 ret = -EINVAL;
705 break;
706 }
707
708 return ret;
709}
710
711static int q6asm_dai_compr_pointer(struct snd_compr_stream *stream,
712 struct snd_compr_tstamp *tstamp)
713{
714 struct snd_compr_runtime *runtime = stream->runtime;
715 struct q6asm_dai_rtd *prtd = runtime->private_data;
716 unsigned long flags;
717
718 spin_lock_irqsave(&prtd->lock, flags);
719
720 tstamp->copied_total = prtd->copied_total;
721 tstamp->byte_offset = prtd->copied_total % prtd->pcm_size;
722
723 spin_unlock_irqrestore(&prtd->lock, flags);
724
725 return 0;
726}
727
728static int q6asm_dai_compr_ack(struct snd_compr_stream *stream,
729 size_t count)
730{
731 struct snd_compr_runtime *runtime = stream->runtime;
732 struct q6asm_dai_rtd *prtd = runtime->private_data;
733 unsigned long flags;
734
735 spin_lock_irqsave(&prtd->lock, flags);
736 prtd->bytes_received += count;
737 spin_unlock_irqrestore(&prtd->lock, flags);
738
739 return count;
740}
741
742static int q6asm_dai_compr_mmap(struct snd_compr_stream *stream,
743 struct vm_area_struct *vma)
744{
745 struct snd_compr_runtime *runtime = stream->runtime;
746 struct q6asm_dai_rtd *prtd = runtime->private_data;
747 struct snd_soc_pcm_runtime *rtd = stream->private_data;
748 struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
749 struct device *dev = c->dev;
750
751 return dma_mmap_coherent(dev, vma,
752 prtd->dma_buffer.area, prtd->dma_buffer.addr,
753 prtd->dma_buffer.bytes);
754}
755
756static int q6asm_dai_compr_get_caps(struct snd_compr_stream *stream,
757 struct snd_compr_caps *caps)
758{
759 caps->direction = SND_COMPRESS_PLAYBACK;
760 caps->min_fragment_size = COMPR_PLAYBACK_MIN_FRAGMENT_SIZE;
761 caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE;
762 caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS;
763 caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;
764 caps->num_codecs = 1;
765 caps->codecs[0] = SND_AUDIOCODEC_MP3;
766
767 return 0;
768}
769
770static int q6asm_dai_compr_get_codec_caps(struct snd_compr_stream *stream,
771 struct snd_compr_codec_caps *codec)
772{
773 switch (codec->codec) {
774 case SND_AUDIOCODEC_MP3:
775 *codec = q6asm_compr_caps;
776 break;
777 default:
778 break;
779 }
780
781 return 0;
782}
783
784static struct snd_compr_ops q6asm_dai_compr_ops = {
785 .open = q6asm_dai_compr_open,
786 .free = q6asm_dai_compr_free,
787 .set_params = q6asm_dai_compr_set_params,
788 .pointer = q6asm_dai_compr_pointer,
789 .trigger = q6asm_dai_compr_trigger,
790 .get_caps = q6asm_dai_compr_get_caps,
791 .get_codec_caps = q6asm_dai_compr_get_codec_caps,
792 .mmap = q6asm_dai_compr_mmap,
793 .ack = q6asm_dai_compr_ack,
794};
795
463static int q6asm_dai_pcm_new(struct snd_soc_pcm_runtime *rtd) 796static int q6asm_dai_pcm_new(struct snd_soc_pcm_runtime *rtd)
464{ 797{
465 struct snd_pcm_substream *psubstream, *csubstream; 798 struct snd_pcm_substream *psubstream, *csubstream;
@@ -515,7 +848,7 @@ static const struct snd_soc_component_driver q6asm_fe_dai_component = {
515 .ops = &q6asm_dai_ops, 848 .ops = &q6asm_dai_ops,
516 .pcm_new = q6asm_dai_pcm_new, 849 .pcm_new = q6asm_dai_pcm_new,
517 .pcm_free = q6asm_dai_pcm_free, 850 .pcm_free = q6asm_dai_pcm_free,
518 851 .compr_ops = &q6asm_dai_compr_ops,
519}; 852};
520 853
521static struct snd_soc_dai_driver q6asm_fe_dais[] = { 854static struct snd_soc_dai_driver q6asm_fe_dais[] = {
@@ -529,6 +862,41 @@ static struct snd_soc_dai_driver q6asm_fe_dais[] = {
529 Q6ASM_FEDAI_DRIVER(8), 862 Q6ASM_FEDAI_DRIVER(8),
530}; 863};
531 864
865static int of_q6asm_parse_dai_data(struct device *dev,
866 struct q6asm_dai_data *pdata)
867{
868 static struct snd_soc_dai_driver *dai_drv;
869 struct snd_soc_pcm_stream empty_stream;
870 struct device_node *node;
871 int ret, id, dir;
872
873 memset(&empty_stream, 0, sizeof(empty_stream));
874
875 for_each_child_of_node(dev->of_node, node) {
876 ret = of_property_read_u32(node, "reg", &id);
877 if (ret || id > MAX_SESSIONS || id < 0) {
878 dev_err(dev, "valid dai id not found:%d\n", ret);
879 continue;
880 }
881
882 dai_drv = &q6asm_fe_dais[id];
883
884 ret = of_property_read_u32(node, "direction", &dir);
885 if (ret)
886 continue;
887
888 if (dir == Q6ASM_DAI_RX)
889 dai_drv->capture = empty_stream;
890 else if (dir == Q6ASM_DAI_TX)
891 dai_drv->playback = empty_stream;
892
893 if (of_property_read_bool(node, "is-compress-dai"))
894 dai_drv->compress_new = snd_soc_new_compress;
895 }
896
897 return 0;
898}
899
532static int q6asm_dai_probe(struct platform_device *pdev) 900static int q6asm_dai_probe(struct platform_device *pdev)
533{ 901{
534 struct device *dev = &pdev->dev; 902 struct device *dev = &pdev->dev;
@@ -549,6 +917,8 @@ static int q6asm_dai_probe(struct platform_device *pdev)
549 917
550 dev_set_drvdata(dev, pdata); 918 dev_set_drvdata(dev, pdata);
551 919
920 of_q6asm_parse_dai_data(dev, pdata);
921
552 return devm_snd_soc_register_component(dev, &q6asm_fe_dai_component, 922 return devm_snd_soc_register_component(dev, &q6asm_fe_dai_component,
553 q6asm_fe_dais, 923 q6asm_fe_dais,
554 ARRAY_SIZE(q6asm_fe_dais)); 924 ARRAY_SIZE(q6asm_fe_dais));
diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c
index e1cfa846a1dc..4f85cb19a309 100644
--- a/sound/soc/qcom/qdsp6/q6asm.c
+++ b/sound/soc/qcom/qdsp6/q6asm.c
@@ -12,6 +12,7 @@
12#include <linux/kref.h> 12#include <linux/kref.h>
13#include <linux/of.h> 13#include <linux/of.h>
14#include <uapi/sound/asound.h> 14#include <uapi/sound/asound.h>
15#include <uapi/sound/compress_params.h>
15#include <linux/delay.h> 16#include <linux/delay.h>
16#include <linux/slab.h> 17#include <linux/slab.h>
17#include <linux/mm.h> 18#include <linux/mm.h>
@@ -36,6 +37,7 @@
36#define ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2 0x00010DA3 37#define ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2 0x00010DA3
37#define ASM_SESSION_CMD_RUN_V2 0x00010DAA 38#define ASM_SESSION_CMD_RUN_V2 0x00010DAA
38#define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2 0x00010DA5 39#define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2 0x00010DA5
40#define ASM_MEDIA_FMT_MP3 0x00010BE9
39#define ASM_DATA_CMD_WRITE_V2 0x00010DAB 41#define ASM_DATA_CMD_WRITE_V2 0x00010DAB
40#define ASM_DATA_CMD_READ_V2 0x00010DAC 42#define ASM_DATA_CMD_READ_V2 0x00010DAC
41#define ASM_SESSION_CMD_SUSPEND 0x00010DEC 43#define ASM_SESSION_CMD_SUSPEND 0x00010DEC
@@ -868,6 +870,9 @@ int q6asm_open_write(struct audio_client *ac, uint32_t format,
868 open->postprocopo_id = ASM_NULL_POPP_TOPOLOGY; 870 open->postprocopo_id = ASM_NULL_POPP_TOPOLOGY;
869 871
870 switch (format) { 872 switch (format) {
873 case SND_AUDIOCODEC_MP3:
874 open->dec_fmt_id = ASM_MEDIA_FMT_MP3;
875 break;
871 case FORMAT_LINEAR_PCM: 876 case FORMAT_LINEAR_PCM:
872 open->dec_fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2; 877 open->dec_fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
873 break; 878 break;
diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c
index d61b8404f7da..ddcd9978cf57 100644
--- a/sound/soc/qcom/qdsp6/q6routing.c
+++ b/sound/soc/qcom/qdsp6/q6routing.c
@@ -453,6 +453,9 @@ static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol,
453static const struct snd_kcontrol_new hdmi_mixer_controls[] = { 453static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
454 Q6ROUTING_RX_MIXERS(HDMI_RX) }; 454 Q6ROUTING_RX_MIXERS(HDMI_RX) };
455 455
456static const struct snd_kcontrol_new display_port_mixer_controls[] = {
457 Q6ROUTING_RX_MIXERS(DISPLAY_PORT_RX) };
458
456static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = { 459static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = {
457 Q6ROUTING_RX_MIXERS(PRIMARY_MI2S_RX) }; 460 Q6ROUTING_RX_MIXERS(PRIMARY_MI2S_RX) };
458 461
@@ -655,6 +658,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
655 hdmi_mixer_controls, 658 hdmi_mixer_controls,
656 ARRAY_SIZE(hdmi_mixer_controls)), 659 ARRAY_SIZE(hdmi_mixer_controls)),
657 660
661 SND_SOC_DAPM_MIXER("DISPLAY_PORT_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
662 display_port_mixer_controls,
663 ARRAY_SIZE(display_port_mixer_controls)),
664
658 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0, 665 SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
659 slimbus_rx_mixer_controls, 666 slimbus_rx_mixer_controls,
660 ARRAY_SIZE(slimbus_rx_mixer_controls)), 667 ARRAY_SIZE(slimbus_rx_mixer_controls)),
@@ -833,6 +840,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
833 840
834static const struct snd_soc_dapm_route intercon[] = { 841static const struct snd_soc_dapm_route intercon[] = {
835 Q6ROUTING_RX_DAPM_ROUTE("HDMI Mixer", "HDMI_RX"), 842 Q6ROUTING_RX_DAPM_ROUTE("HDMI Mixer", "HDMI_RX"),
843 Q6ROUTING_RX_DAPM_ROUTE("DISPLAY_PORT_RX Audio Mixer",
844 "DISPLAY_PORT_RX"),
836 Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_0_RX Audio Mixer", "SLIMBUS_0_RX"), 845 Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_0_RX Audio Mixer", "SLIMBUS_0_RX"),
837 Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_1_RX Audio Mixer", "SLIMBUS_1_RX"), 846 Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_1_RX Audio Mixer", "SLIMBUS_1_RX"),
838 Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_2_RX Audio Mixer", "SLIMBUS_2_RX"), 847 Q6ROUTING_RX_DAPM_ROUTE("SLIMBUS_2_RX Audio Mixer", "SLIMBUS_2_RX"),
diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
index 9effbecc571f..1db8ef668223 100644
--- a/sound/soc/qcom/sdm845.c
+++ b/sound/soc/qcom/sdm845.c
@@ -6,18 +6,31 @@
6#include <linux/module.h> 6#include <linux/module.h>
7#include <linux/platform_device.h> 7#include <linux/platform_device.h>
8#include <linux/of_device.h> 8#include <linux/of_device.h>
9#include <sound/core.h>
9#include <sound/pcm.h> 10#include <sound/pcm.h>
10#include <sound/pcm_params.h> 11#include <sound/pcm_params.h>
12#include <sound/jack.h>
13#include <sound/soc.h>
14#include <uapi/linux/input-event-codes.h>
11#include "common.h" 15#include "common.h"
12#include "qdsp6/q6afe.h" 16#include "qdsp6/q6afe.h"
17#include "../codecs/rt5663.h"
13 18
14#define DEFAULT_SAMPLE_RATE_48K 48000 19#define DEFAULT_SAMPLE_RATE_48K 48000
15#define DEFAULT_MCLK_RATE 24576000 20#define DEFAULT_MCLK_RATE 24576000
16#define DEFAULT_BCLK_RATE 12288000 21#define TDM_BCLK_RATE 6144000
22#define MI2S_BCLK_RATE 1536000
23#define LEFT_SPK_TDM_TX_MASK 0x30
24#define RIGHT_SPK_TDM_TX_MASK 0xC0
25#define SPK_TDM_RX_MASK 0x03
26#define NUM_TDM_SLOTS 8
17 27
18struct sdm845_snd_data { 28struct sdm845_snd_data {
29 struct snd_soc_jack jack;
30 bool jack_setup;
19 struct snd_soc_card *card; 31 struct snd_soc_card *card;
20 uint32_t pri_mi2s_clk_count; 32 uint32_t pri_mi2s_clk_count;
33 uint32_t sec_mi2s_clk_count;
21 uint32_t quat_tdm_clk_count; 34 uint32_t quat_tdm_clk_count;
22}; 35};
23 36
@@ -28,12 +41,12 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
28{ 41{
29 struct snd_soc_pcm_runtime *rtd = substream->private_data; 42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
30 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 43 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
31 int ret = 0; 44 int ret = 0, j;
32 int channels, slot_width; 45 int channels, slot_width;
33 46
34 switch (params_format(params)) { 47 switch (params_format(params)) {
35 case SNDRV_PCM_FORMAT_S16_LE: 48 case SNDRV_PCM_FORMAT_S16_LE:
36 slot_width = 32; 49 slot_width = 16;
37 break; 50 break;
38 default: 51 default:
39 dev_err(rtd->dev, "%s: invalid param format 0x%x\n", 52 dev_err(rtd->dev, "%s: invalid param format 0x%x\n",
@@ -75,6 +88,35 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
75 goto end; 88 goto end;
76 } 89 }
77 } 90 }
91
92 for (j = 0; j < rtd->num_codecs; j++) {
93 struct snd_soc_dai *codec_dai = rtd->codec_dais[j];
94
95 if (!strcmp(codec_dai->component->name_prefix, "Left")) {
96 ret = snd_soc_dai_set_tdm_slot(
97 codec_dai, LEFT_SPK_TDM_TX_MASK,
98 SPK_TDM_RX_MASK, NUM_TDM_SLOTS,
99 slot_width);
100 if (ret < 0) {
101 dev_err(rtd->dev,
102 "DEV0 TDM slot err:%d\n", ret);
103 return ret;
104 }
105 }
106
107 if (!strcmp(codec_dai->component->name_prefix, "Right")) {
108 ret = snd_soc_dai_set_tdm_slot(
109 codec_dai, RIGHT_SPK_TDM_TX_MASK,
110 SPK_TDM_RX_MASK, NUM_TDM_SLOTS,
111 slot_width);
112 if (ret < 0) {
113 dev_err(rtd->dev,
114 "DEV1 TDM slot err:%d\n", ret);
115 return ret;
116 }
117 }
118 }
119
78end: 120end:
79 return ret; 121 return ret;
80} 122}
@@ -84,9 +126,27 @@ static int sdm845_snd_hw_params(struct snd_pcm_substream *substream,
84{ 126{
85 struct snd_soc_pcm_runtime *rtd = substream->private_data; 127 struct snd_soc_pcm_runtime *rtd = substream->private_data;
86 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 128 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
129 struct snd_soc_dai *codec_dai = rtd->codec_dai;
87 int ret = 0; 130 int ret = 0;
88 131
89 switch (cpu_dai->id) { 132 switch (cpu_dai->id) {
133 case PRIMARY_MI2S_RX:
134 case PRIMARY_MI2S_TX:
135 /*
136 * Use ASRC for internal clocks, as PLL rate isn't multiple
137 * of BCLK.
138 */
139 rt5663_sel_asrc_clk_src(
140 codec_dai->component,
141 RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
142 RT5663_CLK_SEL_I2S1_ASRC);
143 ret = snd_soc_dai_set_sysclk(
144 codec_dai, RT5663_SCLK_S_MCLK, DEFAULT_MCLK_RATE,
145 SND_SOC_CLOCK_IN);
146 if (ret < 0)
147 dev_err(rtd->dev,
148 "snd_soc_dai_set_sysclk err = %d\n", ret);
149 break;
90 case QUATERNARY_TDM_RX_0: 150 case QUATERNARY_TDM_RX_0:
91 case QUATERNARY_TDM_TX_0: 151 case QUATERNARY_TDM_TX_0:
92 ret = sdm845_tdm_snd_hw_params(substream, params); 152 ret = sdm845_tdm_snd_hw_params(substream, params);
@@ -98,24 +158,87 @@ static int sdm845_snd_hw_params(struct snd_pcm_substream *substream,
98 return ret; 158 return ret;
99} 159}
100 160
161static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
162{
163 struct snd_soc_component *component;
164 struct snd_soc_dai_link *dai_link = rtd->dai_link;
165 struct snd_soc_card *card = rtd->card;
166 struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(card);
167 int i, rval;
168
169 if (!pdata->jack_setup) {
170 struct snd_jack *jack;
171
172 rval = snd_soc_card_jack_new(card, "Headset Jack",
173 SND_JACK_HEADSET |
174 SND_JACK_HEADPHONE |
175 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
176 SND_JACK_BTN_2 | SND_JACK_BTN_3,
177 &pdata->jack, NULL, 0);
178
179 if (rval < 0) {
180 dev_err(card->dev, "Unable to add Headphone Jack\n");
181 return rval;
182 }
183
184 jack = pdata->jack.jack;
185
186 snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
187 snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
188 snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
189 snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
190 pdata->jack_setup = true;
191 }
192
193 for (i = 0 ; i < dai_link->num_codecs; i++) {
194 struct snd_soc_dai *dai = rtd->codec_dais[i];
195
196 component = dai->component;
197 rval = snd_soc_component_set_jack(
198 component, &pdata->jack, NULL);
199 if (rval != 0 && rval != -ENOTSUPP) {
200 dev_warn(card->dev, "Failed to set jack: %d\n", rval);
201 return rval;
202 }
203 }
204
205 return 0;
206}
207
208
101static int sdm845_snd_startup(struct snd_pcm_substream *substream) 209static int sdm845_snd_startup(struct snd_pcm_substream *substream)
102{ 210{
103 unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS; 211 unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
212 unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBS_CFS;
104 struct snd_soc_pcm_runtime *rtd = substream->private_data; 213 struct snd_soc_pcm_runtime *rtd = substream->private_data;
105 struct snd_soc_card *card = rtd->card; 214 struct snd_soc_card *card = rtd->card;
106 struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card); 215 struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
107 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 216 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
217 struct snd_soc_dai *codec_dai = rtd->codec_dai;
218 int j;
219 int ret;
108 220
109 switch (cpu_dai->id) { 221 switch (cpu_dai->id) {
110 case PRIMARY_MI2S_RX: 222 case PRIMARY_MI2S_RX:
111 case PRIMARY_MI2S_TX: 223 case PRIMARY_MI2S_TX:
224 codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF;
112 if (++(data->pri_mi2s_clk_count) == 1) { 225 if (++(data->pri_mi2s_clk_count) == 1) {
113 snd_soc_dai_set_sysclk(cpu_dai, 226 snd_soc_dai_set_sysclk(cpu_dai,
114 Q6AFE_LPASS_CLK_ID_MCLK_1, 227 Q6AFE_LPASS_CLK_ID_MCLK_1,
115 DEFAULT_MCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); 228 DEFAULT_MCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
116 snd_soc_dai_set_sysclk(cpu_dai, 229 snd_soc_dai_set_sysclk(cpu_dai,
117 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT, 230 Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
118 DEFAULT_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); 231 MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
232 }
233 snd_soc_dai_set_fmt(cpu_dai, fmt);
234 snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
235 break;
236
237 case SECONDARY_MI2S_TX:
238 if (++(data->sec_mi2s_clk_count) == 1) {
239 snd_soc_dai_set_sysclk(cpu_dai,
240 Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
241 MI2S_BCLK_RATE, SNDRV_PCM_STREAM_CAPTURE);
119 } 242 }
120 snd_soc_dai_set_fmt(cpu_dai, fmt); 243 snd_soc_dai_set_fmt(cpu_dai, fmt);
121 break; 244 break;
@@ -125,7 +248,35 @@ static int sdm845_snd_startup(struct snd_pcm_substream *substream)
125 if (++(data->quat_tdm_clk_count) == 1) { 248 if (++(data->quat_tdm_clk_count) == 1) {
126 snd_soc_dai_set_sysclk(cpu_dai, 249 snd_soc_dai_set_sysclk(cpu_dai,
127 Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT, 250 Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT,
128 DEFAULT_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); 251 TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
252 }
253
254 codec_dai_fmt |= SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_DSP_B;
255
256 for (j = 0; j < rtd->num_codecs; j++) {
257 codec_dai = rtd->codec_dais[j];
258
259 if (!strcmp(codec_dai->component->name_prefix,
260 "Left")) {
261 ret = snd_soc_dai_set_fmt(
262 codec_dai, codec_dai_fmt);
263 if (ret < 0) {
264 dev_err(rtd->dev,
265 "Left TDM fmt err:%d\n", ret);
266 return ret;
267 }
268 }
269
270 if (!strcmp(codec_dai->component->name_prefix,
271 "Right")) {
272 ret = snd_soc_dai_set_fmt(
273 codec_dai, codec_dai_fmt);
274 if (ret < 0) {
275 dev_err(rtd->dev,
276 "Right TDM slot err:%d\n", ret);
277 return ret;
278 }
279 }
129 } 280 }
130 break; 281 break;
131 282
@@ -156,6 +307,14 @@ static void sdm845_snd_shutdown(struct snd_pcm_substream *substream)
156 }; 307 };
157 break; 308 break;
158 309
310 case SECONDARY_MI2S_TX:
311 if (--(data->sec_mi2s_clk_count) == 0) {
312 snd_soc_dai_set_sysclk(cpu_dai,
313 Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
314 0, SNDRV_PCM_STREAM_CAPTURE);
315 }
316 break;
317
159 case QUATERNARY_TDM_RX_0: 318 case QUATERNARY_TDM_RX_0:
160 case QUATERNARY_TDM_TX_0: 319 case QUATERNARY_TDM_TX_0:
161 if (--(data->quat_tdm_clk_count) == 0) { 320 if (--(data->quat_tdm_clk_count) == 0) {
@@ -171,7 +330,7 @@ static void sdm845_snd_shutdown(struct snd_pcm_substream *substream)
171 } 330 }
172} 331}
173 332
174static struct snd_soc_ops sdm845_be_ops = { 333static const struct snd_soc_ops sdm845_be_ops = {
175 .hw_params = sdm845_snd_hw_params, 334 .hw_params = sdm845_snd_hw_params,
176 .startup = sdm845_snd_startup, 335 .startup = sdm845_snd_startup,
177 .shutdown = sdm845_snd_shutdown, 336 .shutdown = sdm845_snd_shutdown,
@@ -193,7 +352,15 @@ static int sdm845_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
193 return 0; 352 return 0;
194} 353}
195 354
196static void sdm845_add_be_ops(struct snd_soc_card *card) 355static const struct snd_soc_dapm_widget sdm845_snd_widgets[] = {
356 SND_SOC_DAPM_HP("Headphone Jack", NULL),
357 SND_SOC_DAPM_MIC("Headset Mic", NULL),
358 SND_SOC_DAPM_SPK("Left Spk", NULL),
359 SND_SOC_DAPM_SPK("Right Spk", NULL),
360 SND_SOC_DAPM_MIC("Int Mic", NULL),
361};
362
363static void sdm845_add_ops(struct snd_soc_card *card)
197{ 364{
198 struct snd_soc_dai_link *link; 365 struct snd_soc_dai_link *link;
199 int i; 366 int i;
@@ -203,6 +370,7 @@ static void sdm845_add_be_ops(struct snd_soc_card *card)
203 link->ops = &sdm845_be_ops; 370 link->ops = &sdm845_be_ops;
204 link->be_hw_params_fixup = sdm845_be_hw_params_fixup; 371 link->be_hw_params_fixup = sdm845_be_hw_params_fixup;
205 } 372 }
373 link->init = sdm845_dai_init;
206 } 374 }
207} 375}
208 376
@@ -224,6 +392,8 @@ static int sdm845_snd_platform_probe(struct platform_device *pdev)
224 goto data_alloc_fail; 392 goto data_alloc_fail;
225 } 393 }
226 394
395 card->dapm_widgets = sdm845_snd_widgets;
396 card->num_dapm_widgets = ARRAY_SIZE(sdm845_snd_widgets);
227 card->dev = dev; 397 card->dev = dev;
228 dev_set_drvdata(dev, card); 398 dev_set_drvdata(dev, card);
229 ret = qcom_snd_parse_of(card); 399 ret = qcom_snd_parse_of(card);
@@ -235,7 +405,7 @@ static int sdm845_snd_platform_probe(struct platform_device *pdev)
235 data->card = card; 405 data->card = card;
236 snd_soc_card_set_drvdata(card, data); 406 snd_soc_card_set_drvdata(card, data);
237 407
238 sdm845_add_be_ops(card); 408 sdm845_add_ops(card);
239 ret = snd_soc_register_card(card); 409 ret = snd_soc_register_card(card);
240 if (ret) { 410 if (ret) {
241 dev_err(dev, "Sound card registration failed\n"); 411 dev_err(dev, "Sound card registration failed\n");
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 28327dd2c6cb..e821ccc70f47 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -249,28 +249,8 @@ int rsnd_adg_set_src_timesel_gen2(struct rsnd_mod *src_mod,
249 out = out << shift; 249 out = out << shift;
250 mask = 0x0f1f << shift; 250 mask = 0x0f1f << shift;
251 251
252 switch (id / 2) { 252 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL(id / 2), mask, in);
253 case 0: 253 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL(id / 2), mask, out);
254 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL0, mask, in);
255 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL0, mask, out);
256 break;
257 case 1:
258 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL1, mask, in);
259 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL1, mask, out);
260 break;
261 case 2:
262 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL2, mask, in);
263 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL2, mask, out);
264 break;
265 case 3:
266 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL3, mask, in);
267 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL3, mask, out);
268 break;
269 case 4:
270 rsnd_mod_bset(adg_mod, SRCIN_TIMSEL4, mask, in);
271 rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL4, mask, out);
272 break;
273 }
274 254
275 if (en) 255 if (en)
276 rsnd_mod_bset(adg_mod, DIV_EN, en, en); 256 rsnd_mod_bset(adg_mod, DIV_EN, en, en);
@@ -299,17 +279,7 @@ static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)
299 if (id == 8) 279 if (id == 8)
300 return; 280 return;
301 281
302 switch (id / 4) { 282 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL(id / 4), mask, val);
303 case 0:
304 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL0, mask, val);
305 break;
306 case 1:
307 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL1, mask, val);
308 break;
309 case 2:
310 rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL2, mask, val);
311 break;
312 }
313 283
314 dev_dbg(dev, "AUDIO_CLK_SEL is 0x%x\n", val); 284 dev_dbg(dev, "AUDIO_CLK_SEL is 0x%x\n", val);
315} 285}
@@ -613,7 +583,7 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
613 return -ENOMEM; 583 return -ENOMEM;
614 584
615 ret = rsnd_mod_init(priv, &adg->mod, &adg_ops, 585 ret = rsnd_mod_init(priv, &adg->mod, &adg_ops,
616 NULL, NULL, 0, 0); 586 NULL, 0, 0);
617 if (ret) 587 if (ret)
618 return ret; 588 return ret;
619 589
diff --git a/sound/soc/sh/rcar/cmd.c b/sound/soc/sh/rcar/cmd.c
index cc191cd5fb82..e6bb6a9a0684 100644
--- a/sound/soc/sh/rcar/cmd.c
+++ b/sound/soc/sh/rcar/cmd.c
@@ -116,10 +116,11 @@ static int rsnd_cmd_stop(struct rsnd_mod *mod,
116} 116}
117 117
118static struct rsnd_mod_ops rsnd_cmd_ops = { 118static struct rsnd_mod_ops rsnd_cmd_ops = {
119 .name = CMD_NAME, 119 .name = CMD_NAME,
120 .init = rsnd_cmd_init, 120 .init = rsnd_cmd_init,
121 .start = rsnd_cmd_start, 121 .start = rsnd_cmd_start,
122 .stop = rsnd_cmd_stop, 122 .stop = rsnd_cmd_stop,
123 .get_status = rsnd_mod_get_status,
123}; 124};
124 125
125static struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id) 126static struct rsnd_mod *rsnd_cmd_mod_get(struct rsnd_priv *priv, int id)
@@ -162,7 +163,7 @@ int rsnd_cmd_probe(struct rsnd_priv *priv)
162 for_each_rsnd_cmd(cmd, priv, i) { 163 for_each_rsnd_cmd(cmd, priv, i) {
163 ret = rsnd_mod_init(priv, rsnd_mod_get(cmd), 164 ret = rsnd_mod_init(priv, rsnd_mod_get(cmd),
164 &rsnd_cmd_ops, NULL, 165 &rsnd_cmd_ops, NULL,
165 rsnd_mod_get_status, RSND_MOD_CMD, i); 166 RSND_MOD_CMD, i);
166 if (ret) 167 if (ret)
167 return ret; 168 return ret;
168 } 169 }
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index f930f51b686f..59e250cc2e9d 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -123,8 +123,8 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
123 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 123 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
124 struct device *dev = rsnd_priv_to_dev(priv); 124 struct device *dev = rsnd_priv_to_dev(priv);
125 125
126 dev_warn(dev, "%s[%d] is not your expected module\n", 126 dev_warn(dev, "%s is not your expected module\n",
127 rsnd_mod_name(mod), rsnd_mod_id(mod)); 127 rsnd_mod_name(mod));
128 } 128 }
129} 129}
130 130
@@ -137,20 +137,69 @@ struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io,
137 return mod->ops->dma_req(io, mod); 137 return mod->ops->dma_req(io, mod);
138} 138}
139 139
140u32 *rsnd_mod_get_status(struct rsnd_dai_stream *io, 140#define MOD_NAME_NUM 5
141 struct rsnd_mod *mod, 141#define MOD_NAME_SIZE 16
142char *rsnd_mod_name(struct rsnd_mod *mod)
143{
144 static char names[MOD_NAME_NUM][MOD_NAME_SIZE];
145 static int num;
146 char *name = names[num];
147
148 num++;
149 if (num >= MOD_NAME_NUM)
150 num = 0;
151
152 /*
153 * Let's use same char to avoid pointlessness memory
154 * Thus, rsnd_mod_name() should be used immediately
155 * Don't keep pointer
156 */
157 if ((mod)->ops->id_sub) {
158 snprintf(name, MOD_NAME_SIZE, "%s[%d%d]",
159 mod->ops->name,
160 rsnd_mod_id(mod),
161 rsnd_mod_id_sub(mod));
162 } else {
163 snprintf(name, MOD_NAME_SIZE, "%s[%d]",
164 mod->ops->name,
165 rsnd_mod_id(mod));
166 }
167
168 return name;
169}
170
171u32 *rsnd_mod_get_status(struct rsnd_mod *mod,
172 struct rsnd_dai_stream *io,
142 enum rsnd_mod_type type) 173 enum rsnd_mod_type type)
143{ 174{
144 return &mod->status; 175 return &mod->status;
145} 176}
146 177
178int rsnd_mod_id_raw(struct rsnd_mod *mod)
179{
180 return mod->id;
181}
182
183int rsnd_mod_id(struct rsnd_mod *mod)
184{
185 if ((mod)->ops->id)
186 return (mod)->ops->id(mod);
187
188 return rsnd_mod_id_raw(mod);
189}
190
191int rsnd_mod_id_sub(struct rsnd_mod *mod)
192{
193 if ((mod)->ops->id_sub)
194 return (mod)->ops->id_sub(mod);
195
196 return 0;
197}
198
147int rsnd_mod_init(struct rsnd_priv *priv, 199int rsnd_mod_init(struct rsnd_priv *priv,
148 struct rsnd_mod *mod, 200 struct rsnd_mod *mod,
149 struct rsnd_mod_ops *ops, 201 struct rsnd_mod_ops *ops,
150 struct clk *clk, 202 struct clk *clk,
151 u32* (*get_status)(struct rsnd_dai_stream *io,
152 struct rsnd_mod *mod,
153 enum rsnd_mod_type type),
154 enum rsnd_mod_type type, 203 enum rsnd_mod_type type,
155 int id) 204 int id)
156{ 205{
@@ -164,7 +213,6 @@ int rsnd_mod_init(struct rsnd_priv *priv,
164 mod->type = type; 213 mod->type = type;
165 mod->clk = clk; 214 mod->clk = clk;
166 mod->priv = priv; 215 mod->priv = priv;
167 mod->get_status = get_status;
168 216
169 return ret; 217 return ret;
170} 218}
@@ -228,7 +276,20 @@ int rsnd_runtime_channel_after_ctu_with_params(struct rsnd_dai_stream *io,
228 struct rsnd_mod *ctu_mod = rsnd_io_to_mod_ctu(io); 276 struct rsnd_mod *ctu_mod = rsnd_io_to_mod_ctu(io);
229 277
230 if (ctu_mod) { 278 if (ctu_mod) {
231 u32 converted_chan = rsnd_ctu_converted_channel(ctu_mod); 279 u32 converted_chan = rsnd_io_converted_chan(io);
280
281 /*
282 * !! Note !!
283 *
284 * converted_chan will be used for CTU,
285 * or TDM Split mode.
286 * User shouldn't use CTU with TDM Split mode.
287 */
288 if (rsnd_runtime_is_tdm_split(io)) {
289 struct device *dev = rsnd_priv_to_dev(rsnd_io_to_priv(io));
290
291 dev_err(dev, "CTU and TDM Split should be used\n");
292 }
232 293
233 if (converted_chan) 294 if (converted_chan)
234 return converted_chan; 295 return converted_chan;
@@ -246,7 +307,7 @@ int rsnd_runtime_channel_for_ssi_with_params(struct rsnd_dai_stream *io,
246 rsnd_runtime_channel_original_with_params(io, params); 307 rsnd_runtime_channel_original_with_params(io, params);
247 308
248 /* Use Multi SSI */ 309 /* Use Multi SSI */
249 if (rsnd_runtime_is_ssi_multi(io)) 310 if (rsnd_runtime_is_multi_ssi(io))
250 chan /= rsnd_rdai_ssi_lane_get(rdai); 311 chan /= rsnd_rdai_ssi_lane_get(rdai);
251 312
252 /* TDM Extend Mode needs 8ch */ 313 /* TDM Extend Mode needs 8ch */
@@ -256,7 +317,7 @@ int rsnd_runtime_channel_for_ssi_with_params(struct rsnd_dai_stream *io,
256 return chan; 317 return chan;
257} 318}
258 319
259int rsnd_runtime_is_ssi_multi(struct rsnd_dai_stream *io) 320int rsnd_runtime_is_multi_ssi(struct rsnd_dai_stream *io)
260{ 321{
261 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 322 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
262 int lane = rsnd_rdai_ssi_lane_get(rdai); 323 int lane = rsnd_rdai_ssi_lane_get(rdai);
@@ -267,11 +328,16 @@ int rsnd_runtime_is_ssi_multi(struct rsnd_dai_stream *io)
267 return (chan > 2) && (lane > 1); 328 return (chan > 2) && (lane > 1);
268} 329}
269 330
270int rsnd_runtime_is_ssi_tdm(struct rsnd_dai_stream *io) 331int rsnd_runtime_is_tdm(struct rsnd_dai_stream *io)
271{ 332{
272 return rsnd_runtime_channel_for_ssi(io) >= 6; 333 return rsnd_runtime_channel_for_ssi(io) >= 6;
273} 334}
274 335
336int rsnd_runtime_is_tdm_split(struct rsnd_dai_stream *io)
337{
338 return !!rsnd_flags_has(io, RSND_STREAM_TDM_SPLIT);
339}
340
275/* 341/*
276 * ADINR function 342 * ADINR function
277 */ 343 */
@@ -472,20 +538,19 @@ static int rsnd_status_update(u32 *status,
472 enum rsnd_mod_type *types = rsnd_mod_sequence[is_play]; \ 538 enum rsnd_mod_type *types = rsnd_mod_sequence[is_play]; \
473 for_each_rsnd_mod_arrays(i, mod, io, types, RSND_MOD_MAX) { \ 539 for_each_rsnd_mod_arrays(i, mod, io, types, RSND_MOD_MAX) { \
474 int tmp = 0; \ 540 int tmp = 0; \
475 u32 *status = mod->get_status(io, mod, types[i]); \ 541 u32 *status = mod->ops->get_status(mod, io, types[i]); \
476 int func_call = rsnd_status_update(status, \ 542 int func_call = rsnd_status_update(status, \
477 __rsnd_mod_shift_##fn, \ 543 __rsnd_mod_shift_##fn, \
478 __rsnd_mod_add_##fn, \ 544 __rsnd_mod_add_##fn, \
479 __rsnd_mod_call_##fn); \ 545 __rsnd_mod_call_##fn); \
480 rsnd_dbg_dai_call(dev, "%s[%d]\t0x%08x %s\n", \ 546 rsnd_dbg_dai_call(dev, "%s\t0x%08x %s\n", \
481 rsnd_mod_name(mod), rsnd_mod_id(mod), *status, \ 547 rsnd_mod_name(mod), *status, \
482 (func_call && (mod)->ops->fn) ? #fn : ""); \ 548 (func_call && (mod)->ops->fn) ? #fn : ""); \
483 if (func_call && (mod)->ops->fn) \ 549 if (func_call && (mod)->ops->fn) \
484 tmp = (mod)->ops->fn(mod, io, param); \ 550 tmp = (mod)->ops->fn(mod, io, param); \
485 if (tmp && (tmp != -EPROBE_DEFER)) \ 551 if (tmp && (tmp != -EPROBE_DEFER)) \
486 dev_err(dev, "%s[%d] : %s error %d\n", \ 552 dev_err(dev, "%s : %s error %d\n", \
487 rsnd_mod_name(mod), rsnd_mod_id(mod), \ 553 rsnd_mod_name(mod), #fn, tmp); \
488 #fn, tmp); \
489 ret |= tmp; \ 554 ret |= tmp; \
490 } \ 555 } \
491 ret; \ 556 ret; \
@@ -512,8 +577,8 @@ int rsnd_dai_connect(struct rsnd_mod *mod,
512 577
513 io->mod[type] = mod; 578 io->mod[type] = mod;
514 579
515 dev_dbg(dev, "%s[%d] is connected to io (%s)\n", 580 dev_dbg(dev, "%s is connected to io (%s)\n",
516 rsnd_mod_name(mod), rsnd_mod_id(mod), 581 rsnd_mod_name(mod),
517 rsnd_io_is_play(io) ? "Playback" : "Capture"); 582 rsnd_io_is_play(io) ? "Playback" : "Capture");
518 583
519 return 0; 584 return 0;
@@ -750,6 +815,7 @@ static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai,
750 815
751 switch (slots) { 816 switch (slots) {
752 case 2: 817 case 2:
818 /* TDM Split Mode */
753 case 6: 819 case 6:
754 case 8: 820 case 8:
755 /* TDM Extend Mode */ 821 /* TDM Extend Mode */
@@ -965,6 +1031,82 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
965 .prepare = rsnd_soc_dai_prepare, 1031 .prepare = rsnd_soc_dai_prepare,
966}; 1032};
967 1033
1034static void rsnd_parse_connect_simple(struct rsnd_priv *priv,
1035 struct device_node *dai_np,
1036 int dai_i, int is_play)
1037{
1038 struct device *dev = rsnd_priv_to_dev(priv);
1039 struct rsnd_dai *rdai = rsnd_rdai_get(priv, dai_i);
1040 struct rsnd_dai_stream *io = is_play ?
1041 &rdai->playback :
1042 &rdai->capture;
1043 struct device_node *ssiu_np = rsnd_ssiu_of_node(priv);
1044 struct device_node *np;
1045 int i, j;
1046
1047 if (!ssiu_np)
1048 return;
1049
1050 if (!rsnd_io_to_mod_ssi(io))
1051 return;
1052
1053 /*
1054 * This driver assumes that it is TDM Split mode
1055 * if it includes ssiu node
1056 */
1057 for (i = 0;; i++) {
1058 struct device_node *node = is_play ?
1059 of_parse_phandle(dai_np, "playback", i) :
1060 of_parse_phandle(dai_np, "capture", i);
1061
1062 if (!node)
1063 break;
1064
1065 j = 0;
1066 for_each_child_of_node(ssiu_np, np) {
1067 if (np == node) {
1068 rsnd_flags_set(io, RSND_STREAM_TDM_SPLIT);
1069 dev_dbg(dev, "%s is part of TDM Split\n", io->name);
1070 }
1071 j++;
1072 }
1073
1074 }
1075}
1076
1077static void rsnd_parse_connect_graph(struct rsnd_priv *priv,
1078 struct rsnd_dai_stream *io,
1079 struct device_node *endpoint)
1080{
1081 struct device *dev = rsnd_priv_to_dev(priv);
1082 struct device_node *remote_port = of_graph_get_remote_port(endpoint);
1083 struct device_node *remote_node = of_graph_get_remote_port_parent(endpoint);
1084
1085 if (!rsnd_io_to_mod_ssi(io))
1086 return;
1087
1088 /* HDMI0 */
1089 if (strstr(remote_node->full_name, "hdmi@fead0000")) {
1090 rsnd_flags_set(io, RSND_STREAM_HDMI0);
1091 dev_dbg(dev, "%s connected to HDMI0\n", io->name);
1092 }
1093
1094 /* HDMI1 */
1095 if (strstr(remote_node->full_name, "hdmi@feae0000")) {
1096 rsnd_flags_set(io, RSND_STREAM_HDMI1);
1097 dev_dbg(dev, "%s connected to HDMI1\n", io->name);
1098 }
1099
1100 /*
1101 * This driver assumes that it is TDM Split mode
1102 * if remote node has multi endpoint
1103 */
1104 if (of_get_child_count(remote_port) > 1) {
1105 rsnd_flags_set(io, RSND_STREAM_TDM_SPLIT);
1106 dev_dbg(dev, "%s is part of TDM Split\n", io->name);
1107 }
1108}
1109
968void rsnd_parse_connect_common(struct rsnd_dai *rdai, 1110void rsnd_parse_connect_common(struct rsnd_dai *rdai,
969 struct rsnd_mod* (*mod_get)(struct rsnd_priv *priv, int id), 1111 struct rsnd_mod* (*mod_get)(struct rsnd_priv *priv, int id),
970 struct device_node *node, 1112 struct device_node *node,
@@ -1051,24 +1193,24 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv,
1051 drv->name = rdai->name; 1193 drv->name = rdai->name;
1052 drv->ops = &rsnd_soc_dai_ops; 1194 drv->ops = &rsnd_soc_dai_ops;
1053 1195
1054 snprintf(rdai->playback.name, RSND_DAI_NAME_SIZE, 1196 snprintf(io_playback->name, RSND_DAI_NAME_SIZE,
1055 "DAI%d Playback", dai_i); 1197 "DAI%d Playback", dai_i);
1056 drv->playback.rates = RSND_RATES; 1198 drv->playback.rates = RSND_RATES;
1057 drv->playback.formats = RSND_FMTS; 1199 drv->playback.formats = RSND_FMTS;
1058 drv->playback.channels_min = 2; 1200 drv->playback.channels_min = 2;
1059 drv->playback.channels_max = 8; 1201 drv->playback.channels_max = 8;
1060 drv->playback.stream_name = rdai->playback.name; 1202 drv->playback.stream_name = io_playback->name;
1061 1203
1062 snprintf(rdai->capture.name, RSND_DAI_NAME_SIZE, 1204 snprintf(io_capture->name, RSND_DAI_NAME_SIZE,
1063 "DAI%d Capture", dai_i); 1205 "DAI%d Capture", dai_i);
1064 drv->capture.rates = RSND_RATES; 1206 drv->capture.rates = RSND_RATES;
1065 drv->capture.formats = RSND_FMTS; 1207 drv->capture.formats = RSND_FMTS;
1066 drv->capture.channels_min = 2; 1208 drv->capture.channels_min = 2;
1067 drv->capture.channels_max = 8; 1209 drv->capture.channels_max = 8;
1068 drv->capture.stream_name = rdai->capture.name; 1210 drv->capture.stream_name = io_capture->name;
1069 1211
1070 rdai->playback.rdai = rdai; 1212 io_playback->rdai = rdai;
1071 rdai->capture.rdai = rdai; 1213 io_capture->rdai = rdai;
1072 rsnd_rdai_channels_set(rdai, 2); /* default 2ch */ 1214 rsnd_rdai_channels_set(rdai, 2); /* default 2ch */
1073 rsnd_rdai_ssi_lane_set(rdai, 1); /* default 1lane */ 1215 rsnd_rdai_ssi_lane_set(rdai, 1); /* default 1lane */
1074 rsnd_rdai_width_set(rdai, 32); /* default 32bit width */ 1216 rsnd_rdai_width_set(rdai, 32); /* default 32bit width */
@@ -1081,6 +1223,7 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv,
1081 break; 1223 break;
1082 1224
1083 rsnd_parse_connect_ssi(rdai, playback, capture); 1225 rsnd_parse_connect_ssi(rdai, playback, capture);
1226 rsnd_parse_connect_ssiu(rdai, playback, capture);
1084 rsnd_parse_connect_src(rdai, playback, capture); 1227 rsnd_parse_connect_src(rdai, playback, capture);
1085 rsnd_parse_connect_ctu(rdai, playback, capture); 1228 rsnd_parse_connect_ctu(rdai, playback, capture);
1086 rsnd_parse_connect_mix(rdai, playback, capture); 1229 rsnd_parse_connect_mix(rdai, playback, capture);
@@ -1137,12 +1280,23 @@ static int rsnd_dai_probe(struct rsnd_priv *priv)
1137 if (is_graph) { 1280 if (is_graph) {
1138 for_each_endpoint_of_node(dai_node, dai_np) { 1281 for_each_endpoint_of_node(dai_node, dai_np) {
1139 __rsnd_dai_probe(priv, dai_np, dai_i); 1282 __rsnd_dai_probe(priv, dai_np, dai_i);
1140 rsnd_ssi_parse_hdmi_connection(priv, dai_np, dai_i); 1283 if (rsnd_is_gen3(priv)) {
1284 struct rsnd_dai *rdai = rsnd_rdai_get(priv, dai_i);
1285
1286 rsnd_parse_connect_graph(priv, &rdai->playback, dai_np);
1287 rsnd_parse_connect_graph(priv, &rdai->capture, dai_np);
1288 }
1141 dai_i++; 1289 dai_i++;
1142 } 1290 }
1143 } else { 1291 } else {
1144 for_each_child_of_node(dai_node, dai_np) 1292 for_each_child_of_node(dai_node, dai_np) {
1145 __rsnd_dai_probe(priv, dai_np, dai_i++); 1293 __rsnd_dai_probe(priv, dai_np, dai_i);
1294 if (rsnd_is_gen3(priv)) {
1295 rsnd_parse_connect_simple(priv, dai_np, dai_i, 1);
1296 rsnd_parse_connect_simple(priv, dai_np, dai_i, 0);
1297 }
1298 dai_i++;
1299 }
1146 } 1300 }
1147 1301
1148 return 0; 1302 return 0;
@@ -1157,8 +1311,40 @@ static int rsnd_hw_params(struct snd_pcm_substream *substream,
1157 struct snd_soc_dai *dai = rsnd_substream_to_dai(substream); 1311 struct snd_soc_dai *dai = rsnd_substream_to_dai(substream);
1158 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); 1312 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
1159 struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream); 1313 struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
1314 struct snd_soc_pcm_runtime *fe = substream->private_data;
1160 int ret; 1315 int ret;
1161 1316
1317 /*
1318 * rsnd assumes that it might be used under DPCM if user want to use
1319 * channel / rate convert. Then, rsnd should be FE.
1320 * And then, this function will be called *after* BE settings.
1321 * this means, each BE already has fixuped hw_params.
1322 * see
1323 * dpcm_fe_dai_hw_params()
1324 * dpcm_be_dai_hw_params()
1325 */
1326 io->converted_rate = 0;
1327 io->converted_chan = 0;
1328 if (fe->dai_link->dynamic) {
1329 struct rsnd_priv *priv = rsnd_io_to_priv(io);
1330 struct device *dev = rsnd_priv_to_dev(priv);
1331 struct snd_soc_dpcm *dpcm;
1332 struct snd_pcm_hw_params *be_params;
1333 int stream = substream->stream;
1334
1335 for_each_dpcm_be(fe, stream, dpcm) {
1336 be_params = &dpcm->hw_params;
1337 if (params_channels(hw_params) != params_channels(be_params))
1338 io->converted_chan = params_channels(be_params);
1339 if (params_rate(hw_params) != params_rate(be_params))
1340 io->converted_rate = params_rate(be_params);
1341 }
1342 if (io->converted_chan)
1343 dev_dbg(dev, "convert channels = %d\n", io->converted_chan);
1344 if (io->converted_rate)
1345 dev_dbg(dev, "convert rate = %d\n", io->converted_rate);
1346 }
1347
1162 ret = rsnd_dai_call(hw_params, io, substream, hw_params); 1348 ret = rsnd_dai_call(hw_params, io, substream, hw_params);
1163 if (ret) 1349 if (ret)
1164 return ret; 1350 return ret;
@@ -1339,6 +1525,18 @@ int rsnd_kctrl_new(struct rsnd_mod *mod,
1339 }; 1525 };
1340 int ret; 1526 int ret;
1341 1527
1528 /*
1529 * 1) Avoid duplicate register (ex. MIXer case)
1530 * 2) re-register if card was rebinded
1531 */
1532 list_for_each_entry(kctrl, &card->controls, list) {
1533 struct rsnd_kctrl_cfg *c = kctrl->private_data;
1534
1535 if (strcmp(kctrl->id.name, name) == 0 &&
1536 c->mod == mod)
1537 return 0;
1538 }
1539
1342 if (size > RSND_MAX_CHANNELS) 1540 if (size > RSND_MAX_CHANNELS)
1343 return -EINVAL; 1541 return -EINVAL;
1344 1542
diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c
index ad702377a6c3..8cb06dab234e 100644
--- a/sound/soc/sh/rcar/ctu.c
+++ b/sound/soc/sh/rcar/ctu.c
@@ -72,10 +72,7 @@
72struct rsnd_ctu { 72struct rsnd_ctu {
73 struct rsnd_mod mod; 73 struct rsnd_mod mod;
74 struct rsnd_kctrl_cfg_m pass; 74 struct rsnd_kctrl_cfg_m pass;
75 struct rsnd_kctrl_cfg_m sv0; 75 struct rsnd_kctrl_cfg_m sv[4];
76 struct rsnd_kctrl_cfg_m sv1;
77 struct rsnd_kctrl_cfg_m sv2;
78 struct rsnd_kctrl_cfg_m sv3;
79 struct rsnd_kctrl_cfg_s reset; 76 struct rsnd_kctrl_cfg_s reset;
80 int channels; 77 int channels;
81 u32 flags; 78 u32 flags;
@@ -107,13 +104,6 @@ static void rsnd_ctu_halt(struct rsnd_mod *mod)
107 rsnd_mod_write(mod, CTU_SWRSR, 0); 104 rsnd_mod_write(mod, CTU_SWRSR, 0);
108} 105}
109 106
110int rsnd_ctu_converted_channel(struct rsnd_mod *mod)
111{
112 struct rsnd_ctu *ctu = rsnd_mod_to_ctu(mod);
113
114 return ctu->channels;
115}
116
117static int rsnd_ctu_probe_(struct rsnd_mod *mod, 107static int rsnd_ctu_probe_(struct rsnd_mod *mod,
118 struct rsnd_dai_stream *io, 108 struct rsnd_dai_stream *io,
119 struct rsnd_priv *priv) 109 struct rsnd_priv *priv)
@@ -127,7 +117,7 @@ static void rsnd_ctu_value_init(struct rsnd_dai_stream *io,
127 struct rsnd_ctu *ctu = rsnd_mod_to_ctu(mod); 117 struct rsnd_ctu *ctu = rsnd_mod_to_ctu(mod);
128 u32 cpmdr = 0; 118 u32 cpmdr = 0;
129 u32 scmdr = 0; 119 u32 scmdr = 0;
130 int i; 120 int i, j;
131 121
132 for (i = 0; i < RSND_MAX_CHANNELS; i++) { 122 for (i = 0; i < RSND_MAX_CHANNELS; i++) {
133 u32 val = rsnd_kctrl_valm(ctu->pass, i); 123 u32 val = rsnd_kctrl_valm(ctu->pass, i);
@@ -146,45 +136,13 @@ static void rsnd_ctu_value_init(struct rsnd_dai_stream *io,
146 136
147 rsnd_mod_write(mod, CTU_SCMDR, scmdr); 137 rsnd_mod_write(mod, CTU_SCMDR, scmdr);
148 138
149 if (scmdr > 0) { 139 for (i = 0; i < 4; i++) {
150 rsnd_mod_write(mod, CTU_SV00R, rsnd_kctrl_valm(ctu->sv0, 0)); 140
151 rsnd_mod_write(mod, CTU_SV01R, rsnd_kctrl_valm(ctu->sv0, 1)); 141 if (i >= scmdr)
152 rsnd_mod_write(mod, CTU_SV02R, rsnd_kctrl_valm(ctu->sv0, 2)); 142 break;
153 rsnd_mod_write(mod, CTU_SV03R, rsnd_kctrl_valm(ctu->sv0, 3)); 143
154 rsnd_mod_write(mod, CTU_SV04R, rsnd_kctrl_valm(ctu->sv0, 4)); 144 for (j = 0; j < RSND_MAX_CHANNELS; j++)
155 rsnd_mod_write(mod, CTU_SV05R, rsnd_kctrl_valm(ctu->sv0, 5)); 145 rsnd_mod_write(mod, CTU_SVxxR(i, j), rsnd_kctrl_valm(ctu->sv[i], j));
156 rsnd_mod_write(mod, CTU_SV06R, rsnd_kctrl_valm(ctu->sv0, 6));
157 rsnd_mod_write(mod, CTU_SV07R, rsnd_kctrl_valm(ctu->sv0, 7));
158 }
159 if (scmdr > 1) {
160 rsnd_mod_write(mod, CTU_SV10R, rsnd_kctrl_valm(ctu->sv1, 0));
161 rsnd_mod_write(mod, CTU_SV11R, rsnd_kctrl_valm(ctu->sv1, 1));
162 rsnd_mod_write(mod, CTU_SV12R, rsnd_kctrl_valm(ctu->sv1, 2));
163 rsnd_mod_write(mod, CTU_SV13R, rsnd_kctrl_valm(ctu->sv1, 3));
164 rsnd_mod_write(mod, CTU_SV14R, rsnd_kctrl_valm(ctu->sv1, 4));
165 rsnd_mod_write(mod, CTU_SV15R, rsnd_kctrl_valm(ctu->sv1, 5));
166 rsnd_mod_write(mod, CTU_SV16R, rsnd_kctrl_valm(ctu->sv1, 6));
167 rsnd_mod_write(mod, CTU_SV17R, rsnd_kctrl_valm(ctu->sv1, 7));
168 }
169 if (scmdr > 2) {
170 rsnd_mod_write(mod, CTU_SV20R, rsnd_kctrl_valm(ctu->sv2, 0));
171 rsnd_mod_write(mod, CTU_SV21R, rsnd_kctrl_valm(ctu->sv2, 1));
172 rsnd_mod_write(mod, CTU_SV22R, rsnd_kctrl_valm(ctu->sv2, 2));
173 rsnd_mod_write(mod, CTU_SV23R, rsnd_kctrl_valm(ctu->sv2, 3));
174 rsnd_mod_write(mod, CTU_SV24R, rsnd_kctrl_valm(ctu->sv2, 4));
175 rsnd_mod_write(mod, CTU_SV25R, rsnd_kctrl_valm(ctu->sv2, 5));
176 rsnd_mod_write(mod, CTU_SV26R, rsnd_kctrl_valm(ctu->sv2, 6));
177 rsnd_mod_write(mod, CTU_SV27R, rsnd_kctrl_valm(ctu->sv2, 7));
178 }
179 if (scmdr > 3) {
180 rsnd_mod_write(mod, CTU_SV30R, rsnd_kctrl_valm(ctu->sv3, 0));
181 rsnd_mod_write(mod, CTU_SV31R, rsnd_kctrl_valm(ctu->sv3, 1));
182 rsnd_mod_write(mod, CTU_SV32R, rsnd_kctrl_valm(ctu->sv3, 2));
183 rsnd_mod_write(mod, CTU_SV33R, rsnd_kctrl_valm(ctu->sv3, 3));
184 rsnd_mod_write(mod, CTU_SV34R, rsnd_kctrl_valm(ctu->sv3, 4));
185 rsnd_mod_write(mod, CTU_SV35R, rsnd_kctrl_valm(ctu->sv3, 5));
186 rsnd_mod_write(mod, CTU_SV36R, rsnd_kctrl_valm(ctu->sv3, 6));
187 rsnd_mod_write(mod, CTU_SV37R, rsnd_kctrl_valm(ctu->sv3, 7));
188 } 146 }
189 147
190 rsnd_mod_write(mod, CTU_CTUIR, 0); 148 rsnd_mod_write(mod, CTU_CTUIR, 0);
@@ -201,10 +159,10 @@ static void rsnd_ctu_value_reset(struct rsnd_dai_stream *io,
201 159
202 for (i = 0; i < RSND_MAX_CHANNELS; i++) { 160 for (i = 0; i < RSND_MAX_CHANNELS; i++) {
203 rsnd_kctrl_valm(ctu->pass, i) = 0; 161 rsnd_kctrl_valm(ctu->pass, i) = 0;
204 rsnd_kctrl_valm(ctu->sv0, i) = 0; 162 rsnd_kctrl_valm(ctu->sv[0], i) = 0;
205 rsnd_kctrl_valm(ctu->sv1, i) = 0; 163 rsnd_kctrl_valm(ctu->sv[1], i) = 0;
206 rsnd_kctrl_valm(ctu->sv2, i) = 0; 164 rsnd_kctrl_valm(ctu->sv[2], i) = 0;
207 rsnd_kctrl_valm(ctu->sv3, i) = 0; 165 rsnd_kctrl_valm(ctu->sv[3], i) = 0;
208 } 166 }
209 rsnd_kctrl_vals(ctu->reset) = 0; 167 rsnd_kctrl_vals(ctu->reset) = 0;
210} 168}
@@ -233,43 +191,6 @@ static int rsnd_ctu_quit(struct rsnd_mod *mod,
233 return 0; 191 return 0;
234} 192}
235 193
236static int rsnd_ctu_hw_params(struct rsnd_mod *mod,
237 struct rsnd_dai_stream *io,
238 struct snd_pcm_substream *substream,
239 struct snd_pcm_hw_params *fe_params)
240{
241 struct rsnd_ctu *ctu = rsnd_mod_to_ctu(mod);
242 struct snd_soc_pcm_runtime *fe = substream->private_data;
243
244 /*
245 * CTU assumes that it is used under DPCM if user want to use
246 * channel transfer. Then, CTU should be FE.
247 * And then, this function will be called *after* BE settings.
248 * this means, each BE already has fixuped hw_params.
249 * see
250 * dpcm_fe_dai_hw_params()
251 * dpcm_be_dai_hw_params()
252 */
253 ctu->channels = 0;
254 if (fe->dai_link->dynamic) {
255 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
256 struct device *dev = rsnd_priv_to_dev(priv);
257 struct snd_soc_dpcm *dpcm;
258 struct snd_pcm_hw_params *be_params;
259 int stream = substream->stream;
260
261 for_each_dpcm_be(fe, stream, dpcm) {
262 be_params = &dpcm->hw_params;
263 if (params_channels(fe_params) != params_channels(be_params))
264 ctu->channels = params_channels(be_params);
265 }
266
267 dev_dbg(dev, "CTU convert channels %d\n", ctu->channels);
268 }
269
270 return 0;
271}
272
273static int rsnd_ctu_pcm_new(struct rsnd_mod *mod, 194static int rsnd_ctu_pcm_new(struct rsnd_mod *mod,
274 struct rsnd_dai_stream *io, 195 struct rsnd_dai_stream *io,
275 struct snd_soc_pcm_runtime *rtd) 196 struct snd_soc_pcm_runtime *rtd)
@@ -291,7 +212,7 @@ static int rsnd_ctu_pcm_new(struct rsnd_mod *mod,
291 ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV0", 212 ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV0",
292 rsnd_kctrl_accept_anytime, 213 rsnd_kctrl_accept_anytime,
293 NULL, 214 NULL,
294 &ctu->sv0, RSND_MAX_CHANNELS, 215 &ctu->sv[0], RSND_MAX_CHANNELS,
295 0x00FFFFFF); 216 0x00FFFFFF);
296 if (ret < 0) 217 if (ret < 0)
297 return ret; 218 return ret;
@@ -300,7 +221,7 @@ static int rsnd_ctu_pcm_new(struct rsnd_mod *mod,
300 ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV1", 221 ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV1",
301 rsnd_kctrl_accept_anytime, 222 rsnd_kctrl_accept_anytime,
302 NULL, 223 NULL,
303 &ctu->sv1, RSND_MAX_CHANNELS, 224 &ctu->sv[1], RSND_MAX_CHANNELS,
304 0x00FFFFFF); 225 0x00FFFFFF);
305 if (ret < 0) 226 if (ret < 0)
306 return ret; 227 return ret;
@@ -309,7 +230,7 @@ static int rsnd_ctu_pcm_new(struct rsnd_mod *mod,
309 ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV2", 230 ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV2",
310 rsnd_kctrl_accept_anytime, 231 rsnd_kctrl_accept_anytime,
311 NULL, 232 NULL,
312 &ctu->sv2, RSND_MAX_CHANNELS, 233 &ctu->sv[2], RSND_MAX_CHANNELS,
313 0x00FFFFFF); 234 0x00FFFFFF);
314 if (ret < 0) 235 if (ret < 0)
315 return ret; 236 return ret;
@@ -318,7 +239,7 @@ static int rsnd_ctu_pcm_new(struct rsnd_mod *mod,
318 ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV3", 239 ret = rsnd_kctrl_new_m(mod, io, rtd, "CTU SV3",
319 rsnd_kctrl_accept_anytime, 240 rsnd_kctrl_accept_anytime,
320 NULL, 241 NULL,
321 &ctu->sv3, RSND_MAX_CHANNELS, 242 &ctu->sv[3], RSND_MAX_CHANNELS,
322 0x00FFFFFF); 243 0x00FFFFFF);
323 if (ret < 0) 244 if (ret < 0)
324 return ret; 245 return ret;
@@ -334,13 +255,34 @@ static int rsnd_ctu_pcm_new(struct rsnd_mod *mod,
334 return ret; 255 return ret;
335} 256}
336 257
258static int rsnd_ctu_id(struct rsnd_mod *mod)
259{
260 /*
261 * ctu00: -> 0, ctu01: -> 0, ctu02: -> 0, ctu03: -> 0
262 * ctu10: -> 1, ctu11: -> 1, ctu12: -> 1, ctu13: -> 1
263 */
264 return mod->id / 4;
265}
266
267static int rsnd_ctu_id_sub(struct rsnd_mod *mod)
268{
269 /*
270 * ctu00: -> 0, ctu01: -> 1, ctu02: -> 2, ctu03: -> 3
271 * ctu10: -> 0, ctu11: -> 1, ctu12: -> 2, ctu13: -> 3
272 */
273 return mod->id % 4;
274}
275
337static struct rsnd_mod_ops rsnd_ctu_ops = { 276static struct rsnd_mod_ops rsnd_ctu_ops = {
338 .name = CTU_NAME, 277 .name = CTU_NAME,
339 .probe = rsnd_ctu_probe_, 278 .probe = rsnd_ctu_probe_,
340 .init = rsnd_ctu_init, 279 .init = rsnd_ctu_init,
341 .quit = rsnd_ctu_quit, 280 .quit = rsnd_ctu_quit,
342 .hw_params = rsnd_ctu_hw_params,
343 .pcm_new = rsnd_ctu_pcm_new, 281 .pcm_new = rsnd_ctu_pcm_new,
282 .get_status = rsnd_mod_get_status,
283 .id = rsnd_ctu_id,
284 .id_sub = rsnd_ctu_id_sub,
285 .id_cmd = rsnd_mod_id_raw,
344}; 286};
345 287
346struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id) 288struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id)
@@ -404,7 +346,7 @@ int rsnd_ctu_probe(struct rsnd_priv *priv)
404 } 346 }
405 347
406 ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops, 348 ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops,
407 clk, rsnd_mod_get_status, RSND_MOD_CTU, i); 349 clk, RSND_MOD_CTU, i);
408 if (ret) { 350 if (ret) {
409 of_node_put(np); 351 of_node_put(np);
410 goto rsnd_ctu_probe_done; 352 goto rsnd_ctu_probe_done;
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index 6d1947515dc8..0324a5c39619 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -174,8 +174,8 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod,
174 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 174 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
175 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 175 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
176 176
177 dev_dbg(dev, "%s[%d] %pad -> %pad\n", 177 dev_dbg(dev, "%s %pad -> %pad\n",
178 rsnd_mod_name(mod), rsnd_mod_id(mod), 178 rsnd_mod_name(mod),
179 &cfg.src_addr, &cfg.dst_addr); 179 &cfg.src_addr, &cfg.dst_addr);
180 180
181 ret = dmaengine_slave_config(dmaen->chan, &cfg); 181 ret = dmaengine_slave_config(dmaen->chan, &cfg);
@@ -218,7 +218,7 @@ struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
218 int i = 0; 218 int i = 0;
219 219
220 for_each_child_of_node(of_node, np) { 220 for_each_child_of_node(of_node, np) {
221 if (i == rsnd_mod_id(mod) && (!chan)) 221 if (i == rsnd_mod_id_raw(mod) && (!chan))
222 chan = of_dma_request_slave_channel(np, name); 222 chan = of_dma_request_slave_channel(np, name);
223 i++; 223 i++;
224 } 224 }
@@ -289,12 +289,13 @@ static int rsnd_dmaen_pointer(struct rsnd_mod *mod,
289} 289}
290 290
291static struct rsnd_mod_ops rsnd_dmaen_ops = { 291static struct rsnd_mod_ops rsnd_dmaen_ops = {
292 .name = "audmac", 292 .name = "audmac",
293 .prepare = rsnd_dmaen_prepare, 293 .prepare = rsnd_dmaen_prepare,
294 .cleanup = rsnd_dmaen_cleanup, 294 .cleanup = rsnd_dmaen_cleanup,
295 .start = rsnd_dmaen_start, 295 .start = rsnd_dmaen_start,
296 .stop = rsnd_dmaen_stop, 296 .stop = rsnd_dmaen_stop,
297 .pointer= rsnd_dmaen_pointer, 297 .pointer = rsnd_dmaen_pointer,
298 .get_status = rsnd_mod_get_status,
298}; 299};
299 300
300/* 301/*
@@ -343,14 +344,16 @@ static u32 rsnd_dmapp_get_id(struct rsnd_dai_stream *io,
343 struct rsnd_mod *mod) 344 struct rsnd_mod *mod)
344{ 345{
345 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); 346 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
347 struct rsnd_mod *ssiu = rsnd_io_to_mod_ssiu(io);
346 struct rsnd_mod *src = rsnd_io_to_mod_src(io); 348 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
347 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); 349 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
348 const u8 *entry = NULL; 350 const u8 *entry = NULL;
349 int id = 255; 351 int id = 255;
350 int size = 0; 352 int size = 0;
351 353
352 if (mod == ssi) { 354 if ((mod == ssi) ||
353 int busif = rsnd_ssi_get_busif(io); 355 (mod == ssiu)) {
356 int busif = rsnd_mod_id_sub(ssiu);
354 357
355 entry = gen2_id_table_ssiu; 358 entry = gen2_id_table_ssiu;
356 size = ARRAY_SIZE(gen2_id_table_ssiu); 359 size = ARRAY_SIZE(gen2_id_table_ssiu);
@@ -368,8 +371,7 @@ static u32 rsnd_dmapp_get_id(struct rsnd_dai_stream *io,
368 if ((!entry) || (size <= id)) { 371 if ((!entry) || (size <= id)) {
369 struct device *dev = rsnd_priv_to_dev(rsnd_io_to_priv(io)); 372 struct device *dev = rsnd_priv_to_dev(rsnd_io_to_priv(io));
370 373
371 dev_err(dev, "unknown connection (%s[%d])\n", 374 dev_err(dev, "unknown connection (%s)\n", rsnd_mod_name(mod));
372 rsnd_mod_name(mod), rsnd_mod_id(mod));
373 375
374 /* use non-prohibited SRS number as error */ 376 /* use non-prohibited SRS number as error */
375 return 0x00; /* SSI00 */ 377 return 0x00; /* SSI00 */
@@ -477,10 +479,11 @@ static int rsnd_dmapp_attach(struct rsnd_dai_stream *io,
477} 479}
478 480
479static struct rsnd_mod_ops rsnd_dmapp_ops = { 481static struct rsnd_mod_ops rsnd_dmapp_ops = {
480 .name = "audmac-pp", 482 .name = "audmac-pp",
481 .start = rsnd_dmapp_start, 483 .start = rsnd_dmapp_start,
482 .stop = rsnd_dmapp_stop, 484 .stop = rsnd_dmapp_stop,
483 .quit = rsnd_dmapp_stop, 485 .quit = rsnd_dmapp_stop,
486 .get_status = rsnd_mod_get_status,
484}; 487};
485 488
486/* 489/*
@@ -529,13 +532,14 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io,
529 struct device *dev = rsnd_priv_to_dev(priv); 532 struct device *dev = rsnd_priv_to_dev(priv);
530 phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI); 533 phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI);
531 phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU); 534 phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU);
532 int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod); 535 int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod) ||
536 !!(rsnd_io_to_mod_ssiu(io) == mod);
533 int use_src = !!rsnd_io_to_mod_src(io); 537 int use_src = !!rsnd_io_to_mod_src(io);
534 int use_cmd = !!rsnd_io_to_mod_dvc(io) || 538 int use_cmd = !!rsnd_io_to_mod_dvc(io) ||
535 !!rsnd_io_to_mod_mix(io) || 539 !!rsnd_io_to_mod_mix(io) ||
536 !!rsnd_io_to_mod_ctu(io); 540 !!rsnd_io_to_mod_ctu(io);
537 int id = rsnd_mod_id(mod); 541 int id = rsnd_mod_id(mod);
538 int busif = rsnd_ssi_get_busif(io); 542 int busif = rsnd_mod_id_sub(rsnd_io_to_mod_ssiu(io));
539 struct dma_addr { 543 struct dma_addr {
540 dma_addr_t out_addr; 544 dma_addr_t out_addr;
541 dma_addr_t in_addr; 545 dma_addr_t in_addr;
@@ -619,7 +623,7 @@ static void rsnd_dma_of_path(struct rsnd_mod *this,
619 struct rsnd_mod **mod_from, 623 struct rsnd_mod **mod_from,
620 struct rsnd_mod **mod_to) 624 struct rsnd_mod **mod_to)
621{ 625{
622 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io); 626 struct rsnd_mod *ssi;
623 struct rsnd_mod *src = rsnd_io_to_mod_src(io); 627 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
624 struct rsnd_mod *ctu = rsnd_io_to_mod_ctu(io); 628 struct rsnd_mod *ctu = rsnd_io_to_mod_ctu(io);
625 struct rsnd_mod *mix = rsnd_io_to_mod_mix(io); 629 struct rsnd_mod *mix = rsnd_io_to_mod_mix(io);
@@ -630,6 +634,28 @@ static void rsnd_dma_of_path(struct rsnd_mod *this,
630 struct device *dev = rsnd_priv_to_dev(priv); 634 struct device *dev = rsnd_priv_to_dev(priv);
631 int nr, i, idx; 635 int nr, i, idx;
632 636
637 /*
638 * It should use "rcar_sound,ssiu" on DT.
639 * But, we need to keep compatibility for old version.
640 *
641 * If it has "rcar_sound.ssiu", it will be used.
642 * If not, "rcar_sound.ssi" will be used.
643 * see
644 * rsnd_ssiu_dma_req()
645 * rsnd_ssi_dma_req()
646 */
647 if (rsnd_ssiu_of_node(priv)) {
648 struct rsnd_mod *ssiu = rsnd_io_to_mod_ssiu(io);
649
650 /* use SSIU */
651 ssi = ssiu;
652 if (this == rsnd_io_to_mod_ssi(io))
653 this = ssiu;
654 } else {
655 /* keep compatible, use SSI */
656 ssi = rsnd_io_to_mod_ssi(io);
657 }
658
633 if (!ssi) 659 if (!ssi)
634 return; 660 return;
635 661
@@ -690,12 +716,10 @@ static void rsnd_dma_of_path(struct rsnd_mod *this,
690 *mod_to = mod[1]; 716 *mod_to = mod[1];
691 } 717 }
692 718
693 dev_dbg(dev, "module connection (this is %s[%d])\n", 719 dev_dbg(dev, "module connection (this is %s)\n", rsnd_mod_name(this));
694 rsnd_mod_name(this), rsnd_mod_id(this));
695 for (i = 0; i <= idx; i++) { 720 for (i = 0; i <= idx; i++) {
696 dev_dbg(dev, " %s[%d]%s\n", 721 dev_dbg(dev, " %s%s\n",
697 rsnd_mod_name(mod[i] ? mod[i] : &mem), 722 rsnd_mod_name(mod[i] ? mod[i] : &mem),
698 rsnd_mod_id (mod[i] ? mod[i] : &mem),
699 (mod[i] == *mod_from) ? " from" : 723 (mod[i] == *mod_from) ? " from" :
700 (mod[i] == *mod_to) ? " to" : ""); 724 (mod[i] == *mod_to) ? " to" : "");
701 } 725 }
@@ -756,16 +780,14 @@ static int rsnd_dma_alloc(struct rsnd_dai_stream *io, struct rsnd_mod *mod,
756 *dma_mod = rsnd_mod_get(dma); 780 *dma_mod = rsnd_mod_get(dma);
757 781
758 ret = rsnd_mod_init(priv, *dma_mod, ops, NULL, 782 ret = rsnd_mod_init(priv, *dma_mod, ops, NULL,
759 rsnd_mod_get_status, type, dma_id); 783 type, dma_id);
760 if (ret < 0) 784 if (ret < 0)
761 return ret; 785 return ret;
762 786
763 dev_dbg(dev, "%s[%d] %s[%d] -> %s[%d]\n", 787 dev_dbg(dev, "%s %s -> %s\n",
764 rsnd_mod_name(*dma_mod), rsnd_mod_id(*dma_mod), 788 rsnd_mod_name(*dma_mod),
765 rsnd_mod_name(mod_from ? mod_from : &mem), 789 rsnd_mod_name(mod_from ? mod_from : &mem),
766 rsnd_mod_id (mod_from ? mod_from : &mem), 790 rsnd_mod_name(mod_to ? mod_to : &mem));
767 rsnd_mod_name(mod_to ? mod_to : &mem),
768 rsnd_mod_id (mod_to ? mod_to : &mem));
769 791
770 ret = attach(io, dma, mod_from, mod_to); 792 ret = attach(io, dma, mod_from, mod_to);
771 if (ret < 0) 793 if (ret < 0)
@@ -823,5 +845,5 @@ int rsnd_dma_probe(struct rsnd_priv *priv)
823 priv->dma = dmac; 845 priv->dma = dmac;
824 846
825 /* dummy mem mod for debug */ 847 /* dummy mem mod for debug */
826 return rsnd_mod_init(NULL, &mem, &mem_ops, NULL, NULL, 0, 0); 848 return rsnd_mod_init(NULL, &mem, &mem_ops, NULL, 0, 0);
827} 849}
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index 2b16e0ce6bc5..8d91c0eb0880 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -40,11 +40,8 @@ struct rsnd_dvc {
40 struct rsnd_kctrl_cfg_s ren; /* Ramp Enable */ 40 struct rsnd_kctrl_cfg_s ren; /* Ramp Enable */
41 struct rsnd_kctrl_cfg_s rup; /* Ramp Rate Up */ 41 struct rsnd_kctrl_cfg_s rup; /* Ramp Rate Up */
42 struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */ 42 struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */
43 u32 flags;
44}; 43};
45 44
46#define KCTRL_INITIALIZED (1 << 0)
47
48#define rsnd_dvc_get(priv, id) ((struct rsnd_dvc *)(priv->dvc) + id) 45#define rsnd_dvc_get(priv, id) ((struct rsnd_dvc *)(priv->dvc) + id)
49#define rsnd_dvc_nr(priv) ((priv)->dvc_nr) 46#define rsnd_dvc_nr(priv) ((priv)->dvc_nr)
50 47
@@ -89,14 +86,8 @@ static void rsnd_dvc_volume_parameter(struct rsnd_dai_stream *io,
89 val[i] = rsnd_kctrl_valm(dvc->volume, i); 86 val[i] = rsnd_kctrl_valm(dvc->volume, i);
90 87
91 /* Enable Digital Volume */ 88 /* Enable Digital Volume */
92 rsnd_mod_write(mod, DVC_VOL0R, val[0]); 89 for (i = 0; i < RSND_MAX_CHANNELS; i++)
93 rsnd_mod_write(mod, DVC_VOL1R, val[1]); 90 rsnd_mod_write(mod, DVC_VOLxR(i), val[i]);
94 rsnd_mod_write(mod, DVC_VOL2R, val[2]);
95 rsnd_mod_write(mod, DVC_VOL3R, val[3]);
96 rsnd_mod_write(mod, DVC_VOL4R, val[4]);
97 rsnd_mod_write(mod, DVC_VOL5R, val[5]);
98 rsnd_mod_write(mod, DVC_VOL6R, val[6]);
99 rsnd_mod_write(mod, DVC_VOL7R, val[7]);
100} 91}
101 92
102static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io, 93static void rsnd_dvc_volume_init(struct rsnd_dai_stream *io,
@@ -227,9 +218,6 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
227 int channels = rsnd_rdai_channels_get(rdai); 218 int channels = rsnd_rdai_channels_get(rdai);
228 int ret; 219 int ret;
229 220
230 if (rsnd_flags_has(dvc, KCTRL_INITIALIZED))
231 return 0;
232
233 /* Volume */ 221 /* Volume */
234 ret = rsnd_kctrl_new_m(mod, io, rtd, 222 ret = rsnd_kctrl_new_m(mod, io, rtd,
235 is_play ? 223 is_play ?
@@ -285,8 +273,6 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
285 if (ret < 0) 273 if (ret < 0)
286 return ret; 274 return ret;
287 275
288 rsnd_flags_set(dvc, KCTRL_INITIALIZED);
289
290 return 0; 276 return 0;
291} 277}
292 278
@@ -306,6 +292,7 @@ static struct rsnd_mod_ops rsnd_dvc_ops = {
306 .init = rsnd_dvc_init, 292 .init = rsnd_dvc_init,
307 .quit = rsnd_dvc_quit, 293 .quit = rsnd_dvc_quit,
308 .pcm_new = rsnd_dvc_pcm_new, 294 .pcm_new = rsnd_dvc_pcm_new,
295 .get_status = rsnd_mod_get_status,
309}; 296};
310 297
311struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id) 298struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id)
@@ -365,7 +352,7 @@ int rsnd_dvc_probe(struct rsnd_priv *priv)
365 } 352 }
366 353
367 ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops, 354 ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
368 clk, rsnd_mod_get_status, RSND_MOD_DVC, i); 355 clk, RSND_MOD_DVC, i);
369 if (ret) { 356 if (ret) {
370 of_node_put(np); 357 of_node_put(np);
371 goto rsnd_dvc_probe_done; 358 goto rsnd_dvc_probe_done;
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index 1f7881cc16b2..7cda60188f41 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -26,8 +26,8 @@ struct rsnd_gen {
26 struct regmap *regmap[RSND_BASE_MAX]; 26 struct regmap *regmap[RSND_BASE_MAX];
27 27
28 /* RSND_REG_MAX base */ 28 /* RSND_REG_MAX base */
29 struct regmap_field *regs[RSND_REG_MAX]; 29 struct regmap_field *regs[REG_MAX];
30 const char *reg_name[RSND_REG_MAX]; 30 const char *reg_name[REG_MAX];
31}; 31};
32 32
33#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) 33#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen)
@@ -49,11 +49,11 @@ struct rsnd_regmap_field_conf {
49} 49}
50/* single address mapping */ 50/* single address mapping */
51#define RSND_GEN_S_REG(id, offset) \ 51#define RSND_GEN_S_REG(id, offset) \
52 RSND_REG_SET(RSND_REG_##id, offset, 0, #id) 52 RSND_REG_SET(id, offset, 0, #id)
53 53
54/* multi address mapping */ 54/* multi address mapping */
55#define RSND_GEN_M_REG(id, offset, _id_offset) \ 55#define RSND_GEN_M_REG(id, offset, _id_offset) \
56 RSND_REG_SET(RSND_REG_##id, offset, _id_offset, #id) 56 RSND_REG_SET(id, offset, _id_offset, #id)
57 57
58/* 58/*
59 * basic function 59 * basic function
@@ -71,9 +71,17 @@ static int rsnd_is_accessible_reg(struct rsnd_priv *priv,
71 return 1; 71 return 1;
72} 72}
73 73
74u32 rsnd_read(struct rsnd_priv *priv, 74static int rsnd_mod_id_cmd(struct rsnd_mod *mod)
75 struct rsnd_mod *mod, enum rsnd_reg reg)
76{ 75{
76 if (mod->ops->id_cmd)
77 return mod->ops->id_cmd(mod);
78
79 return rsnd_mod_id(mod);
80}
81
82u32 rsnd_mod_read(struct rsnd_mod *mod, enum rsnd_reg reg)
83{
84 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
77 struct device *dev = rsnd_priv_to_dev(priv); 85 struct device *dev = rsnd_priv_to_dev(priv);
78 struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 86 struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
79 u32 val; 87 u32 val;
@@ -81,35 +89,36 @@ u32 rsnd_read(struct rsnd_priv *priv,
81 if (!rsnd_is_accessible_reg(priv, gen, reg)) 89 if (!rsnd_is_accessible_reg(priv, gen, reg))
82 return 0; 90 return 0;
83 91
84 regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); 92 regmap_fields_read(gen->regs[reg], rsnd_mod_id_cmd(mod), &val);
85 93
86 dev_dbg(dev, "r %s[%d] - %-18s (%4d) : %08x\n", 94 dev_dbg(dev, "r %s - %-18s (%4d) : %08x\n",
87 rsnd_mod_name(mod), rsnd_mod_id(mod), 95 rsnd_mod_name(mod),
88 rsnd_reg_name(gen, reg), reg, val); 96 rsnd_reg_name(gen, reg), reg, val);
89 97
90 return val; 98 return val;
91} 99}
92 100
93void rsnd_write(struct rsnd_priv *priv, 101void rsnd_mod_write(struct rsnd_mod *mod,
94 struct rsnd_mod *mod, 102 enum rsnd_reg reg, u32 data)
95 enum rsnd_reg reg, u32 data)
96{ 103{
104 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
97 struct device *dev = rsnd_priv_to_dev(priv); 105 struct device *dev = rsnd_priv_to_dev(priv);
98 struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 106 struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
99 107
100 if (!rsnd_is_accessible_reg(priv, gen, reg)) 108 if (!rsnd_is_accessible_reg(priv, gen, reg))
101 return; 109 return;
102 110
103 regmap_fields_force_write(gen->regs[reg], rsnd_mod_id(mod), data); 111 regmap_fields_force_write(gen->regs[reg], rsnd_mod_id_cmd(mod), data);
104 112
105 dev_dbg(dev, "w %s[%d] - %-18s (%4d) : %08x\n", 113 dev_dbg(dev, "w %s - %-18s (%4d) : %08x\n",
106 rsnd_mod_name(mod), rsnd_mod_id(mod), 114 rsnd_mod_name(mod),
107 rsnd_reg_name(gen, reg), reg, data); 115 rsnd_reg_name(gen, reg), reg, data);
108} 116}
109 117
110void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, 118void rsnd_mod_bset(struct rsnd_mod *mod,
111 enum rsnd_reg reg, u32 mask, u32 data) 119 enum rsnd_reg reg, u32 mask, u32 data)
112{ 120{
121 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
113 struct device *dev = rsnd_priv_to_dev(priv); 122 struct device *dev = rsnd_priv_to_dev(priv);
114 struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 123 struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
115 124
@@ -117,10 +126,10 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
117 return; 126 return;
118 127
119 regmap_fields_force_update_bits(gen->regs[reg], 128 regmap_fields_force_update_bits(gen->regs[reg],
120 rsnd_mod_id(mod), mask, data); 129 rsnd_mod_id_cmd(mod), mask, data);
121 130
122 dev_dbg(dev, "b %s[%d] - %-18s (%4d) : %08x/%08x\n", 131 dev_dbg(dev, "b %s - %-18s (%4d) : %08x/%08x\n",
123 rsnd_mod_name(mod), rsnd_mod_id(mod), 132 rsnd_mod_name(mod),
124 rsnd_reg_name(gen, reg), reg, data, mask); 133 rsnd_reg_name(gen, reg), reg, data, mask);
125 134
126} 135}
diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c
index 8e3b57eaa708..a3e0370f5704 100644
--- a/sound/soc/sh/rcar/mix.c
+++ b/sound/soc/sh/rcar/mix.c
@@ -256,6 +256,7 @@ static struct rsnd_mod_ops rsnd_mix_ops = {
256 .init = rsnd_mix_init, 256 .init = rsnd_mix_init,
257 .quit = rsnd_mix_quit, 257 .quit = rsnd_mix_quit,
258 .pcm_new = rsnd_mix_pcm_new, 258 .pcm_new = rsnd_mix_pcm_new,
259 .get_status = rsnd_mod_get_status,
259}; 260};
260 261
261struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id) 262struct rsnd_mod *rsnd_mix_mod_get(struct rsnd_priv *priv, int id)
@@ -315,7 +316,7 @@ int rsnd_mix_probe(struct rsnd_priv *priv)
315 } 316 }
316 317
317 ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops, 318 ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops,
318 clk, rsnd_mod_get_status, RSND_MOD_MIX, i); 319 clk, RSND_MOD_MIX, i);
319 if (ret) { 320 if (ret) {
320 of_node_put(np); 321 of_node_put(np);
321 goto rsnd_mix_probe_done; 322 goto rsnd_mix_probe_done;
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 4464d1d0a042..605e4b934982 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -42,165 +42,175 @@
42 */ 42 */
43enum rsnd_reg { 43enum rsnd_reg {
44 /* SCU (MIX/CTU/DVC) */ 44 /* SCU (MIX/CTU/DVC) */
45 RSND_REG_SRC_I_BUSIF_MODE, 45 SRC_I_BUSIF_MODE,
46 RSND_REG_SRC_O_BUSIF_MODE, 46 SRC_O_BUSIF_MODE,
47 RSND_REG_SRC_ROUTE_MODE0, 47 SRC_ROUTE_MODE0,
48 RSND_REG_SRC_SWRSR, 48 SRC_SWRSR,
49 RSND_REG_SRC_SRCIR, 49 SRC_SRCIR,
50 RSND_REG_SRC_ADINR, 50 SRC_ADINR,
51 RSND_REG_SRC_IFSCR, 51 SRC_IFSCR,
52 RSND_REG_SRC_IFSVR, 52 SRC_IFSVR,
53 RSND_REG_SRC_SRCCR, 53 SRC_SRCCR,
54 RSND_REG_SRC_CTRL, 54 SRC_CTRL,
55 RSND_REG_SRC_BSDSR, 55 SRC_BSDSR,
56 RSND_REG_SRC_BSISR, 56 SRC_BSISR,
57 RSND_REG_SRC_INT_ENABLE0, 57 SRC_INT_ENABLE0,
58 RSND_REG_SRC_BUSIF_DALIGN, 58 SRC_BUSIF_DALIGN,
59 RSND_REG_SRCIN_TIMSEL0, 59 SRCIN_TIMSEL0,
60 RSND_REG_SRCIN_TIMSEL1, 60 SRCIN_TIMSEL1,
61 RSND_REG_SRCIN_TIMSEL2, 61 SRCIN_TIMSEL2,
62 RSND_REG_SRCIN_TIMSEL3, 62 SRCIN_TIMSEL3,
63 RSND_REG_SRCIN_TIMSEL4, 63 SRCIN_TIMSEL4,
64 RSND_REG_SRCOUT_TIMSEL0, 64 SRCOUT_TIMSEL0,
65 RSND_REG_SRCOUT_TIMSEL1, 65 SRCOUT_TIMSEL1,
66 RSND_REG_SRCOUT_TIMSEL2, 66 SRCOUT_TIMSEL2,
67 RSND_REG_SRCOUT_TIMSEL3, 67 SRCOUT_TIMSEL3,
68 RSND_REG_SRCOUT_TIMSEL4, 68 SRCOUT_TIMSEL4,
69 RSND_REG_SCU_SYS_STATUS0, 69 SCU_SYS_STATUS0,
70 RSND_REG_SCU_SYS_STATUS1, 70 SCU_SYS_STATUS1,
71 RSND_REG_SCU_SYS_INT_EN0, 71 SCU_SYS_INT_EN0,
72 RSND_REG_SCU_SYS_INT_EN1, 72 SCU_SYS_INT_EN1,
73 RSND_REG_CMD_CTRL, 73 CMD_CTRL,
74 RSND_REG_CMD_BUSIF_MODE, 74 CMD_BUSIF_MODE,
75 RSND_REG_CMD_BUSIF_DALIGN, 75 CMD_BUSIF_DALIGN,
76 RSND_REG_CMD_ROUTE_SLCT, 76 CMD_ROUTE_SLCT,
77 RSND_REG_CMDOUT_TIMSEL, 77 CMDOUT_TIMSEL,
78 RSND_REG_CTU_SWRSR, 78 CTU_SWRSR,
79 RSND_REG_CTU_CTUIR, 79 CTU_CTUIR,
80 RSND_REG_CTU_ADINR, 80 CTU_ADINR,
81 RSND_REG_CTU_CPMDR, 81 CTU_CPMDR,
82 RSND_REG_CTU_SCMDR, 82 CTU_SCMDR,
83 RSND_REG_CTU_SV00R, 83 CTU_SV00R,
84 RSND_REG_CTU_SV01R, 84 CTU_SV01R,
85 RSND_REG_CTU_SV02R, 85 CTU_SV02R,
86 RSND_REG_CTU_SV03R, 86 CTU_SV03R,
87 RSND_REG_CTU_SV04R, 87 CTU_SV04R,
88 RSND_REG_CTU_SV05R, 88 CTU_SV05R,
89 RSND_REG_CTU_SV06R, 89 CTU_SV06R,
90 RSND_REG_CTU_SV07R, 90 CTU_SV07R,
91 RSND_REG_CTU_SV10R, 91 CTU_SV10R,
92 RSND_REG_CTU_SV11R, 92 CTU_SV11R,
93 RSND_REG_CTU_SV12R, 93 CTU_SV12R,
94 RSND_REG_CTU_SV13R, 94 CTU_SV13R,
95 RSND_REG_CTU_SV14R, 95 CTU_SV14R,
96 RSND_REG_CTU_SV15R, 96 CTU_SV15R,
97 RSND_REG_CTU_SV16R, 97 CTU_SV16R,
98 RSND_REG_CTU_SV17R, 98 CTU_SV17R,
99 RSND_REG_CTU_SV20R, 99 CTU_SV20R,
100 RSND_REG_CTU_SV21R, 100 CTU_SV21R,
101 RSND_REG_CTU_SV22R, 101 CTU_SV22R,
102 RSND_REG_CTU_SV23R, 102 CTU_SV23R,
103 RSND_REG_CTU_SV24R, 103 CTU_SV24R,
104 RSND_REG_CTU_SV25R, 104 CTU_SV25R,
105 RSND_REG_CTU_SV26R, 105 CTU_SV26R,
106 RSND_REG_CTU_SV27R, 106 CTU_SV27R,
107 RSND_REG_CTU_SV30R, 107 CTU_SV30R,
108 RSND_REG_CTU_SV31R, 108 CTU_SV31R,
109 RSND_REG_CTU_SV32R, 109 CTU_SV32R,
110 RSND_REG_CTU_SV33R, 110 CTU_SV33R,
111 RSND_REG_CTU_SV34R, 111 CTU_SV34R,
112 RSND_REG_CTU_SV35R, 112 CTU_SV35R,
113 RSND_REG_CTU_SV36R, 113 CTU_SV36R,
114 RSND_REG_CTU_SV37R, 114 CTU_SV37R,
115 RSND_REG_MIX_SWRSR, 115 MIX_SWRSR,
116 RSND_REG_MIX_MIXIR, 116 MIX_MIXIR,
117 RSND_REG_MIX_ADINR, 117 MIX_ADINR,
118 RSND_REG_MIX_MIXMR, 118 MIX_MIXMR,
119 RSND_REG_MIX_MVPDR, 119 MIX_MVPDR,
120 RSND_REG_MIX_MDBAR, 120 MIX_MDBAR,
121 RSND_REG_MIX_MDBBR, 121 MIX_MDBBR,
122 RSND_REG_MIX_MDBCR, 122 MIX_MDBCR,
123 RSND_REG_MIX_MDBDR, 123 MIX_MDBDR,
124 RSND_REG_MIX_MDBER, 124 MIX_MDBER,
125 RSND_REG_DVC_SWRSR, 125 DVC_SWRSR,
126 RSND_REG_DVC_DVUIR, 126 DVC_DVUIR,
127 RSND_REG_DVC_ADINR, 127 DVC_ADINR,
128 RSND_REG_DVC_DVUCR, 128 DVC_DVUCR,
129 RSND_REG_DVC_ZCMCR, 129 DVC_ZCMCR,
130 RSND_REG_DVC_VOL0R, 130 DVC_VOL0R,
131 RSND_REG_DVC_VOL1R, 131 DVC_VOL1R,
132 RSND_REG_DVC_VOL2R, 132 DVC_VOL2R,
133 RSND_REG_DVC_VOL3R, 133 DVC_VOL3R,
134 RSND_REG_DVC_VOL4R, 134 DVC_VOL4R,
135 RSND_REG_DVC_VOL5R, 135 DVC_VOL5R,
136 RSND_REG_DVC_VOL6R, 136 DVC_VOL6R,
137 RSND_REG_DVC_VOL7R, 137 DVC_VOL7R,
138 RSND_REG_DVC_DVUER, 138 DVC_DVUER,
139 RSND_REG_DVC_VRCTR, 139 DVC_VRCTR,
140 RSND_REG_DVC_VRPDR, 140 DVC_VRPDR,
141 RSND_REG_DVC_VRDBR, 141 DVC_VRDBR,
142 142
143 /* ADG */ 143 /* ADG */
144 RSND_REG_BRRA, 144 BRRA,
145 RSND_REG_BRRB, 145 BRRB,
146 RSND_REG_BRGCKR, 146 BRGCKR,
147 RSND_REG_DIV_EN, 147 DIV_EN,
148 RSND_REG_AUDIO_CLK_SEL0, 148 AUDIO_CLK_SEL0,
149 RSND_REG_AUDIO_CLK_SEL1, 149 AUDIO_CLK_SEL1,
150 RSND_REG_AUDIO_CLK_SEL2, 150 AUDIO_CLK_SEL2,
151 151
152 /* SSIU */ 152 /* SSIU */
153 RSND_REG_SSI_MODE, 153 SSI_MODE,
154 RSND_REG_SSI_MODE0, 154 SSI_MODE0,
155 RSND_REG_SSI_MODE1, 155 SSI_MODE1,
156 RSND_REG_SSI_MODE2, 156 SSI_MODE2,
157 RSND_REG_SSI_CONTROL, 157 SSI_CONTROL,
158 RSND_REG_SSI_CTRL, 158 SSI_CTRL,
159 RSND_REG_SSI_BUSIF0_MODE, 159 SSI_BUSIF0_MODE,
160 RSND_REG_SSI_BUSIF0_ADINR, 160 SSI_BUSIF1_MODE,
161 RSND_REG_SSI_BUSIF0_DALIGN, 161 SSI_BUSIF2_MODE,
162 RSND_REG_SSI_BUSIF1_MODE, 162 SSI_BUSIF3_MODE,
163 RSND_REG_SSI_BUSIF1_ADINR, 163 SSI_BUSIF4_MODE,
164 RSND_REG_SSI_BUSIF1_DALIGN, 164 SSI_BUSIF5_MODE,
165 RSND_REG_SSI_BUSIF2_MODE, 165 SSI_BUSIF6_MODE,
166 RSND_REG_SSI_BUSIF2_ADINR, 166 SSI_BUSIF7_MODE,
167 RSND_REG_SSI_BUSIF2_DALIGN, 167 SSI_BUSIF0_ADINR,
168 RSND_REG_SSI_BUSIF3_MODE, 168 SSI_BUSIF1_ADINR,
169 RSND_REG_SSI_BUSIF3_ADINR, 169 SSI_BUSIF2_ADINR,
170 RSND_REG_SSI_BUSIF3_DALIGN, 170 SSI_BUSIF3_ADINR,
171 RSND_REG_SSI_BUSIF4_MODE, 171 SSI_BUSIF4_ADINR,
172 RSND_REG_SSI_BUSIF4_ADINR, 172 SSI_BUSIF5_ADINR,
173 RSND_REG_SSI_BUSIF4_DALIGN, 173 SSI_BUSIF6_ADINR,
174 RSND_REG_SSI_BUSIF5_MODE, 174 SSI_BUSIF7_ADINR,
175 RSND_REG_SSI_BUSIF5_ADINR, 175 SSI_BUSIF0_DALIGN,
176 RSND_REG_SSI_BUSIF5_DALIGN, 176 SSI_BUSIF1_DALIGN,
177 RSND_REG_SSI_BUSIF6_MODE, 177 SSI_BUSIF2_DALIGN,
178 RSND_REG_SSI_BUSIF6_ADINR, 178 SSI_BUSIF3_DALIGN,
179 RSND_REG_SSI_BUSIF6_DALIGN, 179 SSI_BUSIF4_DALIGN,
180 RSND_REG_SSI_BUSIF7_MODE, 180 SSI_BUSIF5_DALIGN,
181 RSND_REG_SSI_BUSIF7_ADINR, 181 SSI_BUSIF6_DALIGN,
182 RSND_REG_SSI_BUSIF7_DALIGN, 182 SSI_BUSIF7_DALIGN,
183 RSND_REG_SSI_INT_ENABLE, 183 SSI_INT_ENABLE,
184 RSND_REG_SSI_SYS_STATUS0, 184 SSI_SYS_STATUS0,
185 RSND_REG_SSI_SYS_STATUS1, 185 SSI_SYS_STATUS1,
186 RSND_REG_SSI_SYS_STATUS2, 186 SSI_SYS_STATUS2,
187 RSND_REG_SSI_SYS_STATUS3, 187 SSI_SYS_STATUS3,
188 RSND_REG_SSI_SYS_STATUS4, 188 SSI_SYS_STATUS4,
189 RSND_REG_SSI_SYS_STATUS5, 189 SSI_SYS_STATUS5,
190 RSND_REG_SSI_SYS_STATUS6, 190 SSI_SYS_STATUS6,
191 RSND_REG_SSI_SYS_STATUS7, 191 SSI_SYS_STATUS7,
192 RSND_REG_HDMI0_SEL, 192 HDMI0_SEL,
193 RSND_REG_HDMI1_SEL, 193 HDMI1_SEL,
194 194
195 /* SSI */ 195 /* SSI */
196 RSND_REG_SSICR, 196 SSICR,
197 RSND_REG_SSISR, 197 SSISR,
198 RSND_REG_SSITDR, 198 SSITDR,
199 RSND_REG_SSIRDR, 199 SSIRDR,
200 RSND_REG_SSIWSR, 200 SSIWSR,
201 201
202 RSND_REG_MAX, 202 REG_MAX,
203}; 203};
204#define SRCIN_TIMSEL(i) (SRCIN_TIMSEL0 + (i))
205#define SRCOUT_TIMSEL(i) (SRCOUT_TIMSEL0 + (i))
206#define CTU_SVxxR(i, j) (CTU_SV00R + (i * 8) + (j))
207#define DVC_VOLxR(i) (DVC_VOL0R + (i))
208#define AUDIO_CLK_SEL(i) (AUDIO_CLK_SEL0 + (i))
209#define SSI_BUSIF_MODE(i) (SSI_BUSIF0_MODE + (i))
210#define SSI_BUSIF_ADINR(i) (SSI_BUSIF0_ADINR + (i))
211#define SSI_BUSIF_DALIGN(i) (SSI_BUSIF0_DALIGN + (i))
212#define SSI_SYS_STATUS(i) (SSI_SYS_STATUS0 + (i))
213
204 214
205struct rsnd_priv; 215struct rsnd_priv;
206struct rsnd_mod; 216struct rsnd_mod;
@@ -210,20 +220,9 @@ struct rsnd_dai_stream;
210/* 220/*
211 * R-Car basic functions 221 * R-Car basic functions
212 */ 222 */
213#define rsnd_mod_read(m, r) \ 223u32 rsnd_mod_read(struct rsnd_mod *mod, enum rsnd_reg reg);
214 rsnd_read(rsnd_mod_to_priv(m), m, RSND_REG_##r) 224void rsnd_mod_write(struct rsnd_mod *mod, enum rsnd_reg reg, u32 data);
215#define rsnd_mod_write(m, r, d) \ 225void rsnd_mod_bset(struct rsnd_mod *mod, enum rsnd_reg reg, u32 mask, u32 data);
216 rsnd_write(rsnd_mod_to_priv(m), m, RSND_REG_##r, d)
217#define rsnd_mod_bset(m, r, s, d) \
218 rsnd_bset(rsnd_mod_to_priv(m), m, RSND_REG_##r, s, d)
219
220u32 rsnd_read(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg);
221void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
222 enum rsnd_reg reg, u32 data);
223void rsnd_force_write(struct rsnd_priv *priv, struct rsnd_mod *mod,
224 enum rsnd_reg reg, u32 data);
225void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg,
226 u32 mask, u32 data);
227u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io); 226u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
228u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io); 227u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io);
229u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod); 228u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod);
@@ -301,6 +300,12 @@ struct rsnd_mod_ops {
301 int (*cleanup)(struct rsnd_mod *mod, 300 int (*cleanup)(struct rsnd_mod *mod,
302 struct rsnd_dai_stream *io, 301 struct rsnd_dai_stream *io,
303 struct rsnd_priv *priv); 302 struct rsnd_priv *priv);
303 u32 *(*get_status)(struct rsnd_mod *mod,
304 struct rsnd_dai_stream *io,
305 enum rsnd_mod_type type);
306 int (*id)(struct rsnd_mod *mod);
307 int (*id_sub)(struct rsnd_mod *mod);
308 int (*id_cmd)(struct rsnd_mod *mod);
304}; 309};
305 310
306struct rsnd_dai_stream; 311struct rsnd_dai_stream;
@@ -310,9 +315,6 @@ struct rsnd_mod {
310 struct rsnd_mod_ops *ops; 315 struct rsnd_mod_ops *ops;
311 struct rsnd_priv *priv; 316 struct rsnd_priv *priv;
312 struct clk *clk; 317 struct clk *clk;
313 u32 *(*get_status)(struct rsnd_dai_stream *io,
314 struct rsnd_mod *mod,
315 enum rsnd_mod_type type);
316 u32 status; 318 u32 status;
317}; 319};
318/* 320/*
@@ -375,8 +377,6 @@ struct rsnd_mod {
375#define __rsnd_mod_call_pointer 0 377#define __rsnd_mod_call_pointer 0
376 378
377#define rsnd_mod_to_priv(mod) ((mod)->priv) 379#define rsnd_mod_to_priv(mod) ((mod)->priv)
378#define rsnd_mod_name(mod) ((mod)->ops->name)
379#define rsnd_mod_id(mod) ((mod)->id)
380#define rsnd_mod_power_on(mod) clk_enable((mod)->clk) 380#define rsnd_mod_power_on(mod) clk_enable((mod)->clk)
381#define rsnd_mod_power_off(mod) clk_disable((mod)->clk) 381#define rsnd_mod_power_off(mod) clk_disable((mod)->clk)
382#define rsnd_mod_get(ip) (&(ip)->mod) 382#define rsnd_mod_get(ip) (&(ip)->mod)
@@ -385,9 +385,6 @@ int rsnd_mod_init(struct rsnd_priv *priv,
385 struct rsnd_mod *mod, 385 struct rsnd_mod *mod,
386 struct rsnd_mod_ops *ops, 386 struct rsnd_mod_ops *ops,
387 struct clk *clk, 387 struct clk *clk,
388 u32* (*get_status)(struct rsnd_dai_stream *io,
389 struct rsnd_mod *mod,
390 enum rsnd_mod_type type),
391 enum rsnd_mod_type type, 388 enum rsnd_mod_type type,
392 int id); 389 int id);
393void rsnd_mod_quit(struct rsnd_mod *mod); 390void rsnd_mod_quit(struct rsnd_mod *mod);
@@ -396,9 +393,13 @@ struct dma_chan *rsnd_mod_dma_req(struct rsnd_dai_stream *io,
396void rsnd_mod_interrupt(struct rsnd_mod *mod, 393void rsnd_mod_interrupt(struct rsnd_mod *mod,
397 void (*callback)(struct rsnd_mod *mod, 394 void (*callback)(struct rsnd_mod *mod,
398 struct rsnd_dai_stream *io)); 395 struct rsnd_dai_stream *io));
399u32 *rsnd_mod_get_status(struct rsnd_dai_stream *io, 396u32 *rsnd_mod_get_status(struct rsnd_mod *mod,
400 struct rsnd_mod *mod, 397 struct rsnd_dai_stream *io,
401 enum rsnd_mod_type type); 398 enum rsnd_mod_type type);
399int rsnd_mod_id(struct rsnd_mod *mod);
400int rsnd_mod_id_raw(struct rsnd_mod *mod);
401int rsnd_mod_id_sub(struct rsnd_mod *mod);
402char *rsnd_mod_name(struct rsnd_mod *mod);
402struct rsnd_mod *rsnd_mod_next(int *iterator, 403struct rsnd_mod *rsnd_mod_next(int *iterator,
403 struct rsnd_dai_stream *io, 404 struct rsnd_dai_stream *io,
404 enum rsnd_mod_type *array, 405 enum rsnd_mod_type *array,
@@ -430,8 +431,9 @@ int rsnd_runtime_channel_after_ctu_with_params(struct rsnd_dai_stream *io,
430 rsnd_runtime_channel_for_ssi_with_params(io, NULL) 431 rsnd_runtime_channel_for_ssi_with_params(io, NULL)
431int rsnd_runtime_channel_for_ssi_with_params(struct rsnd_dai_stream *io, 432int rsnd_runtime_channel_for_ssi_with_params(struct rsnd_dai_stream *io,
432 struct snd_pcm_hw_params *params); 433 struct snd_pcm_hw_params *params);
433int rsnd_runtime_is_ssi_multi(struct rsnd_dai_stream *io); 434int rsnd_runtime_is_multi_ssi(struct rsnd_dai_stream *io);
434int rsnd_runtime_is_ssi_tdm(struct rsnd_dai_stream *io); 435int rsnd_runtime_is_tdm(struct rsnd_dai_stream *io);
436int rsnd_runtime_is_tdm_split(struct rsnd_dai_stream *io);
435 437
436/* 438/*
437 * DT 439 * DT
@@ -440,6 +442,7 @@ int rsnd_runtime_is_ssi_tdm(struct rsnd_dai_stream *io);
440 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, node) 442 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, node)
441#define RSND_NODE_DAI "rcar_sound,dai" 443#define RSND_NODE_DAI "rcar_sound,dai"
442#define RSND_NODE_SSI "rcar_sound,ssi" 444#define RSND_NODE_SSI "rcar_sound,ssi"
445#define RSND_NODE_SSIU "rcar_sound,ssiu"
443#define RSND_NODE_SRC "rcar_sound,src" 446#define RSND_NODE_SRC "rcar_sound,src"
444#define RSND_NODE_CTU "rcar_sound,ctu" 447#define RSND_NODE_CTU "rcar_sound,ctu"
445#define RSND_NODE_MIX "rcar_sound,mix" 448#define RSND_NODE_MIX "rcar_sound,mix"
@@ -456,8 +459,17 @@ struct rsnd_dai_stream {
456 struct rsnd_mod *dma; 459 struct rsnd_mod *dma;
457 struct rsnd_dai *rdai; 460 struct rsnd_dai *rdai;
458 struct device *dmac_dev; /* for IPMMU */ 461 struct device *dmac_dev; /* for IPMMU */
462 u32 converted_rate; /* converted sampling rate */
463 int converted_chan; /* converted channels */
459 u32 parent_ssi_status; 464 u32 parent_ssi_status;
465 u32 flags;
460}; 466};
467
468/* flags */
469#define RSND_STREAM_HDMI0 (1 << 0) /* for HDMI0 */
470#define RSND_STREAM_HDMI1 (1 << 1) /* for HDMI1 */
471#define RSND_STREAM_TDM_SPLIT (1 << 2) /* for TDM split mode */
472
461#define rsnd_io_to_mod(io, i) ((i) < RSND_MOD_MAX ? (io)->mod[(i)] : NULL) 473#define rsnd_io_to_mod(io, i) ((i) < RSND_MOD_MAX ? (io)->mod[(i)] : NULL)
462#define rsnd_io_to_mod_ssi(io) rsnd_io_to_mod((io), RSND_MOD_SSI) 474#define rsnd_io_to_mod_ssi(io) rsnd_io_to_mod((io), RSND_MOD_SSI)
463#define rsnd_io_to_mod_ssiu(io) rsnd_io_to_mod((io), RSND_MOD_SSIU) 475#define rsnd_io_to_mod_ssiu(io) rsnd_io_to_mod((io), RSND_MOD_SSIU)
@@ -472,6 +484,8 @@ struct rsnd_dai_stream {
472#define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io) 484#define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io)
473#define rsnd_io_to_runtime(io) ((io)->substream ? \ 485#define rsnd_io_to_runtime(io) ((io)->substream ? \
474 (io)->substream->runtime : NULL) 486 (io)->substream->runtime : NULL)
487#define rsnd_io_converted_rate(io) ((io)->converted_rate)
488#define rsnd_io_converted_chan(io) ((io)->converted_chan)
475int rsnd_io_is_working(struct rsnd_dai_stream *io); 489int rsnd_io_is_working(struct rsnd_dai_stream *io);
476 490
477struct rsnd_dai { 491struct rsnd_dai {
@@ -712,18 +726,9 @@ extern const char * const volume_ramp_rate[];
712int rsnd_ssi_probe(struct rsnd_priv *priv); 726int rsnd_ssi_probe(struct rsnd_priv *priv);
713void rsnd_ssi_remove(struct rsnd_priv *priv); 727void rsnd_ssi_remove(struct rsnd_priv *priv);
714struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); 728struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
715int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);
716int rsnd_ssi_use_busif(struct rsnd_dai_stream *io); 729int rsnd_ssi_use_busif(struct rsnd_dai_stream *io);
717int rsnd_ssi_get_busif(struct rsnd_dai_stream *io);
718u32 rsnd_ssi_multi_slaves_runtime(struct rsnd_dai_stream *io); 730u32 rsnd_ssi_multi_slaves_runtime(struct rsnd_dai_stream *io);
719 731
720#define RSND_SSI_HDMI_PORT0 0xf0
721#define RSND_SSI_HDMI_PORT1 0xf1
722int rsnd_ssi_hdmi_port(struct rsnd_dai_stream *io);
723void rsnd_ssi_parse_hdmi_connection(struct rsnd_priv *priv,
724 struct device_node *endpoint,
725 int dai_i);
726
727#define rsnd_ssi_is_pin_sharing(io) \ 732#define rsnd_ssi_is_pin_sharing(io) \
728 __rsnd_ssi_is_pin_sharing(rsnd_io_to_mod_ssi(io)) 733 __rsnd_ssi_is_pin_sharing(rsnd_io_to_mod_ssi(io))
729int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); 734int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
@@ -742,6 +747,10 @@ int rsnd_ssiu_attach(struct rsnd_dai_stream *io,
742 struct rsnd_mod *mod); 747 struct rsnd_mod *mod);
743int rsnd_ssiu_probe(struct rsnd_priv *priv); 748int rsnd_ssiu_probe(struct rsnd_priv *priv);
744void rsnd_ssiu_remove(struct rsnd_priv *priv); 749void rsnd_ssiu_remove(struct rsnd_priv *priv);
750void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai,
751 struct device_node *playback,
752 struct device_node *capture);
753#define rsnd_ssiu_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_SSIU)
745 754
746/* 755/*
747 * R-Car SRC 756 * R-Car SRC
@@ -767,7 +776,6 @@ unsigned int rsnd_src_get_rate(struct rsnd_priv *priv,
767 */ 776 */
768int rsnd_ctu_probe(struct rsnd_priv *priv); 777int rsnd_ctu_probe(struct rsnd_priv *priv);
769void rsnd_ctu_remove(struct rsnd_priv *priv); 778void rsnd_ctu_remove(struct rsnd_priv *priv);
770int rsnd_ctu_converted_channel(struct rsnd_mod *mod);
771struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id); 779struct rsnd_mod *rsnd_ctu_mod_get(struct rsnd_priv *priv, int id);
772#define rsnd_ctu_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_CTU) 780#define rsnd_ctu_of_node(priv) rsnd_parse_of_node(priv, RSND_NODE_CTU)
773#define rsnd_parse_connect_ctu(rdai, playback, capture) \ 781#define rsnd_parse_connect_ctu(rdai, playback, capture) \
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index cd38a43b976f..50348a2c9203 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -25,7 +25,6 @@ struct rsnd_src {
25 struct rsnd_mod *dma; 25 struct rsnd_mod *dma;
26 struct rsnd_kctrl_cfg_s sen; /* sync convert enable */ 26 struct rsnd_kctrl_cfg_s sen; /* sync convert enable */
27 struct rsnd_kctrl_cfg_s sync; /* sync convert */ 27 struct rsnd_kctrl_cfg_s sync; /* sync convert */
28 u32 convert_rate; /* sampling rate convert */
29 int irq; 28 int irq;
30}; 29};
31 30
@@ -89,12 +88,12 @@ static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io,
89 return 0; 88 return 0;
90 89
91 if (!rsnd_src_sync_is_enabled(mod)) 90 if (!rsnd_src_sync_is_enabled(mod))
92 return src->convert_rate; 91 return rsnd_io_converted_rate(io);
93 92
94 convert_rate = src->sync.val; 93 convert_rate = src->sync.val;
95 94
96 if (!convert_rate) 95 if (!convert_rate)
97 convert_rate = src->convert_rate; 96 convert_rate = rsnd_io_converted_rate(io);
98 97
99 if (!convert_rate) 98 if (!convert_rate)
100 convert_rate = runtime->rate; 99 convert_rate = runtime->rate;
@@ -135,40 +134,6 @@ unsigned int rsnd_src_get_rate(struct rsnd_priv *priv,
135 return rate; 134 return rate;
136} 135}
137 136
138static int rsnd_src_hw_params(struct rsnd_mod *mod,
139 struct rsnd_dai_stream *io,
140 struct snd_pcm_substream *substream,
141 struct snd_pcm_hw_params *fe_params)
142{
143 struct rsnd_src *src = rsnd_mod_to_src(mod);
144 struct snd_soc_pcm_runtime *fe = substream->private_data;
145
146 /*
147 * SRC assumes that it is used under DPCM if user want to use
148 * sampling rate convert. Then, SRC should be FE.
149 * And then, this function will be called *after* BE settings.
150 * this means, each BE already has fixuped hw_params.
151 * see
152 * dpcm_fe_dai_hw_params()
153 * dpcm_be_dai_hw_params()
154 */
155 src->convert_rate = 0;
156 if (fe->dai_link->dynamic) {
157 int stream = substream->stream;
158 struct snd_soc_dpcm *dpcm;
159 struct snd_pcm_hw_params *be_params;
160
161 for_each_dpcm_be(fe, stream, dpcm) {
162 be_params = &dpcm->hw_params;
163
164 if (params_rate(fe_params) != params_rate(be_params))
165 src->convert_rate = params_rate(be_params);
166 }
167 }
168
169 return 0;
170}
171
172static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, 137static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
173 struct rsnd_mod *mod) 138 struct rsnd_mod *mod)
174{ 139{
@@ -349,9 +314,8 @@ static bool rsnd_src_error_occurred(struct rsnd_mod *mod)
349 status0 = rsnd_mod_read(mod, SCU_SYS_STATUS0); 314 status0 = rsnd_mod_read(mod, SCU_SYS_STATUS0);
350 status1 = rsnd_mod_read(mod, SCU_SYS_STATUS1); 315 status1 = rsnd_mod_read(mod, SCU_SYS_STATUS1);
351 if ((status0 & val0) || (status1 & val1)) { 316 if ((status0 & val0) || (status1 & val1)) {
352 rsnd_dbg_irq_status(dev, "%s[%d] err status : 0x%08x, 0x%08x\n", 317 rsnd_dbg_irq_status(dev, "%s err status : 0x%08x, 0x%08x\n",
353 rsnd_mod_name(mod), rsnd_mod_id(mod), 318 rsnd_mod_name(mod), status0, status1);
354 status0, status1);
355 319
356 ret = true; 320 ret = true;
357 } 321 }
@@ -527,16 +491,16 @@ static int rsnd_src_pcm_new(struct rsnd_mod *mod,
527} 491}
528 492
529static struct rsnd_mod_ops rsnd_src_ops = { 493static struct rsnd_mod_ops rsnd_src_ops = {
530 .name = SRC_NAME, 494 .name = SRC_NAME,
531 .dma_req = rsnd_src_dma_req, 495 .dma_req = rsnd_src_dma_req,
532 .probe = rsnd_src_probe_, 496 .probe = rsnd_src_probe_,
533 .init = rsnd_src_init, 497 .init = rsnd_src_init,
534 .quit = rsnd_src_quit, 498 .quit = rsnd_src_quit,
535 .start = rsnd_src_start, 499 .start = rsnd_src_start,
536 .stop = rsnd_src_stop, 500 .stop = rsnd_src_stop,
537 .irq = rsnd_src_irq, 501 .irq = rsnd_src_irq,
538 .hw_params = rsnd_src_hw_params, 502 .pcm_new = rsnd_src_pcm_new,
539 .pcm_new = rsnd_src_pcm_new, 503 .get_status = rsnd_mod_get_status,
540}; 504};
541 505
542struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) 506struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
@@ -605,8 +569,7 @@ int rsnd_src_probe(struct rsnd_priv *priv)
605 } 569 }
606 570
607 ret = rsnd_mod_init(priv, rsnd_mod_get(src), 571 ret = rsnd_mod_init(priv, rsnd_mod_get(src),
608 &rsnd_src_ops, clk, rsnd_mod_get_status, 572 &rsnd_src_ops, clk, RSND_MOD_SRC, i);
609 RSND_MOD_SRC, i);
610 if (ret) { 573 if (ret) {
611 of_node_put(np); 574 of_node_put(np);
612 goto rsnd_src_probe_done; 575 goto rsnd_src_probe_done;
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 6ec78f3096dd..45ef295743ec 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -99,9 +99,7 @@ struct rsnd_ssi {
99/* flags */ 99/* flags */
100#define RSND_SSI_CLK_PIN_SHARE (1 << 0) 100#define RSND_SSI_CLK_PIN_SHARE (1 << 0)
101#define RSND_SSI_NO_BUSIF (1 << 1) /* SSI+DMA without BUSIF */ 101#define RSND_SSI_NO_BUSIF (1 << 1) /* SSI+DMA without BUSIF */
102#define RSND_SSI_HDMI0 (1 << 2) /* for HDMI0 */ 102#define RSND_SSI_PROBED (1 << 2)
103#define RSND_SSI_HDMI1 (1 << 3) /* for HDMI1 */
104#define RSND_SSI_PROBED (1 << 4)
105 103
106#define for_each_rsnd_ssi(pos, priv, i) \ 104#define for_each_rsnd_ssi(pos, priv, i) \
107 for (i = 0; \ 105 for (i = 0; \
@@ -119,19 +117,7 @@ struct rsnd_ssi {
119 (rsnd_ssi_run_mods(io) & (1 << rsnd_mod_id(mod))) 117 (rsnd_ssi_run_mods(io) & (1 << rsnd_mod_id(mod)))
120#define rsnd_ssi_can_output_clk(mod) (!__rsnd_ssi_is_pin_sharing(mod)) 118#define rsnd_ssi_can_output_clk(mod) (!__rsnd_ssi_is_pin_sharing(mod))
121 119
122int rsnd_ssi_hdmi_port(struct rsnd_dai_stream *io) 120static int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);
123{
124 struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);
125 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
126
127 if (rsnd_flags_has(ssi, RSND_SSI_HDMI0))
128 return RSND_SSI_HDMI_PORT0;
129
130 if (rsnd_flags_has(ssi, RSND_SSI_HDMI1))
131 return RSND_SSI_HDMI_PORT1;
132
133 return 0;
134}
135 121
136int rsnd_ssi_use_busif(struct rsnd_dai_stream *io) 122int rsnd_ssi_use_busif(struct rsnd_dai_stream *io)
137{ 123{
@@ -150,11 +136,6 @@ int rsnd_ssi_use_busif(struct rsnd_dai_stream *io)
150 return use_busif; 136 return use_busif;
151} 137}
152 138
153int rsnd_ssi_get_busif(struct rsnd_dai_stream *io)
154{
155 return 0; /* BUSIF0 only for now */
156}
157
158static void rsnd_ssi_status_clear(struct rsnd_mod *mod) 139static void rsnd_ssi_status_clear(struct rsnd_mod *mod)
159{ 140{
160 rsnd_mod_write(mod, SSISR, 0); 141 rsnd_mod_write(mod, SSISR, 0);
@@ -181,8 +162,7 @@ static void rsnd_ssi_status_check(struct rsnd_mod *mod,
181 udelay(5); 162 udelay(5);
182 } 163 }
183 164
184 dev_warn(dev, "%s[%d] status check failed\n", 165 dev_warn(dev, "%s status check failed\n", rsnd_mod_name(mod));
185 rsnd_mod_name(mod), rsnd_mod_id(mod));
186} 166}
187 167
188static u32 rsnd_ssi_multi_slaves(struct rsnd_dai_stream *io) 168static u32 rsnd_ssi_multi_slaves(struct rsnd_dai_stream *io)
@@ -224,7 +204,7 @@ static u32 rsnd_ssi_run_mods(struct rsnd_dai_stream *io)
224 204
225u32 rsnd_ssi_multi_slaves_runtime(struct rsnd_dai_stream *io) 205u32 rsnd_ssi_multi_slaves_runtime(struct rsnd_dai_stream *io)
226{ 206{
227 if (rsnd_runtime_is_ssi_multi(io)) 207 if (rsnd_runtime_is_multi_ssi(io))
228 return rsnd_ssi_multi_slaves(io); 208 return rsnd_ssi_multi_slaves(io);
229 209
230 return 0; 210 return 0;
@@ -320,6 +300,9 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
320 return 0; 300 return 0;
321 } 301 }
322 302
303 if (rsnd_runtime_is_tdm_split(io))
304 chan = rsnd_io_converted_chan(io);
305
323 main_rate = rsnd_ssi_clk_query(rdai, rate, chan, &idx); 306 main_rate = rsnd_ssi_clk_query(rdai, rate, chan, &idx);
324 if (!main_rate) { 307 if (!main_rate) {
325 dev_err(dev, "unsupported clock rate\n"); 308 dev_err(dev, "unsupported clock rate\n");
@@ -346,9 +329,8 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod,
346 ssi->rate = rate; 329 ssi->rate = rate;
347 ssi->chan = chan; 330 ssi->chan = chan;
348 331
349 dev_dbg(dev, "%s[%d] outputs %u Hz\n", 332 dev_dbg(dev, "%s outputs %d chan %u Hz\n",
350 rsnd_mod_name(mod), 333 rsnd_mod_name(mod), chan, rate);
351 rsnd_mod_id(mod), rate);
352 334
353 return 0; 335 return 0;
354} 336}
@@ -379,14 +361,23 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
379 struct rsnd_dai_stream *io) 361 struct rsnd_dai_stream *io)
380{ 362{
381 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 363 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
364 struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
365 struct device *dev = rsnd_priv_to_dev(priv);
382 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 366 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
383 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 367 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
384 u32 cr_own = ssi->cr_own; 368 u32 cr_own = ssi->cr_own;
385 u32 cr_mode = ssi->cr_mode; 369 u32 cr_mode = ssi->cr_mode;
386 u32 wsr = ssi->wsr; 370 u32 wsr = ssi->wsr;
387 int is_tdm; 371 int width;
372 int is_tdm, is_tdm_split;
373
374 is_tdm = rsnd_runtime_is_tdm(io);
375 is_tdm_split = rsnd_runtime_is_tdm_split(io);
388 376
389 is_tdm = rsnd_runtime_is_ssi_tdm(io); 377 if (is_tdm)
378 dev_dbg(dev, "TDM mode\n");
379 if (is_tdm_split)
380 dev_dbg(dev, "TDM Split mode\n");
390 381
391 cr_own |= FORCE | rsnd_rdai_width_to_swl(rdai); 382 cr_own |= FORCE | rsnd_rdai_width_to_swl(rdai);
392 383
@@ -405,7 +396,7 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
405 * rsnd_ssiu_init_gen2() 396 * rsnd_ssiu_init_gen2()
406 */ 397 */
407 wsr = ssi->wsr; 398 wsr = ssi->wsr;
408 if (is_tdm) { 399 if (is_tdm || is_tdm_split) {
409 wsr |= WS_MODE; 400 wsr |= WS_MODE;
410 cr_own |= CHNL_8; 401 cr_own |= CHNL_8;
411 } 402 }
@@ -421,7 +412,18 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
421 cr_own |= TRMD; 412 cr_own |= TRMD;
422 413
423 cr_own &= ~DWL_MASK; 414 cr_own &= ~DWL_MASK;
424 switch (snd_pcm_format_width(runtime->format)) { 415 width = snd_pcm_format_width(runtime->format);
416 if (is_tdm_split) {
417 /*
418 * The SWL and DWL bits in SSICR should be fixed at 32-bit
419 * setting when TDM split mode.
420 * see datasheet
421 * Operation :: TDM Format Split Function (TDM Split Mode)
422 */
423 width = 32;
424 }
425
426 switch (width) {
425 case 8: 427 case 8:
426 cr_own |= DWL_8; 428 cr_own |= DWL_8;
427 break; 429 break;
@@ -431,6 +433,9 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
431 case 24: 433 case 24:
432 cr_own |= DWL_24; 434 cr_own |= DWL_24;
433 break; 435 break;
436 case 32:
437 cr_own |= DWL_32;
438 break;
434 } 439 }
435 440
436 if (rsnd_ssi_is_dma_mode(mod)) { 441 if (rsnd_ssi_is_dma_mode(mod)) {
@@ -494,8 +499,7 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
494 return 0; 499 return 0;
495 500
496 if (!ssi->usrcnt) { 501 if (!ssi->usrcnt) {
497 dev_err(dev, "%s[%d] usrcnt error\n", 502 dev_err(dev, "%s usrcnt error\n", rsnd_mod_name(mod));
498 rsnd_mod_name(mod), rsnd_mod_id(mod));
499 return -EIO; 503 return -EIO;
500 } 504 }
501 505
@@ -654,8 +658,8 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
654 658
655 /* DMA only */ 659 /* DMA only */
656 if (is_dma && (status & (UIRQ | OIRQ))) { 660 if (is_dma && (status & (UIRQ | OIRQ))) {
657 rsnd_dbg_irq_status(dev, "%s[%d] err status : 0x%08x\n", 661 rsnd_dbg_irq_status(dev, "%s err status : 0x%08x\n",
658 rsnd_mod_name(mod), rsnd_mod_id(mod), status); 662 rsnd_mod_name(mod), status);
659 663
660 stop = true; 664 stop = true;
661 } 665 }
@@ -681,6 +685,41 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
681 return IRQ_HANDLED; 685 return IRQ_HANDLED;
682} 686}
683 687
688static u32 *rsnd_ssi_get_status(struct rsnd_mod *mod,
689 struct rsnd_dai_stream *io,
690 enum rsnd_mod_type type)
691{
692 /*
693 * SSIP (= SSI parent) needs to be special, otherwise,
694 * 2nd SSI might doesn't start. see also rsnd_mod_call()
695 *
696 * We can't include parent SSI status on SSI, because we don't know
697 * how many SSI requests parent SSI. Thus, it is localed on "io" now.
698 * ex) trouble case
699 * Playback: SSI0
700 * Capture : SSI1 (needs SSI0)
701 *
702 * 1) start Capture -> SSI0/SSI1 are started.
703 * 2) start Playback -> SSI0 doesn't work, because it is already
704 * marked as "started" on 1)
705 *
706 * OTOH, using each mod's status is good for MUX case.
707 * It doesn't need to start in 2nd start
708 * ex)
709 * IO-0: SRC0 -> CTU1 -+-> MUX -> DVC -> SSIU -> SSI0
710 * |
711 * IO-1: SRC1 -> CTU2 -+
712 *
713 * 1) start IO-0 -> start SSI0
714 * 2) start IO-1 -> SSI0 doesn't need to start, because it is
715 * already started on 1)
716 */
717 if (type == RSND_MOD_SSIP)
718 return &io->parent_ssi_status;
719
720 return rsnd_mod_get_status(mod, io, type);
721}
722
684/* 723/*
685 * SSI PIO 724 * SSI PIO
686 */ 725 */
@@ -730,7 +769,7 @@ static int rsnd_ssi_common_probe(struct rsnd_mod *mod,
730{ 769{
731 struct device *dev = rsnd_priv_to_dev(priv); 770 struct device *dev = rsnd_priv_to_dev(priv);
732 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 771 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
733 int ret; 772 int ret = 0;
734 773
735 /* 774 /*
736 * SSIP/SSIU/IRQ are not needed on 775 * SSIP/SSIU/IRQ are not needed on
@@ -744,10 +783,6 @@ static int rsnd_ssi_common_probe(struct rsnd_mod *mod,
744 * see rsnd_ssi_pcm_new() 783 * see rsnd_ssi_pcm_new()
745 */ 784 */
746 785
747 ret = rsnd_ssiu_attach(io, mod);
748 if (ret < 0)
749 return ret;
750
751 /* 786 /*
752 * SSI might be called again as PIO fallback 787 * SSI might be called again as PIO fallback
753 * It is easy to manual handling for IRQ request/free 788 * It is easy to manual handling for IRQ request/free
@@ -876,18 +911,19 @@ static int rsnd_ssi_prepare(struct rsnd_mod *mod,
876} 911}
877 912
878static struct rsnd_mod_ops rsnd_ssi_pio_ops = { 913static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
879 .name = SSI_NAME, 914 .name = SSI_NAME,
880 .probe = rsnd_ssi_common_probe, 915 .probe = rsnd_ssi_common_probe,
881 .remove = rsnd_ssi_common_remove, 916 .remove = rsnd_ssi_common_remove,
882 .init = rsnd_ssi_pio_init, 917 .init = rsnd_ssi_pio_init,
883 .quit = rsnd_ssi_quit, 918 .quit = rsnd_ssi_quit,
884 .start = rsnd_ssi_start, 919 .start = rsnd_ssi_start,
885 .stop = rsnd_ssi_stop, 920 .stop = rsnd_ssi_stop,
886 .irq = rsnd_ssi_irq, 921 .irq = rsnd_ssi_irq,
887 .pointer = rsnd_ssi_pio_pointer, 922 .pointer = rsnd_ssi_pio_pointer,
888 .pcm_new = rsnd_ssi_pcm_new, 923 .pcm_new = rsnd_ssi_pcm_new,
889 .hw_params = rsnd_ssi_hw_params, 924 .hw_params = rsnd_ssi_hw_params,
890 .prepare = rsnd_ssi_prepare, 925 .prepare = rsnd_ssi_prepare,
926 .get_status = rsnd_ssi_get_status,
891}; 927};
892 928
893static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, 929static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
@@ -928,8 +964,7 @@ static int rsnd_ssi_fallback(struct rsnd_mod *mod,
928 */ 964 */
929 mod->ops = &rsnd_ssi_pio_ops; 965 mod->ops = &rsnd_ssi_pio_ops;
930 966
931 dev_info(dev, "%s[%d] fallback to PIO mode\n", 967 dev_info(dev, "%s fallback to PIO mode\n", rsnd_mod_name(mod));
932 rsnd_mod_name(mod), rsnd_mod_id(mod));
933 968
934 return 0; 969 return 0;
935} 970}
@@ -941,6 +976,17 @@ static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_dai_stream *io,
941 int is_play = rsnd_io_is_play(io); 976 int is_play = rsnd_io_is_play(io);
942 char *name; 977 char *name;
943 978
979 /*
980 * It should use "rcar_sound,ssiu" on DT.
981 * But, we need to keep compatibility for old version.
982 *
983 * If it has "rcar_sound.ssiu", it will be used.
984 * If not, "rcar_sound.ssi" will be used.
985 * see
986 * rsnd_ssiu_dma_req()
987 * rsnd_dma_of_path()
988 */
989
944 if (rsnd_ssi_use_busif(io)) 990 if (rsnd_ssi_use_busif(io))
945 name = is_play ? "rxu" : "txu"; 991 name = is_play ? "rxu" : "txu";
946 else 992 else
@@ -951,27 +997,27 @@ static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_dai_stream *io,
951} 997}
952 998
953static struct rsnd_mod_ops rsnd_ssi_dma_ops = { 999static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
954 .name = SSI_NAME, 1000 .name = SSI_NAME,
955 .dma_req = rsnd_ssi_dma_req, 1001 .dma_req = rsnd_ssi_dma_req,
956 .probe = rsnd_ssi_dma_probe, 1002 .probe = rsnd_ssi_dma_probe,
957 .remove = rsnd_ssi_common_remove, 1003 .remove = rsnd_ssi_common_remove,
958 .init = rsnd_ssi_init, 1004 .init = rsnd_ssi_init,
959 .quit = rsnd_ssi_quit, 1005 .quit = rsnd_ssi_quit,
960 .start = rsnd_ssi_start, 1006 .start = rsnd_ssi_start,
961 .stop = rsnd_ssi_stop, 1007 .stop = rsnd_ssi_stop,
962 .irq = rsnd_ssi_irq, 1008 .irq = rsnd_ssi_irq,
963 .pcm_new = rsnd_ssi_pcm_new, 1009 .pcm_new = rsnd_ssi_pcm_new,
964 .fallback = rsnd_ssi_fallback, 1010 .fallback = rsnd_ssi_fallback,
965 .hw_params = rsnd_ssi_hw_params, 1011 .hw_params = rsnd_ssi_hw_params,
966 .prepare = rsnd_ssi_prepare, 1012 .prepare = rsnd_ssi_prepare,
1013 .get_status = rsnd_ssi_get_status,
967}; 1014};
968 1015
969int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod) 1016static int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod)
970{ 1017{
971 return mod->ops == &rsnd_ssi_dma_ops; 1018 return mod->ops == &rsnd_ssi_dma_ops;
972} 1019}
973 1020
974
975/* 1021/*
976 * ssi mod function 1022 * ssi mod function
977 */ 1023 */
@@ -1027,54 +1073,6 @@ void rsnd_parse_connect_ssi(struct rsnd_dai *rdai,
1027 of_node_put(node); 1073 of_node_put(node);
1028} 1074}
1029 1075
1030static void __rsnd_ssi_parse_hdmi_connection(struct rsnd_priv *priv,
1031 struct rsnd_dai_stream *io,
1032 struct device_node *remote_ep)
1033{
1034 struct device *dev = rsnd_priv_to_dev(priv);
1035 struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io);
1036 struct rsnd_ssi *ssi;
1037 struct device_node *remote_node = of_graph_get_port_parent(remote_ep);
1038
1039 /* support Gen3 only */
1040 if (!rsnd_is_gen3(priv))
1041 return;
1042
1043 if (!mod)
1044 return;
1045
1046 ssi = rsnd_mod_to_ssi(mod);
1047
1048 /* HDMI0 */
1049 if (strstr(remote_node->full_name, "hdmi@fead0000")) {
1050 rsnd_flags_set(ssi, RSND_SSI_HDMI0);
1051 dev_dbg(dev, "%s[%d] connected to HDMI0\n",
1052 rsnd_mod_name(mod), rsnd_mod_id(mod));
1053 }
1054
1055 /* HDMI1 */
1056 if (strstr(remote_node->full_name, "hdmi@feae0000")) {
1057 rsnd_flags_set(ssi, RSND_SSI_HDMI1);
1058 dev_dbg(dev, "%s[%d] connected to HDMI1\n",
1059 rsnd_mod_name(mod), rsnd_mod_id(mod));
1060 }
1061}
1062
1063void rsnd_ssi_parse_hdmi_connection(struct rsnd_priv *priv,
1064 struct device_node *endpoint,
1065 int dai_i)
1066{
1067 struct rsnd_dai *rdai = rsnd_rdai_get(priv, dai_i);
1068 struct device_node *remote_ep;
1069
1070 remote_ep = of_graph_get_remote_endpoint(endpoint);
1071 if (!remote_ep)
1072 return;
1073
1074 __rsnd_ssi_parse_hdmi_connection(priv, &rdai->playback, remote_ep);
1075 __rsnd_ssi_parse_hdmi_connection(priv, &rdai->capture, remote_ep);
1076}
1077
1078struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id) 1076struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id)
1079{ 1077{
1080 if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv))) 1078 if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv)))
@@ -1091,41 +1089,6 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod)
1091 return !!(rsnd_flags_has(rsnd_mod_to_ssi(mod), RSND_SSI_CLK_PIN_SHARE)); 1089 return !!(rsnd_flags_has(rsnd_mod_to_ssi(mod), RSND_SSI_CLK_PIN_SHARE));
1092} 1090}
1093 1091
1094static u32 *rsnd_ssi_get_status(struct rsnd_dai_stream *io,
1095 struct rsnd_mod *mod,
1096 enum rsnd_mod_type type)
1097{
1098 /*
1099 * SSIP (= SSI parent) needs to be special, otherwise,
1100 * 2nd SSI might doesn't start. see also rsnd_mod_call()
1101 *
1102 * We can't include parent SSI status on SSI, because we don't know
1103 * how many SSI requests parent SSI. Thus, it is localed on "io" now.
1104 * ex) trouble case
1105 * Playback: SSI0
1106 * Capture : SSI1 (needs SSI0)
1107 *
1108 * 1) start Capture -> SSI0/SSI1 are started.
1109 * 2) start Playback -> SSI0 doesn't work, because it is already
1110 * marked as "started" on 1)
1111 *
1112 * OTOH, using each mod's status is good for MUX case.
1113 * It doesn't need to start in 2nd start
1114 * ex)
1115 * IO-0: SRC0 -> CTU1 -+-> MUX -> DVC -> SSIU -> SSI0
1116 * |
1117 * IO-1: SRC1 -> CTU2 -+
1118 *
1119 * 1) start IO-0 -> start SSI0
1120 * 2) start IO-1 -> SSI0 doesn't need to start, because it is
1121 * already started on 1)
1122 */
1123 if (type == RSND_MOD_SSIP)
1124 return &io->parent_ssi_status;
1125
1126 return rsnd_mod_get_status(io, mod, type);
1127}
1128
1129int rsnd_ssi_probe(struct rsnd_priv *priv) 1092int rsnd_ssi_probe(struct rsnd_priv *priv)
1130{ 1093{
1131 struct device_node *node; 1094 struct device_node *node;
@@ -1192,7 +1155,7 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
1192 ops = &rsnd_ssi_dma_ops; 1155 ops = &rsnd_ssi_dma_ops;
1193 1156
1194 ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk, 1157 ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk,
1195 rsnd_ssi_get_status, RSND_MOD_SSI, i); 1158 RSND_MOD_SSI, i);
1196 if (ret) { 1159 if (ret) {
1197 of_node_put(np); 1160 of_node_put(np);
1198 goto rsnd_ssi_probe_done; 1161 goto rsnd_ssi_probe_done;
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c
index 39b67643b5dc..c5934adcfd01 100644
--- a/sound/soc/sh/rcar/ssiu.c
+++ b/sound/soc/sh/rcar/ssiu.c
@@ -12,8 +12,14 @@ struct rsnd_ssiu {
12 struct rsnd_mod mod; 12 struct rsnd_mod mod;
13 u32 busif_status[8]; /* for BUSIF0 - BUSIF7 */ 13 u32 busif_status[8]; /* for BUSIF0 - BUSIF7 */
14 unsigned int usrcnt; 14 unsigned int usrcnt;
15 int id;
16 int id_sub;
15}; 17};
16 18
19/* SSI_MODE */
20#define TDM_EXT (1 << 0)
21#define TDM_SPLIT (1 << 8)
22
17#define rsnd_ssiu_nr(priv) ((priv)->ssiu_nr) 23#define rsnd_ssiu_nr(priv) ((priv)->ssiu_nr)
18#define rsnd_mod_to_ssiu(_mod) container_of((_mod), struct rsnd_ssiu, mod) 24#define rsnd_mod_to_ssiu(_mod) container_of((_mod), struct rsnd_ssiu, mod)
19#define for_each_rsnd_ssiu(pos, priv, i) \ 25#define for_each_rsnd_ssiu(pos, priv, i) \
@@ -22,6 +28,33 @@ struct rsnd_ssiu {
22 ((pos) = ((struct rsnd_ssiu *)(priv)->ssiu + i)); \ 28 ((pos) = ((struct rsnd_ssiu *)(priv)->ssiu + i)); \
23 i++) 29 i++)
24 30
31/*
32 * SSI Gen2 Gen3
33 * 0 BUSIF0-3 BUSIF0-7
34 * 1 BUSIF0-3 BUSIF0-7
35 * 2 BUSIF0-3 BUSIF0-7
36 * 3 BUSIF0 BUSIF0-7
37 * 4 BUSIF0 BUSIF0-7
38 * 5 BUSIF0 BUSIF0
39 * 6 BUSIF0 BUSIF0
40 * 7 BUSIF0 BUSIF0
41 * 8 BUSIF0 BUSIF0
42 * 9 BUSIF0-3 BUSIF0-7
43 * total 22 52
44 */
45static const int gen2_id[] = { 0, 4, 8, 12, 13, 14, 15, 16, 17, 18 };
46static const int gen3_id[] = { 0, 8, 16, 24, 32, 40, 41, 42, 43, 44 };
47
48static u32 *rsnd_ssiu_get_status(struct rsnd_mod *mod,
49 struct rsnd_dai_stream *io,
50 enum rsnd_mod_type type)
51{
52 struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
53 int busif = rsnd_mod_id_sub(mod);
54
55 return &ssiu->busif_status[busif];
56}
57
25static int rsnd_ssiu_init(struct rsnd_mod *mod, 58static int rsnd_ssiu_init(struct rsnd_mod *mod,
26 struct rsnd_dai_stream *io, 59 struct rsnd_dai_stream *io,
27 struct rsnd_priv *priv) 60 struct rsnd_priv *priv)
@@ -32,6 +65,7 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod,
32 int id = rsnd_mod_id(mod); 65 int id = rsnd_mod_id(mod);
33 u32 mask1, val1; 66 u32 mask1, val1;
34 u32 mask2, val2; 67 u32 mask2, val2;
68 int i;
35 69
36 /* clear status */ 70 /* clear status */
37 switch (id) { 71 switch (id) {
@@ -40,16 +74,12 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod,
40 case 2: 74 case 2:
41 case 3: 75 case 3:
42 case 4: 76 case 4:
43 rsnd_mod_write(mod, SSI_SYS_STATUS0, 0xf << (id * 4)); 77 for (i = 0; i < 4; i++)
44 rsnd_mod_write(mod, SSI_SYS_STATUS2, 0xf << (id * 4)); 78 rsnd_mod_write(mod, SSI_SYS_STATUS(i * 2), 0xf << (id * 4));
45 rsnd_mod_write(mod, SSI_SYS_STATUS4, 0xf << (id * 4));
46 rsnd_mod_write(mod, SSI_SYS_STATUS6, 0xf << (id * 4));
47 break; 79 break;
48 case 9: 80 case 9:
49 rsnd_mod_write(mod, SSI_SYS_STATUS1, 0xf << 4); 81 for (i = 0; i < 4; i++)
50 rsnd_mod_write(mod, SSI_SYS_STATUS3, 0xf << 4); 82 rsnd_mod_write(mod, SSI_SYS_STATUS((i * 2) + 1), 0xf << (id * 4));
51 rsnd_mod_write(mod, SSI_SYS_STATUS5, 0xf << 4);
52 rsnd_mod_write(mod, SSI_SYS_STATUS7, 0xf << 4);
53 break; 83 break;
54 } 84 }
55 85
@@ -115,8 +145,9 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod,
115} 145}
116 146
117static struct rsnd_mod_ops rsnd_ssiu_ops_gen1 = { 147static struct rsnd_mod_ops rsnd_ssiu_ops_gen1 = {
118 .name = SSIU_NAME, 148 .name = SSIU_NAME,
119 .init = rsnd_ssiu_init, 149 .init = rsnd_ssiu_init,
150 .get_status = rsnd_ssiu_get_status,
120}; 151};
121 152
122static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod, 153static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
@@ -124,7 +155,8 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
124 struct rsnd_priv *priv) 155 struct rsnd_priv *priv)
125{ 156{
126 struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod); 157 struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
127 int hdmi = rsnd_ssi_hdmi_port(io); 158 u32 has_hdmi0 = rsnd_flags_has(io, RSND_STREAM_HDMI0);
159 u32 has_hdmi1 = rsnd_flags_has(io, RSND_STREAM_HDMI1);
128 int ret; 160 int ret;
129 u32 mode = 0; 161 u32 mode = 0;
130 162
@@ -134,20 +166,21 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
134 166
135 ssiu->usrcnt++; 167 ssiu->usrcnt++;
136 168
137 if (rsnd_runtime_is_ssi_tdm(io)) { 169 /*
138 /* 170 * TDM Extend/Split Mode
139 * TDM Extend Mode 171 * see
140 * see 172 * rsnd_ssi_config_init()
141 * rsnd_ssi_config_init() 173 */
142 */ 174 if (rsnd_runtime_is_tdm(io))
143 mode = 0x1; 175 mode = TDM_EXT;
144 } 176 else if (rsnd_runtime_is_tdm_split(io))
177 mode = TDM_SPLIT;
145 178
146 rsnd_mod_write(mod, SSI_MODE, mode); 179 rsnd_mod_write(mod, SSI_MODE, mode);
147 180
148 if (rsnd_ssi_use_busif(io)) { 181 if (rsnd_ssi_use_busif(io)) {
149 int id = rsnd_mod_id(mod); 182 int id = rsnd_mod_id(mod);
150 int busif = rsnd_ssi_get_busif(io); 183 int busif = rsnd_mod_id_sub(mod);
151 184
152 /* 185 /*
153 * FIXME 186 * FIXME
@@ -162,46 +195,18 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
162 id, busif); 195 id, busif);
163 } 196 }
164 197
165#define RSND_WRITE_BUSIF(i) \ 198 rsnd_mod_write(mod, SSI_BUSIF_ADINR(busif),
166 rsnd_mod_write(mod, SSI_BUSIF##i##_ADINR, \ 199 rsnd_get_adinr_bit(mod, io) |
167 rsnd_get_adinr_bit(mod, io) | \ 200 (rsnd_io_is_play(io) ?
168 (rsnd_io_is_play(io) ? \ 201 rsnd_runtime_channel_after_ctu(io) :
169 rsnd_runtime_channel_after_ctu(io) : \ 202 rsnd_runtime_channel_original(io)));
170 rsnd_runtime_channel_original(io))); \ 203 rsnd_mod_write(mod, SSI_BUSIF_MODE(busif),
171 rsnd_mod_write(mod, SSI_BUSIF##i##_MODE, \ 204 rsnd_get_busif_shift(io, mod) | 1);
172 rsnd_get_busif_shift(io, mod) | 1); \ 205 rsnd_mod_write(mod, SSI_BUSIF_DALIGN(busif),
173 rsnd_mod_write(mod, SSI_BUSIF##i##_DALIGN, \ 206 rsnd_get_dalign(mod, io));
174 rsnd_get_dalign(mod, io))
175
176 switch (busif) {
177 case 0:
178 RSND_WRITE_BUSIF(0);
179 break;
180 case 1:
181 RSND_WRITE_BUSIF(1);
182 break;
183 case 2:
184 RSND_WRITE_BUSIF(2);
185 break;
186 case 3:
187 RSND_WRITE_BUSIF(3);
188 break;
189 case 4:
190 RSND_WRITE_BUSIF(4);
191 break;
192 case 5:
193 RSND_WRITE_BUSIF(5);
194 break;
195 case 6:
196 RSND_WRITE_BUSIF(6);
197 break;
198 case 7:
199 RSND_WRITE_BUSIF(7);
200 break;
201 }
202 } 207 }
203 208
204 if (hdmi) { 209 if (has_hdmi0 || has_hdmi1) {
205 enum rsnd_mod_type rsnd_ssi_array[] = { 210 enum rsnd_mod_type rsnd_ssi_array[] = {
206 RSND_MOD_SSIM1, 211 RSND_MOD_SSIM1,
207 RSND_MOD_SSIM2, 212 RSND_MOD_SSIM2,
@@ -227,14 +232,10 @@ static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
227 rsnd_mod_id(pos) << shift; 232 rsnd_mod_id(pos) << shift;
228 } 233 }
229 234
230 switch (hdmi) { 235 if (has_hdmi0)
231 case RSND_SSI_HDMI_PORT0:
232 rsnd_mod_write(mod, HDMI0_SEL, val); 236 rsnd_mod_write(mod, HDMI0_SEL, val);
233 break; 237 if (has_hdmi1)
234 case RSND_SSI_HDMI_PORT1:
235 rsnd_mod_write(mod, HDMI1_SEL, val); 238 rsnd_mod_write(mod, HDMI1_SEL, val);
236 break;
237 }
238 } 239 }
239 240
240 return 0; 241 return 0;
@@ -244,7 +245,7 @@ static int rsnd_ssiu_start_gen2(struct rsnd_mod *mod,
244 struct rsnd_dai_stream *io, 245 struct rsnd_dai_stream *io,
245 struct rsnd_priv *priv) 246 struct rsnd_priv *priv)
246{ 247{
247 int busif = rsnd_ssi_get_busif(io); 248 int busif = rsnd_mod_id_sub(mod);
248 249
249 if (!rsnd_ssi_use_busif(io)) 250 if (!rsnd_ssi_use_busif(io))
250 return 0; 251 return 0;
@@ -262,7 +263,7 @@ static int rsnd_ssiu_stop_gen2(struct rsnd_mod *mod,
262 struct rsnd_priv *priv) 263 struct rsnd_priv *priv)
263{ 264{
264 struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod); 265 struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
265 int busif = rsnd_ssi_get_busif(io); 266 int busif = rsnd_mod_id_sub(mod);
266 267
267 if (!rsnd_ssi_use_busif(io)) 268 if (!rsnd_ssi_use_busif(io))
268 return 0; 269 return 0;
@@ -278,11 +279,53 @@ static int rsnd_ssiu_stop_gen2(struct rsnd_mod *mod,
278 return 0; 279 return 0;
279} 280}
280 281
282static int rsnd_ssiu_id(struct rsnd_mod *mod)
283{
284 struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
285
286 /* see rsnd_ssiu_probe() */
287 return ssiu->id;
288}
289
290static int rsnd_ssiu_id_sub(struct rsnd_mod *mod)
291{
292 struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
293
294 /* see rsnd_ssiu_probe() */
295 return ssiu->id_sub;
296}
297
298static struct dma_chan *rsnd_ssiu_dma_req(struct rsnd_dai_stream *io,
299 struct rsnd_mod *mod)
300{
301 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
302 int is_play = rsnd_io_is_play(io);
303 char *name;
304
305 /*
306 * It should use "rcar_sound,ssiu" on DT.
307 * But, we need to keep compatibility for old version.
308 *
309 * If it has "rcar_sound.ssiu", it will be used.
310 * If not, "rcar_sound.ssi" will be used.
311 * see
312 * rsnd_ssi_dma_req()
313 * rsnd_dma_of_path()
314 */
315
316 name = is_play ? "rx" : "tx";
317
318 return rsnd_dma_request_channel(rsnd_ssiu_of_node(priv),
319 mod, name);
320}
321
281static struct rsnd_mod_ops rsnd_ssiu_ops_gen2 = { 322static struct rsnd_mod_ops rsnd_ssiu_ops_gen2 = {
282 .name = SSIU_NAME, 323 .name = SSIU_NAME,
283 .init = rsnd_ssiu_init_gen2, 324 .dma_req = rsnd_ssiu_dma_req,
284 .start = rsnd_ssiu_start_gen2, 325 .init = rsnd_ssiu_init_gen2,
285 .stop = rsnd_ssiu_stop_gen2, 326 .start = rsnd_ssiu_start_gen2,
327 .stop = rsnd_ssiu_stop_gen2,
328 .get_status = rsnd_ssiu_get_status,
286}; 329};
287 330
288static struct rsnd_mod *rsnd_ssiu_mod_get(struct rsnd_priv *priv, int id) 331static struct rsnd_mod *rsnd_ssiu_mod_get(struct rsnd_priv *priv, int id)
@@ -293,36 +336,85 @@ static struct rsnd_mod *rsnd_ssiu_mod_get(struct rsnd_priv *priv, int id)
293 return rsnd_mod_get((struct rsnd_ssiu *)(priv->ssiu) + id); 336 return rsnd_mod_get((struct rsnd_ssiu *)(priv->ssiu) + id);
294} 337}
295 338
296int rsnd_ssiu_attach(struct rsnd_dai_stream *io, 339static void rsnd_parse_connect_ssiu_compatible(struct rsnd_priv *priv,
297 struct rsnd_mod *ssi_mod) 340 struct rsnd_dai_stream *io)
298{ 341{
299 struct rsnd_priv *priv = rsnd_io_to_priv(io); 342 struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
300 struct rsnd_mod *mod = rsnd_ssiu_mod_get(priv, rsnd_mod_id(ssi_mod)); 343 struct rsnd_mod *mod;
344 struct rsnd_ssiu *ssiu;
345 int i;
301 346
302 rsnd_mod_confirm_ssi(ssi_mod); 347 if (!ssi_mod)
348 return;
303 349
304 return rsnd_dai_connect(mod, io, mod->type); 350 /* select BUSIF0 */
351 for_each_rsnd_ssiu(ssiu, priv, i) {
352 mod = rsnd_mod_get(ssiu);
353
354 if ((rsnd_mod_id(ssi_mod) == rsnd_mod_id(mod)) &&
355 (rsnd_mod_id_sub(mod) == 0)) {
356 rsnd_dai_connect(mod, io, mod->type);
357 return;
358 }
359 }
305} 360}
306 361
307static u32 *rsnd_ssiu_get_status(struct rsnd_dai_stream *io, 362void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai,
308 struct rsnd_mod *mod, 363 struct device_node *playback,
309 enum rsnd_mod_type type) 364 struct device_node *capture)
310{ 365{
311 struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod); 366 struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
312 int busif = rsnd_ssi_get_busif(io); 367 struct device_node *node = rsnd_ssiu_of_node(priv);
368 struct device_node *np;
369 struct rsnd_mod *mod;
370 struct rsnd_dai_stream *io_p = &rdai->playback;
371 struct rsnd_dai_stream *io_c = &rdai->capture;
372 int i;
313 373
314 return &ssiu->busif_status[busif]; 374 /* use rcar_sound,ssiu if exist */
375 if (node) {
376 i = 0;
377 for_each_child_of_node(node, np) {
378 mod = rsnd_ssiu_mod_get(priv, i);
379 if (np == playback)
380 rsnd_dai_connect(mod, io_p, mod->type);
381 if (np == capture)
382 rsnd_dai_connect(mod, io_c, mod->type);
383 i++;
384 }
385
386 of_node_put(node);
387 }
388
389 /* Keep DT compatibility */
390 if (!rsnd_io_to_mod_ssiu(io_p))
391 rsnd_parse_connect_ssiu_compatible(priv, io_p);
392 if (!rsnd_io_to_mod_ssiu(io_c))
393 rsnd_parse_connect_ssiu_compatible(priv, io_c);
315} 394}
316 395
317int rsnd_ssiu_probe(struct rsnd_priv *priv) 396int rsnd_ssiu_probe(struct rsnd_priv *priv)
318{ 397{
319 struct device *dev = rsnd_priv_to_dev(priv); 398 struct device *dev = rsnd_priv_to_dev(priv);
399 struct device_node *node;
320 struct rsnd_ssiu *ssiu; 400 struct rsnd_ssiu *ssiu;
321 struct rsnd_mod_ops *ops; 401 struct rsnd_mod_ops *ops;
402 const int *list = NULL;
322 int i, nr, ret; 403 int i, nr, ret;
323 404
324 /* same number to SSI */ 405 /*
325 nr = priv->ssi_nr; 406 * Keep DT compatibility.
407 * if it has "rcar_sound,ssiu", use it.
408 * if not, use "rcar_sound,ssi"
409 * see
410 * rsnd_ssiu_bufsif_to_id()
411 */
412 node = rsnd_ssiu_of_node(priv);
413 if (node)
414 nr = of_get_child_count(node);
415 else
416 nr = priv->ssi_nr;
417
326 ssiu = devm_kcalloc(dev, nr, sizeof(*ssiu), GFP_KERNEL); 418 ssiu = devm_kcalloc(dev, nr, sizeof(*ssiu), GFP_KERNEL);
327 if (!ssiu) 419 if (!ssiu)
328 return -ENOMEM; 420 return -ENOMEM;
@@ -335,10 +427,46 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv)
335 else 427 else
336 ops = &rsnd_ssiu_ops_gen2; 428 ops = &rsnd_ssiu_ops_gen2;
337 429
430 /* Keep compatibility */
431 nr = 0;
432 if ((node) &&
433 (ops == &rsnd_ssiu_ops_gen2)) {
434 ops->id = rsnd_ssiu_id;
435 ops->id_sub = rsnd_ssiu_id_sub;
436
437 if (rsnd_is_gen2(priv)) {
438 list = gen2_id;
439 nr = ARRAY_SIZE(gen2_id);
440 } else if (rsnd_is_gen3(priv)) {
441 list = gen3_id;
442 nr = ARRAY_SIZE(gen3_id);
443 } else {
444 dev_err(dev, "unknown SSIU\n");
445 return -ENODEV;
446 }
447 }
448
338 for_each_rsnd_ssiu(ssiu, priv, i) { 449 for_each_rsnd_ssiu(ssiu, priv, i) {
450 if (node) {
451 int j;
452
453 /*
454 * see
455 * rsnd_ssiu_get_id()
456 * rsnd_ssiu_get_id_sub()
457 */
458 for (j = 0; j < nr; j++) {
459 if (list[j] > i)
460 break;
461 ssiu->id = j;
462 ssiu->id_sub = i - list[ssiu->id];
463 }
464 } else {
465 ssiu->id = i;
466 }
467
339 ret = rsnd_mod_init(priv, rsnd_mod_get(ssiu), 468 ret = rsnd_mod_init(priv, rsnd_mod_get(ssiu),
340 ops, NULL, rsnd_ssiu_get_status, 469 ops, NULL, RSND_MOD_SSIU, i);
341 RSND_MOD_SSIU, i);
342 if (ret) 470 if (ret)
343 return ret; 471 return ret;
344 } 472 }
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index b29d0f65611e..0462b3ec977a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1467,7 +1467,7 @@ static int soc_link_dai_pcm_new(struct snd_soc_dai **dais, int num_dais,
1467 for (i = 0; i < num_dais; ++i) { 1467 for (i = 0; i < num_dais; ++i) {
1468 struct snd_soc_dai_driver *drv = dais[i]->driver; 1468 struct snd_soc_dai_driver *drv = dais[i]->driver;
1469 1469
1470 if (!rtd->dai_link->no_pcm && drv->pcm_new) 1470 if (drv->pcm_new)
1471 ret = drv->pcm_new(rtd, dais[i]); 1471 ret = drv->pcm_new(rtd, dais[i]);
1472 if (ret < 0) { 1472 if (ret < 0) {
1473 dev_err(dais[i]->dev, 1473 dev_err(dais[i]->dev,
@@ -3485,12 +3485,11 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np,
3485} 3485}
3486EXPORT_SYMBOL_GPL(snd_soc_of_parse_tdm_slot); 3486EXPORT_SYMBOL_GPL(snd_soc_of_parse_tdm_slot);
3487 3487
3488void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card, 3488void snd_soc_of_parse_node_prefix(struct device_node *np,
3489 struct snd_soc_codec_conf *codec_conf, 3489 struct snd_soc_codec_conf *codec_conf,
3490 struct device_node *of_node, 3490 struct device_node *of_node,
3491 const char *propname) 3491 const char *propname)
3492{ 3492{
3493 struct device_node *np = card->dev->of_node;
3494 const char *str; 3493 const char *str;
3495 int ret; 3494 int ret;
3496 3495
@@ -3503,7 +3502,7 @@ void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
3503 codec_conf->of_node = of_node; 3502 codec_conf->of_node = of_node;
3504 codec_conf->name_prefix = str; 3503 codec_conf->name_prefix = str;
3505} 3504}
3506EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_prefix); 3505EXPORT_SYMBOL_GPL(snd_soc_of_parse_node_prefix);
3507 3506
3508int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, 3507int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
3509 const char *propname) 3508 const char *propname)
diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c
index d597eba61992..bcb35cae2a2c 100644
--- a/sound/soc/stm/stm32_sai.c
+++ b/sound/soc/stm/stm32_sai.c
@@ -74,14 +74,14 @@ static int stm32_sai_sync_conf_provider(struct stm32_sai_data *sai, int synco)
74 return ret; 74 return ret;
75 } 75 }
76 76
77 dev_dbg(&sai->pdev->dev, "Set %s%s as synchro provider\n", 77 dev_dbg(&sai->pdev->dev, "Set %pOFn%s as synchro provider\n",
78 sai->pdev->dev.of_node->name, 78 sai->pdev->dev.of_node,
79 synco == STM_SAI_SYNC_OUT_A ? "A" : "B"); 79 synco == STM_SAI_SYNC_OUT_A ? "A" : "B");
80 80
81 prev_synco = FIELD_GET(SAI_GCR_SYNCOUT_MASK, readl_relaxed(sai->base)); 81 prev_synco = FIELD_GET(SAI_GCR_SYNCOUT_MASK, readl_relaxed(sai->base));
82 if (prev_synco != STM_SAI_SYNC_OUT_NONE && synco != prev_synco) { 82 if (prev_synco != STM_SAI_SYNC_OUT_NONE && synco != prev_synco) {
83 dev_err(&sai->pdev->dev, "%s%s already set as sync provider\n", 83 dev_err(&sai->pdev->dev, "%pOFn%s already set as sync provider\n",
84 sai->pdev->dev.of_node->name, 84 sai->pdev->dev.of_node,
85 prev_synco == STM_SAI_SYNC_OUT_A ? "A" : "B"); 85 prev_synco == STM_SAI_SYNC_OUT_A ? "A" : "B");
86 clk_disable_unprepare(sai->pclk); 86 clk_disable_unprepare(sai->pclk);
87 return -EINVAL; 87 return -EINVAL;
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
index 211589b0b2ef..d4825700b63f 100644
--- a/sound/soc/stm/stm32_sai_sub.c
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -336,8 +336,7 @@ static int stm32_sai_mclk_set_rate(struct clk_hw *hw, unsigned long rate,
336{ 336{
337 struct stm32_sai_mclk_data *mclk = to_mclk_data(hw); 337 struct stm32_sai_mclk_data *mclk = to_mclk_data(hw);
338 struct stm32_sai_sub_data *sai = mclk->sai_data; 338 struct stm32_sai_sub_data *sai = mclk->sai_data;
339 unsigned int div; 339 int div, ret;
340 int ret;
341 340
342 div = stm32_sai_get_clk_div(sai, parent_rate, rate); 341 div = stm32_sai_get_clk_div(sai, parent_rate, rate);
343 if (div < 0) 342 if (div < 0)
diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c
index 8f5f999df631..df1fed0aa001 100644
--- a/sound/soc/sunxi/sun50i-codec-analog.c
+++ b/sound/soc/sunxi/sun50i-codec-analog.c
@@ -274,6 +274,7 @@ static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = {
274 * stream widgets at the card level. 274 * stream widgets at the card level.
275 */ 275 */
276 276
277 SND_SOC_DAPM_REGULATOR_SUPPLY("hpvcc", 0, 0),
277 SND_SOC_DAPM_MUX("Headphone Source Playback Route", 278 SND_SOC_DAPM_MUX("Headphone Source Playback Route",
278 SND_SOC_NOPM, 0, 0, sun50i_codec_hp_src), 279 SND_SOC_NOPM, 0, 0, sun50i_codec_hp_src),
279 SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN50I_ADDA_HP_CTRL, 280 SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN50I_ADDA_HP_CTRL,
@@ -361,6 +362,7 @@ static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = {
361 { "Headphone Source Playback Route", "Mixer", "Left Mixer" }, 362 { "Headphone Source Playback Route", "Mixer", "Left Mixer" },
362 { "Headphone Source Playback Route", "Mixer", "Right Mixer" }, 363 { "Headphone Source Playback Route", "Mixer", "Right Mixer" },
363 { "Headphone Amp", NULL, "Headphone Source Playback Route" }, 364 { "Headphone Amp", NULL, "Headphone Source Playback Route" },
365 { "Headphone Amp", NULL, "hpvcc" },
364 { "HP", NULL, "Headphone Amp" }, 366 { "HP", NULL, "Headphone Amp" },
365 367
366 /* Microphone Routes */ 368 /* Microphone Routes */
diff --git a/sound/soc/ti/Kconfig b/sound/soc/ti/Kconfig
new file mode 100644
index 000000000000..4bf3c15d4e51
--- /dev/null
+++ b/sound/soc/ti/Kconfig
@@ -0,0 +1,209 @@
1menu "Audio support for Texas Instruments SoCs"
2depends on DMA_OMAP || TI_EDMA || COMPILE_TEST
3
4config SND_SOC_TI_EDMA_PCM
5 tristate
6 select SND_SOC_GENERIC_DMAENGINE_PCM
7
8config SND_SOC_TI_SDMA_PCM
9 tristate
10 select SND_SOC_GENERIC_DMAENGINE_PCM
11
12comment "Texas Instruments DAI support for:"
13config SND_SOC_DAVINCI_ASP
14 tristate "daVinci Audio Serial Port (ASP) or McBSP suport"
15 depends on ARCH_DAVINCI || COMPILE_TEST
16 select SND_SOC_TI_EDMA_PCM
17 help
18 Say Y or M here if you want audio support via daVinci ASP or McBSP.
19 The driver only implements the ASP support which is a subset of
20 daVinci McBSP (w/o the multichannel support).
21
22config SND_SOC_DAVINCI_MCASP
23 tristate "Multichannel Audio Serial Port (McASP) support"
24 select SND_SOC_TI_EDMA_PCM if TI_EDMA
25 select SND_SOC_TI_SDMA_PCM if DMA_OMAP
26 help
27 Say Y or M here if you want to have support for McASP IP found in
28 various Texas Instruments SoCs like:
29 - daVinci devices
30 - Sitara line of SoCs (AM335x, AM438x, etc)
31 - DRA7x devices
32 - Keystone devices
33
34config SND_SOC_DAVINCI_VCIF
35 tristate "daVinci Voice Interface (VCIF) suport"
36 depends on ARCH_DAVINCI || COMPILE_TEST
37 select SND_SOC_TI_EDMA_PCM
38 help
39 Say Y or M here if you want audio support via daVinci VCIF.
40
41config SND_SOC_OMAP_DMIC
42 tristate "Digital Microphone Module (DMIC) support"
43 depends on ARCH_OMAP4 || SOC_OMAP5 || COMPILE_TEST
44 select SND_SOC_TI_SDMA_PCM
45 help
46 Say Y or M here if you want to have support for DMIC IP found in
47 OMAP4 and OMAP5.
48
49config SND_SOC_OMAP_MCBSP
50 tristate "Multichannel Buffered Serial Port (McBSP) support"
51 depends on ARCH_OMAP || ARCH_OMAP1 || COMPILE_TEST
52 select SND_SOC_TI_SDMA_PCM
53 help
54 Say Y or M here if you want to have support for McBSP IP found in
55 Texas Instruments OMAP1/2/3/4/5 SoCs.
56
57config SND_SOC_OMAP_MCPDM
58 tristate "Multichannel PDM Controller (McPDM) support"
59 depends on ARCH_OMAP4 || SOC_OMAP5 || COMPILE_TEST
60 select SND_SOC_TI_SDMA_PCM
61 help
62 Say Y or M here if you want to have support for McPDM IP found in
63 OMAP4 and OMAP5.
64
65comment "Audio support for boards with Texas Instruments SoCs"
66config SND_SOC_NOKIA_N810
67 tristate "SoC Audio support for Nokia N810"
68 depends on MACH_NOKIA_N810 && I2C
69 select SND_SOC_OMAP_MCBSP
70 select SND_SOC_TLV320AIC3X
71 help
72 Say Y or M if you want to add support for SoC audio on Nokia N810.
73
74config SND_SOC_NOKIA_RX51
75 tristate "SoC Audio support for Nokia RX-51"
76 depends on ARCH_OMAP3 && I2C && GPIOLIB
77 select SND_SOC_OMAP_MCBSP
78 select SND_SOC_TLV320AIC3X
79 select SND_SOC_TPA6130A2
80 help
81 Say Y or M if you want to add support for SoC audio on Nokia RX-51
82 hardware. This is also known as Nokia N900 product.
83
84config SND_SOC_OMAP3_PANDORA
85 tristate "SoC Audio support for OMAP3 Pandora"
86 depends on ARCH_OMAP3
87 depends on TWL4030_CORE
88 select SND_SOC_OMAP_MCBSP
89 select SND_SOC_TWL4030
90 help
91 Say Y or M if you want to add support for SoC audio on the OMAP3 Pandora.
92
93config SND_SOC_OMAP3_TWL4030
94 tristate "SoC Audio support for OMAP3 based boards with twl4030 codec"
95 depends on ARCH_OMAP3 || COMPILE_TEST
96 depends on TWL4030_CORE
97 select SND_SOC_OMAP_MCBSP
98 select SND_SOC_TWL4030
99 help
100 Say Y or M if you want to add support for SoC audio on OMAP3 based
101 boards using twl4030 as codec. This driver currently supports:
102 - Beagleboard or Devkit8000
103 - Gumstix Overo or CompuLab CM-T35/CM-T3730
104 - IGEP v2
105 - OMAP3EVM
106 - SDP3430
107 - Zoom2
108
109config SND_SOC_OMAP_ABE_TWL6040
110 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
111 depends on TWL6040_CORE && COMMON_CLK
112 depends on ARCH_OMAP4 || (SOC_OMAP5 && MFD_PALMAS) || COMPILE_TEST
113 select SND_SOC_OMAP_DMIC
114 select SND_SOC_OMAP_MCPDM
115 select SND_SOC_TWL6040
116 help
117 Say Y or M if you want to add support for SoC audio on OMAP boards
118 using ABE and twl6040 codec. This driver currently supports:
119 - SDP4430/Blaze boards
120 - PandaBoard (4430)
121 - PandaBoardES (4460)
122 - OMAP5 uEVM
123
124config SND_SOC_OMAP_AMS_DELTA
125 tristate "SoC Audio support for Amstrad E3 (Delta) videophone"
126 depends on MACH_AMS_DELTA && TTY
127 select SND_SOC_OMAP_MCBSP
128 select SND_SOC_CX20442
129 help
130 Say Y or M if you want to add support for SoC audio device
131 connected to a handset and a speakerphone found on Amstrad E3 (Delta)
132 videophone.
133
134 Note that in order to get those devices fully supported, you have to
135 build the kernel with standard serial port driver included and
136 configured for at least 4 ports. Then, from userspace, you must load
137 a line discipline #19 on the modem (ttyS3) serial line. The simplest
138 way to achieve this is to install util-linux-ng and use the included
139 ldattach utility. This can be started automatically from udev,
140 a simple rule like this one should do the trick (it does for me):
141 ACTION=="add", KERNEL=="controlC0", \
142 RUN+="/usr/sbin/ldattach 19 /dev/ttyS3"
143
144config SND_SOC_OMAP_HDMI
145 tristate "OMAP4/5 HDMI audio support"
146 depends on OMAP4_DSS_HDMI || OMAP5_DSS_HDMI || COMPILE_TEST
147 select SND_SOC_TI_SDMA_PCM
148 help
149 For HDMI audio to work OMAPDSS HDMI support should be
150 enabled.
151 The hdmi audio driver implements cpu-dai component using the
152 callbacks provided by OMAPDSS and registers the component
153 under DSS HDMI device. Omap-pcm is registered for platform
154 component also under DSS HDMI device. Dummy codec is used as
155 as codec component. The hdmi audio driver implements also
156 the card and registers it under its own platform device.
157 The device for the driver is registered by OMAPDSS hdmi
158 driver.
159
160config SND_SOC_OMAP_OSK5912
161 tristate "SoC Audio support for omap osk5912"
162 depends on MACH_OMAP_OSK && I2C
163 select SND_SOC_OMAP_MCBSP
164 select SND_SOC_TLV320AIC23_I2C
165 help
166 Say Y or M if you want to add support for SoC audio on osk5912.
167
168config SND_SOC_DAVINCI_EVM
169 tristate "SoC Audio support for DaVinci EVMs"
170 depends on ARCH_DAVINCI && I2C
171 select SND_SOC_DAVINCI_ASP if MACH_DAVINCI_DM355_EVM
172 select SND_SOC_DAVINCI_ASP if SND_SOC_DM365_AIC3X_CODEC
173 select SND_SOC_DAVINCI_VCIF if SND_SOC_DM365_VOICE_CODEC
174 select SND_SOC_DAVINCI_ASP if MACH_DAVINCI_EVM # DM6446
175 select SND_SOC_DAVINCI_MCASP if MACH_DAVINCI_DM6467_EVM
176 select SND_SOC_SPDIF if MACH_DAVINCI_DM6467_EVM
177 select SND_SOC_DAVINCI_MCASP if MACH_DAVINCI_DA830_EVM
178 select SND_SOC_DAVINCI_MCASP if MACH_DAVINCI_DA850_EVM
179 select SND_SOC_TLV320AIC3X
180 help
181 Say Y if you want to add support for SoC audio on the following TI
182 DaVinci EVM platforms:
183 - DM355
184 - DM365
185 - DM6446
186 - DM6447
187 - DM830
188 - DM850
189
190choice
191 prompt "DM365 codec select"
192 depends on SND_SOC_DAVINCI_EVM
193 depends on MACH_DAVINCI_DM365_EVM
194
195config SND_SOC_DM365_AIC3X_CODEC
196 bool "Audio Codec - AIC3101"
197 help
198 Say Y if you want to add support for AIC3101 audio codec
199
200config SND_SOC_DM365_VOICE_CODEC
201 bool "Voice Codec - CQ93VC"
202 select MFD_DAVINCI_VOICECODEC
203 select SND_SOC_CQ0093VC
204 help
205 Say Y if you want to add support for SoC On-chip voice codec
206endchoice
207
208endmenu
209
diff --git a/sound/soc/ti/Makefile b/sound/soc/ti/Makefile
new file mode 100644
index 000000000000..08c44d56ef3e
--- /dev/null
+++ b/sound/soc/ti/Makefile
@@ -0,0 +1,44 @@
1# SPDX-License-Identifier: GPL-2.0
2
3# Platform drivers
4snd-soc-ti-edma-objs := edma-pcm.o
5snd-soc-ti-sdma-objs := sdma-pcm.o
6
7obj-$(CONFIG_SND_SOC_TI_EDMA_PCM) += snd-soc-ti-edma.o
8obj-$(CONFIG_SND_SOC_TI_SDMA_PCM) += snd-soc-ti-sdma.o
9
10# CPU DAI drivers
11snd-soc-davinci-asp-objs := davinci-i2s.o
12snd-soc-davinci-mcasp-objs := davinci-mcasp.o
13snd-soc-davinci-vcif-objs := davinci-vcif.o
14snd-soc-omap-dmic-objs := omap-dmic.o
15snd-soc-omap-mcbsp-objs := omap-mcbsp.o omap-mcbsp-st.o
16snd-soc-omap-mcpdm-objs := omap-mcpdm.o
17
18obj-$(CONFIG_SND_SOC_DAVINCI_ASP) += snd-soc-davinci-asp.o
19obj-$(CONFIG_SND_SOC_DAVINCI_MCASP) += snd-soc-davinci-mcasp.o
20obj-$(CONFIG_SND_SOC_DAVINCI_VCIF) += snd-soc-davinci-vcif.o
21obj-$(CONFIG_SND_SOC_OMAP_DMIC) += snd-soc-omap-dmic.o
22obj-$(CONFIG_SND_SOC_OMAP_MCBSP) += snd-soc-omap-mcbsp.o
23obj-$(CONFIG_SND_SOC_OMAP_MCPDM) += snd-soc-omap-mcpdm.o
24
25# Machine drivers
26snd-soc-davinci-evm-objs := davinci-evm.o
27snd-soc-n810-objs := n810.o
28snd-soc-rx51-objs := rx51.o
29snd-soc-omap3pandora-objs := omap3pandora.o
30snd-soc-omap-twl4030-objs := omap-twl4030.o
31snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o
32snd-soc-ams-delta-objs := ams-delta.o
33snd-soc-omap-hdmi-objs := omap-hdmi.o
34snd-soc-osk5912-objs := osk5912.o
35
36obj-$(CONFIG_SND_SOC_DAVINCI_EVM) += snd-soc-davinci-evm.o
37obj-$(CONFIG_SND_SOC_NOKIA_N810) += snd-soc-n810.o
38obj-$(CONFIG_SND_SOC_NOKIA_RX51) += snd-soc-rx51.o
39obj-$(CONFIG_SND_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
40obj-$(CONFIG_SND_SOC_OMAP3_TWL4030) += snd-soc-omap-twl4030.o
41obj-$(CONFIG_SND_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o
42obj-$(CONFIG_SND_SOC_OMAP_AMS_DELTA) += snd-soc-ams-delta.o
43obj-$(CONFIG_SND_SOC_OMAP_HDMI) += snd-soc-omap-hdmi.o
44obj-$(CONFIG_SND_SOC_OMAP_OSK5912) += snd-soc-osk5912.o
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/ti/ams-delta.c
index 4dce494dfbd3..4dce494dfbd3 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/ti/ams-delta.c
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/ti/davinci-evm.c
index 7a369e0f2093..4869d6311510 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/ti/davinci-evm.c
@@ -170,7 +170,7 @@ static struct snd_soc_dai_link dm355_evm_dai = {
170}; 170};
171 171
172static struct snd_soc_dai_link dm365_evm_dai = { 172static struct snd_soc_dai_link dm365_evm_dai = {
173#ifdef CONFIG_SND_DM365_AIC3X_CODEC 173#ifdef CONFIG_SND_SOC_DM365_AIC3X_CODEC
174 .name = "TLV320AIC3X", 174 .name = "TLV320AIC3X",
175 .stream_name = "AIC3X", 175 .stream_name = "AIC3X",
176 .cpu_dai_name = "davinci-mcbsp", 176 .cpu_dai_name = "davinci-mcbsp",
@@ -181,7 +181,7 @@ static struct snd_soc_dai_link dm365_evm_dai = {
181 .ops = &evm_ops, 181 .ops = &evm_ops,
182 .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | 182 .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM |
183 SND_SOC_DAIFMT_IB_NF, 183 SND_SOC_DAIFMT_IB_NF,
184#elif defined(CONFIG_SND_DM365_VOICE_CODEC) 184#elif defined(CONFIG_SND_SOC_DM365_VOICE_CODEC)
185 .name = "Voice Codec - CQ93VC", 185 .name = "Voice Codec - CQ93VC",
186 .stream_name = "CQ93", 186 .stream_name = "CQ93",
187 .cpu_dai_name = "davinci-vcif", 187 .cpu_dai_name = "davinci-vcif",
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/ti/davinci-i2s.c
index a3206e65e5e5..a3206e65e5e5 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/ti/davinci-i2s.c
diff --git a/sound/soc/davinci/davinci-i2s.h b/sound/soc/ti/davinci-i2s.h
index 48dac3e2521a..48dac3e2521a 100644
--- a/sound/soc/davinci/davinci-i2s.h
+++ b/sound/soc/ti/davinci-i2s.h
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/ti/davinci-mcasp.c
index 267aee776b2d..eeda6d5565bc 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/ti/davinci-mcasp.c
@@ -28,6 +28,7 @@
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#include <linux/math64.h>
31#include <linux/bitmap.h>
31 32
32#include <sound/asoundef.h> 33#include <sound/asoundef.h>
33#include <sound/core.h> 34#include <sound/core.h>
@@ -38,7 +39,7 @@
38#include <sound/dmaengine_pcm.h> 39#include <sound/dmaengine_pcm.h>
39 40
40#include "edma-pcm.h" 41#include "edma-pcm.h"
41#include "../omap/sdma-pcm.h" 42#include "sdma-pcm.h"
42#include "davinci-mcasp.h" 43#include "davinci-mcasp.h"
43 44
44#define MCASP_MAX_AFIFO_DEPTH 64 45#define MCASP_MAX_AFIFO_DEPTH 64
@@ -84,6 +85,7 @@ struct davinci_mcasp {
84 u32 tdm_mask[2]; 85 u32 tdm_mask[2];
85 int slot_width; 86 int slot_width;
86 u8 op_mode; 87 u8 op_mode;
88 u8 dismod;
87 u8 num_serializer; 89 u8 num_serializer;
88 u8 *serial_dir; 90 u8 *serial_dir;
89 u8 version; 91 u8 version;
@@ -95,6 +97,8 @@ struct davinci_mcasp {
95 int sysclk_freq; 97 int sysclk_freq;
96 bool bclk_master; 98 bool bclk_master;
97 99
100 unsigned long pdir; /* Pin direction bitfield */
101
98 /* McASP FIFO related */ 102 /* McASP FIFO related */
99 u8 txnumevt; 103 u8 txnumevt;
100 u8 rxnumevt; 104 u8 rxnumevt;
@@ -169,6 +173,30 @@ static bool mcasp_is_synchronous(struct davinci_mcasp *mcasp)
169 return !(aclkxctl & TX_ASYNC) && rxfmctl & AFSRE; 173 return !(aclkxctl & TX_ASYNC) && rxfmctl & AFSRE;
170} 174}
171 175
176static inline void mcasp_set_clk_pdir(struct davinci_mcasp *mcasp, bool enable)
177{
178 u32 bit = PIN_BIT_AMUTE;
179
180 for_each_set_bit_from(bit, &mcasp->pdir, PIN_BIT_AFSR + 1) {
181 if (enable)
182 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit));
183 else
184 mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit));
185 }
186}
187
188static inline void mcasp_set_axr_pdir(struct davinci_mcasp *mcasp, bool enable)
189{
190 u32 bit;
191
192 for_each_set_bit(bit, &mcasp->pdir, PIN_BIT_AFSR) {
193 if (enable)
194 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit));
195 else
196 mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit));
197 }
198}
199
172static void mcasp_start_rx(struct davinci_mcasp *mcasp) 200static void mcasp_start_rx(struct davinci_mcasp *mcasp)
173{ 201{
174 if (mcasp->rxnumevt) { /* enable FIFO */ 202 if (mcasp->rxnumevt) { /* enable FIFO */
@@ -192,6 +220,7 @@ static void mcasp_start_rx(struct davinci_mcasp *mcasp)
192 } 220 }
193 221
194 /* Activate serializer(s) */ 222 /* Activate serializer(s) */
223 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF);
195 mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSERCLR); 224 mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSERCLR);
196 /* Release RX state machine */ 225 /* Release RX state machine */
197 mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSMRST); 226 mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, RXSMRST);
@@ -219,7 +248,10 @@ static void mcasp_start_tx(struct davinci_mcasp *mcasp)
219 /* Start clocks */ 248 /* Start clocks */
220 mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST); 249 mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST);
221 mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST); 250 mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST);
251 mcasp_set_clk_pdir(mcasp, true);
252
222 /* Activate serializer(s) */ 253 /* Activate serializer(s) */
254 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF);
223 mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR); 255 mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR);
224 256
225 /* wait for XDATA to be cleared */ 257 /* wait for XDATA to be cleared */
@@ -228,6 +260,8 @@ static void mcasp_start_tx(struct davinci_mcasp *mcasp)
228 (cnt < 100000)) 260 (cnt < 100000))
229 cnt++; 261 cnt++;
230 262
263 mcasp_set_axr_pdir(mcasp, true);
264
231 /* Release TX state machine */ 265 /* Release TX state machine */
232 mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSMRST); 266 mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXSMRST);
233 /* Release Frame Sync generator */ 267 /* Release Frame Sync generator */
@@ -258,8 +292,10 @@ static void mcasp_stop_rx(struct davinci_mcasp *mcasp)
258 * In synchronous mode stop the TX clocks if no other stream is 292 * In synchronous mode stop the TX clocks if no other stream is
259 * running 293 * running
260 */ 294 */
261 if (mcasp_is_synchronous(mcasp) && !mcasp->streams) 295 if (mcasp_is_synchronous(mcasp) && !mcasp->streams) {
296 mcasp_set_clk_pdir(mcasp, false);
262 mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, 0); 297 mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, 0);
298 }
263 299
264 mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, 0); 300 mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLR_REG, 0);
265 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF); 301 mcasp_set_reg(mcasp, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF);
@@ -285,6 +321,9 @@ static void mcasp_stop_tx(struct davinci_mcasp *mcasp)
285 */ 321 */
286 if (mcasp_is_synchronous(mcasp) && mcasp->streams) 322 if (mcasp_is_synchronous(mcasp) && mcasp->streams)
287 val = TXHCLKRST | TXCLKRST | TXFSRST; 323 val = TXHCLKRST | TXCLKRST | TXFSRST;
324 else
325 mcasp_set_clk_pdir(mcasp, false);
326
288 327
289 mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, val); 328 mcasp_set_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, val);
290 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF); 329 mcasp_set_reg(mcasp, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF);
@@ -294,6 +333,8 @@ static void mcasp_stop_tx(struct davinci_mcasp *mcasp)
294 333
295 mcasp_clr_bits(mcasp, reg, FIFO_ENABLE); 334 mcasp_clr_bits(mcasp, reg, FIFO_ENABLE);
296 } 335 }
336
337 mcasp_set_axr_pdir(mcasp, false);
297} 338}
298 339
299static void davinci_mcasp_stop(struct davinci_mcasp *mcasp, int stream) 340static void davinci_mcasp_stop(struct davinci_mcasp *mcasp, int stream)
@@ -444,8 +485,13 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
444 mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); 485 mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
445 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE); 486 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
446 487
447 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, ACLKX | ACLKR); 488 /* BCLK */
448 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR); 489 set_bit(PIN_BIT_ACLKX, &mcasp->pdir);
490 set_bit(PIN_BIT_ACLKR, &mcasp->pdir);
491 /* Frame Sync */
492 set_bit(PIN_BIT_AFSX, &mcasp->pdir);
493 set_bit(PIN_BIT_AFSR, &mcasp->pdir);
494
449 mcasp->bclk_master = 1; 495 mcasp->bclk_master = 1;
450 break; 496 break;
451 case SND_SOC_DAIFMT_CBS_CFM: 497 case SND_SOC_DAIFMT_CBS_CFM:
@@ -456,8 +502,13 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
456 mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); 502 mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
457 mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE); 503 mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
458 504
459 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, ACLKX | ACLKR); 505 /* BCLK */
460 mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR); 506 set_bit(PIN_BIT_ACLKX, &mcasp->pdir);
507 set_bit(PIN_BIT_ACLKR, &mcasp->pdir);
508 /* Frame Sync */
509 clear_bit(PIN_BIT_AFSX, &mcasp->pdir);
510 clear_bit(PIN_BIT_AFSR, &mcasp->pdir);
511
461 mcasp->bclk_master = 1; 512 mcasp->bclk_master = 1;
462 break; 513 break;
463 case SND_SOC_DAIFMT_CBM_CFS: 514 case SND_SOC_DAIFMT_CBM_CFS:
@@ -468,8 +519,13 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
468 mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); 519 mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
469 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE); 520 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
470 521
471 mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, ACLKX | ACLKR); 522 /* BCLK */
472 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR); 523 clear_bit(PIN_BIT_ACLKX, &mcasp->pdir);
524 clear_bit(PIN_BIT_ACLKR, &mcasp->pdir);
525 /* Frame Sync */
526 set_bit(PIN_BIT_AFSX, &mcasp->pdir);
527 set_bit(PIN_BIT_AFSR, &mcasp->pdir);
528
473 mcasp->bclk_master = 0; 529 mcasp->bclk_master = 0;
474 break; 530 break;
475 case SND_SOC_DAIFMT_CBM_CFM: 531 case SND_SOC_DAIFMT_CBM_CFM:
@@ -480,8 +536,13 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
480 mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE); 536 mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
481 mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE); 537 mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
482 538
483 mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, 539 /* BCLK */
484 ACLKX | AFSX | ACLKR | AHCLKR | AFSR); 540 clear_bit(PIN_BIT_ACLKX, &mcasp->pdir);
541 clear_bit(PIN_BIT_ACLKR, &mcasp->pdir);
542 /* Frame Sync */
543 clear_bit(PIN_BIT_AFSX, &mcasp->pdir);
544 clear_bit(PIN_BIT_AFSR, &mcasp->pdir);
545
485 mcasp->bclk_master = 0; 546 mcasp->bclk_master = 0;
486 break; 547 break;
487 default: 548 default:
@@ -596,11 +657,11 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id,
596 if (dir == SND_SOC_CLOCK_OUT) { 657 if (dir == SND_SOC_CLOCK_OUT) {
597 mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); 658 mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE);
598 mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); 659 mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE);
599 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AHCLKX); 660 set_bit(PIN_BIT_AHCLKX, &mcasp->pdir);
600 } else { 661 } else {
601 mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); 662 mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE);
602 mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); 663 mcasp_clr_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE);
603 mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AHCLKX); 664 clear_bit(PIN_BIT_AHCLKX, &mcasp->pdir);
604 } 665 }
605 666
606 mcasp->sysclk_freq = freq; 667 mcasp->sysclk_freq = freq;
@@ -773,17 +834,23 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
773 mcasp->serial_dir[i]); 834 mcasp->serial_dir[i]);
774 if (mcasp->serial_dir[i] == TX_MODE && 835 if (mcasp->serial_dir[i] == TX_MODE &&
775 tx_ser < max_active_serializers) { 836 tx_ser < max_active_serializers) {
776 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AXR(i));
777 mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i), 837 mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
778 DISMOD_LOW, DISMOD_MASK); 838 mcasp->dismod, DISMOD_MASK);
839 set_bit(PIN_BIT_AXR(i), &mcasp->pdir);
779 tx_ser++; 840 tx_ser++;
780 } else if (mcasp->serial_dir[i] == RX_MODE && 841 } else if (mcasp->serial_dir[i] == RX_MODE &&
781 rx_ser < max_active_serializers) { 842 rx_ser < max_active_serializers) {
782 mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AXR(i)); 843 clear_bit(PIN_BIT_AXR(i), &mcasp->pdir);
783 rx_ser++; 844 rx_ser++;
784 } else if (mcasp->serial_dir[i] == INACTIVE_MODE) { 845 } else if (mcasp->serial_dir[i] == INACTIVE_MODE) {
785 mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i), 846 mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
786 SRMOD_INACTIVE, SRMOD_MASK); 847 SRMOD_INACTIVE, SRMOD_MASK);
848 clear_bit(PIN_BIT_AXR(i), &mcasp->pdir);
849 } else if (mcasp->serial_dir[i] == TX_MODE) {
850 /* Unused TX pins, clear PDIR */
851 mcasp_mod_bits(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
852 mcasp->dismod, DISMOD_MASK);
853 clear_bit(PIN_BIT_AXR(i), &mcasp->pdir);
787 } 854 }
788 } 855 }
789 856
@@ -1645,6 +1712,7 @@ static struct davinci_mcasp_pdata *davinci_mcasp_set_pdata_from_of(
1645 1712
1646 if (pdev->dev.platform_data) { 1713 if (pdev->dev.platform_data) {
1647 pdata = pdev->dev.platform_data; 1714 pdata = pdev->dev.platform_data;
1715 pdata->dismod = DISMOD_LOW;
1648 return pdata; 1716 return pdata;
1649 } else if (match) { 1717 } else if (match) {
1650 pdata = devm_kmemdup(&pdev->dev, match->data, sizeof(*pdata), 1718 pdata = devm_kmemdup(&pdev->dev, match->data, sizeof(*pdata),
@@ -1734,6 +1802,18 @@ static struct davinci_mcasp_pdata *davinci_mcasp_set_pdata_from_of(
1734 if (ret >= 0) 1802 if (ret >= 0)
1735 pdata->sram_size_capture = val; 1803 pdata->sram_size_capture = val;
1736 1804
1805 ret = of_property_read_u32(np, "dismod", &val);
1806 if (ret >= 0) {
1807 if (val == 0 || val == 2 || val == 3) {
1808 pdata->dismod = DISMOD_VAL(val);
1809 } else {
1810 dev_warn(&pdev->dev, "Invalid dismod value: %u\n", val);
1811 pdata->dismod = DISMOD_LOW;
1812 }
1813 } else {
1814 pdata->dismod = DISMOD_LOW;
1815 }
1816
1737 return pdata; 1817 return pdata;
1738 1818
1739nodata: 1819nodata:
@@ -1909,6 +1989,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1909 mcasp->version = pdata->version; 1989 mcasp->version = pdata->version;
1910 mcasp->txnumevt = pdata->txnumevt; 1990 mcasp->txnumevt = pdata->txnumevt;
1911 mcasp->rxnumevt = pdata->rxnumevt; 1991 mcasp->rxnumevt = pdata->rxnumevt;
1992 mcasp->dismod = pdata->dismod;
1912 1993
1913 mcasp->dev = &pdev->dev; 1994 mcasp->dev = &pdev->dev;
1914 1995
@@ -2068,9 +2149,9 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
2068 ret = davinci_mcasp_get_dma_type(mcasp); 2149 ret = davinci_mcasp_get_dma_type(mcasp);
2069 switch (ret) { 2150 switch (ret) {
2070 case PCM_EDMA: 2151 case PCM_EDMA:
2071#if IS_BUILTIN(CONFIG_SND_EDMA_SOC) || \ 2152#if IS_BUILTIN(CONFIG_SND_SOC_TI_EDMA_PCM) || \
2072 (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \ 2153 (IS_MODULE(CONFIG_SND_SOC_DAVINCI_MCASP) && \
2073 IS_MODULE(CONFIG_SND_EDMA_SOC)) 2154 IS_MODULE(CONFIG_SND_SOC_TI_EDMA_PCM))
2074 ret = edma_pcm_platform_register(&pdev->dev); 2155 ret = edma_pcm_platform_register(&pdev->dev);
2075#else 2156#else
2076 dev_err(&pdev->dev, "Missing SND_EDMA_SOC\n"); 2157 dev_err(&pdev->dev, "Missing SND_EDMA_SOC\n");
@@ -2079,9 +2160,9 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
2079#endif 2160#endif
2080 break; 2161 break;
2081 case PCM_SDMA: 2162 case PCM_SDMA:
2082#if IS_BUILTIN(CONFIG_SND_SDMA_SOC) || \ 2163#if IS_BUILTIN(CONFIG_SND_SOC_TI_SDMA_PCM) || \
2083 (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \ 2164 (IS_MODULE(CONFIG_SND_SOC_DAVINCI_MCASP) && \
2084 IS_MODULE(CONFIG_SND_SDMA_SOC)) 2165 IS_MODULE(CONFIG_SND_SOC_TI_SDMA_PCM))
2085 ret = sdma_pcm_platform_register(&pdev->dev, NULL, NULL); 2166 ret = sdma_pcm_platform_register(&pdev->dev, NULL, NULL);
2086#else 2167#else
2087 dev_err(&pdev->dev, "Missing SND_SDMA_SOC\n"); 2168 dev_err(&pdev->dev, "Missing SND_SDMA_SOC\n");
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/ti/davinci-mcasp.h
index afddc8010c54..5e4060d8fe56 100644
--- a/sound/soc/davinci/davinci-mcasp.h
+++ b/sound/soc/ti/davinci-mcasp.h
@@ -108,27 +108,18 @@
108 108
109/* 109/*
110 * DAVINCI_MCASP_PFUNC_REG - Pin Function / GPIO Enable Register Bits 110 * DAVINCI_MCASP_PFUNC_REG - Pin Function / GPIO Enable Register Bits
111 */
112#define AXR(n) (1<<n)
113#define PFUNC_AMUTE BIT(25)
114#define ACLKX BIT(26)
115#define AHCLKX BIT(27)
116#define AFSX BIT(28)
117#define ACLKR BIT(29)
118#define AHCLKR BIT(30)
119#define AFSR BIT(31)
120
121/*
122 * DAVINCI_MCASP_PDIR_REG - Pin Direction Register Bits 111 * DAVINCI_MCASP_PDIR_REG - Pin Direction Register Bits
112 * DAVINCI_MCASP_PDOUT_REG - Pin output in GPIO mode
113 * DAVINCI_MCASP_PDSET_REG - Pin input in GPIO mode
123 */ 114 */
124#define AXR(n) (1<<n) 115#define PIN_BIT_AXR(n) (n)
125#define PDIR_AMUTE BIT(25) 116#define PIN_BIT_AMUTE 25
126#define ACLKX BIT(26) 117#define PIN_BIT_ACLKX 26
127#define AHCLKX BIT(27) 118#define PIN_BIT_AHCLKX 27
128#define AFSX BIT(28) 119#define PIN_BIT_AFSX 28
129#define ACLKR BIT(29) 120#define PIN_BIT_ACLKR 29
130#define AHCLKR BIT(30) 121#define PIN_BIT_AHCLKR 30
131#define AFSR BIT(31) 122#define PIN_BIT_AFSR 31
132 123
133/* 124/*
134 * DAVINCI_MCASP_TXDITCTL_REG - Transmit DIT Control Register Bits 125 * DAVINCI_MCASP_TXDITCTL_REG - Transmit DIT Control Register Bits
@@ -218,6 +209,7 @@
218#define DISMOD_3STATE (0x0) 209#define DISMOD_3STATE (0x0)
219#define DISMOD_LOW (0x2 << 2) 210#define DISMOD_LOW (0x2 << 2)
220#define DISMOD_HIGH (0x3 << 2) 211#define DISMOD_HIGH (0x3 << 2)
212#define DISMOD_VAL(x) ((x) << 2)
221#define DISMOD_MASK DISMOD_HIGH 213#define DISMOD_MASK DISMOD_HIGH
222#define TXSTATE BIT(4) 214#define TXSTATE BIT(4)
223#define RXSTATE BIT(5) 215#define RXSTATE BIT(5)
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/ti/davinci-vcif.c
index 5415b72393fa..5415b72393fa 100644
--- a/sound/soc/davinci/davinci-vcif.c
+++ b/sound/soc/ti/davinci-vcif.c
diff --git a/sound/soc/davinci/edma-pcm.c b/sound/soc/ti/edma-pcm.c
index 59e588abe54b..59e588abe54b 100644
--- a/sound/soc/davinci/edma-pcm.c
+++ b/sound/soc/ti/edma-pcm.c
diff --git a/sound/soc/davinci/edma-pcm.h b/sound/soc/ti/edma-pcm.h
index b0957744851c..8058bdb0f032 100644
--- a/sound/soc/davinci/edma-pcm.h
+++ b/sound/soc/ti/edma-pcm.h
@@ -20,13 +20,13 @@
20#ifndef __EDMA_PCM_H__ 20#ifndef __EDMA_PCM_H__
21#define __EDMA_PCM_H__ 21#define __EDMA_PCM_H__
22 22
23#if IS_ENABLED(CONFIG_SND_EDMA_SOC) 23#if IS_ENABLED(CONFIG_SND_SOC_TI_EDMA_PCM)
24int edma_pcm_platform_register(struct device *dev); 24int edma_pcm_platform_register(struct device *dev);
25#else 25#else
26static inline int edma_pcm_platform_register(struct device *dev) 26static inline int edma_pcm_platform_register(struct device *dev)
27{ 27{
28 return 0; 28 return 0;
29} 29}
30#endif /* CONFIG_SND_EDMA_SOC */ 30#endif /* CONFIG_SND_SOC_TI_EDMA_PCM */
31 31
32#endif /* __EDMA_PCM_H__ */ 32#endif /* __EDMA_PCM_H__ */
diff --git a/sound/soc/omap/n810.c b/sound/soc/ti/n810.c
index 9cfefe44a75f..9cfefe44a75f 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/ti/n810.c
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/ti/omap-abe-twl6040.c
index fed45b41f9d3..fed45b41f9d3 100644
--- a/sound/soc/omap/omap-abe-twl6040.c
+++ b/sound/soc/ti/omap-abe-twl6040.c
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/ti/omap-dmic.c
index cba9645b6487..cba9645b6487 100644
--- a/sound/soc/omap/omap-dmic.c
+++ b/sound/soc/ti/omap-dmic.c
diff --git a/sound/soc/omap/omap-dmic.h b/sound/soc/ti/omap-dmic.h
index 231e728bff0e..231e728bff0e 100644
--- a/sound/soc/omap/omap-dmic.h
+++ b/sound/soc/ti/omap-dmic.h
diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/ti/omap-hdmi.c
index 673a9eb153b2..673a9eb153b2 100644
--- a/sound/soc/omap/omap-hdmi-audio.c
+++ b/sound/soc/ti/omap-hdmi.c
diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/ti/omap-mcbsp-priv.h
index 46ae1269a698..7865cda4bf0a 100644
--- a/sound/soc/omap/mcbsp.h
+++ b/sound/soc/ti/omap-mcbsp-priv.h
@@ -1,28 +1,15 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/* 2/*
2 * sound/soc/omap/mcbsp.h
3 *
4 * OMAP Multi-Channel Buffered Serial Port 3 * OMAP Multi-Channel Buffered Serial Port
5 * 4 *
6 * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com> 5 * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
7 * Peter Ujfalusi <peter.ujfalusi@ti.com> 6 * Peter Ujfalusi <peter.ujfalusi@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */ 7 */
24#ifndef __ASOC_MCBSP_H 8
25#define __ASOC_MCBSP_H 9#ifndef __OMAP_MCBSP_PRIV_H__
10#define __OMAP_MCBSP_PRIV_H__
11
12#include <linux/platform_data/asoc-ti-mcbsp.h>
26 13
27#ifdef CONFIG_ARCH_OMAP1 14#ifdef CONFIG_ARCH_OMAP1
28#define mcbsp_omap1() 1 15#define mcbsp_omap1() 1
@@ -30,8 +17,6 @@
30#define mcbsp_omap1() 0 17#define mcbsp_omap1() 0
31#endif 18#endif
32 19
33#include <sound/dmaengine_pcm.h>
34
35/* McBSP register numbers. Register address offset = num * reg_step */ 20/* McBSP register numbers. Register address offset = num * reg_step */
36enum { 21enum {
37 /* Common registers */ 22 /* Common registers */
@@ -85,15 +70,6 @@ enum {
85 OMAP_MCBSP_REG_SSELCR, 70 OMAP_MCBSP_REG_SSELCR,
86}; 71};
87 72
88/* OMAP3 sidetone control registers */
89#define OMAP_ST_REG_REV 0x00
90#define OMAP_ST_REG_SYSCONFIG 0x10
91#define OMAP_ST_REG_IRQSTATUS 0x18
92#define OMAP_ST_REG_IRQENABLE 0x1C
93#define OMAP_ST_REG_SGAINCR 0x24
94#define OMAP_ST_REG_SFIRCR 0x28
95#define OMAP_ST_REG_SSELCR 0x2C
96
97/************************** McBSP SPCR1 bit definitions ***********************/ 73/************************** McBSP SPCR1 bit definitions ***********************/
98#define RRST BIT(0) 74#define RRST BIT(0)
99#define RRDY BIT(1) 75#define RRDY BIT(1)
@@ -202,24 +178,6 @@ enum {
202#define SIDLEMODE(value) (((value) & 0x3) << 3) 178#define SIDLEMODE(value) (((value) & 0x3) << 3)
203#define CLOCKACTIVITY(value) (((value) & 0x3) << 8) 179#define CLOCKACTIVITY(value) (((value) & 0x3) << 8)
204 180
205/********************** McBSP SSELCR bit definitions ***********************/
206#define SIDETONEEN BIT(10)
207
208/********************** McBSP Sidetone SYSCONFIG bit definitions ***********/
209#define ST_AUTOIDLE BIT(0)
210
211/********************** McBSP Sidetone SGAINCR bit definitions *************/
212#define ST_CH0GAIN(value) ((value) & 0xffff) /* Bits 0:15 */
213#define ST_CH1GAIN(value) (((value) & 0xffff) << 16) /* Bits 16:31 */
214
215/********************** McBSP Sidetone SFIRCR bit definitions **************/
216#define ST_FIRCOEFF(value) ((value) & 0xffff) /* Bits 0:15 */
217
218/********************** McBSP Sidetone SSELCR bit definitions **************/
219#define ST_SIDETONEEN BIT(0)
220#define ST_COEFFWREN BIT(1)
221#define ST_COEFFWRDONE BIT(2)
222
223/********************** McBSP DMA operating modes **************************/ 181/********************** McBSP DMA operating modes **************************/
224#define MCBSP_DMA_MODE_ELEMENT 0 182#define MCBSP_DMA_MODE_ELEMENT 0
225#define MCBSP_DMA_MODE_THRESHOLD 1 183#define MCBSP_DMA_MODE_THRESHOLD 1
@@ -278,16 +236,7 @@ struct omap_mcbsp_reg_cfg {
278 u16 rccr; 236 u16 rccr;
279}; 237};
280 238
281struct omap_mcbsp_st_data { 239struct omap_mcbsp_st_data;
282 void __iomem *io_base_st;
283 struct clk *mcbsp_iclk;
284 bool running;
285 bool enabled;
286 s16 taps[128]; /* Sidetone filter coefficients */
287 int nr_taps; /* Number of filter coefficients in use */
288 s16 ch0gain;
289 s16 ch1gain;
290};
291 240
292struct omap_mcbsp { 241struct omap_mcbsp {
293 struct device *dev; 242 struct device *dev;
@@ -330,29 +279,46 @@ struct omap_mcbsp {
330 struct pm_qos_request pm_qos_req; 279 struct pm_qos_request pm_qos_req;
331}; 280};
332 281
333void omap_mcbsp_config(struct omap_mcbsp *mcbsp, 282static inline void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
334 const struct omap_mcbsp_reg_cfg *config); 283{
335void omap_mcbsp_set_tx_threshold(struct omap_mcbsp *mcbsp, u16 threshold); 284 void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step;
336void omap_mcbsp_set_rx_threshold(struct omap_mcbsp *mcbsp, u16 threshold); 285
337u16 omap_mcbsp_get_tx_delay(struct omap_mcbsp *mcbsp); 286 if (mcbsp->pdata->reg_size == 2) {
338u16 omap_mcbsp_get_rx_delay(struct omap_mcbsp *mcbsp); 287 ((u16 *)mcbsp->reg_cache)[reg] = (u16)val;
339int omap_mcbsp_get_dma_op_mode(struct omap_mcbsp *mcbsp); 288 writew_relaxed((u16)val, addr);
340int omap_mcbsp_request(struct omap_mcbsp *mcbsp); 289 } else {
341void omap_mcbsp_free(struct omap_mcbsp *mcbsp); 290 ((u32 *)mcbsp->reg_cache)[reg] = val;
342void omap_mcbsp_start(struct omap_mcbsp *mcbsp, int tx, int rx); 291 writel_relaxed(val, addr);
343void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx); 292 }
344 293}
345/* McBSP functional clock source changing function */ 294
346int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id); 295static inline int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg,
296 bool from_cache)
297{
298 void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step;
299
300 if (mcbsp->pdata->reg_size == 2) {
301 return !from_cache ? readw_relaxed(addr) :
302 ((u16 *)mcbsp->reg_cache)[reg];
303 } else {
304 return !from_cache ? readl_relaxed(addr) :
305 ((u32 *)mcbsp->reg_cache)[reg];
306 }
307}
308
309#define MCBSP_READ(mcbsp, reg) \
310 omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 0)
311#define MCBSP_WRITE(mcbsp, reg, val) \
312 omap_mcbsp_write(mcbsp, OMAP_MCBSP_REG_##reg, val)
313#define MCBSP_READ_CACHE(mcbsp, reg) \
314 omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1)
315
347 316
348/* Sidetone specific API */ 317/* Sidetone specific API */
349int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain); 318int omap_mcbsp_st_init(struct platform_device *pdev);
350int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain); 319void omap_mcbsp_st_cleanup(struct platform_device *pdev);
351int omap_st_enable(struct omap_mcbsp *mcbsp);
352int omap_st_disable(struct omap_mcbsp *mcbsp);
353int omap_st_is_enabled(struct omap_mcbsp *mcbsp);
354 320
355int omap_mcbsp_init(struct platform_device *pdev); 321int omap_mcbsp_st_start(struct omap_mcbsp *mcbsp);
356void omap_mcbsp_cleanup(struct omap_mcbsp *mcbsp); 322int omap_mcbsp_st_stop(struct omap_mcbsp *mcbsp);
357 323
358#endif /* __ASOC_MCBSP_H */ 324#endif /* __OMAP_MCBSP_PRIV_H__ */
diff --git a/sound/soc/ti/omap-mcbsp-st.c b/sound/soc/ti/omap-mcbsp-st.c
new file mode 100644
index 000000000000..1a3fe854e856
--- /dev/null
+++ b/sound/soc/ti/omap-mcbsp-st.c
@@ -0,0 +1,516 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * McBSP Sidetone support
4 *
5 * Copyright (C) 2004 Nokia Corporation
6 * Author: Samuel Ortiz <samuel.ortiz@nokia.com>
7 *
8 * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
9 * Peter Ujfalusi <peter.ujfalusi@ti.com>
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/device.h>
15#include <linux/platform_device.h>
16#include <linux/interrupt.h>
17#include <linux/err.h>
18#include <linux/clk.h>
19#include <linux/delay.h>
20#include <linux/io.h>
21#include <linux/slab.h>
22#include <linux/pm_runtime.h>
23
24#include "omap-mcbsp.h"
25#include "omap-mcbsp-priv.h"
26
27/* OMAP3 sidetone control registers */
28#define OMAP_ST_REG_REV 0x00
29#define OMAP_ST_REG_SYSCONFIG 0x10
30#define OMAP_ST_REG_IRQSTATUS 0x18
31#define OMAP_ST_REG_IRQENABLE 0x1C
32#define OMAP_ST_REG_SGAINCR 0x24
33#define OMAP_ST_REG_SFIRCR 0x28
34#define OMAP_ST_REG_SSELCR 0x2C
35
36/********************** McBSP SSELCR bit definitions ***********************/
37#define SIDETONEEN BIT(10)
38
39/********************** McBSP Sidetone SYSCONFIG bit definitions ***********/
40#define ST_AUTOIDLE BIT(0)
41
42/********************** McBSP Sidetone SGAINCR bit definitions *************/
43#define ST_CH0GAIN(value) ((value) & 0xffff) /* Bits 0:15 */
44#define ST_CH1GAIN(value) (((value) & 0xffff) << 16) /* Bits 16:31 */
45
46/********************** McBSP Sidetone SFIRCR bit definitions **************/
47#define ST_FIRCOEFF(value) ((value) & 0xffff) /* Bits 0:15 */
48
49/********************** McBSP Sidetone SSELCR bit definitions **************/
50#define ST_SIDETONEEN BIT(0)
51#define ST_COEFFWREN BIT(1)
52#define ST_COEFFWRDONE BIT(2)
53
54struct omap_mcbsp_st_data {
55 void __iomem *io_base_st;
56 struct clk *mcbsp_iclk;
57 bool running;
58 bool enabled;
59 s16 taps[128]; /* Sidetone filter coefficients */
60 int nr_taps; /* Number of filter coefficients in use */
61 s16 ch0gain;
62 s16 ch1gain;
63};
64
65static void omap_mcbsp_st_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
66{
67 writel_relaxed(val, mcbsp->st_data->io_base_st + reg);
68}
69
70static int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
71{
72 return readl_relaxed(mcbsp->st_data->io_base_st + reg);
73}
74
75#define MCBSP_ST_READ(mcbsp, reg) omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg)
76#define MCBSP_ST_WRITE(mcbsp, reg, val) \
77 omap_mcbsp_st_write(mcbsp, OMAP_ST_REG_##reg, val)
78
79static void omap_mcbsp_st_on(struct omap_mcbsp *mcbsp)
80{
81 unsigned int w;
82
83 if (mcbsp->pdata->force_ick_on)
84 mcbsp->pdata->force_ick_on(mcbsp->st_data->mcbsp_iclk, true);
85
86 /* Disable Sidetone clock auto-gating for normal operation */
87 w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
88 MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w & ~(ST_AUTOIDLE));
89
90 /* Enable McBSP Sidetone */
91 w = MCBSP_READ(mcbsp, SSELCR);
92 MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN);
93
94 /* Enable Sidetone from Sidetone Core */
95 w = MCBSP_ST_READ(mcbsp, SSELCR);
96 MCBSP_ST_WRITE(mcbsp, SSELCR, w | ST_SIDETONEEN);
97}
98
99static void omap_mcbsp_st_off(struct omap_mcbsp *mcbsp)
100{
101 unsigned int w;
102
103 w = MCBSP_ST_READ(mcbsp, SSELCR);
104 MCBSP_ST_WRITE(mcbsp, SSELCR, w & ~(ST_SIDETONEEN));
105
106 w = MCBSP_READ(mcbsp, SSELCR);
107 MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN));
108
109 /* Enable Sidetone clock auto-gating to reduce power consumption */
110 w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
111 MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w | ST_AUTOIDLE);
112
113 if (mcbsp->pdata->force_ick_on)
114 mcbsp->pdata->force_ick_on(mcbsp->st_data->mcbsp_iclk, false);
115}
116
117static void omap_mcbsp_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
118{
119 u16 val, i;
120
121 val = MCBSP_ST_READ(mcbsp, SSELCR);
122
123 if (val & ST_COEFFWREN)
124 MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));
125
126 MCBSP_ST_WRITE(mcbsp, SSELCR, val | ST_COEFFWREN);
127
128 for (i = 0; i < 128; i++)
129 MCBSP_ST_WRITE(mcbsp, SFIRCR, fir[i]);
130
131 i = 0;
132
133 val = MCBSP_ST_READ(mcbsp, SSELCR);
134 while (!(val & ST_COEFFWRDONE) && (++i < 1000))
135 val = MCBSP_ST_READ(mcbsp, SSELCR);
136
137 MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));
138
139 if (i == 1000)
140 dev_err(mcbsp->dev, "McBSP FIR load error!\n");
141}
142
143static void omap_mcbsp_st_chgain(struct omap_mcbsp *mcbsp)
144{
145 u16 w;
146 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
147
148 w = MCBSP_ST_READ(mcbsp, SSELCR);
149
150 MCBSP_ST_WRITE(mcbsp, SGAINCR, ST_CH0GAIN(st_data->ch0gain) |
151 ST_CH1GAIN(st_data->ch1gain));
152}
153
154static int omap_mcbsp_st_set_chgain(struct omap_mcbsp *mcbsp, int channel,
155 s16 chgain)
156{
157 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
158 int ret = 0;
159
160 if (!st_data)
161 return -ENOENT;
162
163 spin_lock_irq(&mcbsp->lock);
164 if (channel == 0)
165 st_data->ch0gain = chgain;
166 else if (channel == 1)
167 st_data->ch1gain = chgain;
168 else
169 ret = -EINVAL;
170
171 if (st_data->enabled)
172 omap_mcbsp_st_chgain(mcbsp);
173 spin_unlock_irq(&mcbsp->lock);
174
175 return ret;
176}
177
178static int omap_mcbsp_st_get_chgain(struct omap_mcbsp *mcbsp, int channel,
179 s16 *chgain)
180{
181 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
182 int ret = 0;
183
184 if (!st_data)
185 return -ENOENT;
186
187 spin_lock_irq(&mcbsp->lock);
188 if (channel == 0)
189 *chgain = st_data->ch0gain;
190 else if (channel == 1)
191 *chgain = st_data->ch1gain;
192 else
193 ret = -EINVAL;
194 spin_unlock_irq(&mcbsp->lock);
195
196 return ret;
197}
198
199static int omap_mcbsp_st_enable(struct omap_mcbsp *mcbsp)
200{
201 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
202
203 if (!st_data)
204 return -ENODEV;
205
206 spin_lock_irq(&mcbsp->lock);
207 st_data->enabled = 1;
208 omap_mcbsp_st_start(mcbsp);
209 spin_unlock_irq(&mcbsp->lock);
210
211 return 0;
212}
213
214static int omap_mcbsp_st_disable(struct omap_mcbsp *mcbsp)
215{
216 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
217 int ret = 0;
218
219 if (!st_data)
220 return -ENODEV;
221
222 spin_lock_irq(&mcbsp->lock);
223 omap_mcbsp_st_stop(mcbsp);
224 st_data->enabled = 0;
225 spin_unlock_irq(&mcbsp->lock);
226
227 return ret;
228}
229
230static int omap_mcbsp_st_is_enabled(struct omap_mcbsp *mcbsp)
231{
232 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
233
234 if (!st_data)
235 return -ENODEV;
236
237 return st_data->enabled;
238}
239
240static ssize_t st_taps_show(struct device *dev,
241 struct device_attribute *attr, char *buf)
242{
243 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
244 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
245 ssize_t status = 0;
246 int i;
247
248 spin_lock_irq(&mcbsp->lock);
249 for (i = 0; i < st_data->nr_taps; i++)
250 status += sprintf(&buf[status], (i ? ", %d" : "%d"),
251 st_data->taps[i]);
252 if (i)
253 status += sprintf(&buf[status], "\n");
254 spin_unlock_irq(&mcbsp->lock);
255
256 return status;
257}
258
259static ssize_t st_taps_store(struct device *dev,
260 struct device_attribute *attr,
261 const char *buf, size_t size)
262{
263 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
264 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
265 int val, tmp, status, i = 0;
266
267 spin_lock_irq(&mcbsp->lock);
268 memset(st_data->taps, 0, sizeof(st_data->taps));
269 st_data->nr_taps = 0;
270
271 do {
272 status = sscanf(buf, "%d%n", &val, &tmp);
273 if (status < 0 || status == 0) {
274 size = -EINVAL;
275 goto out;
276 }
277 if (val < -32768 || val > 32767) {
278 size = -EINVAL;
279 goto out;
280 }
281 st_data->taps[i++] = val;
282 buf += tmp;
283 if (*buf != ',')
284 break;
285 buf++;
286 } while (1);
287
288 st_data->nr_taps = i;
289
290out:
291 spin_unlock_irq(&mcbsp->lock);
292
293 return size;
294}
295
296static DEVICE_ATTR_RW(st_taps);
297
298static const struct attribute *sidetone_attrs[] = {
299 &dev_attr_st_taps.attr,
300 NULL,
301};
302
303static const struct attribute_group sidetone_attr_group = {
304 .attrs = (struct attribute **)sidetone_attrs,
305};
306
307int omap_mcbsp_st_start(struct omap_mcbsp *mcbsp)
308{
309 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
310
311 if (st_data->enabled && !st_data->running) {
312 omap_mcbsp_st_fir_write(mcbsp, st_data->taps);
313 omap_mcbsp_st_chgain(mcbsp);
314
315 if (!mcbsp->free) {
316 omap_mcbsp_st_on(mcbsp);
317 st_data->running = 1;
318 }
319 }
320
321 return 0;
322}
323
324int omap_mcbsp_st_stop(struct omap_mcbsp *mcbsp)
325{
326 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
327
328 if (st_data->running) {
329 if (!mcbsp->free) {
330 omap_mcbsp_st_off(mcbsp);
331 st_data->running = 0;
332 }
333 }
334
335 return 0;
336}
337
338int omap_mcbsp_st_init(struct platform_device *pdev)
339{
340 struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
341 struct omap_mcbsp_st_data *st_data;
342 struct resource *res;
343 int ret;
344
345 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sidetone");
346 if (!res)
347 return 0;
348
349 st_data = devm_kzalloc(mcbsp->dev, sizeof(*mcbsp->st_data), GFP_KERNEL);
350 if (!st_data)
351 return -ENOMEM;
352
353 st_data->mcbsp_iclk = clk_get(mcbsp->dev, "ick");
354 if (IS_ERR(st_data->mcbsp_iclk)) {
355 dev_warn(mcbsp->dev,
356 "Failed to get ick, sidetone might be broken\n");
357 st_data->mcbsp_iclk = NULL;
358 }
359
360 st_data->io_base_st = devm_ioremap(mcbsp->dev, res->start,
361 resource_size(res));
362 if (!st_data->io_base_st)
363 return -ENOMEM;
364
365 ret = sysfs_create_group(&mcbsp->dev->kobj, &sidetone_attr_group);
366 if (ret)
367 return ret;
368
369 mcbsp->st_data = st_data;
370
371 return 0;
372}
373
374void omap_mcbsp_st_cleanup(struct platform_device *pdev)
375{
376 struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
377
378 if (mcbsp->st_data) {
379 sysfs_remove_group(&mcbsp->dev->kobj, &sidetone_attr_group);
380 clk_put(mcbsp->st_data->mcbsp_iclk);
381 }
382}
383
384static int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol,
385 struct snd_ctl_elem_info *uinfo)
386{
387 struct soc_mixer_control *mc =
388 (struct soc_mixer_control *)kcontrol->private_value;
389 int max = mc->max;
390 int min = mc->min;
391
392 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
393 uinfo->count = 1;
394 uinfo->value.integer.min = min;
395 uinfo->value.integer.max = max;
396 return 0;
397}
398
399#define OMAP_MCBSP_ST_CHANNEL_VOLUME(channel) \
400static int \
401omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \
402 struct snd_ctl_elem_value *uc) \
403{ \
404 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \
405 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); \
406 struct soc_mixer_control *mc = \
407 (struct soc_mixer_control *)kc->private_value; \
408 int max = mc->max; \
409 int min = mc->min; \
410 int val = uc->value.integer.value[0]; \
411 \
412 if (val < min || val > max) \
413 return -EINVAL; \
414 \
415 /* OMAP McBSP implementation uses index values 0..4 */ \
416 return omap_mcbsp_st_set_chgain(mcbsp, channel, val); \
417} \
418 \
419static int \
420omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \
421 struct snd_ctl_elem_value *uc) \
422{ \
423 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \
424 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); \
425 s16 chgain; \
426 \
427 if (omap_mcbsp_st_get_chgain(mcbsp, channel, &chgain)) \
428 return -EAGAIN; \
429 \
430 uc->value.integer.value[0] = chgain; \
431 return 0; \
432}
433
434OMAP_MCBSP_ST_CHANNEL_VOLUME(0)
435OMAP_MCBSP_ST_CHANNEL_VOLUME(1)
436
437static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol,
438 struct snd_ctl_elem_value *ucontrol)
439{
440 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
441 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
442 u8 value = ucontrol->value.integer.value[0];
443
444 if (value == omap_mcbsp_st_is_enabled(mcbsp))
445 return 0;
446
447 if (value)
448 omap_mcbsp_st_enable(mcbsp);
449 else
450 omap_mcbsp_st_disable(mcbsp);
451
452 return 1;
453}
454
455static int omap_mcbsp_st_get_mode(struct snd_kcontrol *kcontrol,
456 struct snd_ctl_elem_value *ucontrol)
457{
458 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
459 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
460
461 ucontrol->value.integer.value[0] = omap_mcbsp_st_is_enabled(mcbsp);
462 return 0;
463}
464
465#define OMAP_MCBSP_SOC_SINGLE_S16_EXT(xname, xmin, xmax, \
466 xhandler_get, xhandler_put) \
467{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
468 .info = omap_mcbsp_st_info_volsw, \
469 .get = xhandler_get, .put = xhandler_put, \
470 .private_value = (unsigned long)&(struct soc_mixer_control) \
471 {.min = xmin, .max = xmax} }
472
473#define OMAP_MCBSP_ST_CONTROLS(port) \
474static const struct snd_kcontrol_new omap_mcbsp##port##_st_controls[] = { \
475SOC_SINGLE_EXT("McBSP" #port " Sidetone Switch", 1, 0, 1, 0, \
476 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode), \
477OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 0 Volume", \
478 -32768, 32767, \
479 omap_mcbsp_get_st_ch0_volume, \
480 omap_mcbsp_set_st_ch0_volume), \
481OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 1 Volume", \
482 -32768, 32767, \
483 omap_mcbsp_get_st_ch1_volume, \
484 omap_mcbsp_set_st_ch1_volume), \
485}
486
487OMAP_MCBSP_ST_CONTROLS(2);
488OMAP_MCBSP_ST_CONTROLS(3);
489
490int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd, int port_id)
491{
492 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
493 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
494
495 if (!mcbsp->st_data) {
496 dev_warn(mcbsp->dev, "No sidetone data for port\n");
497 return 0;
498 }
499
500 switch (port_id) {
501 case 2: /* McBSP 2 */
502 return snd_soc_add_dai_controls(cpu_dai,
503 omap_mcbsp2_st_controls,
504 ARRAY_SIZE(omap_mcbsp2_st_controls));
505 case 3: /* McBSP 3 */
506 return snd_soc_add_dai_controls(cpu_dai,
507 omap_mcbsp3_st_controls,
508 ARRAY_SIZE(omap_mcbsp3_st_controls));
509 default:
510 dev_err(mcbsp->dev, "Port %d not supported\n", port_id);
511 break;
512 }
513
514 return -EINVAL;
515}
516EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls);
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/ti/omap-mcbsp.c
index 2d6decbfc99e..a395598f1f20 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/ti/omap-mcbsp.c
@@ -35,21 +35,12 @@
35#include <sound/soc.h> 35#include <sound/soc.h>
36#include <sound/dmaengine_pcm.h> 36#include <sound/dmaengine_pcm.h>
37 37
38#include <linux/platform_data/asoc-ti-mcbsp.h> 38#include "omap-mcbsp-priv.h"
39#include "mcbsp.h"
40#include "omap-mcbsp.h" 39#include "omap-mcbsp.h"
41#include "sdma-pcm.h" 40#include "sdma-pcm.h"
42 41
43#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000) 42#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000)
44 43
45#define OMAP_MCBSP_SOC_SINGLE_S16_EXT(xname, xmin, xmax, \
46 xhandler_get, xhandler_put) \
47{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
48 .info = omap_mcbsp_st_info_volsw, \
49 .get = xhandler_get, .put = xhandler_put, \
50 .private_value = (unsigned long) &(struct soc_mixer_control) \
51 {.min = xmin, .max = xmax} }
52
53enum { 44enum {
54 OMAP_MCBSP_WORD_8 = 0, 45 OMAP_MCBSP_WORD_8 = 0,
55 OMAP_MCBSP_WORD_12, 46 OMAP_MCBSP_WORD_12,
@@ -59,6 +50,699 @@ enum {
59 OMAP_MCBSP_WORD_32, 50 OMAP_MCBSP_WORD_32,
60}; 51};
61 52
53static void omap_mcbsp_dump_reg(struct omap_mcbsp *mcbsp)
54{
55 dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id);
56 dev_dbg(mcbsp->dev, "DRR2: 0x%04x\n", MCBSP_READ(mcbsp, DRR2));
57 dev_dbg(mcbsp->dev, "DRR1: 0x%04x\n", MCBSP_READ(mcbsp, DRR1));
58 dev_dbg(mcbsp->dev, "DXR2: 0x%04x\n", MCBSP_READ(mcbsp, DXR2));
59 dev_dbg(mcbsp->dev, "DXR1: 0x%04x\n", MCBSP_READ(mcbsp, DXR1));
60 dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n", MCBSP_READ(mcbsp, SPCR2));
61 dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n", MCBSP_READ(mcbsp, SPCR1));
62 dev_dbg(mcbsp->dev, "RCR2: 0x%04x\n", MCBSP_READ(mcbsp, RCR2));
63 dev_dbg(mcbsp->dev, "RCR1: 0x%04x\n", MCBSP_READ(mcbsp, RCR1));
64 dev_dbg(mcbsp->dev, "XCR2: 0x%04x\n", MCBSP_READ(mcbsp, XCR2));
65 dev_dbg(mcbsp->dev, "XCR1: 0x%04x\n", MCBSP_READ(mcbsp, XCR1));
66 dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n", MCBSP_READ(mcbsp, SRGR2));
67 dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n", MCBSP_READ(mcbsp, SRGR1));
68 dev_dbg(mcbsp->dev, "PCR0: 0x%04x\n", MCBSP_READ(mcbsp, PCR0));
69 dev_dbg(mcbsp->dev, "***********************\n");
70}
71
72static int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id)
73{
74 struct clk *fck_src;
75 const char *src;
76 int r;
77
78 if (fck_src_id == MCBSP_CLKS_PAD_SRC)
79 src = "pad_fck";
80 else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
81 src = "prcm_fck";
82 else
83 return -EINVAL;
84
85 fck_src = clk_get(mcbsp->dev, src);
86 if (IS_ERR(fck_src)) {
87 dev_err(mcbsp->dev, "CLKS: could not clk_get() %s\n", src);
88 return -EINVAL;
89 }
90
91 pm_runtime_put_sync(mcbsp->dev);
92
93 r = clk_set_parent(mcbsp->fclk, fck_src);
94 if (r) {
95 dev_err(mcbsp->dev, "CLKS: could not clk_set_parent() to %s\n",
96 src);
97 clk_put(fck_src);
98 return r;
99 }
100
101 pm_runtime_get_sync(mcbsp->dev);
102
103 clk_put(fck_src);
104
105 return 0;
106}
107
108static irqreturn_t omap_mcbsp_irq_handler(int irq, void *data)
109{
110 struct omap_mcbsp *mcbsp = data;
111 u16 irqst;
112
113 irqst = MCBSP_READ(mcbsp, IRQST);
114 dev_dbg(mcbsp->dev, "IRQ callback : 0x%x\n", irqst);
115
116 if (irqst & RSYNCERREN)
117 dev_err(mcbsp->dev, "RX Frame Sync Error!\n");
118 if (irqst & RFSREN)
119 dev_dbg(mcbsp->dev, "RX Frame Sync\n");
120 if (irqst & REOFEN)
121 dev_dbg(mcbsp->dev, "RX End Of Frame\n");
122 if (irqst & RRDYEN)
123 dev_dbg(mcbsp->dev, "RX Buffer Threshold Reached\n");
124 if (irqst & RUNDFLEN)
125 dev_err(mcbsp->dev, "RX Buffer Underflow!\n");
126 if (irqst & ROVFLEN)
127 dev_err(mcbsp->dev, "RX Buffer Overflow!\n");
128
129 if (irqst & XSYNCERREN)
130 dev_err(mcbsp->dev, "TX Frame Sync Error!\n");
131 if (irqst & XFSXEN)
132 dev_dbg(mcbsp->dev, "TX Frame Sync\n");
133 if (irqst & XEOFEN)
134 dev_dbg(mcbsp->dev, "TX End Of Frame\n");
135 if (irqst & XRDYEN)
136 dev_dbg(mcbsp->dev, "TX Buffer threshold Reached\n");
137 if (irqst & XUNDFLEN)
138 dev_err(mcbsp->dev, "TX Buffer Underflow!\n");
139 if (irqst & XOVFLEN)
140 dev_err(mcbsp->dev, "TX Buffer Overflow!\n");
141 if (irqst & XEMPTYEOFEN)
142 dev_dbg(mcbsp->dev, "TX Buffer empty at end of frame\n");
143
144 MCBSP_WRITE(mcbsp, IRQST, irqst);
145
146 return IRQ_HANDLED;
147}
148
149static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *data)
150{
151 struct omap_mcbsp *mcbsp = data;
152 u16 irqst_spcr2;
153
154 irqst_spcr2 = MCBSP_READ(mcbsp, SPCR2);
155 dev_dbg(mcbsp->dev, "TX IRQ callback : 0x%x\n", irqst_spcr2);
156
157 if (irqst_spcr2 & XSYNC_ERR) {
158 dev_err(mcbsp->dev, "TX Frame Sync Error! : 0x%x\n",
159 irqst_spcr2);
160 /* Writing zero to XSYNC_ERR clears the IRQ */
161 MCBSP_WRITE(mcbsp, SPCR2, MCBSP_READ_CACHE(mcbsp, SPCR2));
162 }
163
164 return IRQ_HANDLED;
165}
166
167static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *data)
168{
169 struct omap_mcbsp *mcbsp = data;
170 u16 irqst_spcr1;
171
172 irqst_spcr1 = MCBSP_READ(mcbsp, SPCR1);
173 dev_dbg(mcbsp->dev, "RX IRQ callback : 0x%x\n", irqst_spcr1);
174
175 if (irqst_spcr1 & RSYNC_ERR) {
176 dev_err(mcbsp->dev, "RX Frame Sync Error! : 0x%x\n",
177 irqst_spcr1);
178 /* Writing zero to RSYNC_ERR clears the IRQ */
179 MCBSP_WRITE(mcbsp, SPCR1, MCBSP_READ_CACHE(mcbsp, SPCR1));
180 }
181
182 return IRQ_HANDLED;
183}
184
185/*
186 * omap_mcbsp_config simply write a config to the
187 * appropriate McBSP.
188 * You either call this function or set the McBSP registers
189 * by yourself before calling omap_mcbsp_start().
190 */
191static void omap_mcbsp_config(struct omap_mcbsp *mcbsp,
192 const struct omap_mcbsp_reg_cfg *config)
193{
194 dev_dbg(mcbsp->dev, "Configuring McBSP%d phys_base: 0x%08lx\n",
195 mcbsp->id, mcbsp->phys_base);
196
197 /* We write the given config */
198 MCBSP_WRITE(mcbsp, SPCR2, config->spcr2);
199 MCBSP_WRITE(mcbsp, SPCR1, config->spcr1);
200 MCBSP_WRITE(mcbsp, RCR2, config->rcr2);
201 MCBSP_WRITE(mcbsp, RCR1, config->rcr1);
202 MCBSP_WRITE(mcbsp, XCR2, config->xcr2);
203 MCBSP_WRITE(mcbsp, XCR1, config->xcr1);
204 MCBSP_WRITE(mcbsp, SRGR2, config->srgr2);
205 MCBSP_WRITE(mcbsp, SRGR1, config->srgr1);
206 MCBSP_WRITE(mcbsp, MCR2, config->mcr2);
207 MCBSP_WRITE(mcbsp, MCR1, config->mcr1);
208 MCBSP_WRITE(mcbsp, PCR0, config->pcr0);
209 if (mcbsp->pdata->has_ccr) {
210 MCBSP_WRITE(mcbsp, XCCR, config->xccr);
211 MCBSP_WRITE(mcbsp, RCCR, config->rccr);
212 }
213 /* Enable wakeup behavior */
214 if (mcbsp->pdata->has_wakeup)
215 MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
216
217 /* Enable TX/RX sync error interrupts by default */
218 if (mcbsp->irq)
219 MCBSP_WRITE(mcbsp, IRQEN, RSYNCERREN | XSYNCERREN |
220 RUNDFLEN | ROVFLEN | XUNDFLEN | XOVFLEN);
221}
222
223/**
224 * omap_mcbsp_dma_reg_params - returns the address of mcbsp data register
225 * @mcbsp: omap_mcbsp struct for the McBSP instance
226 * @stream: Stream direction (playback/capture)
227 *
228 * Returns the address of mcbsp data transmit register or data receive register
229 * to be used by DMA for transferring/receiving data
230 */
231static int omap_mcbsp_dma_reg_params(struct omap_mcbsp *mcbsp,
232 unsigned int stream)
233{
234 int data_reg;
235
236 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
237 if (mcbsp->pdata->reg_size == 2)
238 data_reg = OMAP_MCBSP_REG_DXR1;
239 else
240 data_reg = OMAP_MCBSP_REG_DXR;
241 } else {
242 if (mcbsp->pdata->reg_size == 2)
243 data_reg = OMAP_MCBSP_REG_DRR1;
244 else
245 data_reg = OMAP_MCBSP_REG_DRR;
246 }
247
248 return mcbsp->phys_dma_base + data_reg * mcbsp->pdata->reg_step;
249}
250
251/*
252 * omap_mcbsp_set_rx_threshold configures the transmit threshold in words.
253 * The threshold parameter is 1 based, and it is converted (threshold - 1)
254 * for the THRSH2 register.
255 */
256static void omap_mcbsp_set_tx_threshold(struct omap_mcbsp *mcbsp, u16 threshold)
257{
258 if (threshold && threshold <= mcbsp->max_tx_thres)
259 MCBSP_WRITE(mcbsp, THRSH2, threshold - 1);
260}
261
262/*
263 * omap_mcbsp_set_rx_threshold configures the receive threshold in words.
264 * The threshold parameter is 1 based, and it is converted (threshold - 1)
265 * for the THRSH1 register.
266 */
267static void omap_mcbsp_set_rx_threshold(struct omap_mcbsp *mcbsp, u16 threshold)
268{
269 if (threshold && threshold <= mcbsp->max_rx_thres)
270 MCBSP_WRITE(mcbsp, THRSH1, threshold - 1);
271}
272
273/*
274 * omap_mcbsp_get_tx_delay returns the number of used slots in the McBSP FIFO
275 */
276static u16 omap_mcbsp_get_tx_delay(struct omap_mcbsp *mcbsp)
277{
278 u16 buffstat;
279
280 /* Returns the number of free locations in the buffer */
281 buffstat = MCBSP_READ(mcbsp, XBUFFSTAT);
282
283 /* Number of slots are different in McBSP ports */
284 return mcbsp->pdata->buffer_size - buffstat;
285}
286
287/*
288 * omap_mcbsp_get_rx_delay returns the number of free slots in the McBSP FIFO
289 * to reach the threshold value (when the DMA will be triggered to read it)
290 */
291static u16 omap_mcbsp_get_rx_delay(struct omap_mcbsp *mcbsp)
292{
293 u16 buffstat, threshold;
294
295 /* Returns the number of used locations in the buffer */
296 buffstat = MCBSP_READ(mcbsp, RBUFFSTAT);
297 /* RX threshold */
298 threshold = MCBSP_READ(mcbsp, THRSH1);
299
300 /* Return the number of location till we reach the threshold limit */
301 if (threshold <= buffstat)
302 return 0;
303 else
304 return threshold - buffstat;
305}
306
307static int omap_mcbsp_request(struct omap_mcbsp *mcbsp)
308{
309 void *reg_cache;
310 int err;
311
312 reg_cache = kzalloc(mcbsp->reg_cache_size, GFP_KERNEL);
313 if (!reg_cache)
314 return -ENOMEM;
315
316 spin_lock(&mcbsp->lock);
317 if (!mcbsp->free) {
318 dev_err(mcbsp->dev, "McBSP%d is currently in use\n", mcbsp->id);
319 err = -EBUSY;
320 goto err_kfree;
321 }
322
323 mcbsp->free = false;
324 mcbsp->reg_cache = reg_cache;
325 spin_unlock(&mcbsp->lock);
326
327 if(mcbsp->pdata->ops && mcbsp->pdata->ops->request)
328 mcbsp->pdata->ops->request(mcbsp->id - 1);
329
330 /*
331 * Make sure that transmitter, receiver and sample-rate generator are
332 * not running before activating IRQs.
333 */
334 MCBSP_WRITE(mcbsp, SPCR1, 0);
335 MCBSP_WRITE(mcbsp, SPCR2, 0);
336
337 if (mcbsp->irq) {
338 err = request_irq(mcbsp->irq, omap_mcbsp_irq_handler, 0,
339 "McBSP", (void *)mcbsp);
340 if (err != 0) {
341 dev_err(mcbsp->dev, "Unable to request IRQ\n");
342 goto err_clk_disable;
343 }
344 } else {
345 err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler, 0,
346 "McBSP TX", (void *)mcbsp);
347 if (err != 0) {
348 dev_err(mcbsp->dev, "Unable to request TX IRQ\n");
349 goto err_clk_disable;
350 }
351
352 err = request_irq(mcbsp->rx_irq, omap_mcbsp_rx_irq_handler, 0,
353 "McBSP RX", (void *)mcbsp);
354 if (err != 0) {
355 dev_err(mcbsp->dev, "Unable to request RX IRQ\n");
356 goto err_free_irq;
357 }
358 }
359
360 return 0;
361err_free_irq:
362 free_irq(mcbsp->tx_irq, (void *)mcbsp);
363err_clk_disable:
364 if(mcbsp->pdata->ops && mcbsp->pdata->ops->free)
365 mcbsp->pdata->ops->free(mcbsp->id - 1);
366
367 /* Disable wakeup behavior */
368 if (mcbsp->pdata->has_wakeup)
369 MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
370
371 spin_lock(&mcbsp->lock);
372 mcbsp->free = true;
373 mcbsp->reg_cache = NULL;
374err_kfree:
375 spin_unlock(&mcbsp->lock);
376 kfree(reg_cache);
377
378 return err;
379}
380
381static void omap_mcbsp_free(struct omap_mcbsp *mcbsp)
382{
383 void *reg_cache;
384
385 if(mcbsp->pdata->ops && mcbsp->pdata->ops->free)
386 mcbsp->pdata->ops->free(mcbsp->id - 1);
387
388 /* Disable wakeup behavior */
389 if (mcbsp->pdata->has_wakeup)
390 MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
391
392 /* Disable interrupt requests */
393 if (mcbsp->irq)
394 MCBSP_WRITE(mcbsp, IRQEN, 0);
395
396 if (mcbsp->irq) {
397 free_irq(mcbsp->irq, (void *)mcbsp);
398 } else {
399 free_irq(mcbsp->rx_irq, (void *)mcbsp);
400 free_irq(mcbsp->tx_irq, (void *)mcbsp);
401 }
402
403 reg_cache = mcbsp->reg_cache;
404
405 /*
406 * Select CLKS source from internal source unconditionally before
407 * marking the McBSP port as free.
408 * If the external clock source via MCBSP_CLKS pin has been selected the
409 * system will refuse to enter idle if the CLKS pin source is not reset
410 * back to internal source.
411 */
412 if (!mcbsp_omap1())
413 omap2_mcbsp_set_clks_src(mcbsp, MCBSP_CLKS_PRCM_SRC);
414
415 spin_lock(&mcbsp->lock);
416 if (mcbsp->free)
417 dev_err(mcbsp->dev, "McBSP%d was not reserved\n", mcbsp->id);
418 else
419 mcbsp->free = true;
420 mcbsp->reg_cache = NULL;
421 spin_unlock(&mcbsp->lock);
422
423 kfree(reg_cache);
424}
425
426/*
427 * Here we start the McBSP, by enabling transmitter, receiver or both.
428 * If no transmitter or receiver is active prior calling, then sample-rate
429 * generator and frame sync are started.
430 */
431static void omap_mcbsp_start(struct omap_mcbsp *mcbsp, int stream)
432{
433 int tx = (stream == SNDRV_PCM_STREAM_PLAYBACK);
434 int rx = !tx;
435 int enable_srg = 0;
436 u16 w;
437
438 if (mcbsp->st_data)
439 omap_mcbsp_st_start(mcbsp);
440
441 /* Only enable SRG, if McBSP is master */
442 w = MCBSP_READ_CACHE(mcbsp, PCR0);
443 if (w & (FSXM | FSRM | CLKXM | CLKRM))
444 enable_srg = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
445 MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
446
447 if (enable_srg) {
448 /* Start the sample generator */
449 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
450 MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 6));
451 }
452
453 /* Enable transmitter and receiver */
454 tx &= 1;
455 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
456 MCBSP_WRITE(mcbsp, SPCR2, w | tx);
457
458 rx &= 1;
459 w = MCBSP_READ_CACHE(mcbsp, SPCR1);
460 MCBSP_WRITE(mcbsp, SPCR1, w | rx);
461
462 /*
463 * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec
464 * REVISIT: 100us may give enough time for two CLKSRG, however
465 * due to some unknown PM related, clock gating etc. reason it
466 * is now at 500us.
467 */
468 udelay(500);
469
470 if (enable_srg) {
471 /* Start frame sync */
472 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
473 MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7));
474 }
475
476 if (mcbsp->pdata->has_ccr) {
477 /* Release the transmitter and receiver */
478 w = MCBSP_READ_CACHE(mcbsp, XCCR);
479 w &= ~(tx ? XDISABLE : 0);
480 MCBSP_WRITE(mcbsp, XCCR, w);
481 w = MCBSP_READ_CACHE(mcbsp, RCCR);
482 w &= ~(rx ? RDISABLE : 0);
483 MCBSP_WRITE(mcbsp, RCCR, w);
484 }
485
486 /* Dump McBSP Regs */
487 omap_mcbsp_dump_reg(mcbsp);
488}
489
490static void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int stream)
491{
492 int tx = (stream == SNDRV_PCM_STREAM_PLAYBACK);
493 int rx = !tx;
494 int idle;
495 u16 w;
496
497 /* Reset transmitter */
498 tx &= 1;
499 if (mcbsp->pdata->has_ccr) {
500 w = MCBSP_READ_CACHE(mcbsp, XCCR);
501 w |= (tx ? XDISABLE : 0);
502 MCBSP_WRITE(mcbsp, XCCR, w);
503 }
504 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
505 MCBSP_WRITE(mcbsp, SPCR2, w & ~tx);
506
507 /* Reset receiver */
508 rx &= 1;
509 if (mcbsp->pdata->has_ccr) {
510 w = MCBSP_READ_CACHE(mcbsp, RCCR);
511 w |= (rx ? RDISABLE : 0);
512 MCBSP_WRITE(mcbsp, RCCR, w);
513 }
514 w = MCBSP_READ_CACHE(mcbsp, SPCR1);
515 MCBSP_WRITE(mcbsp, SPCR1, w & ~rx);
516
517 idle = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
518 MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
519
520 if (idle) {
521 /* Reset the sample rate generator */
522 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
523 MCBSP_WRITE(mcbsp, SPCR2, w & ~(1 << 6));
524 }
525
526 if (mcbsp->st_data)
527 omap_mcbsp_st_stop(mcbsp);
528}
529
530#define max_thres(m) (mcbsp->pdata->buffer_size)
531#define valid_threshold(m, val) ((val) <= max_thres(m))
532#define THRESHOLD_PROP_BUILDER(prop) \
533static ssize_t prop##_show(struct device *dev, \
534 struct device_attribute *attr, char *buf) \
535{ \
536 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
537 \
538 return sprintf(buf, "%u\n", mcbsp->prop); \
539} \
540 \
541static ssize_t prop##_store(struct device *dev, \
542 struct device_attribute *attr, \
543 const char *buf, size_t size) \
544{ \
545 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
546 unsigned long val; \
547 int status; \
548 \
549 status = kstrtoul(buf, 0, &val); \
550 if (status) \
551 return status; \
552 \
553 if (!valid_threshold(mcbsp, val)) \
554 return -EDOM; \
555 \
556 mcbsp->prop = val; \
557 return size; \
558} \
559 \
560static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store)
561
562THRESHOLD_PROP_BUILDER(max_tx_thres);
563THRESHOLD_PROP_BUILDER(max_rx_thres);
564
565static const char * const dma_op_modes[] = {
566 "element", "threshold",
567};
568
569static ssize_t dma_op_mode_show(struct device *dev,
570 struct device_attribute *attr, char *buf)
571{
572 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
573 int dma_op_mode, i = 0;
574 ssize_t len = 0;
575 const char * const *s;
576
577 dma_op_mode = mcbsp->dma_op_mode;
578
579 for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) {
580 if (dma_op_mode == i)
581 len += sprintf(buf + len, "[%s] ", *s);
582 else
583 len += sprintf(buf + len, "%s ", *s);
584 }
585 len += sprintf(buf + len, "\n");
586
587 return len;
588}
589
590static ssize_t dma_op_mode_store(struct device *dev,
591 struct device_attribute *attr, const char *buf,
592 size_t size)
593{
594 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
595 int i;
596
597 i = sysfs_match_string(dma_op_modes, buf);
598 if (i < 0)
599 return i;
600
601 spin_lock_irq(&mcbsp->lock);
602 if (!mcbsp->free) {
603 size = -EBUSY;
604 goto unlock;
605 }
606 mcbsp->dma_op_mode = i;
607
608unlock:
609 spin_unlock_irq(&mcbsp->lock);
610
611 return size;
612}
613
614static DEVICE_ATTR_RW(dma_op_mode);
615
616static const struct attribute *additional_attrs[] = {
617 &dev_attr_max_tx_thres.attr,
618 &dev_attr_max_rx_thres.attr,
619 &dev_attr_dma_op_mode.attr,
620 NULL,
621};
622
623static const struct attribute_group additional_attr_group = {
624 .attrs = (struct attribute **)additional_attrs,
625};
626
627/*
628 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
629 * 730 has only 2 McBSP, and both of them are MPU peripherals.
630 */
631static int omap_mcbsp_init(struct platform_device *pdev)
632{
633 struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
634 struct resource *res;
635 int ret = 0;
636
637 spin_lock_init(&mcbsp->lock);
638 mcbsp->free = true;
639
640 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
641 if (!res)
642 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
643
644 mcbsp->io_base = devm_ioremap_resource(&pdev->dev, res);
645 if (IS_ERR(mcbsp->io_base))
646 return PTR_ERR(mcbsp->io_base);
647
648 mcbsp->phys_base = res->start;
649 mcbsp->reg_cache_size = resource_size(res);
650
651 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma");
652 if (!res)
653 mcbsp->phys_dma_base = mcbsp->phys_base;
654 else
655 mcbsp->phys_dma_base = res->start;
656
657 /*
658 * OMAP1, 2 uses two interrupt lines: TX, RX
659 * OMAP2430, OMAP3 SoC have combined IRQ line as well.
660 * OMAP4 and newer SoC only have the combined IRQ line.
661 * Use the combined IRQ if available since it gives better debugging
662 * possibilities.
663 */
664 mcbsp->irq = platform_get_irq_byname(pdev, "common");
665 if (mcbsp->irq == -ENXIO) {
666 mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx");
667
668 if (mcbsp->tx_irq == -ENXIO) {
669 mcbsp->irq = platform_get_irq(pdev, 0);
670 mcbsp->tx_irq = 0;
671 } else {
672 mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx");
673 mcbsp->irq = 0;
674 }
675 }
676
677 if (!pdev->dev.of_node) {
678 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
679 if (!res) {
680 dev_err(&pdev->dev, "invalid tx DMA channel\n");
681 return -ENODEV;
682 }
683 mcbsp->dma_req[0] = res->start;
684 mcbsp->dma_data[0].filter_data = &mcbsp->dma_req[0];
685
686 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
687 if (!res) {
688 dev_err(&pdev->dev, "invalid rx DMA channel\n");
689 return -ENODEV;
690 }
691 mcbsp->dma_req[1] = res->start;
692 mcbsp->dma_data[1].filter_data = &mcbsp->dma_req[1];
693 } else {
694 mcbsp->dma_data[0].filter_data = "tx";
695 mcbsp->dma_data[1].filter_data = "rx";
696 }
697
698 mcbsp->dma_data[0].addr = omap_mcbsp_dma_reg_params(mcbsp,
699 SNDRV_PCM_STREAM_PLAYBACK);
700 mcbsp->dma_data[1].addr = omap_mcbsp_dma_reg_params(mcbsp,
701 SNDRV_PCM_STREAM_CAPTURE);
702
703 mcbsp->fclk = clk_get(&pdev->dev, "fck");
704 if (IS_ERR(mcbsp->fclk)) {
705 ret = PTR_ERR(mcbsp->fclk);
706 dev_err(mcbsp->dev, "unable to get fck: %d\n", ret);
707 return ret;
708 }
709
710 mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
711 if (mcbsp->pdata->buffer_size) {
712 /*
713 * Initially configure the maximum thresholds to a safe value.
714 * The McBSP FIFO usage with these values should not go under
715 * 16 locations.
716 * If the whole FIFO without safety buffer is used, than there
717 * is a possibility that the DMA will be not able to push the
718 * new data on time, causing channel shifts in runtime.
719 */
720 mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10;
721 mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10;
722
723 ret = sysfs_create_group(&mcbsp->dev->kobj,
724 &additional_attr_group);
725 if (ret) {
726 dev_err(mcbsp->dev,
727 "Unable to create additional controls\n");
728 goto err_thres;
729 }
730 }
731
732 ret = omap_mcbsp_st_init(pdev);
733 if (ret)
734 goto err_st;
735
736 return 0;
737
738err_st:
739 if (mcbsp->pdata->buffer_size)
740 sysfs_remove_group(&mcbsp->dev->kobj, &additional_attr_group);
741err_thres:
742 clk_put(mcbsp->fclk);
743 return ret;
744}
745
62/* 746/*
63 * Stream DMA parameters. DMA request line and port address are set runtime 747 * Stream DMA parameters. DMA request line and port address are set runtime
64 * since they are different between OMAP1 and later OMAPs 748 * since they are different between OMAP1 and later OMAPs
@@ -71,6 +755,10 @@ static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream,
71 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); 755 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
72 int words; 756 int words;
73 757
758 /* No need to proceed further if McBSP does not have FIFO */
759 if (mcbsp->pdata->buffer_size == 0)
760 return;
761
74 /* 762 /*
75 * Configure McBSP threshold based on either: 763 * Configure McBSP threshold based on either:
76 * packet_size, when the sDMA is in packet mode, or based on the 764 * packet_size, when the sDMA is in packet mode, or based on the
@@ -201,27 +889,26 @@ static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
201 struct snd_soc_dai *cpu_dai) 889 struct snd_soc_dai *cpu_dai)
202{ 890{
203 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); 891 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
204 int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
205 892
206 switch (cmd) { 893 switch (cmd) {
207 case SNDRV_PCM_TRIGGER_START: 894 case SNDRV_PCM_TRIGGER_START:
208 case SNDRV_PCM_TRIGGER_RESUME: 895 case SNDRV_PCM_TRIGGER_RESUME:
209 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 896 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
210 mcbsp->active++; 897 mcbsp->active++;
211 omap_mcbsp_start(mcbsp, play, !play); 898 omap_mcbsp_start(mcbsp, substream->stream);
212 break; 899 break;
213 900
214 case SNDRV_PCM_TRIGGER_STOP: 901 case SNDRV_PCM_TRIGGER_STOP:
215 case SNDRV_PCM_TRIGGER_SUSPEND: 902 case SNDRV_PCM_TRIGGER_SUSPEND:
216 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 903 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
217 omap_mcbsp_stop(mcbsp, play, !play); 904 omap_mcbsp_stop(mcbsp, substream->stream);
218 mcbsp->active--; 905 mcbsp->active--;
219 break; 906 break;
220 default: 907 default:
221 err = -EINVAL; 908 return -EINVAL;
222 } 909 }
223 910
224 return err; 911 return 0;
225} 912}
226 913
227static snd_pcm_sframes_t omap_mcbsp_dai_delay( 914static snd_pcm_sframes_t omap_mcbsp_dai_delay(
@@ -234,6 +921,10 @@ static snd_pcm_sframes_t omap_mcbsp_dai_delay(
234 u16 fifo_use; 921 u16 fifo_use;
235 snd_pcm_sframes_t delay; 922 snd_pcm_sframes_t delay;
236 923
924 /* No need to proceed further if McBSP does not have FIFO */
925 if (mcbsp->pdata->buffer_size == 0)
926 return 0;
927
237 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 928 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
238 fifo_use = omap_mcbsp_get_tx_delay(mcbsp); 929 fifo_use = omap_mcbsp_get_tx_delay(mcbsp);
239 else 930 else
@@ -649,132 +1340,6 @@ static const struct snd_soc_component_driver omap_mcbsp_component = {
649 .name = "omap-mcbsp", 1340 .name = "omap-mcbsp",
650}; 1341};
651 1342
652static int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol,
653 struct snd_ctl_elem_info *uinfo)
654{
655 struct soc_mixer_control *mc =
656 (struct soc_mixer_control *)kcontrol->private_value;
657 int max = mc->max;
658 int min = mc->min;
659
660 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
661 uinfo->count = 1;
662 uinfo->value.integer.min = min;
663 uinfo->value.integer.max = max;
664 return 0;
665}
666
667#define OMAP_MCBSP_ST_CHANNEL_VOLUME(channel) \
668static int \
669omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \
670 struct snd_ctl_elem_value *uc) \
671{ \
672 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \
673 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); \
674 struct soc_mixer_control *mc = \
675 (struct soc_mixer_control *)kc->private_value; \
676 int max = mc->max; \
677 int min = mc->min; \
678 int val = uc->value.integer.value[0]; \
679 \
680 if (val < min || val > max) \
681 return -EINVAL; \
682 \
683 /* OMAP McBSP implementation uses index values 0..4 */ \
684 return omap_st_set_chgain(mcbsp, channel, val); \
685} \
686 \
687static int \
688omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \
689 struct snd_ctl_elem_value *uc) \
690{ \
691 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \
692 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); \
693 s16 chgain; \
694 \
695 if (omap_st_get_chgain(mcbsp, channel, &chgain)) \
696 return -EAGAIN; \
697 \
698 uc->value.integer.value[0] = chgain; \
699 return 0; \
700}
701
702OMAP_MCBSP_ST_CHANNEL_VOLUME(0)
703OMAP_MCBSP_ST_CHANNEL_VOLUME(1)
704
705static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol,
706 struct snd_ctl_elem_value *ucontrol)
707{
708 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
709 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
710 u8 value = ucontrol->value.integer.value[0];
711
712 if (value == omap_st_is_enabled(mcbsp))
713 return 0;
714
715 if (value)
716 omap_st_enable(mcbsp);
717 else
718 omap_st_disable(mcbsp);
719
720 return 1;
721}
722
723static int omap_mcbsp_st_get_mode(struct snd_kcontrol *kcontrol,
724 struct snd_ctl_elem_value *ucontrol)
725{
726 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
727 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
728
729 ucontrol->value.integer.value[0] = omap_st_is_enabled(mcbsp);
730 return 0;
731}
732
733#define OMAP_MCBSP_ST_CONTROLS(port) \
734static const struct snd_kcontrol_new omap_mcbsp##port##_st_controls[] = { \
735SOC_SINGLE_EXT("McBSP" #port " Sidetone Switch", 1, 0, 1, 0, \
736 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode), \
737OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 0 Volume", \
738 -32768, 32767, \
739 omap_mcbsp_get_st_ch0_volume, \
740 omap_mcbsp_set_st_ch0_volume), \
741OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 1 Volume", \
742 -32768, 32767, \
743 omap_mcbsp_get_st_ch1_volume, \
744 omap_mcbsp_set_st_ch1_volume), \
745}
746
747OMAP_MCBSP_ST_CONTROLS(2);
748OMAP_MCBSP_ST_CONTROLS(3);
749
750int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd, int port_id)
751{
752 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
753 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
754
755 if (!mcbsp->st_data) {
756 dev_warn(mcbsp->dev, "No sidetone data for port\n");
757 return 0;
758 }
759
760 switch (port_id) {
761 case 2: /* McBSP 2 */
762 return snd_soc_add_dai_controls(cpu_dai,
763 omap_mcbsp2_st_controls,
764 ARRAY_SIZE(omap_mcbsp2_st_controls));
765 case 3: /* McBSP 3 */
766 return snd_soc_add_dai_controls(cpu_dai,
767 omap_mcbsp3_st_controls,
768 ARRAY_SIZE(omap_mcbsp3_st_controls));
769 default:
770 dev_err(mcbsp->dev, "Port %d not supported\n", port_id);
771 break;
772 }
773
774 return -EINVAL;
775}
776EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls);
777
778static struct omap_mcbsp_platform_data omap2420_pdata = { 1343static struct omap_mcbsp_platform_data omap2420_pdata = {
779 .reg_step = 4, 1344 .reg_step = 4,
780 .reg_size = 2, 1345 .reg_size = 2,
@@ -862,6 +1427,11 @@ static int asoc_mcbsp_probe(struct platform_device *pdev)
862 if (ret) 1427 if (ret)
863 return ret; 1428 return ret;
864 1429
1430 if (mcbsp->pdata->reg_size == 2) {
1431 omap_mcbsp_dai.playback.formats = SNDRV_PCM_FMTBIT_S16_LE;
1432 omap_mcbsp_dai.capture.formats = SNDRV_PCM_FMTBIT_S16_LE;
1433 }
1434
865 ret = devm_snd_soc_register_component(&pdev->dev, 1435 ret = devm_snd_soc_register_component(&pdev->dev,
866 &omap_mcbsp_component, 1436 &omap_mcbsp_component,
867 &omap_mcbsp_dai, 1); 1437 &omap_mcbsp_dai, 1);
@@ -881,7 +1451,10 @@ static int asoc_mcbsp_remove(struct platform_device *pdev)
881 if (pm_qos_request_active(&mcbsp->pm_qos_req)) 1451 if (pm_qos_request_active(&mcbsp->pm_qos_req))
882 pm_qos_remove_request(&mcbsp->pm_qos_req); 1452 pm_qos_remove_request(&mcbsp->pm_qos_req);
883 1453
884 omap_mcbsp_cleanup(mcbsp); 1454 if (mcbsp->pdata->buffer_size)
1455 sysfs_remove_group(&mcbsp->dev->kobj, &additional_attr_group);
1456
1457 omap_mcbsp_st_cleanup(pdev);
885 1458
886 clk_put(mcbsp->fclk); 1459 clk_put(mcbsp->fclk);
887 1460
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/ti/omap-mcbsp.h
index 2e3369c27be3..7911d24898c9 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/ti/omap-mcbsp.h
@@ -22,8 +22,10 @@
22 * 22 *
23 */ 23 */
24 24
25#ifndef __OMAP_I2S_H__ 25#ifndef __OMAP_MCBSP_H__
26#define __OMAP_I2S_H__ 26#define __OMAP_MCBSP_H__
27
28#include <sound/dmaengine_pcm.h>
27 29
28/* Source clocks for McBSP sample rate generator */ 30/* Source clocks for McBSP sample rate generator */
29enum omap_mcbsp_clksrg_clk { 31enum omap_mcbsp_clksrg_clk {
@@ -41,4 +43,4 @@ enum omap_mcbsp_div {
41 43
42int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd, int port_id); 44int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd, int port_id);
43 45
44#endif 46#endif /* __OMAP_MCBSP_H__ */
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/ti/omap-mcpdm.c
index 7d5bdc5a2890..7d5bdc5a2890 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/ti/omap-mcpdm.c
diff --git a/sound/soc/omap/omap-mcpdm.h b/sound/soc/ti/omap-mcpdm.h
index de8cf26595b1..de8cf26595b1 100644
--- a/sound/soc/omap/omap-mcpdm.h
+++ b/sound/soc/ti/omap-mcpdm.h
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/ti/omap-twl4030.c
index cccc316743fa..cccc316743fa 100644
--- a/sound/soc/omap/omap-twl4030.c
+++ b/sound/soc/ti/omap-twl4030.c
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/ti/omap3pandora.c
index 4e3de712159c..4e3de712159c 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/ti/omap3pandora.c
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/ti/osk5912.c
index e4096779ca05..e4096779ca05 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/ti/osk5912.c
diff --git a/sound/soc/omap/rx51.c b/sound/soc/ti/rx51.c
index 57448bd5ad77..57448bd5ad77 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/ti/rx51.c
diff --git a/sound/soc/omap/sdma-pcm.c b/sound/soc/ti/sdma-pcm.c
index 21a9c2499d48..21a9c2499d48 100644
--- a/sound/soc/omap/sdma-pcm.c
+++ b/sound/soc/ti/sdma-pcm.c
diff --git a/sound/soc/omap/sdma-pcm.h b/sound/soc/ti/sdma-pcm.h
index 34a7f90b2587..cb0627c8dd34 100644
--- a/sound/soc/omap/sdma-pcm.h
+++ b/sound/soc/ti/sdma-pcm.h
@@ -7,7 +7,7 @@
7#ifndef __SDMA_PCM_H__ 7#ifndef __SDMA_PCM_H__
8#define __SDMA_PCM_H__ 8#define __SDMA_PCM_H__
9 9
10#if IS_ENABLED(CONFIG_SND_SDMA_SOC) 10#if IS_ENABLED(CONFIG_SND_SOC_TI_SDMA_PCM)
11int sdma_pcm_platform_register(struct device *dev, 11int sdma_pcm_platform_register(struct device *dev,
12 char *txdmachan, char *rxdmachan); 12 char *txdmachan, char *rxdmachan);
13#else 13#else
@@ -16,6 +16,6 @@ static inline int sdma_pcm_platform_register(struct device *dev,
16{ 16{
17 return -ENODEV; 17 return -ENODEV;
18} 18}
19#endif /* CONFIG_SND_SDMA_SOC */ 19#endif /* CONFIG_SND_SOC_TI_SDMA_PCM */
20 20
21#endif /* __SDMA_PCM_H__ */ 21#endif /* __SDMA_PCM_H__ */
diff --git a/sound/soc/xilinx/Kconfig b/sound/soc/xilinx/Kconfig
new file mode 100644
index 000000000000..25e287feb58c
--- /dev/null
+++ b/sound/soc/xilinx/Kconfig
@@ -0,0 +1,8 @@
1config SND_SOC_XILINX_I2S
2 tristate "Audio support for the the Xilinx I2S"
3 help
4 Select this option to enable Xilinx I2S Audio. This enables
5 I2S playback and capture using xilinx soft IP. In transmitter
6 mode, IP receives audio in AES format, extracts PCM and sends
7 PCM data. In receiver mode, IP receives PCM audio and
8 encapsulates PCM in AES format and sends AES data.
diff --git a/sound/soc/xilinx/Makefile b/sound/soc/xilinx/Makefile
new file mode 100644
index 000000000000..6c1209b9ee75
--- /dev/null
+++ b/sound/soc/xilinx/Makefile
@@ -0,0 +1,2 @@
1snd-soc-xlnx-i2s-objs := xlnx_i2s.o
2obj-$(CONFIG_SND_SOC_XILINX_I2S) += snd-soc-xlnx-i2s.o
diff --git a/sound/soc/xilinx/xlnx_i2s.c b/sound/soc/xilinx/xlnx_i2s.c
new file mode 100644
index 000000000000..d4ae9eff41ce
--- /dev/null
+++ b/sound/soc/xilinx/xlnx_i2s.c
@@ -0,0 +1,185 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Xilinx ASoC I2S audio support
4 *
5 * Copyright (C) 2018 Xilinx, Inc.
6 *
7 * Author: Praveen Vuppala <praveenv@xilinx.com>
8 * Author: Maruthi Srinivas Bayyavarapu <maruthis@xilinx.com>
9 */
10
11#include <linux/io.h>
12#include <linux/module.h>
13#include <linux/of.h>
14#include <linux/of_platform.h>
15#include <linux/platform_device.h>
16#include <sound/pcm_params.h>
17#include <sound/soc.h>
18
19#define DRV_NAME "xlnx_i2s"
20
21#define I2S_CORE_CTRL_OFFSET 0x08
22#define I2S_I2STIM_OFFSET 0x20
23#define I2S_CH0_OFFSET 0x30
24#define I2S_I2STIM_VALID_MASK GENMASK(7, 0)
25
26static int xlnx_i2s_set_sclkout_div(struct snd_soc_dai *cpu_dai,
27 int div_id, int div)
28{
29 void __iomem *base = snd_soc_dai_get_drvdata(cpu_dai);
30
31 if (!div || (div & ~I2S_I2STIM_VALID_MASK))
32 return -EINVAL;
33
34 writel(div, base + I2S_I2STIM_OFFSET);
35
36 return 0;
37}
38
39static int xlnx_i2s_hw_params(struct snd_pcm_substream *substream,
40 struct snd_pcm_hw_params *params,
41 struct snd_soc_dai *i2s_dai)
42{
43 u32 reg_off, chan_id;
44 void __iomem *base = snd_soc_dai_get_drvdata(i2s_dai);
45
46 chan_id = params_channels(params) / 2;
47
48 while (chan_id > 0) {
49 reg_off = I2S_CH0_OFFSET + ((chan_id - 1) * 4);
50 writel(chan_id, base + reg_off);
51 chan_id--;
52 }
53
54 return 0;
55}
56
57static int xlnx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
58 struct snd_soc_dai *i2s_dai)
59{
60 void __iomem *base = snd_soc_dai_get_drvdata(i2s_dai);
61
62 switch (cmd) {
63 case SNDRV_PCM_TRIGGER_START:
64 case SNDRV_PCM_TRIGGER_RESUME:
65 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
66 writel(1, base + I2S_CORE_CTRL_OFFSET);
67 break;
68 case SNDRV_PCM_TRIGGER_STOP:
69 case SNDRV_PCM_TRIGGER_SUSPEND:
70 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
71 writel(0, base + I2S_CORE_CTRL_OFFSET);
72 break;
73 default:
74 return -EINVAL;
75 }
76
77 return 0;
78}
79
80static const struct snd_soc_dai_ops xlnx_i2s_dai_ops = {
81 .trigger = xlnx_i2s_trigger,
82 .set_clkdiv = xlnx_i2s_set_sclkout_div,
83 .hw_params = xlnx_i2s_hw_params
84};
85
86static const struct snd_soc_component_driver xlnx_i2s_component = {
87 .name = DRV_NAME,
88};
89
90static const struct of_device_id xlnx_i2s_of_match[] = {
91 { .compatible = "xlnx,i2s-transmitter-1.0", },
92 { .compatible = "xlnx,i2s-receiver-1.0", },
93 {},
94};
95MODULE_DEVICE_TABLE(of, xlnx_i2s_of_match);
96
97static int xlnx_i2s_probe(struct platform_device *pdev)
98{
99 struct resource *res;
100 void __iomem *base;
101 struct snd_soc_dai_driver *dai_drv;
102 int ret;
103 u32 ch, format, data_width;
104 struct device *dev = &pdev->dev;
105 struct device_node *node = dev->of_node;
106
107 dai_drv = devm_kzalloc(&pdev->dev, sizeof(*dai_drv), GFP_KERNEL);
108 if (!dai_drv)
109 return -ENOMEM;
110
111 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
112 base = devm_ioremap_resource(&pdev->dev, res);
113 if (IS_ERR(base))
114 return PTR_ERR(base);
115
116 ret = of_property_read_u32(node, "xlnx,num-channels", &ch);
117 if (ret < 0) {
118 dev_err(dev, "cannot get supported channels\n");
119 return ret;
120 }
121 ch = ch * 2;
122
123 ret = of_property_read_u32(node, "xlnx,dwidth", &data_width);
124 if (ret < 0) {
125 dev_err(dev, "cannot get data width\n");
126 return ret;
127 }
128 switch (data_width) {
129 case 16:
130 format = SNDRV_PCM_FMTBIT_S16_LE;
131 break;
132 case 24:
133 format = SNDRV_PCM_FMTBIT_S24_LE;
134 break;
135 default:
136 return -EINVAL;
137 }
138
139 if (of_device_is_compatible(node, "xlnx,i2s-transmitter-1.0")) {
140 dai_drv->name = "xlnx_i2s_playback";
141 dai_drv->playback.stream_name = "Playback";
142 dai_drv->playback.formats = format;
143 dai_drv->playback.channels_min = ch;
144 dai_drv->playback.channels_max = ch;
145 dai_drv->playback.rates = SNDRV_PCM_RATE_8000_192000;
146 dai_drv->ops = &xlnx_i2s_dai_ops;
147 } else if (of_device_is_compatible(node, "xlnx,i2s-receiver-1.0")) {
148 dai_drv->name = "xlnx_i2s_capture";
149 dai_drv->capture.stream_name = "Capture";
150 dai_drv->capture.formats = format;
151 dai_drv->capture.channels_min = ch;
152 dai_drv->capture.channels_max = ch;
153 dai_drv->capture.rates = SNDRV_PCM_RATE_8000_192000;
154 dai_drv->ops = &xlnx_i2s_dai_ops;
155 } else {
156 return -ENODEV;
157 }
158
159 dev_set_drvdata(&pdev->dev, base);
160
161 ret = devm_snd_soc_register_component(&pdev->dev, &xlnx_i2s_component,
162 dai_drv, 1);
163 if (ret) {
164 dev_err(&pdev->dev, "i2s component registration failed\n");
165 return ret;
166 }
167
168 dev_info(&pdev->dev, "%s DAI registered\n", dai_drv->name);
169
170 return ret;
171}
172
173static struct platform_driver xlnx_i2s_aud_driver = {
174 .driver = {
175 .name = DRV_NAME,
176 .of_match_table = xlnx_i2s_of_match,
177 },
178 .probe = xlnx_i2s_probe,
179};
180
181module_platform_driver(xlnx_i2s_aud_driver);
182
183MODULE_LICENSE("GPL v2");
184MODULE_AUTHOR("Praveen Vuppala <praveenv@xilinx.com>");
185MODULE_AUTHOR("Maruthi Srinivas Bayyavarapu <maruthis@xilinx.com>");