aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-15 18:41:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-15 18:41:41 -0400
commitd0a3997c0c3f9351e24029349dee65dd1d9e8d84 (patch)
tree7a04fe282b0c7b329cd87cdb891f0f3879dc71a6 /sound/soc
parent6d50ff91d9780263160262daeb6adfdda8ddbc6c (diff)
parentd6eb9e3ec78c98324097bab8eea266c3bb0d0ac7 (diff)
Merge tag 'sound-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "There have been major modernization with the standard bus: in ALSA sequencer core and HD-audio. Also, HD-audio receives the regmap support replacing the in-house cache register cache code. These changes shouldn't impact the existing behavior, but rather refactoring. In addition, HD-audio got the code split to a core library part and the "legacy" driver parts. This is a preliminary work for adapting the upcoming ASoC HD-audio driver, and the whole transition is still work in progress, likely finished in 4.1. Along with them, there are many updates in ASoC area as usual, too: lots of cleanups, Intel code shuffling, etc. Here are some highlights: ALSA core: - PCM: the audio timestamp / wallclock enhancement - PCM: fixes in DPCM management - Fixes / cleanups of user-space control element management - Sequencer: modernization using the standard bus HD-audio: - Modernization using the standard bus - Regmap support - Use standard runtime PM for codec power saving - Widget-path based power-saving for IDT, VIA and Realtek codecs - Reorganized sysfs entries for each codec object - More Dell headset support ASoC: - Move of jack registration to the card level - Lots of ASoC cleanups, mainly moving things from the CODEC level to the card level - Support for DAPM routes specified by both the machine driver and DT - Continuing improvements to rcar - pcm512x enhacements - Intel platforms updates - rt5670 updates / fixes - New platforms / devices: some non-DSP Qualcomm platforms, Google's Storm platform, Maxmim MAX98925 CODECs and the Ingenic JZ4780 SoC Misc: - ice1724: Improved ESI W192M support - emu10k1: Emu 1010 fixes/enhancement" * tag 'sound-4.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (411 commits) ALSA: hda - set GET bit when adding a vendor verb to the codec regmap ALSA: hda/realtek - Enable the ALC292 dock fixup on the Thinkpad T450 ALSA: hda - Fix another race in runtime PM refcounting ALSA: hda - Expose codec type sysfs ALSA: ctl: fix to handle several elements added by one operation for userspace element ASoC: Intel: fix array_size.cocci warnings ASoC: n810: Automatically disconnect non-connected pins ASoC: n810: Consistently pass the card DAPM context to n810_ext_control() ASoC: davinci-evm: Use card DAPM context to access widgets ASoC: mop500_ab8500: Use card DAPM context to access widgets ASoC: wm1133-ev1: Use card DAPM context to access widgets ASoC: atmel: Improve machine driver compile test coverage ASoC: atmel: Add dependency to SND_SOC_I2C_AND_SPI where necessary ALSA: control: Fix a typo of SNDRV_CTL_ELEM_ACCESS_TLV_* with SNDRV_CTL_TLV_OP_* ALSA: usb-audio: Don't attempt to get Microsoft Lifecam Cinema sample rate ASoC: rnsd: fix build regression without CONFIG_OF ALSA: emu10k1: add toggles for E-mu 1010 optical ports ALSA: ctl: fill identical information to return value when adding userspace elements ALSA: ctl: fix a bug to return no identical information in info operation for userspace controls ALSA: ctl: confirm to return all identical information in 'activate' event ...
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/Kconfig1
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/atmel/Kconfig9
-rw-r--r--sound/soc/atmel/Makefile2
-rw-r--r--sound/soc/atmel/atmel-pcm-dma.c4
-rw-r--r--sound/soc/atmel/atmel-pcm-pdc.c79
-rw-r--r--sound/soc/atmel/atmel-pcm.c121
-rw-r--r--sound/soc/atmel/atmel-pcm.h5
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c111
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.h1
-rw-r--r--sound/soc/codecs/Kconfig22
-rw-r--r--sound/soc/codecs/Makefile6
-rw-r--r--sound/soc/codecs/ab8500-codec.c2
-rw-r--r--sound/soc/codecs/adau1977.c17
-rw-r--r--sound/soc/codecs/ak4554.c2
-rw-r--r--sound/soc/codecs/ak4642.c41
-rw-r--r--sound/soc/codecs/arizona.c6
-rw-r--r--sound/soc/codecs/cs35l32.c19
-rw-r--r--sound/soc/codecs/cs4265.c19
-rw-r--r--sound/soc/codecs/cs4271.c4
-rw-r--r--sound/soc/codecs/cx20442.c4
-rw-r--r--sound/soc/codecs/max98090.c17
-rw-r--r--sound/soc/codecs/max98357a.c11
-rw-r--r--sound/soc/codecs/max98925.c655
-rw-r--r--sound/soc/codecs/max98925.h832
-rw-r--r--sound/soc/codecs/pcm512x.c186
-rw-r--r--sound/soc/codecs/rt286.c40
-rw-r--r--sound/soc/codecs/rt5631.c2
-rw-r--r--sound/soc/codecs/rt5645.c90
-rw-r--r--sound/soc/codecs/rt5645.h2
-rw-r--r--sound/soc/codecs/rt5670.c213
-rw-r--r--sound/soc/codecs/rt5670.h10
-rw-r--r--sound/soc/codecs/rt5677.c207
-rw-r--r--sound/soc/codecs/rt5677.h85
-rw-r--r--sound/soc/codecs/sn95031.c14
-rw-r--r--sound/soc/codecs/sn95031.h3
-rw-r--r--sound/soc/codecs/sta350.c30
-rw-r--r--sound/soc/codecs/tas2552.c13
-rw-r--r--sound/soc/codecs/tlv320aic23-i2c.c4
-rw-r--r--sound/soc/codecs/wm2200.c9
-rw-r--r--sound/soc/codecs/wm5100.c7
-rw-r--r--sound/soc/codecs/wm5102.c1
-rw-r--r--sound/soc/codecs/wm8350.c25
-rw-r--r--sound/soc/codecs/wm8731.c34
-rw-r--r--sound/soc/codecs/wm8741.c8
-rw-r--r--sound/soc/codecs/wm8753.c73
-rw-r--r--sound/soc/codecs/wm8804-i2c.c65
-rw-r--r--sound/soc/codecs/wm8804-spi.c57
-rw-r--r--sound/soc/codecs/wm8804.c534
-rw-r--r--sound/soc/codecs/wm8804.h8
-rw-r--r--sound/soc/codecs/wm8971.c99
-rw-r--r--sound/soc/codecs/wm8996.c12
-rw-r--r--sound/soc/codecs/wm_adsp.c13
-rw-r--r--sound/soc/davinci/Kconfig18
-rw-r--r--sound/soc/davinci/Makefile2
-rw-r--r--sound/soc/davinci/davinci-evm.c17
-rw-r--r--sound/soc/davinci/davinci-i2s.c67
-rw-r--r--sound/soc/davinci/davinci-mcasp.c335
-rw-r--r--sound/soc/davinci/davinci-pcm.c861
-rw-r--r--sound/soc/davinci/davinci-pcm.h41
-rw-r--r--sound/soc/davinci/davinci-vcif.c55
-rw-r--r--sound/soc/fsl/Kconfig4
-rw-r--r--sound/soc/fsl/fsl-asoc-card.c6
-rw-r--r--sound/soc/fsl/fsl_ssi.c32
-rw-r--r--sound/soc/fsl/imx-es8328.c6
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.c2
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c2
-rw-r--r--sound/soc/fsl/pcm030-audio-fabric.c2
-rw-r--r--sound/soc/fsl/wm1133-ev1.c15
-rw-r--r--sound/soc/generic/simple-card.c50
-rw-r--r--sound/soc/intel/Makefile42
-rw-r--r--sound/soc/intel/atom/Makefile7
-rw-r--r--sound/soc/intel/atom/sst-atom-controls.c (renamed from sound/soc/intel/sst-atom-controls.c)0
-rw-r--r--sound/soc/intel/atom/sst-atom-controls.h (renamed from sound/soc/intel/sst-atom-controls.h)0
-rw-r--r--sound/soc/intel/atom/sst-mfld-dsp.h (renamed from sound/soc/intel/sst-mfld-dsp.h)0
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform-compress.c (renamed from sound/soc/intel/sst-mfld-platform-compress.c)0
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform-pcm.c (renamed from sound/soc/intel/sst-mfld-platform-pcm.c)60
-rw-r--r--sound/soc/intel/atom/sst-mfld-platform.h (renamed from sound/soc/intel/sst-mfld-platform.h)1
-rw-r--r--sound/soc/intel/atom/sst/Makefile (renamed from sound/soc/intel/sst/Makefile)0
-rw-r--r--sound/soc/intel/atom/sst/sst.c (renamed from sound/soc/intel/sst/sst.c)130
-rw-r--r--sound/soc/intel/atom/sst/sst.h (renamed from sound/soc/intel/sst/sst.h)12
-rw-r--r--sound/soc/intel/atom/sst/sst_acpi.c (renamed from sound/soc/intel/sst/sst_acpi.c)4
-rw-r--r--sound/soc/intel/atom/sst/sst_drv_interface.c (renamed from sound/soc/intel/sst/sst_drv_interface.c)69
-rw-r--r--sound/soc/intel/atom/sst/sst_ipc.c (renamed from sound/soc/intel/sst/sst_ipc.c)2
-rw-r--r--sound/soc/intel/atom/sst/sst_loader.c (renamed from sound/soc/intel/sst/sst_loader.c)12
-rw-r--r--sound/soc/intel/atom/sst/sst_pci.c (renamed from sound/soc/intel/sst/sst_pci.c)0
-rw-r--r--sound/soc/intel/atom/sst/sst_pvt.c (renamed from sound/soc/intel/sst/sst_pvt.c)26
-rw-r--r--sound/soc/intel/atom/sst/sst_stream.c (renamed from sound/soc/intel/sst/sst_stream.c)2
-rw-r--r--sound/soc/intel/baytrail/Makefile4
-rw-r--r--sound/soc/intel/baytrail/sst-baytrail-dsp.c (renamed from sound/soc/intel/sst-baytrail-dsp.c)4
-rw-r--r--sound/soc/intel/baytrail/sst-baytrail-ipc.c (renamed from sound/soc/intel/sst-baytrail-ipc.c)364
-rw-r--r--sound/soc/intel/baytrail/sst-baytrail-ipc.h (renamed from sound/soc/intel/sst-baytrail-ipc.h)0
-rw-r--r--sound/soc/intel/baytrail/sst-baytrail-pcm.c (renamed from sound/soc/intel/sst-baytrail-pcm.c)4
-rw-r--r--sound/soc/intel/boards/Makefile15
-rw-r--r--sound/soc/intel/boards/broadwell.c (renamed from sound/soc/intel/broadwell.c)50
-rw-r--r--sound/soc/intel/boards/byt-max98090.c (renamed from sound/soc/intel/byt-max98090.c)13
-rw-r--r--sound/soc/intel/boards/byt-rt5640.c (renamed from sound/soc/intel/byt-rt5640.c)4
-rw-r--r--sound/soc/intel/boards/bytcr_rt5640.c (renamed from sound/soc/intel/bytcr_dpcm_rt5640.c)8
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5645.c (renamed from sound/soc/intel/cht_bsw_rt5645.c)20
-rw-r--r--sound/soc/intel/boards/cht_bsw_rt5672.c (renamed from sound/soc/intel/cht_bsw_rt5672.c)108
-rw-r--r--sound/soc/intel/boards/haswell.c (renamed from sound/soc/intel/haswell.c)10
-rw-r--r--sound/soc/intel/boards/mfld_machine.c (renamed from sound/soc/intel/mfld_machine.c)24
-rw-r--r--sound/soc/intel/common/Makefile7
-rw-r--r--sound/soc/intel/common/sst-acpi.c (renamed from sound/soc/intel/sst-acpi.c)1
-rw-r--r--sound/soc/intel/common/sst-dsp-priv.h (renamed from sound/soc/intel/sst-dsp-priv.h)13
-rw-r--r--sound/soc/intel/common/sst-dsp.c (renamed from sound/soc/intel/sst-dsp.c)0
-rw-r--r--sound/soc/intel/common/sst-dsp.h (renamed from sound/soc/intel/sst-dsp.h)2
-rw-r--r--sound/soc/intel/common/sst-firmware.c (renamed from sound/soc/intel/sst-firmware.c)10
-rw-r--r--sound/soc/intel/common/sst-ipc.c294
-rw-r--r--sound/soc/intel/common/sst-ipc.h91
-rw-r--r--sound/soc/intel/haswell/Makefile4
-rw-r--r--sound/soc/intel/haswell/sst-haswell-dsp.c (renamed from sound/soc/intel/sst-haswell-dsp.c)9
-rw-r--r--sound/soc/intel/haswell/sst-haswell-ipc.c (renamed from sound/soc/intel/sst-haswell-ipc.c)794
-rw-r--r--sound/soc/intel/haswell/sst-haswell-ipc.h (renamed from sound/soc/intel/sst-haswell-ipc.h)53
-rw-r--r--sound/soc/intel/haswell/sst-haswell-pcm.c (renamed from sound/soc/intel/sst-haswell-pcm.c)140
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c84
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c2
-rw-r--r--sound/soc/nuc900/nuc900-audio.h3
-rw-r--r--sound/soc/nuc900/nuc900-pcm.c31
-rw-r--r--sound/soc/omap/Kconfig4
-rw-r--r--sound/soc/omap/ams-delta.c4
-rw-r--r--sound/soc/omap/n810.c23
-rw-r--r--sound/soc/omap/omap-abe-twl6040.c10
-rw-r--r--sound/soc/omap/omap-hdmi-audio.c2
-rw-r--r--sound/soc/omap/omap-pcm.c21
-rw-r--r--sound/soc/omap/omap-twl4030.c12
-rw-r--r--sound/soc/omap/rx51.c6
-rw-r--r--sound/soc/pxa/hx4700.c11
-rw-r--r--sound/soc/pxa/palm27x.c11
-rw-r--r--sound/soc/pxa/ttc-dkb.c15
-rw-r--r--sound/soc/pxa/z2.c10
-rw-r--r--sound/soc/qcom/Kconfig25
-rw-r--r--sound/soc/qcom/Makefile11
-rw-r--r--sound/soc/qcom/lpass-cpu.c491
-rw-r--r--sound/soc/qcom/lpass-lpaif-ipq806x.h172
-rw-r--r--sound/soc/qcom/lpass-platform.c526
-rw-r--r--sound/soc/qcom/lpass.h51
-rw-r--r--sound/soc/qcom/storm.c162
-rw-r--r--sound/soc/samsung/h1940_uda1380.c9
-rw-r--r--sound/soc/samsung/littlemill.c12
-rw-r--r--sound/soc/samsung/lowland.c14
-rw-r--r--sound/soc/samsung/rx1950_uda1380.c9
-rw-r--r--sound/soc/samsung/smartq_wm8987.c11
-rw-r--r--sound/soc/samsung/speyside.c14
-rw-r--r--sound/soc/samsung/tobermory.c13
-rw-r--r--sound/soc/sh/Kconfig6
-rw-r--r--sound/soc/sh/fsi.c71
-rw-r--r--sound/soc/sh/rcar/Makefile7
-rw-r--r--sound/soc/sh/rcar/adg.c4
-rw-r--r--sound/soc/sh/rcar/core.c278
-rw-r--r--sound/soc/sh/rcar/dma.c616
-rw-r--r--sound/soc/sh/rcar/dvc.c45
-rw-r--r--sound/soc/sh/rcar/gen.c152
-rw-r--r--sound/soc/sh/rcar/rsnd.h92
-rw-r--r--sound/soc/sh/rcar/rsrc-card.c512
-rw-r--r--sound/soc/sh/rcar/src.c250
-rw-r--r--sound/soc/sh/rcar/ssi.c73
-rw-r--r--sound/soc/soc-core.c124
-rw-r--r--sound/soc/soc-dapm.c182
-rw-r--r--sound/soc/soc-jack.c42
-rw-r--r--sound/soc/soc-pcm.c17
-rw-r--r--sound/soc/tegra/tegra_alc5632.c14
-rw-r--r--sound/soc/tegra/tegra_max98090.c26
-rw-r--r--sound/soc/tegra/tegra_rt5640.c10
-rw-r--r--sound/soc/tegra/tegra_rt5677.c20
-rw-r--r--sound/soc/tegra/tegra_wm8903.c21
-rw-r--r--sound/soc/tegra/tegra_wm9712.c6
-rw-r--r--sound/soc/ux500/mop500_ab8500.c36
168 files changed, 8553 insertions, 3583 deletions
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index dcc79aa0236b..3ba52da18bc6 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -47,6 +47,7 @@ source "sound/soc/kirkwood/Kconfig"
47source "sound/soc/intel/Kconfig" 47source "sound/soc/intel/Kconfig"
48source "sound/soc/mxs/Kconfig" 48source "sound/soc/mxs/Kconfig"
49source "sound/soc/pxa/Kconfig" 49source "sound/soc/pxa/Kconfig"
50source "sound/soc/qcom/Kconfig"
50source "sound/soc/rockchip/Kconfig" 51source "sound/soc/rockchip/Kconfig"
51source "sound/soc/samsung/Kconfig" 52source "sound/soc/samsung/Kconfig"
52source "sound/soc/sh/Kconfig" 53source "sound/soc/sh/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 5b3c8f67c8db..974ba708b482 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_SND_SOC) += nuc900/
28obj-$(CONFIG_SND_SOC) += omap/ 28obj-$(CONFIG_SND_SOC) += omap/
29obj-$(CONFIG_SND_SOC) += kirkwood/ 29obj-$(CONFIG_SND_SOC) += kirkwood/
30obj-$(CONFIG_SND_SOC) += pxa/ 30obj-$(CONFIG_SND_SOC) += pxa/
31obj-$(CONFIG_SND_SOC) += qcom/
31obj-$(CONFIG_SND_SOC) += rockchip/ 32obj-$(CONFIG_SND_SOC) += rockchip/
32obj-$(CONFIG_SND_SOC) += samsung/ 33obj-$(CONFIG_SND_SOC) += samsung/
33obj-$(CONFIG_SND_SOC) += sh/ 34obj-$(CONFIG_SND_SOC) += sh/
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index 1579e994acf8..e7d08806f3e9 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -25,7 +25,8 @@ config SND_ATMEL_SOC_SSC
25 25
26config SND_AT91_SOC_SAM9G20_WM8731 26config SND_AT91_SOC_SAM9G20_WM8731
27 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" 27 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
28 depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC 28 depends on ARCH_AT91 || COMPILE_TEST
29 depends on ATMEL_SSC && SND_ATMEL_SOC && SND_SOC_I2C_AND_SPI
29 select SND_ATMEL_SOC_PDC 30 select SND_ATMEL_SOC_PDC
30 select SND_ATMEL_SOC_SSC 31 select SND_ATMEL_SOC_SSC
31 select SND_SOC_WM8731 32 select SND_SOC_WM8731
@@ -35,7 +36,8 @@ config SND_AT91_SOC_SAM9G20_WM8731
35 36
36config SND_ATMEL_SOC_WM8904 37config SND_ATMEL_SOC_WM8904
37 tristate "Atmel ASoC driver for boards using WM8904 codec" 38 tristate "Atmel ASoC driver for boards using WM8904 codec"
38 depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC && I2C 39 depends on ARCH_AT91 || COMPILE_TEST
40 depends on ATMEL_SSC && SND_ATMEL_SOC && I2C
39 select SND_ATMEL_SOC_SSC 41 select SND_ATMEL_SOC_SSC
40 select SND_ATMEL_SOC_DMA 42 select SND_ATMEL_SOC_DMA
41 select SND_SOC_WM8904 43 select SND_SOC_WM8904
@@ -45,7 +47,8 @@ config SND_ATMEL_SOC_WM8904
45 47
46config SND_AT91_SOC_SAM9X5_WM8731 48config SND_AT91_SOC_SAM9X5_WM8731
47 tristate "SoC Audio support for WM8731-based at91sam9x5 board" 49 tristate "SoC Audio support for WM8731-based at91sam9x5 board"
48 depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC 50 depends on ARCH_AT91 || COMPILE_TEST
51 depends on ATMEL_SSC && SND_ATMEL_SOC && SND_SOC_I2C_AND_SPI
49 select SND_ATMEL_SOC_SSC 52 select SND_ATMEL_SOC_SSC
50 select SND_ATMEL_SOC_DMA 53 select SND_ATMEL_SOC_DMA
51 select SND_SOC_WM8731 54 select SND_SOC_WM8731
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
index 466a821da98c..b327e5cc8de3 100644
--- a/sound/soc/atmel/Makefile
+++ b/sound/soc/atmel/Makefile
@@ -1,10 +1,8 @@
1# AT91 Platform Support 1# AT91 Platform Support
2snd-soc-atmel-pcm-objs := atmel-pcm.o
3snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o 2snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o
4snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o 3snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o
5snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o 4snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o
6 5
7obj-$(CONFIG_SND_ATMEL_SOC) += snd-soc-atmel-pcm.o
8obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o 6obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o
9obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o 7obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o
10obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o 8obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
diff --git a/sound/soc/atmel/atmel-pcm-dma.c b/sound/soc/atmel/atmel-pcm-dma.c
index b8e7bad05eb1..b6625c8c411b 100644
--- a/sound/soc/atmel/atmel-pcm-dma.c
+++ b/sound/soc/atmel/atmel-pcm-dma.c
@@ -54,7 +54,7 @@ static const struct snd_pcm_hardware atmel_pcm_dma_hardware = {
54 .period_bytes_max = 2 * 0xffff, /* if 2 bytes format */ 54 .period_bytes_max = 2 * 0xffff, /* if 2 bytes format */
55 .periods_min = 8, 55 .periods_min = 8,
56 .periods_max = 1024, /* no limit */ 56 .periods_max = 1024, /* no limit */
57 .buffer_bytes_max = ATMEL_SSC_DMABUF_SIZE, 57 .buffer_bytes_max = 512 * 1024,
58}; 58};
59 59
60/** 60/**
@@ -119,7 +119,7 @@ static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream,
119static const struct snd_dmaengine_pcm_config atmel_dmaengine_pcm_config = { 119static const struct snd_dmaengine_pcm_config atmel_dmaengine_pcm_config = {
120 .prepare_slave_config = atmel_pcm_configure_dma, 120 .prepare_slave_config = atmel_pcm_configure_dma,
121 .pcm_hardware = &atmel_pcm_dma_hardware, 121 .pcm_hardware = &atmel_pcm_dma_hardware,
122 .prealloc_buffer_size = ATMEL_SSC_DMABUF_SIZE, 122 .prealloc_buffer_size = 64 * 1024,
123}; 123};
124 124
125int atmel_pcm_dma_platform_register(struct device *dev) 125int atmel_pcm_dma_platform_register(struct device *dev)
diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c
index a366b3503c28..da861b44413f 100644
--- a/sound/soc/atmel/atmel-pcm-pdc.c
+++ b/sound/soc/atmel/atmel-pcm-pdc.c
@@ -47,6 +47,85 @@
47#include "atmel-pcm.h" 47#include "atmel-pcm.h"
48 48
49 49
50static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
51 int stream)
52{
53 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
54 struct snd_dma_buffer *buf = &substream->dma_buffer;
55 size_t size = ATMEL_SSC_DMABUF_SIZE;
56
57 buf->dev.type = SNDRV_DMA_TYPE_DEV;
58 buf->dev.dev = pcm->card->dev;
59 buf->private_data = NULL;
60 buf->area = dma_alloc_coherent(pcm->card->dev, size,
61 &buf->addr, GFP_KERNEL);
62 pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%zu\n",
63 (void *)buf->area, (void *)(long)buf->addr, size);
64
65 if (!buf->area)
66 return -ENOMEM;
67
68 buf->bytes = size;
69 return 0;
70}
71
72static int atmel_pcm_mmap(struct snd_pcm_substream *substream,
73 struct vm_area_struct *vma)
74{
75 return remap_pfn_range(vma, vma->vm_start,
76 substream->dma_buffer.addr >> PAGE_SHIFT,
77 vma->vm_end - vma->vm_start, vma->vm_page_prot);
78}
79
80static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
81{
82 struct snd_card *card = rtd->card->snd_card;
83 struct snd_pcm *pcm = rtd->pcm;
84 int ret;
85
86 ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
87 if (ret)
88 return ret;
89
90 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
91 pr_debug("atmel-pcm: allocating PCM playback DMA buffer\n");
92 ret = atmel_pcm_preallocate_dma_buffer(pcm,
93 SNDRV_PCM_STREAM_PLAYBACK);
94 if (ret)
95 goto out;
96 }
97
98 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
99 pr_debug("atmel-pcm: allocating PCM capture DMA buffer\n");
100 ret = atmel_pcm_preallocate_dma_buffer(pcm,
101 SNDRV_PCM_STREAM_CAPTURE);
102 if (ret)
103 goto out;
104 }
105 out:
106 return ret;
107}
108
109static void atmel_pcm_free(struct snd_pcm *pcm)
110{
111 struct snd_pcm_substream *substream;
112 struct snd_dma_buffer *buf;
113 int stream;
114
115 for (stream = 0; stream < 2; stream++) {
116 substream = pcm->streams[stream].substream;
117 if (!substream)
118 continue;
119
120 buf = &substream->dma_buffer;
121 if (!buf->area)
122 continue;
123 dma_free_coherent(pcm->card->dev, buf->bytes,
124 buf->area, buf->addr);
125 buf->area = NULL;
126 }
127}
128
50/*--------------------------------------------------------------------------*\ 129/*--------------------------------------------------------------------------*\
51 * Hardware definition 130 * Hardware definition
52\*--------------------------------------------------------------------------*/ 131\*--------------------------------------------------------------------------*/
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
deleted file mode 100644
index 8ae3fa5ac60a..000000000000
--- a/sound/soc/atmel/atmel-pcm.c
+++ /dev/null
@@ -1,121 +0,0 @@
1/*
2 * atmel-pcm.c -- ALSA PCM interface for the Atmel atmel SoC.
3 *
4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2008 Atmel
6 *
7 * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
8 *
9 * Based on at91-pcm. by:
10 * Frank Mandarino <fmandarino@endrelia.com>
11 * Copyright 2006 Endrelia Technologies Inc.
12 *
13 * Based on pxa2xx-pcm.c by:
14 *
15 * Author: Nicolas Pitre
16 * Created: Nov 30, 2004
17 * Copyright: (C) 2004 MontaVista Software, Inc.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 */
33
34#include <linux/module.h>
35#include <linux/dma-mapping.h>
36#include <sound/pcm.h>
37#include <sound/soc.h>
38#include "atmel-pcm.h"
39
40static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
41 int stream)
42{
43 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
44 struct snd_dma_buffer *buf = &substream->dma_buffer;
45 size_t size = ATMEL_SSC_DMABUF_SIZE;
46
47 buf->dev.type = SNDRV_DMA_TYPE_DEV;
48 buf->dev.dev = pcm->card->dev;
49 buf->private_data = NULL;
50 buf->area = dma_alloc_coherent(pcm->card->dev, size,
51 &buf->addr, GFP_KERNEL);
52 pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%zu\n",
53 (void *)buf->area, (void *)(long)buf->addr, size);
54
55 if (!buf->area)
56 return -ENOMEM;
57
58 buf->bytes = size;
59 return 0;
60}
61
62int atmel_pcm_mmap(struct snd_pcm_substream *substream,
63 struct vm_area_struct *vma)
64{
65 return remap_pfn_range(vma, vma->vm_start,
66 substream->dma_buffer.addr >> PAGE_SHIFT,
67 vma->vm_end - vma->vm_start, vma->vm_page_prot);
68}
69EXPORT_SYMBOL_GPL(atmel_pcm_mmap);
70
71int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd)
72{
73 struct snd_card *card = rtd->card->snd_card;
74 struct snd_pcm *pcm = rtd->pcm;
75 int ret;
76
77 ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
78 if (ret)
79 return ret;
80
81 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
82 pr_debug("atmel-pcm: allocating PCM playback DMA buffer\n");
83 ret = atmel_pcm_preallocate_dma_buffer(pcm,
84 SNDRV_PCM_STREAM_PLAYBACK);
85 if (ret)
86 goto out;
87 }
88
89 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
90 pr_debug("atmel-pcm: allocating PCM capture DMA buffer\n");
91 ret = atmel_pcm_preallocate_dma_buffer(pcm,
92 SNDRV_PCM_STREAM_CAPTURE);
93 if (ret)
94 goto out;
95 }
96 out:
97 return ret;
98}
99EXPORT_SYMBOL_GPL(atmel_pcm_new);
100
101void atmel_pcm_free(struct snd_pcm *pcm)
102{
103 struct snd_pcm_substream *substream;
104 struct snd_dma_buffer *buf;
105 int stream;
106
107 for (stream = 0; stream < 2; stream++) {
108 substream = pcm->streams[stream].substream;
109 if (!substream)
110 continue;
111
112 buf = &substream->dma_buffer;
113 if (!buf->area)
114 continue;
115 dma_free_coherent(pcm->card->dev, buf->bytes,
116 buf->area, buf->addr);
117 buf->area = NULL;
118 }
119}
120EXPORT_SYMBOL_GPL(atmel_pcm_free);
121
diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h
index 12ae814eff21..6eaf081cad50 100644
--- a/sound/soc/atmel/atmel-pcm.h
+++ b/sound/soc/atmel/atmel-pcm.h
@@ -83,11 +83,6 @@ struct atmel_pcm_dma_params {
83#define ssc_readx(base, reg) (__raw_readl((base) + (reg))) 83#define ssc_readx(base, reg) (__raw_readl((base) + (reg)))
84#define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg)) 84#define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg))
85 85
86int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd);
87void atmel_pcm_free(struct snd_pcm *pcm);
88int atmel_pcm_mmap(struct snd_pcm_substream *substream,
89 struct vm_area_struct *vma);
90
91#if defined(CONFIG_SND_ATMEL_SOC_PDC) || \ 86#if defined(CONFIG_SND_ATMEL_SOC_PDC) || \
92 defined(CONFIG_SND_ATMEL_SOC_PDC_MODULE) 87 defined(CONFIG_SND_ATMEL_SOC_PDC_MODULE)
93int atmel_pcm_pdc_platform_register(struct device *dev); 88int atmel_pcm_pdc_platform_register(struct device *dev);
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index fb0b7e8b08ff..841d05946b88 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -187,6 +187,94 @@ static irqreturn_t atmel_ssc_interrupt(int irq, void *dev_id)
187 return IRQ_HANDLED; 187 return IRQ_HANDLED;
188} 188}
189 189
190/*
191 * When the bit clock is input, limit the maximum rate according to the
192 * Serial Clock Ratio Considerations section from the SSC documentation:
193 *
194 * The Transmitter and the Receiver can be programmed to operate
195 * with the clock signals provided on either the TK or RK pins.
196 * This allows the SSC to support many slave-mode data transfers.
197 * In this case, the maximum clock speed allowed on the RK pin is:
198 * - Peripheral clock divided by 2 if Receiver Frame Synchro is input
199 * - Peripheral clock divided by 3 if Receiver Frame Synchro is output
200 * In addition, the maximum clock speed allowed on the TK pin is:
201 * - Peripheral clock divided by 6 if Transmit Frame Synchro is input
202 * - Peripheral clock divided by 2 if Transmit Frame Synchro is output
203 *
204 * When the bit clock is output, limit the rate according to the
205 * SSC divider restrictions.
206 */
207static int atmel_ssc_hw_rule_rate(struct snd_pcm_hw_params *params,
208 struct snd_pcm_hw_rule *rule)
209{
210 struct atmel_ssc_info *ssc_p = rule->private;
211 struct ssc_device *ssc = ssc_p->ssc;
212 struct snd_interval *i = hw_param_interval(params, rule->var);
213 struct snd_interval t;
214 struct snd_ratnum r = {
215 .den_min = 1,
216 .den_max = 4095,
217 .den_step = 1,
218 };
219 unsigned int num = 0, den = 0;
220 int frame_size;
221 int mck_div = 2;
222 int ret;
223
224 frame_size = snd_soc_params_to_frame_size(params);
225 if (frame_size < 0)
226 return frame_size;
227
228 switch (ssc_p->daifmt & SND_SOC_DAIFMT_MASTER_MASK) {
229 case SND_SOC_DAIFMT_CBM_CFS:
230 if ((ssc_p->dir_mask & SSC_DIR_MASK_CAPTURE)
231 && ssc->clk_from_rk_pin)
232 /* Receiver Frame Synchro (i.e. capture)
233 * is output (format is _CFS) and the RK pin
234 * is used for input (format is _CBM_).
235 */
236 mck_div = 3;
237 break;
238
239 case SND_SOC_DAIFMT_CBM_CFM:
240 if ((ssc_p->dir_mask & SSC_DIR_MASK_PLAYBACK)
241 && !ssc->clk_from_rk_pin)
242 /* Transmit Frame Synchro (i.e. playback)
243 * is input (format is _CFM) and the TK pin
244 * is used for input (format _CBM_ but not
245 * using the RK pin).
246 */
247 mck_div = 6;
248 break;
249 }
250
251 switch (ssc_p->daifmt & SND_SOC_DAIFMT_MASTER_MASK) {
252 case SND_SOC_DAIFMT_CBS_CFS:
253 r.num = ssc_p->mck_rate / mck_div / frame_size;
254
255 ret = snd_interval_ratnum(i, 1, &r, &num, &den);
256 if (ret >= 0 && den && rule->var == SNDRV_PCM_HW_PARAM_RATE) {
257 params->rate_num = num;
258 params->rate_den = den;
259 }
260 break;
261
262 case SND_SOC_DAIFMT_CBM_CFS:
263 case SND_SOC_DAIFMT_CBM_CFM:
264 t.min = 8000;
265 t.max = ssc_p->mck_rate / mck_div / frame_size;
266 t.openmin = t.openmax = 0;
267 t.integer = 0;
268 ret = snd_interval_refine(i, &t);
269 break;
270
271 default:
272 ret = -EINVAL;
273 break;
274 }
275
276 return ret;
277}
190 278
191/*-------------------------------------------------------------------------*\ 279/*-------------------------------------------------------------------------*\
192 * DAI functions 280 * DAI functions
@@ -200,6 +288,7 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream,
200 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id]; 288 struct atmel_ssc_info *ssc_p = &ssc_info[dai->id];
201 struct atmel_pcm_dma_params *dma_params; 289 struct atmel_pcm_dma_params *dma_params;
202 int dir, dir_mask; 290 int dir, dir_mask;
291 int ret;
203 292
204 pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n", 293 pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n",
205 ssc_readl(ssc_p->ssc->regs, SR)); 294 ssc_readl(ssc_p->ssc->regs, SR));
@@ -207,6 +296,7 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream,
207 /* Enable PMC peripheral clock for this SSC */ 296 /* Enable PMC peripheral clock for this SSC */
208 pr_debug("atmel_ssc_dai: Starting clock\n"); 297 pr_debug("atmel_ssc_dai: Starting clock\n");
209 clk_enable(ssc_p->ssc->clk); 298 clk_enable(ssc_p->ssc->clk);
299 ssc_p->mck_rate = clk_get_rate(ssc_p->ssc->clk);
210 300
211 /* Reset the SSC to keep it at a clean status */ 301 /* Reset the SSC to keep it at a clean status */
212 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST)); 302 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
@@ -219,6 +309,17 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream,
219 dir_mask = SSC_DIR_MASK_CAPTURE; 309 dir_mask = SSC_DIR_MASK_CAPTURE;
220 } 310 }
221 311
312 ret = snd_pcm_hw_rule_add(substream->runtime, 0,
313 SNDRV_PCM_HW_PARAM_RATE,
314 atmel_ssc_hw_rule_rate,
315 ssc_p,
316 SNDRV_PCM_HW_PARAM_FRAME_BITS,
317 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
318 if (ret < 0) {
319 dev_err(dai->dev, "Failed to specify rate rule: %d\n", ret);
320 return ret;
321 }
322
222 dma_params = &ssc_dma_params[dai->id][dir]; 323 dma_params = &ssc_dma_params[dai->id][dir];
223 dma_params->ssc = ssc_p->ssc; 324 dma_params->ssc = ssc_p->ssc;
224 dma_params->substream = substream; 325 dma_params->substream = substream;
@@ -783,8 +884,6 @@ static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
783# define atmel_ssc_resume NULL 884# define atmel_ssc_resume NULL
784#endif /* CONFIG_PM */ 885#endif /* CONFIG_PM */
785 886
786#define ATMEL_SSC_RATES (SNDRV_PCM_RATE_8000_96000)
787
788#define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ 887#define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
789 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 888 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
790 889
@@ -804,12 +903,16 @@ static struct snd_soc_dai_driver atmel_ssc_dai = {
804 .playback = { 903 .playback = {
805 .channels_min = 1, 904 .channels_min = 1,
806 .channels_max = 2, 905 .channels_max = 2,
807 .rates = ATMEL_SSC_RATES, 906 .rates = SNDRV_PCM_RATE_CONTINUOUS,
907 .rate_min = 8000,
908 .rate_max = 384000,
808 .formats = ATMEL_SSC_FORMATS,}, 909 .formats = ATMEL_SSC_FORMATS,},
809 .capture = { 910 .capture = {
810 .channels_min = 1, 911 .channels_min = 1,
811 .channels_max = 2, 912 .channels_max = 2,
812 .rates = ATMEL_SSC_RATES, 913 .rates = SNDRV_PCM_RATE_CONTINUOUS,
914 .rate_min = 8000,
915 .rate_max = 384000,
813 .formats = ATMEL_SSC_FORMATS,}, 916 .formats = ATMEL_SSC_FORMATS,},
814 .ops = &atmel_ssc_dai_ops, 917 .ops = &atmel_ssc_dai_ops,
815}; 918};
diff --git a/sound/soc/atmel/atmel_ssc_dai.h b/sound/soc/atmel/atmel_ssc_dai.h
index b1f08d511495..80b153857a88 100644
--- a/sound/soc/atmel/atmel_ssc_dai.h
+++ b/sound/soc/atmel/atmel_ssc_dai.h
@@ -115,6 +115,7 @@ struct atmel_ssc_info {
115 unsigned short rcmr_period; 115 unsigned short rcmr_period;
116 struct atmel_pcm_dma_params *dma_params[2]; 116 struct atmel_pcm_dma_params *dma_params[2];
117 struct atmel_ssc_state ssc_state; 117 struct atmel_ssc_state ssc_state;
118 unsigned long mck_rate;
118}; 119};
119 120
120int atmel_ssc_set_audio(int ssc_id); 121int atmel_ssc_set_audio(int ssc_id);
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index ea9f0e31f9d4..061c46587628 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -70,6 +70,7 @@ config SND_SOC_ALL_CODECS
70 select SND_SOC_MAX98090 if I2C 70 select SND_SOC_MAX98090 if I2C
71 select SND_SOC_MAX98095 if I2C 71 select SND_SOC_MAX98095 if I2C
72 select SND_SOC_MAX98357A if GPIOLIB 72 select SND_SOC_MAX98357A if GPIOLIB
73 select SND_SOC_MAX98925 if I2C
73 select SND_SOC_MAX9850 if I2C 74 select SND_SOC_MAX9850 if I2C
74 select SND_SOC_MAX9768 if I2C 75 select SND_SOC_MAX9768 if I2C
75 select SND_SOC_MAX9877 if I2C 76 select SND_SOC_MAX9877 if I2C
@@ -141,7 +142,8 @@ config SND_SOC_ALL_CODECS
141 select SND_SOC_WM8770 if SPI_MASTER 142 select SND_SOC_WM8770 if SPI_MASTER
142 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI 143 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
143 select SND_SOC_WM8782 144 select SND_SOC_WM8782
144 select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI 145 select SND_SOC_WM8804_I2C if I2C
146 select SND_SOC_WM8804_SPI if SPI_MASTER
145 select SND_SOC_WM8900 if I2C 147 select SND_SOC_WM8900 if I2C
146 select SND_SOC_WM8903 if I2C 148 select SND_SOC_WM8903 if I2C
147 select SND_SOC_WM8904 if I2C 149 select SND_SOC_WM8904 if I2C
@@ -460,6 +462,9 @@ config SND_SOC_MAX98095
460config SND_SOC_MAX98357A 462config SND_SOC_MAX98357A
461 tristate 463 tristate
462 464
465config SND_SOC_MAX98925
466 tristate
467
463config SND_SOC_MAX9850 468config SND_SOC_MAX9850
464 tristate 469 tristate
465 470
@@ -744,8 +749,19 @@ config SND_SOC_WM8782
744 tristate 749 tristate
745 750
746config SND_SOC_WM8804 751config SND_SOC_WM8804
747 tristate "Wolfson Microelectronics WM8804 S/PDIF transceiver" 752 tristate
748 depends on SND_SOC_I2C_AND_SPI 753
754config SND_SOC_WM8804_I2C
755 tristate "Wolfson Microelectronics WM8804 S/PDIF transceiver I2C"
756 depends on I2C
757 select SND_SOC_WM8804
758 select REGMAP_I2C
759
760config SND_SOC_WM8804_SPI
761 tristate "Wolfson Microelectronics WM8804 S/PDIF transceiver SPI"
762 depends on SPI_MASTER
763 select SND_SOC_WM8804
764 select REGMAP_SPI
749 765
750config SND_SOC_WM8900 766config SND_SOC_WM8900
751 tristate 767 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 69b8666d187a..abe2d7edf65c 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -65,6 +65,7 @@ snd-soc-max98088-objs := max98088.o
65snd-soc-max98090-objs := max98090.o 65snd-soc-max98090-objs := max98090.o
66snd-soc-max98095-objs := max98095.o 66snd-soc-max98095-objs := max98095.o
67snd-soc-max98357a-objs := max98357a.o 67snd-soc-max98357a-objs := max98357a.o
68snd-soc-max98925-objs := max98925.o
68snd-soc-max9850-objs := max9850.o 69snd-soc-max9850-objs := max9850.o
69snd-soc-mc13783-objs := mc13783.o 70snd-soc-mc13783-objs := mc13783.o
70snd-soc-ml26124-objs := ml26124.o 71snd-soc-ml26124-objs := ml26124.o
@@ -145,6 +146,8 @@ snd-soc-wm8770-objs := wm8770.o
145snd-soc-wm8776-objs := wm8776.o 146snd-soc-wm8776-objs := wm8776.o
146snd-soc-wm8782-objs := wm8782.o 147snd-soc-wm8782-objs := wm8782.o
147snd-soc-wm8804-objs := wm8804.o 148snd-soc-wm8804-objs := wm8804.o
149snd-soc-wm8804-i2c-objs := wm8804-i2c.o
150snd-soc-wm8804-spi-objs := wm8804-spi.o
148snd-soc-wm8900-objs := wm8900.o 151snd-soc-wm8900-objs := wm8900.o
149snd-soc-wm8903-objs := wm8903.o 152snd-soc-wm8903-objs := wm8903.o
150snd-soc-wm8904-objs := wm8904.o 153snd-soc-wm8904-objs := wm8904.o
@@ -247,6 +250,7 @@ obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
247obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o 250obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o
248obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o 251obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o
249obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o 252obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o
253obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
250obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 254obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
251obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o 255obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
252obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o 256obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
@@ -323,6 +327,8 @@ obj-$(CONFIG_SND_SOC_WM8770) += snd-soc-wm8770.o
323obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o 327obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
324obj-$(CONFIG_SND_SOC_WM8782) += snd-soc-wm8782.o 328obj-$(CONFIG_SND_SOC_WM8782) += snd-soc-wm8782.o
325obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o 329obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o
330obj-$(CONFIG_SND_SOC_WM8804_I2C) += snd-soc-wm8804-i2c.o
331obj-$(CONFIG_SND_SOC_WM8804_SPI) += snd-soc-wm8804-spi.o
326obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o 332obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
327obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o 333obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
328obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o 334obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 7895689588da..88ca9cb0ce79 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -2003,7 +2003,6 @@ static int ab8500_audio_setup_mics(struct snd_soc_codec *codec,
2003 2003
2004 return 0; 2004 return 0;
2005} 2005}
2006EXPORT_SYMBOL_GPL(ab8500_audio_setup_mics);
2007 2006
2008static int ab8500_audio_set_ear_cmv(struct snd_soc_codec *codec, 2007static int ab8500_audio_set_ear_cmv(struct snd_soc_codec *codec,
2009 enum ear_cm_voltage ear_cmv) 2008 enum ear_cm_voltage ear_cmv)
@@ -2036,7 +2035,6 @@ static int ab8500_audio_set_ear_cmv(struct snd_soc_codec *codec,
2036 2035
2037 return 0; 2036 return 0;
2038} 2037}
2039EXPORT_SYMBOL_GPL(ab8500_audio_set_ear_cmv);
2040 2038
2041static int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai, 2039static int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai,
2042 unsigned int delay) 2040 unsigned int delay)
diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c
index 70ab35744aba..7ad8e156e2df 100644
--- a/sound/soc/codecs/adau1977.c
+++ b/sound/soc/codecs/adau1977.c
@@ -938,22 +938,15 @@ int adau1977_probe(struct device *dev, struct regmap *regmap,
938 adau1977->dvdd_reg = NULL; 938 adau1977->dvdd_reg = NULL;
939 } 939 }
940 940
941 adau1977->reset_gpio = devm_gpiod_get(dev, "reset"); 941 adau1977->reset_gpio = devm_gpiod_get_optional(dev, "reset",
942 if (IS_ERR(adau1977->reset_gpio)) { 942 GPIOD_OUT_LOW);
943 ret = PTR_ERR(adau1977->reset_gpio); 943 if (IS_ERR(adau1977->reset_gpio))
944 if (ret != -ENOENT && ret != -ENOSYS) 944 return PTR_ERR(adau1977->reset_gpio);
945 return PTR_ERR(adau1977->reset_gpio);
946 adau1977->reset_gpio = NULL;
947 }
948 945
949 dev_set_drvdata(dev, adau1977); 946 dev_set_drvdata(dev, adau1977);
950 947
951 if (adau1977->reset_gpio) { 948 if (adau1977->reset_gpio)
952 ret = gpiod_direction_output(adau1977->reset_gpio, 0);
953 if (ret)
954 return ret;
955 ndelay(100); 949 ndelay(100);
956 }
957 950
958 ret = adau1977_power_enable(adau1977); 951 ret = adau1977_power_enable(adau1977);
959 if (ret) 952 if (ret)
diff --git a/sound/soc/codecs/ak4554.c b/sound/soc/codecs/ak4554.c
index 16ce9f9fefa1..298dedc05140 100644
--- a/sound/soc/codecs/ak4554.c
+++ b/sound/soc/codecs/ak4554.c
@@ -84,7 +84,7 @@ static int ak4554_soc_remove(struct platform_device *pdev)
84 return 0; 84 return 0;
85} 85}
86 86
87static struct of_device_id ak4554_of_match[] = { 87static const struct of_device_id ak4554_of_match[] = {
88 { .compatible = "asahi-kasei,ak4554" }, 88 { .compatible = "asahi-kasei,ak4554" },
89 {}, 89 {},
90}; 90};
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index dde8b49c19ad..13585e88f597 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -97,6 +97,9 @@
97#define PMMP (1 << 2) /* MPWR pin Power Management */ 97#define PMMP (1 << 2) /* MPWR pin Power Management */
98#define MGAIN0 (1 << 0) /* MIC amp gain*/ 98#define MGAIN0 (1 << 0) /* MIC amp gain*/
99 99
100/* SG_SL2 */
101#define LOPS (1 << 6) /* Stero Line-out Power Save Mode */
102
100/* TIMER */ 103/* TIMER */
101#define ZTM(param) ((param & 0x3) << 4) /* ALC Zero Crossing TimeOut */ 104#define ZTM(param) ((param & 0x3) << 4) /* ALC Zero Crossing TimeOut */
102#define WTM(param) (((param & 0x4) << 4) | ((param & 0x3) << 2)) 105#define WTM(param) (((param & 0x4) << 4) | ((param & 0x3) << 2))
@@ -168,6 +171,29 @@ static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = {
168 SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0), 171 SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0),
169}; 172};
170 173
174/* event handlers */
175static int ak4642_lout_event(struct snd_soc_dapm_widget *w,
176 struct snd_kcontrol *kcontrol, int event)
177{
178 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
179
180 switch (event) {
181 case SND_SOC_DAPM_PRE_PMD:
182 case SND_SOC_DAPM_PRE_PMU:
183 /* Power save mode ON */
184 snd_soc_update_bits(codec, SG_SL2, LOPS, LOPS);
185 break;
186 case SND_SOC_DAPM_POST_PMU:
187 case SND_SOC_DAPM_POST_PMD:
188 /* Power save mode OFF */
189 mdelay(300);
190 snd_soc_update_bits(codec, SG_SL2, LOPS, 0);
191 break;
192 }
193
194 return 0;
195}
196
171static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = { 197static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
172 198
173 /* Outputs */ 199 /* Outputs */
@@ -182,12 +208,15 @@ static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
182 208
183 SND_SOC_DAPM_PGA("DACH", MD_CTL4, 0, 0, NULL, 0), 209 SND_SOC_DAPM_PGA("DACH", MD_CTL4, 0, 0, NULL, 0),
184 210
185 SND_SOC_DAPM_MIXER("LINEOUT Mixer", PW_MGMT1, 3, 0, 211 SND_SOC_DAPM_MIXER_E("LINEOUT Mixer", PW_MGMT1, 3, 0,
186 &ak4642_lout_mixer_controls[0], 212 &ak4642_lout_mixer_controls[0],
187 ARRAY_SIZE(ak4642_lout_mixer_controls)), 213 ARRAY_SIZE(ak4642_lout_mixer_controls),
214 ak4642_lout_event,
215 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
216 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
188 217
189 /* DAC */ 218 /* DAC */
190 SND_SOC_DAPM_DAC("DAC", "HiFi Playback", PW_MGMT1, 2, 0), 219 SND_SOC_DAPM_DAC("DAC", NULL, PW_MGMT1, 2, 0),
191}; 220};
192 221
193static const struct snd_soc_dapm_route ak4642_intercon[] = { 222static const struct snd_soc_dapm_route ak4642_intercon[] = {
@@ -205,6 +234,8 @@ static const struct snd_soc_dapm_route ak4642_intercon[] = {
205 {"DACH", NULL, "DAC"}, 234 {"DACH", NULL, "DAC"},
206 235
207 {"LINEOUT Mixer", "DACL", "DAC"}, 236 {"LINEOUT Mixer", "DACL", "DAC"},
237
238 { "DAC", NULL, "Playback" },
208}; 239};
209 240
210/* 241/*
@@ -468,13 +499,13 @@ static struct snd_soc_dai_driver ak4642_dai = {
468 .name = "ak4642-hifi", 499 .name = "ak4642-hifi",
469 .playback = { 500 .playback = {
470 .stream_name = "Playback", 501 .stream_name = "Playback",
471 .channels_min = 1, 502 .channels_min = 2,
472 .channels_max = 2, 503 .channels_max = 2,
473 .rates = SNDRV_PCM_RATE_8000_48000, 504 .rates = SNDRV_PCM_RATE_8000_48000,
474 .formats = SNDRV_PCM_FMTBIT_S16_LE }, 505 .formats = SNDRV_PCM_FMTBIT_S16_LE },
475 .capture = { 506 .capture = {
476 .stream_name = "Capture", 507 .stream_name = "Capture",
477 .channels_min = 1, 508 .channels_min = 2,
478 .channels_max = 2, 509 .channels_max = 2,
479 .rates = SNDRV_PCM_RATE_8000_48000, 510 .rates = SNDRV_PCM_RATE_8000_48000,
480 .formats = SNDRV_PCM_FMTBIT_S16_LE }, 511 .formats = SNDRV_PCM_FMTBIT_S16_LE },
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 95d31d6291ac..57da0ceda03f 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -1902,7 +1902,7 @@ static int arizona_is_enabled_fll(struct arizona_fll *fll)
1902static int arizona_enable_fll(struct arizona_fll *fll) 1902static int arizona_enable_fll(struct arizona_fll *fll)
1903{ 1903{
1904 struct arizona *arizona = fll->arizona; 1904 struct arizona *arizona = fll->arizona;
1905 int ret; 1905 unsigned long time_left;
1906 bool use_sync = false; 1906 bool use_sync = false;
1907 int already_enabled = arizona_is_enabled_fll(fll); 1907 int already_enabled = arizona_is_enabled_fll(fll);
1908 struct arizona_fll_cfg cfg; 1908 struct arizona_fll_cfg cfg;
@@ -1978,9 +1978,9 @@ static int arizona_enable_fll(struct arizona_fll *fll)
1978 regmap_update_bits_async(arizona->regmap, fll->base + 1, 1978 regmap_update_bits_async(arizona->regmap, fll->base + 1,
1979 ARIZONA_FLL1_FREERUN, 0); 1979 ARIZONA_FLL1_FREERUN, 0);
1980 1980
1981 ret = wait_for_completion_timeout(&fll->ok, 1981 time_left = wait_for_completion_timeout(&fll->ok,
1982 msecs_to_jiffies(250)); 1982 msecs_to_jiffies(250));
1983 if (ret == 0) 1983 if (time_left == 0)
1984 arizona_fll_warn(fll, "Timed out waiting for lock\n"); 1984 arizona_fll_warn(fll, "Timed out waiting for lock\n");
1985 1985
1986 return 0; 1986 return 0;
diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c
index f2b8aad21274..60598b230341 100644
--- a/sound/soc/codecs/cs35l32.c
+++ b/sound/soc/codecs/cs35l32.c
@@ -437,20 +437,13 @@ static int cs35l32_i2c_probe(struct i2c_client *i2c_client,
437 } 437 }
438 438
439 /* Reset the Device */ 439 /* Reset the Device */
440 cs35l32->reset_gpio = devm_gpiod_get(&i2c_client->dev, 440 cs35l32->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev,
441 "reset-gpios"); 441 "reset", GPIOD_OUT_LOW);
442 if (IS_ERR(cs35l32->reset_gpio)) { 442 if (IS_ERR(cs35l32->reset_gpio))
443 ret = PTR_ERR(cs35l32->reset_gpio); 443 return PTR_ERR(cs35l32->reset_gpio);
444 if (ret != -ENOENT && ret != -ENOSYS) 444
445 return ret; 445 if (cs35l32->reset_gpio)
446
447 cs35l32->reset_gpio = NULL;
448 } else {
449 ret = gpiod_direction_output(cs35l32->reset_gpio, 0);
450 if (ret)
451 return ret;
452 gpiod_set_value_cansleep(cs35l32->reset_gpio, 1); 446 gpiod_set_value_cansleep(cs35l32->reset_gpio, 1);
453 }
454 447
455 /* initialize codec */ 448 /* initialize codec */
456 ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_AB, &reg); 449 ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_AB, &reg);
diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c
index ce6086835ebd..cac48ddf3ba6 100644
--- a/sound/soc/codecs/cs4265.c
+++ b/sound/soc/codecs/cs4265.c
@@ -605,21 +605,14 @@ static int cs4265_i2c_probe(struct i2c_client *i2c_client,
605 return ret; 605 return ret;
606 } 606 }
607 607
608 cs4265->reset_gpio = devm_gpiod_get(&i2c_client->dev, 608 cs4265->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev,
609 "reset-gpios"); 609 "reset", GPIOD_OUT_LOW);
610 if (IS_ERR(cs4265->reset_gpio)) { 610 if (IS_ERR(cs4265->reset_gpio))
611 ret = PTR_ERR(cs4265->reset_gpio); 611 return PTR_ERR(cs4265->reset_gpio);
612 if (ret != -ENOENT && ret != -ENOSYS) 612
613 return ret; 613 if (cs4265->reset_gpio) {
614
615 cs4265->reset_gpio = NULL;
616 } else {
617 ret = gpiod_direction_output(cs4265->reset_gpio, 0);
618 if (ret)
619 return ret;
620 mdelay(1); 614 mdelay(1);
621 gpiod_set_value_cansleep(cs4265->reset_gpio, 1); 615 gpiod_set_value_cansleep(cs4265->reset_gpio, 1);
622
623 } 616 }
624 617
625 i2c_set_clientdata(i2c_client, cs4265); 618 i2c_set_clientdata(i2c_client, cs4265);
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index 7d3a6accaf9a..e770ee6f36da 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -561,10 +561,10 @@ static int cs4271_codec_probe(struct snd_soc_codec *codec)
561 if (gpio_is_valid(cs4271->gpio_nreset)) { 561 if (gpio_is_valid(cs4271->gpio_nreset)) {
562 /* Reset codec */ 562 /* Reset codec */
563 gpio_direction_output(cs4271->gpio_nreset, 0); 563 gpio_direction_output(cs4271->gpio_nreset, 0);
564 udelay(1); 564 mdelay(1);
565 gpio_set_value(cs4271->gpio_nreset, 1); 565 gpio_set_value(cs4271->gpio_nreset, 1);
566 /* Give the codec time to wake up */ 566 /* Give the codec time to wake up */
567 udelay(1); 567 mdelay(1);
568 } 568 }
569 569
570 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2, 570 ret = regmap_update_bits(cs4271->regmap, CS4271_MODE2,
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 0b10979513c4..0f334bc1b63c 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -420,7 +420,7 @@ static int cx20442_platform_probe(struct platform_device *pdev)
420 &cx20442_codec_dev, &cx20442_dai, 1); 420 &cx20442_codec_dev, &cx20442_dai, 1);
421} 421}
422 422
423static int __exit cx20442_platform_remove(struct platform_device *pdev) 423static int cx20442_platform_remove(struct platform_device *pdev)
424{ 424{
425 snd_soc_unregister_codec(&pdev->dev); 425 snd_soc_unregister_codec(&pdev->dev);
426 return 0; 426 return 0;
@@ -431,7 +431,7 @@ static struct platform_driver cx20442_platform_driver = {
431 .name = "cx20442-codec", 431 .name = "cx20442-codec",
432 }, 432 },
433 .probe = cx20442_platform_probe, 433 .probe = cx20442_platform_probe,
434 .remove = __exit_p(cx20442_platform_remove), 434 .remove = cx20442_platform_remove,
435}; 435};
436 436
437module_platform_driver(cx20442_platform_driver); 437module_platform_driver(cx20442_platform_driver);
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index b112b1c2c394..3e33ef2acf3c 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -2605,8 +2605,24 @@ err_enable:
2605 return ret; 2605 return ret;
2606} 2606}
2607 2607
2608static void max98090_i2c_shutdown(struct i2c_client *i2c)
2609{
2610 struct max98090_priv *max98090 = dev_get_drvdata(&i2c->dev);
2611
2612 /*
2613 * Enable volume smoothing, disable zero cross. This will cause
2614 * a quick 40ms ramp to mute on shutdown.
2615 */
2616 regmap_write(max98090->regmap,
2617 M98090_REG_LEVEL_CONTROL, M98090_VSENN_MASK);
2618 regmap_write(max98090->regmap,
2619 M98090_REG_DEVICE_SHUTDOWN, 0x00);
2620 msleep(40);
2621}
2622
2608static int max98090_i2c_remove(struct i2c_client *client) 2623static int max98090_i2c_remove(struct i2c_client *client)
2609{ 2624{
2625 max98090_i2c_shutdown(client);
2610 snd_soc_unregister_codec(&client->dev); 2626 snd_soc_unregister_codec(&client->dev);
2611 return 0; 2627 return 0;
2612} 2628}
@@ -2696,6 +2712,7 @@ static struct i2c_driver max98090_i2c_driver = {
2696 .acpi_match_table = ACPI_PTR(max98090_acpi_match), 2712 .acpi_match_table = ACPI_PTR(max98090_acpi_match),
2697 }, 2713 },
2698 .probe = max98090_i2c_probe, 2714 .probe = max98090_i2c_probe,
2715 .shutdown = max98090_i2c_shutdown,
2699 .remove = max98090_i2c_remove, 2716 .remove = max98090_i2c_remove,
2700 .id_table = max98090_i2c_id, 2717 .id_table = max98090_i2c_id,
2701}; 2718};
diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c
index e9e6efbc21dd..bf3e933ee895 100644
--- a/sound/soc/codecs/max98357a.c
+++ b/sound/soc/codecs/max98357a.c
@@ -26,8 +26,6 @@
26#include <sound/soc-dai.h> 26#include <sound/soc-dai.h>
27#include <sound/soc-dapm.h> 27#include <sound/soc-dapm.h>
28 28
29#define DRV_NAME "max98357a"
30
31static int max98357a_daiops_trigger(struct snd_pcm_substream *substream, 29static int max98357a_daiops_trigger(struct snd_pcm_substream *substream,
32 int cmd, struct snd_soc_dai *dai) 30 int cmd, struct snd_soc_dai *dai)
33{ 31{
@@ -87,9 +85,9 @@ static struct snd_soc_dai_ops max98357a_dai_ops = {
87}; 85};
88 86
89static struct snd_soc_dai_driver max98357a_dai_driver = { 87static struct snd_soc_dai_driver max98357a_dai_driver = {
90 .name = DRV_NAME, 88 .name = "HiFi",
91 .playback = { 89 .playback = {
92 .stream_name = DRV_NAME "-playback", 90 .stream_name = "HiFi Playback",
93 .formats = SNDRV_PCM_FMTBIT_S16 | 91 .formats = SNDRV_PCM_FMTBIT_S16 |
94 SNDRV_PCM_FMTBIT_S24 | 92 SNDRV_PCM_FMTBIT_S24 |
95 SNDRV_PCM_FMTBIT_S32, 93 SNDRV_PCM_FMTBIT_S32,
@@ -127,7 +125,7 @@ static int max98357a_platform_remove(struct platform_device *pdev)
127 125
128#ifdef CONFIG_OF 126#ifdef CONFIG_OF
129static const struct of_device_id max98357a_device_id[] = { 127static const struct of_device_id max98357a_device_id[] = {
130 { .compatible = "maxim," DRV_NAME, }, 128 { .compatible = "maxim,max98357a" },
131 {} 129 {}
132}; 130};
133MODULE_DEVICE_TABLE(of, max98357a_device_id); 131MODULE_DEVICE_TABLE(of, max98357a_device_id);
@@ -135,7 +133,7 @@ MODULE_DEVICE_TABLE(of, max98357a_device_id);
135 133
136static struct platform_driver max98357a_platform_driver = { 134static struct platform_driver max98357a_platform_driver = {
137 .driver = { 135 .driver = {
138 .name = DRV_NAME, 136 .name = "max98357a",
139 .of_match_table = of_match_ptr(max98357a_device_id), 137 .of_match_table = of_match_ptr(max98357a_device_id),
140 }, 138 },
141 .probe = max98357a_platform_probe, 139 .probe = max98357a_platform_probe,
@@ -145,4 +143,3 @@ module_platform_driver(max98357a_platform_driver);
145 143
146MODULE_DESCRIPTION("Maxim MAX98357A Codec Driver"); 144MODULE_DESCRIPTION("Maxim MAX98357A Codec Driver");
147MODULE_LICENSE("GPL v2"); 145MODULE_LICENSE("GPL v2");
148MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/codecs/max98925.c b/sound/soc/codecs/max98925.c
new file mode 100644
index 000000000000..9b5a17de4690
--- /dev/null
+++ b/sound/soc/codecs/max98925.c
@@ -0,0 +1,655 @@
1/*
2 * max98925.c -- ALSA SoC Stereo MAX98925 driver
3 * Copyright 2013-15 Maxim Integrated Products
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/delay.h>
9#include <linux/i2c.h>
10#include <linux/module.h>
11#include <linux/regmap.h>
12#include <linux/slab.h>
13#include <linux/cdev.h>
14#include <sound/pcm.h>
15#include <sound/pcm_params.h>
16#include <sound/soc.h>
17#include <sound/tlv.h>
18#include "max98925.h"
19
20static const char *const dai_text[] = {
21 "Left", "Right", "LeftRight", "LeftRightDiv2",
22};
23
24static const char * const max98925_boost_voltage_text[] = {
25 "8.5V", "8.25V", "8.0V", "7.75V", "7.5V", "7.25V", "7.0V", "6.75V",
26 "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V"
27};
28
29static SOC_ENUM_SINGLE_DECL(max98925_boost_voltage,
30 MAX98925_CONFIGURATION, M98925_BST_VOUT_SHIFT,
31 max98925_boost_voltage_text);
32
33static const char *const hpf_text[] = {
34 "Disable", "DC Block", "100Hz", "200Hz", "400Hz", "800Hz",
35};
36
37static const struct reg_default max98925_reg[] = {
38 { 0x0B, 0x00 }, /* IRQ Enable0 */
39 { 0x0C, 0x00 }, /* IRQ Enable1 */
40 { 0x0D, 0x00 }, /* IRQ Enable2 */
41 { 0x0E, 0x00 }, /* IRQ Clear0 */
42 { 0x0F, 0x00 }, /* IRQ Clear1 */
43 { 0x10, 0x00 }, /* IRQ Clear2 */
44 { 0x11, 0xC0 }, /* Map0 */
45 { 0x12, 0x00 }, /* Map1 */
46 { 0x13, 0x00 }, /* Map2 */
47 { 0x14, 0xF0 }, /* Map3 */
48 { 0x15, 0x00 }, /* Map4 */
49 { 0x16, 0xAB }, /* Map5 */
50 { 0x17, 0x89 }, /* Map6 */
51 { 0x18, 0x00 }, /* Map7 */
52 { 0x19, 0x00 }, /* Map8 */
53 { 0x1A, 0x06 }, /* DAI Clock Mode 1 */
54 { 0x1B, 0xC0 }, /* DAI Clock Mode 2 */
55 { 0x1C, 0x00 }, /* DAI Clock Divider Denominator MSBs */
56 { 0x1D, 0x00 }, /* DAI Clock Divider Denominator LSBs */
57 { 0x1E, 0xF0 }, /* DAI Clock Divider Numerator MSBs */
58 { 0x1F, 0x00 }, /* DAI Clock Divider Numerator LSBs */
59 { 0x20, 0x50 }, /* Format */
60 { 0x21, 0x00 }, /* TDM Slot Select */
61 { 0x22, 0x00 }, /* DOUT Configuration VMON */
62 { 0x23, 0x00 }, /* DOUT Configuration IMON */
63 { 0x24, 0x00 }, /* DOUT Configuration VBAT */
64 { 0x25, 0x00 }, /* DOUT Configuration VBST */
65 { 0x26, 0x00 }, /* DOUT Configuration FLAG */
66 { 0x27, 0xFF }, /* DOUT HiZ Configuration 1 */
67 { 0x28, 0xFF }, /* DOUT HiZ Configuration 2 */
68 { 0x29, 0xFF }, /* DOUT HiZ Configuration 3 */
69 { 0x2A, 0xFF }, /* DOUT HiZ Configuration 4 */
70 { 0x2B, 0x02 }, /* DOUT Drive Strength */
71 { 0x2C, 0x90 }, /* Filters */
72 { 0x2D, 0x00 }, /* Gain */
73 { 0x2E, 0x02 }, /* Gain Ramping */
74 { 0x2F, 0x00 }, /* Speaker Amplifier */
75 { 0x30, 0x0A }, /* Threshold */
76 { 0x31, 0x00 }, /* ALC Attack */
77 { 0x32, 0x80 }, /* ALC Atten and Release */
78 { 0x33, 0x00 }, /* ALC Infinite Hold Release */
79 { 0x34, 0x92 }, /* ALC Configuration */
80 { 0x35, 0x01 }, /* Boost Converter */
81 { 0x36, 0x00 }, /* Block Enable */
82 { 0x37, 0x00 }, /* Configuration */
83 { 0x38, 0x00 }, /* Global Enable */
84 { 0x3A, 0x00 }, /* Boost Limiter */
85};
86
87static const struct soc_enum max98925_dai_enum =
88 SOC_ENUM_SINGLE(MAX98925_GAIN, 5, ARRAY_SIZE(dai_text), dai_text);
89
90static const struct soc_enum max98925_hpf_enum =
91 SOC_ENUM_SINGLE(MAX98925_FILTERS, 0, ARRAY_SIZE(hpf_text), hpf_text);
92
93static const struct snd_kcontrol_new max98925_hpf_sel_mux =
94 SOC_DAPM_ENUM("Rc Filter MUX Mux", max98925_hpf_enum);
95
96static const struct snd_kcontrol_new max98925_dai_sel_mux =
97 SOC_DAPM_ENUM("DAI IN MUX Mux", max98925_dai_enum);
98
99static int max98925_dac_event(struct snd_soc_dapm_widget *w,
100 struct snd_kcontrol *kcontrol, int event)
101{
102 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
103 struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
104
105 switch (event) {
106 case SND_SOC_DAPM_PRE_PMU:
107 regmap_update_bits(max98925->regmap,
108 MAX98925_BLOCK_ENABLE,
109 M98925_BST_EN_MASK |
110 M98925_ADC_IMON_EN_MASK | M98925_ADC_VMON_EN_MASK,
111 M98925_BST_EN_MASK |
112 M98925_ADC_IMON_EN_MASK | M98925_ADC_VMON_EN_MASK);
113 break;
114 case SND_SOC_DAPM_POST_PMD:
115 regmap_update_bits(max98925->regmap,
116 MAX98925_BLOCK_ENABLE, M98925_BST_EN_MASK |
117 M98925_ADC_IMON_EN_MASK | M98925_ADC_VMON_EN_MASK, 0);
118 break;
119 default:
120 return 0;
121 }
122 return 0;
123}
124
125static const struct snd_soc_dapm_widget max98925_dapm_widgets[] = {
126 SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
127 SND_SOC_DAPM_MUX("DAI IN MUX", SND_SOC_NOPM, 0, 0,
128 &max98925_dai_sel_mux),
129 SND_SOC_DAPM_MUX("Rc Filter MUX", SND_SOC_NOPM, 0, 0,
130 &max98925_hpf_sel_mux),
131 SND_SOC_DAPM_DAC_E("Amp Enable", NULL, MAX98925_BLOCK_ENABLE,
132 M98925_SPK_EN_SHIFT, 0, max98925_dac_event,
133 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
134 SND_SOC_DAPM_SUPPLY("Global Enable", MAX98925_GLOBAL_ENABLE,
135 M98925_EN_SHIFT, 0, NULL, 0),
136 SND_SOC_DAPM_OUTPUT("BE_OUT"),
137};
138
139static const struct snd_soc_dapm_route max98925_audio_map[] = {
140 {"DAI IN MUX", "Left", "DAI_OUT"},
141 {"DAI IN MUX", "Right", "DAI_OUT"},
142 {"DAI IN MUX", "LeftRight", "DAI_OUT"},
143 {"DAI IN MUX", "LeftRightDiv2", "DAI_OUT"},
144 {"Rc Filter MUX", "Disable", "DAI IN MUX"},
145 {"Rc Filter MUX", "DC Block", "DAI IN MUX"},
146 {"Rc Filter MUX", "100Hz", "DAI IN MUX"},
147 {"Rc Filter MUX", "200Hz", "DAI IN MUX"},
148 {"Rc Filter MUX", "400Hz", "DAI IN MUX"},
149 {"Rc Filter MUX", "800Hz", "DAI IN MUX"},
150 {"Amp Enable", NULL, "Rc Filter MUX"},
151 {"BE_OUT", NULL, "Amp Enable"},
152 {"BE_OUT", NULL, "Global Enable"},
153};
154
155static bool max98925_volatile_register(struct device *dev, unsigned int reg)
156{
157 switch (reg) {
158 case MAX98925_VBAT_DATA:
159 case MAX98925_VBST_DATA:
160 case MAX98925_LIVE_STATUS0:
161 case MAX98925_LIVE_STATUS1:
162 case MAX98925_LIVE_STATUS2:
163 case MAX98925_STATE0:
164 case MAX98925_STATE1:
165 case MAX98925_STATE2:
166 case MAX98925_FLAG0:
167 case MAX98925_FLAG1:
168 case MAX98925_FLAG2:
169 case MAX98925_REV_VERSION:
170 return true;
171 default:
172 return false;
173 }
174}
175
176static bool max98925_readable_register(struct device *dev, unsigned int reg)
177{
178 switch (reg) {
179 case MAX98925_IRQ_CLEAR0:
180 case MAX98925_IRQ_CLEAR1:
181 case MAX98925_IRQ_CLEAR2:
182 case MAX98925_ALC_HOLD_RLS:
183 return false;
184 default:
185 return true;
186 }
187}
188
189static DECLARE_TLV_DB_SCALE(max98925_spk_tlv, -600, 100, 0);
190
191static const struct snd_kcontrol_new max98925_snd_controls[] = {
192 SOC_SINGLE_TLV("Speaker Volume", MAX98925_GAIN,
193 M98925_SPK_GAIN_SHIFT, (1<<M98925_SPK_GAIN_WIDTH)-1, 0,
194 max98925_spk_tlv),
195 SOC_SINGLE("Ramp Switch", MAX98925_GAIN_RAMPING,
196 M98925_SPK_RMP_EN_SHIFT, 1, 0),
197 SOC_SINGLE("ZCD Switch", MAX98925_GAIN_RAMPING,
198 M98925_SPK_ZCD_EN_SHIFT, 1, 0),
199 SOC_SINGLE("ALC Switch", MAX98925_THRESHOLD,
200 M98925_ALC_EN_SHIFT, 1, 0),
201 SOC_SINGLE("ALC Threshold", MAX98925_THRESHOLD, M98925_ALC_TH_SHIFT,
202 (1<<M98925_ALC_TH_WIDTH)-1, 0),
203 SOC_ENUM("Boost Output Voltage", max98925_boost_voltage),
204};
205
206/* codec sample rate and n/m dividers parameter table */
207static const struct {
208 int rate;
209 int sr;
210 int divisors[3][2];
211} rate_table[] = {
212 {
213 .rate = 8000,
214 .sr = 0,
215 .divisors = { {1, 375}, {5, 1764}, {1, 384} }
216 },
217 {
218 .rate = 11025,
219 .sr = 1,
220 .divisors = { {147, 40000}, {1, 256}, {147, 40960} }
221 },
222 {
223 .rate = 12000,
224 .sr = 2,
225 .divisors = { {1, 250}, {5, 1176}, {1, 256} }
226 },
227 {
228 .rate = 16000,
229 .sr = 3,
230 .divisors = { {2, 375}, {5, 882}, {1, 192} }
231 },
232 {
233 .rate = 22050,
234 .sr = 4,
235 .divisors = { {147, 20000}, {1, 128}, {147, 20480} }
236 },
237 {
238 .rate = 24000,
239 .sr = 5,
240 .divisors = { {1, 125}, {5, 588}, {1, 128} }
241 },
242 {
243 .rate = 32000,
244 .sr = 6,
245 .divisors = { {4, 375}, {5, 441}, {1, 96} }
246 },
247 {
248 .rate = 44100,
249 .sr = 7,
250 .divisors = { {147, 10000}, {1, 64}, {147, 10240} }
251 },
252 {
253 .rate = 48000,
254 .sr = 8,
255 .divisors = { {2, 125}, {5, 294}, {1, 64} }
256 },
257};
258
259static inline int max98925_rate_value(struct snd_soc_codec *codec,
260 int rate, int clock, int *value, int *n, int *m)
261{
262 int ret = -EINVAL;
263 int i;
264
265 for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
266 if (rate_table[i].rate >= rate) {
267 *value = rate_table[i].sr;
268 *n = rate_table[i].divisors[clock][0];
269 *m = rate_table[i].divisors[clock][1];
270 ret = 0;
271 break;
272 }
273 }
274 dev_dbg(codec->dev, "%s: sample rate is %d, returning %d\n",
275 __func__, rate_table[i].rate, *value);
276 return ret;
277}
278
279static void max98925_set_sense_data(struct max98925_priv *max98925)
280{
281 /* set VMON slots */
282 regmap_update_bits(max98925->regmap,
283 MAX98925_DOUT_CFG_VMON,
284 M98925_DAI_VMON_EN_MASK, M98925_DAI_VMON_EN_MASK);
285 regmap_update_bits(max98925->regmap,
286 MAX98925_DOUT_CFG_VMON,
287 M98925_DAI_VMON_SLOT_MASK,
288 max98925->v_slot << M98925_DAI_VMON_SLOT_SHIFT);
289 /* set IMON slots */
290 regmap_update_bits(max98925->regmap,
291 MAX98925_DOUT_CFG_IMON,
292 M98925_DAI_IMON_EN_MASK, M98925_DAI_IMON_EN_MASK);
293 regmap_update_bits(max98925->regmap,
294 MAX98925_DOUT_CFG_IMON,
295 M98925_DAI_IMON_SLOT_MASK,
296 max98925->i_slot << M98925_DAI_IMON_SLOT_SHIFT);
297}
298
299static int max98925_dai_set_fmt(struct snd_soc_dai *codec_dai,
300 unsigned int fmt)
301{
302 struct snd_soc_codec *codec = codec_dai->codec;
303 struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
304 unsigned int invert = 0;
305
306 dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
307 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
308 case SND_SOC_DAIFMT_CBS_CFS:
309 /* set DAI to slave mode */
310 regmap_update_bits(max98925->regmap,
311 MAX98925_DAI_CLK_MODE2,
312 M98925_DAI_MAS_MASK, 0);
313 max98925_set_sense_data(max98925);
314 break;
315 case SND_SOC_DAIFMT_CBM_CFM:
316 /*
317 * set left channel DAI to master mode,
318 * right channel always slave
319 */
320 regmap_update_bits(max98925->regmap,
321 MAX98925_DAI_CLK_MODE2,
322 M98925_DAI_MAS_MASK, M98925_DAI_MAS_MASK);
323 break;
324 case SND_SOC_DAIFMT_CBS_CFM:
325 case SND_SOC_DAIFMT_CBM_CFS:
326 default:
327 dev_err(codec->dev, "DAI clock mode unsupported");
328 return -EINVAL;
329 }
330
331 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
332 case SND_SOC_DAIFMT_NB_NF:
333 break;
334 case SND_SOC_DAIFMT_NB_IF:
335 invert = M98925_DAI_WCI_MASK;
336 break;
337 case SND_SOC_DAIFMT_IB_NF:
338 invert = M98925_DAI_BCI_MASK;
339 break;
340 case SND_SOC_DAIFMT_IB_IF:
341 invert = M98925_DAI_BCI_MASK | M98925_DAI_WCI_MASK;
342 break;
343 default:
344 dev_err(codec->dev, "DAI invert mode unsupported");
345 return -EINVAL;
346 }
347
348 regmap_update_bits(max98925->regmap, MAX98925_FORMAT,
349 M98925_DAI_BCI_MASK, invert);
350 return 0;
351}
352
353static int max98925_set_clock(struct max98925_priv *max98925,
354 struct snd_pcm_hw_params *params)
355{
356 unsigned int dai_sr = 0, clock, mdll, n, m;
357 struct snd_soc_codec *codec = max98925->codec;
358 int rate = params_rate(params);
359 /* BCLK/LRCLK ratio calculation */
360 int blr_clk_ratio = params_channels(params) * max98925->ch_size;
361
362 switch (blr_clk_ratio) {
363 case 32:
364 regmap_update_bits(max98925->regmap,
365 MAX98925_DAI_CLK_MODE2,
366 M98925_DAI_BSEL_MASK, M98925_DAI_BSEL_32);
367 break;
368 case 48:
369 regmap_update_bits(max98925->regmap,
370 MAX98925_DAI_CLK_MODE2,
371 M98925_DAI_BSEL_MASK, M98925_DAI_BSEL_48);
372 break;
373 case 64:
374 regmap_update_bits(max98925->regmap,
375 MAX98925_DAI_CLK_MODE2,
376 M98925_DAI_BSEL_MASK, M98925_DAI_BSEL_64);
377 break;
378 default:
379 return -EINVAL;
380 }
381
382 switch (max98925->sysclk) {
383 case 6000000:
384 clock = 0;
385 mdll = M98925_MDLL_MULT_MCLKx16;
386 break;
387 case 11289600:
388 clock = 1;
389 mdll = M98925_MDLL_MULT_MCLKx8;
390 break;
391 case 12000000:
392 clock = 0;
393 mdll = M98925_MDLL_MULT_MCLKx8;
394 break;
395 case 12288000:
396 clock = 2;
397 mdll = M98925_MDLL_MULT_MCLKx8;
398 break;
399 default:
400 dev_info(max98925->codec->dev, "unsupported sysclk %d\n",
401 max98925->sysclk);
402 return -EINVAL;
403 }
404
405 if (max98925_rate_value(codec, rate, clock, &dai_sr, &n, &m))
406 return -EINVAL;
407
408 /* set DAI_SR to correct LRCLK frequency */
409 regmap_update_bits(max98925->regmap,
410 MAX98925_DAI_CLK_MODE2,
411 M98925_DAI_SR_MASK, dai_sr << M98925_DAI_SR_SHIFT);
412 /* set DAI m divider */
413 regmap_write(max98925->regmap,
414 MAX98925_DAI_CLK_DIV_M_MSBS, m >> 8);
415 regmap_write(max98925->regmap,
416 MAX98925_DAI_CLK_DIV_M_LSBS, m & 0xFF);
417 /* set DAI n divider */
418 regmap_write(max98925->regmap,
419 MAX98925_DAI_CLK_DIV_N_MSBS, n >> 8);
420 regmap_write(max98925->regmap,
421 MAX98925_DAI_CLK_DIV_N_LSBS, n & 0xFF);
422 /* set MDLL */
423 regmap_update_bits(max98925->regmap, MAX98925_DAI_CLK_MODE1,
424 M98925_MDLL_MULT_MASK, mdll << M98925_MDLL_MULT_SHIFT);
425 return 0;
426}
427
428static int max98925_dai_hw_params(struct snd_pcm_substream *substream,
429 struct snd_pcm_hw_params *params,
430 struct snd_soc_dai *dai)
431{
432 struct snd_soc_codec *codec = dai->codec;
433 struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
434
435 switch (snd_pcm_format_width(params_format(params))) {
436 case 16:
437 regmap_update_bits(max98925->regmap,
438 MAX98925_FORMAT,
439 M98925_DAI_CHANSZ_MASK, M98925_DAI_CHANSZ_16);
440 max98925->ch_size = 16;
441 break;
442 case 24:
443 regmap_update_bits(max98925->regmap,
444 MAX98925_FORMAT,
445 M98925_DAI_CHANSZ_MASK, M98925_DAI_CHANSZ_24);
446 max98925->ch_size = 24;
447 break;
448 case 32:
449 regmap_update_bits(max98925->regmap,
450 MAX98925_FORMAT,
451 M98925_DAI_CHANSZ_MASK, M98925_DAI_CHANSZ_32);
452 max98925->ch_size = 32;
453 break;
454 default:
455 pr_err("%s: format unsupported %d",
456 __func__, params_format(params));
457 return -EINVAL;
458 }
459 dev_dbg(codec->dev, "%s: format supported %d",
460 __func__, params_format(params));
461 return max98925_set_clock(max98925, params);
462}
463
464static int max98925_dai_set_sysclk(struct snd_soc_dai *dai,
465 int clk_id, unsigned int freq, int dir)
466{
467 struct snd_soc_codec *codec = dai->codec;
468 struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
469
470 switch (clk_id) {
471 case 0:
472 /* use MCLK for Left channel, right channel always BCLK */
473 regmap_update_bits(max98925->regmap,
474 MAX98925_DAI_CLK_MODE1,
475 M98925_DAI_CLK_SOURCE_MASK, 0);
476 break;
477 case 1:
478 /* configure dai clock source to BCLK instead of MCLK */
479 regmap_update_bits(max98925->regmap,
480 MAX98925_DAI_CLK_MODE1,
481 M98925_DAI_CLK_SOURCE_MASK,
482 M98925_DAI_CLK_SOURCE_MASK);
483 break;
484 default:
485 return -EINVAL;
486 }
487 max98925->sysclk = freq;
488 return 0;
489}
490
491#define MAX98925_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
492 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
493
494static const struct snd_soc_dai_ops max98925_dai_ops = {
495 .set_sysclk = max98925_dai_set_sysclk,
496 .set_fmt = max98925_dai_set_fmt,
497 .hw_params = max98925_dai_hw_params,
498};
499
500static struct snd_soc_dai_driver max98925_dai[] = {
501 {
502 .name = "max98925-aif1",
503 .playback = {
504 .stream_name = "HiFi Playback",
505 .channels_min = 1,
506 .channels_max = 2,
507 .rates = SNDRV_PCM_RATE_8000_48000,
508 .formats = MAX98925_FORMATS,
509 },
510 .capture = {
511 .stream_name = "HiFi Capture",
512 .channels_min = 1,
513 .channels_max = 2,
514 .rates = SNDRV_PCM_RATE_8000_48000,
515 .formats = MAX98925_FORMATS,
516 },
517 .ops = &max98925_dai_ops,
518 }
519};
520
521static int max98925_probe(struct snd_soc_codec *codec)
522{
523 struct max98925_priv *max98925 = snd_soc_codec_get_drvdata(codec);
524
525 max98925->codec = codec;
526 codec->control_data = max98925->regmap;
527 regmap_write(max98925->regmap, MAX98925_GLOBAL_ENABLE, 0x00);
528 /* It's not the default but we need to set DAI_DLY */
529 regmap_write(max98925->regmap,
530 MAX98925_FORMAT, M98925_DAI_DLY_MASK);
531 regmap_write(max98925->regmap, MAX98925_TDM_SLOT_SELECT, 0xC8);
532 regmap_write(max98925->regmap, MAX98925_DOUT_HIZ_CFG1, 0xFF);
533 regmap_write(max98925->regmap, MAX98925_DOUT_HIZ_CFG2, 0xFF);
534 regmap_write(max98925->regmap, MAX98925_DOUT_HIZ_CFG3, 0xFF);
535 regmap_write(max98925->regmap, MAX98925_DOUT_HIZ_CFG4, 0xF0);
536 regmap_write(max98925->regmap, MAX98925_FILTERS, 0xD8);
537 regmap_write(max98925->regmap, MAX98925_ALC_CONFIGURATION, 0xF8);
538 regmap_write(max98925->regmap, MAX98925_CONFIGURATION, 0xF0);
539 /* Disable ALC muting */
540 regmap_write(max98925->regmap, MAX98925_BOOST_LIMITER, 0xF8);
541 return 0;
542}
543
544static const struct snd_soc_codec_driver soc_codec_dev_max98925 = {
545 .probe = max98925_probe,
546 .controls = max98925_snd_controls,
547 .num_controls = ARRAY_SIZE(max98925_snd_controls),
548 .dapm_routes = max98925_audio_map,
549 .num_dapm_routes = ARRAY_SIZE(max98925_audio_map),
550 .dapm_widgets = max98925_dapm_widgets,
551 .num_dapm_widgets = ARRAY_SIZE(max98925_dapm_widgets),
552};
553
554static const struct regmap_config max98925_regmap = {
555 .reg_bits = 8,
556 .val_bits = 8,
557 .max_register = MAX98925_REV_VERSION,
558 .reg_defaults = max98925_reg,
559 .num_reg_defaults = ARRAY_SIZE(max98925_reg),
560 .volatile_reg = max98925_volatile_register,
561 .readable_reg = max98925_readable_register,
562 .cache_type = REGCACHE_RBTREE,
563};
564
565static int max98925_i2c_probe(struct i2c_client *i2c,
566 const struct i2c_device_id *id)
567{
568 int ret, reg;
569 u32 value;
570 struct max98925_priv *max98925;
571
572 max98925 = devm_kzalloc(&i2c->dev,
573 sizeof(*max98925), GFP_KERNEL);
574 if (!max98925)
575 return -ENOMEM;
576
577 i2c_set_clientdata(i2c, max98925);
578 max98925->regmap = devm_regmap_init_i2c(i2c, &max98925_regmap);
579 if (IS_ERR(max98925->regmap)) {
580 ret = PTR_ERR(max98925->regmap);
581 dev_err(&i2c->dev,
582 "Failed to allocate regmap: %d\n", ret);
583 goto err_out;
584 }
585
586 if (!of_property_read_u32(i2c->dev.of_node, "vmon-slot-no", &value)) {
587 if (value > M98925_DAI_VMON_SLOT_1E_1F) {
588 dev_err(&i2c->dev, "vmon slot number is wrong:\n");
589 return -EINVAL;
590 }
591 max98925->v_slot = value;
592 }
593 if (!of_property_read_u32(i2c->dev.of_node, "imon-slot-no", &value)) {
594 if (value > M98925_DAI_IMON_SLOT_1E_1F) {
595 dev_err(&i2c->dev, "imon slot number is wrong:\n");
596 return -EINVAL;
597 }
598 max98925->i_slot = value;
599 }
600 ret = regmap_read(max98925->regmap,
601 MAX98925_REV_VERSION, &reg);
602 if ((ret < 0) ||
603 ((reg != MAX98925_VERSION) &&
604 (reg != MAX98925_VERSION1))) {
605 dev_err(&i2c->dev,
606 "device initialization error (%d 0x%02X)\n",
607 ret, reg);
608 goto err_out;
609 }
610 dev_info(&i2c->dev, "device version 0x%02X\n", reg);
611
612 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98925,
613 max98925_dai, ARRAY_SIZE(max98925_dai));
614 if (ret < 0)
615 dev_err(&i2c->dev,
616 "Failed to register codec: %d\n", ret);
617err_out:
618 return ret;
619}
620
621static int max98925_i2c_remove(struct i2c_client *client)
622{
623 snd_soc_unregister_codec(&client->dev);
624 return 0;
625}
626
627static const struct i2c_device_id max98925_i2c_id[] = {
628 { "max98925", 0 },
629 { }
630};
631MODULE_DEVICE_TABLE(i2c, max98925_i2c_id);
632
633static const struct of_device_id max98925_of_match[] = {
634 { .compatible = "maxim,max98925", },
635 { }
636};
637MODULE_DEVICE_TABLE(of, max98925_of_match);
638
639static struct i2c_driver max98925_i2c_driver = {
640 .driver = {
641 .name = "max98925",
642 .owner = THIS_MODULE,
643 .of_match_table = of_match_ptr(max98925_of_match),
644 .pm = NULL,
645 },
646 .probe = max98925_i2c_probe,
647 .remove = max98925_i2c_remove,
648 .id_table = max98925_i2c_id,
649};
650
651module_i2c_driver(max98925_i2c_driver)
652
653MODULE_DESCRIPTION("ALSA SoC MAX98925 driver");
654MODULE_AUTHOR("Ralph Birt <rdbirt@gmail.com>, Anish kumar <anish.kumar@maximintegrated.com>");
655MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max98925.h b/sound/soc/codecs/max98925.h
new file mode 100644
index 000000000000..3783248f2780
--- /dev/null
+++ b/sound/soc/codecs/max98925.h
@@ -0,0 +1,832 @@
1/*
2 * max98925.h -- MAX98925 ALSA SoC Audio driver
3 *
4 * Copyright 2013-2015 Maxim Integrated Products
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _MAX98925_H
12#define _MAX98925_H
13
14#define MAX98925_VERSION 0x51
15#define MAX98925_VERSION1 0x80
16#define MAX98925_VBAT_DATA 0x00
17#define MAX98925_VBST_DATA 0x01
18#define MAX98925_LIVE_STATUS0 0x02
19#define MAX98925_LIVE_STATUS1 0x03
20#define MAX98925_LIVE_STATUS2 0x04
21#define MAX98925_STATE0 0x05
22#define MAX98925_STATE1 0x06
23#define MAX98925_STATE2 0x07
24#define MAX98925_FLAG0 0x08
25#define MAX98925_FLAG1 0x09
26#define MAX98925_FLAG2 0x0A
27#define MAX98925_IRQ_ENABLE0 0x0B
28#define MAX98925_IRQ_ENABLE1 0x0C
29#define MAX98925_IRQ_ENABLE2 0x0D
30#define MAX98925_IRQ_CLEAR0 0x0E
31#define MAX98925_IRQ_CLEAR1 0x0F
32#define MAX98925_IRQ_CLEAR2 0x10
33#define MAX98925_MAP0 0x11
34#define MAX98925_MAP1 0x12
35#define MAX98925_MAP2 0x13
36#define MAX98925_MAP3 0x14
37#define MAX98925_MAP4 0x15
38#define MAX98925_MAP5 0x16
39#define MAX98925_MAP6 0x17
40#define MAX98925_MAP7 0x18
41#define MAX98925_MAP8 0x19
42#define MAX98925_DAI_CLK_MODE1 0x1A
43#define MAX98925_DAI_CLK_MODE2 0x1B
44#define MAX98925_DAI_CLK_DIV_M_MSBS 0x1C
45#define MAX98925_DAI_CLK_DIV_M_LSBS 0x1D
46#define MAX98925_DAI_CLK_DIV_N_MSBS 0x1E
47#define MAX98925_DAI_CLK_DIV_N_LSBS 0x1F
48#define MAX98925_FORMAT 0x20
49#define MAX98925_TDM_SLOT_SELECT 0x21
50#define MAX98925_DOUT_CFG_VMON 0x22
51#define MAX98925_DOUT_CFG_IMON 0x23
52#define MAX98925_DOUT_CFG_VBAT 0x24
53#define MAX98925_DOUT_CFG_VBST 0x25
54#define MAX98925_DOUT_CFG_FLAG 0x26
55#define MAX98925_DOUT_HIZ_CFG1 0x27
56#define MAX98925_DOUT_HIZ_CFG2 0x28
57#define MAX98925_DOUT_HIZ_CFG3 0x29
58#define MAX98925_DOUT_HIZ_CFG4 0x2A
59#define MAX98925_DOUT_DRV_STRENGTH 0x2B
60#define MAX98925_FILTERS 0x2C
61#define MAX98925_GAIN 0x2D
62#define MAX98925_GAIN_RAMPING 0x2E
63#define MAX98925_SPK_AMP 0x2F
64#define MAX98925_THRESHOLD 0x30
65#define MAX98925_ALC_ATTACK 0x31
66#define MAX98925_ALC_ATTEN_RLS 0x32
67#define MAX98925_ALC_HOLD_RLS 0x33
68#define MAX98925_ALC_CONFIGURATION 0x34
69#define MAX98925_BOOST_CONVERTER 0x35
70#define MAX98925_BLOCK_ENABLE 0x36
71#define MAX98925_CONFIGURATION 0x37
72#define MAX98925_GLOBAL_ENABLE 0x38
73#define MAX98925_BOOST_LIMITER 0x3A
74#define MAX98925_REV_VERSION 0xFF
75
76#define MAX98925_REG_CNT (MAX98925_R03A_BOOST_LIMITER+1)
77
78/* MAX98925 Register Bit Fields */
79
80/* MAX98925_R002_LIVE_STATUS0 */
81#define M98925_THERMWARN_STATUS_MASK (1<<3)
82#define M98925_THERMWARN_STATUS_SHIFT 3
83#define M98925_THERMWARN_STATUS_WIDTH 1
84#define M98925_THERMSHDN_STATUS_MASK (1<<1)
85#define M98925_THERMSHDN_STATUS_SHIFT 1
86#define M98925_THERMSHDN_STATUS_WIDTH 1
87
88/* MAX98925_R003_LIVE_STATUS1 */
89#define M98925_SPKCURNT_STATUS_MASK (1<<5)
90#define M98925_SPKCURNT_STATUS_SHIFT 5
91#define M98925_SPKCURNT_STATUS_WIDTH 1
92#define M98925_WATCHFAIL_STATUS_MASK (1<<4)
93#define M98925_WATCHFAIL_STATUS_SHIFT 4
94#define M98925_WATCHFAIL_STATUS_WIDTH 1
95#define M98925_ALCINFH_STATUS_MASK (1<<3)
96#define M98925_ALCINFH_STATUS_SHIFT 3
97#define M98925_ALCINFH_STATUS_WIDTH 1
98#define M98925_ALCACT_STATUS_MASK (1<<2)
99#define M98925_ALCACT_STATUS_SHIFT 2
100#define M98925_ALCACT_STATUS_WIDTH 1
101#define M98925_ALCMUT_STATUS_MASK (1<<1)
102#define M98925_ALCMUT_STATUS_SHIFT 1
103#define M98925_ALCMUT_STATUS_WIDTH 1
104#define M98925_ACLP_STATUS_MASK (1<<0)
105#define M98925_ACLP_STATUS_SHIFT 0
106#define M98925_ACLP_STATUS_WIDTH 1
107
108/* MAX98925_R004_LIVE_STATUS2 */
109#define M98925_SLOTOVRN_STATUS_MASK (1<<6)
110#define M98925_SLOTOVRN_STATUS_SHIFT 6
111#define M98925_SLOTOVRN_STATUS_WIDTH 1
112#define M98925_INVALSLOT_STATUS_MASK (1<<5)
113#define M98925_INVALSLOT_STATUS_SHIFT 5
114#define M98925_INVALSLOT_STATUS_WIDTH 1
115#define M98925_SLOTCNFLT_STATUS_MASK (1<<4)
116#define M98925_SLOTCNFLT_STATUS_SHIFT 4
117#define M98925_SLOTCNFLT_STATUS_WIDTH 1
118#define M98925_VBSTOVFL_STATUS_MASK (1<<3)
119#define M98925_VBSTOVFL_STATUS_SHIFT 3
120#define M98925_VBSTOVFL_STATUS_WIDTH 1
121#define M98925_VBATOVFL_STATUS_MASK (1<<2)
122#define M98925_VBATOVFL_STATUS_SHIFT 2
123#define M98925_VBATOVFL_STATUS_WIDTH 1
124#define M98925_IMONOVFL_STATUS_MASK (1<<1)
125#define M98925_IMONOVFL_STATUS_SHIFT 1
126#define M98925_IMONOVFL_STATUS_WIDTH 1
127#define M98925_VMONOVFL_STATUS_MASK (1<<0)
128#define M98925_VMONOVFL_STATUS_SHIFT 0
129#define M98925_VMONOVFL_STATUS_WIDTH 1
130
131/* MAX98925_R005_STATE0 */
132#define M98925_THERMWARN_END_STATE_MASK (1<<3)
133#define M98925_THERMWARN_END_STATE_SHIFT 3
134#define M98925_THERMWARN_END_STATE_WIDTH 1
135#define M98925_THERMWARN_BGN_STATE_MASK (1<<2)
136#define M98925_THERMWARN_BGN_STATE_SHIFT 1
137#define M98925_THERMWARN_BGN_STATE_WIDTH 1
138#define M98925_THERMSHDN_END_STATE_MASK (1<<1)
139#define M98925_THERMSHDN_END_STATE_SHIFT 1
140#define M98925_THERMSHDN_END_STATE_WIDTH 1
141#define M98925_THERMSHDN_BGN_STATE_MASK (1<<0)
142#define M98925_THERMSHDN_BGN_STATE_SHIFT 0
143#define M98925_THERMSHDN_BGN_STATE_WIDTH 1
144
145/* MAX98925_R006_STATE1 */
146#define M98925_SPRCURNT_STATE_MASK (1<<5)
147#define M98925_SPRCURNT_STATE_SHIFT 5
148#define M98925_SPRCURNT_STATE_WIDTH 1
149#define M98925_WATCHFAIL_STATE_MASK (1<<4)
150#define M98925_WATCHFAIL_STATE_SHIFT 4
151#define M98925_WATCHFAIL_STATE_WIDTH 1
152#define M98925_ALCINFH_STATE_MASK (1<<3)
153#define M98925_ALCINFH_STATE_SHIFT 3
154#define M98925_ALCINFH_STATE_WIDTH 1
155#define M98925_ALCACT_STATE_MASK (1<<2)
156#define M98925_ALCACT_STATE_SHIFT 2
157#define M98925_ALCACT_STATE_WIDTH 1
158#define M98925_ALCMUT_STATE_MASK (1<<1)
159#define M98925_ALCMUT_STATE_SHIFT 1
160#define M98925_ALCMUT_STATE_WIDTH 1
161#define M98925_ALCP_STATE_MASK (1<<0)
162#define M98925_ALCP_STATE_SHIFT 0
163#define M98925_ALCP_STATE_WIDTH 1
164
165/* MAX98925_R007_STATE2 */
166#define M98925_SLOTOVRN_STATE_MASK (1<<6)
167#define M98925_SLOTOVRN_STATE_SHIFT 6
168#define M98925_SLOTOVRN_STATE_WIDTH 1
169#define M98925_INVALSLOT_STATE_MASK (1<<5)
170#define M98925_INVALSLOT_STATE_SHIFT 5
171#define M98925_INVALSLOT_STATE_WIDTH 1
172#define M98925_SLOTCNFLT_STATE_MASK (1<<4)
173#define M98925_SLOTCNFLT_STATE_SHIFT 4
174#define M98925_SLOTCNFLT_STATE_WIDTH 1
175#define M98925_VBSTOVFL_STATE_MASK (1<<3)
176#define M98925_VBSTOVFL_STATE_SHIFT 3
177#define M98925_VBSTOVFL_STATE_WIDTH 1
178#define M98925_VBATOVFL_STATE_MASK (1<<2)
179#define M98925_VBATOVFL_STATE_SHIFT 2
180#define M98925_VBATOVFL_STATE_WIDTH 1
181#define M98925_IMONOVFL_STATE_MASK (1<<1)
182#define M98925_IMONOVFL_STATE_SHIFT 1
183#define M98925_IMONOVFL_STATE_WIDTH 1
184#define M98925_VMONOVFL_STATE_MASK (1<<0)
185#define M98925_VMONOVFL_STATE_SHIFT 0
186#define M98925_VMONOVFL_STATE_WIDTH 1
187
188/* MAX98925_R008_FLAG0 */
189#define M98925_THERMWARN_END_FLAG_MASK (1<<3)
190#define M98925_THERMWARN_END_FLAG_SHIFT 3
191#define M98925_THERMWARN_END_FLAG_WIDTH 1
192#define M98925_THERMWARN_BGN_FLAG_MASK (1<<2)
193#define M98925_THERMWARN_BGN_FLAG_SHIFT 2
194#define M98925_THERMWARN_BGN_FLAG_WIDTH 1
195#define M98925_THERMSHDN_END_FLAG_MASK (1<<1)
196#define M98925_THERMSHDN_END_FLAG_SHIFT 1
197#define M98925_THERMSHDN_END_FLAG_WIDTH 1
198#define M98925_THERMSHDN_BGN_FLAG_MASK (1<<0)
199#define M98925_THERMSHDN_BGN_FLAG_SHIFT 0
200#define M98925_THERMSHDN_BGN_FLAG_WIDTH 1
201
202/* MAX98925_R009_FLAG1 */
203#define M98925_SPKCURNT_FLAG_MASK (1<<5)
204#define M98925_SPKCURNT_FLAG_SHIFT 5
205#define M98925_SPKCURNT_FLAG_WIDTH 1
206#define M98925_WATCHFAIL_FLAG_MASK (1<<4)
207#define M98925_WATCHFAIL_FLAG_SHIFT 4
208#define M98925_WATCHFAIL_FLAG_WIDTH 1
209#define M98925_ALCINFH_FLAG_MASK (1<<3)
210#define M98925_ALCINFH_FLAG_SHIFT 3
211#define M98925_ALCINFH_FLAG_WIDTH 1
212#define M98925_ALCACT_FLAG_MASK (1<<2)
213#define M98925_ALCACT_FLAG_SHIFT 2
214#define M98925_ALCACT_FLAG_WIDTH 1
215#define M98925_ALCMUT_FLAG_MASK (1<<1)
216#define M98925_ALCMUT_FLAG_SHIFT 1
217#define M98925_ALCMUT_FLAG_WIDTH 1
218#define M98925_ALCP_FLAG_MASK (1<<0)
219#define M98925_ALCP_FLAG_SHIFT 0
220#define M98925_ALCP_FLAG_WIDTH 1
221
222/* MAX98925_R00A_FLAG2 */
223#define M98925_SLOTOVRN_FLAG_MASK (1<<6)
224#define M98925_SLOTOVRN_FLAG_SHIFT 6
225#define M98925_SLOTOVRN_FLAG_WIDTH 1
226#define M98925_INVALSLOT_FLAG_MASK (1<<5)
227#define M98925_INVALSLOT_FLAG_SHIFT 5
228#define M98925_INVALSLOT_FLAG_WIDTH 1
229#define M98925_SLOTCNFLT_FLAG_MASK (1<<4)
230#define M98925_SLOTCNFLT_FLAG_SHIFT 4
231#define M98925_SLOTCNFLT_FLAG_WIDTH 1
232#define M98925_VBSTOVFL_FLAG_MASK (1<<3)
233#define M98925_VBSTOVFL_FLAG_SHIFT 3
234#define M98925_VBSTOVFL_FLAG_WIDTH 1
235#define M98925_VBATOVFL_FLAG_MASK (1<<2)
236#define M98925_VBATOVFL_FLAG_SHIFT 2
237#define M98925_VBATOVFL_FLAG_WIDTH 1
238#define M98925_IMONOVFL_FLAG_MASK (1<<1)
239#define M98925_IMONOVFL_FLAG_SHIFT 1
240#define M98925_IMONOVFL_FLAG_WIDTH 1
241#define M98925_VMONOVFL_FLAG_MASK (1<<0)
242#define M98925_VMONOVFL_FLAG_SHIFT 0
243#define M98925_VMONOVFL_FLAG_WIDTH 1
244
245/* MAX98925_R00B_IRQ_ENABLE0 */
246#define M98925_THERMWARN_END_EN_MASK (1<<3)
247#define M98925_THERMWARN_END_EN_SHIFT 3
248#define M98925_THERMWARN_END_EN_WIDTH 1
249#define M98925_THERMWARN_BGN_EN_MASK (1<<2)
250#define M98925_THERMWARN_BGN_EN_SHIFT 2
251#define M98925_THERMWARN_BGN_EN_WIDTH 1
252#define M98925_THERMSHDN_END_EN_MASK (1<<1)
253#define M98925_THERMSHDN_END_EN_SHIFT 1
254#define M98925_THERMSHDN_END_EN_WIDTH 1
255#define M98925_THERMSHDN_BGN_EN_MASK (1<<0)
256#define M98925_THERMSHDN_BGN_EN_SHIFT 0
257#define M98925_THERMSHDN_BGN_EN_WIDTH 1
258
259/* MAX98925_R00C_IRQ_ENABLE1 */
260#define M98925_SPKCURNT_EN_MASK (1<<5)
261#define M98925_SPKCURNT_EN_SHIFT 5
262#define M98925_SPKCURNT_EN_WIDTH 1
263#define M98925_WATCHFAIL_EN_MASK (1<<4)
264#define M98925_WATCHFAIL_EN_SHIFT 4
265#define M98925_WATCHFAIL_EN_WIDTH 1
266#define M98925_ALCINFH_EN_MASK (1<<3)
267#define M98925_ALCINFH_EN_SHIFT 3
268#define M98925_ALCINFH_EN_WIDTH 1
269#define M98925_ALCACT_EN_MASK (1<<2)
270#define M98925_ALCACT_EN_SHIFT 2
271#define M98925_ALCACT_EN_WIDTH 1
272#define M98925_ALCMUT_EN_MASK (1<<1)
273#define M98925_ALCMUT_EN_SHIFT 1
274#define M98925_ALCMUT_EN_WIDTH 1
275#define M98925_ALCP_EN_MASK (1<<0)
276#define M98925_ALCP_EN_SHIFT 0
277#define M98925_ALCP_EN_WIDTH 1
278
279/* MAX98925_R00D_IRQ_ENABLE2 */
280#define M98925_SLOTOVRN_EN_MASK (1<<6)
281#define M98925_SLOTOVRN_EN_SHIFT 6
282#define M98925_SLOTOVRN_EN_WIDTH 1
283#define M98925_INVALSLOT_EN_MASK (1<<5)
284#define M98925_INVALSLOT_EN_SHIFT 5
285#define M98925_INVALSLOT_EN_WIDTH 1
286#define M98925_SLOTCNFLT_EN_MASK (1<<4)
287#define M98925_SLOTCNFLT_EN_SHIFT 4
288#define M98925_SLOTCNFLT_EN_WIDTH 1
289#define M98925_VBSTOVFL_EN_MASK (1<<3)
290#define M98925_VBSTOVFL_EN_SHIFT 3
291#define M98925_VBSTOVFL_EN_WIDTH 1
292#define M98925_VBATOVFL_EN_MASK (1<<2)
293#define M98925_VBATOVFL_EN_SHIFT 2
294#define M98925_VBATOVFL_EN_WIDTH 1
295#define M98925_IMONOVFL_EN_MASK (1<<1)
296#define M98925_IMONOVFL_EN_SHIFT 1
297#define M98925_IMONOVFL_EN_WIDTH 1
298#define M98925_VMONOVFL_EN_MASK (1<<0)
299#define M98925_VMONOVFL_EN_SHIFT 0
300#define M98925_VMONOVFL_EN_WIDTH 1
301
302/* MAX98925_R00E_IRQ_CLEAR0 */
303#define M98925_THERMWARN_END_CLR_MASK (1<<3)
304#define M98925_THERMWARN_END_CLR_SHIFT 3
305#define M98925_THERMWARN_END_CLR_WIDTH 1
306#define M98925_THERMWARN_BGN_CLR_MASK (1<<2)
307#define M98925_THERMWARN_BGN_CLR_SHIFT 2
308#define M98925_THERMWARN_BGN_CLR_WIDTH 1
309#define M98925_THERMSHDN_END_CLR_MASK (1<<1)
310#define M98925_THERMSHDN_END_CLR_SHIFT 1
311#define M98925_THERMSHDN_END_CLR_WIDTH 1
312#define M98925_THERMSHDN_BGN_CLR_MASK (1<<0)
313#define M98925_THERMSHDN_BGN_CLR_SHIFT 0
314#define M98925_THERMSHDN_BGN_CLR_WIDTH 1
315
316/* MAX98925_R00F_IRQ_CLEAR1 */
317#define M98925_SPKCURNT_CLR_MASK (1<<5)
318#define M98925_SPKCURNT_CLR_SHIFT 5
319#define M98925_SPKCURNT_CLR_WIDTH 1
320#define M98925_WATCHFAIL_CLR_MASK (1<<4)
321#define M98925_WATCHFAIL_CLR_SHIFT 4
322#define M98925_WATCHFAIL_CLR_WIDTH 1
323#define M98925_ALCINFH_CLR_MASK (1<<3)
324#define M98925_ALCINFH_CLR_SHIFT 3
325#define M98925_ALCINFH_CLR_WIDTH 1
326#define M98925_ALCACT_CLR_MASK (1<<2)
327#define M98925_ALCACT_CLR_SHIFT 2
328#define M98925_ALCACT_CLR_WIDTH 1
329#define M98925_ALCMUT_CLR_MASK (1<<1)
330#define M98925_ALCMUT_CLR_SHIFT 1
331#define M98925_ALCMUT_CLR_WIDTH 1
332#define M98925_ALCP_CLR_MASK (1<<0)
333#define M98925_ALCP_CLR_SHIFT 0
334#define M98925_ALCP_CLR_WIDTH 1
335
336/* MAX98925_R010_IRQ_CLEAR2 */
337#define M98925_SLOTOVRN_CLR_MASK (1<<6)
338#define M98925_SLOTOVRN_CLR_SHIFT 6
339#define M98925_SLOTOVRN_CLR_WIDTH 1
340#define M98925_INVALSLOT_CLR_MASK (1<<5)
341#define M98925_INVALSLOT_CLR_SHIFT 5
342#define M98925_INVALSLOT_CLR_WIDTH 1
343#define M98925_SLOTCNFLT_CLR_MASK (1<<4)
344#define M98925_SLOTCNFLT_CLR_SHIFT 4
345#define M98925_SLOTCNFLT_CLR_WIDTH 1
346#define M98925_VBSTOVFL_CLR_MASK (1<<3)
347#define M98925_VBSTOVFL_CLR_SHIFT 3
348#define M98925_VBSTOVFL_CLR_WIDTH 1
349#define M98925_VBATOVFL_CLR_MASK (1<<2)
350#define M98925_VBATOVFL_CLR_SHIFT 2
351#define M98925_VBATOVFL_CLR_WIDTH 1
352#define M98925_IMONOVFL_CLR_MASK (1<<1)
353#define M98925_IMONOVFL_CLR_SHIFT 1
354#define M98925_IMONOVFL_CLR_WIDTH 1
355#define M98925_VMONOVFL_CLR_MASK (1<<0)
356#define M98925_VMONOVFL_CLR_SHIFT 0
357#define M98925_VMONOVFL_CLR_WIDTH 1
358
359/* MAX98925_R011_MAP0 */
360#define M98925_ER_THERMWARN_EN_MASK (1<<7)
361#define M98925_ER_THERMWARN_EN_SHIFT 7
362#define M98925_ER_THERMWARN_EN_WIDTH 1
363#define M98925_ER_THERMWARN_MAP_MASK (0x07<<4)
364#define M98925_ER_THERMWARN_MAP_SHIFT 4
365#define M98925_ER_THERMWARN_MAP_WIDTH 3
366
367/* MAX98925_R012_MAP1 */
368#define M98925_ER_ALCMUT_EN_MASK (1<<7)
369#define M98925_ER_ALCMUT_EN_SHIFT 7
370#define M98925_ER_ALCMUT_EN_WIDTH 1
371#define M98925_ER_ALCMUT_MAP_MASK (0x07<<4)
372#define M98925_ER_ALCMUT_MAP_SHIFT 4
373#define M98925_ER_ALCMUT_MAP_WIDTH 3
374#define M98925_ER_ALCP_EN_MASK (1<<3)
375#define M98925_ER_ALCP_EN_SHIFT 3
376#define M98925_ER_ALCP_EN_WIDTH 1
377#define M98925_ER_ALCP_MAP_MASK (0x07<<0)
378#define M98925_ER_ALCP_MAP_SHIFT 0
379#define M98925_ER_ALCP_MAP_WIDTH 3
380
381/* MAX98925_R013_MAP2 */
382#define M98925_ER_ALCINFH_EN_MASK (1<<7)
383#define M98925_ER_ALCINFH_EN_SHIFT 7
384#define M98925_ER_ALCINFH_EN_WIDTH 1
385#define M98925_ER_ALCINFH_MAP_MASK (0x07<<4)
386#define M98925_ER_ALCINFH_MAP_SHIFT 4
387#define M98925_ER_ALCINFH_MAP_WIDTH 3
388#define M98925_ER_ALCACT_EN_MASK (1<<3)
389#define M98925_ER_ALCACT_EN_SHIFT 3
390#define M98925_ER_ALCACT_EN_WIDTH 1
391#define M98925_ER_ALCACT_MAP_MASK (0x07<<0)
392#define M98925_ER_ALCACT_MAP_SHIFT 0
393#define M98925_ER_ALCACT_MAP_WIDTH 3
394
395/* MAX98925_R014_MAP3 */
396#define M98925_ER_SPKCURNT_EN_MASK (1<<7)
397#define M98925_ER_SPKCURNT_EN_SHIFT 7
398#define M98925_ER_SPKCURNT_EN_WIDTH 1
399#define M98925_ER_SPKCURNT_MAP_MASK (0x07<<4)
400#define M98925_ER_SPKCURNT_MAP_SHIFT 4
401#define M98925_ER_SPKCURNT_MAP_WIDTH 3
402
403/* MAX98925_R015_MAP4 */
404/* RESERVED */
405
406/* MAX98925_R016_MAP5 */
407#define M98925_ER_IMONOVFL_EN_MASK (1<<7)
408#define M98925_ER_IMONOVFL_EN_SHIFT 7
409#define M98925_ER_IMONOVFL_EN_WIDTH 1
410#define M98925_ER_IMONOVFL_MAP_MASK (0x07<<4)
411#define M98925_ER_IMONOVFL_MAP_SHIFT 4
412#define M98925_ER_IMONOVFL_MAP_WIDTH 3
413#define M98925_ER_VMONOVFL_EN_MASK (1<<3)
414#define M98925_ER_VMONOVFL_EN_SHIFT 3
415#define M98925_ER_VMONOVFL_EN_WIDTH 1
416#define M98925_ER_VMONOVFL_MAP_MASK (0x07<<0)
417#define M98925_ER_VMONOVFL_MAP_SHIFT 0
418#define M98925_ER_VMONOVFL_MAP_WIDTH 3
419
420/* MAX98925_R017_MAP6 */
421#define M98925_ER_VBSTOVFL_EN_MASK (1<<7)
422#define M98925_ER_VBSTOVFL_EN_SHIFT 7
423#define M98925_ER_VBSTOVFL_EN_WIDTH 1
424#define M98925_ER_VBSTOVFL_MAP_MASK (0x07<<4)
425#define M98925_ER_VBSTOVFL_MAP_SHIFT 4
426#define M98925_ER_VBSTOVFL_MAP_WIDTH 3
427#define M98925_ER_VBATOVFL_EN_MASK (1<<3)
428#define M98925_ER_VBATOVFL_EN_SHIFT 3
429#define M98925_ER_VBATOVFL_EN_WIDTH 1
430#define M98925_ER_VBATOVFL_MAP_MASK (0x07<<0)
431#define M98925_ER_VBATOVFL_MAP_SHIFT 0
432#define M98925_ER_VBATOVFL_MAP_WIDTH 3
433
434/* MAX98925_R018_MAP7 */
435#define M98925_ER_INVALSLOT_EN_MASK (1<<7)
436#define M98925_ER_INVALSLOT_EN_SHIFT 7
437#define M98925_ER_INVALSLOT_EN_WIDTH 1
438#define M98925_ER_INVALSLOT_MAP_MASK (0x07<<4)
439#define M98925_ER_INVALSLOT_MAP_SHIFT 4
440#define M98925_ER_INVALSLOT_MAP_WIDTH 3
441#define M98925_ER_SLOTCNFLT_EN_MASK (1<<3)
442#define M98925_ER_SLOTCNFLT_EN_SHIFT 3
443#define M98925_ER_SLOTCNFLT_EN_WIDTH 1
444#define M98925_ER_SLOTCNFLT_MAP_MASK (0x07<<0)
445#define M98925_ER_SLOTCNFLT_MAP_SHIFT 0
446#define M98925_ER_SLOTCNFLT_MAP_WIDTH 3
447
448/* MAX98925_R019_MAP8 */
449#define M98925_ER_SLOTOVRN_EN_MASK (1<<3)
450#define M98925_ER_SLOTOVRN_EN_SHIFT 3
451#define M98925_ER_SLOTOVRN_EN_WIDTH 1
452#define M98925_ER_SLOTOVRN_MAP_MASK (0x07<<0)
453#define M98925_ER_SLOTOVRN_MAP_SHIFT 0
454#define M98925_ER_SLOTOVRN_MAP_WIDTH 3
455
456/* MAX98925_R01A_DAI_CLK_MODE1 */
457#define M98925_DAI_CLK_SOURCE_MASK (1<<6)
458#define M98925_DAI_CLK_SOURCE_SHIFT 6
459#define M98925_DAI_CLK_SOURCE_WIDTH 1
460#define M98925_MDLL_MULT_MASK (0x0F<<0)
461#define M98925_MDLL_MULT_SHIFT 0
462#define M98925_MDLL_MULT_WIDTH 4
463
464#define M98925_MDLL_MULT_MCLKx8 6
465#define M98925_MDLL_MULT_MCLKx16 8
466
467/* MAX98925_R01B_DAI_CLK_MODE2 */
468#define M98925_DAI_SR_MASK (0x0F<<4)
469#define M98925_DAI_SR_SHIFT 4
470#define M98925_DAI_SR_WIDTH 4
471#define M98925_DAI_MAS_MASK (1<<3)
472#define M98925_DAI_MAS_SHIFT 3
473#define M98925_DAI_MAS_WIDTH 1
474#define M98925_DAI_BSEL_MASK (0x07<<0)
475#define M98925_DAI_BSEL_SHIFT 0
476#define M98925_DAI_BSEL_WIDTH 3
477
478#define M98925_DAI_BSEL_32 (0 << M98925_DAI_BSEL_SHIFT)
479#define M98925_DAI_BSEL_48 (1 << M98925_DAI_BSEL_SHIFT)
480#define M98925_DAI_BSEL_64 (2 << M98925_DAI_BSEL_SHIFT)
481#define M98925_DAI_BSEL_256 (6 << M98925_DAI_BSEL_SHIFT)
482
483/* MAX98925_R01C_DAI_CLK_DIV_M_MSBS */
484#define M98925_DAI_M_MSBS_MASK (0xFF<<0)
485#define M98925_DAI_M_MSBS_SHIFT 0
486#define M98925_DAI_M_MSBS_WIDTH 8
487
488/* MAX98925_R01D_DAI_CLK_DIV_M_LSBS */
489#define M98925_DAI_M_LSBS_MASK (0xFF<<0)
490#define M98925_DAI_M_LSBS_SHIFT 0
491#define M98925_DAI_M_LSBS_WIDTH 8
492
493/* MAX98925_R01E_DAI_CLK_DIV_N_MSBS */
494#define M98925_DAI_N_MSBS_MASK (0x7F<<0)
495#define M98925_DAI_N_MSBS_SHIFT 0
496#define M98925_DAI_N_MSBS_WIDTH 7
497
498/* MAX98925_R01F_DAI_CLK_DIV_N_LSBS */
499#define M98925_DAI_N_LSBS_MASK (0xFF<<0)
500#define M98925_DAI_N_LSBS_SHIFT 0
501#define M98925_DAI_N_LSBS_WIDTH 8
502
503/* MAX98925_R020_FORMAT */
504#define M98925_DAI_CHANSZ_MASK (0x03<<6)
505#define M98925_DAI_CHANSZ_SHIFT 6
506#define M98925_DAI_CHANSZ_WIDTH 2
507#define M98925_DAI_EXTBCLK_HIZ_MASK (1<<4)
508#define M98925_DAI_EXTBCLK_HIZ_SHIFT 4
509#define M98925_DAI_EXTBCLK_HIZ_WIDTH 1
510#define M98925_DAI_WCI_MASK (1<<3)
511#define M98925_DAI_WCI_SHIFT 3
512#define M98925_DAI_WCI_WIDTH 1
513#define M98925_DAI_BCI_MASK (1<<2)
514#define M98925_DAI_BCI_SHIFT 2
515#define M98925_DAI_BCI_WIDTH 1
516#define M98925_DAI_DLY_MASK (1<<1)
517#define M98925_DAI_DLY_SHIFT 1
518#define M98925_DAI_DLY_WIDTH 1
519#define M98925_DAI_TDM_MASK (1<<0)
520#define M98925_DAI_TDM_SHIFT 0
521#define M98925_DAI_TDM_WIDTH 1
522
523#define M98925_DAI_CHANSZ_16 (1 << M98925_DAI_CHANSZ_SHIFT)
524#define M98925_DAI_CHANSZ_24 (2 << M98925_DAI_CHANSZ_SHIFT)
525#define M98925_DAI_CHANSZ_32 (3 << M98925_DAI_CHANSZ_SHIFT)
526
527/* MAX98925_R021_TDM_SLOT_SELECT */
528#define M98925_DAI_DO_EN_MASK (1<<7)
529#define M98925_DAI_DO_EN_SHIFT 7
530#define M98925_DAI_DO_EN_WIDTH 1
531#define M98925_DAI_DIN_EN_MASK (1<<6)
532#define M98925_DAI_DIN_EN_SHIFT 6
533#define M98925_DAI_DIN_EN_WIDTH 1
534#define M98925_DAI_INR_SOURCE_MASK (0x07<<3)
535#define M98925_DAI_INR_SOURCE_SHIFT 3
536#define M98925_DAI_INR_SOURCE_WIDTH 3
537#define M98925_DAI_INL_SOURCE_MASK (0x07<<0)
538#define M98925_DAI_INL_SOURCE_SHIFT 0
539#define M98925_DAI_INL_SOURCE_WIDTH 3
540
541/* MAX98925_R022_DOUT_CFG_VMON */
542#define M98925_DAI_VMON_EN_MASK (1<<5)
543#define M98925_DAI_VMON_EN_SHIFT 5
544#define M98925_DAI_VMON_EN_WIDTH 1
545#define M98925_DAI_VMON_SLOT_MASK (0x1F<<0)
546#define M98925_DAI_VMON_SLOT_SHIFT 0
547#define M98925_DAI_VMON_SLOT_WIDTH 5
548
549#define M98925_DAI_VMON_SLOT_00_01 (0 << M98925_DAI_VMON_SLOT_SHIFT)
550#define M98925_DAI_VMON_SLOT_01_02 (1 << M98925_DAI_VMON_SLOT_SHIFT)
551#define M98925_DAI_VMON_SLOT_02_03 (2 << M98925_DAI_VMON_SLOT_SHIFT)
552#define M98925_DAI_VMON_SLOT_03_04 (3 << M98925_DAI_VMON_SLOT_SHIFT)
553#define M98925_DAI_VMON_SLOT_04_05 (4 << M98925_DAI_VMON_SLOT_SHIFT)
554#define M98925_DAI_VMON_SLOT_05_06 (5 << M98925_DAI_VMON_SLOT_SHIFT)
555#define M98925_DAI_VMON_SLOT_06_07 (6 << M98925_DAI_VMON_SLOT_SHIFT)
556#define M98925_DAI_VMON_SLOT_07_08 (7 << M98925_DAI_VMON_SLOT_SHIFT)
557#define M98925_DAI_VMON_SLOT_08_09 (8 << M98925_DAI_VMON_SLOT_SHIFT)
558#define M98925_DAI_VMON_SLOT_09_0A (9 << M98925_DAI_VMON_SLOT_SHIFT)
559#define M98925_DAI_VMON_SLOT_0A_0B (10 << M98925_DAI_VMON_SLOT_SHIFT)
560#define M98925_DAI_VMON_SLOT_0B_0C (11 << M98925_DAI_VMON_SLOT_SHIFT)
561#define M98925_DAI_VMON_SLOT_0C_0D (12 << M98925_DAI_VMON_SLOT_SHIFT)
562#define M98925_DAI_VMON_SLOT_0D_0E (13 << M98925_DAI_VMON_SLOT_SHIFT)
563#define M98925_DAI_VMON_SLOT_0E_0F (14 << M98925_DAI_VMON_SLOT_SHIFT)
564#define M98925_DAI_VMON_SLOT_0F_10 (15 << M98925_DAI_VMON_SLOT_SHIFT)
565#define M98925_DAI_VMON_SLOT_10_11 (16 << M98925_DAI_VMON_SLOT_SHIFT)
566#define M98925_DAI_VMON_SLOT_11_12 (17 << M98925_DAI_VMON_SLOT_SHIFT)
567#define M98925_DAI_VMON_SLOT_12_13 (18 << M98925_DAI_VMON_SLOT_SHIFT)
568#define M98925_DAI_VMON_SLOT_13_14 (19 << M98925_DAI_VMON_SLOT_SHIFT)
569#define M98925_DAI_VMON_SLOT_14_15 (20 << M98925_DAI_VMON_SLOT_SHIFT)
570#define M98925_DAI_VMON_SLOT_15_16 (21 << M98925_DAI_VMON_SLOT_SHIFT)
571#define M98925_DAI_VMON_SLOT_16_17 (22 << M98925_DAI_VMON_SLOT_SHIFT)
572#define M98925_DAI_VMON_SLOT_17_18 (23 << M98925_DAI_VMON_SLOT_SHIFT)
573#define M98925_DAI_VMON_SLOT_18_19 (24 << M98925_DAI_VMON_SLOT_SHIFT)
574#define M98925_DAI_VMON_SLOT_19_1A (25 << M98925_DAI_VMON_SLOT_SHIFT)
575#define M98925_DAI_VMON_SLOT_1A_1B (26 << M98925_DAI_VMON_SLOT_SHIFT)
576#define M98925_DAI_VMON_SLOT_1B_1C (27 << M98925_DAI_VMON_SLOT_SHIFT)
577#define M98925_DAI_VMON_SLOT_1C_1D (28 << M98925_DAI_VMON_SLOT_SHIFT)
578#define M98925_DAI_VMON_SLOT_1D_1E (29 << M98925_DAI_VMON_SLOT_SHIFT)
579#define M98925_DAI_VMON_SLOT_1E_1F (30 << M98925_DAI_VMON_SLOT_SHIFT)
580
581/* MAX98925_R023_DOUT_CFG_IMON */
582#define M98925_DAI_IMON_EN_MASK (1<<5)
583#define M98925_DAI_IMON_EN_SHIFT 5
584#define M98925_DAI_IMON_EN_WIDTH 1
585#define M98925_DAI_IMON_SLOT_MASK (0x1F<<0)
586#define M98925_DAI_IMON_SLOT_SHIFT 0
587#define M98925_DAI_IMON_SLOT_WIDTH 5
588
589#define M98925_DAI_IMON_SLOT_00_01 (0 << M98925_DAI_IMON_SLOT_SHIFT)
590#define M98925_DAI_IMON_SLOT_01_02 (1 << M98925_DAI_IMON_SLOT_SHIFT)
591#define M98925_DAI_IMON_SLOT_02_03 (2 << M98925_DAI_IMON_SLOT_SHIFT)
592#define M98925_DAI_IMON_SLOT_03_04 (3 << M98925_DAI_IMON_SLOT_SHIFT)
593#define M98925_DAI_IMON_SLOT_04_05 (4 << M98925_DAI_IMON_SLOT_SHIFT)
594#define M98925_DAI_IMON_SLOT_05_06 (5 << M98925_DAI_IMON_SLOT_SHIFT)
595#define M98925_DAI_IMON_SLOT_06_07 (6 << M98925_DAI_IMON_SLOT_SHIFT)
596#define M98925_DAI_IMON_SLOT_07_08 (7 << M98925_DAI_IMON_SLOT_SHIFT)
597#define M98925_DAI_IMON_SLOT_08_09 (8 << M98925_DAI_IMON_SLOT_SHIFT)
598#define M98925_DAI_IMON_SLOT_09_0A (9 << M98925_DAI_IMON_SLOT_SHIFT)
599#define M98925_DAI_IMON_SLOT_0A_0B (10 << M98925_DAI_IMON_SLOT_SHIFT)
600#define M98925_DAI_IMON_SLOT_0B_0C (11 << M98925_DAI_IMON_SLOT_SHIFT)
601#define M98925_DAI_IMON_SLOT_0C_0D (12 << M98925_DAI_IMON_SLOT_SHIFT)
602#define M98925_DAI_IMON_SLOT_0D_0E (13 << M98925_DAI_IMON_SLOT_SHIFT)
603#define M98925_DAI_IMON_SLOT_0E_0F (14 << M98925_DAI_IMON_SLOT_SHIFT)
604#define M98925_DAI_IMON_SLOT_0F_10 (15 << M98925_DAI_IMON_SLOT_SHIFT)
605#define M98925_DAI_IMON_SLOT_10_11 (16 << M98925_DAI_IMON_SLOT_SHIFT)
606#define M98925_DAI_IMON_SLOT_11_12 (17 << M98925_DAI_IMON_SLOT_SHIFT)
607#define M98925_DAI_IMON_SLOT_12_13 (18 << M98925_DAI_IMON_SLOT_SHIFT)
608#define M98925_DAI_IMON_SLOT_13_14 (19 << M98925_DAI_IMON_SLOT_SHIFT)
609#define M98925_DAI_IMON_SLOT_14_15 (20 << M98925_DAI_IMON_SLOT_SHIFT)
610#define M98925_DAI_IMON_SLOT_15_16 (21 << M98925_DAI_IMON_SLOT_SHIFT)
611#define M98925_DAI_IMON_SLOT_16_17 (22 << M98925_DAI_IMON_SLOT_SHIFT)
612#define M98925_DAI_IMON_SLOT_17_18 (23 << M98925_DAI_IMON_SLOT_SHIFT)
613#define M98925_DAI_IMON_SLOT_18_19 (24 << M98925_DAI_IMON_SLOT_SHIFT)
614#define M98925_DAI_IMON_SLOT_19_1A (25 << M98925_DAI_IMON_SLOT_SHIFT)
615#define M98925_DAI_IMON_SLOT_1A_1B (26 << M98925_DAI_IMON_SLOT_SHIFT)
616#define M98925_DAI_IMON_SLOT_1B_1C (27 << M98925_DAI_IMON_SLOT_SHIFT)
617#define M98925_DAI_IMON_SLOT_1C_1D (28 << M98925_DAI_IMON_SLOT_SHIFT)
618#define M98925_DAI_IMON_SLOT_1D_1E (29 << M98925_DAI_IMON_SLOT_SHIFT)
619#define M98925_DAI_IMON_SLOT_1E_1F (30 << M98925_DAI_IMON_SLOT_SHIFT)
620
621/* MAX98925_R024_DOUT_CFG_VBAT */
622#define M98925_DAI_VBAT_EN_MASK (1<<5)
623#define M98925_DAI_VBAT_EN_SHIFT 5
624#define M98925_DAI_VBAT_EN_WIDTH 1
625#define M98925_DAI_VBAT_SLOT_MASK (0x1F<<0)
626#define M98925_DAI_VBAT_SLOT_SHIFT 0
627#define M98925_DAI_VBAT_SLOT_WIDTH 5
628
629/* MAX98925_R025_DOUT_CFG_VBST */
630#define M98925_DAI_VBST_EN_MASK (1<<5)
631#define M98925_DAI_VBST_EN_SHIFT 5
632#define M98925_DAI_VBST_EN_WIDTH 1
633#define M98925_DAI_VBST_SLOT_MASK (0x1F<<0)
634#define M98925_DAI_VBST_SLOT_SHIFT 0
635#define M98925_DAI_VBST_SLOT_WIDTH 5
636
637/* MAX98925_R026_DOUT_CFG_FLAG */
638#define M98925_DAI_FLAG_EN_MASK (1<<5)
639#define M98925_DAI_FLAG_EN_SHIFT 5
640#define M98925_DAI_FLAG_EN_WIDTH 1
641#define M98925_DAI_FLAG_SLOT_MASK (0x1F<<0)
642#define M98925_DAI_FLAG_SLOT_SHIFT 0
643#define M98925_DAI_FLAG_SLOT_WIDTH 5
644
645/* MAX98925_R027_DOUT_HIZ_CFG1 */
646#define M98925_DAI_SLOT_HIZ_CFG1_MASK (0xFF<<0)
647#define M98925_DAI_SLOT_HIZ_CFG1_SHIFT 0
648#define M98925_DAI_SLOT_HIZ_CFG1_WIDTH 8
649
650/* MAX98925_R028_DOUT_HIZ_CFG2 */
651#define M98925_DAI_SLOT_HIZ_CFG2_MASK (0xFF<<0)
652#define M98925_DAI_SLOT_HIZ_CFG2_SHIFT 0
653#define M98925_DAI_SLOT_HIZ_CFG2_WIDTH 8
654
655/* MAX98925_R029_DOUT_HIZ_CFG3 */
656#define M98925_DAI_SLOT_HIZ_CFG3_MASK (0xFF<<0)
657#define M98925_DAI_SLOT_HIZ_CFG3_SHIFT 0
658#define M98925_DAI_SLOT_HIZ_CFG3_WIDTH 8
659
660/* MAX98925_R02A_DOUT_HIZ_CFG4 */
661#define M98925_DAI_SLOT_HIZ_CFG4_MASK (0xFF<<0)
662#define M98925_DAI_SLOT_HIZ_CFG4_SHIFT 0
663#define M98925_DAI_SLOT_HIZ_CFG4_WIDTH 8
664
665/* MAX98925_R02B_DOUT_DRV_STRENGTH */
666#define M98925_DAI_OUT_DRIVE_MASK (0x03<<0)
667#define M98925_DAI_OUT_DRIVE_SHIFT 0
668#define M98925_DAI_OUT_DRIVE_WIDTH 2
669
670/* MAX98925_R02C_FILTERS */
671#define M98925_ADC_DITHER_EN_MASK (1<<7)
672#define M98925_ADC_DITHER_EN_SHIFT 7
673#define M98925_ADC_DITHER_EN_WIDTH 1
674#define M98925_IV_DCB_EN_MASK (1<<6)
675#define M98925_IV_DCB_EN_SHIFT 6
676#define M98925_IV_DCB_EN_WIDTH 1
677#define M98925_DAC_DITHER_EN_MASK (1<<4)
678#define M98925_DAC_DITHER_EN_SHIFT 4
679#define M98925_DAC_DITHER_EN_WIDTH 1
680#define M98925_DAC_FILTER_MODE_MASK (1<<3)
681#define M98925_DAC_FILTER_MODE_SHIFT 3
682#define M98925_DAC_FILTER_MODE_WIDTH 1
683#define M98925_DAC_HPF_MASK (0x07<<0)
684#define M98925_DAC_HPF_SHIFT 0
685#define M98925_DAC_HPF_WIDTH 3
686#define M98925_DAC_HPF_DISABLE (0 << M98925_DAC_HPF_SHIFT)
687#define M98925_DAC_HPF_DC_BLOCK (1 << M98925_DAC_HPF_SHIFT)
688#define M98925_DAC_HPF_EN_100 (2 << M98925_DAC_HPF_SHIFT)
689#define M98925_DAC_HPF_EN_200 (3 << M98925_DAC_HPF_SHIFT)
690#define M98925_DAC_HPF_EN_400 (4 << M98925_DAC_HPF_SHIFT)
691#define M98925_DAC_HPF_EN_800 (5 << M98925_DAC_HPF_SHIFT)
692
693/* MAX98925_R02D_GAIN */
694#define M98925_DAC_IN_SEL_MASK (0x03<<5)
695#define M98925_DAC_IN_SEL_SHIFT 5
696#define M98925_DAC_IN_SEL_WIDTH 2
697#define M98925_SPK_GAIN_MASK (0x1F<<0)
698#define M98925_SPK_GAIN_SHIFT 0
699#define M98925_SPK_GAIN_WIDTH 5
700
701#define M98925_DAC_IN_SEL_LEFT_DAI (0 << M98925_DAC_IN_SEL_SHIFT)
702#define M98925_DAC_IN_SEL_RIGHT_DAI (1 << M98925_DAC_IN_SEL_SHIFT)
703#define M98925_DAC_IN_SEL_SUMMED_DAI (2 << M98925_DAC_IN_SEL_SHIFT)
704#define M98925_DAC_IN_SEL_DIV2_SUMMED_DAI (3 << M98925_DAC_IN_SEL_SHIFT)
705
706/* MAX98925_R02E_GAIN_RAMPING */
707#define M98925_SPK_RMP_EN_MASK (1<<1)
708#define M98925_SPK_RMP_EN_SHIFT 1
709#define M98925_SPK_RMP_EN_WIDTH 1
710#define M98925_SPK_ZCD_EN_MASK (1<<0)
711#define M98925_SPK_ZCD_EN_SHIFT 0
712#define M98925_SPK_ZCD_EN_WIDTH 1
713
714/* MAX98925_R02F_SPK_AMP */
715#define M98925_SPK_MODE_MASK (1<<0)
716#define M98925_SPK_MODE_SHIFT 0
717#define M98925_SPK_MODE_WIDTH 1
718
719/* MAX98925_R030_THRESHOLD */
720#define M98925_ALC_EN_MASK (1<<5)
721#define M98925_ALC_EN_SHIFT 5
722#define M98925_ALC_EN_WIDTH 1
723#define M98925_ALC_TH_MASK (0x1F<<0)
724#define M98925_ALC_TH_SHIFT 0
725#define M98925_ALC_TH_WIDTH 5
726
727/* MAX98925_R031_ALC_ATTACK */
728#define M98925_ALC_ATK_STEP_MASK (0x0F<<4)
729#define M98925_ALC_ATK_STEP_SHIFT 4
730#define M98925_ALC_ATK_STEP_WIDTH 4
731#define M98925_ALC_ATK_RATE_MASK (0x7<<0)
732#define M98925_ALC_ATK_RATE_SHIFT 0
733#define M98925_ALC_ATK_RATE_WIDTH 3
734
735/* MAX98925_R032_ALC_ATTEN_RLS */
736#define M98925_ALC_MAX_ATTEN_MASK (0x0F<<4)
737#define M98925_ALC_MAX_ATTEN_SHIFT 4
738#define M98925_ALC_MAX_ATTEN_WIDTH 4
739#define M98925_ALC_RLS_RATE_MASK (0x7<<0)
740#define M98925_ALC_RLS_RATE_SHIFT 0
741#define M98925_ALC_RLS_RATE_WIDTH 3
742
743/* MAX98925_R033_ALC_HOLD_RLS */
744#define M98925_ALC_RLS_TGR_MASK (1<<0)
745#define M98925_ALC_RLS_TGR_SHIFT 0
746#define M98925_ALC_RLS_TGR_WIDTH 1
747
748/* MAX98925_R034_ALC_CONFIGURATION */
749#define M98925_ALC_MUTE_EN_MASK (1<<7)
750#define M98925_ALC_MUTE_EN_SHIFT 7
751#define M98925_ALC_MUTE_EN_WIDTH 1
752#define M98925_ALC_MUTE_DLY_MASK (0x07<<4)
753#define M98925_ALC_MUTE_DLY_SHIFT 4
754#define M98925_ALC_MUTE_DLY_WIDTH 3
755#define M98925_ALC_RLS_DBT_MASK (0x07<<0)
756#define M98925_ALC_RLS_DBT_SHIFT 0
757#define M98925_ALC_RLS_DBT_WIDTH 3
758
759/* MAX98925_R035_BOOST_CONVERTER */
760#define M98925_BST_SYNC_MASK (1<<7)
761#define M98925_BST_SYNC_SHIFT 7
762#define M98925_BST_SYNC_WIDTH 1
763#define M98925_BST_PHASE_MASK (0x03<<4)
764#define M98925_BST_PHASE_SHIFT 4
765#define M98925_BST_PHASE_WIDTH 2
766#define M98925_BST_SKIP_MODE_MASK (0x03<<0)
767#define M98925_BST_SKIP_MODE_SHIFT 0
768#define M98925_BST_SKIP_MODE_WIDTH 2
769
770/* MAX98925_R036_BLOCK_ENABLE */
771#define M98925_BST_EN_MASK (1<<7)
772#define M98925_BST_EN_SHIFT 7
773#define M98925_BST_EN_WIDTH 1
774#define M98925_WATCH_EN_MASK (1<<6)
775#define M98925_WATCH_EN_SHIFT 6
776#define M98925_WATCH_EN_WIDTH 1
777#define M98925_CLKMON_EN_MASK (1<<5)
778#define M98925_CLKMON_EN_SHIFT 5
779#define M98925_CLKMON_EN_WIDTH 1
780#define M98925_SPK_EN_MASK (1<<4)
781#define M98925_SPK_EN_SHIFT 4
782#define M98925_SPK_EN_WIDTH 1
783#define M98925_ADC_VBST_EN_MASK (1<<3)
784#define M98925_ADC_VBST_EN_SHIFT 3
785#define M98925_ADC_VBST_EN_WIDTH 1
786#define M98925_ADC_VBAT_EN_MASK (1<<2)
787#define M98925_ADC_VBAT_EN_SHIFT 2
788#define M98925_ADC_VBAT_EN_WIDTH 1
789#define M98925_ADC_IMON_EN_MASK (1<<1)
790#define M98925_ADC_IMON_EN_SHIFT 1
791#define M98925_ADC_IMON_EN_WIDTH 1
792#define M98925_ADC_VMON_EN_MASK (1<<0)
793#define M98925_ADC_VMON_EN_SHIFT 0
794#define M98925_ADC_VMON_EN_WIDTH 1
795
796/* MAX98925_R037_CONFIGURATION */
797#define M98925_BST_VOUT_MASK (0x0F<<4)
798#define M98925_BST_VOUT_SHIFT 4
799#define M98925_BST_VOUT_WIDTH 4
800#define M98925_THERMWARN_LEVEL_MASK (0x03<<2)
801#define M98925_THERMWARN_LEVEL_SHIFT 2
802#define M98925_THERMWARN_LEVEL_WIDTH 2
803#define M98925_WATCH_TIME_MASK (0x03<<0)
804#define M98925_WATCH_TIME_SHIFT 0
805#define M98925_WATCH_TIME_WIDTH 2
806
807/* MAX98925_R038_GLOBAL_ENABLE */
808#define M98925_EN_MASK (1<<7)
809#define M98925_EN_SHIFT 7
810#define M98925_EN_WIDTH 1
811
812/* MAX98925_R03A_BOOST_LIMITER */
813#define M98925_BST_ILIM_MASK (0x1F<<3)
814#define M98925_BST_ILIM_SHIFT 3
815#define M98925_BST_ILIM_WIDTH 5
816
817/* MAX98925_R0FF_VERSION */
818#define M98925_REV_ID_MASK (0xFF<<0)
819#define M98925_REV_ID_SHIFT 0
820#define M98925_REV_ID_WIDTH 8
821
822struct max98925_priv {
823 struct regmap *regmap;
824 struct snd_soc_codec *codec;
825 struct max98925_pdata *pdata;
826 unsigned int sysclk;
827 unsigned int v_slot;
828 unsigned int i_slot;
829 unsigned int spk_gain;
830 unsigned int ch_size;
831};
832#endif
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
index 474cae82a874..5a30fdd0da00 100644
--- a/sound/soc/codecs/pcm512x.c
+++ b/sound/soc/codecs/pcm512x.c
@@ -54,6 +54,9 @@ struct pcm512x_priv {
54 int pll_d; 54 int pll_d;
55 int pll_p; 55 int pll_p;
56 unsigned long real_pll; 56 unsigned long real_pll;
57 unsigned long overclock_pll;
58 unsigned long overclock_dac;
59 unsigned long overclock_dsp;
57}; 60};
58 61
59/* 62/*
@@ -224,6 +227,90 @@ static bool pcm512x_volatile(struct device *dev, unsigned int reg)
224 } 227 }
225} 228}
226 229
230static int pcm512x_overclock_pll_get(struct snd_kcontrol *kcontrol,
231 struct snd_ctl_elem_value *ucontrol)
232{
233 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
234 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
235
236 ucontrol->value.integer.value[0] = pcm512x->overclock_pll;
237 return 0;
238}
239
240static int pcm512x_overclock_pll_put(struct snd_kcontrol *kcontrol,
241 struct snd_ctl_elem_value *ucontrol)
242{
243 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
244 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
245
246 switch (codec->dapm.bias_level) {
247 case SND_SOC_BIAS_OFF:
248 case SND_SOC_BIAS_STANDBY:
249 break;
250 default:
251 return -EBUSY;
252 }
253
254 pcm512x->overclock_pll = ucontrol->value.integer.value[0];
255 return 0;
256}
257
258static int pcm512x_overclock_dsp_get(struct snd_kcontrol *kcontrol,
259 struct snd_ctl_elem_value *ucontrol)
260{
261 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
262 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
263
264 ucontrol->value.integer.value[0] = pcm512x->overclock_dsp;
265 return 0;
266}
267
268static int pcm512x_overclock_dsp_put(struct snd_kcontrol *kcontrol,
269 struct snd_ctl_elem_value *ucontrol)
270{
271 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
272 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
273
274 switch (codec->dapm.bias_level) {
275 case SND_SOC_BIAS_OFF:
276 case SND_SOC_BIAS_STANDBY:
277 break;
278 default:
279 return -EBUSY;
280 }
281
282 pcm512x->overclock_dsp = ucontrol->value.integer.value[0];
283 return 0;
284}
285
286static int pcm512x_overclock_dac_get(struct snd_kcontrol *kcontrol,
287 struct snd_ctl_elem_value *ucontrol)
288{
289 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
290 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
291
292 ucontrol->value.integer.value[0] = pcm512x->overclock_dac;
293 return 0;
294}
295
296static int pcm512x_overclock_dac_put(struct snd_kcontrol *kcontrol,
297 struct snd_ctl_elem_value *ucontrol)
298{
299 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
300 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
301
302 switch (codec->dapm.bias_level) {
303 case SND_SOC_BIAS_OFF:
304 case SND_SOC_BIAS_STANDBY:
305 break;
306 default:
307 return -EBUSY;
308 }
309
310 pcm512x->overclock_dac = ucontrol->value.integer.value[0];
311 return 0;
312}
313
227static const DECLARE_TLV_DB_SCALE(digital_tlv, -10350, 50, 1); 314static const DECLARE_TLV_DB_SCALE(digital_tlv, -10350, 50, 1);
228static const DECLARE_TLV_DB_SCALE(analog_tlv, -600, 600, 0); 315static const DECLARE_TLV_DB_SCALE(analog_tlv, -600, 600, 0);
229static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 80, 0); 316static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 80, 0);
@@ -304,9 +391,9 @@ static const struct soc_enum pcm512x_veds =
304static const struct snd_kcontrol_new pcm512x_controls[] = { 391static const struct snd_kcontrol_new pcm512x_controls[] = {
305SOC_DOUBLE_R_TLV("Digital Playback Volume", PCM512x_DIGITAL_VOLUME_2, 392SOC_DOUBLE_R_TLV("Digital Playback Volume", PCM512x_DIGITAL_VOLUME_2,
306 PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv), 393 PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv),
307SOC_DOUBLE_TLV("Playback Volume", PCM512x_ANALOG_GAIN_CTRL, 394SOC_DOUBLE_TLV("Analogue Playback Volume", PCM512x_ANALOG_GAIN_CTRL,
308 PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv), 395 PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv),
309SOC_DOUBLE_TLV("Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST, 396SOC_DOUBLE_TLV("Analogue Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST,
310 PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv), 397 PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv),
311SOC_DOUBLE("Digital Playback Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT, 398SOC_DOUBLE("Digital Playback Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT,
312 PCM512x_RQMR_SHIFT, 1, 1), 399 PCM512x_RQMR_SHIFT, 1, 1),
@@ -328,6 +415,13 @@ SOC_ENUM("Volume Ramp Up Rate", pcm512x_vnuf),
328SOC_ENUM("Volume Ramp Up Step", pcm512x_vnus), 415SOC_ENUM("Volume Ramp Up Step", pcm512x_vnus),
329SOC_ENUM("Volume Ramp Down Emergency Rate", pcm512x_vedf), 416SOC_ENUM("Volume Ramp Down Emergency Rate", pcm512x_vedf),
330SOC_ENUM("Volume Ramp Down Emergency Step", pcm512x_veds), 417SOC_ENUM("Volume Ramp Down Emergency Step", pcm512x_veds),
418
419SOC_SINGLE_EXT("Max Overclock PLL", SND_SOC_NOPM, 0, 20, 0,
420 pcm512x_overclock_pll_get, pcm512x_overclock_pll_put),
421SOC_SINGLE_EXT("Max Overclock DSP", SND_SOC_NOPM, 0, 40, 0,
422 pcm512x_overclock_dsp_get, pcm512x_overclock_dsp_put),
423SOC_SINGLE_EXT("Max Overclock DAC", SND_SOC_NOPM, 0, 40, 0,
424 pcm512x_overclock_dac_get, pcm512x_overclock_dac_put),
331}; 425};
332 426
333static const struct snd_soc_dapm_widget pcm512x_dapm_widgets[] = { 427static const struct snd_soc_dapm_widget pcm512x_dapm_widgets[] = {
@@ -346,6 +440,45 @@ static const struct snd_soc_dapm_route pcm512x_dapm_routes[] = {
346 { "OUTR", NULL, "DACR" }, 440 { "OUTR", NULL, "DACR" },
347}; 441};
348 442
443static unsigned long pcm512x_pll_max(struct pcm512x_priv *pcm512x)
444{
445 return 25000000 + 25000000 * pcm512x->overclock_pll / 100;
446}
447
448static unsigned long pcm512x_dsp_max(struct pcm512x_priv *pcm512x)
449{
450 return 50000000 + 50000000 * pcm512x->overclock_dsp / 100;
451}
452
453static unsigned long pcm512x_dac_max(struct pcm512x_priv *pcm512x,
454 unsigned long rate)
455{
456 return rate + rate * pcm512x->overclock_dac / 100;
457}
458
459static unsigned long pcm512x_sck_max(struct pcm512x_priv *pcm512x)
460{
461 if (!pcm512x->pll_out)
462 return 25000000;
463 return pcm512x_pll_max(pcm512x);
464}
465
466static unsigned long pcm512x_ncp_target(struct pcm512x_priv *pcm512x,
467 unsigned long dac_rate)
468{
469 /*
470 * If the DAC is not actually overclocked, use the good old
471 * NCP target rate...
472 */
473 if (dac_rate <= 6144000)
474 return 1536000;
475 /*
476 * ...but if the DAC is in fact overclocked, bump the NCP target
477 * rate to get the recommended dividers even when overclocking.
478 */
479 return pcm512x_dac_max(pcm512x, 1536000);
480}
481
349static const u32 pcm512x_dai_rates[] = { 482static const u32 pcm512x_dai_rates[] = {
350 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 483 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000,
351 88200, 96000, 176400, 192000, 384000, 484 88200, 96000, 176400, 192000, 384000,
@@ -359,6 +492,7 @@ static const struct snd_pcm_hw_constraint_list constraints_slave = {
359static int pcm512x_hw_rule_rate(struct snd_pcm_hw_params *params, 492static int pcm512x_hw_rule_rate(struct snd_pcm_hw_params *params,
360 struct snd_pcm_hw_rule *rule) 493 struct snd_pcm_hw_rule *rule)
361{ 494{
495 struct pcm512x_priv *pcm512x = rule->private;
362 struct snd_interval ranges[2]; 496 struct snd_interval ranges[2];
363 int frame_size; 497 int frame_size;
364 498
@@ -377,7 +511,7 @@ static int pcm512x_hw_rule_rate(struct snd_pcm_hw_params *params,
377 */ 511 */
378 memset(ranges, 0, sizeof(ranges)); 512 memset(ranges, 0, sizeof(ranges));
379 ranges[0].min = 8000; 513 ranges[0].min = 8000;
380 ranges[0].max = 25000000 / frame_size / 2; 514 ranges[0].max = pcm512x_sck_max(pcm512x) / frame_size / 2;
381 ranges[1].min = DIV_ROUND_UP(16000000, frame_size); 515 ranges[1].min = DIV_ROUND_UP(16000000, frame_size);
382 ranges[1].max = 384000; 516 ranges[1].max = 384000;
383 break; 517 break;
@@ -408,7 +542,7 @@ static int pcm512x_dai_startup_master(struct snd_pcm_substream *substream,
408 return snd_pcm_hw_rule_add(substream->runtime, 0, 542 return snd_pcm_hw_rule_add(substream->runtime, 0,
409 SNDRV_PCM_HW_PARAM_RATE, 543 SNDRV_PCM_HW_PARAM_RATE,
410 pcm512x_hw_rule_rate, 544 pcm512x_hw_rule_rate,
411 NULL, 545 pcm512x,
412 SNDRV_PCM_HW_PARAM_FRAME_BITS, 546 SNDRV_PCM_HW_PARAM_FRAME_BITS,
413 SNDRV_PCM_HW_PARAM_CHANNELS, -1); 547 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
414 548
@@ -517,6 +651,8 @@ static unsigned long pcm512x_find_sck(struct snd_soc_dai *dai,
517 unsigned long bclk_rate) 651 unsigned long bclk_rate)
518{ 652{
519 struct device *dev = dai->dev; 653 struct device *dev = dai->dev;
654 struct snd_soc_codec *codec = dai->codec;
655 struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
520 unsigned long sck_rate; 656 unsigned long sck_rate;
521 int pow2; 657 int pow2;
522 658
@@ -527,9 +663,10 @@ static unsigned long pcm512x_find_sck(struct snd_soc_dai *dai,
527 * as many factors of 2 as possible, as that makes it easier 663 * as many factors of 2 as possible, as that makes it easier
528 * to find a fast DAC rate 664 * to find a fast DAC rate
529 */ 665 */
530 pow2 = 1 << fls((25000000 - 16000000) / bclk_rate); 666 pow2 = 1 << fls((pcm512x_pll_max(pcm512x) - 16000000) / bclk_rate);
531 for (; pow2; pow2 >>= 1) { 667 for (; pow2; pow2 >>= 1) {
532 sck_rate = rounddown(25000000, bclk_rate * pow2); 668 sck_rate = rounddown(pcm512x_pll_max(pcm512x),
669 bclk_rate * pow2);
533 if (sck_rate >= 16000000) 670 if (sck_rate >= 16000000)
534 break; 671 break;
535 } 672 }
@@ -576,8 +713,8 @@ static int pcm512x_find_pll_coeff(struct snd_soc_dai *dai,
576 713
577 /* pllin_rate / P (or here, den) cannot be greater than 20 MHz */ 714 /* pllin_rate / P (or here, den) cannot be greater than 20 MHz */
578 if (pllin_rate / den > 20000000 && num < 8) { 715 if (pllin_rate / den > 20000000 && num < 8) {
579 num *= 20000000 / (pllin_rate / den); 716 num *= DIV_ROUND_UP(pllin_rate / den, 20000000);
580 den *= 20000000 / (pllin_rate / den); 717 den *= DIV_ROUND_UP(pllin_rate / den, 20000000);
581 } 718 }
582 dev_dbg(dev, "num / den = %lu / %lu\n", num, den); 719 dev_dbg(dev, "num / den = %lu / %lu\n", num, den);
583 720
@@ -678,7 +815,7 @@ static unsigned long pcm512x_pllin_dac_rate(struct snd_soc_dai *dai,
678 return 0; /* futile, quit early */ 815 return 0; /* futile, quit early */
679 816
680 /* run DAC no faster than 6144000 Hz */ 817 /* run DAC no faster than 6144000 Hz */
681 for (dac_rate = rounddown(6144000, osr_rate); 818 for (dac_rate = rounddown(pcm512x_dac_max(pcm512x, 6144000), osr_rate);
682 dac_rate; 819 dac_rate;
683 dac_rate -= osr_rate) { 820 dac_rate -= osr_rate) {
684 821
@@ -805,7 +942,7 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
805 osr_rate = 16 * sample_rate; 942 osr_rate = 16 * sample_rate;
806 943
807 /* run DSP no faster than 50 MHz */ 944 /* run DSP no faster than 50 MHz */
808 dsp_div = mck_rate > 50000000 ? 2 : 1; 945 dsp_div = mck_rate > pcm512x_dsp_max(pcm512x) ? 2 : 1;
809 946
810 dac_rate = pcm512x_pllin_dac_rate(dai, osr_rate, pllin_rate); 947 dac_rate = pcm512x_pllin_dac_rate(dai, osr_rate, pllin_rate);
811 if (dac_rate) { 948 if (dac_rate) {
@@ -836,7 +973,8 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
836 dacsrc_rate = pllin_rate; 973 dacsrc_rate = pllin_rate;
837 } else { 974 } else {
838 /* run DAC no faster than 6144000 Hz */ 975 /* run DAC no faster than 6144000 Hz */
839 unsigned long dac_mul = 6144000 / osr_rate; 976 unsigned long dac_mul = pcm512x_dac_max(pcm512x, 6144000)
977 / osr_rate;
840 unsigned long sck_mul = sck_rate / osr_rate; 978 unsigned long sck_mul = sck_rate / osr_rate;
841 979
842 for (; dac_mul; dac_mul--) { 980 for (; dac_mul; dac_mul--) {
@@ -863,28 +1001,30 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
863 dacsrc_rate = sck_rate; 1001 dacsrc_rate = sck_rate;
864 } 1002 }
865 1003
1004 osr_div = DIV_ROUND_CLOSEST(dac_rate, osr_rate);
1005 if (osr_div > 128) {
1006 dev_err(dev, "Failed to find OSR divider\n");
1007 return -EINVAL;
1008 }
1009
866 dac_div = DIV_ROUND_CLOSEST(dacsrc_rate, dac_rate); 1010 dac_div = DIV_ROUND_CLOSEST(dacsrc_rate, dac_rate);
867 if (dac_div > 128) { 1011 if (dac_div > 128) {
868 dev_err(dev, "Failed to find DAC divider\n"); 1012 dev_err(dev, "Failed to find DAC divider\n");
869 return -EINVAL; 1013 return -EINVAL;
870 } 1014 }
1015 dac_rate = dacsrc_rate / dac_div;
871 1016
872 ncp_div = DIV_ROUND_CLOSEST(dacsrc_rate / dac_div, 1536000); 1017 ncp_div = DIV_ROUND_CLOSEST(dac_rate,
873 if (ncp_div > 128 || dacsrc_rate / dac_div / ncp_div > 2048000) { 1018 pcm512x_ncp_target(pcm512x, dac_rate));
1019 if (ncp_div > 128 || dac_rate / ncp_div > 2048000) {
874 /* run NCP no faster than 2048000 Hz, but why? */ 1020 /* run NCP no faster than 2048000 Hz, but why? */
875 ncp_div = DIV_ROUND_UP(dacsrc_rate / dac_div, 2048000); 1021 ncp_div = DIV_ROUND_UP(dac_rate, 2048000);
876 if (ncp_div > 128) { 1022 if (ncp_div > 128) {
877 dev_err(dev, "Failed to find NCP divider\n"); 1023 dev_err(dev, "Failed to find NCP divider\n");
878 return -EINVAL; 1024 return -EINVAL;
879 } 1025 }
880 } 1026 }
881 1027
882 osr_div = DIV_ROUND_CLOSEST(dac_rate, osr_rate);
883 if (osr_div > 128) {
884 dev_err(dev, "Failed to find OSR divider\n");
885 return -EINVAL;
886 }
887
888 idac = mck_rate / (dsp_div * sample_rate); 1028 idac = mck_rate / (dsp_div * sample_rate);
889 1029
890 ret = regmap_write(pcm512x->regmap, PCM512x_DSP_CLKDIV, dsp_div - 1); 1030 ret = regmap_write(pcm512x->regmap, PCM512x_DSP_CLKDIV, dsp_div - 1);
@@ -937,11 +1077,11 @@ static int pcm512x_set_dividers(struct snd_soc_dai *dai,
937 return ret; 1077 return ret;
938 } 1078 }
939 1079
940 if (sample_rate <= 48000) 1080 if (sample_rate <= pcm512x_dac_max(pcm512x, 48000))
941 fssp = PCM512x_FSSP_48KHZ; 1081 fssp = PCM512x_FSSP_48KHZ;
942 else if (sample_rate <= 96000) 1082 else if (sample_rate <= pcm512x_dac_max(pcm512x, 96000))
943 fssp = PCM512x_FSSP_96KHZ; 1083 fssp = PCM512x_FSSP_96KHZ;
944 else if (sample_rate <= 192000) 1084 else if (sample_rate <= pcm512x_dac_max(pcm512x, 192000))
945 fssp = PCM512x_FSSP_192KHZ; 1085 fssp = PCM512x_FSSP_192KHZ;
946 else 1086 else
947 fssp = PCM512x_FSSP_384KHZ; 1087 fssp = PCM512x_FSSP_384KHZ;
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index 9b541e52da8c..0fcda35a3a93 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -395,9 +395,20 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
395 395
396 rt286->jack = jack; 396 rt286->jack = jack;
397 397
398 /* Send an initial empty report */ 398 if (jack) {
399 snd_soc_jack_report(rt286->jack, 0, 399 /* enable IRQ */
400 SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); 400 if (rt286->jack->status & SND_JACK_HEADPHONE)
401 snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO1");
402 regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x2);
403 /* Send an initial empty report */
404 snd_soc_jack_report(rt286->jack, rt286->jack->status,
405 SND_JACK_MICROPHONE | SND_JACK_HEADPHONE);
406 } else {
407 /* disable IRQ */
408 regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x0);
409 snd_soc_dapm_disable_pin(&codec->dapm, "LDO1");
410 }
411 snd_soc_dapm_sync(&codec->dapm);
401 412
402 return 0; 413 return 0;
403} 414}
@@ -1037,7 +1048,6 @@ static int rt286_probe(struct snd_soc_codec *codec)
1037 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec); 1048 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
1038 1049
1039 rt286->codec = codec; 1050 rt286->codec = codec;
1040 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
1041 1051
1042 if (rt286->i2c->irq) { 1052 if (rt286->i2c->irq) {
1043 regmap_update_bits(rt286->regmap, 1053 regmap_update_bits(rt286->regmap,
@@ -1209,7 +1219,7 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1209{ 1219{
1210 struct rt286_platform_data *pdata = dev_get_platdata(&i2c->dev); 1220 struct rt286_platform_data *pdata = dev_get_platdata(&i2c->dev);
1211 struct rt286_priv *rt286; 1221 struct rt286_priv *rt286;
1212 int i, ret; 1222 int i, ret, val;
1213 1223
1214 rt286 = devm_kzalloc(&i2c->dev, sizeof(*rt286), 1224 rt286 = devm_kzalloc(&i2c->dev, sizeof(*rt286),
1215 GFP_KERNEL); 1225 GFP_KERNEL);
@@ -1224,11 +1234,15 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1224 return ret; 1234 return ret;
1225 } 1235 }
1226 1236
1227 regmap_read(rt286->regmap, 1237 ret = regmap_read(rt286->regmap,
1228 RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &ret); 1238 RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &val);
1229 if (ret != RT286_VENDOR_ID && ret != RT288_VENDOR_ID) { 1239 if (ret != 0) {
1240 dev_err(&i2c->dev, "I2C error %d\n", ret);
1241 return ret;
1242 }
1243 if (val != RT286_VENDOR_ID && val != RT288_VENDOR_ID) {
1230 dev_err(&i2c->dev, 1244 dev_err(&i2c->dev,
1231 "Device with ID register %x is not rt286\n", ret); 1245 "Device with ID register %x is not rt286\n", val);
1232 return -ENODEV; 1246 return -ENODEV;
1233 } 1247 }
1234 1248
@@ -1236,6 +1250,14 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1236 rt286->i2c = i2c; 1250 rt286->i2c = i2c;
1237 i2c_set_clientdata(i2c, rt286); 1251 i2c_set_clientdata(i2c, rt286);
1238 1252
1253 /* restore codec default */
1254 for (i = 0; i < INDEX_CACHE_SIZE; i++)
1255 regmap_write(rt286->regmap, rt286->index_cache[i].reg,
1256 rt286->index_cache[i].def);
1257 for (i = 0; i < ARRAY_SIZE(rt286_reg); i++)
1258 regmap_write(rt286->regmap, rt286_reg[i].reg,
1259 rt286_reg[i].def);
1260
1239 if (pdata) 1261 if (pdata)
1240 rt286->pdata = *pdata; 1262 rt286->pdata = *pdata;
1241 1263
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c
index c61852742ee3..2c10d77727af 100644
--- a/sound/soc/codecs/rt5631.c
+++ b/sound/soc/codecs/rt5631.c
@@ -1675,7 +1675,7 @@ static const struct i2c_device_id rt5631_i2c_id[] = {
1675MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id); 1675MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id);
1676 1676
1677#ifdef CONFIG_OF 1677#ifdef CONFIG_OF
1678static struct of_device_id rt5631_i2c_dt_ids[] = { 1678static const struct of_device_id rt5631_i2c_dt_ids[] = {
1679 { .compatible = "realtek,rt5631"}, 1679 { .compatible = "realtek,rt5631"},
1680 { .compatible = "realtek,alc5631"}, 1680 { .compatible = "realtek,alc5631"},
1681 { } 1681 { }
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index c9a4c5be083b..69528ae5410c 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -1270,6 +1270,8 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on)
1270 snd_soc_update_bits(codec, RT5645_PWR_ANLG1, 1270 snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
1271 RT5645_PWR_HP_L | RT5645_PWR_HP_R | 1271 RT5645_PWR_HP_L | RT5645_PWR_HP_R |
1272 RT5645_PWR_HA, 0); 1272 RT5645_PWR_HA, 0);
1273 snd_soc_update_bits(codec, RT5645_DEPOP_M2,
1274 RT5645_DEPOP_MASK, 0);
1273 } 1275 }
1274 } 1276 }
1275} 1277}
@@ -1538,8 +1540,6 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = {
1538 1540
1539 SND_SOC_DAPM_SUPPLY_S("adc stereo1 filter", 1, RT5645_PWR_DIG2, 1541 SND_SOC_DAPM_SUPPLY_S("adc stereo1 filter", 1, RT5645_PWR_DIG2,
1540 RT5645_PWR_ADC_S1F_BIT, 0, NULL, 0), 1542 RT5645_PWR_ADC_S1F_BIT, 0, NULL, 0),
1541 SND_SOC_DAPM_SUPPLY_S("adc stereo2 filter", 1, RT5645_PWR_DIG2,
1542 RT5645_PWR_ADC_S2F_BIT, 0, NULL, 0),
1543 SND_SOC_DAPM_MIXER_E("Sto1 ADC MIXL", SND_SOC_NOPM, 0, 0, 1543 SND_SOC_DAPM_MIXER_E("Sto1 ADC MIXL", SND_SOC_NOPM, 0, 0,
1544 rt5645_sto1_adc_l_mix, ARRAY_SIZE(rt5645_sto1_adc_l_mix), 1544 rt5645_sto1_adc_l_mix, ARRAY_SIZE(rt5645_sto1_adc_l_mix),
1545 NULL, 0), 1545 NULL, 0),
@@ -1729,7 +1729,6 @@ static const struct snd_soc_dapm_widget rt5650_specific_dapm_widgets[] = {
1729 1729
1730static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { 1730static const struct snd_soc_dapm_route rt5645_dapm_routes[] = {
1731 { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc }, 1731 { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc },
1732 { "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc },
1733 { "adc mono left filter", NULL, "ADC MONO L ASRC", is_using_asrc }, 1732 { "adc mono left filter", NULL, "ADC MONO L ASRC", is_using_asrc },
1734 { "adc mono right filter", NULL, "ADC MONO R ASRC", is_using_asrc }, 1733 { "adc mono right filter", NULL, "ADC MONO R ASRC", is_using_asrc },
1735 { "dac mono left filter", NULL, "DAC MONO L ASRC", is_using_asrc }, 1734 { "dac mono left filter", NULL, "DAC MONO L ASRC", is_using_asrc },
@@ -2052,7 +2051,7 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream,
2052{ 2051{
2053 struct snd_soc_codec *codec = dai->codec; 2052 struct snd_soc_codec *codec = dai->codec;
2054 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); 2053 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
2055 unsigned int val_len = 0, val_clk, mask_clk; 2054 unsigned int val_len = 0, val_clk, mask_clk, dl_sft;
2056 int pre_div, bclk_ms, frame_size; 2055 int pre_div, bclk_ms, frame_size;
2057 2056
2058 rt5645->lrck[dai->id] = params_rate(params); 2057 rt5645->lrck[dai->id] = params_rate(params);
@@ -2066,6 +2065,16 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream,
2066 dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size); 2065 dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size);
2067 return -EINVAL; 2066 return -EINVAL;
2068 } 2067 }
2068
2069 switch (rt5645->codec_type) {
2070 case CODEC_TYPE_RT5650:
2071 dl_sft = 4;
2072 break;
2073 default:
2074 dl_sft = 2;
2075 break;
2076 }
2077
2069 bclk_ms = frame_size > 32; 2078 bclk_ms = frame_size > 32;
2070 rt5645->bclk[dai->id] = rt5645->lrck[dai->id] * (32 << bclk_ms); 2079 rt5645->bclk[dai->id] = rt5645->lrck[dai->id] * (32 << bclk_ms);
2071 2080
@@ -2078,13 +2087,13 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream,
2078 case 16: 2087 case 16:
2079 break; 2088 break;
2080 case 20: 2089 case 20:
2081 val_len |= RT5645_I2S_DL_20; 2090 val_len = 0x1;
2082 break; 2091 break;
2083 case 24: 2092 case 24:
2084 val_len |= RT5645_I2S_DL_24; 2093 val_len = 0x2;
2085 break; 2094 break;
2086 case 8: 2095 case 8:
2087 val_len |= RT5645_I2S_DL_8; 2096 val_len = 0x3;
2088 break; 2097 break;
2089 default: 2098 default:
2090 return -EINVAL; 2099 return -EINVAL;
@@ -2096,7 +2105,7 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream,
2096 val_clk = bclk_ms << RT5645_I2S_BCLK_MS1_SFT | 2105 val_clk = bclk_ms << RT5645_I2S_BCLK_MS1_SFT |
2097 pre_div << RT5645_I2S_PD1_SFT; 2106 pre_div << RT5645_I2S_PD1_SFT;
2098 snd_soc_update_bits(codec, RT5645_I2S1_SDP, 2107 snd_soc_update_bits(codec, RT5645_I2S1_SDP,
2099 RT5645_I2S_DL_MASK, val_len); 2108 (0x3 << dl_sft), (val_len << dl_sft));
2100 snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk); 2109 snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk);
2101 break; 2110 break;
2102 case RT5645_AIF2: 2111 case RT5645_AIF2:
@@ -2104,7 +2113,7 @@ static int rt5645_hw_params(struct snd_pcm_substream *substream,
2104 val_clk = bclk_ms << RT5645_I2S_BCLK_MS2_SFT | 2113 val_clk = bclk_ms << RT5645_I2S_BCLK_MS2_SFT |
2105 pre_div << RT5645_I2S_PD2_SFT; 2114 pre_div << RT5645_I2S_PD2_SFT;
2106 snd_soc_update_bits(codec, RT5645_I2S2_SDP, 2115 snd_soc_update_bits(codec, RT5645_I2S2_SDP,
2107 RT5645_I2S_DL_MASK, val_len); 2116 (0x3 << dl_sft), (val_len << dl_sft));
2108 snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk); 2117 snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk);
2109 break; 2118 break;
2110 default: 2119 default:
@@ -2119,7 +2128,16 @@ static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2119{ 2128{
2120 struct snd_soc_codec *codec = dai->codec; 2129 struct snd_soc_codec *codec = dai->codec;
2121 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); 2130 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
2122 unsigned int reg_val = 0; 2131 unsigned int reg_val = 0, pol_sft;
2132
2133 switch (rt5645->codec_type) {
2134 case CODEC_TYPE_RT5650:
2135 pol_sft = 8;
2136 break;
2137 default:
2138 pol_sft = 7;
2139 break;
2140 }
2123 2141
2124 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 2142 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2125 case SND_SOC_DAIFMT_CBM_CFM: 2143 case SND_SOC_DAIFMT_CBM_CFM:
@@ -2137,7 +2155,7 @@ static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2137 case SND_SOC_DAIFMT_NB_NF: 2155 case SND_SOC_DAIFMT_NB_NF:
2138 break; 2156 break;
2139 case SND_SOC_DAIFMT_IB_NF: 2157 case SND_SOC_DAIFMT_IB_NF:
2140 reg_val |= RT5645_I2S_BP_INV; 2158 reg_val |= (1 << pol_sft);
2141 break; 2159 break;
2142 default: 2160 default:
2143 return -EINVAL; 2161 return -EINVAL;
@@ -2161,12 +2179,12 @@ static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2161 switch (dai->id) { 2179 switch (dai->id) {
2162 case RT5645_AIF1: 2180 case RT5645_AIF1:
2163 snd_soc_update_bits(codec, RT5645_I2S1_SDP, 2181 snd_soc_update_bits(codec, RT5645_I2S1_SDP,
2164 RT5645_I2S_MS_MASK | RT5645_I2S_BP_MASK | 2182 RT5645_I2S_MS_MASK | (1 << pol_sft) |
2165 RT5645_I2S_DF_MASK, reg_val); 2183 RT5645_I2S_DF_MASK, reg_val);
2166 break; 2184 break;
2167 case RT5645_AIF2: 2185 case RT5645_AIF2:
2168 snd_soc_update_bits(codec, RT5645_I2S2_SDP, 2186 snd_soc_update_bits(codec, RT5645_I2S2_SDP,
2169 RT5645_I2S_MS_MASK | RT5645_I2S_BP_MASK | 2187 RT5645_I2S_MS_MASK | (1 << pol_sft) |
2170 RT5645_I2S_DF_MASK, reg_val); 2188 RT5645_I2S_DF_MASK, reg_val);
2171 break; 2189 break;
2172 default: 2190 default:
@@ -2285,23 +2303,42 @@ static int rt5645_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
2285 unsigned int rx_mask, int slots, int slot_width) 2303 unsigned int rx_mask, int slots, int slot_width)
2286{ 2304{
2287 struct snd_soc_codec *codec = dai->codec; 2305 struct snd_soc_codec *codec = dai->codec;
2288 unsigned int val = 0; 2306 struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
2307 unsigned int i_slot_sft, o_slot_sft, i_width_sht, o_width_sht, en_sft;
2308 unsigned int mask, val = 0;
2289 2309
2310 switch (rt5645->codec_type) {
2311 case CODEC_TYPE_RT5650:
2312 en_sft = 15;
2313 i_slot_sft = 10;
2314 o_slot_sft = 8;
2315 i_width_sht = 6;
2316 o_width_sht = 4;
2317 mask = 0x8ff0;
2318 break;
2319 default:
2320 en_sft = 14;
2321 i_slot_sft = o_slot_sft = 12;
2322 i_width_sht = o_width_sht = 10;
2323 mask = 0x7c00;
2324 break;
2325 }
2290 if (rx_mask || tx_mask) { 2326 if (rx_mask || tx_mask) {
2291 val |= (1 << 14); 2327 val |= (1 << en_sft);
2292 snd_soc_update_bits(codec, RT5645_BASS_BACK, 2328 if (rt5645->codec_type == CODEC_TYPE_RT5645)
2293 RT5645_G_BB_BST_MASK, RT5645_G_BB_BST_25DB); 2329 snd_soc_update_bits(codec, RT5645_BASS_BACK,
2330 RT5645_G_BB_BST_MASK, RT5645_G_BB_BST_25DB);
2294 } 2331 }
2295 2332
2296 switch (slots) { 2333 switch (slots) {
2297 case 4: 2334 case 4:
2298 val |= (1 << 12); 2335 val |= (1 << i_slot_sft) | (1 << o_slot_sft);
2299 break; 2336 break;
2300 case 6: 2337 case 6:
2301 val |= (2 << 12); 2338 val |= (2 << i_slot_sft) | (2 << o_slot_sft);
2302 break; 2339 break;
2303 case 8: 2340 case 8:
2304 val |= (3 << 12); 2341 val |= (3 << i_slot_sft) | (3 << o_slot_sft);
2305 break; 2342 break;
2306 case 2: 2343 case 2:
2307 default: 2344 default:
@@ -2310,20 +2347,20 @@ static int rt5645_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
2310 2347
2311 switch (slot_width) { 2348 switch (slot_width) {
2312 case 20: 2349 case 20:
2313 val |= (1 << 10); 2350 val |= (1 << i_width_sht) | (1 << o_width_sht);
2314 break; 2351 break;
2315 case 24: 2352 case 24:
2316 val |= (2 << 10); 2353 val |= (2 << i_width_sht) | (2 << o_width_sht);
2317 break; 2354 break;
2318 case 32: 2355 case 32:
2319 val |= (3 << 10); 2356 val |= (3 << i_width_sht) | (3 << o_width_sht);
2320 break; 2357 break;
2321 case 16: 2358 case 16:
2322 default: 2359 default:
2323 break; 2360 break;
2324 } 2361 }
2325 2362
2326 snd_soc_update_bits(codec, RT5645_TDM_CTRL_1, 0x7c00, val); 2363 snd_soc_update_bits(codec, RT5645_TDM_CTRL_1, mask, val);
2327 2364
2328 return 0; 2365 return 0;
2329} 2366}
@@ -2361,7 +2398,8 @@ static int rt5645_set_bias_level(struct snd_soc_codec *codec,
2361 2398
2362 case SND_SOC_BIAS_OFF: 2399 case SND_SOC_BIAS_OFF:
2363 snd_soc_write(codec, RT5645_DEPOP_M2, 0x1100); 2400 snd_soc_write(codec, RT5645_DEPOP_M2, 0x1100);
2364 snd_soc_write(codec, RT5645_GEN_CTRL1, 0x0128); 2401 snd_soc_update_bits(codec, RT5645_GEN_CTRL1,
2402 RT5645_DIG_GATE_CTRL, 0);
2365 snd_soc_update_bits(codec, RT5645_PWR_ANLG1, 2403 snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
2366 RT5645_PWR_VREF1 | RT5645_PWR_MB | 2404 RT5645_PWR_VREF1 | RT5645_PWR_MB |
2367 RT5645_PWR_BG | RT5645_PWR_VREF2 | 2405 RT5645_PWR_BG | RT5645_PWR_VREF2 |
@@ -2598,7 +2636,7 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5645 = {
2598static const struct regmap_config rt5645_regmap = { 2636static const struct regmap_config rt5645_regmap = {
2599 .reg_bits = 8, 2637 .reg_bits = 8,
2600 .val_bits = 16, 2638 .val_bits = 16,
2601 2639 .use_single_rw = true,
2602 .max_register = RT5645_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5645_ranges) * 2640 .max_register = RT5645_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5645_ranges) *
2603 RT5645_PR_SPACING), 2641 RT5645_PR_SPACING),
2604 .volatile_reg = rt5645_volatile_register, 2642 .volatile_reg = rt5645_volatile_register,
diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h
index dbfd98c22f4d..db78e9462876 100644
--- a/sound/soc/codecs/rt5645.h
+++ b/sound/soc/codecs/rt5645.h
@@ -804,8 +804,6 @@
804#define RT5645_PWR_DAC_MF_L_BIT 10 804#define RT5645_PWR_DAC_MF_L_BIT 10
805#define RT5645_PWR_DAC_MF_R (0x1 << 9) 805#define RT5645_PWR_DAC_MF_R (0x1 << 9)
806#define RT5645_PWR_DAC_MF_R_BIT 9 806#define RT5645_PWR_DAC_MF_R_BIT 9
807#define RT5645_PWR_ADC_S2F (0x1 << 8)
808#define RT5645_PWR_ADC_S2F_BIT 8
809#define RT5645_PWR_PDM1 (0x1 << 7) 807#define RT5645_PWR_PDM1 (0x1 << 7)
810#define RT5645_PWR_PDM1_BIT 7 808#define RT5645_PWR_PDM1_BIT 7
811#define RT5645_PWR_PDM2 (0x1 << 6) 809#define RT5645_PWR_PDM2 (0x1 << 6)
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
index fd102613d20d..cc7f84a150a7 100644
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -403,6 +403,189 @@ static bool rt5670_readable_register(struct device *dev, unsigned int reg)
403 } 403 }
404} 404}
405 405
406/**
407 * rt5670_headset_detect - Detect headset.
408 * @codec: SoC audio codec device.
409 * @jack_insert: Jack insert or not.
410 *
411 * Detect whether is headset or not when jack inserted.
412 *
413 * Returns detect status.
414 */
415
416static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert)
417{
418 int val;
419 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
420
421 if (jack_insert) {
422 snd_soc_dapm_force_enable_pin(&codec->dapm,
423 "Mic Det Power");
424 snd_soc_dapm_sync(&codec->dapm);
425 snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x0);
426 snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
427 RT5670_CBJ_DET_MODE | RT5670_CBJ_MN_JD,
428 RT5670_CBJ_MN_JD);
429 snd_soc_write(codec, RT5670_GPIO_CTRL2, 0x0004);
430 snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
431 RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ);
432 snd_soc_update_bits(codec, RT5670_CJ_CTRL1,
433 RT5670_CBJ_BST1_EN, RT5670_CBJ_BST1_EN);
434 snd_soc_write(codec, RT5670_JD_CTRL3, 0x00f0);
435 snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
436 RT5670_CBJ_MN_JD, RT5670_CBJ_MN_JD);
437 snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
438 RT5670_CBJ_MN_JD, 0);
439 msleep(300);
440 val = snd_soc_read(codec, RT5670_CJ_CTRL3) & 0x7;
441 if (val == 0x1 || val == 0x2) {
442 rt5670->jack_type = SND_JACK_HEADSET;
443 /* for push button */
444 snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x8);
445 snd_soc_update_bits(codec, RT5670_IL_CMD, 0x40, 0x40);
446 snd_soc_read(codec, RT5670_IL_CMD);
447 } else {
448 snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
449 rt5670->jack_type = SND_JACK_HEADPHONE;
450 snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power");
451 snd_soc_dapm_sync(&codec->dapm);
452 }
453 } else {
454 snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x0);
455 snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
456 rt5670->jack_type = 0;
457 snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power");
458 snd_soc_dapm_sync(&codec->dapm);
459 }
460
461 return rt5670->jack_type;
462}
463
464void rt5670_jack_suspend(struct snd_soc_codec *codec)
465{
466 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
467
468 rt5670->jack_type_saved = rt5670->jack_type;
469 rt5670_headset_detect(codec, 0);
470}
471EXPORT_SYMBOL_GPL(rt5670_jack_suspend);
472
473void rt5670_jack_resume(struct snd_soc_codec *codec)
474{
475 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
476
477 if (rt5670->jack_type_saved)
478 rt5670_headset_detect(codec, 1);
479}
480EXPORT_SYMBOL_GPL(rt5670_jack_resume);
481
482static int rt5670_button_detect(struct snd_soc_codec *codec)
483{
484 int btn_type, val;
485
486 val = snd_soc_read(codec, RT5670_IL_CMD);
487 btn_type = val & 0xff80;
488 snd_soc_write(codec, RT5670_IL_CMD, val);
489 if (btn_type != 0) {
490 msleep(20);
491 val = snd_soc_read(codec, RT5670_IL_CMD);
492 snd_soc_write(codec, RT5670_IL_CMD, val);
493 }
494
495 return btn_type;
496}
497
498static int rt5670_irq_detection(void *data)
499{
500 struct rt5670_priv *rt5670 = (struct rt5670_priv *)data;
501 struct snd_soc_jack_gpio *gpio = &rt5670->hp_gpio;
502 struct snd_soc_jack *jack = rt5670->jack;
503 int val, btn_type, report = jack->status;
504
505 if (rt5670->pdata.jd_mode == 1) /* 2 port */
506 val = snd_soc_read(rt5670->codec, RT5670_A_JD_CTRL1) & 0x0070;
507 else
508 val = snd_soc_read(rt5670->codec, RT5670_A_JD_CTRL1) & 0x0020;
509
510 switch (val) {
511 /* jack in */
512 case 0x30: /* 2 port */
513 case 0x0: /* 1 port or 2 port */
514 if (rt5670->jack_type == 0) {
515 report = rt5670_headset_detect(rt5670->codec, 1);
516 /* for push button and jack out */
517 gpio->debounce_time = 25;
518 break;
519 }
520 btn_type = 0;
521 if (snd_soc_read(rt5670->codec, RT5670_INT_IRQ_ST) & 0x4) {
522 /* button pressed */
523 report = SND_JACK_HEADSET;
524 btn_type = rt5670_button_detect(rt5670->codec);
525 switch (btn_type) {
526 case 0x2000: /* up */
527 report |= SND_JACK_BTN_1;
528 break;
529 case 0x0400: /* center */
530 report |= SND_JACK_BTN_0;
531 break;
532 case 0x0080: /* down */
533 report |= SND_JACK_BTN_2;
534 break;
535 default:
536 dev_err(rt5670->codec->dev,
537 "Unexpected button code 0x%04x\n",
538 btn_type);
539 break;
540 }
541 }
542 if (btn_type == 0)/* button release */
543 report = rt5670->jack_type;
544
545 break;
546 /* jack out */
547 case 0x70: /* 2 port */
548 case 0x10: /* 2 port */
549 case 0x20: /* 1 port */
550 report = 0;
551 snd_soc_update_bits(rt5670->codec, RT5670_INT_IRQ_ST, 0x1, 0x0);
552 rt5670_headset_detect(rt5670->codec, 0);
553 gpio->debounce_time = 150; /* for jack in */
554 break;
555 default:
556 break;
557 }
558
559 return report;
560}
561
562int rt5670_set_jack_detect(struct snd_soc_codec *codec,
563 struct snd_soc_jack *jack)
564{
565 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
566 int ret;
567
568 rt5670->jack = jack;
569 rt5670->hp_gpio.gpiod_dev = codec->dev;
570 rt5670->hp_gpio.name = "headphone detect";
571 rt5670->hp_gpio.report = SND_JACK_HEADSET |
572 SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2;
573 rt5670->hp_gpio.debounce_time = 150;
574 rt5670->hp_gpio.wake = true;
575 rt5670->hp_gpio.data = (struct rt5670_priv *)rt5670;
576 rt5670->hp_gpio.jack_status_check = rt5670_irq_detection;
577
578 ret = snd_soc_jack_add_gpios(rt5670->jack, 1,
579 &rt5670->hp_gpio);
580 if (ret) {
581 dev_err(codec->dev, "Adding jack GPIO failed\n");
582 return ret;
583 }
584
585 return 0;
586}
587EXPORT_SYMBOL_GPL(rt5670_set_jack_detect);
588
406static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); 589static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
407static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); 590static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
408static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); 591static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
@@ -517,11 +700,9 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
517 struct snd_soc_dapm_widget *sink) 700 struct snd_soc_dapm_widget *sink)
518{ 701{
519 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); 702 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
520 unsigned int val; 703 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
521 704
522 val = snd_soc_read(codec, RT5670_GLB_CLK); 705 if (rt5670->sysclk_src == RT5670_SCLK_S_PLL1)
523 val &= RT5670_SCLK_SRC_MASK;
524 if (val == RT5670_SCLK_SRC_PLL1)
525 return 1; 706 return 1;
526 else 707 else
527 return 0; 708 return 0;
@@ -2271,16 +2452,6 @@ static int rt5670_set_dai_sysclk(struct snd_soc_dai *dai,
2271 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); 2452 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
2272 unsigned int reg_val = 0; 2453 unsigned int reg_val = 0;
2273 2454
2274 if (freq == rt5670->sysclk && clk_id == rt5670->sysclk_src)
2275 return 0;
2276
2277 if (rt5670->pdata.jd_mode) {
2278 if (clk_id == RT5670_SCLK_S_PLL1)
2279 snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1");
2280 else
2281 snd_soc_dapm_disable_pin(&codec->dapm, "PLL1");
2282 snd_soc_dapm_sync(&codec->dapm);
2283 }
2284 switch (clk_id) { 2455 switch (clk_id) {
2285 case RT5670_SCLK_S_MCLK: 2456 case RT5670_SCLK_S_MCLK:
2286 reg_val |= RT5670_SCLK_SRC_MCLK; 2457 reg_val |= RT5670_SCLK_SRC_MCLK;
@@ -2298,7 +2469,8 @@ static int rt5670_set_dai_sysclk(struct snd_soc_dai *dai,
2298 snd_soc_update_bits(codec, RT5670_GLB_CLK, 2469 snd_soc_update_bits(codec, RT5670_GLB_CLK,
2299 RT5670_SCLK_SRC_MASK, reg_val); 2470 RT5670_SCLK_SRC_MASK, reg_val);
2300 rt5670->sysclk = freq; 2471 rt5670->sysclk = freq;
2301 rt5670->sysclk_src = clk_id; 2472 if (clk_id != RT5670_SCLK_S_RCCLK)
2473 rt5670->sysclk_src = clk_id;
2302 2474
2303 dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); 2475 dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
2304 2476
@@ -2517,6 +2689,7 @@ static int rt5670_remove(struct snd_soc_codec *codec)
2517 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); 2689 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
2518 2690
2519 regmap_write(rt5670->regmap, RT5670_RESET, 0); 2691 regmap_write(rt5670->regmap, RT5670_RESET, 0);
2692 snd_soc_jack_free_gpios(rt5670->jack, 1, &rt5670->hp_gpio);
2520 return 0; 2693 return 0;
2521} 2694}
2522 2695
@@ -2676,6 +2849,7 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
2676 if (dmi_check_system(dmi_platform_intel_braswell)) { 2849 if (dmi_check_system(dmi_platform_intel_braswell)) {
2677 rt5670->pdata.dmic_en = true; 2850 rt5670->pdata.dmic_en = true;
2678 rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P; 2851 rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P;
2852 rt5670->pdata.dev_gpio = true;
2679 rt5670->pdata.jd_mode = 1; 2853 rt5670->pdata.jd_mode = 1;
2680 } 2854 }
2681 2855
@@ -2717,12 +2891,17 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
2717 regmap_update_bits(rt5670->regmap, RT5670_IN2, 2891 regmap_update_bits(rt5670->regmap, RT5670_IN2,
2718 RT5670_IN_DF2, RT5670_IN_DF2); 2892 RT5670_IN_DF2, RT5670_IN_DF2);
2719 2893
2720 if (i2c->irq) { 2894 if (rt5670->pdata.dev_gpio) {
2895 /* for push button */
2896 regmap_write(rt5670->regmap, RT5670_IL_CMD, 0x0000);
2897 regmap_write(rt5670->regmap, RT5670_IL_CMD2, 0x0010);
2898 regmap_write(rt5670->regmap, RT5670_IL_CMD3, 0x0014);
2899 /* for irq */
2721 regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1, 2900 regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1,
2722 RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ); 2901 RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ);
2723 regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2, 2902 regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
2724 RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT); 2903 RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT);
2725 2904 regmap_update_bits(rt5670->regmap, RT5670_DIG_MISC, 0x8, 0x8);
2726 } 2905 }
2727 2906
2728 if (rt5670->pdata.jd_mode) { 2907 if (rt5670->pdata.jd_mode) {
diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h
index 21f8e18c13c4..dc2b46236c5c 100644
--- a/sound/soc/codecs/rt5670.h
+++ b/sound/soc/codecs/rt5670.h
@@ -1950,17 +1950,20 @@ enum {
1950}; 1950};
1951 1951
1952enum { 1952enum {
1953 RT5670_DMIC1_DISABLED,
1953 RT5670_DMIC_DATA_GPIO6, 1954 RT5670_DMIC_DATA_GPIO6,
1954 RT5670_DMIC_DATA_IN2P, 1955 RT5670_DMIC_DATA_IN2P,
1955 RT5670_DMIC_DATA_GPIO7, 1956 RT5670_DMIC_DATA_GPIO7,
1956}; 1957};
1957 1958
1958enum { 1959enum {
1960 RT5670_DMIC2_DISABLED,
1959 RT5670_DMIC_DATA_GPIO8, 1961 RT5670_DMIC_DATA_GPIO8,
1960 RT5670_DMIC_DATA_IN3N, 1962 RT5670_DMIC_DATA_IN3N,
1961}; 1963};
1962 1964
1963enum { 1965enum {
1966 RT5670_DMIC3_DISABLED,
1964 RT5670_DMIC_DATA_GPIO9, 1967 RT5670_DMIC_DATA_GPIO9,
1965 RT5670_DMIC_DATA_GPIO10, 1968 RT5670_DMIC_DATA_GPIO10,
1966 RT5670_DMIC_DATA_GPIO5, 1969 RT5670_DMIC_DATA_GPIO5,
@@ -1985,6 +1988,8 @@ struct rt5670_priv {
1985 struct snd_soc_codec *codec; 1988 struct snd_soc_codec *codec;
1986 struct rt5670_platform_data pdata; 1989 struct rt5670_platform_data pdata;
1987 struct regmap *regmap; 1990 struct regmap *regmap;
1991 struct snd_soc_jack *jack;
1992 struct snd_soc_jack_gpio hp_gpio;
1988 1993
1989 int sysclk; 1994 int sysclk;
1990 int sysclk_src; 1995 int sysclk_src;
@@ -1999,6 +2004,11 @@ struct rt5670_priv {
1999 int dsp_sw; /* expected parameter setting */ 2004 int dsp_sw; /* expected parameter setting */
2000 int dsp_rate; 2005 int dsp_rate;
2001 int jack_type; 2006 int jack_type;
2007 int jack_type_saved;
2002}; 2008};
2003 2009
2010void rt5670_jack_suspend(struct snd_soc_codec *codec);
2011void rt5670_jack_resume(struct snd_soc_codec *codec);
2012int rt5670_set_jack_detect(struct snd_soc_codec *codec,
2013 struct snd_soc_jack *jack);
2004#endif /* __RT5670_H__ */ 2014#endif /* __RT5670_H__ */
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index fb9c20eace3f..af182586712d 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -718,11 +718,24 @@ static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on)
718 RT5677_LDO1_SEL_MASK, 0x0); 718 RT5677_LDO1_SEL_MASK, 0x0);
719 regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG2, 719 regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG2,
720 RT5677_PWR_LDO1, RT5677_PWR_LDO1); 720 RT5677_PWR_LDO1, RT5677_PWR_LDO1);
721 regmap_update_bits(rt5677->regmap, RT5677_GLB_CLK1, 721 switch (rt5677->type) {
722 RT5677_MCLK_SRC_MASK, RT5677_MCLK2_SRC); 722 case RT5677:
723 regmap_update_bits(rt5677->regmap, RT5677_GLB_CLK2, 723 regmap_update_bits(rt5677->regmap, RT5677_GLB_CLK1,
724 RT5677_PLL2_PR_SRC_MASK | RT5677_DSP_CLK_SRC_MASK, 724 RT5677_MCLK_SRC_MASK, RT5677_MCLK2_SRC);
725 RT5677_PLL2_PR_SRC_MCLK2 | RT5677_DSP_CLK_SRC_BYPASS); 725 regmap_update_bits(rt5677->regmap, RT5677_GLB_CLK2,
726 RT5677_PLL2_PR_SRC_MASK |
727 RT5677_DSP_CLK_SRC_MASK,
728 RT5677_PLL2_PR_SRC_MCLK2 |
729 RT5677_DSP_CLK_SRC_BYPASS);
730 break;
731 case RT5676:
732 regmap_update_bits(rt5677->regmap, RT5677_GLB_CLK2,
733 RT5677_DSP_CLK_SRC_MASK,
734 RT5677_DSP_CLK_SRC_BYPASS);
735 break;
736 default:
737 break;
738 }
726 regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x07ff); 739 regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x07ff);
727 regmap_write(rt5677->regmap, RT5677_PWR_DSP1, 0x07fd); 740 regmap_write(rt5677->regmap, RT5677_PWR_DSP1, 0x07fd);
728 rt5677_set_dsp_mode(codec, true); 741 rt5677_set_dsp_mode(codec, true);
@@ -1021,6 +1034,169 @@ static int can_use_asrc(struct snd_soc_dapm_widget *source,
1021 return 0; 1034 return 0;
1022} 1035}
1023 1036
1037/**
1038 * rt5677_sel_asrc_clk_src - select ASRC clock source for a set of filters
1039 * @codec: SoC audio codec device.
1040 * @filter_mask: mask of filters.
1041 * @clk_src: clock source
1042 *
1043 * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5677 can
1044 * only support standard 32fs or 64fs i2s format, ASRC should be enabled to
1045 * support special i2s clock format such as Intel's 100fs(100 * sampling rate).
1046 * ASRC function will track i2s clock and generate a corresponding system clock
1047 * for codec. This function provides an API to select the clock source for a
1048 * set of filters specified by the mask. And the codec driver will turn on ASRC
1049 * for these filters if ASRC is selected as their clock source.
1050 */
1051int rt5677_sel_asrc_clk_src(struct snd_soc_codec *codec,
1052 unsigned int filter_mask, unsigned int clk_src)
1053{
1054 struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
1055 unsigned int asrc3_mask = 0, asrc3_value = 0;
1056 unsigned int asrc4_mask = 0, asrc4_value = 0;
1057 unsigned int asrc5_mask = 0, asrc5_value = 0;
1058 unsigned int asrc6_mask = 0, asrc6_value = 0;
1059 unsigned int asrc7_mask = 0, asrc7_value = 0;
1060
1061 switch (clk_src) {
1062 case RT5677_CLK_SEL_SYS:
1063 case RT5677_CLK_SEL_I2S1_ASRC:
1064 case RT5677_CLK_SEL_I2S2_ASRC:
1065 case RT5677_CLK_SEL_I2S3_ASRC:
1066 case RT5677_CLK_SEL_I2S4_ASRC:
1067 case RT5677_CLK_SEL_I2S5_ASRC:
1068 case RT5677_CLK_SEL_I2S6_ASRC:
1069 case RT5677_CLK_SEL_SYS2:
1070 case RT5677_CLK_SEL_SYS3:
1071 case RT5677_CLK_SEL_SYS4:
1072 case RT5677_CLK_SEL_SYS5:
1073 case RT5677_CLK_SEL_SYS6:
1074 case RT5677_CLK_SEL_SYS7:
1075 break;
1076
1077 default:
1078 return -EINVAL;
1079 }
1080
1081 /* ASRC 3 */
1082 if (filter_mask & RT5677_DA_STEREO_FILTER) {
1083 asrc3_mask |= RT5677_DA_STO_CLK_SEL_MASK;
1084 asrc3_value = (asrc3_value & ~RT5677_DA_STO_CLK_SEL_MASK)
1085 | (clk_src << RT5677_DA_STO_CLK_SEL_SFT);
1086 }
1087
1088 if (filter_mask & RT5677_DA_MONO2_L_FILTER) {
1089 asrc3_mask |= RT5677_DA_MONO2L_CLK_SEL_MASK;
1090 asrc3_value = (asrc3_value & ~RT5677_DA_MONO2L_CLK_SEL_MASK)
1091 | (clk_src << RT5677_DA_MONO2L_CLK_SEL_SFT);
1092 }
1093
1094 if (filter_mask & RT5677_DA_MONO2_R_FILTER) {
1095 asrc3_mask |= RT5677_DA_MONO2R_CLK_SEL_MASK;
1096 asrc3_value = (asrc3_value & ~RT5677_DA_MONO2R_CLK_SEL_MASK)
1097 | (clk_src << RT5677_DA_MONO2R_CLK_SEL_SFT);
1098 }
1099
1100 if (asrc3_mask)
1101 regmap_update_bits(rt5677->regmap, RT5677_ASRC_3, asrc3_mask,
1102 asrc3_value);
1103
1104 /* ASRC 4 */
1105 if (filter_mask & RT5677_DA_MONO3_L_FILTER) {
1106 asrc4_mask |= RT5677_DA_MONO3L_CLK_SEL_MASK;
1107 asrc4_value = (asrc4_value & ~RT5677_DA_MONO3L_CLK_SEL_MASK)
1108 | (clk_src << RT5677_DA_MONO3L_CLK_SEL_SFT);
1109 }
1110
1111 if (filter_mask & RT5677_DA_MONO3_R_FILTER) {
1112 asrc4_mask |= RT5677_DA_MONO3R_CLK_SEL_MASK;
1113 asrc4_value = (asrc4_value & ~RT5677_DA_MONO3R_CLK_SEL_MASK)
1114 | (clk_src << RT5677_DA_MONO3R_CLK_SEL_SFT);
1115 }
1116
1117 if (filter_mask & RT5677_DA_MONO4_L_FILTER) {
1118 asrc4_mask |= RT5677_DA_MONO4L_CLK_SEL_MASK;
1119 asrc4_value = (asrc4_value & ~RT5677_DA_MONO4L_CLK_SEL_MASK)
1120 | (clk_src << RT5677_DA_MONO4L_CLK_SEL_SFT);
1121 }
1122
1123 if (filter_mask & RT5677_DA_MONO4_R_FILTER) {
1124 asrc4_mask |= RT5677_DA_MONO4R_CLK_SEL_MASK;
1125 asrc4_value = (asrc4_value & ~RT5677_DA_MONO4R_CLK_SEL_MASK)
1126 | (clk_src << RT5677_DA_MONO4R_CLK_SEL_SFT);
1127 }
1128
1129 if (asrc4_mask)
1130 regmap_update_bits(rt5677->regmap, RT5677_ASRC_4, asrc4_mask,
1131 asrc4_value);
1132
1133 /* ASRC 5 */
1134 if (filter_mask & RT5677_AD_STEREO1_FILTER) {
1135 asrc5_mask |= RT5677_AD_STO1_CLK_SEL_MASK;
1136 asrc5_value = (asrc5_value & ~RT5677_AD_STO1_CLK_SEL_MASK)
1137 | (clk_src << RT5677_AD_STO1_CLK_SEL_SFT);
1138 }
1139
1140 if (filter_mask & RT5677_AD_STEREO2_FILTER) {
1141 asrc5_mask |= RT5677_AD_STO2_CLK_SEL_MASK;
1142 asrc5_value = (asrc5_value & ~RT5677_AD_STO2_CLK_SEL_MASK)
1143 | (clk_src << RT5677_AD_STO2_CLK_SEL_SFT);
1144 }
1145
1146 if (filter_mask & RT5677_AD_STEREO3_FILTER) {
1147 asrc5_mask |= RT5677_AD_STO3_CLK_SEL_MASK;
1148 asrc5_value = (asrc5_value & ~RT5677_AD_STO3_CLK_SEL_MASK)
1149 | (clk_src << RT5677_AD_STO3_CLK_SEL_SFT);
1150 }
1151
1152 if (filter_mask & RT5677_AD_STEREO4_FILTER) {
1153 asrc5_mask |= RT5677_AD_STO4_CLK_SEL_MASK;
1154 asrc5_value = (asrc5_value & ~RT5677_AD_STO4_CLK_SEL_MASK)
1155 | (clk_src << RT5677_AD_STO4_CLK_SEL_SFT);
1156 }
1157
1158 if (asrc5_mask)
1159 regmap_update_bits(rt5677->regmap, RT5677_ASRC_5, asrc5_mask,
1160 asrc5_value);
1161
1162 /* ASRC 6 */
1163 if (filter_mask & RT5677_AD_MONO_L_FILTER) {
1164 asrc6_mask |= RT5677_AD_MONOL_CLK_SEL_MASK;
1165 asrc6_value = (asrc6_value & ~RT5677_AD_MONOL_CLK_SEL_MASK)
1166 | (clk_src << RT5677_AD_MONOL_CLK_SEL_SFT);
1167 }
1168
1169 if (filter_mask & RT5677_AD_MONO_R_FILTER) {
1170 asrc6_mask |= RT5677_AD_MONOR_CLK_SEL_MASK;
1171 asrc6_value = (asrc6_value & ~RT5677_AD_MONOR_CLK_SEL_MASK)
1172 | (clk_src << RT5677_AD_MONOR_CLK_SEL_SFT);
1173 }
1174
1175 if (asrc6_mask)
1176 regmap_update_bits(rt5677->regmap, RT5677_ASRC_6, asrc6_mask,
1177 asrc6_value);
1178
1179 /* ASRC 7 */
1180 if (filter_mask & RT5677_DSP_OB_0_3_FILTER) {
1181 asrc7_mask |= RT5677_DSP_OB_0_3_CLK_SEL_MASK;
1182 asrc7_value = (asrc7_value & ~RT5677_DSP_OB_0_3_CLK_SEL_MASK)
1183 | (clk_src << RT5677_DSP_OB_0_3_CLK_SEL_SFT);
1184 }
1185
1186 if (filter_mask & RT5677_DSP_OB_4_7_FILTER) {
1187 asrc7_mask |= RT5677_DSP_OB_4_7_CLK_SEL_MASK;
1188 asrc7_value = (asrc7_value & ~RT5677_DSP_OB_4_7_CLK_SEL_MASK)
1189 | (clk_src << RT5677_DSP_OB_4_7_CLK_SEL_SFT);
1190 }
1191
1192 if (asrc7_mask)
1193 regmap_update_bits(rt5677->regmap, RT5677_ASRC_7, asrc7_mask,
1194 asrc7_value);
1195
1196 return 0;
1197}
1198EXPORT_SYMBOL_GPL(rt5677_sel_asrc_clk_src);
1199
1024/* Digital Mixer */ 1200/* Digital Mixer */
1025static const struct snd_kcontrol_new rt5677_sto1_adc_l_mix[] = { 1201static const struct snd_kcontrol_new rt5677_sto1_adc_l_mix[] = {
1026 SOC_DAPM_SINGLE("ADC1 Switch", RT5677_STO1_ADC_MIXER, 1202 SOC_DAPM_SINGLE("ADC1 Switch", RT5677_STO1_ADC_MIXER,
@@ -4500,10 +4676,10 @@ static int rt5677_suspend(struct snd_soc_codec *codec)
4500 if (!rt5677->dsp_vad_en) { 4676 if (!rt5677->dsp_vad_en) {
4501 regcache_cache_only(rt5677->regmap, true); 4677 regcache_cache_only(rt5677->regmap, true);
4502 regcache_mark_dirty(rt5677->regmap); 4678 regcache_mark_dirty(rt5677->regmap);
4503 }
4504 4679
4505 if (gpio_is_valid(rt5677->pow_ldo2)) 4680 if (gpio_is_valid(rt5677->pow_ldo2))
4506 gpio_set_value_cansleep(rt5677->pow_ldo2, 0); 4681 gpio_set_value_cansleep(rt5677->pow_ldo2, 0);
4682 }
4507 4683
4508 return 0; 4684 return 0;
4509} 4685}
@@ -4512,12 +4688,12 @@ static int rt5677_resume(struct snd_soc_codec *codec)
4512{ 4688{
4513 struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); 4689 struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
4514 4690
4515 if (gpio_is_valid(rt5677->pow_ldo2)) {
4516 gpio_set_value_cansleep(rt5677->pow_ldo2, 1);
4517 msleep(10);
4518 }
4519
4520 if (!rt5677->dsp_vad_en) { 4691 if (!rt5677->dsp_vad_en) {
4692 if (gpio_is_valid(rt5677->pow_ldo2)) {
4693 gpio_set_value_cansleep(rt5677->pow_ldo2, 1);
4694 msleep(10);
4695 }
4696
4521 regcache_cache_only(rt5677->regmap, false); 4697 regcache_cache_only(rt5677->regmap, false);
4522 regcache_sync(rt5677->regmap); 4698 regcache_sync(rt5677->regmap);
4523 } 4699 }
@@ -4733,7 +4909,8 @@ static const struct regmap_config rt5677_regmap = {
4733}; 4909};
4734 4910
4735static const struct i2c_device_id rt5677_i2c_id[] = { 4911static const struct i2c_device_id rt5677_i2c_id[] = {
4736 { "rt5677", 0 }, 4912 { "rt5677", RT5677 },
4913 { "rt5676", RT5676 },
4737 { } 4914 { }
4738}; 4915};
4739MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); 4916MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id);
@@ -4850,6 +5027,8 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
4850 5027
4851 i2c_set_clientdata(i2c, rt5677); 5028 i2c_set_clientdata(i2c, rt5677);
4852 5029
5030 rt5677->type = id->driver_data;
5031
4853 if (pdata) 5032 if (pdata)
4854 rt5677->pdata = *pdata; 5033 rt5677->pdata = *pdata;
4855 5034
diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h
index c0a625f290cc..9dceb41d18ea 100644
--- a/sound/soc/codecs/rt5677.h
+++ b/sound/soc/codecs/rt5677.h
@@ -1406,6 +1406,46 @@
1406#define RT5677_DSP_CLK_SRC_PLL2 (0x0 << 7) 1406#define RT5677_DSP_CLK_SRC_PLL2 (0x0 << 7)
1407#define RT5677_DSP_CLK_SRC_BYPASS (0x1 << 7) 1407#define RT5677_DSP_CLK_SRC_BYPASS (0x1 << 7)
1408 1408
1409/* ASRC Control 3 (0x85) */
1410#define RT5677_DA_STO_CLK_SEL_MASK (0xf << 12)
1411#define RT5677_DA_STO_CLK_SEL_SFT 12
1412#define RT5677_DA_MONO2L_CLK_SEL_MASK (0xf << 4)
1413#define RT5677_DA_MONO2L_CLK_SEL_SFT 4
1414#define RT5677_DA_MONO2R_CLK_SEL_MASK (0xf << 0)
1415#define RT5677_DA_MONO2R_CLK_SEL_SFT 0
1416
1417/* ASRC Control 4 (0x86) */
1418#define RT5677_DA_MONO3L_CLK_SEL_MASK (0xf << 12)
1419#define RT5677_DA_MONO3L_CLK_SEL_SFT 12
1420#define RT5677_DA_MONO3R_CLK_SEL_MASK (0xf << 8)
1421#define RT5677_DA_MONO3R_CLK_SEL_SFT 8
1422#define RT5677_DA_MONO4L_CLK_SEL_MASK (0xf << 4)
1423#define RT5677_DA_MONO4L_CLK_SEL_SFT 4
1424#define RT5677_DA_MONO4R_CLK_SEL_MASK (0xf << 0)
1425#define RT5677_DA_MONO4R_CLK_SEL_SFT 0
1426
1427/* ASRC Control 5 (0x87) */
1428#define RT5677_AD_STO1_CLK_SEL_MASK (0xf << 12)
1429#define RT5677_AD_STO1_CLK_SEL_SFT 12
1430#define RT5677_AD_STO2_CLK_SEL_MASK (0xf << 8)
1431#define RT5677_AD_STO2_CLK_SEL_SFT 8
1432#define RT5677_AD_STO3_CLK_SEL_MASK (0xf << 4)
1433#define RT5677_AD_STO3_CLK_SEL_SFT 4
1434#define RT5677_AD_STO4_CLK_SEL_MASK (0xf << 0)
1435#define RT5677_AD_STO4_CLK_SEL_SFT 0
1436
1437/* ASRC Control 6 (0x88) */
1438#define RT5677_AD_MONOL_CLK_SEL_MASK (0xf << 12)
1439#define RT5677_AD_MONOL_CLK_SEL_SFT 12
1440#define RT5677_AD_MONOR_CLK_SEL_MASK (0xf << 8)
1441#define RT5677_AD_MONOR_CLK_SEL_SFT 8
1442
1443/* ASRC Control 7 (0x89) */
1444#define RT5677_DSP_OB_0_3_CLK_SEL_MASK (0xf << 12)
1445#define RT5677_DSP_OB_0_3_CLK_SEL_SFT 12
1446#define RT5677_DSP_OB_4_7_CLK_SEL_MASK (0xf << 8)
1447#define RT5677_DSP_OB_4_7_CLK_SEL_SFT 8
1448
1409/* VAD Function Control 4 (0x9f) */ 1449/* VAD Function Control 4 (0x9f) */
1410#define RT5677_VAD_SRC_MASK (0x7 << 8) 1450#define RT5677_VAD_SRC_MASK (0x7 << 8)
1411#define RT5677_VAD_SRC_SFT 8 1451#define RT5677_VAD_SRC_SFT 8
@@ -1665,6 +1705,47 @@ enum {
1665 RT5677_IRQ_JD3, 1705 RT5677_IRQ_JD3,
1666}; 1706};
1667 1707
1708enum rt5677_type {
1709 RT5677,
1710 RT5676,
1711};
1712
1713/* ASRC clock source selection */
1714enum {
1715 RT5677_CLK_SEL_SYS,
1716 RT5677_CLK_SEL_I2S1_ASRC,
1717 RT5677_CLK_SEL_I2S2_ASRC,
1718 RT5677_CLK_SEL_I2S3_ASRC,
1719 RT5677_CLK_SEL_I2S4_ASRC,
1720 RT5677_CLK_SEL_I2S5_ASRC,
1721 RT5677_CLK_SEL_I2S6_ASRC,
1722 RT5677_CLK_SEL_SYS2,
1723 RT5677_CLK_SEL_SYS3,
1724 RT5677_CLK_SEL_SYS4,
1725 RT5677_CLK_SEL_SYS5,
1726 RT5677_CLK_SEL_SYS6,
1727 RT5677_CLK_SEL_SYS7,
1728};
1729
1730/* filter mask */
1731enum {
1732 RT5677_DA_STEREO_FILTER = 0x1,
1733 RT5677_DA_MONO2_L_FILTER = (0x1 << 1),
1734 RT5677_DA_MONO2_R_FILTER = (0x1 << 2),
1735 RT5677_DA_MONO3_L_FILTER = (0x1 << 3),
1736 RT5677_DA_MONO3_R_FILTER = (0x1 << 4),
1737 RT5677_DA_MONO4_L_FILTER = (0x1 << 5),
1738 RT5677_DA_MONO4_R_FILTER = (0x1 << 6),
1739 RT5677_AD_STEREO1_FILTER = (0x1 << 7),
1740 RT5677_AD_STEREO2_FILTER = (0x1 << 8),
1741 RT5677_AD_STEREO3_FILTER = (0x1 << 9),
1742 RT5677_AD_STEREO4_FILTER = (0x1 << 10),
1743 RT5677_AD_MONO_L_FILTER = (0x1 << 11),
1744 RT5677_AD_MONO_R_FILTER = (0x1 << 12),
1745 RT5677_DSP_OB_0_3_FILTER = (0x1 << 13),
1746 RT5677_DSP_OB_4_7_FILTER = (0x1 << 14),
1747};
1748
1668struct rt5677_priv { 1749struct rt5677_priv {
1669 struct snd_soc_codec *codec; 1750 struct snd_soc_codec *codec;
1670 struct rt5677_platform_data pdata; 1751 struct rt5677_platform_data pdata;
@@ -1681,6 +1762,7 @@ struct rt5677_priv {
1681 int pll_in; 1762 int pll_in;
1682 int pll_out; 1763 int pll_out;
1683 int pow_ldo2; /* POW_LDO2 pin */ 1764 int pow_ldo2; /* POW_LDO2 pin */
1765 enum rt5677_type type;
1684#ifdef CONFIG_GPIOLIB 1766#ifdef CONFIG_GPIOLIB
1685 struct gpio_chip gpio_chip; 1767 struct gpio_chip gpio_chip;
1686#endif 1768#endif
@@ -1690,4 +1772,7 @@ struct rt5677_priv {
1690 bool is_vref_slow; 1772 bool is_vref_slow;
1691}; 1773};
1692 1774
1775int rt5677_sel_asrc_clk_src(struct snd_soc_codec *codec,
1776 unsigned int filter_mask, unsigned int clk_src);
1777
1693#endif /* __RT5677_H__ */ 1778#endif /* __RT5677_H__ */
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index 82095d6cd070..7947c0ebb1ed 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -783,19 +783,21 @@ static inline void sn95031_enable_jack_btn(struct snd_soc_codec *codec)
783 snd_soc_write(codec, SN95031_BTNCTRL2, 0x01); 783 snd_soc_write(codec, SN95031_BTNCTRL2, 0x01);
784} 784}
785 785
786static int sn95031_get_headset_state(struct snd_soc_jack *mfld_jack) 786static int sn95031_get_headset_state(struct snd_soc_codec *codec,
787 struct snd_soc_jack *mfld_jack)
787{ 788{
788 int micbias = sn95031_get_mic_bias(mfld_jack->codec); 789 int micbias = sn95031_get_mic_bias(codec);
789 790
790 int jack_type = snd_soc_jack_get_type(mfld_jack, micbias); 791 int jack_type = snd_soc_jack_get_type(mfld_jack, micbias);
791 792
792 pr_debug("jack type detected = %d\n", jack_type); 793 pr_debug("jack type detected = %d\n", jack_type);
793 if (jack_type == SND_JACK_HEADSET) 794 if (jack_type == SND_JACK_HEADSET)
794 sn95031_enable_jack_btn(mfld_jack->codec); 795 sn95031_enable_jack_btn(codec);
795 return jack_type; 796 return jack_type;
796} 797}
797 798
798void sn95031_jack_detection(struct mfld_jack_data *jack_data) 799void sn95031_jack_detection(struct snd_soc_codec *codec,
800 struct mfld_jack_data *jack_data)
799{ 801{
800 unsigned int status; 802 unsigned int status;
801 unsigned int mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_HEADSET; 803 unsigned int mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_HEADSET;
@@ -809,11 +811,11 @@ void sn95031_jack_detection(struct mfld_jack_data *jack_data)
809 status = SND_JACK_HEADSET | SND_JACK_BTN_1; 811 status = SND_JACK_HEADSET | SND_JACK_BTN_1;
810 } else if (jack_data->intr_id & 0x4) { 812 } else if (jack_data->intr_id & 0x4) {
811 pr_debug("headset or headphones inserted\n"); 813 pr_debug("headset or headphones inserted\n");
812 status = sn95031_get_headset_state(jack_data->mfld_jack); 814 status = sn95031_get_headset_state(codec, jack_data->mfld_jack);
813 } else if (jack_data->intr_id & 0x8) { 815 } else if (jack_data->intr_id & 0x8) {
814 pr_debug("headset or headphones removed\n"); 816 pr_debug("headset or headphones removed\n");
815 status = 0; 817 status = 0;
816 sn95031_disable_jack_btn(jack_data->mfld_jack->codec); 818 sn95031_disable_jack_btn(codec);
817 } else { 819 } else {
818 pr_err("unidentified interrupt\n"); 820 pr_err("unidentified interrupt\n");
819 return; 821 return;
diff --git a/sound/soc/codecs/sn95031.h b/sound/soc/codecs/sn95031.h
index 20376d234fb8..7651fe4e6a45 100644
--- a/sound/soc/codecs/sn95031.h
+++ b/sound/soc/codecs/sn95031.h
@@ -127,6 +127,7 @@ struct mfld_jack_data {
127 struct snd_soc_jack *mfld_jack; 127 struct snd_soc_jack *mfld_jack;
128}; 128};
129 129
130extern void sn95031_jack_detection(struct mfld_jack_data *jack_data); 130extern void sn95031_jack_detection(struct snd_soc_codec *codec,
131 struct mfld_jack_data *jack_data);
131 132
132#endif 133#endif
diff --git a/sound/soc/codecs/sta350.c b/sound/soc/codecs/sta350.c
index bda2ee18769e..669e3228241e 100644
--- a/sound/soc/codecs/sta350.c
+++ b/sound/soc/codecs/sta350.c
@@ -1213,27 +1213,15 @@ static int sta350_i2c_probe(struct i2c_client *i2c,
1213#endif 1213#endif
1214 1214
1215 /* GPIOs */ 1215 /* GPIOs */
1216 sta350->gpiod_nreset = devm_gpiod_get(dev, "reset"); 1216 sta350->gpiod_nreset = devm_gpiod_get_optional(dev, "reset",
1217 if (IS_ERR(sta350->gpiod_nreset)) { 1217 GPIOD_OUT_LOW);
1218 ret = PTR_ERR(sta350->gpiod_nreset); 1218 if (IS_ERR(sta350->gpiod_nreset))
1219 if (ret != -ENOENT && ret != -ENOSYS) 1219 return PTR_ERR(sta350->gpiod_nreset);
1220 return ret; 1220
1221 1221 sta350->gpiod_power_down = devm_gpiod_get(dev, "power-down",
1222 sta350->gpiod_nreset = NULL; 1222 GPIOD_OUT_LOW);
1223 } else { 1223 if (IS_ERR(sta350->gpiod_power_down))
1224 gpiod_direction_output(sta350->gpiod_nreset, 0); 1224 return PTR_ERR(sta350->gpiod_power_down);
1225 }
1226
1227 sta350->gpiod_power_down = devm_gpiod_get(dev, "power-down");
1228 if (IS_ERR(sta350->gpiod_power_down)) {
1229 ret = PTR_ERR(sta350->gpiod_power_down);
1230 if (ret != -ENOENT && ret != -ENOSYS)
1231 return ret;
1232
1233 sta350->gpiod_power_down = NULL;
1234 } else {
1235 gpiod_direction_output(sta350->gpiod_power_down, 0);
1236 }
1237 1225
1238 /* regulators */ 1226 /* regulators */
1239 for (i = 0; i < ARRAY_SIZE(sta350->supplies); i++) 1227 for (i = 0; i < ARRAY_SIZE(sta350->supplies); i++)
diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c
index ae23acdd2708..dfb4ff5cc9ea 100644
--- a/sound/soc/codecs/tas2552.c
+++ b/sound/soc/codecs/tas2552.c
@@ -485,16 +485,9 @@ static int tas2552_probe(struct i2c_client *client,
485 if (data == NULL) 485 if (data == NULL)
486 return -ENOMEM; 486 return -ENOMEM;
487 487
488 data->enable_gpio = devm_gpiod_get(dev, "enable"); 488 data->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
489 if (IS_ERR(data->enable_gpio)) { 489 if (IS_ERR(data->enable_gpio))
490 ret = PTR_ERR(data->enable_gpio); 490 return PTR_ERR(data->enable_gpio);
491 if (ret != -ENOENT && ret != -ENOSYS)
492 return ret;
493
494 data->enable_gpio = NULL;
495 } else {
496 gpiod_direction_output(data->enable_gpio, 0);
497 }
498 491
499 data->tas2552_client = client; 492 data->tas2552_client = client;
500 data->regmap = devm_regmap_init_i2c(client, &tas2552_regmap_config); 493 data->regmap = devm_regmap_init_i2c(client, &tas2552_regmap_config);
diff --git a/sound/soc/codecs/tlv320aic23-i2c.c b/sound/soc/codecs/tlv320aic23-i2c.c
index f13701995482..78a94af65518 100644
--- a/sound/soc/codecs/tlv320aic23-i2c.c
+++ b/sound/soc/codecs/tlv320aic23-i2c.c
@@ -31,7 +31,7 @@ static int tlv320aic23_i2c_probe(struct i2c_client *i2c,
31 return tlv320aic23_probe(&i2c->dev, regmap); 31 return tlv320aic23_probe(&i2c->dev, regmap);
32} 32}
33 33
34static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c) 34static int tlv320aic23_i2c_remove(struct i2c_client *i2c)
35{ 35{
36 snd_soc_unregister_codec(&i2c->dev); 36 snd_soc_unregister_codec(&i2c->dev);
37 return 0; 37 return 0;
@@ -56,7 +56,7 @@ static struct i2c_driver tlv320aic23_i2c_driver = {
56 .of_match_table = of_match_ptr(tlv320aic23_of_match), 56 .of_match_table = of_match_ptr(tlv320aic23_of_match),
57 }, 57 },
58 .probe = tlv320aic23_i2c_probe, 58 .probe = tlv320aic23_i2c_probe,
59 .remove = __exit_p(tlv320aic23_i2c_remove), 59 .remove = tlv320aic23_i2c_remove,
60 .id_table = tlv320aic23_id, 60 .id_table = tlv320aic23_id,
61}; 61};
62 62
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
index 15599845a660..5a9da28f4f33 100644
--- a/sound/soc/codecs/wm2200.c
+++ b/sound/soc/codecs/wm2200.c
@@ -1554,7 +1554,6 @@ static int wm2200_probe(struct snd_soc_codec *codec)
1554 int ret; 1554 int ret;
1555 1555
1556 wm2200->codec = codec; 1556 wm2200->codec = codec;
1557 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
1558 1557
1559 ret = snd_soc_add_codec_controls(codec, wm_adsp1_fw_controls, 2); 1558 ret = snd_soc_add_codec_controls(codec, wm_adsp1_fw_controls, 2);
1560 if (ret != 0) 1559 if (ret != 0)
@@ -1942,6 +1941,7 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1942 struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec); 1941 struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
1943 struct _fll_div factors; 1942 struct _fll_div factors;
1944 int ret, i, timeout; 1943 int ret, i, timeout;
1944 unsigned long time_left;
1945 1945
1946 if (!Fout) { 1946 if (!Fout) {
1947 dev_dbg(codec->dev, "FLL disabled"); 1947 dev_dbg(codec->dev, "FLL disabled");
@@ -2021,9 +2021,10 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2021 /* Poll for the lock; will use the interrupt to exit quickly */ 2021 /* Poll for the lock; will use the interrupt to exit quickly */
2022 for (i = 0; i < timeout; i++) { 2022 for (i = 0; i < timeout; i++) {
2023 if (i2c->irq) { 2023 if (i2c->irq) {
2024 ret = wait_for_completion_timeout(&wm2200->fll_lock, 2024 time_left = wait_for_completion_timeout(
2025 msecs_to_jiffies(25)); 2025 &wm2200->fll_lock,
2026 if (ret > 0) 2026 msecs_to_jiffies(25));
2027 if (time_left > 0)
2027 break; 2028 break;
2028 } else { 2029 } else {
2029 msleep(1); 2030 msleep(1);
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index ea09db585aa1..96740379b711 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -1762,6 +1762,7 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1762 struct _fll_div factors; 1762 struct _fll_div factors;
1763 struct wm5100_fll *fll; 1763 struct wm5100_fll *fll;
1764 int ret, base, lock, i, timeout; 1764 int ret, base, lock, i, timeout;
1765 unsigned long time_left;
1765 1766
1766 switch (fll_id) { 1767 switch (fll_id) {
1767 case WM5100_FLL1: 1768 case WM5100_FLL1:
@@ -1842,9 +1843,9 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1842 /* Poll for the lock; will use interrupt when we can test */ 1843 /* Poll for the lock; will use interrupt when we can test */
1843 for (i = 0; i < timeout; i++) { 1844 for (i = 0; i < timeout; i++) {
1844 if (i2c->irq) { 1845 if (i2c->irq) {
1845 ret = wait_for_completion_timeout(&fll->lock, 1846 time_left = wait_for_completion_timeout(&fll->lock,
1846 msecs_to_jiffies(25)); 1847 msecs_to_jiffies(25));
1847 if (ret > 0) 1848 if (time_left > 0)
1848 break; 1849 break;
1849 } else { 1850 } else {
1850 msleep(1); 1851 msleep(1);
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index 6d0fe0ac95a3..0c6d1bc0526e 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -1861,7 +1861,6 @@ static unsigned int wm5102_digital_vu[] = {
1861 ARIZONA_DAC_DIGITAL_VOLUME_2L, 1861 ARIZONA_DAC_DIGITAL_VOLUME_2L,
1862 ARIZONA_DAC_DIGITAL_VOLUME_2R, 1862 ARIZONA_DAC_DIGITAL_VOLUME_2R,
1863 ARIZONA_DAC_DIGITAL_VOLUME_3L, 1863 ARIZONA_DAC_DIGITAL_VOLUME_3L,
1864 ARIZONA_DAC_DIGITAL_VOLUME_3R,
1865 ARIZONA_DAC_DIGITAL_VOLUME_4L, 1864 ARIZONA_DAC_DIGITAL_VOLUME_4L,
1866 ARIZONA_DAC_DIGITAL_VOLUME_4R, 1865 ARIZONA_DAC_DIGITAL_VOLUME_4R,
1867 ARIZONA_DAC_DIGITAL_VOLUME_5L, 1866 ARIZONA_DAC_DIGITAL_VOLUME_5L,
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index c81a9eab3e3e..c65e5a75fc1a 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -69,14 +69,14 @@ struct wm8350_data {
69 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; 69 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
70 int fll_freq_out; 70 int fll_freq_out;
71 int fll_freq_in; 71 int fll_freq_in;
72 struct delayed_work pga_work;
72}; 73};
73 74
74/* 75/*
75 * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown. 76 * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown.
76 */ 77 */
77static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec) 78static inline int wm8350_out1_ramp_step(struct wm8350_data *wm8350_data)
78{ 79{
79 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
80 struct wm8350_output *out1 = &wm8350_data->out1; 80 struct wm8350_output *out1 = &wm8350_data->out1;
81 struct wm8350 *wm8350 = wm8350_data->wm8350; 81 struct wm8350 *wm8350 = wm8350_data->wm8350;
82 int left_complete = 0, right_complete = 0; 82 int left_complete = 0, right_complete = 0;
@@ -140,9 +140,8 @@ static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec)
140/* 140/*
141 * Ramp OUT2 PGA volume to minimise pops at stream startup and shutdown. 141 * Ramp OUT2 PGA volume to minimise pops at stream startup and shutdown.
142 */ 142 */
143static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec) 143static inline int wm8350_out2_ramp_step(struct wm8350_data *wm8350_data)
144{ 144{
145 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
146 struct wm8350_output *out2 = &wm8350_data->out2; 145 struct wm8350_output *out2 = &wm8350_data->out2;
147 struct wm8350 *wm8350 = wm8350_data->wm8350; 146 struct wm8350 *wm8350 = wm8350_data->wm8350;
148 int left_complete = 0, right_complete = 0; 147 int left_complete = 0, right_complete = 0;
@@ -210,10 +209,8 @@ static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec)
210 */ 209 */
211static void wm8350_pga_work(struct work_struct *work) 210static void wm8350_pga_work(struct work_struct *work)
212{ 211{
213 struct snd_soc_dapm_context *dapm = 212 struct wm8350_data *wm8350_data =
214 container_of(work, struct snd_soc_dapm_context, delayed_work.work); 213 container_of(work, struct wm8350_data, pga_work.work);
215 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
216 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
217 struct wm8350_output *out1 = &wm8350_data->out1, 214 struct wm8350_output *out1 = &wm8350_data->out1,
218 *out2 = &wm8350_data->out2; 215 *out2 = &wm8350_data->out2;
219 int i, out1_complete, out2_complete; 216 int i, out1_complete, out2_complete;
@@ -226,9 +223,9 @@ static void wm8350_pga_work(struct work_struct *work)
226 for (i = 0; i <= 63; i++) { 223 for (i = 0; i <= 63; i++) {
227 out1_complete = 1, out2_complete = 1; 224 out1_complete = 1, out2_complete = 1;
228 if (out1->ramp != WM8350_RAMP_NONE) 225 if (out1->ramp != WM8350_RAMP_NONE)
229 out1_complete = wm8350_out1_ramp_step(codec); 226 out1_complete = wm8350_out1_ramp_step(wm8350_data);
230 if (out2->ramp != WM8350_RAMP_NONE) 227 if (out2->ramp != WM8350_RAMP_NONE)
231 out2_complete = wm8350_out2_ramp_step(codec); 228 out2_complete = wm8350_out2_ramp_step(wm8350_data);
232 229
233 /* ramp finished ? */ 230 /* ramp finished ? */
234 if (out1_complete && out2_complete) 231 if (out1_complete && out2_complete)
@@ -283,7 +280,7 @@ static int pga_event(struct snd_soc_dapm_widget *w,
283 out->ramp = WM8350_RAMP_UP; 280 out->ramp = WM8350_RAMP_UP;
284 out->active = 1; 281 out->active = 1;
285 282
286 schedule_delayed_work(&codec->dapm.delayed_work, 283 schedule_delayed_work(&wm8350_data->pga_work,
287 msecs_to_jiffies(1)); 284 msecs_to_jiffies(1));
288 break; 285 break;
289 286
@@ -291,7 +288,7 @@ static int pga_event(struct snd_soc_dapm_widget *w,
291 out->ramp = WM8350_RAMP_DOWN; 288 out->ramp = WM8350_RAMP_DOWN;
292 out->active = 0; 289 out->active = 0;
293 290
294 schedule_delayed_work(&codec->dapm.delayed_work, 291 schedule_delayed_work(&wm8350_data->pga_work,
295 msecs_to_jiffies(1)); 292 msecs_to_jiffies(1));
296 break; 293 break;
297 } 294 }
@@ -1492,7 +1489,7 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec)
1492 /* Put the codec into reset if it wasn't already */ 1489 /* Put the codec into reset if it wasn't already */
1493 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1490 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1494 1491
1495 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8350_pga_work); 1492 INIT_DELAYED_WORK(&priv->pga_work, wm8350_pga_work);
1496 INIT_DELAYED_WORK(&priv->hpl.work, wm8350_hpl_work); 1493 INIT_DELAYED_WORK(&priv->hpl.work, wm8350_hpl_work);
1497 INIT_DELAYED_WORK(&priv->hpr.work, wm8350_hpr_work); 1494 INIT_DELAYED_WORK(&priv->hpr.work, wm8350_hpr_work);
1498 1495
@@ -1578,7 +1575,7 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec)
1578 1575
1579 /* if there was any work waiting then we run it now and 1576 /* if there was any work waiting then we run it now and
1580 * wait for its completion */ 1577 * wait for its completion */
1581 flush_delayed_work(&codec->dapm.delayed_work); 1578 flush_delayed_work(&priv->pga_work);
1582 1579
1583 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1580 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1584 1581
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index c6d10533e2bd..2245b6a32f3d 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -25,6 +25,7 @@
25#include <linux/spi/spi.h> 25#include <linux/spi/spi.h>
26#include <linux/of_device.h> 26#include <linux/of_device.h>
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <linux/clk.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include <sound/pcm.h> 30#include <sound/pcm.h>
30#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
@@ -45,6 +46,7 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
45/* codec private data */ 46/* codec private data */
46struct wm8731_priv { 47struct wm8731_priv {
47 struct regmap *regmap; 48 struct regmap *regmap;
49 struct clk *mclk;
48 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; 50 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
49 const struct snd_pcm_hw_constraint_list *constraints; 51 const struct snd_pcm_hw_constraint_list *constraints;
50 unsigned int sysclk; 52 unsigned int sysclk;
@@ -390,6 +392,8 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
390 switch (clk_id) { 392 switch (clk_id) {
391 case WM8731_SYSCLK_XTAL: 393 case WM8731_SYSCLK_XTAL:
392 case WM8731_SYSCLK_MCLK: 394 case WM8731_SYSCLK_MCLK:
395 if (wm8731->mclk && clk_set_rate(wm8731->mclk, freq))
396 return -EINVAL;
393 wm8731->sysclk_type = clk_id; 397 wm8731->sysclk_type = clk_id;
394 break; 398 break;
395 default: 399 default:
@@ -491,6 +495,8 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
491 495
492 switch (level) { 496 switch (level) {
493 case SND_SOC_BIAS_ON: 497 case SND_SOC_BIAS_ON:
498 if (wm8731->mclk)
499 clk_prepare_enable(wm8731->mclk);
494 break; 500 break;
495 case SND_SOC_BIAS_PREPARE: 501 case SND_SOC_BIAS_PREPARE:
496 break; 502 break;
@@ -509,6 +515,8 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
509 snd_soc_write(codec, WM8731_PWR, reg | 0x0040); 515 snd_soc_write(codec, WM8731_PWR, reg | 0x0040);
510 break; 516 break;
511 case SND_SOC_BIAS_OFF: 517 case SND_SOC_BIAS_OFF:
518 if (wm8731->mclk)
519 clk_disable_unprepare(wm8731->mclk);
512 snd_soc_write(codec, WM8731_PWR, 0xffff); 520 snd_soc_write(codec, WM8731_PWR, 0xffff);
513 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), 521 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
514 wm8731->supplies); 522 wm8731->supplies);
@@ -667,6 +675,19 @@ static int wm8731_spi_probe(struct spi_device *spi)
667 if (wm8731 == NULL) 675 if (wm8731 == NULL)
668 return -ENOMEM; 676 return -ENOMEM;
669 677
678 wm8731->mclk = devm_clk_get(&spi->dev, "mclk");
679 if (IS_ERR(wm8731->mclk)) {
680 ret = PTR_ERR(wm8731->mclk);
681 if (ret == -ENOENT) {
682 wm8731->mclk = NULL;
683 dev_warn(&spi->dev, "Assuming static MCLK\n");
684 } else {
685 dev_err(&spi->dev, "Failed to get MCLK: %d\n",
686 ret);
687 return ret;
688 }
689 }
690
670 mutex_init(&wm8731->lock); 691 mutex_init(&wm8731->lock);
671 692
672 wm8731->regmap = devm_regmap_init_spi(spi, &wm8731_regmap); 693 wm8731->regmap = devm_regmap_init_spi(spi, &wm8731_regmap);
@@ -718,6 +739,19 @@ static int wm8731_i2c_probe(struct i2c_client *i2c,
718 if (wm8731 == NULL) 739 if (wm8731 == NULL)
719 return -ENOMEM; 740 return -ENOMEM;
720 741
742 wm8731->mclk = devm_clk_get(&i2c->dev, "mclk");
743 if (IS_ERR(wm8731->mclk)) {
744 ret = PTR_ERR(wm8731->mclk);
745 if (ret == -ENOENT) {
746 wm8731->mclk = NULL;
747 dev_warn(&i2c->dev, "Assuming static MCLK\n");
748 } else {
749 dev_err(&i2c->dev, "Failed to get MCLK: %d\n",
750 ret);
751 return ret;
752 }
753 }
754
721 mutex_init(&wm8731->lock); 755 mutex_init(&wm8731->lock);
722 756
723 wm8731->regmap = devm_regmap_init_i2c(i2c, &wm8731_regmap); 757 wm8731->regmap = devm_regmap_init_i2c(i2c, &wm8731_regmap);
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 31bb4801a005..9e71c768966f 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -123,7 +123,7 @@ static struct {
123}; 123};
124 124
125static const unsigned int rates_11289[] = { 125static const unsigned int rates_11289[] = {
126 44100, 88235, 126 44100, 88200,
127}; 127};
128 128
129static const struct snd_pcm_hw_constraint_list constraints_11289 = { 129static const struct snd_pcm_hw_constraint_list constraints_11289 = {
@@ -150,7 +150,7 @@ static const struct snd_pcm_hw_constraint_list constraints_16384 = {
150}; 150};
151 151
152static const unsigned int rates_16934[] = { 152static const unsigned int rates_16934[] = {
153 44100, 88235, 153 44100, 88200,
154}; 154};
155 155
156static const struct snd_pcm_hw_constraint_list constraints_16934 = { 156static const struct snd_pcm_hw_constraint_list constraints_16934 = {
@@ -168,7 +168,7 @@ static const struct snd_pcm_hw_constraint_list constraints_18432 = {
168}; 168};
169 169
170static const unsigned int rates_22579[] = { 170static const unsigned int rates_22579[] = {
171 44100, 88235, 1764000 171 44100, 88200, 176400
172}; 172};
173 173
174static const struct snd_pcm_hw_constraint_list constraints_22579 = { 174static const struct snd_pcm_hw_constraint_list constraints_22579 = {
@@ -186,7 +186,7 @@ static const struct snd_pcm_hw_constraint_list constraints_24576 = {
186}; 186};
187 187
188static const unsigned int rates_36864[] = { 188static const unsigned int rates_36864[] = {
189 48000, 96000, 19200 189 48000, 96000, 192000
190}; 190};
191 191
192static const struct snd_pcm_hw_constraint_list constraints_36864 = { 192static const struct snd_pcm_hw_constraint_list constraints_36864 = {
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 21ca3a94fc96..c50a5959345f 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -153,6 +153,7 @@ struct wm8753_priv {
153 unsigned int hifi_fmt; 153 unsigned int hifi_fmt;
154 154
155 int dai_func; 155 int dai_func;
156 struct delayed_work charge_work;
156}; 157};
157 158
158#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0) 159#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
@@ -1326,9 +1327,19 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
1326 return 0; 1327 return 0;
1327} 1328}
1328 1329
1330static void wm8753_charge_work(struct work_struct *work)
1331{
1332 struct wm8753_priv *wm8753 =
1333 container_of(work, struct wm8753_priv, charge_work.work);
1334
1335 /* Set to 500k */
1336 regmap_update_bits(wm8753->regmap, WM8753_PWR1, 0x0180, 0x0100);
1337}
1338
1329static int wm8753_set_bias_level(struct snd_soc_codec *codec, 1339static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1330 enum snd_soc_bias_level level) 1340 enum snd_soc_bias_level level)
1331{ 1341{
1342 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1332 u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e; 1343 u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e;
1333 1344
1334 switch (level) { 1345 switch (level) {
@@ -1337,14 +1348,22 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1337 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0); 1348 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
1338 break; 1349 break;
1339 case SND_SOC_BIAS_PREPARE: 1350 case SND_SOC_BIAS_PREPARE:
1340 /* set vmid to 5k for quick power up */ 1351 /* Wait until fully charged */
1341 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1); 1352 flush_delayed_work(&wm8753->charge_work);
1342 break; 1353 break;
1343 case SND_SOC_BIAS_STANDBY: 1354 case SND_SOC_BIAS_STANDBY:
1344 /* mute dac and set vmid to 500k, enable VREF */ 1355 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1345 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141); 1356 /* set vmid to 5k for quick power up */
1357 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
1358 schedule_delayed_work(&wm8753->charge_work,
1359 msecs_to_jiffies(caps_charge));
1360 } else {
1361 /* mute dac and set vmid to 500k, enable VREF */
1362 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
1363 }
1346 break; 1364 break;
1347 case SND_SOC_BIAS_OFF: 1365 case SND_SOC_BIAS_OFF:
1366 cancel_delayed_work_sync(&wm8753->charge_work);
1348 snd_soc_write(codec, WM8753_PWR1, 0x0001); 1367 snd_soc_write(codec, WM8753_PWR1, 0x0001);
1349 break; 1368 break;
1350 } 1369 }
@@ -1428,38 +1447,12 @@ static struct snd_soc_dai_driver wm8753_dai[] = {
1428}, 1447},
1429}; 1448};
1430 1449
1431static void wm8753_work(struct work_struct *work)
1432{
1433 struct snd_soc_dapm_context *dapm =
1434 container_of(work, struct snd_soc_dapm_context,
1435 delayed_work.work);
1436 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
1437 wm8753_set_bias_level(codec, dapm->bias_level);
1438}
1439
1440static int wm8753_suspend(struct snd_soc_codec *codec)
1441{
1442 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1443 return 0;
1444}
1445
1446static int wm8753_resume(struct snd_soc_codec *codec) 1450static int wm8753_resume(struct snd_soc_codec *codec)
1447{ 1451{
1448 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 1452 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1449 1453
1450 regcache_sync(wm8753->regmap); 1454 regcache_sync(wm8753->regmap);
1451 1455
1452 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1453
1454 /* charge wm8753 caps */
1455 if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
1456 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1457 codec->dapm.bias_level = SND_SOC_BIAS_ON;
1458 queue_delayed_work(system_power_efficient_wq,
1459 &codec->dapm.delayed_work,
1460 msecs_to_jiffies(caps_charge));
1461 }
1462
1463 return 0; 1456 return 0;
1464} 1457}
1465 1458
@@ -1468,7 +1461,7 @@ static int wm8753_probe(struct snd_soc_codec *codec)
1468 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 1461 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1469 int ret; 1462 int ret;
1470 1463
1471 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work); 1464 INIT_DELAYED_WORK(&wm8753->charge_work, wm8753_charge_work);
1472 1465
1473 ret = wm8753_reset(codec); 1466 ret = wm8753_reset(codec);
1474 if (ret < 0) { 1467 if (ret < 0) {
@@ -1476,14 +1469,8 @@ static int wm8753_probe(struct snd_soc_codec *codec)
1476 return ret; 1469 return ret;
1477 } 1470 }
1478 1471
1479 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1480 wm8753->dai_func = 0; 1472 wm8753->dai_func = 0;
1481 1473
1482 /* charge output caps */
1483 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1484 schedule_delayed_work(&codec->dapm.delayed_work,
1485 msecs_to_jiffies(caps_charge));
1486
1487 /* set the update bits */ 1474 /* set the update bits */
1488 snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100); 1475 snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
1489 snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100); 1476 snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
@@ -1499,21 +1486,11 @@ static int wm8753_probe(struct snd_soc_codec *codec)
1499 return 0; 1486 return 0;
1500} 1487}
1501 1488
1502/* power down chip */
1503static int wm8753_remove(struct snd_soc_codec *codec)
1504{
1505 flush_delayed_work(&codec->dapm.delayed_work);
1506 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1507
1508 return 0;
1509}
1510
1511static struct snd_soc_codec_driver soc_codec_dev_wm8753 = { 1489static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
1512 .probe = wm8753_probe, 1490 .probe = wm8753_probe,
1513 .remove = wm8753_remove,
1514 .suspend = wm8753_suspend,
1515 .resume = wm8753_resume, 1491 .resume = wm8753_resume,
1516 .set_bias_level = wm8753_set_bias_level, 1492 .set_bias_level = wm8753_set_bias_level,
1493 .suspend_bias_off = true,
1517 1494
1518 .controls = wm8753_snd_controls, 1495 .controls = wm8753_snd_controls,
1519 .num_controls = ARRAY_SIZE(wm8753_snd_controls), 1496 .num_controls = ARRAY_SIZE(wm8753_snd_controls),
diff --git a/sound/soc/codecs/wm8804-i2c.c b/sound/soc/codecs/wm8804-i2c.c
new file mode 100644
index 000000000000..6596f5f3a0c3
--- /dev/null
+++ b/sound/soc/codecs/wm8804-i2c.c
@@ -0,0 +1,65 @@
1/*
2 * wm8804-i2c.c -- WM8804 S/PDIF transceiver driver - I2C
3 *
4 * Copyright 2015 Cirrus Logic Inc
5 *
6 * Author: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/i2c.h>
16
17#include "wm8804.h"
18
19static int wm8804_i2c_probe(struct i2c_client *i2c,
20 const struct i2c_device_id *id)
21{
22 struct regmap *regmap;
23
24 regmap = devm_regmap_init_i2c(i2c, &wm8804_regmap_config);
25 if (IS_ERR(regmap))
26 return PTR_ERR(regmap);
27
28 return wm8804_probe(&i2c->dev, regmap);
29}
30
31static int wm8804_i2c_remove(struct i2c_client *i2c)
32{
33 wm8804_remove(&i2c->dev);
34 return 0;
35}
36
37static const struct i2c_device_id wm8804_i2c_id[] = {
38 { "wm8804", 0 },
39 { }
40};
41MODULE_DEVICE_TABLE(i2c, wm8804_i2c_id);
42
43static const struct of_device_id wm8804_of_match[] = {
44 { .compatible = "wlf,wm8804", },
45 { }
46};
47MODULE_DEVICE_TABLE(of, wm8804_of_match);
48
49static struct i2c_driver wm8804_i2c_driver = {
50 .driver = {
51 .name = "wm8804",
52 .owner = THIS_MODULE,
53 .pm = &wm8804_pm,
54 .of_match_table = wm8804_of_match,
55 },
56 .probe = wm8804_i2c_probe,
57 .remove = wm8804_i2c_remove,
58 .id_table = wm8804_i2c_id
59};
60
61module_i2c_driver(wm8804_i2c_driver);
62
63MODULE_DESCRIPTION("ASoC WM8804 driver - I2C");
64MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.wolfsonmicro.com>");
65MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8804-spi.c b/sound/soc/codecs/wm8804-spi.c
new file mode 100644
index 000000000000..407a3cf391e5
--- /dev/null
+++ b/sound/soc/codecs/wm8804-spi.c
@@ -0,0 +1,57 @@
1/*
2 * wm8804-spi.c -- WM8804 S/PDIF transceiver driver - SPI
3 *
4 * Copyright 2015 Cirrus Logic Inc
5 *
6 * Author: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/spi/spi.h>
16
17#include "wm8804.h"
18
19static int wm8804_spi_probe(struct spi_device *spi)
20{
21 struct regmap *regmap;
22
23 regmap = devm_regmap_init_spi(spi, &wm8804_regmap_config);
24 if (IS_ERR(regmap))
25 return PTR_ERR(regmap);
26
27 return wm8804_probe(&spi->dev, regmap);
28}
29
30static int wm8804_spi_remove(struct spi_device *spi)
31{
32 wm8804_remove(&spi->dev);
33 return 0;
34}
35
36static const struct of_device_id wm8804_of_match[] = {
37 { .compatible = "wlf,wm8804", },
38 { }
39};
40MODULE_DEVICE_TABLE(of, wm8804_of_match);
41
42static struct spi_driver wm8804_spi_driver = {
43 .driver = {
44 .name = "wm8804",
45 .owner = THIS_MODULE,
46 .pm = &wm8804_pm,
47 .of_match_table = wm8804_of_match,
48 },
49 .probe = wm8804_spi_probe,
50 .remove = wm8804_spi_remove
51};
52
53module_spi_driver(wm8804_spi_driver);
54
55MODULE_DESCRIPTION("ASoC WM8804 driver - SPI");
56MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.wolfsonmicro.com>");
57MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index b2b0e68f707e..1e403f67cf16 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -13,12 +13,11 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/moduleparam.h> 14#include <linux/moduleparam.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/gpio/consumer.h>
16#include <linux/delay.h> 17#include <linux/delay.h>
17#include <linux/pm.h> 18#include <linux/pm.h>
18#include <linux/i2c.h> 19#include <linux/pm_runtime.h>
19#include <linux/of_device.h> 20#include <linux/of_device.h>
20#include <linux/spi/spi.h>
21#include <linux/regmap.h>
22#include <linux/regulator/consumer.h> 21#include <linux/regulator/consumer.h>
23#include <linux/slab.h> 22#include <linux/slab.h>
24#include <sound/core.h> 23#include <sound/core.h>
@@ -27,6 +26,7 @@
27#include <sound/soc.h> 26#include <sound/soc.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29#include <sound/tlv.h> 28#include <sound/tlv.h>
29#include <sound/soc-dapm.h>
30 30
31#include "wm8804.h" 31#include "wm8804.h"
32 32
@@ -60,18 +60,23 @@ static const struct reg_default wm8804_reg_defaults[] = {
60}; 60};
61 61
62struct wm8804_priv { 62struct wm8804_priv {
63 struct device *dev;
63 struct regmap *regmap; 64 struct regmap *regmap;
64 struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES]; 65 struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES];
65 struct notifier_block disable_nb[WM8804_NUM_SUPPLIES]; 66 struct notifier_block disable_nb[WM8804_NUM_SUPPLIES];
66 int mclk_div; 67 int mclk_div;
67};
68 68
69static int txsrc_get(struct snd_kcontrol *kcontrol, 69 struct gpio_desc *reset;
70 struct snd_ctl_elem_value *ucontrol); 70
71 int aif_pwr;
72};
71 73
72static int txsrc_put(struct snd_kcontrol *kcontrol, 74static int txsrc_put(struct snd_kcontrol *kcontrol,
73 struct snd_ctl_elem_value *ucontrol); 75 struct snd_ctl_elem_value *ucontrol);
74 76
77static int wm8804_aif_event(struct snd_soc_dapm_widget *w,
78 struct snd_kcontrol *kcontrol, int event);
79
75/* 80/*
76 * We can't use the same notifier block for more than one supply and 81 * We can't use the same notifier block for more than one supply and
77 * there's no way I can see to get from a callback to the caller 82 * there's no way I can see to get from a callback to the caller
@@ -93,26 +98,62 @@ WM8804_REGULATOR_EVENT(0)
93WM8804_REGULATOR_EVENT(1) 98WM8804_REGULATOR_EVENT(1)
94 99
95static const char *txsrc_text[] = { "S/PDIF RX", "AIF" }; 100static const char *txsrc_text[] = { "S/PDIF RX", "AIF" };
96static SOC_ENUM_SINGLE_EXT_DECL(txsrc, txsrc_text); 101static const SOC_ENUM_SINGLE_DECL(txsrc, WM8804_SPDTX4, 6, txsrc_text);
97 102
98static const struct snd_kcontrol_new wm8804_snd_controls[] = { 103static const struct snd_kcontrol_new wm8804_tx_source_mux[] = {
99 SOC_ENUM_EXT("Input Source", txsrc, txsrc_get, txsrc_put), 104 SOC_DAPM_ENUM_EXT("Input Source", txsrc,
100 SOC_SINGLE("TX Playback Switch", WM8804_PWRDN, 2, 1, 1), 105 snd_soc_dapm_get_enum_double, txsrc_put),
101 SOC_SINGLE("AIF Playback Switch", WM8804_PWRDN, 4, 1, 1)
102}; 106};
103 107
104static int txsrc_get(struct snd_kcontrol *kcontrol, 108static const struct snd_soc_dapm_widget wm8804_dapm_widgets[] = {
105 struct snd_ctl_elem_value *ucontrol) 109SND_SOC_DAPM_OUTPUT("SPDIF Out"),
106{ 110SND_SOC_DAPM_INPUT("SPDIF In"),
107 struct snd_soc_codec *codec; 111
108 unsigned int src; 112SND_SOC_DAPM_PGA("SPDIFTX", WM8804_PWRDN, 2, 1, NULL, 0),
113SND_SOC_DAPM_PGA("SPDIFRX", WM8804_PWRDN, 1, 1, NULL, 0),
114
115SND_SOC_DAPM_MUX("Tx Source", SND_SOC_NOPM, 6, 0, wm8804_tx_source_mux),
116
117SND_SOC_DAPM_AIF_OUT_E("AIFTX", NULL, 0, SND_SOC_NOPM, 0, 0, wm8804_aif_event,
118 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
119SND_SOC_DAPM_AIF_IN_E("AIFRX", NULL, 0, SND_SOC_NOPM, 0, 0, wm8804_aif_event,
120 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
121};
122
123static const struct snd_soc_dapm_route wm8804_dapm_routes[] = {
124 { "AIFRX", NULL, "Playback" },
125 { "Tx Source", "AIF", "AIFRX" },
109 126
110 codec = snd_soc_kcontrol_codec(kcontrol); 127 { "SPDIFRX", NULL, "SPDIF In" },
111 src = snd_soc_read(codec, WM8804_SPDTX4); 128 { "Tx Source", "S/PDIF RX", "SPDIFRX" },
112 if (src & 0x40) 129
113 ucontrol->value.integer.value[0] = 1; 130 { "SPDIFTX", NULL, "Tx Source" },
114 else 131 { "SPDIF Out", NULL, "SPDIFTX" },
115 ucontrol->value.integer.value[0] = 0; 132
133 { "AIFTX", NULL, "SPDIFRX" },
134 { "Capture", NULL, "AIFTX" },
135};
136
137static int wm8804_aif_event(struct snd_soc_dapm_widget *w,
138 struct snd_kcontrol *kcontrol, int event)
139{
140 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
141 struct wm8804_priv *wm8804 = snd_soc_codec_get_drvdata(codec);
142
143 switch (event) {
144 case SND_SOC_DAPM_POST_PMU:
145 /* power up the aif */
146 if (!wm8804->aif_pwr)
147 snd_soc_update_bits(codec, WM8804_PWRDN, 0x10, 0x0);
148 wm8804->aif_pwr++;
149 break;
150 case SND_SOC_DAPM_POST_PMD:
151 /* power down only both paths are disabled */
152 wm8804->aif_pwr--;
153 if (!wm8804->aif_pwr)
154 snd_soc_update_bits(codec, WM8804_PWRDN, 0x10, 0x10);
155 break;
156 }
116 157
117 return 0; 158 return 0;
118} 159}
@@ -120,48 +161,33 @@ static int txsrc_get(struct snd_kcontrol *kcontrol,
120static int txsrc_put(struct snd_kcontrol *kcontrol, 161static int txsrc_put(struct snd_kcontrol *kcontrol,
121 struct snd_ctl_elem_value *ucontrol) 162 struct snd_ctl_elem_value *ucontrol)
122{ 163{
123 struct snd_soc_codec *codec; 164 struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
124 unsigned int src, txpwr; 165 struct snd_soc_dapm_context *dapm = &codec->dapm;
166 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
167 unsigned int val = ucontrol->value.enumerated.item[0] << e->shift_l;
168 unsigned int mask = 1 << e->shift_l;
169 unsigned int txpwr;
170
171 if (val != 0 && val != mask)
172 return -EINVAL;
125 173
126 codec = snd_soc_kcontrol_codec(kcontrol); 174 snd_soc_dapm_mutex_lock(dapm);
127 175
128 if (ucontrol->value.integer.value[0] != 0 176 if (snd_soc_test_bits(codec, e->reg, mask, val)) {
129 && ucontrol->value.integer.value[0] != 1) 177 /* save the current power state of the transmitter */
130 return -EINVAL; 178 txpwr = snd_soc_read(codec, WM8804_PWRDN) & 0x4;
131 179
132 src = snd_soc_read(codec, WM8804_SPDTX4); 180 /* power down the transmitter */
133 switch ((src & 0x40) >> 6) { 181 snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x4);
134 case 0:
135 if (!ucontrol->value.integer.value[0])
136 return 0;
137 break;
138 case 1:
139 if (ucontrol->value.integer.value[1])
140 return 0;
141 break;
142 }
143 182
144 /* save the current power state of the transmitter */ 183 /* set the tx source */
145 txpwr = snd_soc_read(codec, WM8804_PWRDN) & 0x4; 184 snd_soc_update_bits(codec, e->reg, mask, val);
146 /* power down the transmitter */ 185
147 snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x4); 186 /* restore the transmitter's configuration */
148 /* set the tx source */ 187 snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, txpwr);
149 snd_soc_update_bits(codec, WM8804_SPDTX4, 0x40,
150 ucontrol->value.integer.value[0] << 6);
151
152 if (ucontrol->value.integer.value[0]) {
153 /* power down the receiver */
154 snd_soc_update_bits(codec, WM8804_PWRDN, 0x2, 0x2);
155 /* power up the AIF */
156 snd_soc_update_bits(codec, WM8804_PWRDN, 0x10, 0);
157 } else {
158 /* don't power down the AIF -- may be used as an output */
159 /* power up the receiver */
160 snd_soc_update_bits(codec, WM8804_PWRDN, 0x2, 0);
161 } 188 }
162 189
163 /* restore the transmitter's configuration */ 190 snd_soc_dapm_mutex_unlock(dapm);
164 snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, txpwr);
165 191
166 return 0; 192 return 0;
167} 193}
@@ -185,9 +211,9 @@ static bool wm8804_volatile(struct device *dev, unsigned int reg)
185 } 211 }
186} 212}
187 213
188static int wm8804_reset(struct snd_soc_codec *codec) 214static int wm8804_soft_reset(struct wm8804_priv *wm8804)
189{ 215{
190 return snd_soc_write(codec, WM8804_RST_DEVID1, 0x0); 216 return regmap_write(wm8804->regmap, WM8804_RST_DEVID1, 0x0);
191} 217}
192 218
193static int wm8804_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 219static int wm8804_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
@@ -379,19 +405,19 @@ static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id,
379 int source, unsigned int freq_in, 405 int source, unsigned int freq_in,
380 unsigned int freq_out) 406 unsigned int freq_out)
381{ 407{
382 struct snd_soc_codec *codec; 408 struct snd_soc_codec *codec = dai->codec;
409 struct wm8804_priv *wm8804 = snd_soc_codec_get_drvdata(codec);
410 bool change;
383 411
384 codec = dai->codec;
385 if (!freq_in || !freq_out) { 412 if (!freq_in || !freq_out) {
386 /* disable the PLL */ 413 /* disable the PLL */
387 snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0x1); 414 regmap_update_bits_check(wm8804->regmap, WM8804_PWRDN,
388 return 0; 415 0x1, 0x1, &change);
416 if (change)
417 pm_runtime_put(wm8804->dev);
389 } else { 418 } else {
390 int ret; 419 int ret;
391 struct pll_div pll_div; 420 struct pll_div pll_div;
392 struct wm8804_priv *wm8804;
393
394 wm8804 = snd_soc_codec_get_drvdata(codec);
395 421
396 ret = pll_factors(&pll_div, freq_out, freq_in, 422 ret = pll_factors(&pll_div, freq_out, freq_in,
397 wm8804->mclk_div); 423 wm8804->mclk_div);
@@ -399,7 +425,10 @@ static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id,
399 return ret; 425 return ret;
400 426
401 /* power down the PLL before reprogramming it */ 427 /* power down the PLL before reprogramming it */
402 snd_soc_update_bits(codec, WM8804_PWRDN, 0x1, 0x1); 428 regmap_update_bits_check(wm8804->regmap, WM8804_PWRDN,
429 0x1, 0x1, &change);
430 if (!change)
431 pm_runtime_get_sync(wm8804->dev);
403 432
404 /* set PLLN and PRESCALE */ 433 /* set PLLN and PRESCALE */
405 snd_soc_update_bits(codec, WM8804_PLL4, 0xf | 0x10, 434 snd_soc_update_bits(codec, WM8804_PLL4, 0xf | 0x10,
@@ -477,141 +506,6 @@ static int wm8804_set_clkdiv(struct snd_soc_dai *dai,
477 return 0; 506 return 0;
478} 507}
479 508
480static int wm8804_set_bias_level(struct snd_soc_codec *codec,
481 enum snd_soc_bias_level level)
482{
483 int ret;
484 struct wm8804_priv *wm8804;
485
486 wm8804 = snd_soc_codec_get_drvdata(codec);
487 switch (level) {
488 case SND_SOC_BIAS_ON:
489 break;
490 case SND_SOC_BIAS_PREPARE:
491 /* power up the OSC and the PLL */
492 snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0);
493 break;
494 case SND_SOC_BIAS_STANDBY:
495 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
496 ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies),
497 wm8804->supplies);
498 if (ret) {
499 dev_err(codec->dev,
500 "Failed to enable supplies: %d\n",
501 ret);
502 return ret;
503 }
504 regcache_sync(wm8804->regmap);
505 }
506 /* power down the OSC and the PLL */
507 snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0x9);
508 break;
509 case SND_SOC_BIAS_OFF:
510 /* power down the OSC and the PLL */
511 snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0x9);
512 regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies),
513 wm8804->supplies);
514 break;
515 }
516
517 codec->dapm.bias_level = level;
518 return 0;
519}
520
521static int wm8804_remove(struct snd_soc_codec *codec)
522{
523 struct wm8804_priv *wm8804;
524 int i;
525
526 wm8804 = snd_soc_codec_get_drvdata(codec);
527
528 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); ++i)
529 regulator_unregister_notifier(wm8804->supplies[i].consumer,
530 &wm8804->disable_nb[i]);
531 return 0;
532}
533
534static int wm8804_probe(struct snd_soc_codec *codec)
535{
536 struct wm8804_priv *wm8804;
537 int i, id1, id2, ret;
538
539 wm8804 = snd_soc_codec_get_drvdata(codec);
540
541 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++)
542 wm8804->supplies[i].supply = wm8804_supply_names[i];
543
544 ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8804->supplies),
545 wm8804->supplies);
546 if (ret) {
547 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
548 return ret;
549 }
550
551 wm8804->disable_nb[0].notifier_call = wm8804_regulator_event_0;
552 wm8804->disable_nb[1].notifier_call = wm8804_regulator_event_1;
553
554 /* This should really be moved into the regulator core */
555 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) {
556 ret = regulator_register_notifier(wm8804->supplies[i].consumer,
557 &wm8804->disable_nb[i]);
558 if (ret != 0) {
559 dev_err(codec->dev,
560 "Failed to register regulator notifier: %d\n",
561 ret);
562 }
563 }
564
565 ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies),
566 wm8804->supplies);
567 if (ret) {
568 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
569 return ret;
570 }
571
572 id1 = snd_soc_read(codec, WM8804_RST_DEVID1);
573 if (id1 < 0) {
574 dev_err(codec->dev, "Failed to read device ID: %d\n", id1);
575 ret = id1;
576 goto err_reg_enable;
577 }
578
579 id2 = snd_soc_read(codec, WM8804_DEVID2);
580 if (id2 < 0) {
581 dev_err(codec->dev, "Failed to read device ID: %d\n", id2);
582 ret = id2;
583 goto err_reg_enable;
584 }
585
586 id2 = (id2 << 8) | id1;
587
588 if (id2 != 0x8805) {
589 dev_err(codec->dev, "Invalid device ID: %#x\n", id2);
590 ret = -EINVAL;
591 goto err_reg_enable;
592 }
593
594 ret = snd_soc_read(codec, WM8804_DEVREV);
595 if (ret < 0) {
596 dev_err(codec->dev, "Failed to read device revision: %d\n",
597 ret);
598 goto err_reg_enable;
599 }
600 dev_info(codec->dev, "revision %c\n", ret + 'A');
601
602 ret = wm8804_reset(codec);
603 if (ret < 0) {
604 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
605 goto err_reg_enable;
606 }
607
608 return 0;
609
610err_reg_enable:
611 regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies);
612 return ret;
613}
614
615static const struct snd_soc_dai_ops wm8804_dai_ops = { 509static const struct snd_soc_dai_ops wm8804_dai_ops = {
616 .hw_params = wm8804_hw_params, 510 .hw_params = wm8804_hw_params,
617 .set_fmt = wm8804_set_fmt, 511 .set_fmt = wm8804_set_fmt,
@@ -649,22 +543,15 @@ static struct snd_soc_dai_driver wm8804_dai = {
649}; 543};
650 544
651static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = { 545static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
652 .probe = wm8804_probe,
653 .remove = wm8804_remove,
654 .set_bias_level = wm8804_set_bias_level,
655 .idle_bias_off = true, 546 .idle_bias_off = true,
656 547
657 .controls = wm8804_snd_controls, 548 .dapm_widgets = wm8804_dapm_widgets,
658 .num_controls = ARRAY_SIZE(wm8804_snd_controls), 549 .num_dapm_widgets = ARRAY_SIZE(wm8804_dapm_widgets),
659}; 550 .dapm_routes = wm8804_dapm_routes,
660 551 .num_dapm_routes = ARRAY_SIZE(wm8804_dapm_routes),
661static const struct of_device_id wm8804_of_match[] = {
662 { .compatible = "wlf,wm8804", },
663 { }
664}; 552};
665MODULE_DEVICE_TABLE(of, wm8804_of_match);
666 553
667static const struct regmap_config wm8804_regmap_config = { 554const struct regmap_config wm8804_regmap_config = {
668 .reg_bits = 8, 555 .reg_bits = 8,
669 .val_bits = 8, 556 .val_bits = 8,
670 557
@@ -675,128 +562,169 @@ static const struct regmap_config wm8804_regmap_config = {
675 .reg_defaults = wm8804_reg_defaults, 562 .reg_defaults = wm8804_reg_defaults,
676 .num_reg_defaults = ARRAY_SIZE(wm8804_reg_defaults), 563 .num_reg_defaults = ARRAY_SIZE(wm8804_reg_defaults),
677}; 564};
565EXPORT_SYMBOL_GPL(wm8804_regmap_config);
678 566
679#if defined(CONFIG_SPI_MASTER) 567int wm8804_probe(struct device *dev, struct regmap *regmap)
680static int wm8804_spi_probe(struct spi_device *spi)
681{ 568{
682 struct wm8804_priv *wm8804; 569 struct wm8804_priv *wm8804;
683 int ret; 570 unsigned int id1, id2;
571 int i, ret;
684 572
685 wm8804 = devm_kzalloc(&spi->dev, sizeof *wm8804, GFP_KERNEL); 573 wm8804 = devm_kzalloc(dev, sizeof(*wm8804), GFP_KERNEL);
686 if (!wm8804) 574 if (!wm8804)
687 return -ENOMEM; 575 return -ENOMEM;
688 576
689 wm8804->regmap = devm_regmap_init_spi(spi, &wm8804_regmap_config); 577 dev_set_drvdata(dev, wm8804);
690 if (IS_ERR(wm8804->regmap)) { 578
691 ret = PTR_ERR(wm8804->regmap); 579 wm8804->dev = dev;
580 wm8804->regmap = regmap;
581
582 wm8804->reset = devm_gpiod_get_optional(dev, "wlf,reset",
583 GPIOD_OUT_LOW);
584 if (IS_ERR(wm8804->reset)) {
585 ret = PTR_ERR(wm8804->reset);
586 dev_err(dev, "Failed to get reset line: %d\n", ret);
692 return ret; 587 return ret;
693 } 588 }
694 589
695 spi_set_drvdata(spi, wm8804); 590 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++)
591 wm8804->supplies[i].supply = wm8804_supply_names[i];
696 592
697 ret = snd_soc_register_codec(&spi->dev, 593 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(wm8804->supplies),
698 &soc_codec_dev_wm8804, &wm8804_dai, 1); 594 wm8804->supplies);
595 if (ret) {
596 dev_err(dev, "Failed to request supplies: %d\n", ret);
597 return ret;
598 }
699 599
700 return ret; 600 wm8804->disable_nb[0].notifier_call = wm8804_regulator_event_0;
701} 601 wm8804->disable_nb[1].notifier_call = wm8804_regulator_event_1;
702 602
703static int wm8804_spi_remove(struct spi_device *spi) 603 /* This should really be moved into the regulator core */
704{ 604 for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) {
705 snd_soc_unregister_codec(&spi->dev); 605 struct regulator *regulator = wm8804->supplies[i].consumer;
706 return 0;
707}
708 606
709static struct spi_driver wm8804_spi_driver = { 607 ret = devm_regulator_register_notifier(regulator,
710 .driver = { 608 &wm8804->disable_nb[i]);
711 .name = "wm8804", 609 if (ret != 0) {
712 .owner = THIS_MODULE, 610 dev_err(dev,
713 .of_match_table = wm8804_of_match, 611 "Failed to register regulator notifier: %d\n",
714 }, 612 ret);
715 .probe = wm8804_spi_probe, 613 return ret;
716 .remove = wm8804_spi_remove 614 }
717}; 615 }
718#endif
719 616
720#if IS_ENABLED(CONFIG_I2C) 617 ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies),
721static int wm8804_i2c_probe(struct i2c_client *i2c, 618 wm8804->supplies);
722 const struct i2c_device_id *id) 619 if (ret) {
723{ 620 dev_err(dev, "Failed to enable supplies: %d\n", ret);
724 struct wm8804_priv *wm8804; 621 return ret;
725 int ret; 622 }
726 623
727 wm8804 = devm_kzalloc(&i2c->dev, sizeof *wm8804, GFP_KERNEL); 624 if (wm8804->reset)
728 if (!wm8804) 625 gpiod_set_value_cansleep(wm8804->reset, 1);
729 return -ENOMEM;
730 626
731 wm8804->regmap = devm_regmap_init_i2c(i2c, &wm8804_regmap_config); 627 ret = regmap_read(regmap, WM8804_RST_DEVID1, &id1);
732 if (IS_ERR(wm8804->regmap)) { 628 if (ret < 0) {
733 ret = PTR_ERR(wm8804->regmap); 629 dev_err(dev, "Failed to read device ID: %d\n", ret);
734 return ret; 630 goto err_reg_enable;
631 }
632
633 ret = regmap_read(regmap, WM8804_DEVID2, &id2);
634 if (ret < 0) {
635 dev_err(dev, "Failed to read device ID: %d\n", ret);
636 goto err_reg_enable;
637 }
638
639 id2 = (id2 << 8) | id1;
640
641 if (id2 != 0x8805) {
642 dev_err(dev, "Invalid device ID: %#x\n", id2);
643 ret = -EINVAL;
644 goto err_reg_enable;
645 }
646
647 ret = regmap_read(regmap, WM8804_DEVREV, &id1);
648 if (ret < 0) {
649 dev_err(dev, "Failed to read device revision: %d\n",
650 ret);
651 goto err_reg_enable;
735 } 652 }
653 dev_info(dev, "revision %c\n", id1 + 'A');
736 654
737 i2c_set_clientdata(i2c, wm8804); 655 if (!wm8804->reset) {
656 ret = wm8804_soft_reset(wm8804);
657 if (ret < 0) {
658 dev_err(dev, "Failed to issue reset: %d\n", ret);
659 goto err_reg_enable;
660 }
661 }
662
663 ret = snd_soc_register_codec(dev, &soc_codec_dev_wm8804,
664 &wm8804_dai, 1);
665 if (ret < 0) {
666 dev_err(dev, "Failed to register CODEC: %d\n", ret);
667 goto err_reg_enable;
668 }
669
670 pm_runtime_set_active(dev);
671 pm_runtime_enable(dev);
672 pm_runtime_idle(dev);
738 673
739 ret = snd_soc_register_codec(&i2c->dev, 674 return 0;
740 &soc_codec_dev_wm8804, &wm8804_dai, 1); 675
676err_reg_enable:
677 regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies);
741 return ret; 678 return ret;
742} 679}
680EXPORT_SYMBOL_GPL(wm8804_probe);
743 681
744static int wm8804_i2c_remove(struct i2c_client *i2c) 682void wm8804_remove(struct device *dev)
745{ 683{
746 snd_soc_unregister_codec(&i2c->dev); 684 pm_runtime_disable(dev);
747 return 0; 685 snd_soc_unregister_codec(dev);
748} 686}
687EXPORT_SYMBOL_GPL(wm8804_remove);
749 688
750static const struct i2c_device_id wm8804_i2c_id[] = { 689#if IS_ENABLED(CONFIG_PM)
751 { "wm8804", 0 }, 690static int wm8804_runtime_resume(struct device *dev)
752 { }
753};
754MODULE_DEVICE_TABLE(i2c, wm8804_i2c_id);
755
756static struct i2c_driver wm8804_i2c_driver = {
757 .driver = {
758 .name = "wm8804",
759 .owner = THIS_MODULE,
760 .of_match_table = wm8804_of_match,
761 },
762 .probe = wm8804_i2c_probe,
763 .remove = wm8804_i2c_remove,
764 .id_table = wm8804_i2c_id
765};
766#endif
767
768static int __init wm8804_modinit(void)
769{ 691{
770 int ret = 0; 692 struct wm8804_priv *wm8804 = dev_get_drvdata(dev);
693 int ret;
771 694
772#if IS_ENABLED(CONFIG_I2C) 695 ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies),
773 ret = i2c_add_driver(&wm8804_i2c_driver); 696 wm8804->supplies);
774 if (ret) { 697 if (ret) {
775 printk(KERN_ERR "Failed to register wm8804 I2C driver: %d\n", 698 dev_err(wm8804->dev, "Failed to enable supplies: %d\n", ret);
776 ret); 699 return ret;
777 }
778#endif
779#if defined(CONFIG_SPI_MASTER)
780 ret = spi_register_driver(&wm8804_spi_driver);
781 if (ret != 0) {
782 printk(KERN_ERR "Failed to register wm8804 SPI driver: %d\n",
783 ret);
784 } 700 }
785#endif 701
786 return ret; 702 regcache_sync(wm8804->regmap);
703
704 /* Power up OSCCLK */
705 regmap_update_bits(wm8804->regmap, WM8804_PWRDN, 0x8, 0x0);
706
707 return 0;
787} 708}
788module_init(wm8804_modinit);
789 709
790static void __exit wm8804_exit(void) 710static int wm8804_runtime_suspend(struct device *dev)
791{ 711{
792#if IS_ENABLED(CONFIG_I2C) 712 struct wm8804_priv *wm8804 = dev_get_drvdata(dev);
793 i2c_del_driver(&wm8804_i2c_driver); 713
794#endif 714 /* Power down OSCCLK */
795#if defined(CONFIG_SPI_MASTER) 715 regmap_update_bits(wm8804->regmap, WM8804_PWRDN, 0x8, 0x8);
796 spi_unregister_driver(&wm8804_spi_driver); 716
797#endif 717 regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies),
718 wm8804->supplies);
719
720 return 0;
798} 721}
799module_exit(wm8804_exit); 722#endif
723
724const struct dev_pm_ops wm8804_pm = {
725 SET_RUNTIME_PM_OPS(wm8804_runtime_suspend, wm8804_runtime_resume, NULL)
726};
727EXPORT_SYMBOL_GPL(wm8804_pm);
800 728
801MODULE_DESCRIPTION("ASoC WM8804 driver"); 729MODULE_DESCRIPTION("ASoC WM8804 driver");
802MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>"); 730MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8804.h b/sound/soc/codecs/wm8804.h
index e72d4f4ba6b1..aa72fa66c932 100644
--- a/sound/soc/codecs/wm8804.h
+++ b/sound/soc/codecs/wm8804.h
@@ -13,6 +13,8 @@
13#ifndef _WM8804_H 13#ifndef _WM8804_H
14#define _WM8804_H 14#define _WM8804_H
15 15
16#include <linux/regmap.h>
17
16/* 18/*
17 * Register values. 19 * Register values.
18 */ 20 */
@@ -62,4 +64,10 @@
62#define WM8804_MCLKDIV_256FS 0 64#define WM8804_MCLKDIV_256FS 0
63#define WM8804_MCLKDIV_128FS 1 65#define WM8804_MCLKDIV_128FS 1
64 66
67extern const struct regmap_config wm8804_regmap_config;
68extern const struct dev_pm_ops wm8804_pm;
69
70int wm8804_probe(struct device *dev, struct regmap *regmap);
71void wm8804_remove(struct device *dev);
72
65#endif /* _WM8804_H */ 73#endif /* _WM8804_H */
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 39ddb9b8834c..f9cbabdc6238 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -31,11 +31,11 @@
31 31
32#define WM8971_REG_COUNT 43 32#define WM8971_REG_COUNT 43
33 33
34static struct workqueue_struct *wm8971_workq = NULL;
35
36/* codec private data */ 34/* codec private data */
37struct wm8971_priv { 35struct wm8971_priv {
38 unsigned int sysclk; 36 unsigned int sysclk;
37 struct delayed_work charge_work;
38 struct regmap *regmap;
39}; 39};
40 40
41/* 41/*
@@ -552,9 +552,19 @@ static int wm8971_mute(struct snd_soc_dai *dai, int mute)
552 return 0; 552 return 0;
553} 553}
554 554
555static void wm8971_charge_work(struct work_struct *work)
556{
557 struct wm8971_priv *wm8971 =
558 container_of(work, struct wm8971_priv, charge_work.work);
559
560 /* Set to 500k */
561 regmap_update_bits(wm8971->regmap, WM8971_PWR1, 0x0180, 0x0100);
562}
563
555static int wm8971_set_bias_level(struct snd_soc_codec *codec, 564static int wm8971_set_bias_level(struct snd_soc_codec *codec,
556 enum snd_soc_bias_level level) 565 enum snd_soc_bias_level level)
557{ 566{
567 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
558 u16 pwr_reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e; 568 u16 pwr_reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
559 569
560 switch (level) { 570 switch (level) {
@@ -563,15 +573,24 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec,
563 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x00c1); 573 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x00c1);
564 break; 574 break;
565 case SND_SOC_BIAS_PREPARE: 575 case SND_SOC_BIAS_PREPARE:
576 /* Wait until fully charged */
577 flush_delayed_work(&wm8971->charge_work);
566 break; 578 break;
567 case SND_SOC_BIAS_STANDBY: 579 case SND_SOC_BIAS_STANDBY:
568 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) 580 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
569 snd_soc_cache_sync(codec); 581 snd_soc_cache_sync(codec);
582 /* charge output caps - set vmid to 5k for quick power up */
583 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x01c0);
584 queue_delayed_work(system_power_efficient_wq,
585 &wm8971->charge_work, msecs_to_jiffies(1000));
586 } else {
587 /* mute dac and set vmid to 500k, enable VREF */
588 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
589 }
570 590
571 /* mute dac and set vmid to 500k, enable VREF */
572 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
573 break; 591 break;
574 case SND_SOC_BIAS_OFF: 592 case SND_SOC_BIAS_OFF:
593 cancel_delayed_work_sync(&wm8971->charge_work);
575 snd_soc_write(codec, WM8971_PWR1, 0x0001); 594 snd_soc_write(codec, WM8971_PWR1, 0x0001);
576 break; 595 break;
577 } 596 }
@@ -610,58 +629,14 @@ static struct snd_soc_dai_driver wm8971_dai = {
610 .ops = &wm8971_dai_ops, 629 .ops = &wm8971_dai_ops,
611}; 630};
612 631
613static void wm8971_work(struct work_struct *work)
614{
615 struct snd_soc_dapm_context *dapm =
616 container_of(work, struct snd_soc_dapm_context,
617 delayed_work.work);
618 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
619 wm8971_set_bias_level(codec, codec->dapm.bias_level);
620}
621
622static int wm8971_suspend(struct snd_soc_codec *codec)
623{
624 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
625 return 0;
626}
627
628static int wm8971_resume(struct snd_soc_codec *codec)
629{
630 u16 reg;
631
632 wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
633
634 /* charge wm8971 caps */
635 if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
636 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
637 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
638 codec->dapm.bias_level = SND_SOC_BIAS_ON;
639 queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
640 msecs_to_jiffies(1000));
641 }
642
643 return 0;
644}
645
646static int wm8971_probe(struct snd_soc_codec *codec) 632static int wm8971_probe(struct snd_soc_codec *codec)
647{ 633{
648 int ret = 0; 634 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
649 u16 reg;
650 635
651 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8971_work); 636 INIT_DELAYED_WORK(&wm8971->charge_work, wm8971_charge_work);
652 wm8971_workq = create_workqueue("wm8971");
653 if (wm8971_workq == NULL)
654 return -ENOMEM;
655 637
656 wm8971_reset(codec); 638 wm8971_reset(codec);
657 639
658 /* charge output caps - set vmid to 5k for quick power up */
659 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
660 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
661 codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
662 queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
663 msecs_to_jiffies(1000));
664
665 /* set the update bits */ 640 /* set the update bits */
666 snd_soc_update_bits(codec, WM8971_LDAC, 0x0100, 0x0100); 641 snd_soc_update_bits(codec, WM8971_LDAC, 0x0100, 0x0100);
667 snd_soc_update_bits(codec, WM8971_RDAC, 0x0100, 0x0100); 642 snd_soc_update_bits(codec, WM8971_RDAC, 0x0100, 0x0100);
@@ -672,26 +647,13 @@ static int wm8971_probe(struct snd_soc_codec *codec)
672 snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100); 647 snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100);
673 snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100); 648 snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100);
674 649
675 return ret;
676}
677
678
679/* power down chip */
680static int wm8971_remove(struct snd_soc_codec *codec)
681{
682 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
683
684 if (wm8971_workq)
685 destroy_workqueue(wm8971_workq);
686 return 0; 650 return 0;
687} 651}
688 652
689static struct snd_soc_codec_driver soc_codec_dev_wm8971 = { 653static struct snd_soc_codec_driver soc_codec_dev_wm8971 = {
690 .probe = wm8971_probe, 654 .probe = wm8971_probe,
691 .remove = wm8971_remove,
692 .suspend = wm8971_suspend,
693 .resume = wm8971_resume,
694 .set_bias_level = wm8971_set_bias_level, 655 .set_bias_level = wm8971_set_bias_level,
656 .suspend_bias_off = true,
695 657
696 .controls = wm8971_snd_controls, 658 .controls = wm8971_snd_controls,
697 .num_controls = ARRAY_SIZE(wm8971_snd_controls), 659 .num_controls = ARRAY_SIZE(wm8971_snd_controls),
@@ -715,7 +677,6 @@ static int wm8971_i2c_probe(struct i2c_client *i2c,
715 const struct i2c_device_id *id) 677 const struct i2c_device_id *id)
716{ 678{
717 struct wm8971_priv *wm8971; 679 struct wm8971_priv *wm8971;
718 struct regmap *regmap;
719 int ret; 680 int ret;
720 681
721 wm8971 = devm_kzalloc(&i2c->dev, sizeof(struct wm8971_priv), 682 wm8971 = devm_kzalloc(&i2c->dev, sizeof(struct wm8971_priv),
@@ -723,9 +684,9 @@ static int wm8971_i2c_probe(struct i2c_client *i2c,
723 if (wm8971 == NULL) 684 if (wm8971 == NULL)
724 return -ENOMEM; 685 return -ENOMEM;
725 686
726 regmap = devm_regmap_init_i2c(i2c, &wm8971_regmap); 687 wm8971->regmap = devm_regmap_init_i2c(i2c, &wm8971_regmap);
727 if (IS_ERR(regmap)) 688 if (IS_ERR(wm8971->regmap))
728 return PTR_ERR(regmap); 689 return PTR_ERR(wm8971->regmap);
729 690
730 i2c_set_clientdata(i2c, wm8971); 691 i2c_set_clientdata(i2c, wm8971);
731 692
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index dc92d5e4e942..308748a022c5 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -2009,7 +2009,7 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2009 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 2009 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
2010 struct i2c_client *i2c = to_i2c_client(codec->dev); 2010 struct i2c_client *i2c = to_i2c_client(codec->dev);
2011 struct _fll_div fll_div; 2011 struct _fll_div fll_div;
2012 unsigned long timeout; 2012 unsigned long timeout, time_left;
2013 int ret, reg, retry; 2013 int ret, reg, retry;
2014 2014
2015 /* Any change? */ 2015 /* Any change? */
@@ -2110,13 +2110,15 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
2110 if (i2c->irq) 2110 if (i2c->irq)
2111 timeout *= 10; 2111 timeout *= 10;
2112 else 2112 else
2113 timeout /= 2; 2113 /* ensure timeout of atleast 1 jiffies */
2114 timeout = timeout/2 ? : 1;
2114 2115
2115 for (retry = 0; retry < 10; retry++) { 2116 for (retry = 0; retry < 10; retry++) {
2116 ret = wait_for_completion_timeout(&wm8996->fll_lock, 2117 time_left = wait_for_completion_timeout(&wm8996->fll_lock,
2117 timeout); 2118 timeout);
2118 if (ret != 0) { 2119 if (time_left != 0) {
2119 WARN_ON(!i2c->irq); 2120 WARN_ON(!i2c->irq);
2121 ret = 1;
2120 break; 2122 break;
2121 } 2123 }
2122 2124
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index ff67b334065b..d01c2095452f 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -420,10 +420,9 @@ static int wm_coeff_put(struct snd_kcontrol *kcontrol,
420 420
421 memcpy(ctl->cache, p, ctl->len); 421 memcpy(ctl->cache, p, ctl->len);
422 422
423 if (!ctl->enabled) { 423 ctl->set = 1;
424 ctl->set = 1; 424 if (!ctl->enabled)
425 return 0; 425 return 0;
426 }
427 426
428 return wm_coeff_write_control(kcontrol, p, ctl->len); 427 return wm_coeff_write_control(kcontrol, p, ctl->len);
429} 428}
@@ -1185,7 +1184,6 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
1185 int ret, pos, blocks, type, offset, reg; 1184 int ret, pos, blocks, type, offset, reg;
1186 char *file; 1185 char *file;
1187 struct wm_adsp_buf *buf; 1186 struct wm_adsp_buf *buf;
1188 int tmp;
1189 1187
1190 file = kzalloc(PAGE_SIZE, GFP_KERNEL); 1188 file = kzalloc(PAGE_SIZE, GFP_KERNEL);
1191 if (file == NULL) 1189 if (file == NULL)
@@ -1335,12 +1333,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
1335 } 1333 }
1336 } 1334 }
1337 1335
1338 tmp = le32_to_cpu(blk->len) % 4; 1336 pos += (le32_to_cpu(blk->len) + sizeof(*blk) + 3) & ~0x03;
1339 if (tmp)
1340 pos += le32_to_cpu(blk->len) + (4 - tmp) + sizeof(*blk);
1341 else
1342 pos += le32_to_cpu(blk->len) + sizeof(*blk);
1343
1344 blocks++; 1337 blocks++;
1345 } 1338 }
1346 1339
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index 2b81ca418d2a..3736d9aabc56 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -1,14 +1,16 @@
1config SND_DAVINCI_SOC 1config SND_DAVINCI_SOC
2 tristate "SoC Audio for TI DAVINCI" 2 tristate
3 depends on ARCH_DAVINCI 3 depends on ARCH_DAVINCI
4 select SND_EDMA_SOC
4 5
5config SND_EDMA_SOC 6config SND_EDMA_SOC
6 tristate "SoC Audio for Texas Instruments chips using eDMA (AM33XX/43XX)" 7 tristate "SoC Audio for Texas Instruments chips using eDMA"
7 depends on SOC_AM33XX || SOC_AM43XX 8 depends on SOC_AM33XX || SOC_AM43XX || ARCH_DAVINCI
8 select SND_SOC_GENERIC_DMAENGINE_PCM 9 select SND_SOC_GENERIC_DMAENGINE_PCM
9 help 10 help
10 Say Y or M here if you want audio support for TI SoC which uses eDMA. 11 Say Y or M here if you want audio support for TI SoC which uses eDMA.
11 The following line of SoCs are supported by this platform driver: 12 The following line of SoCs are supported by this platform driver:
13 - daVinci devices
12 - AM335x 14 - AM335x
13 - AM437x/AM438x 15 - AM437x/AM438x
14 16
@@ -17,7 +19,7 @@ config SND_DAVINCI_SOC_I2S
17 19
18config SND_DAVINCI_SOC_MCASP 20config SND_DAVINCI_SOC_MCASP
19 tristate "Multichannel Audio Serial Port (McASP) support" 21 tristate "Multichannel Audio Serial Port (McASP) support"
20 depends on SND_DAVINCI_SOC || SND_OMAP_SOC || SND_EDMA_SOC 22 depends on SND_OMAP_SOC || SND_EDMA_SOC
21 help 23 help
22 Say Y or M here if you want to have support for McASP IP found in 24 Say Y or M here if you want to have support for McASP IP found in
23 various Texas Instruments SoCs like: 25 various Texas Instruments SoCs like:
@@ -45,7 +47,7 @@ config SND_AM33XX_SOC_EVM
45 47
46config SND_DAVINCI_SOC_EVM 48config SND_DAVINCI_SOC_EVM
47 tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM" 49 tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM"
48 depends on SND_DAVINCI_SOC && I2C 50 depends on SND_EDMA_SOC && I2C
49 depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM 51 depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM
50 select SND_DAVINCI_SOC_GENERIC_EVM 52 select SND_DAVINCI_SOC_GENERIC_EVM
51 help 53 help
@@ -73,7 +75,7 @@ endchoice
73 75
74config SND_DM6467_SOC_EVM 76config SND_DM6467_SOC_EVM
75 tristate "SoC Audio support for DaVinci DM6467 EVM" 77 tristate "SoC Audio support for DaVinci DM6467 EVM"
76 depends on SND_DAVINCI_SOC && MACH_DAVINCI_DM6467_EVM && I2C 78 depends on SND_EDMA_SOC && MACH_DAVINCI_DM6467_EVM && I2C
77 select SND_DAVINCI_SOC_GENERIC_EVM 79 select SND_DAVINCI_SOC_GENERIC_EVM
78 select SND_SOC_SPDIF 80 select SND_SOC_SPDIF
79 81
@@ -82,7 +84,7 @@ config SND_DM6467_SOC_EVM
82 84
83config SND_DA830_SOC_EVM 85config SND_DA830_SOC_EVM
84 tristate "SoC Audio support for DA830/OMAP-L137 EVM" 86 tristate "SoC Audio support for DA830/OMAP-L137 EVM"
85 depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA830_EVM && I2C 87 depends on SND_EDMA_SOC && MACH_DAVINCI_DA830_EVM && I2C
86 select SND_DAVINCI_SOC_GENERIC_EVM 88 select SND_DAVINCI_SOC_GENERIC_EVM
87 89
88 help 90 help
@@ -91,7 +93,7 @@ config SND_DA830_SOC_EVM
91 93
92config SND_DA850_SOC_EVM 94config SND_DA850_SOC_EVM
93 tristate "SoC Audio support for DA850/OMAP-L138 EVM" 95 tristate "SoC Audio support for DA850/OMAP-L138 EVM"
94 depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM && I2C 96 depends on SND_EDMA_SOC && MACH_DAVINCI_DA850_EVM && I2C
95 select SND_DAVINCI_SOC_GENERIC_EVM 97 select SND_DAVINCI_SOC_GENERIC_EVM
96 help 98 help
97 Say Y if you want to add support for SoC audio on TI 99 Say Y if you want to add support for SoC audio on TI
diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile
index 09bf2ba92d38..f883933c1a19 100644
--- a/sound/soc/davinci/Makefile
+++ b/sound/soc/davinci/Makefile
@@ -1,11 +1,9 @@
1# DAVINCI Platform Support 1# DAVINCI Platform Support
2snd-soc-davinci-objs := davinci-pcm.o
3snd-soc-edma-objs := edma-pcm.o 2snd-soc-edma-objs := edma-pcm.o
4snd-soc-davinci-i2s-objs := davinci-i2s.o 3snd-soc-davinci-i2s-objs := davinci-i2s.o
5snd-soc-davinci-mcasp-objs:= davinci-mcasp.o 4snd-soc-davinci-mcasp-objs:= davinci-mcasp.o
6snd-soc-davinci-vcif-objs:= davinci-vcif.o 5snd-soc-davinci-vcif-objs:= davinci-vcif.o
7 6
8obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o
9obj-$(CONFIG_SND_EDMA_SOC) += snd-soc-edma.o 7obj-$(CONFIG_SND_EDMA_SOC) += snd-soc-edma.o
10obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o 8obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o
11obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o 9obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index b6bb5947a8a8..731fb0d86c6a 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -117,7 +117,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
117static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd) 117static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
118{ 118{
119 struct snd_soc_card *card = rtd->card; 119 struct snd_soc_card *card = rtd->card;
120 struct snd_soc_codec *codec = rtd->codec;
121 struct device_node *np = card->dev->of_node; 120 struct device_node *np = card->dev->of_node;
122 int ret; 121 int ret;
123 122
@@ -136,9 +135,9 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
136 } 135 }
137 136
138 /* not connected */ 137 /* not connected */
139 snd_soc_dapm_nc_pin(&codec->dapm, "MONO_LOUT"); 138 snd_soc_dapm_nc_pin(&card->dapm, "MONO_LOUT");
140 snd_soc_dapm_nc_pin(&codec->dapm, "HPLCOM"); 139 snd_soc_dapm_nc_pin(&card->dapm, "HPLCOM");
141 snd_soc_dapm_nc_pin(&codec->dapm, "HPRCOM"); 140 snd_soc_dapm_nc_pin(&card->dapm, "HPRCOM");
142 141
143 return 0; 142 return 0;
144} 143}
@@ -425,18 +424,8 @@ static int davinci_evm_probe(struct platform_device *pdev)
425 return ret; 424 return ret;
426} 425}
427 426
428static int davinci_evm_remove(struct platform_device *pdev)
429{
430 struct snd_soc_card *card = platform_get_drvdata(pdev);
431
432 snd_soc_unregister_card(card);
433
434 return 0;
435}
436
437static struct platform_driver davinci_evm_driver = { 427static struct platform_driver davinci_evm_driver = {
438 .probe = davinci_evm_probe, 428 .probe = davinci_evm_probe,
439 .remove = davinci_evm_remove,
440 .driver = { 429 .driver = {
441 .name = "davinci_evm", 430 .name = "davinci_evm",
442 .pm = &snd_soc_pm_ops, 431 .pm = &snd_soc_pm_ops,
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 15fb28fc8e1b..56cb4d95637d 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -23,8 +23,9 @@
23#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
24#include <sound/initval.h> 24#include <sound/initval.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/dmaengine_pcm.h>
26 27
27#include "davinci-pcm.h" 28#include "edma-pcm.h"
28#include "davinci-i2s.h" 29#include "davinci-i2s.h"
29 30
30 31
@@ -122,7 +123,8 @@ static const unsigned char double_fmt[SNDRV_PCM_FORMAT_S32_LE + 1] = {
122 123
123struct davinci_mcbsp_dev { 124struct davinci_mcbsp_dev {
124 struct device *dev; 125 struct device *dev;
125 struct davinci_pcm_dma_params dma_params[2]; 126 struct snd_dmaengine_dai_dma_data dma_data[2];
127 int dma_request[2];
126 void __iomem *base; 128 void __iomem *base;
127#define MOD_DSP_A 0 129#define MOD_DSP_A 0
128#define MOD_DSP_B 1 130#define MOD_DSP_B 1
@@ -419,8 +421,6 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
419 struct snd_soc_dai *dai) 421 struct snd_soc_dai *dai)
420{ 422{
421 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai); 423 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
422 struct davinci_pcm_dma_params *dma_params =
423 &dev->dma_params[substream->stream];
424 struct snd_interval *i = NULL; 424 struct snd_interval *i = NULL;
425 int mcbsp_word_length, master; 425 int mcbsp_word_length, master;
426 unsigned int rcr, xcr, srgr, clk_div, freq, framesize; 426 unsigned int rcr, xcr, srgr, clk_div, freq, framesize;
@@ -532,8 +532,6 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
532 return -EINVAL; 532 return -EINVAL;
533 } 533 }
534 } 534 }
535 dma_params->acnt = dma_params->data_type = data_type[fmt];
536 dma_params->fifo_level = 0;
537 mcbsp_word_length = asp_word_length[fmt]; 535 mcbsp_word_length = asp_word_length[fmt];
538 536
539 switch (master) { 537 switch (master) {
@@ -600,15 +598,6 @@ static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
600 return ret; 598 return ret;
601} 599}
602 600
603static int davinci_i2s_startup(struct snd_pcm_substream *substream,
604 struct snd_soc_dai *dai)
605{
606 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
607
608 snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
609 return 0;
610}
611
612static void davinci_i2s_shutdown(struct snd_pcm_substream *substream, 601static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
613 struct snd_soc_dai *dai) 602 struct snd_soc_dai *dai)
614{ 603{
@@ -620,7 +609,6 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
620#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 609#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
621 610
622static const struct snd_soc_dai_ops davinci_i2s_dai_ops = { 611static const struct snd_soc_dai_ops davinci_i2s_dai_ops = {
623 .startup = davinci_i2s_startup,
624 .shutdown = davinci_i2s_shutdown, 612 .shutdown = davinci_i2s_shutdown,
625 .prepare = davinci_i2s_prepare, 613 .prepare = davinci_i2s_prepare,
626 .trigger = davinci_i2s_trigger, 614 .trigger = davinci_i2s_trigger,
@@ -630,7 +618,18 @@ static const struct snd_soc_dai_ops davinci_i2s_dai_ops = {
630 618
631}; 619};
632 620
621static int davinci_i2s_dai_probe(struct snd_soc_dai *dai)
622{
623 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
624
625 dai->playback_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
626 dai->capture_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE];
627
628 return 0;
629}
630
633static struct snd_soc_dai_driver davinci_i2s_dai = { 631static struct snd_soc_dai_driver davinci_i2s_dai = {
632 .probe = davinci_i2s_dai_probe,
634 .playback = { 633 .playback = {
635 .channels_min = 2, 634 .channels_min = 2,
636 .channels_max = 2, 635 .channels_max = 2,
@@ -651,11 +650,9 @@ static const struct snd_soc_component_driver davinci_i2s_component = {
651 650
652static int davinci_i2s_probe(struct platform_device *pdev) 651static int davinci_i2s_probe(struct platform_device *pdev)
653{ 652{
654 struct snd_platform_data *pdata = pdev->dev.platform_data;
655 struct davinci_mcbsp_dev *dev; 653 struct davinci_mcbsp_dev *dev;
656 struct resource *mem, *ioarea, *res; 654 struct resource *mem, *ioarea, *res;
657 enum dma_event_q asp_chan_q = EVENTQ_0; 655 int *dma;
658 enum dma_event_q ram_chan_q = EVENTQ_1;
659 int ret; 656 int ret;
660 657
661 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 658 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -676,22 +673,6 @@ static int davinci_i2s_probe(struct platform_device *pdev)
676 GFP_KERNEL); 673 GFP_KERNEL);
677 if (!dev) 674 if (!dev)
678 return -ENOMEM; 675 return -ENOMEM;
679 if (pdata) {
680 dev->enable_channel_combine = pdata->enable_channel_combine;
681 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].sram_size =
682 pdata->sram_size_playback;
683 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].sram_size =
684 pdata->sram_size_capture;
685 dev->clk_input_pin = pdata->clk_input_pin;
686 dev->i2s_accurate_sck = pdata->i2s_accurate_sck;
687 asp_chan_q = pdata->asp_chan_q;
688 ram_chan_q = pdata->ram_chan_q;
689 }
690
691 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].asp_chan_q = asp_chan_q;
692 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].ram_chan_q = ram_chan_q;
693 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].asp_chan_q = asp_chan_q;
694 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].ram_chan_q = ram_chan_q;
695 676
696 dev->clk = clk_get(&pdev->dev, NULL); 677 dev->clk = clk_get(&pdev->dev, NULL);
697 if (IS_ERR(dev->clk)) 678 if (IS_ERR(dev->clk))
@@ -705,10 +686,10 @@ static int davinci_i2s_probe(struct platform_device *pdev)
705 goto err_release_clk; 686 goto err_release_clk;
706 } 687 }
707 688
708 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr = 689 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr =
709 (dma_addr_t)(mem->start + DAVINCI_MCBSP_DXR_REG); 690 (dma_addr_t)(mem->start + DAVINCI_MCBSP_DXR_REG);
710 691
711 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr = 692 dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr =
712 (dma_addr_t)(mem->start + DAVINCI_MCBSP_DRR_REG); 693 (dma_addr_t)(mem->start + DAVINCI_MCBSP_DRR_REG);
713 694
714 /* first TX, then RX */ 695 /* first TX, then RX */
@@ -718,7 +699,9 @@ static int davinci_i2s_probe(struct platform_device *pdev)
718 ret = -ENXIO; 699 ret = -ENXIO;
719 goto err_release_clk; 700 goto err_release_clk;
720 } 701 }
721 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start; 702 dma = &dev->dma_request[SNDRV_PCM_STREAM_PLAYBACK];
703 *dma = res->start;
704 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = dma;
722 705
723 res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 706 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
724 if (!res) { 707 if (!res) {
@@ -726,9 +709,11 @@ static int davinci_i2s_probe(struct platform_device *pdev)
726 ret = -ENXIO; 709 ret = -ENXIO;
727 goto err_release_clk; 710 goto err_release_clk;
728 } 711 }
729 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; 712 dma = &dev->dma_request[SNDRV_PCM_STREAM_CAPTURE];
730 dev->dev = &pdev->dev; 713 *dma = res->start;
714 dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data = dma;
731 715
716 dev->dev = &pdev->dev;
732 dev_set_drvdata(&pdev->dev, dev); 717 dev_set_drvdata(&pdev->dev, dev);
733 718
734 ret = snd_soc_register_component(&pdev->dev, &davinci_i2s_component, 719 ret = snd_soc_register_component(&pdev->dev, &davinci_i2s_component,
@@ -736,7 +721,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
736 if (ret != 0) 721 if (ret != 0)
737 goto err_release_clk; 722 goto err_release_clk;
738 723
739 ret = davinci_soc_platform_register(&pdev->dev); 724 ret = edma_pcm_platform_register(&pdev->dev);
740 if (ret) { 725 if (ret) {
741 dev_err(&pdev->dev, "register PCM failed: %d\n", ret); 726 dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
742 goto err_unregister_component; 727 goto err_unregister_component;
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index de3b155a5011..bb4b78eada58 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -26,6 +26,8 @@
26#include <linux/of.h> 26#include <linux/of.h>
27#include <linux/of_platform.h> 27#include <linux/of_platform.h>
28#include <linux/of_device.h> 28#include <linux/of_device.h>
29#include <linux/platform_data/davinci_asp.h>
30#include <linux/math64.h>
29 31
30#include <sound/asoundef.h> 32#include <sound/asoundef.h>
31#include <sound/core.h> 33#include <sound/core.h>
@@ -36,7 +38,6 @@
36#include <sound/dmaengine_pcm.h> 38#include <sound/dmaengine_pcm.h>
37#include <sound/omap-pcm.h> 39#include <sound/omap-pcm.h>
38 40
39#include "davinci-pcm.h"
40#include "edma-pcm.h" 41#include "edma-pcm.h"
41#include "davinci-mcasp.h" 42#include "davinci-mcasp.h"
42 43
@@ -62,10 +63,15 @@ struct davinci_mcasp_context {
62 u32 config_regs[ARRAY_SIZE(context_regs)]; 63 u32 config_regs[ARRAY_SIZE(context_regs)];
63 u32 afifo_regs[2]; /* for read/write fifo control registers */ 64 u32 afifo_regs[2]; /* for read/write fifo control registers */
64 u32 *xrsr_regs; /* for serializer configuration */ 65 u32 *xrsr_regs; /* for serializer configuration */
66 bool pm_state;
67};
68
69struct davinci_mcasp_ruledata {
70 struct davinci_mcasp *mcasp;
71 int serializers;
65}; 72};
66 73
67struct davinci_mcasp { 74struct davinci_mcasp {
68 struct davinci_pcm_dma_params dma_params[2];
69 struct snd_dmaengine_dai_dma_data dma_data[2]; 75 struct snd_dmaengine_dai_dma_data dma_data[2];
70 void __iomem *base; 76 void __iomem *base;
71 u32 fifo_base; 77 u32 fifo_base;
@@ -82,6 +88,7 @@ struct davinci_mcasp {
82 u16 bclk_lrclk_ratio; 88 u16 bclk_lrclk_ratio;
83 int streams; 89 int streams;
84 u32 irq_request[2]; 90 u32 irq_request[2];
91 int dma_request[2];
85 92
86 int sysclk_freq; 93 int sysclk_freq;
87 bool bclk_master; 94 bool bclk_master;
@@ -98,6 +105,8 @@ struct davinci_mcasp {
98#ifdef CONFIG_PM_SLEEP 105#ifdef CONFIG_PM_SLEEP
99 struct davinci_mcasp_context context; 106 struct davinci_mcasp_context context;
100#endif 107#endif
108
109 struct davinci_mcasp_ruledata ruledata[2];
101}; 110};
102 111
103static inline void mcasp_set_bits(struct davinci_mcasp *mcasp, u32 offset, 112static inline void mcasp_set_bits(struct davinci_mcasp *mcasp, u32 offset,
@@ -441,6 +450,18 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
441 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR); 450 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR);
442 mcasp->bclk_master = 1; 451 mcasp->bclk_master = 1;
443 break; 452 break;
453 case SND_SOC_DAIFMT_CBS_CFM:
454 /* codec is clock slave and frame master */
455 mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
456 mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
457
458 mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
459 mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
460
461 mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, ACLKX | ACLKR);
462 mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR);
463 mcasp->bclk_master = 1;
464 break;
444 case SND_SOC_DAIFMT_CBM_CFS: 465 case SND_SOC_DAIFMT_CBM_CFS:
445 /* codec is clock master and frame slave */ 466 /* codec is clock master and frame slave */
446 mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE); 467 mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
@@ -507,7 +528,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
507 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); 528 mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
508 } 529 }
509out: 530out:
510 pm_runtime_put_sync(mcasp->dev); 531 pm_runtime_put(mcasp->dev);
511 return ret; 532 return ret;
512} 533}
513 534
@@ -516,6 +537,7 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id,
516{ 537{
517 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); 538 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
518 539
540 pm_runtime_get_sync(mcasp->dev);
519 switch (div_id) { 541 switch (div_id) {
520 case 0: /* MCLK divider */ 542 case 0: /* MCLK divider */
521 mcasp_mod_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, 543 mcasp_mod_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG,
@@ -541,6 +563,7 @@ static int __davinci_mcasp_set_clkdiv(struct snd_soc_dai *dai, int div_id,
541 return -EINVAL; 563 return -EINVAL;
542 } 564 }
543 565
566 pm_runtime_put(mcasp->dev);
544 return 0; 567 return 0;
545} 568}
546 569
@@ -555,6 +578,7 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id,
555{ 578{
556 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); 579 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
557 580
581 pm_runtime_get_sync(mcasp->dev);
558 if (dir == SND_SOC_CLOCK_OUT) { 582 if (dir == SND_SOC_CLOCK_OUT) {
559 mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE); 583 mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE);
560 mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE); 584 mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKRCTL_REG, AHCLKRE);
@@ -567,6 +591,7 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id,
567 591
568 mcasp->sysclk_freq = freq; 592 mcasp->sysclk_freq = freq;
569 593
594 pm_runtime_put(mcasp->dev);
570 return 0; 595 return 0;
571} 596}
572 597
@@ -631,7 +656,6 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
631static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, 656static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
632 int period_words, int channels) 657 int period_words, int channels)
633{ 658{
634 struct davinci_pcm_dma_params *dma_params = &mcasp->dma_params[stream];
635 struct snd_dmaengine_dai_dma_data *dma_data = &mcasp->dma_data[stream]; 659 struct snd_dmaengine_dai_dma_data *dma_data = &mcasp->dma_data[stream];
636 int i; 660 int i;
637 u8 tx_ser = 0; 661 u8 tx_ser = 0;
@@ -699,10 +723,8 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
699 * For example if three serializers are enabled the DMA 723 * For example if three serializers are enabled the DMA
700 * need to transfer three words per DMA request. 724 * need to transfer three words per DMA request.
701 */ 725 */
702 dma_params->fifo_level = active_serializers;
703 dma_data->maxburst = active_serializers; 726 dma_data->maxburst = active_serializers;
704 } else { 727 } else {
705 dma_params->fifo_level = 0;
706 dma_data->maxburst = 0; 728 dma_data->maxburst = 0;
707 } 729 }
708 return 0; 730 return 0;
@@ -734,7 +756,6 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream,
734 /* Configure the burst size for platform drivers */ 756 /* Configure the burst size for platform drivers */
735 if (numevt == 1) 757 if (numevt == 1)
736 numevt = 0; 758 numevt = 0;
737 dma_params->fifo_level = numevt;
738 dma_data->maxburst = numevt; 759 dma_data->maxburst = numevt;
739 760
740 return 0; 761 return 0;
@@ -855,13 +876,35 @@ static int mcasp_dit_hw_param(struct davinci_mcasp *mcasp,
855 return 0; 876 return 0;
856} 877}
857 878
879static int davinci_mcasp_calc_clk_div(struct davinci_mcasp *mcasp,
880 unsigned int bclk_freq,
881 int *error_ppm)
882{
883 int div = mcasp->sysclk_freq / bclk_freq;
884 int rem = mcasp->sysclk_freq % bclk_freq;
885
886 if (rem != 0) {
887 if (div == 0 ||
888 ((mcasp->sysclk_freq / div) - bclk_freq) >
889 (bclk_freq - (mcasp->sysclk_freq / (div+1)))) {
890 div++;
891 rem = rem - bclk_freq;
892 }
893 }
894 if (error_ppm)
895 *error_ppm =
896 (div*1000000 + (int)div64_long(1000000LL*rem,
897 (int)bclk_freq))
898 /div - 1000000;
899
900 return div;
901}
902
858static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, 903static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
859 struct snd_pcm_hw_params *params, 904 struct snd_pcm_hw_params *params,
860 struct snd_soc_dai *cpu_dai) 905 struct snd_soc_dai *cpu_dai)
861{ 906{
862 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); 907 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
863 struct davinci_pcm_dma_params *dma_params =
864 &mcasp->dma_params[substream->stream];
865 int word_length; 908 int word_length;
866 int channels = params_channels(params); 909 int channels = params_channels(params);
867 int period_size = params_period_size(params); 910 int period_size = params_period_size(params);
@@ -872,16 +915,20 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
872 * the machine driver, we need to calculate the ratio. 915 * the machine driver, we need to calculate the ratio.
873 */ 916 */
874 if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) { 917 if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) {
875 unsigned int bclk_freq = snd_soc_params_to_bclk(params); 918 int channels = params_channels(params);
876 unsigned int div = mcasp->sysclk_freq / bclk_freq; 919 int rate = params_rate(params);
877 if (mcasp->sysclk_freq % bclk_freq != 0) { 920 int sbits = params_width(params);
878 if (((mcasp->sysclk_freq / div) - bclk_freq) > 921 int ppm, div;
879 (bclk_freq - (mcasp->sysclk_freq / (div+1)))) 922
880 div++; 923 if (channels > mcasp->tdm_slots)
881 dev_warn(mcasp->dev, 924 channels = mcasp->tdm_slots;
882 "Inaccurate BCLK: %u Hz / %u != %u Hz\n", 925
883 mcasp->sysclk_freq, div, bclk_freq); 926 div = davinci_mcasp_calc_clk_div(mcasp, rate*sbits*channels,
884 } 927 &ppm);
928 if (ppm)
929 dev_info(mcasp->dev, "Sample-rate is off by %d PPM\n",
930 ppm);
931
885 __davinci_mcasp_set_clkdiv(cpu_dai, 1, div, 0); 932 __davinci_mcasp_set_clkdiv(cpu_dai, 1, div, 0);
886 } 933 }
887 934
@@ -902,31 +949,26 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
902 switch (params_format(params)) { 949 switch (params_format(params)) {
903 case SNDRV_PCM_FORMAT_U8: 950 case SNDRV_PCM_FORMAT_U8:
904 case SNDRV_PCM_FORMAT_S8: 951 case SNDRV_PCM_FORMAT_S8:
905 dma_params->data_type = 1;
906 word_length = 8; 952 word_length = 8;
907 break; 953 break;
908 954
909 case SNDRV_PCM_FORMAT_U16_LE: 955 case SNDRV_PCM_FORMAT_U16_LE:
910 case SNDRV_PCM_FORMAT_S16_LE: 956 case SNDRV_PCM_FORMAT_S16_LE:
911 dma_params->data_type = 2;
912 word_length = 16; 957 word_length = 16;
913 break; 958 break;
914 959
915 case SNDRV_PCM_FORMAT_U24_3LE: 960 case SNDRV_PCM_FORMAT_U24_3LE:
916 case SNDRV_PCM_FORMAT_S24_3LE: 961 case SNDRV_PCM_FORMAT_S24_3LE:
917 dma_params->data_type = 3;
918 word_length = 24; 962 word_length = 24;
919 break; 963 break;
920 964
921 case SNDRV_PCM_FORMAT_U24_LE: 965 case SNDRV_PCM_FORMAT_U24_LE:
922 case SNDRV_PCM_FORMAT_S24_LE: 966 case SNDRV_PCM_FORMAT_S24_LE:
923 dma_params->data_type = 4;
924 word_length = 24; 967 word_length = 24;
925 break; 968 break;
926 969
927 case SNDRV_PCM_FORMAT_U32_LE: 970 case SNDRV_PCM_FORMAT_U32_LE:
928 case SNDRV_PCM_FORMAT_S32_LE: 971 case SNDRV_PCM_FORMAT_S32_LE:
929 dma_params->data_type = 4;
930 word_length = 32; 972 word_length = 32;
931 break; 973 break;
932 974
@@ -935,11 +977,6 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
935 return -EINVAL; 977 return -EINVAL;
936 } 978 }
937 979
938 if (mcasp->version == MCASP_VERSION_2 && !dma_params->fifo_level)
939 dma_params->acnt = 4;
940 else
941 dma_params->acnt = dma_params->data_type;
942
943 davinci_config_channel_size(mcasp, word_length); 980 davinci_config_channel_size(mcasp, word_length);
944 981
945 if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) 982 if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE)
@@ -973,10 +1010,126 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
973 return ret; 1010 return ret;
974} 1011}
975 1012
1013static const unsigned int davinci_mcasp_dai_rates[] = {
1014 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000,
1015 88200, 96000, 176400, 192000,
1016};
1017
1018#define DAVINCI_MAX_RATE_ERROR_PPM 1000
1019
1020static int davinci_mcasp_hw_rule_rate(struct snd_pcm_hw_params *params,
1021 struct snd_pcm_hw_rule *rule)
1022{
1023 struct davinci_mcasp_ruledata *rd = rule->private;
1024 struct snd_interval *ri =
1025 hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
1026 int sbits = params_width(params);
1027 int channels = params_channels(params);
1028 unsigned int list[ARRAY_SIZE(davinci_mcasp_dai_rates)];
1029 int i, count = 0;
1030
1031 if (channels > rd->mcasp->tdm_slots)
1032 channels = rd->mcasp->tdm_slots;
1033
1034 for (i = 0; i < ARRAY_SIZE(davinci_mcasp_dai_rates); i++) {
1035 if (ri->min <= davinci_mcasp_dai_rates[i] &&
1036 ri->max >= davinci_mcasp_dai_rates[i]) {
1037 uint bclk_freq = sbits*channels*
1038 davinci_mcasp_dai_rates[i];
1039 int ppm;
1040
1041 davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm);
1042 if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM)
1043 list[count++] = davinci_mcasp_dai_rates[i];
1044 }
1045 }
1046 dev_dbg(rd->mcasp->dev,
1047 "%d frequencies (%d-%d) for %d sbits and %d channels\n",
1048 count, ri->min, ri->max, sbits, channels);
1049
1050 return snd_interval_list(hw_param_interval(params, rule->var),
1051 count, list, 0);
1052}
1053
1054static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params,
1055 struct snd_pcm_hw_rule *rule)
1056{
1057 struct davinci_mcasp_ruledata *rd = rule->private;
1058 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1059 struct snd_mask nfmt;
1060 int rate = params_rate(params);
1061 int channels = params_channels(params);
1062 int i, count = 0;
1063
1064 snd_mask_none(&nfmt);
1065
1066 if (channels > rd->mcasp->tdm_slots)
1067 channels = rd->mcasp->tdm_slots;
1068
1069 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
1070 if (snd_mask_test(fmt, i)) {
1071 uint bclk_freq = snd_pcm_format_width(i)*channels*rate;
1072 int ppm;
1073
1074 davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm);
1075 if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) {
1076 snd_mask_set(&nfmt, i);
1077 count++;
1078 }
1079 }
1080 }
1081 dev_dbg(rd->mcasp->dev,
1082 "%d possible sample format for %d Hz and %d channels\n",
1083 count, rate, channels);
1084
1085 return snd_mask_refine(fmt, &nfmt);
1086}
1087
1088static int davinci_mcasp_hw_rule_channels(struct snd_pcm_hw_params *params,
1089 struct snd_pcm_hw_rule *rule)
1090{
1091 struct davinci_mcasp_ruledata *rd = rule->private;
1092 struct snd_interval *ci =
1093 hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
1094 int sbits = params_width(params);
1095 int rate = params_rate(params);
1096 int max_chan_per_wire = rd->mcasp->tdm_slots < ci->max ?
1097 rd->mcasp->tdm_slots : ci->max;
1098 unsigned int list[ci->max - ci->min + 1];
1099 int c1, c, count = 0;
1100
1101 for (c1 = ci->min; c1 <= max_chan_per_wire; c1++) {
1102 uint bclk_freq = c1*sbits*rate;
1103 int ppm;
1104
1105 davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm);
1106 if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) {
1107 /* If we can use all tdm_slots, we can put any
1108 amount of channels to remaining wires as
1109 long as they fit in. */
1110 if (c1 == rd->mcasp->tdm_slots) {
1111 for (c = c1; c <= rd->serializers*c1 &&
1112 c <= ci->max; c++)
1113 list[count++] = c;
1114 } else {
1115 list[count++] = c1;
1116 }
1117 }
1118 }
1119 dev_dbg(rd->mcasp->dev,
1120 "%d possible channel counts (%d-%d) for %d Hz and %d sbits\n",
1121 count, ci->min, ci->max, rate, sbits);
1122
1123 return snd_interval_list(hw_param_interval(params, rule->var),
1124 count, list, 0);
1125}
1126
976static int davinci_mcasp_startup(struct snd_pcm_substream *substream, 1127static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
977 struct snd_soc_dai *cpu_dai) 1128 struct snd_soc_dai *cpu_dai)
978{ 1129{
979 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); 1130 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
1131 struct davinci_mcasp_ruledata *ruledata =
1132 &mcasp->ruledata[substream->stream];
980 u32 max_channels = 0; 1133 u32 max_channels = 0;
981 int i, dir; 1134 int i, dir;
982 1135
@@ -998,6 +1151,7 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
998 if (mcasp->serial_dir[i] == dir) 1151 if (mcasp->serial_dir[i] == dir)
999 max_channels++; 1152 max_channels++;
1000 } 1153 }
1154 ruledata->serializers = max_channels;
1001 max_channels *= mcasp->tdm_slots; 1155 max_channels *= mcasp->tdm_slots;
1002 /* 1156 /*
1003 * If the already active stream has less channels than the calculated 1157 * If the already active stream has less channels than the calculated
@@ -1012,6 +1166,42 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
1012 snd_pcm_hw_constraint_minmax(substream->runtime, 1166 snd_pcm_hw_constraint_minmax(substream->runtime,
1013 SNDRV_PCM_HW_PARAM_CHANNELS, 1167 SNDRV_PCM_HW_PARAM_CHANNELS,
1014 2, max_channels); 1168 2, max_channels);
1169
1170 /*
1171 * If we rely on implicit BCLK divider setting we should
1172 * set constraints based on what we can provide.
1173 */
1174 if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) {
1175 int ret;
1176
1177 ruledata->mcasp = mcasp;
1178
1179 ret = snd_pcm_hw_rule_add(substream->runtime, 0,
1180 SNDRV_PCM_HW_PARAM_RATE,
1181 davinci_mcasp_hw_rule_rate,
1182 ruledata,
1183 SNDRV_PCM_HW_PARAM_FORMAT,
1184 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
1185 if (ret)
1186 return ret;
1187 ret = snd_pcm_hw_rule_add(substream->runtime, 0,
1188 SNDRV_PCM_HW_PARAM_FORMAT,
1189 davinci_mcasp_hw_rule_format,
1190 ruledata,
1191 SNDRV_PCM_HW_PARAM_RATE,
1192 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
1193 if (ret)
1194 return ret;
1195 ret = snd_pcm_hw_rule_add(substream->runtime, 0,
1196 SNDRV_PCM_HW_PARAM_CHANNELS,
1197 davinci_mcasp_hw_rule_channels,
1198 ruledata,
1199 SNDRV_PCM_HW_PARAM_RATE,
1200 SNDRV_PCM_HW_PARAM_FORMAT, -1);
1201 if (ret)
1202 return ret;
1203 }
1204
1015 return 0; 1205 return 0;
1016} 1206}
1017 1207
@@ -1043,17 +1233,8 @@ static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai)
1043{ 1233{
1044 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); 1234 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
1045 1235
1046 if (mcasp->version >= MCASP_VERSION_3) { 1236 dai->playback_dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
1047 /* Using dmaengine PCM */ 1237 dai->capture_dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE];
1048 dai->playback_dma_data =
1049 &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
1050 dai->capture_dma_data =
1051 &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE];
1052 } else {
1053 /* Using davinci-pcm */
1054 dai->playback_dma_data = mcasp->dma_params;
1055 dai->capture_dma_data = mcasp->dma_params;
1056 }
1057 1238
1058 return 0; 1239 return 0;
1059} 1240}
@@ -1066,6 +1247,10 @@ static int davinci_mcasp_suspend(struct snd_soc_dai *dai)
1066 u32 reg; 1247 u32 reg;
1067 int i; 1248 int i;
1068 1249
1250 context->pm_state = pm_runtime_enabled(mcasp->dev);
1251 if (!context->pm_state)
1252 pm_runtime_get_sync(mcasp->dev);
1253
1069 for (i = 0; i < ARRAY_SIZE(context_regs); i++) 1254 for (i = 0; i < ARRAY_SIZE(context_regs); i++)
1070 context->config_regs[i] = mcasp_get_reg(mcasp, context_regs[i]); 1255 context->config_regs[i] = mcasp_get_reg(mcasp, context_regs[i]);
1071 1256
@@ -1082,6 +1267,8 @@ static int davinci_mcasp_suspend(struct snd_soc_dai *dai)
1082 context->xrsr_regs[i] = mcasp_get_reg(mcasp, 1267 context->xrsr_regs[i] = mcasp_get_reg(mcasp,
1083 DAVINCI_MCASP_XRSRCTL_REG(i)); 1268 DAVINCI_MCASP_XRSRCTL_REG(i));
1084 1269
1270 pm_runtime_put_sync(mcasp->dev);
1271
1085 return 0; 1272 return 0;
1086} 1273}
1087 1274
@@ -1092,6 +1279,8 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai)
1092 u32 reg; 1279 u32 reg;
1093 int i; 1280 int i;
1094 1281
1282 pm_runtime_get_sync(mcasp->dev);
1283
1095 for (i = 0; i < ARRAY_SIZE(context_regs); i++) 1284 for (i = 0; i < ARRAY_SIZE(context_regs); i++)
1096 mcasp_set_reg(mcasp, context_regs[i], context->config_regs[i]); 1285 mcasp_set_reg(mcasp, context_regs[i], context->config_regs[i]);
1097 1286
@@ -1108,6 +1297,9 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai)
1108 mcasp_set_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i), 1297 mcasp_set_reg(mcasp, DAVINCI_MCASP_XRSRCTL_REG(i),
1109 context->xrsr_regs[i]); 1298 context->xrsr_regs[i]);
1110 1299
1300 if (!context->pm_state)
1301 pm_runtime_put_sync(mcasp->dev);
1302
1111 return 0; 1303 return 0;
1112} 1304}
1113#else 1305#else
@@ -1172,28 +1364,24 @@ static const struct snd_soc_component_driver davinci_mcasp_component = {
1172static struct davinci_mcasp_pdata dm646x_mcasp_pdata = { 1364static struct davinci_mcasp_pdata dm646x_mcasp_pdata = {
1173 .tx_dma_offset = 0x400, 1365 .tx_dma_offset = 0x400,
1174 .rx_dma_offset = 0x400, 1366 .rx_dma_offset = 0x400,
1175 .asp_chan_q = EVENTQ_0,
1176 .version = MCASP_VERSION_1, 1367 .version = MCASP_VERSION_1,
1177}; 1368};
1178 1369
1179static struct davinci_mcasp_pdata da830_mcasp_pdata = { 1370static struct davinci_mcasp_pdata da830_mcasp_pdata = {
1180 .tx_dma_offset = 0x2000, 1371 .tx_dma_offset = 0x2000,
1181 .rx_dma_offset = 0x2000, 1372 .rx_dma_offset = 0x2000,
1182 .asp_chan_q = EVENTQ_0,
1183 .version = MCASP_VERSION_2, 1373 .version = MCASP_VERSION_2,
1184}; 1374};
1185 1375
1186static struct davinci_mcasp_pdata am33xx_mcasp_pdata = { 1376static struct davinci_mcasp_pdata am33xx_mcasp_pdata = {
1187 .tx_dma_offset = 0, 1377 .tx_dma_offset = 0,
1188 .rx_dma_offset = 0, 1378 .rx_dma_offset = 0,
1189 .asp_chan_q = EVENTQ_0,
1190 .version = MCASP_VERSION_3, 1379 .version = MCASP_VERSION_3,
1191}; 1380};
1192 1381
1193static struct davinci_mcasp_pdata dra7_mcasp_pdata = { 1382static struct davinci_mcasp_pdata dra7_mcasp_pdata = {
1194 .tx_dma_offset = 0x200, 1383 .tx_dma_offset = 0x200,
1195 .rx_dma_offset = 0x284, 1384 .rx_dma_offset = 0x284,
1196 .asp_chan_q = EVENTQ_0,
1197 .version = MCASP_VERSION_4, 1385 .version = MCASP_VERSION_4,
1198}; 1386};
1199 1387
@@ -1370,12 +1558,12 @@ nodata:
1370 1558
1371static int davinci_mcasp_probe(struct platform_device *pdev) 1559static int davinci_mcasp_probe(struct platform_device *pdev)
1372{ 1560{
1373 struct davinci_pcm_dma_params *dma_params;
1374 struct snd_dmaengine_dai_dma_data *dma_data; 1561 struct snd_dmaengine_dai_dma_data *dma_data;
1375 struct resource *mem, *ioarea, *res, *dat; 1562 struct resource *mem, *ioarea, *res, *dat;
1376 struct davinci_mcasp_pdata *pdata; 1563 struct davinci_mcasp_pdata *pdata;
1377 struct davinci_mcasp *mcasp; 1564 struct davinci_mcasp *mcasp;
1378 char *irq_name; 1565 char *irq_name;
1566 int *dma;
1379 int irq; 1567 int irq;
1380 int ret; 1568 int ret;
1381 1569
@@ -1415,13 +1603,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1415 1603
1416 pm_runtime_enable(&pdev->dev); 1604 pm_runtime_enable(&pdev->dev);
1417 1605
1418 ret = pm_runtime_get_sync(&pdev->dev);
1419 if (IS_ERR_VALUE(ret)) {
1420 dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n");
1421 pm_runtime_disable(&pdev->dev);
1422 return ret;
1423 }
1424
1425 mcasp->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); 1606 mcasp->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
1426 if (!mcasp->base) { 1607 if (!mcasp->base) {
1427 dev_err(&pdev->dev, "ioremap failed\n"); 1608 dev_err(&pdev->dev, "ioremap failed\n");
@@ -1509,59 +1690,45 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1509 if (dat) 1690 if (dat)
1510 mcasp->dat_port = true; 1691 mcasp->dat_port = true;
1511 1692
1512 dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
1513 dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; 1693 dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
1514 dma_params->asp_chan_q = pdata->asp_chan_q;
1515 dma_params->ram_chan_q = pdata->ram_chan_q;
1516 dma_params->sram_pool = pdata->sram_pool;
1517 dma_params->sram_size = pdata->sram_size_playback;
1518 if (dat) 1694 if (dat)
1519 dma_params->dma_addr = dat->start; 1695 dma_data->addr = dat->start;
1520 else 1696 else
1521 dma_params->dma_addr = mem->start + pdata->tx_dma_offset; 1697 dma_data->addr = mem->start + pdata->tx_dma_offset;
1522
1523 /* Unconditional dmaengine stuff */
1524 dma_data->addr = dma_params->dma_addr;
1525 1698
1699 dma = &mcasp->dma_request[SNDRV_PCM_STREAM_PLAYBACK];
1526 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 1700 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
1527 if (res) 1701 if (res)
1528 dma_params->channel = res->start; 1702 *dma = res->start;
1529 else 1703 else
1530 dma_params->channel = pdata->tx_dma_channel; 1704 *dma = pdata->tx_dma_channel;
1531 1705
1532 /* dmaengine filter data for DT and non-DT boot */ 1706 /* dmaengine filter data for DT and non-DT boot */
1533 if (pdev->dev.of_node) 1707 if (pdev->dev.of_node)
1534 dma_data->filter_data = "tx"; 1708 dma_data->filter_data = "tx";
1535 else 1709 else
1536 dma_data->filter_data = &dma_params->channel; 1710 dma_data->filter_data = dma;
1537 1711
1538 /* RX is not valid in DIT mode */ 1712 /* RX is not valid in DIT mode */
1539 if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) { 1713 if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) {
1540 dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_CAPTURE];
1541 dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE]; 1714 dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE];
1542 dma_params->asp_chan_q = pdata->asp_chan_q;
1543 dma_params->ram_chan_q = pdata->ram_chan_q;
1544 dma_params->sram_pool = pdata->sram_pool;
1545 dma_params->sram_size = pdata->sram_size_capture;
1546 if (dat) 1715 if (dat)
1547 dma_params->dma_addr = dat->start; 1716 dma_data->addr = dat->start;
1548 else 1717 else
1549 dma_params->dma_addr = mem->start + pdata->rx_dma_offset; 1718 dma_data->addr = mem->start + pdata->rx_dma_offset;
1550
1551 /* Unconditional dmaengine stuff */
1552 dma_data->addr = dma_params->dma_addr;
1553 1719
1720 dma = &mcasp->dma_request[SNDRV_PCM_STREAM_CAPTURE];
1554 res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 1721 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
1555 if (res) 1722 if (res)
1556 dma_params->channel = res->start; 1723 *dma = res->start;
1557 else 1724 else
1558 dma_params->channel = pdata->rx_dma_channel; 1725 *dma = pdata->rx_dma_channel;
1559 1726
1560 /* dmaengine filter data for DT and non-DT boot */ 1727 /* dmaengine filter data for DT and non-DT boot */
1561 if (pdev->dev.of_node) 1728 if (pdev->dev.of_node)
1562 dma_data->filter_data = "rx"; 1729 dma_data->filter_data = "rx";
1563 else 1730 else
1564 dma_data->filter_data = &dma_params->channel; 1731 dma_data->filter_data = dma;
1565 } 1732 }
1566 1733
1567 if (mcasp->version < MCASP_VERSION_3) { 1734 if (mcasp->version < MCASP_VERSION_3) {
@@ -1584,17 +1751,11 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1584 goto err; 1751 goto err;
1585 1752
1586 switch (mcasp->version) { 1753 switch (mcasp->version) {
1587#if IS_BUILTIN(CONFIG_SND_DAVINCI_SOC) || \
1588 (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \
1589 IS_MODULE(CONFIG_SND_DAVINCI_SOC))
1590 case MCASP_VERSION_1:
1591 case MCASP_VERSION_2:
1592 ret = davinci_soc_platform_register(&pdev->dev);
1593 break;
1594#endif
1595#if IS_BUILTIN(CONFIG_SND_EDMA_SOC) || \ 1754#if IS_BUILTIN(CONFIG_SND_EDMA_SOC) || \
1596 (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \ 1755 (IS_MODULE(CONFIG_SND_DAVINCI_SOC_MCASP) && \
1597 IS_MODULE(CONFIG_SND_EDMA_SOC)) 1756 IS_MODULE(CONFIG_SND_EDMA_SOC))
1757 case MCASP_VERSION_1:
1758 case MCASP_VERSION_2:
1598 case MCASP_VERSION_3: 1759 case MCASP_VERSION_3:
1599 ret = edma_pcm_platform_register(&pdev->dev); 1760 ret = edma_pcm_platform_register(&pdev->dev);
1600 break; 1761 break;
@@ -1621,14 +1782,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1621 return 0; 1782 return 0;
1622 1783
1623err: 1784err:
1624 pm_runtime_put_sync(&pdev->dev);
1625 pm_runtime_disable(&pdev->dev); 1785 pm_runtime_disable(&pdev->dev);
1626 return ret; 1786 return ret;
1627} 1787}
1628 1788
1629static int davinci_mcasp_remove(struct platform_device *pdev) 1789static int davinci_mcasp_remove(struct platform_device *pdev)
1630{ 1790{
1631 pm_runtime_put_sync(&pdev->dev);
1632 pm_runtime_disable(&pdev->dev); 1791 pm_runtime_disable(&pdev->dev);
1633 1792
1634 return 0; 1793 return 0;
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
deleted file mode 100644
index 7809e9d935fc..000000000000
--- a/sound/soc/davinci/davinci-pcm.c
+++ /dev/null
@@ -1,861 +0,0 @@
1/*
2 * ALSA PCM interface for the TI DAVINCI processor
3 *
4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * added SRAM ping/pong (C) 2008 Troy Kisky <troy.kisky@boundarydevices.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/slab.h>
17#include <linux/dma-mapping.h>
18#include <linux/kernel.h>
19#include <linux/genalloc.h>
20#include <linux/platform_data/edma.h>
21
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26
27#include <asm/dma.h>
28
29#include "davinci-pcm.h"
30
31#ifdef DEBUG
32static void print_buf_info(int slot, char *name)
33{
34 struct edmacc_param p;
35 if (slot < 0)
36 return;
37 edma_read_slot(slot, &p);
38 printk(KERN_DEBUG "%s: 0x%x, opt=%x, src=%x, a_b_cnt=%x dst=%x\n",
39 name, slot, p.opt, p.src, p.a_b_cnt, p.dst);
40 printk(KERN_DEBUG " src_dst_bidx=%x link_bcntrld=%x src_dst_cidx=%x ccnt=%x\n",
41 p.src_dst_bidx, p.link_bcntrld, p.src_dst_cidx, p.ccnt);
42}
43#else
44static void print_buf_info(int slot, char *name)
45{
46}
47#endif
48
49static struct snd_pcm_hardware pcm_hardware_playback = {
50 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
51 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
52 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME|
53 SNDRV_PCM_INFO_BATCH),
54 .buffer_bytes_max = 128 * 1024,
55 .period_bytes_min = 32,
56 .period_bytes_max = 8 * 1024,
57 .periods_min = 16,
58 .periods_max = 255,
59 .fifo_size = 0,
60};
61
62static struct snd_pcm_hardware pcm_hardware_capture = {
63 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
64 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
65 SNDRV_PCM_INFO_PAUSE |
66 SNDRV_PCM_INFO_BATCH),
67 .buffer_bytes_max = 128 * 1024,
68 .period_bytes_min = 32,
69 .period_bytes_max = 8 * 1024,
70 .periods_min = 16,
71 .periods_max = 255,
72 .fifo_size = 0,
73};
74
75/*
76 * How ping/pong works....
77 *
78 * Playback:
79 * ram_params - copys 2*ping_size from start of SDRAM to iram,
80 * links to ram_link2
81 * ram_link2 - copys rest of SDRAM to iram in ping_size units,
82 * links to ram_link
83 * ram_link - copys entire SDRAM to iram in ping_size uints,
84 * links to self
85 *
86 * asp_params - same as asp_link[0]
87 * asp_link[0] - copys from lower half of iram to asp port
88 * links to asp_link[1], triggers iram copy event on completion
89 * asp_link[1] - copys from upper half of iram to asp port
90 * links to asp_link[0], triggers iram copy event on completion
91 * triggers interrupt only needed to let upper SOC levels update position
92 * in stream on completion
93 *
94 * When playback is started:
95 * ram_params started
96 * asp_params started
97 *
98 * Capture:
99 * ram_params - same as ram_link,
100 * links to ram_link
101 * ram_link - same as playback
102 * links to self
103 *
104 * asp_params - same as playback
105 * asp_link[0] - same as playback
106 * asp_link[1] - same as playback
107 *
108 * When capture is started:
109 * asp_params started
110 */
111struct davinci_runtime_data {
112 spinlock_t lock;
113 int period; /* current DMA period */
114 int asp_channel; /* Master DMA channel */
115 int asp_link[2]; /* asp parameter link channel, ping/pong */
116 struct davinci_pcm_dma_params *params; /* DMA params */
117 int ram_channel;
118 int ram_link;
119 int ram_link2;
120 struct edmacc_param asp_params;
121 struct edmacc_param ram_params;
122};
123
124static void davinci_pcm_period_elapsed(struct snd_pcm_substream *substream)
125{
126 struct davinci_runtime_data *prtd = substream->runtime->private_data;
127 struct snd_pcm_runtime *runtime = substream->runtime;
128
129 prtd->period++;
130 if (unlikely(prtd->period >= runtime->periods))
131 prtd->period = 0;
132}
133
134static void davinci_pcm_period_reset(struct snd_pcm_substream *substream)
135{
136 struct davinci_runtime_data *prtd = substream->runtime->private_data;
137
138 prtd->period = 0;
139}
140/*
141 * Not used with ping/pong
142 */
143static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
144{
145 struct davinci_runtime_data *prtd = substream->runtime->private_data;
146 struct snd_pcm_runtime *runtime = substream->runtime;
147 unsigned int period_size;
148 unsigned int dma_offset;
149 dma_addr_t dma_pos;
150 dma_addr_t src, dst;
151 unsigned short src_bidx, dst_bidx;
152 unsigned short src_cidx, dst_cidx;
153 unsigned int data_type;
154 unsigned short acnt;
155 unsigned int count;
156 unsigned int fifo_level;
157
158 period_size = snd_pcm_lib_period_bytes(substream);
159 dma_offset = prtd->period * period_size;
160 dma_pos = runtime->dma_addr + dma_offset;
161 fifo_level = prtd->params->fifo_level;
162
163 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
164 "dma_ptr = %x period_size=%x\n", prtd->asp_link[0], dma_pos,
165 period_size);
166
167 data_type = prtd->params->data_type;
168 count = period_size / data_type;
169 if (fifo_level)
170 count /= fifo_level;
171
172 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
173 src = dma_pos;
174 dst = prtd->params->dma_addr;
175 src_bidx = data_type;
176 dst_bidx = 4;
177 src_cidx = data_type * fifo_level;
178 dst_cidx = 0;
179 } else {
180 src = prtd->params->dma_addr;
181 dst = dma_pos;
182 src_bidx = 0;
183 dst_bidx = data_type;
184 src_cidx = 0;
185 dst_cidx = data_type * fifo_level;
186 }
187
188 acnt = prtd->params->acnt;
189 edma_set_src(prtd->asp_link[0], src, INCR, W8BIT);
190 edma_set_dest(prtd->asp_link[0], dst, INCR, W8BIT);
191
192 edma_set_src_index(prtd->asp_link[0], src_bidx, src_cidx);
193 edma_set_dest_index(prtd->asp_link[0], dst_bidx, dst_cidx);
194
195 if (!fifo_level)
196 edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0,
197 ASYNC);
198 else
199 edma_set_transfer_params(prtd->asp_link[0], acnt,
200 fifo_level,
201 count, fifo_level,
202 ABSYNC);
203}
204
205static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
206{
207 struct snd_pcm_substream *substream = data;
208 struct davinci_runtime_data *prtd = substream->runtime->private_data;
209
210 print_buf_info(prtd->ram_channel, "i ram_channel");
211 pr_debug("davinci_pcm: link=%d, status=0x%x\n", link, ch_status);
212
213 if (unlikely(ch_status != EDMA_DMA_COMPLETE))
214 return;
215
216 if (snd_pcm_running(substream)) {
217 spin_lock(&prtd->lock);
218 if (prtd->ram_channel < 0) {
219 /* No ping/pong must fix up link dma data*/
220 davinci_pcm_enqueue_dma(substream);
221 }
222 davinci_pcm_period_elapsed(substream);
223 spin_unlock(&prtd->lock);
224 snd_pcm_period_elapsed(substream);
225 }
226}
227
228#ifdef CONFIG_GENERIC_ALLOCATOR
229static int allocate_sram(struct snd_pcm_substream *substream,
230 struct gen_pool *sram_pool, unsigned size,
231 struct snd_pcm_hardware *ppcm)
232{
233 struct snd_dma_buffer *buf = &substream->dma_buffer;
234 struct snd_dma_buffer *iram_dma = NULL;
235 dma_addr_t iram_phys = 0;
236 void *iram_virt = NULL;
237
238 if (buf->private_data || !size)
239 return 0;
240
241 ppcm->period_bytes_max = size;
242 iram_virt = gen_pool_dma_alloc(sram_pool, size, &iram_phys);
243 if (!iram_virt)
244 goto exit1;
245 iram_dma = kzalloc(sizeof(*iram_dma), GFP_KERNEL);
246 if (!iram_dma)
247 goto exit2;
248 iram_dma->area = iram_virt;
249 iram_dma->addr = iram_phys;
250 memset(iram_dma->area, 0, size);
251 iram_dma->bytes = size;
252 buf->private_data = iram_dma;
253 return 0;
254exit2:
255 if (iram_virt)
256 gen_pool_free(sram_pool, (unsigned)iram_virt, size);
257exit1:
258 return -ENOMEM;
259}
260
261static void davinci_free_sram(struct snd_pcm_substream *substream,
262 struct snd_dma_buffer *iram_dma)
263{
264 struct davinci_runtime_data *prtd = substream->runtime->private_data;
265 struct gen_pool *sram_pool = prtd->params->sram_pool;
266
267 gen_pool_free(sram_pool, (unsigned) iram_dma->area, iram_dma->bytes);
268}
269#else
270static int allocate_sram(struct snd_pcm_substream *substream,
271 struct gen_pool *sram_pool, unsigned size,
272 struct snd_pcm_hardware *ppcm)
273{
274 return 0;
275}
276
277static void davinci_free_sram(struct snd_pcm_substream *substream,
278 struct snd_dma_buffer *iram_dma)
279{
280}
281#endif
282
283/*
284 * Only used with ping/pong.
285 * This is called after runtime->dma_addr, period_bytes and data_type are valid
286 */
287static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
288{
289 unsigned short ram_src_cidx, ram_dst_cidx;
290 struct snd_pcm_runtime *runtime = substream->runtime;
291 struct davinci_runtime_data *prtd = runtime->private_data;
292 struct snd_dma_buffer *iram_dma =
293 (struct snd_dma_buffer *)substream->dma_buffer.private_data;
294 struct davinci_pcm_dma_params *params = prtd->params;
295 unsigned int data_type = params->data_type;
296 unsigned int acnt = params->acnt;
297 /* divide by 2 for ping/pong */
298 unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1;
299 unsigned int fifo_level = prtd->params->fifo_level;
300 unsigned int count;
301 if ((data_type == 0) || (data_type > 4)) {
302 printk(KERN_ERR "%s: data_type=%i\n", __func__, data_type);
303 return -EINVAL;
304 }
305 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
306 dma_addr_t asp_src_pong = iram_dma->addr + ping_size;
307 ram_src_cidx = ping_size;
308 ram_dst_cidx = -ping_size;
309 edma_set_src(prtd->asp_link[1], asp_src_pong, INCR, W8BIT);
310
311 edma_set_src_index(prtd->asp_link[0], data_type,
312 data_type * fifo_level);
313 edma_set_src_index(prtd->asp_link[1], data_type,
314 data_type * fifo_level);
315
316 edma_set_src(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
317 } else {
318 dma_addr_t asp_dst_pong = iram_dma->addr + ping_size;
319 ram_src_cidx = -ping_size;
320 ram_dst_cidx = ping_size;
321 edma_set_dest(prtd->asp_link[1], asp_dst_pong, INCR, W8BIT);
322
323 edma_set_dest_index(prtd->asp_link[0], data_type,
324 data_type * fifo_level);
325 edma_set_dest_index(prtd->asp_link[1], data_type,
326 data_type * fifo_level);
327
328 edma_set_dest(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
329 }
330
331 if (!fifo_level) {
332 count = ping_size / data_type;
333 edma_set_transfer_params(prtd->asp_link[0], acnt, count,
334 1, 0, ASYNC);
335 edma_set_transfer_params(prtd->asp_link[1], acnt, count,
336 1, 0, ASYNC);
337 } else {
338 count = ping_size / (data_type * fifo_level);
339 edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level,
340 count, fifo_level, ABSYNC);
341 edma_set_transfer_params(prtd->asp_link[1], acnt, fifo_level,
342 count, fifo_level, ABSYNC);
343 }
344
345 edma_set_src_index(prtd->ram_link, ping_size, ram_src_cidx);
346 edma_set_dest_index(prtd->ram_link, ping_size, ram_dst_cidx);
347 edma_set_transfer_params(prtd->ram_link, ping_size, 2,
348 runtime->periods, 2, ASYNC);
349
350 /* init master params */
351 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
352 edma_read_slot(prtd->ram_link, &prtd->ram_params);
353 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
354 struct edmacc_param p_ram;
355 /* Copy entire iram buffer before playback started */
356 prtd->ram_params.a_b_cnt = (1 << 16) | (ping_size << 1);
357 /* 0 dst_bidx */
358 prtd->ram_params.src_dst_bidx = (ping_size << 1);
359 /* 0 dst_cidx */
360 prtd->ram_params.src_dst_cidx = (ping_size << 1);
361 prtd->ram_params.ccnt = 1;
362
363 /* Skip 1st period */
364 edma_read_slot(prtd->ram_link, &p_ram);
365 p_ram.src += (ping_size << 1);
366 p_ram.ccnt -= 1;
367 edma_write_slot(prtd->ram_link2, &p_ram);
368 /*
369 * When 1st started, ram -> iram dma channel will fill the
370 * entire iram. Then, whenever a ping/pong asp buffer finishes,
371 * 1/2 iram will be filled.
372 */
373 prtd->ram_params.link_bcntrld =
374 EDMA_CHAN_SLOT(prtd->ram_link2) << 5;
375 }
376 return 0;
377}
378
379/* 1 asp tx or rx channel using 2 parameter channels
380 * 1 ram to/from iram channel using 1 parameter channel
381 *
382 * Playback
383 * ram copy channel kicks off first,
384 * 1st ram copy of entire iram buffer completion kicks off asp channel
385 * asp tcc always kicks off ram copy of 1/2 iram buffer
386 *
387 * Record
388 * asp channel starts, tcc kicks off ram copy
389 */
390static int request_ping_pong(struct snd_pcm_substream *substream,
391 struct davinci_runtime_data *prtd,
392 struct snd_dma_buffer *iram_dma)
393{
394 dma_addr_t asp_src_ping;
395 dma_addr_t asp_dst_ping;
396 int ret;
397 struct davinci_pcm_dma_params *params = prtd->params;
398
399 /* Request ram master channel */
400 ret = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY,
401 davinci_pcm_dma_irq, substream,
402 prtd->params->ram_chan_q);
403 if (ret < 0)
404 goto exit1;
405
406 /* Request ram link channel */
407 ret = prtd->ram_link = edma_alloc_slot(
408 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
409 if (ret < 0)
410 goto exit2;
411
412 ret = prtd->asp_link[1] = edma_alloc_slot(
413 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
414 if (ret < 0)
415 goto exit3;
416
417 prtd->ram_link2 = -1;
418 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
419 ret = prtd->ram_link2 = edma_alloc_slot(
420 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
421 if (ret < 0)
422 goto exit4;
423 }
424 /* circle ping-pong buffers */
425 edma_link(prtd->asp_link[0], prtd->asp_link[1]);
426 edma_link(prtd->asp_link[1], prtd->asp_link[0]);
427 /* circle ram buffers */
428 edma_link(prtd->ram_link, prtd->ram_link);
429
430 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
431 asp_src_ping = iram_dma->addr;
432 asp_dst_ping = params->dma_addr; /* fifo */
433 } else {
434 asp_src_ping = params->dma_addr; /* fifo */
435 asp_dst_ping = iram_dma->addr;
436 }
437 /* ping */
438 edma_set_src(prtd->asp_link[0], asp_src_ping, INCR, W16BIT);
439 edma_set_dest(prtd->asp_link[0], asp_dst_ping, INCR, W16BIT);
440 edma_set_src_index(prtd->asp_link[0], 0, 0);
441 edma_set_dest_index(prtd->asp_link[0], 0, 0);
442
443 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
444 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN);
445 prtd->asp_params.opt |= TCCHEN |
446 EDMA_TCC(prtd->ram_channel & 0x3f);
447 edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
448
449 /* pong */
450 edma_set_src(prtd->asp_link[1], asp_src_ping, INCR, W16BIT);
451 edma_set_dest(prtd->asp_link[1], asp_dst_ping, INCR, W16BIT);
452 edma_set_src_index(prtd->asp_link[1], 0, 0);
453 edma_set_dest_index(prtd->asp_link[1], 0, 0);
454
455 edma_read_slot(prtd->asp_link[1], &prtd->asp_params);
456 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f));
457 /* interrupt after every pong completion */
458 prtd->asp_params.opt |= TCINTEN | TCCHEN |
459 EDMA_TCC(prtd->ram_channel & 0x3f);
460 edma_write_slot(prtd->asp_link[1], &prtd->asp_params);
461
462 /* ram */
463 edma_set_src(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
464 edma_set_dest(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
465 pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u,"
466 "for asp:%u %u %u\n", __func__,
467 prtd->ram_channel, prtd->ram_link, prtd->ram_link2,
468 prtd->asp_channel, prtd->asp_link[0],
469 prtd->asp_link[1]);
470 return 0;
471exit4:
472 edma_free_channel(prtd->asp_link[1]);
473 prtd->asp_link[1] = -1;
474exit3:
475 edma_free_channel(prtd->ram_link);
476 prtd->ram_link = -1;
477exit2:
478 edma_free_channel(prtd->ram_channel);
479 prtd->ram_channel = -1;
480exit1:
481 return ret;
482}
483
484static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
485{
486 struct snd_dma_buffer *iram_dma;
487 struct davinci_runtime_data *prtd = substream->runtime->private_data;
488 struct davinci_pcm_dma_params *params = prtd->params;
489 int ret;
490
491 if (!params)
492 return -ENODEV;
493
494 /* Request asp master DMA channel */
495 ret = prtd->asp_channel = edma_alloc_channel(params->channel,
496 davinci_pcm_dma_irq, substream,
497 prtd->params->asp_chan_q);
498 if (ret < 0)
499 goto exit1;
500
501 /* Request asp link channels */
502 ret = prtd->asp_link[0] = edma_alloc_slot(
503 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
504 if (ret < 0)
505 goto exit2;
506
507 iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data;
508 if (iram_dma) {
509 if (request_ping_pong(substream, prtd, iram_dma) == 0)
510 return 0;
511 printk(KERN_WARNING "%s: dma channel allocation failed,"
512 "not using sram\n", __func__);
513 }
514
515 /* Issue transfer completion IRQ when the channel completes a
516 * transfer, then always reload from the same slot (by a kind
517 * of loopback link). The completion IRQ handler will update
518 * the reload slot with a new buffer.
519 *
520 * REVISIT save p_ram here after setting up everything except
521 * the buffer and its length (ccnt) ... use it as a template
522 * so davinci_pcm_enqueue_dma() takes less time in IRQ.
523 */
524 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
525 prtd->asp_params.opt |= TCINTEN |
526 EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel));
527 prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(prtd->asp_link[0]) << 5;
528 edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
529 return 0;
530exit2:
531 edma_free_channel(prtd->asp_channel);
532 prtd->asp_channel = -1;
533exit1:
534 return ret;
535}
536
537static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
538{
539 struct davinci_runtime_data *prtd = substream->runtime->private_data;
540 int ret = 0;
541
542 spin_lock(&prtd->lock);
543
544 switch (cmd) {
545 case SNDRV_PCM_TRIGGER_START:
546 edma_start(prtd->asp_channel);
547 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
548 prtd->ram_channel >= 0) {
549 /* copy 1st iram buffer */
550 edma_start(prtd->ram_channel);
551 }
552 break;
553 case SNDRV_PCM_TRIGGER_RESUME:
554 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
555 edma_resume(prtd->asp_channel);
556 break;
557 case SNDRV_PCM_TRIGGER_STOP:
558 case SNDRV_PCM_TRIGGER_SUSPEND:
559 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
560 edma_pause(prtd->asp_channel);
561 break;
562 default:
563 ret = -EINVAL;
564 break;
565 }
566
567 spin_unlock(&prtd->lock);
568
569 return ret;
570}
571
572static int davinci_pcm_prepare(struct snd_pcm_substream *substream)
573{
574 struct davinci_runtime_data *prtd = substream->runtime->private_data;
575
576 davinci_pcm_period_reset(substream);
577 if (prtd->ram_channel >= 0) {
578 int ret = ping_pong_dma_setup(substream);
579 if (ret < 0)
580 return ret;
581
582 edma_write_slot(prtd->ram_channel, &prtd->ram_params);
583 edma_write_slot(prtd->asp_channel, &prtd->asp_params);
584
585 print_buf_info(prtd->ram_channel, "ram_channel");
586 print_buf_info(prtd->ram_link, "ram_link");
587 print_buf_info(prtd->ram_link2, "ram_link2");
588 print_buf_info(prtd->asp_channel, "asp_channel");
589 print_buf_info(prtd->asp_link[0], "asp_link[0]");
590 print_buf_info(prtd->asp_link[1], "asp_link[1]");
591
592 /*
593 * There is a phase offset of 2 periods between the position
594 * used by dma setup and the position reported in the pointer
595 * function.
596 *
597 * The phase offset, when not using ping-pong buffers, is due to
598 * the two consecutive calls to davinci_pcm_enqueue_dma() below.
599 *
600 * Whereas here, with ping-pong buffers, the phase is due to
601 * there being an entire buffer transfer complete before the
602 * first dma completion event triggers davinci_pcm_dma_irq().
603 */
604 davinci_pcm_period_elapsed(substream);
605 davinci_pcm_period_elapsed(substream);
606
607 return 0;
608 }
609 davinci_pcm_enqueue_dma(substream);
610 davinci_pcm_period_elapsed(substream);
611
612 /* Copy self-linked parameter RAM entry into master channel */
613 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
614 edma_write_slot(prtd->asp_channel, &prtd->asp_params);
615 davinci_pcm_enqueue_dma(substream);
616 davinci_pcm_period_elapsed(substream);
617
618 return 0;
619}
620
621static snd_pcm_uframes_t
622davinci_pcm_pointer(struct snd_pcm_substream *substream)
623{
624 struct snd_pcm_runtime *runtime = substream->runtime;
625 struct davinci_runtime_data *prtd = runtime->private_data;
626 unsigned int offset;
627 int asp_count;
628 unsigned int period_size = snd_pcm_lib_period_bytes(substream);
629
630 /*
631 * There is a phase offset of 2 periods between the position used by dma
632 * setup and the position reported in the pointer function. Either +2 in
633 * the dma setup or -2 here in the pointer function (with wrapping,
634 * both) accounts for this offset -- choose the latter since it makes
635 * the first-time setup clearer.
636 */
637 spin_lock(&prtd->lock);
638 asp_count = prtd->period - 2;
639 spin_unlock(&prtd->lock);
640
641 if (asp_count < 0)
642 asp_count += runtime->periods;
643 asp_count *= period_size;
644
645 offset = bytes_to_frames(runtime, asp_count);
646 if (offset >= runtime->buffer_size)
647 offset = 0;
648
649 return offset;
650}
651
652static int davinci_pcm_open(struct snd_pcm_substream *substream)
653{
654 struct snd_pcm_runtime *runtime = substream->runtime;
655 struct davinci_runtime_data *prtd;
656 struct snd_pcm_hardware *ppcm;
657 int ret = 0;
658 struct snd_soc_pcm_runtime *rtd = substream->private_data;
659 struct davinci_pcm_dma_params *pa;
660 struct davinci_pcm_dma_params *params;
661
662 pa = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
663 if (!pa)
664 return -ENODEV;
665 params = &pa[substream->stream];
666
667 ppcm = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
668 &pcm_hardware_playback : &pcm_hardware_capture;
669 allocate_sram(substream, params->sram_pool, params->sram_size, ppcm);
670 snd_soc_set_runtime_hwparams(substream, ppcm);
671 /* ensure that buffer size is a multiple of period size */
672 ret = snd_pcm_hw_constraint_integer(runtime,
673 SNDRV_PCM_HW_PARAM_PERIODS);
674 if (ret < 0)
675 return ret;
676
677 prtd = kzalloc(sizeof(struct davinci_runtime_data), GFP_KERNEL);
678 if (prtd == NULL)
679 return -ENOMEM;
680
681 spin_lock_init(&prtd->lock);
682 prtd->params = params;
683 prtd->asp_channel = -1;
684 prtd->asp_link[0] = prtd->asp_link[1] = -1;
685 prtd->ram_channel = -1;
686 prtd->ram_link = -1;
687 prtd->ram_link2 = -1;
688
689 runtime->private_data = prtd;
690
691 ret = davinci_pcm_dma_request(substream);
692 if (ret) {
693 printk(KERN_ERR "davinci_pcm: Failed to get dma channels\n");
694 kfree(prtd);
695 }
696
697 return ret;
698}
699
700static int davinci_pcm_close(struct snd_pcm_substream *substream)
701{
702 struct snd_pcm_runtime *runtime = substream->runtime;
703 struct davinci_runtime_data *prtd = runtime->private_data;
704
705 if (prtd->ram_channel >= 0)
706 edma_stop(prtd->ram_channel);
707 if (prtd->asp_channel >= 0)
708 edma_stop(prtd->asp_channel);
709 if (prtd->asp_link[0] >= 0)
710 edma_unlink(prtd->asp_link[0]);
711 if (prtd->asp_link[1] >= 0)
712 edma_unlink(prtd->asp_link[1]);
713 if (prtd->ram_link >= 0)
714 edma_unlink(prtd->ram_link);
715
716 if (prtd->asp_link[0] >= 0)
717 edma_free_slot(prtd->asp_link[0]);
718 if (prtd->asp_link[1] >= 0)
719 edma_free_slot(prtd->asp_link[1]);
720 if (prtd->asp_channel >= 0)
721 edma_free_channel(prtd->asp_channel);
722 if (prtd->ram_link >= 0)
723 edma_free_slot(prtd->ram_link);
724 if (prtd->ram_link2 >= 0)
725 edma_free_slot(prtd->ram_link2);
726 if (prtd->ram_channel >= 0)
727 edma_free_channel(prtd->ram_channel);
728
729 kfree(prtd);
730
731 return 0;
732}
733
734static int davinci_pcm_hw_params(struct snd_pcm_substream *substream,
735 struct snd_pcm_hw_params *hw_params)
736{
737 return snd_pcm_lib_malloc_pages(substream,
738 params_buffer_bytes(hw_params));
739}
740
741static int davinci_pcm_hw_free(struct snd_pcm_substream *substream)
742{
743 return snd_pcm_lib_free_pages(substream);
744}
745
746static int davinci_pcm_mmap(struct snd_pcm_substream *substream,
747 struct vm_area_struct *vma)
748{
749 struct snd_pcm_runtime *runtime = substream->runtime;
750
751 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
752 runtime->dma_area,
753 runtime->dma_addr,
754 runtime->dma_bytes);
755}
756
757static struct snd_pcm_ops davinci_pcm_ops = {
758 .open = davinci_pcm_open,
759 .close = davinci_pcm_close,
760 .ioctl = snd_pcm_lib_ioctl,
761 .hw_params = davinci_pcm_hw_params,
762 .hw_free = davinci_pcm_hw_free,
763 .prepare = davinci_pcm_prepare,
764 .trigger = davinci_pcm_trigger,
765 .pointer = davinci_pcm_pointer,
766 .mmap = davinci_pcm_mmap,
767};
768
769static int davinci_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream,
770 size_t size)
771{
772 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
773 struct snd_dma_buffer *buf = &substream->dma_buffer;
774
775 buf->dev.type = SNDRV_DMA_TYPE_DEV;
776 buf->dev.dev = pcm->card->dev;
777 buf->private_data = NULL;
778 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
779 &buf->addr, GFP_KERNEL);
780
781 pr_debug("davinci_pcm: preallocate_dma_buffer: area=%p, addr=%p, "
782 "size=%d\n", (void *) buf->area, (void *) buf->addr, size);
783
784 if (!buf->area)
785 return -ENOMEM;
786
787 buf->bytes = size;
788 return 0;
789}
790
791static void davinci_pcm_free(struct snd_pcm *pcm)
792{
793 struct snd_pcm_substream *substream;
794 struct snd_dma_buffer *buf;
795 int stream;
796
797 for (stream = 0; stream < 2; stream++) {
798 struct snd_dma_buffer *iram_dma;
799 substream = pcm->streams[stream].substream;
800 if (!substream)
801 continue;
802
803 buf = &substream->dma_buffer;
804 if (!buf->area)
805 continue;
806
807 dma_free_writecombine(pcm->card->dev, buf->bytes,
808 buf->area, buf->addr);
809 buf->area = NULL;
810 iram_dma = buf->private_data;
811 if (iram_dma) {
812 davinci_free_sram(substream, iram_dma);
813 kfree(iram_dma);
814 }
815 }
816}
817
818static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd)
819{
820 struct snd_card *card = rtd->card->snd_card;
821 struct snd_pcm *pcm = rtd->pcm;
822 int ret;
823
824 ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
825 if (ret)
826 return ret;
827
828 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
829 ret = davinci_pcm_preallocate_dma_buffer(pcm,
830 SNDRV_PCM_STREAM_PLAYBACK,
831 pcm_hardware_playback.buffer_bytes_max);
832 if (ret)
833 return ret;
834 }
835
836 if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
837 ret = davinci_pcm_preallocate_dma_buffer(pcm,
838 SNDRV_PCM_STREAM_CAPTURE,
839 pcm_hardware_capture.buffer_bytes_max);
840 if (ret)
841 return ret;
842 }
843
844 return 0;
845}
846
847static struct snd_soc_platform_driver davinci_soc_platform = {
848 .ops = &davinci_pcm_ops,
849 .pcm_new = davinci_pcm_new,
850 .pcm_free = davinci_pcm_free,
851};
852
853int davinci_soc_platform_register(struct device *dev)
854{
855 return devm_snd_soc_register_platform(dev, &davinci_soc_platform);
856}
857EXPORT_SYMBOL_GPL(davinci_soc_platform_register);
858
859MODULE_AUTHOR("Vladimir Barinov");
860MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
861MODULE_LICENSE("GPL");
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
deleted file mode 100644
index 0fe2346a9aa2..000000000000
--- a/sound/soc/davinci/davinci-pcm.h
+++ /dev/null
@@ -1,41 +0,0 @@
1/*
2 * ALSA PCM interface for the TI DAVINCI processor
3 *
4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef _DAVINCI_PCM_H
13#define _DAVINCI_PCM_H
14
15#include <linux/genalloc.h>
16#include <linux/platform_data/davinci_asp.h>
17#include <linux/platform_data/edma.h>
18
19struct davinci_pcm_dma_params {
20 int channel; /* sync dma channel ID */
21 unsigned short acnt;
22 dma_addr_t dma_addr; /* device physical address for DMA */
23 unsigned sram_size;
24 struct gen_pool *sram_pool; /* SRAM gen_pool for ping pong */
25 enum dma_event_q asp_chan_q; /* event queue number for ASP channel */
26 enum dma_event_q ram_chan_q; /* event queue number for RAM channel */
27 unsigned char data_type; /* xfer data type */
28 unsigned char convert_mono_stereo;
29 unsigned int fifo_level;
30};
31
32#if IS_ENABLED(CONFIG_SND_DAVINCI_SOC)
33int davinci_soc_platform_register(struct device *dev);
34#else
35static inline int davinci_soc_platform_register(struct device *dev)
36{
37 return 0;
38}
39#endif /* CONFIG_SND_DAVINCI_SOC */
40
41#endif
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c
index 5bee04279ebe..fabd05f24aeb 100644
--- a/sound/soc/davinci/davinci-vcif.c
+++ b/sound/soc/davinci/davinci-vcif.c
@@ -33,8 +33,9 @@
33#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
34#include <sound/initval.h> 34#include <sound/initval.h>
35#include <sound/soc.h> 35#include <sound/soc.h>
36#include <sound/dmaengine_pcm.h>
36 37
37#include "davinci-pcm.h" 38#include "edma-pcm.h"
38#include "davinci-i2s.h" 39#include "davinci-i2s.h"
39 40
40#define MOD_REG_BIT(val, mask, set) do { \ 41#define MOD_REG_BIT(val, mask, set) do { \
@@ -47,7 +48,8 @@
47 48
48struct davinci_vcif_dev { 49struct davinci_vcif_dev {
49 struct davinci_vc *davinci_vc; 50 struct davinci_vc *davinci_vc;
50 struct davinci_pcm_dma_params dma_params[2]; 51 struct snd_dmaengine_dai_dma_data dma_data[2];
52 int dma_request[2];
51}; 53};
52 54
53static void davinci_vcif_start(struct snd_pcm_substream *substream) 55static void davinci_vcif_start(struct snd_pcm_substream *substream)
@@ -93,8 +95,6 @@ static int davinci_vcif_hw_params(struct snd_pcm_substream *substream,
93{ 95{
94 struct davinci_vcif_dev *davinci_vcif_dev = snd_soc_dai_get_drvdata(dai); 96 struct davinci_vcif_dev *davinci_vcif_dev = snd_soc_dai_get_drvdata(dai);
95 struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc; 97 struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc;
96 struct davinci_pcm_dma_params *dma_params =
97 &davinci_vcif_dev->dma_params[substream->stream];
98 u32 w; 98 u32 w;
99 99
100 /* Restart the codec before setup */ 100 /* Restart the codec before setup */
@@ -113,16 +113,12 @@ static int davinci_vcif_hw_params(struct snd_pcm_substream *substream,
113 /* Determine xfer data type */ 113 /* Determine xfer data type */
114 switch (params_format(params)) { 114 switch (params_format(params)) {
115 case SNDRV_PCM_FORMAT_U8: 115 case SNDRV_PCM_FORMAT_U8:
116 dma_params->data_type = 0;
117
118 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 | 116 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 |
119 DAVINCI_VC_CTRL_RD_UNSIGNED | 117 DAVINCI_VC_CTRL_RD_UNSIGNED |
120 DAVINCI_VC_CTRL_WD_BITS_8 | 118 DAVINCI_VC_CTRL_WD_BITS_8 |
121 DAVINCI_VC_CTRL_WD_UNSIGNED, 1); 119 DAVINCI_VC_CTRL_WD_UNSIGNED, 1);
122 break; 120 break;
123 case SNDRV_PCM_FORMAT_S8: 121 case SNDRV_PCM_FORMAT_S8:
124 dma_params->data_type = 1;
125
126 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 | 122 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 |
127 DAVINCI_VC_CTRL_WD_BITS_8, 1); 123 DAVINCI_VC_CTRL_WD_BITS_8, 1);
128 124
@@ -130,8 +126,6 @@ static int davinci_vcif_hw_params(struct snd_pcm_substream *substream,
130 DAVINCI_VC_CTRL_WD_UNSIGNED, 0); 126 DAVINCI_VC_CTRL_WD_UNSIGNED, 0);
131 break; 127 break;
132 case SNDRV_PCM_FORMAT_S16_LE: 128 case SNDRV_PCM_FORMAT_S16_LE:
133 dma_params->data_type = 2;
134
135 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 | 129 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 |
136 DAVINCI_VC_CTRL_RD_UNSIGNED | 130 DAVINCI_VC_CTRL_RD_UNSIGNED |
137 DAVINCI_VC_CTRL_WD_BITS_8 | 131 DAVINCI_VC_CTRL_WD_BITS_8 |
@@ -142,8 +136,6 @@ static int davinci_vcif_hw_params(struct snd_pcm_substream *substream,
142 return -EINVAL; 136 return -EINVAL;
143 } 137 }
144 138
145 dma_params->acnt = dma_params->data_type;
146
147 writel(w, davinci_vc->base + DAVINCI_VC_CTRL); 139 writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
148 140
149 return 0; 141 return 0;
@@ -172,24 +164,25 @@ static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd,
172 return ret; 164 return ret;
173} 165}
174 166
175static int davinci_vcif_startup(struct snd_pcm_substream *substream,
176 struct snd_soc_dai *dai)
177{
178 struct davinci_vcif_dev *dev = snd_soc_dai_get_drvdata(dai);
179
180 snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
181 return 0;
182}
183
184#define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000 167#define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000
185 168
186static const struct snd_soc_dai_ops davinci_vcif_dai_ops = { 169static const struct snd_soc_dai_ops davinci_vcif_dai_ops = {
187 .startup = davinci_vcif_startup,
188 .trigger = davinci_vcif_trigger, 170 .trigger = davinci_vcif_trigger,
189 .hw_params = davinci_vcif_hw_params, 171 .hw_params = davinci_vcif_hw_params,
190}; 172};
191 173
174static int davinci_vcif_dai_probe(struct snd_soc_dai *dai)
175{
176 struct davinci_vcif_dev *dev = snd_soc_dai_get_drvdata(dai);
177
178 dai->playback_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK];
179 dai->capture_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE];
180
181 return 0;
182}
183
192static struct snd_soc_dai_driver davinci_vcif_dai = { 184static struct snd_soc_dai_driver davinci_vcif_dai = {
185 .probe = davinci_vcif_dai_probe,
193 .playback = { 186 .playback = {
194 .channels_min = 1, 187 .channels_min = 1,
195 .channels_max = 2, 188 .channels_max = 2,
@@ -225,16 +218,16 @@ static int davinci_vcif_probe(struct platform_device *pdev)
225 218
226 /* DMA tx params */ 219 /* DMA tx params */
227 davinci_vcif_dev->davinci_vc = davinci_vc; 220 davinci_vcif_dev->davinci_vc = davinci_vc;
228 davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = 221 davinci_vcif_dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data =
229 davinci_vc->davinci_vcif.dma_tx_channel; 222 &davinci_vc->davinci_vcif.dma_tx_channel;
230 davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr = 223 davinci_vcif_dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr =
231 davinci_vc->davinci_vcif.dma_tx_addr; 224 davinci_vc->davinci_vcif.dma_tx_addr;
232 225
233 /* DMA rx params */ 226 /* DMA rx params */
234 davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = 227 davinci_vcif_dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data =
235 davinci_vc->davinci_vcif.dma_rx_channel; 228 &davinci_vc->davinci_vcif.dma_rx_channel;
236 davinci_vcif_dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr = 229 davinci_vcif_dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr =
237 davinci_vc->davinci_vcif.dma_rx_addr; 230 davinci_vc->davinci_vcif.dma_rx_addr;
238 231
239 dev_set_drvdata(&pdev->dev, davinci_vcif_dev); 232 dev_set_drvdata(&pdev->dev, davinci_vcif_dev);
240 233
@@ -245,7 +238,7 @@ static int davinci_vcif_probe(struct platform_device *pdev)
245 return ret; 238 return ret;
246 } 239 }
247 240
248 ret = davinci_soc_platform_register(&pdev->dev); 241 ret = edma_pcm_platform_register(&pdev->dev);
249 if (ret) { 242 if (ret) {
250 dev_err(&pdev->dev, "register PCM failed: %d\n", ret); 243 dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
251 snd_soc_unregister_component(&pdev->dev); 244 snd_soc_unregister_component(&pdev->dev);
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 081e406b3713..19c302b0d763 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -24,7 +24,7 @@ config SND_SOC_FSL_SAI
24 in-tree drivers select it automatically. 24 in-tree drivers select it automatically.
25 25
26config SND_SOC_FSL_SSI 26config SND_SOC_FSL_SSI
27 tristate "Synchronous Serial Interface module support" 27 tristate "Synchronous Serial Interface module (SSI) support"
28 select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n 28 select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
29 select SND_SOC_IMX_PCM_FIQ if SND_IMX_SOC != n && (MXC_TZIC || MXC_AVIC) 29 select SND_SOC_IMX_PCM_FIQ if SND_IMX_SOC != n && (MXC_TZIC || MXC_AVIC)
30 select REGMAP_MMIO 30 select REGMAP_MMIO
@@ -35,7 +35,7 @@ config SND_SOC_FSL_SSI
35 in-tree drivers select it automatically. 35 in-tree drivers select it automatically.
36 36
37config SND_SOC_FSL_SPDIF 37config SND_SOC_FSL_SPDIF
38 tristate "Sony/Philips Digital Interface module support" 38 tristate "Sony/Philips Digital Interface (S/PDIF) module support"
39 select REGMAP_MMIO 39 select REGMAP_MMIO
40 select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n 40 select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
41 select SND_SOC_IMX_PCM_FIQ if SND_IMX_SOC != n && (MXC_TZIC || MXC_AVIC) 41 select SND_SOC_IMX_PCM_FIQ if SND_IMX_SOC != n && (MXC_TZIC || MXC_AVIC)
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 3f6959c8e2f7..de438871040b 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -512,6 +512,12 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
512 memcpy(priv->dai_link, fsl_asoc_card_dai, 512 memcpy(priv->dai_link, fsl_asoc_card_dai,
513 sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link)); 513 sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link));
514 514
515 ret = snd_soc_of_parse_audio_routing(&priv->card, "audio-routing");
516 if (ret) {
517 dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret);
518 goto asrc_fail;
519 }
520
515 /* Normal DAI Link */ 521 /* Normal DAI Link */
516 priv->dai_link[0].cpu_of_node = cpu_np; 522 priv->dai_link[0].cpu_of_node = cpu_np;
517 priv->dai_link[0].codec_of_node = codec_np; 523 priv->dai_link[0].codec_of_node = codec_np;
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 6b0c8f717ec2..e8bb8eef1d16 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -1288,7 +1288,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1288 const struct of_device_id *of_id; 1288 const struct of_device_id *of_id;
1289 const char *p, *sprop; 1289 const char *p, *sprop;
1290 const uint32_t *iprop; 1290 const uint32_t *iprop;
1291 struct resource res; 1291 struct resource *res;
1292 void __iomem *iomem; 1292 void __iomem *iomem;
1293 char name[64]; 1293 char name[64];
1294 1294
@@ -1335,19 +1335,11 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1335 } 1335 }
1336 ssi_private->cpu_dai_drv.name = dev_name(&pdev->dev); 1336 ssi_private->cpu_dai_drv.name = dev_name(&pdev->dev);
1337 1337
1338 /* Get the addresses and IRQ */ 1338 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1339 ret = of_address_to_resource(np, 0, &res); 1339 iomem = devm_ioremap_resource(&pdev->dev, res);
1340 if (ret) { 1340 if (IS_ERR(iomem))
1341 dev_err(&pdev->dev, "could not determine device resources\n"); 1341 return PTR_ERR(iomem);
1342 return ret; 1342 ssi_private->ssi_phys = res->start;
1343 }
1344 ssi_private->ssi_phys = res.start;
1345
1346 iomem = devm_ioremap(&pdev->dev, res.start, resource_size(&res));
1347 if (!iomem) {
1348 dev_err(&pdev->dev, "could not map device resources\n");
1349 return -ENOMEM;
1350 }
1351 1343
1352 ret = of_property_match_string(np, "clock-names", "ipg"); 1344 ret = of_property_match_string(np, "clock-names", "ipg");
1353 if (ret < 0) { 1345 if (ret < 0) {
@@ -1393,8 +1385,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1393 return ret; 1385 return ret;
1394 } 1386 }
1395 1387
1396 ret = snd_soc_register_component(&pdev->dev, &fsl_ssi_component, 1388 ret = devm_snd_soc_register_component(&pdev->dev, &fsl_ssi_component,
1397 &ssi_private->cpu_dai_drv, 1); 1389 &ssi_private->cpu_dai_drv, 1);
1398 if (ret) { 1390 if (ret) {
1399 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); 1391 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
1400 goto error_asoc_register; 1392 goto error_asoc_register;
@@ -1407,13 +1399,13 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1407 if (ret < 0) { 1399 if (ret < 0) {
1408 dev_err(&pdev->dev, "could not claim irq %u\n", 1400 dev_err(&pdev->dev, "could not claim irq %u\n",
1409 ssi_private->irq); 1401 ssi_private->irq);
1410 goto error_irq; 1402 goto error_asoc_register;
1411 } 1403 }
1412 } 1404 }
1413 1405
1414 ret = fsl_ssi_debugfs_create(&ssi_private->dbg_stats, &pdev->dev); 1406 ret = fsl_ssi_debugfs_create(&ssi_private->dbg_stats, &pdev->dev);
1415 if (ret) 1407 if (ret)
1416 goto error_irq; 1408 goto error_asoc_register;
1417 1409
1418 /* 1410 /*
1419 * If codec-handle property is missing from SSI node, we assume 1411 * If codec-handle property is missing from SSI node, we assume
@@ -1454,9 +1446,6 @@ done:
1454error_sound_card: 1446error_sound_card:
1455 fsl_ssi_debugfs_remove(&ssi_private->dbg_stats); 1447 fsl_ssi_debugfs_remove(&ssi_private->dbg_stats);
1456 1448
1457error_irq:
1458 snd_soc_unregister_component(&pdev->dev);
1459
1460error_asoc_register: 1449error_asoc_register:
1461 if (ssi_private->soc->imx) 1450 if (ssi_private->soc->imx)
1462 fsl_ssi_imx_clean(pdev, ssi_private); 1451 fsl_ssi_imx_clean(pdev, ssi_private);
@@ -1472,7 +1461,6 @@ static int fsl_ssi_remove(struct platform_device *pdev)
1472 1461
1473 if (ssi_private->pdev) 1462 if (ssi_private->pdev)
1474 platform_device_unregister(ssi_private->pdev); 1463 platform_device_unregister(ssi_private->pdev);
1475 snd_soc_unregister_component(&pdev->dev);
1476 1464
1477 if (ssi_private->soc->imx) 1465 if (ssi_private->soc->imx)
1478 fsl_ssi_imx_clean(pdev, ssi_private); 1466 fsl_ssi_imx_clean(pdev, ssi_private);
diff --git a/sound/soc/fsl/imx-es8328.c b/sound/soc/fsl/imx-es8328.c
index f8cf10e16ce9..20e7400e2611 100644
--- a/sound/soc/fsl/imx-es8328.c
+++ b/sound/soc/fsl/imx-es8328.c
@@ -53,9 +53,9 @@ static int imx_es8328_dai_init(struct snd_soc_pcm_runtime *rtd)
53 53
54 /* Headphone jack detection */ 54 /* Headphone jack detection */
55 if (gpio_is_valid(data->jack_gpio)) { 55 if (gpio_is_valid(data->jack_gpio)) {
56 ret = snd_soc_jack_new(rtd->codec, "Headphone", 56 ret = snd_soc_card_jack_new(rtd->card, "Headphone",
57 SND_JACK_HEADPHONE | SND_JACK_BTN_0, 57 SND_JACK_HEADPHONE | SND_JACK_BTN_0,
58 &headset_jack); 58 &headset_jack, NULL, 0);
59 if (ret) 59 if (ret)
60 return ret; 60 return ret;
61 61
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index 08d2a8069b0a..0bab76051fd8 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -326,7 +326,7 @@ static int psc_ac97_of_remove(struct platform_device *op)
326} 326}
327 327
328/* Match table for of_platform binding */ 328/* Match table for of_platform binding */
329static struct of_device_id psc_ac97_match[] = { 329static const struct of_device_id psc_ac97_match[] = {
330 { .compatible = "fsl,mpc5200-psc-ac97", }, 330 { .compatible = "fsl,mpc5200-psc-ac97", },
331 { .compatible = "fsl,mpc5200b-psc-ac97", }, 331 { .compatible = "fsl,mpc5200b-psc-ac97", },
332 {} 332 {}
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 51fb0c00fe73..d8232943ccb6 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -217,7 +217,7 @@ static int psc_i2s_of_remove(struct platform_device *op)
217} 217}
218 218
219/* Match table for of_platform binding */ 219/* Match table for of_platform binding */
220static struct of_device_id psc_i2s_match[] = { 220static const struct of_device_id psc_i2s_match[] = {
221 { .compatible = "fsl,mpc5200-psc-i2s", }, 221 { .compatible = "fsl,mpc5200-psc-i2s", },
222 { .compatible = "fsl,mpc5200b-psc-i2s", }, 222 { .compatible = "fsl,mpc5200b-psc-i2s", },
223 {} 223 {}
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c
index c44459d24c50..ec731223cab3 100644
--- a/sound/soc/fsl/pcm030-audio-fabric.c
+++ b/sound/soc/fsl/pcm030-audio-fabric.c
@@ -113,7 +113,7 @@ static int pcm030_fabric_remove(struct platform_device *op)
113 return ret; 113 return ret;
114} 114}
115 115
116static struct of_device_id pcm030_audio_match[] = { 116static const struct of_device_id pcm030_audio_match[] = {
117 { .compatible = "phytec,pcm030-audio-fabric", }, 117 { .compatible = "phytec,pcm030-audio-fabric", },
118 {} 118 {}
119}; 119};
diff --git a/sound/soc/fsl/wm1133-ev1.c b/sound/soc/fsl/wm1133-ev1.c
index a958937ab405..b454972dce35 100644
--- a/sound/soc/fsl/wm1133-ev1.c
+++ b/sound/soc/fsl/wm1133-ev1.c
@@ -202,23 +202,20 @@ static struct snd_soc_jack_pin mic_jack_pins[] = {
202static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd) 202static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
203{ 203{
204 struct snd_soc_codec *codec = rtd->codec; 204 struct snd_soc_codec *codec = rtd->codec;
205 struct snd_soc_dapm_context *dapm = &codec->dapm;
206 205
207 /* Headphone jack detection */ 206 /* Headphone jack detection */
208 snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, &hp_jack); 207 snd_soc_card_jack_new(rtd->card, "Headphone", SND_JACK_HEADPHONE,
209 snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins), 208 &hp_jack, hp_jack_pins, ARRAY_SIZE(hp_jack_pins));
210 hp_jack_pins);
211 wm8350_hp_jack_detect(codec, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE); 209 wm8350_hp_jack_detect(codec, WM8350_JDR, &hp_jack, SND_JACK_HEADPHONE);
212 210
213 /* Microphone jack detection */ 211 /* Microphone jack detection */
214 snd_soc_jack_new(codec, "Microphone", 212 snd_soc_card_jack_new(rtd->card, "Microphone",
215 SND_JACK_MICROPHONE | SND_JACK_BTN_0, &mic_jack); 213 SND_JACK_MICROPHONE | SND_JACK_BTN_0, &mic_jack,
216 snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins), 214 mic_jack_pins, ARRAY_SIZE(mic_jack_pins));
217 mic_jack_pins);
218 wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE, 215 wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE,
219 SND_JACK_BTN_0); 216 SND_JACK_BTN_0);
220 217
221 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); 218 snd_soc_dapm_force_enable_pin(&rtd->card->dapm, "Mic Bias");
222 219
223 return 0; 220 return 0;
224} 221}
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index fb550b5869d2..33feee9ca8c3 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -125,14 +125,6 @@ static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
125{ 125{
126 int ret; 126 int ret;
127 127
128 if (set->fmt) {
129 ret = snd_soc_dai_set_fmt(dai, set->fmt);
130 if (ret && ret != -ENOTSUPP) {
131 dev_err(dai->dev, "simple-card: set_fmt error\n");
132 goto err;
133 }
134 }
135
136 if (set->sysclk) { 128 if (set->sysclk) {
137 ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0); 129 ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0);
138 if (ret && ret != -ENOTSUPP) { 130 if (ret && ret != -ENOTSUPP) {
@@ -176,11 +168,11 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
176 return ret; 168 return ret;
177 169
178 if (gpio_is_valid(priv->gpio_hp_det)) { 170 if (gpio_is_valid(priv->gpio_hp_det)) {
179 snd_soc_jack_new(codec->codec, "Headphones", SND_JACK_HEADPHONE, 171 snd_soc_card_jack_new(rtd->card, "Headphones",
180 &simple_card_hp_jack); 172 SND_JACK_HEADPHONE,
181 snd_soc_jack_add_pins(&simple_card_hp_jack, 173 &simple_card_hp_jack,
182 ARRAY_SIZE(simple_card_hp_jack_pins), 174 simple_card_hp_jack_pins,
183 simple_card_hp_jack_pins); 175 ARRAY_SIZE(simple_card_hp_jack_pins));
184 176
185 simple_card_hp_jack_gpio.gpio = priv->gpio_hp_det; 177 simple_card_hp_jack_gpio.gpio = priv->gpio_hp_det;
186 simple_card_hp_jack_gpio.invert = priv->gpio_hp_det_invert; 178 simple_card_hp_jack_gpio.invert = priv->gpio_hp_det_invert;
@@ -189,11 +181,11 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
189 } 181 }
190 182
191 if (gpio_is_valid(priv->gpio_mic_det)) { 183 if (gpio_is_valid(priv->gpio_mic_det)) {
192 snd_soc_jack_new(codec->codec, "Mic Jack", SND_JACK_MICROPHONE, 184 snd_soc_card_jack_new(rtd->card, "Mic Jack",
193 &simple_card_mic_jack); 185 SND_JACK_MICROPHONE,
194 snd_soc_jack_add_pins(&simple_card_mic_jack, 186 &simple_card_mic_jack,
195 ARRAY_SIZE(simple_card_mic_jack_pins), 187 simple_card_mic_jack_pins,
196 simple_card_mic_jack_pins); 188 ARRAY_SIZE(simple_card_mic_jack_pins));
197 simple_card_mic_jack_gpio.gpio = priv->gpio_mic_det; 189 simple_card_mic_jack_gpio.gpio = priv->gpio_mic_det;
198 simple_card_mic_jack_gpio.invert = priv->gpio_mic_det_invert; 190 simple_card_mic_jack_gpio.invert = priv->gpio_mic_det_invert;
199 snd_soc_jack_add_gpios(&simple_card_mic_jack, 1, 191 snd_soc_jack_add_gpios(&simple_card_mic_jack, 1,
@@ -269,12 +261,10 @@ static int asoc_simple_card_parse_daifmt(struct device_node *node,
269 struct device_node *codec, 261 struct device_node *codec,
270 char *prefix, int idx) 262 char *prefix, int idx)
271{ 263{
264 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
272 struct device *dev = simple_priv_to_dev(priv); 265 struct device *dev = simple_priv_to_dev(priv);
273 struct device_node *bitclkmaster = NULL; 266 struct device_node *bitclkmaster = NULL;
274 struct device_node *framemaster = NULL; 267 struct device_node *framemaster = NULL;
275 struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx);
276 struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai;
277 struct asoc_simple_dai *codec_dai = &dai_props->codec_dai;
278 unsigned int daifmt; 268 unsigned int daifmt;
279 269
280 daifmt = snd_soc_of_parse_daifmt(node, prefix, 270 daifmt = snd_soc_of_parse_daifmt(node, prefix,
@@ -289,8 +279,7 @@ static int asoc_simple_card_parse_daifmt(struct device_node *node,
289 */ 279 */
290 dev_dbg(dev, "Revert to legacy daifmt parsing\n"); 280 dev_dbg(dev, "Revert to legacy daifmt parsing\n");
291 281
292 cpu_dai->fmt = codec_dai->fmt = 282 daifmt = snd_soc_of_parse_daifmt(codec, NULL, NULL, NULL) |
293 snd_soc_of_parse_daifmt(codec, NULL, NULL, NULL) |
294 (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK); 283 (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK);
295 } else { 284 } else {
296 if (codec == bitclkmaster) 285 if (codec == bitclkmaster)
@@ -299,11 +288,10 @@ static int asoc_simple_card_parse_daifmt(struct device_node *node,
299 else 288 else
300 daifmt |= (codec == framemaster) ? 289 daifmt |= (codec == framemaster) ?
301 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS; 290 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
302
303 cpu_dai->fmt = daifmt;
304 codec_dai->fmt = daifmt;
305 } 291 }
306 292
293 dai_link->dai_fmt = daifmt;
294
307 of_node_put(bitclkmaster); 295 of_node_put(bitclkmaster);
308 of_node_put(framemaster); 296 of_node_put(framemaster);
309 297
@@ -384,13 +372,12 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
384 dai_link->init = asoc_simple_card_dai_init; 372 dai_link->init = asoc_simple_card_dai_init;
385 373
386 dev_dbg(dev, "\tname : %s\n", dai_link->stream_name); 374 dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
387 dev_dbg(dev, "\tcpu : %s / %04x / %d\n", 375 dev_dbg(dev, "\tformat : %04x\n", dai_link->dai_fmt);
376 dev_dbg(dev, "\tcpu : %s / %d\n",
388 dai_link->cpu_dai_name, 377 dai_link->cpu_dai_name,
389 dai_props->cpu_dai.fmt,
390 dai_props->cpu_dai.sysclk); 378 dai_props->cpu_dai.sysclk);
391 dev_dbg(dev, "\tcodec : %s / %04x / %d\n", 379 dev_dbg(dev, "\tcodec : %s / %d\n",
392 dai_link->codec_dai_name, 380 dai_link->codec_dai_name,
393 dai_props->codec_dai.fmt,
394 dai_props->codec_dai.sysclk); 381 dai_props->codec_dai.sysclk);
395 382
396 /* 383 /*
@@ -577,14 +564,13 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
577 dai_link->codec_name = cinfo->codec; 564 dai_link->codec_name = cinfo->codec;
578 dai_link->cpu_dai_name = cinfo->cpu_dai.name; 565 dai_link->cpu_dai_name = cinfo->cpu_dai.name;
579 dai_link->codec_dai_name = cinfo->codec_dai.name; 566 dai_link->codec_dai_name = cinfo->codec_dai.name;
567 dai_link->dai_fmt = cinfo->daifmt;
580 dai_link->init = asoc_simple_card_dai_init; 568 dai_link->init = asoc_simple_card_dai_init;
581 memcpy(&priv->dai_props->cpu_dai, &cinfo->cpu_dai, 569 memcpy(&priv->dai_props->cpu_dai, &cinfo->cpu_dai,
582 sizeof(priv->dai_props->cpu_dai)); 570 sizeof(priv->dai_props->cpu_dai));
583 memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai, 571 memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai,
584 sizeof(priv->dai_props->codec_dai)); 572 sizeof(priv->dai_props->codec_dai));
585 573
586 priv->dai_props->cpu_dai.fmt |= cinfo->daifmt;
587 priv->dai_props->codec_dai.fmt |= cinfo->daifmt;
588 } 574 }
589 575
590 snd_soc_card_set_drvdata(&priv->snd_card, priv); 576 snd_soc_card_set_drvdata(&priv->snd_card, priv);
diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile
index a8e53c45c6b6..cd9aee9871a3 100644
--- a/sound/soc/intel/Makefile
+++ b/sound/soc/intel/Makefile
@@ -1,42 +1,10 @@
1# Core support 1# Core support
2snd-soc-sst-dsp-objs := sst-dsp.o sst-firmware.o 2obj-$(CONFIG_SND_SOC_INTEL_SST) += common/
3snd-soc-sst-acpi-objs := sst-acpi.o
4
5snd-soc-sst-mfld-platform-objs := sst-mfld-platform-pcm.o \
6 sst-mfld-platform-compress.o sst-atom-controls.o
7snd-soc-mfld-machine-objs := mfld_machine.o
8
9obj-$(CONFIG_SND_SST_MFLD_PLATFORM) += snd-soc-sst-mfld-platform.o
10obj-$(CONFIG_SND_MFLD_MACHINE) += snd-soc-mfld-machine.o
11
12obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o
13obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o
14 3
15# Platform Support 4# Platform Support
16snd-soc-sst-haswell-pcm-objs := \ 5obj-$(CONFIG_SND_SOC_INTEL_HASWELL) += haswell/
17 sst-haswell-ipc.o sst-haswell-pcm.o sst-haswell-dsp.o 6obj-$(CONFIG_SND_SOC_INTEL_BAYTRAIL) += baytrail/
18snd-soc-sst-baytrail-pcm-objs := \ 7obj-$(CONFIG_SND_SOC_INTEL_BAYTRAIL) += atom/
19 sst-baytrail-ipc.o sst-baytrail-pcm.o sst-baytrail-dsp.o
20
21obj-$(CONFIG_SND_SOC_INTEL_HASWELL) += snd-soc-sst-haswell-pcm.o
22obj-$(CONFIG_SND_SOC_INTEL_BAYTRAIL) += snd-soc-sst-baytrail-pcm.o
23 8
24# Machine support 9# Machine support
25snd-soc-sst-haswell-objs := haswell.o 10obj-$(CONFIG_SND_SOC_INTEL_SST) += boards/
26snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o
27snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o
28snd-soc-sst-broadwell-objs := broadwell.o
29snd-soc-sst-bytcr-dpcm-rt5640-objs := bytcr_dpcm_rt5640.o
30snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
31snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o
32
33obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
34obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
35obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o
36obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o
37obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-dpcm-rt5640.o
38obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
39obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o
40
41# DSP driver
42obj-$(CONFIG_SND_SST_IPC) += sst/
diff --git a/sound/soc/intel/atom/Makefile b/sound/soc/intel/atom/Makefile
new file mode 100644
index 000000000000..ce8074fa6d66
--- /dev/null
+++ b/sound/soc/intel/atom/Makefile
@@ -0,0 +1,7 @@
1snd-soc-sst-mfld-platform-objs := sst-mfld-platform-pcm.o \
2 sst-mfld-platform-compress.o sst-atom-controls.o
3
4obj-$(CONFIG_SND_SST_MFLD_PLATFORM) += snd-soc-sst-mfld-platform.o
5
6# DSP driver
7obj-$(CONFIG_SND_SST_IPC) += sst/
diff --git a/sound/soc/intel/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c
index 90aa5c0476f3..90aa5c0476f3 100644
--- a/sound/soc/intel/sst-atom-controls.c
+++ b/sound/soc/intel/atom/sst-atom-controls.c
diff --git a/sound/soc/intel/sst-atom-controls.h b/sound/soc/intel/atom/sst-atom-controls.h
index daecc58f28af..daecc58f28af 100644
--- a/sound/soc/intel/sst-atom-controls.h
+++ b/sound/soc/intel/atom/sst-atom-controls.h
diff --git a/sound/soc/intel/sst-mfld-dsp.h b/sound/soc/intel/atom/sst-mfld-dsp.h
index 4257263157cd..4257263157cd 100644
--- a/sound/soc/intel/sst-mfld-dsp.h
+++ b/sound/soc/intel/atom/sst-mfld-dsp.h
diff --git a/sound/soc/intel/sst-mfld-platform-compress.c b/sound/soc/intel/atom/sst-mfld-platform-compress.c
index 395168986462..395168986462 100644
--- a/sound/soc/intel/sst-mfld-platform-compress.c
+++ b/sound/soc/intel/atom/sst-mfld-platform-compress.c
diff --git a/sound/soc/intel/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
index 7523cbef8780..2fbaf2c75d17 100644
--- a/sound/soc/intel/sst-mfld-platform-pcm.c
+++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
@@ -594,11 +594,13 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream,
594 ret_val = stream->ops->stream_drop(sst->dev, str_id); 594 ret_val = stream->ops->stream_drop(sst->dev, str_id);
595 break; 595 break;
596 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 596 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
597 case SNDRV_PCM_TRIGGER_SUSPEND:
597 dev_dbg(rtd->dev, "sst: in pause\n"); 598 dev_dbg(rtd->dev, "sst: in pause\n");
598 status = SST_PLATFORM_PAUSED; 599 status = SST_PLATFORM_PAUSED;
599 ret_val = stream->ops->stream_pause(sst->dev, str_id); 600 ret_val = stream->ops->stream_pause(sst->dev, str_id);
600 break; 601 break;
601 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 602 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
603 case SNDRV_PCM_TRIGGER_RESUME:
602 dev_dbg(rtd->dev, "sst: in pause release\n"); 604 dev_dbg(rtd->dev, "sst: in pause release\n");
603 status = SST_PLATFORM_RUNNING; 605 status = SST_PLATFORM_RUNNING;
604 ret_val = stream->ops->stream_pause_release(sst->dev, str_id); 606 ret_val = stream->ops->stream_pause_release(sst->dev, str_id);
@@ -665,6 +667,9 @@ static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
665 667
666static int sst_soc_probe(struct snd_soc_platform *platform) 668static int sst_soc_probe(struct snd_soc_platform *platform)
667{ 669{
670 struct sst_data *drv = dev_get_drvdata(platform->dev);
671
672 drv->soc_card = platform->component.card;
668 return sst_dsp_init_v2_dpcm(platform); 673 return sst_dsp_init_v2_dpcm(platform);
669} 674}
670 675
@@ -727,9 +732,64 @@ static int sst_platform_remove(struct platform_device *pdev)
727 return 0; 732 return 0;
728} 733}
729 734
735#ifdef CONFIG_PM_SLEEP
736
737static int sst_soc_prepare(struct device *dev)
738{
739 struct sst_data *drv = dev_get_drvdata(dev);
740 int i;
741
742 /* suspend all pcms first */
743 snd_soc_suspend(drv->soc_card->dev);
744 snd_soc_poweroff(drv->soc_card->dev);
745
746 /* set the SSPs to idle */
747 for (i = 0; i < drv->soc_card->num_rtd; i++) {
748 struct snd_soc_dai *dai = drv->soc_card->rtd[i].cpu_dai;
749
750 if (dai->active) {
751 send_ssp_cmd(dai, dai->name, 0);
752 sst_handle_vb_timer(dai, false);
753 }
754 }
755
756 return 0;
757}
758
759static void sst_soc_complete(struct device *dev)
760{
761 struct sst_data *drv = dev_get_drvdata(dev);
762 int i;
763
764 /* restart SSPs */
765 for (i = 0; i < drv->soc_card->num_rtd; i++) {
766 struct snd_soc_dai *dai = drv->soc_card->rtd[i].cpu_dai;
767
768 if (dai->active) {
769 sst_handle_vb_timer(dai, true);
770 send_ssp_cmd(dai, dai->name, 1);
771 }
772 }
773 snd_soc_resume(drv->soc_card->dev);
774}
775
776#else
777
778#define sst_soc_prepare NULL
779#define sst_soc_complete NULL
780
781#endif
782
783
784static const struct dev_pm_ops sst_platform_pm = {
785 .prepare = sst_soc_prepare,
786 .complete = sst_soc_complete,
787};
788
730static struct platform_driver sst_platform_driver = { 789static struct platform_driver sst_platform_driver = {
731 .driver = { 790 .driver = {
732 .name = "sst-mfld-platform", 791 .name = "sst-mfld-platform",
792 .pm = &sst_platform_pm,
733 }, 793 },
734 .probe = sst_platform_probe, 794 .probe = sst_platform_probe,
735 .remove = sst_platform_remove, 795 .remove = sst_platform_remove,
diff --git a/sound/soc/intel/sst-mfld-platform.h b/sound/soc/intel/atom/sst-mfld-platform.h
index 79c8d1246a8f..9094314be2b0 100644
--- a/sound/soc/intel/sst-mfld-platform.h
+++ b/sound/soc/intel/atom/sst-mfld-platform.h
@@ -174,6 +174,7 @@ struct sst_data {
174 struct sst_platform_data *pdata; 174 struct sst_platform_data *pdata;
175 struct snd_sst_bytes_v2 *byte_stream; 175 struct snd_sst_bytes_v2 *byte_stream;
176 struct mutex lock; 176 struct mutex lock;
177 struct snd_soc_card *soc_card;
177}; 178};
178int sst_register_dsp(struct sst_device *sst); 179int sst_register_dsp(struct sst_device *sst);
179int sst_unregister_dsp(struct sst_device *sst); 180int sst_unregister_dsp(struct sst_device *sst);
diff --git a/sound/soc/intel/sst/Makefile b/sound/soc/intel/atom/sst/Makefile
index fd21726361b5..fd21726361b5 100644
--- a/sound/soc/intel/sst/Makefile
+++ b/sound/soc/intel/atom/sst/Makefile
diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/atom/sst/sst.c
index 11c578651c1c..96c2e420cce6 100644
--- a/sound/soc/intel/sst/sst.c
+++ b/sound/soc/intel/atom/sst/sst.c
@@ -32,7 +32,7 @@
32#include <asm/platform_sst_audio.h> 32#include <asm/platform_sst_audio.h>
33#include "../sst-mfld-platform.h" 33#include "../sst-mfld-platform.h"
34#include "sst.h" 34#include "sst.h"
35#include "../sst-dsp.h" 35#include "../../common/sst-dsp.h"
36 36
37MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>"); 37MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
38MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>"); 38MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
@@ -423,23 +423,135 @@ static int intel_sst_runtime_suspend(struct device *dev)
423 return ret; 423 return ret;
424} 424}
425 425
426static int intel_sst_runtime_resume(struct device *dev) 426static int intel_sst_suspend(struct device *dev)
427{ 427{
428 int ret = 0;
429 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 428 struct intel_sst_drv *ctx = dev_get_drvdata(dev);
429 struct sst_fw_save *fw_save;
430 int i, ret = 0;
430 431
431 if (ctx->sst_state == SST_RESET) { 432 /* check first if we are already in SW reset */
432 ret = sst_load_fw(ctx); 433 if (ctx->sst_state == SST_RESET)
433 if (ret) { 434 return 0;
434 dev_err(dev, "FW download fail %d\n", ret); 435
435 sst_set_fw_state_locked(ctx, SST_RESET); 436 /*
437 * check if any stream is active and running
438 * they should already by suspend by soc_suspend
439 */
440 for (i = 1; i <= ctx->info.max_streams; i++) {
441 struct stream_info *stream = &ctx->streams[i];
442
443 if (stream->status == STREAM_RUNNING) {
444 dev_err(dev, "stream %d is running, cant susupend, abort\n", i);
445 return -EBUSY;
436 } 446 }
437 } 447 }
448 synchronize_irq(ctx->irq_num);
449 flush_workqueue(ctx->post_msg_wq);
450
451 /* Move the SST state to Reset */
452 sst_set_fw_state_locked(ctx, SST_RESET);
453
454 /* tell DSP we are suspending */
455 if (ctx->ops->save_dsp_context(ctx))
456 return -EBUSY;
457
458 /* save the memories */
459 fw_save = kzalloc(sizeof(*fw_save), GFP_KERNEL);
460 if (!fw_save)
461 return -ENOMEM;
462 fw_save->iram = kzalloc(ctx->iram_end - ctx->iram_base, GFP_KERNEL);
463 if (!fw_save->iram) {
464 ret = -ENOMEM;
465 goto iram;
466 }
467 fw_save->dram = kzalloc(ctx->dram_end - ctx->dram_base, GFP_KERNEL);
468 if (!fw_save->dram) {
469 ret = -ENOMEM;
470 goto dram;
471 }
472 fw_save->sram = kzalloc(SST_MAILBOX_SIZE, GFP_KERNEL);
473 if (!fw_save->sram) {
474 ret = -ENOMEM;
475 goto sram;
476 }
477
478 fw_save->ddr = kzalloc(ctx->ddr_end - ctx->ddr_base, GFP_KERNEL);
479 if (!fw_save->ddr) {
480 ret = -ENOMEM;
481 goto ddr;
482 }
483
484 memcpy32_fromio(fw_save->iram, ctx->iram, ctx->iram_end - ctx->iram_base);
485 memcpy32_fromio(fw_save->dram, ctx->dram, ctx->dram_end - ctx->dram_base);
486 memcpy32_fromio(fw_save->sram, ctx->mailbox, SST_MAILBOX_SIZE);
487 memcpy32_fromio(fw_save->ddr, ctx->ddr, ctx->ddr_end - ctx->ddr_base);
488
489 ctx->fw_save = fw_save;
490 ctx->ops->reset(ctx);
491 return 0;
492ddr:
493 kfree(fw_save->sram);
494sram:
495 kfree(fw_save->dram);
496dram:
497 kfree(fw_save->iram);
498iram:
499 kfree(fw_save);
500 return ret;
501}
502
503static int intel_sst_resume(struct device *dev)
504{
505 struct intel_sst_drv *ctx = dev_get_drvdata(dev);
506 struct sst_fw_save *fw_save = ctx->fw_save;
507 int ret = 0;
508 struct sst_block *block;
509
510 if (!fw_save)
511 return 0;
512
513 sst_set_fw_state_locked(ctx, SST_FW_LOADING);
514
515 /* we have to restore the memory saved */
516 ctx->ops->reset(ctx);
517
518 ctx->fw_save = NULL;
519
520 memcpy32_toio(ctx->iram, fw_save->iram, ctx->iram_end - ctx->iram_base);
521 memcpy32_toio(ctx->dram, fw_save->dram, ctx->dram_end - ctx->dram_base);
522 memcpy32_toio(ctx->mailbox, fw_save->sram, SST_MAILBOX_SIZE);
523 memcpy32_toio(ctx->ddr, fw_save->ddr, ctx->ddr_end - ctx->ddr_base);
524
525 kfree(fw_save->sram);
526 kfree(fw_save->dram);
527 kfree(fw_save->iram);
528 kfree(fw_save->ddr);
529 kfree(fw_save);
530
531 block = sst_create_block(ctx, 0, FW_DWNL_ID);
532 if (block == NULL)
533 return -ENOMEM;
534
535
536 /* start and wait for ack */
537 ctx->ops->start(ctx);
538 ret = sst_wait_timeout(ctx, block);
539 if (ret) {
540 dev_err(ctx->dev, "fw download failed %d\n", ret);
541 /* FW download failed due to timeout */
542 ret = -EBUSY;
543
544 } else {
545 sst_set_fw_state_locked(ctx, SST_FW_RUNNING);
546 }
547
548 sst_free_block(ctx, block);
438 return ret; 549 return ret;
439} 550}
440 551
441const struct dev_pm_ops intel_sst_pm = { 552const struct dev_pm_ops intel_sst_pm = {
553 .suspend = intel_sst_suspend,
554 .resume = intel_sst_resume,
442 .runtime_suspend = intel_sst_runtime_suspend, 555 .runtime_suspend = intel_sst_runtime_suspend,
443 .runtime_resume = intel_sst_runtime_resume,
444}; 556};
445EXPORT_SYMBOL_GPL(intel_sst_pm); 557EXPORT_SYMBOL_GPL(intel_sst_pm);
diff --git a/sound/soc/intel/sst/sst.h b/sound/soc/intel/atom/sst/sst.h
index 562bc483d6b7..3f493862e98d 100644
--- a/sound/soc/intel/sst/sst.h
+++ b/sound/soc/intel/atom/sst/sst.h
@@ -337,6 +337,13 @@ struct sst_shim_regs64 {
337 u64 csr2; 337 u64 csr2;
338}; 338};
339 339
340struct sst_fw_save {
341 void *iram;
342 void *dram;
343 void *sram;
344 void *ddr;
345};
346
340/** 347/**
341 * struct intel_sst_drv - driver ops 348 * struct intel_sst_drv - driver ops
342 * 349 *
@@ -428,6 +435,8 @@ struct intel_sst_drv {
428 * persistent till worker thread gets called 435 * persistent till worker thread gets called
429 */ 436 */
430 char firmware_name[FW_NAME_SIZE]; 437 char firmware_name[FW_NAME_SIZE];
438
439 struct sst_fw_save *fw_save;
431}; 440};
432 441
433/* misc definitions */ 442/* misc definitions */
@@ -544,4 +553,7 @@ int sst_alloc_drv_context(struct intel_sst_drv **ctx,
544int sst_context_init(struct intel_sst_drv *ctx); 553int sst_context_init(struct intel_sst_drv *ctx);
545void sst_context_cleanup(struct intel_sst_drv *ctx); 554void sst_context_cleanup(struct intel_sst_drv *ctx);
546void sst_configure_runtime_pm(struct intel_sst_drv *ctx); 555void sst_configure_runtime_pm(struct intel_sst_drv *ctx);
556void memcpy32_toio(void __iomem *dst, const void *src, int count);
557void memcpy32_fromio(void *dst, const void __iomem *src, int count);
558
547#endif 559#endif
diff --git a/sound/soc/intel/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
index b782dfdcdbba..05f693083911 100644
--- a/sound/soc/intel/sst/sst_acpi.c
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
@@ -39,7 +39,7 @@
39#include <acpi/actypes.h> 39#include <acpi/actypes.h>
40#include <acpi/acpi_bus.h> 40#include <acpi/acpi_bus.h>
41#include "../sst-mfld-platform.h" 41#include "../sst-mfld-platform.h"
42#include "../sst-dsp.h" 42#include "../../common/sst-dsp.h"
43#include "sst.h" 43#include "sst.h"
44 44
45struct sst_machines { 45struct sst_machines {
@@ -309,7 +309,7 @@ static int sst_acpi_probe(struct platform_device *pdev)
309 ctx->shim_regs64 = devm_kzalloc(ctx->dev, sizeof(*ctx->shim_regs64), 309 ctx->shim_regs64 = devm_kzalloc(ctx->dev, sizeof(*ctx->shim_regs64),
310 GFP_KERNEL); 310 GFP_KERNEL);
311 if (!ctx->shim_regs64) { 311 if (!ctx->shim_regs64) {
312 return -ENOMEM; 312 ret = -ENOMEM;
313 goto do_sst_cleanup; 313 goto do_sst_cleanup;
314 } 314 }
315 315
diff --git a/sound/soc/intel/sst/sst_drv_interface.c b/sound/soc/intel/atom/sst/sst_drv_interface.c
index 5f75ef3cdd22..7b50a9d17ec1 100644
--- a/sound/soc/intel/sst/sst_drv_interface.c
+++ b/sound/soc/intel/atom/sst/sst_drv_interface.c
@@ -32,7 +32,7 @@
32#include <asm/platform_sst_audio.h> 32#include <asm/platform_sst_audio.h>
33#include "../sst-mfld-platform.h" 33#include "../sst-mfld-platform.h"
34#include "sst.h" 34#include "sst.h"
35#include "../sst-dsp.h" 35#include "../../common/sst-dsp.h"
36 36
37 37
38 38
@@ -138,12 +138,36 @@ int sst_get_stream(struct intel_sst_drv *ctx,
138static int sst_power_control(struct device *dev, bool state) 138static int sst_power_control(struct device *dev, bool state)
139{ 139{
140 struct intel_sst_drv *ctx = dev_get_drvdata(dev); 140 struct intel_sst_drv *ctx = dev_get_drvdata(dev);
141 141 int ret = 0;
142 dev_dbg(ctx->dev, "state:%d", state); 142 int usage_count = 0;
143 if (state == true) 143
144 return pm_runtime_get_sync(dev); 144#ifdef CONFIG_PM
145 else 145 usage_count = atomic_read(&dev->power.usage_count);
146#else
147 usage_count = 1;
148#endif
149
150 if (state == true) {
151 ret = pm_runtime_get_sync(dev);
152
153 dev_dbg(ctx->dev, "Enable: pm usage count: %d\n", usage_count);
154 if (ret < 0) {
155 dev_err(ctx->dev, "Runtime get failed with err: %d\n", ret);
156 return ret;
157 }
158 if ((ctx->sst_state == SST_RESET) && (usage_count == 1)) {
159 ret = sst_load_fw(ctx);
160 if (ret) {
161 dev_err(dev, "FW download fail %d\n", ret);
162 sst_set_fw_state_locked(ctx, SST_RESET);
163 ret = sst_pm_runtime_put(ctx);
164 }
165 }
166 } else {
167 dev_dbg(ctx->dev, "Disable: pm usage count: %d\n", usage_count);
146 return sst_pm_runtime_put(ctx); 168 return sst_pm_runtime_put(ctx);
169 }
170 return ret;
147} 171}
148 172
149/* 173/*
@@ -357,7 +381,7 @@ static int sst_cdev_tstamp(struct device *dev, unsigned int str_id,
357 tstamp->copied_total = fw_tstamp.ring_buffer_counter; 381 tstamp->copied_total = fw_tstamp.ring_buffer_counter;
358 tstamp->pcm_frames = fw_tstamp.frames_decoded; 382 tstamp->pcm_frames = fw_tstamp.frames_decoded;
359 tstamp->pcm_io_frames = div_u64(fw_tstamp.hardware_counter, 383 tstamp->pcm_io_frames = div_u64(fw_tstamp.hardware_counter,
360 (u64)((stream->num_ch) * SST_GET_BYTES_PER_SAMPLE(24))); 384 (u64)stream->num_ch * SST_GET_BYTES_PER_SAMPLE(24));
361 tstamp->sampling_rate = fw_tstamp.sampling_frequency; 385 tstamp->sampling_rate = fw_tstamp.sampling_frequency;
362 386
363 dev_dbg(dev, "PCM = %u\n", tstamp->pcm_io_frames); 387 dev_dbg(dev, "PCM = %u\n", tstamp->pcm_io_frames);
@@ -572,6 +596,35 @@ static int sst_stream_drop(struct device *dev, int str_id)
572 return sst_drop_stream(ctx, str_id); 596 return sst_drop_stream(ctx, str_id);
573} 597}
574 598
599static int sst_stream_pause(struct device *dev, int str_id)
600{
601 struct stream_info *str_info;
602 struct intel_sst_drv *ctx = dev_get_drvdata(dev);
603
604 if (ctx->sst_state != SST_FW_RUNNING)
605 return 0;
606
607 str_info = get_stream_info(ctx, str_id);
608 if (!str_info)
609 return -EINVAL;
610
611 return sst_pause_stream(ctx, str_id);
612}
613
614static int sst_stream_resume(struct device *dev, int str_id)
615{
616 struct stream_info *str_info;
617 struct intel_sst_drv *ctx = dev_get_drvdata(dev);
618
619 if (ctx->sst_state != SST_FW_RUNNING)
620 return 0;
621
622 str_info = get_stream_info(ctx, str_id);
623 if (!str_info)
624 return -EINVAL;
625 return sst_resume_stream(ctx, str_id);
626}
627
575static int sst_stream_init(struct device *dev, struct pcm_stream_info *str_info) 628static int sst_stream_init(struct device *dev, struct pcm_stream_info *str_info)
576{ 629{
577 int str_id = 0; 630 int str_id = 0;
@@ -633,6 +686,8 @@ static struct sst_ops pcm_ops = {
633 .stream_init = sst_stream_init, 686 .stream_init = sst_stream_init,
634 .stream_start = sst_stream_start, 687 .stream_start = sst_stream_start,
635 .stream_drop = sst_stream_drop, 688 .stream_drop = sst_stream_drop,
689 .stream_pause = sst_stream_pause,
690 .stream_pause_release = sst_stream_resume,
636 .stream_read_tstamp = sst_read_timestamp, 691 .stream_read_tstamp = sst_read_timestamp,
637 .send_byte_stream = sst_send_byte_stream, 692 .send_byte_stream = sst_send_byte_stream,
638 .close = sst_close_pcm_stream, 693 .close = sst_close_pcm_stream,
diff --git a/sound/soc/intel/sst/sst_ipc.c b/sound/soc/intel/atom/sst/sst_ipc.c
index 484e60978477..5a278618466c 100644
--- a/sound/soc/intel/sst/sst_ipc.c
+++ b/sound/soc/intel/atom/sst/sst_ipc.c
@@ -32,7 +32,7 @@
32#include <asm/platform_sst_audio.h> 32#include <asm/platform_sst_audio.h>
33#include "../sst-mfld-platform.h" 33#include "../sst-mfld-platform.h"
34#include "sst.h" 34#include "sst.h"
35#include "../sst-dsp.h" 35#include "../../common/sst-dsp.h"
36 36
37struct sst_block *sst_create_block(struct intel_sst_drv *ctx, 37struct sst_block *sst_create_block(struct intel_sst_drv *ctx,
38 u32 msg_id, u32 drv_id) 38 u32 msg_id, u32 drv_id)
diff --git a/sound/soc/intel/sst/sst_loader.c b/sound/soc/intel/atom/sst/sst_loader.c
index 7888cd707853..33917146d9c4 100644
--- a/sound/soc/intel/sst/sst_loader.c
+++ b/sound/soc/intel/atom/sst/sst_loader.c
@@ -37,9 +37,17 @@
37#include <asm/platform_sst_audio.h> 37#include <asm/platform_sst_audio.h>
38#include "../sst-mfld-platform.h" 38#include "../sst-mfld-platform.h"
39#include "sst.h" 39#include "sst.h"
40#include "../sst-dsp.h" 40#include "../../common/sst-dsp.h"
41 41
42static inline void memcpy32_toio(void __iomem *dst, const void *src, int count) 42void memcpy32_toio(void __iomem *dst, const void *src, int count)
43{
44 /* __iowrite32_copy uses 32-bit count values so divide by 4 for
45 * right count in words
46 */
47 __iowrite32_copy(dst, src, count/4);
48}
49
50void memcpy32_fromio(void *dst, const void __iomem *src, int count)
43{ 51{
44 /* __iowrite32_copy uses 32-bit count values so divide by 4 for 52 /* __iowrite32_copy uses 32-bit count values so divide by 4 for
45 * right count in words 53 * right count in words
diff --git a/sound/soc/intel/sst/sst_pci.c b/sound/soc/intel/atom/sst/sst_pci.c
index 3a0b3bf0af97..3a0b3bf0af97 100644
--- a/sound/soc/intel/sst/sst_pci.c
+++ b/sound/soc/intel/atom/sst/sst_pci.c
diff --git a/sound/soc/intel/sst/sst_pvt.c b/sound/soc/intel/atom/sst/sst_pvt.c
index 4b7720864492..adb32fefd693 100644
--- a/sound/soc/intel/sst/sst_pvt.c
+++ b/sound/soc/intel/atom/sst/sst_pvt.c
@@ -34,7 +34,7 @@
34#include <asm/platform_sst_audio.h> 34#include <asm/platform_sst_audio.h>
35#include "../sst-mfld-platform.h" 35#include "../sst-mfld-platform.h"
36#include "sst.h" 36#include "sst.h"
37#include "../sst-dsp.h" 37#include "../../common/sst-dsp.h"
38 38
39int sst_shim_write(void __iomem *addr, int offset, int value) 39int sst_shim_write(void __iomem *addr, int offset, int value)
40{ 40{
@@ -111,30 +111,6 @@ int sst_wait_interruptible(struct intel_sst_drv *sst_drv_ctx,
111 111
112} 112}
113 113
114unsigned long long read_shim_data(struct intel_sst_drv *sst, int addr)
115{
116 unsigned long long val = 0;
117
118 switch (sst->dev_id) {
119 case SST_MRFLD_PCI_ID:
120 case SST_BYT_ACPI_ID:
121 val = sst_shim_read64(sst->shim, addr);
122 break;
123 }
124 return val;
125}
126
127void write_shim_data(struct intel_sst_drv *sst, int addr,
128 unsigned long long data)
129{
130 switch (sst->dev_id) {
131 case SST_MRFLD_PCI_ID:
132 case SST_BYT_ACPI_ID:
133 sst_shim_write64(sst->shim, addr, (u64) data);
134 break;
135 }
136}
137
138/* 114/*
139 * sst_wait_timeout - wait on event for timeout 115 * sst_wait_timeout - wait on event for timeout
140 * 116 *
diff --git a/sound/soc/intel/sst/sst_stream.c b/sound/soc/intel/atom/sst/sst_stream.c
index dae2a41997aa..a74c64c7053c 100644
--- a/sound/soc/intel/sst/sst_stream.c
+++ b/sound/soc/intel/atom/sst/sst_stream.c
@@ -31,7 +31,7 @@
31#include <asm/platform_sst_audio.h> 31#include <asm/platform_sst_audio.h>
32#include "../sst-mfld-platform.h" 32#include "../sst-mfld-platform.h"
33#include "sst.h" 33#include "sst.h"
34#include "../sst-dsp.h" 34#include "../../common/sst-dsp.h"
35 35
36int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params) 36int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params)
37{ 37{
diff --git a/sound/soc/intel/baytrail/Makefile b/sound/soc/intel/baytrail/Makefile
new file mode 100644
index 000000000000..488408cadf6d
--- /dev/null
+++ b/sound/soc/intel/baytrail/Makefile
@@ -0,0 +1,4 @@
1snd-soc-sst-baytrail-pcm-objs := \
2 sst-baytrail-ipc.o sst-baytrail-pcm.o sst-baytrail-dsp.o
3
4obj-$(CONFIG_SND_SOC_INTEL_BAYTRAIL) += snd-soc-sst-baytrail-pcm.o
diff --git a/sound/soc/intel/sst-baytrail-dsp.c b/sound/soc/intel/baytrail/sst-baytrail-dsp.c
index 5a9e56700f31..01d023cc05dd 100644
--- a/sound/soc/intel/sst-baytrail-dsp.c
+++ b/sound/soc/intel/baytrail/sst-baytrail-dsp.c
@@ -22,8 +22,8 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/firmware.h> 23#include <linux/firmware.h>
24 24
25#include "sst-dsp.h" 25#include "../common/sst-dsp.h"
26#include "sst-dsp-priv.h" 26#include "../common/sst-dsp-priv.h"
27#include "sst-baytrail-ipc.h" 27#include "sst-baytrail-ipc.h"
28 28
29#define SST_BYT_FW_SIGNATURE_SIZE 4 29#define SST_BYT_FW_SIGNATURE_SIZE 4
diff --git a/sound/soc/intel/sst-baytrail-ipc.c b/sound/soc/intel/baytrail/sst-baytrail-ipc.c
index b4ad98c43e5c..1efb33b36303 100644
--- a/sound/soc/intel/sst-baytrail-ipc.c
+++ b/sound/soc/intel/baytrail/sst-baytrail-ipc.c
@@ -29,8 +29,9 @@
29#include <asm/div64.h> 29#include <asm/div64.h>
30 30
31#include "sst-baytrail-ipc.h" 31#include "sst-baytrail-ipc.h"
32#include "sst-dsp.h" 32#include "../common/sst-dsp.h"
33#include "sst-dsp-priv.h" 33#include "../common/sst-dsp-priv.h"
34#include "../common/sst-ipc.h"
34 35
35/* IPC message timeout */ 36/* IPC message timeout */
36#define IPC_TIMEOUT_MSECS 300 37#define IPC_TIMEOUT_MSECS 300
@@ -142,23 +143,6 @@ struct sst_byt_fw_init {
142 u8 debug_info; 143 u8 debug_info;
143} __packed; 144} __packed;
144 145
145/* driver internal IPC message structure */
146struct ipc_message {
147 struct list_head list;
148 u64 header;
149
150 /* direction wrt host CPU */
151 char tx_data[SST_BYT_IPC_MAX_PAYLOAD_SIZE];
152 size_t tx_size;
153 char rx_data[SST_BYT_IPC_MAX_PAYLOAD_SIZE];
154 size_t rx_size;
155
156 wait_queue_head_t waitq;
157 bool complete;
158 bool wait;
159 int errno;
160};
161
162struct sst_byt_stream; 146struct sst_byt_stream;
163struct sst_byt; 147struct sst_byt;
164 148
@@ -195,14 +179,7 @@ struct sst_byt {
195 struct sst_fw *fw; 179 struct sst_fw *fw;
196 180
197 /* IPC messaging */ 181 /* IPC messaging */
198 struct list_head tx_list; 182 struct sst_generic_ipc ipc;
199 struct list_head rx_list;
200 struct list_head empty_list;
201 wait_queue_head_t wait_txq;
202 struct task_struct *tx_thread;
203 struct kthread_worker kworker;
204 struct kthread_work kwork;
205 struct ipc_message *msg;
206}; 183};
207 184
208static inline u64 sst_byt_header(int msg_id, int data, bool large, int str_id) 185static inline u64 sst_byt_header(int msg_id, int data, bool large, int str_id)
@@ -246,209 +223,6 @@ static struct sst_byt_stream *sst_byt_get_stream(struct sst_byt *byt,
246 return NULL; 223 return NULL;
247} 224}
248 225
249static void sst_byt_ipc_shim_dbg(struct sst_byt *byt, const char *text)
250{
251 struct sst_dsp *sst = byt->dsp;
252 u64 isr, ipcd, imrx, ipcx;
253
254 ipcx = sst_dsp_shim_read64_unlocked(sst, SST_IPCX);
255 isr = sst_dsp_shim_read64_unlocked(sst, SST_ISRX);
256 ipcd = sst_dsp_shim_read64_unlocked(sst, SST_IPCD);
257 imrx = sst_dsp_shim_read64_unlocked(sst, SST_IMRX);
258
259 dev_err(byt->dev,
260 "ipc: --%s-- ipcx 0x%llx isr 0x%llx ipcd 0x%llx imrx 0x%llx\n",
261 text, ipcx, isr, ipcd, imrx);
262}
263
264/* locks held by caller */
265static struct ipc_message *sst_byt_msg_get_empty(struct sst_byt *byt)
266{
267 struct ipc_message *msg = NULL;
268
269 if (!list_empty(&byt->empty_list)) {
270 msg = list_first_entry(&byt->empty_list,
271 struct ipc_message, list);
272 list_del(&msg->list);
273 }
274
275 return msg;
276}
277
278static void sst_byt_ipc_tx_msgs(struct kthread_work *work)
279{
280 struct sst_byt *byt =
281 container_of(work, struct sst_byt, kwork);
282 struct ipc_message *msg;
283 u64 ipcx;
284 unsigned long flags;
285
286 spin_lock_irqsave(&byt->dsp->spinlock, flags);
287 if (list_empty(&byt->tx_list)) {
288 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
289 return;
290 }
291
292 /* if the DSP is busy we will TX messages after IRQ */
293 ipcx = sst_dsp_shim_read64_unlocked(byt->dsp, SST_IPCX);
294 if (ipcx & SST_BYT_IPCX_BUSY) {
295 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
296 return;
297 }
298
299 msg = list_first_entry(&byt->tx_list, struct ipc_message, list);
300
301 list_move(&msg->list, &byt->rx_list);
302
303 /* send the message */
304 if (msg->header & IPC_HEADER_LARGE(true))
305 sst_dsp_outbox_write(byt->dsp, msg->tx_data, msg->tx_size);
306 sst_dsp_shim_write64_unlocked(byt->dsp, SST_IPCX, msg->header);
307
308 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
309}
310
311static inline void sst_byt_tx_msg_reply_complete(struct sst_byt *byt,
312 struct ipc_message *msg)
313{
314 msg->complete = true;
315
316 if (!msg->wait)
317 list_add_tail(&msg->list, &byt->empty_list);
318 else
319 wake_up(&msg->waitq);
320}
321
322static void sst_byt_drop_all(struct sst_byt *byt)
323{
324 struct ipc_message *msg, *tmp;
325 unsigned long flags;
326
327 /* drop all TX and Rx messages before we stall + reset DSP */
328 spin_lock_irqsave(&byt->dsp->spinlock, flags);
329 list_for_each_entry_safe(msg, tmp, &byt->tx_list, list) {
330 list_move(&msg->list, &byt->empty_list);
331 }
332
333 list_for_each_entry_safe(msg, tmp, &byt->rx_list, list) {
334 list_move(&msg->list, &byt->empty_list);
335 }
336
337 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
338}
339
340static int sst_byt_tx_wait_done(struct sst_byt *byt, struct ipc_message *msg,
341 void *rx_data)
342{
343 unsigned long flags;
344 int ret;
345
346 /* wait for DSP completion */
347 ret = wait_event_timeout(msg->waitq, msg->complete,
348 msecs_to_jiffies(IPC_TIMEOUT_MSECS));
349
350 spin_lock_irqsave(&byt->dsp->spinlock, flags);
351 if (ret == 0) {
352 list_del(&msg->list);
353 sst_byt_ipc_shim_dbg(byt, "message timeout");
354
355 ret = -ETIMEDOUT;
356 } else {
357
358 /* copy the data returned from DSP */
359 if (msg->rx_size)
360 memcpy(rx_data, msg->rx_data, msg->rx_size);
361 ret = msg->errno;
362 }
363
364 list_add_tail(&msg->list, &byt->empty_list);
365 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
366 return ret;
367}
368
369static int sst_byt_ipc_tx_message(struct sst_byt *byt, u64 header,
370 void *tx_data, size_t tx_bytes,
371 void *rx_data, size_t rx_bytes, int wait)
372{
373 unsigned long flags;
374 struct ipc_message *msg;
375
376 spin_lock_irqsave(&byt->dsp->spinlock, flags);
377
378 msg = sst_byt_msg_get_empty(byt);
379 if (msg == NULL) {
380 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
381 return -EBUSY;
382 }
383
384 msg->header = header;
385 msg->tx_size = tx_bytes;
386 msg->rx_size = rx_bytes;
387 msg->wait = wait;
388 msg->errno = 0;
389 msg->complete = false;
390
391 if (tx_bytes) {
392 /* msg content = lower 32-bit of the header + data */
393 *(u32 *)msg->tx_data = (u32)(header & (u32)-1);
394 memcpy(msg->tx_data + sizeof(u32), tx_data, tx_bytes);
395 msg->tx_size += sizeof(u32);
396 }
397
398 list_add_tail(&msg->list, &byt->tx_list);
399 spin_unlock_irqrestore(&byt->dsp->spinlock, flags);
400
401 queue_kthread_work(&byt->kworker, &byt->kwork);
402
403 if (wait)
404 return sst_byt_tx_wait_done(byt, msg, rx_data);
405 else
406 return 0;
407}
408
409static inline int sst_byt_ipc_tx_msg_wait(struct sst_byt *byt, u64 header,
410 void *tx_data, size_t tx_bytes,
411 void *rx_data, size_t rx_bytes)
412{
413 return sst_byt_ipc_tx_message(byt, header, tx_data, tx_bytes,
414 rx_data, rx_bytes, 1);
415}
416
417static inline int sst_byt_ipc_tx_msg_nowait(struct sst_byt *byt, u64 header,
418 void *tx_data, size_t tx_bytes)
419{
420 return sst_byt_ipc_tx_message(byt, header, tx_data, tx_bytes,
421 NULL, 0, 0);
422}
423
424static struct ipc_message *sst_byt_reply_find_msg(struct sst_byt *byt,
425 u64 header)
426{
427 struct ipc_message *msg = NULL, *_msg;
428 u64 mask;
429
430 /* match reply to message sent based on msg and stream IDs */
431 mask = IPC_HEADER_MSG_ID_MASK |
432 IPC_HEADER_STR_ID_MASK << IPC_HEADER_STR_ID_SHIFT;
433 header &= mask;
434
435 if (list_empty(&byt->rx_list)) {
436 dev_err(byt->dev,
437 "ipc: rx list is empty but received 0x%llx\n", header);
438 goto out;
439 }
440
441 list_for_each_entry(_msg, &byt->rx_list, list) {
442 if ((_msg->header & mask) == header) {
443 msg = _msg;
444 break;
445 }
446 }
447
448out:
449 return msg;
450}
451
452static void sst_byt_stream_update(struct sst_byt *byt, struct ipc_message *msg) 226static void sst_byt_stream_update(struct sst_byt *byt, struct ipc_message *msg)
453{ 227{
454 struct sst_byt_stream *stream; 228 struct sst_byt_stream *stream;
@@ -477,7 +251,7 @@ static int sst_byt_process_reply(struct sst_byt *byt, u64 header)
477{ 251{
478 struct ipc_message *msg; 252 struct ipc_message *msg;
479 253
480 msg = sst_byt_reply_find_msg(byt, header); 254 msg = sst_ipc_reply_find_msg(&byt->ipc, header);
481 if (msg == NULL) 255 if (msg == NULL)
482 return 1; 256 return 1;
483 257
@@ -491,7 +265,7 @@ static int sst_byt_process_reply(struct sst_byt *byt, u64 header)
491 265
492 list_del(&msg->list); 266 list_del(&msg->list);
493 /* wake up */ 267 /* wake up */
494 sst_byt_tx_msg_reply_complete(byt, msg); 268 sst_ipc_tx_msg_reply_complete(&byt->ipc, msg);
495 269
496 return 1; 270 return 1;
497} 271}
@@ -538,6 +312,7 @@ static irqreturn_t sst_byt_irq_thread(int irq, void *context)
538{ 312{
539 struct sst_dsp *sst = (struct sst_dsp *) context; 313 struct sst_dsp *sst = (struct sst_dsp *) context;
540 struct sst_byt *byt = sst_dsp_get_thread_context(sst); 314 struct sst_byt *byt = sst_dsp_get_thread_context(sst);
315 struct sst_generic_ipc *ipc = &byt->ipc;
541 u64 header; 316 u64 header;
542 unsigned long flags; 317 unsigned long flags;
543 318
@@ -569,7 +344,7 @@ static irqreturn_t sst_byt_irq_thread(int irq, void *context)
569 spin_unlock_irqrestore(&sst->spinlock, flags); 344 spin_unlock_irqrestore(&sst->spinlock, flags);
570 345
571 /* continue to send any remaining messages... */ 346 /* continue to send any remaining messages... */
572 queue_kthread_work(&byt->kworker, &byt->kwork); 347 queue_kthread_work(&ipc->kworker, &ipc->kwork);
573 348
574 return IRQ_HANDLED; 349 return IRQ_HANDLED;
575} 350}
@@ -656,7 +431,8 @@ int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream)
656 header = sst_byt_header(IPC_IA_ALLOC_STREAM, 431 header = sst_byt_header(IPC_IA_ALLOC_STREAM,
657 sizeof(*str_req) + sizeof(u32), 432 sizeof(*str_req) + sizeof(u32),
658 true, stream->str_id); 433 true, stream->str_id);
659 ret = sst_byt_ipc_tx_msg_wait(byt, header, str_req, sizeof(*str_req), 434 ret = sst_ipc_tx_message_wait(&byt->ipc, header, str_req,
435 sizeof(*str_req),
660 reply, sizeof(*reply)); 436 reply, sizeof(*reply));
661 if (ret < 0) { 437 if (ret < 0) {
662 dev_err(byt->dev, "ipc: error stream commit failed\n"); 438 dev_err(byt->dev, "ipc: error stream commit failed\n");
@@ -679,7 +455,7 @@ int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream)
679 goto out; 455 goto out;
680 456
681 header = sst_byt_header(IPC_IA_FREE_STREAM, 0, false, stream->str_id); 457 header = sst_byt_header(IPC_IA_FREE_STREAM, 0, false, stream->str_id);
682 ret = sst_byt_ipc_tx_msg_wait(byt, header, NULL, 0, NULL, 0); 458 ret = sst_ipc_tx_message_wait(&byt->ipc, header, NULL, 0, NULL, 0);
683 if (ret < 0) { 459 if (ret < 0) {
684 dev_err(byt->dev, "ipc: free stream %d failed\n", 460 dev_err(byt->dev, "ipc: free stream %d failed\n",
685 stream->str_id); 461 stream->str_id);
@@ -703,9 +479,11 @@ static int sst_byt_stream_operations(struct sst_byt *byt, int type,
703 479
704 header = sst_byt_header(type, 0, false, stream_id); 480 header = sst_byt_header(type, 0, false, stream_id);
705 if (wait) 481 if (wait)
706 return sst_byt_ipc_tx_msg_wait(byt, header, NULL, 0, NULL, 0); 482 return sst_ipc_tx_message_wait(&byt->ipc, header, NULL,
483 0, NULL, 0);
707 else 484 else
708 return sst_byt_ipc_tx_msg_nowait(byt, header, NULL, 0); 485 return sst_ipc_tx_message_nowait(&byt->ipc, header,
486 NULL, 0);
709} 487}
710 488
711/* stream ALSA trigger operations */ 489/* stream ALSA trigger operations */
@@ -725,7 +503,7 @@ int sst_byt_stream_start(struct sst_byt *byt, struct sst_byt_stream *stream,
725 tx_msg = &start_stream; 503 tx_msg = &start_stream;
726 size = sizeof(start_stream); 504 size = sizeof(start_stream);
727 505
728 ret = sst_byt_ipc_tx_msg_nowait(byt, header, tx_msg, size); 506 ret = sst_ipc_tx_message_nowait(&byt->ipc, header, tx_msg, size);
729 if (ret < 0) 507 if (ret < 0)
730 dev_err(byt->dev, "ipc: error failed to start stream %d\n", 508 dev_err(byt->dev, "ipc: error failed to start stream %d\n",
731 stream->str_id); 509 stream->str_id);
@@ -790,23 +568,6 @@ int sst_byt_get_dsp_position(struct sst_byt *byt,
790 return do_div(fw_tstamp.ring_buffer_counter, buffer_size); 568 return do_div(fw_tstamp.ring_buffer_counter, buffer_size);
791} 569}
792 570
793static int msg_empty_list_init(struct sst_byt *byt)
794{
795 struct ipc_message *msg;
796 int i;
797
798 byt->msg = kzalloc(sizeof(*msg) * IPC_EMPTY_LIST_SIZE, GFP_KERNEL);
799 if (byt->msg == NULL)
800 return -ENOMEM;
801
802 for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
803 init_waitqueue_head(&byt->msg[i].waitq);
804 list_add(&byt->msg[i].list, &byt->empty_list);
805 }
806
807 return 0;
808}
809
810struct sst_dsp *sst_byt_get_dsp(struct sst_byt *byt) 571struct sst_dsp *sst_byt_get_dsp(struct sst_byt *byt)
811{ 572{
812 return byt->dsp; 573 return byt->dsp;
@@ -823,7 +584,7 @@ int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata)
823 584
824 dev_dbg(byt->dev, "dsp reset\n"); 585 dev_dbg(byt->dev, "dsp reset\n");
825 sst_dsp_reset(byt->dsp); 586 sst_dsp_reset(byt->dsp);
826 sst_byt_drop_all(byt); 587 sst_ipc_drop_all(&byt->ipc);
827 dev_dbg(byt->dev, "dsp in reset\n"); 588 dev_dbg(byt->dev, "dsp in reset\n");
828 589
829 dev_dbg(byt->dev, "free all blocks and unload fw\n"); 590 dev_dbg(byt->dev, "free all blocks and unload fw\n");
@@ -876,9 +637,52 @@ int sst_byt_dsp_wait_for_ready(struct device *dev, struct sst_pdata *pdata)
876} 637}
877EXPORT_SYMBOL_GPL(sst_byt_dsp_wait_for_ready); 638EXPORT_SYMBOL_GPL(sst_byt_dsp_wait_for_ready);
878 639
640static void byt_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
641{
642 if (msg->header & IPC_HEADER_LARGE(true))
643 sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size);
644
645 sst_dsp_shim_write64_unlocked(ipc->dsp, SST_IPCX, msg->header);
646}
647
648static void byt_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
649{
650 struct sst_dsp *sst = ipc->dsp;
651 u64 isr, ipcd, imrx, ipcx;
652
653 ipcx = sst_dsp_shim_read64_unlocked(sst, SST_IPCX);
654 isr = sst_dsp_shim_read64_unlocked(sst, SST_ISRX);
655 ipcd = sst_dsp_shim_read64_unlocked(sst, SST_IPCD);
656 imrx = sst_dsp_shim_read64_unlocked(sst, SST_IMRX);
657
658 dev_err(ipc->dev,
659 "ipc: --%s-- ipcx 0x%llx isr 0x%llx ipcd 0x%llx imrx 0x%llx\n",
660 text, ipcx, isr, ipcd, imrx);
661}
662
663static void byt_tx_data_copy(struct ipc_message *msg, char *tx_data,
664 size_t tx_size)
665{
666 /* msg content = lower 32-bit of the header + data */
667 *(u32 *)msg->tx_data = (u32)(msg->header & (u32)-1);
668 memcpy(msg->tx_data + sizeof(u32), tx_data, tx_size);
669 msg->tx_size += sizeof(u32);
670}
671
672static u64 byt_reply_msg_match(u64 header, u64 *mask)
673{
674 /* match reply to message sent based on msg and stream IDs */
675 *mask = IPC_HEADER_MSG_ID_MASK |
676 IPC_HEADER_STR_ID_MASK << IPC_HEADER_STR_ID_SHIFT;
677 header &= *mask;
678
679 return header;
680}
681
879int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata) 682int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata)
880{ 683{
881 struct sst_byt *byt; 684 struct sst_byt *byt;
685 struct sst_generic_ipc *ipc;
882 struct sst_fw *byt_sst_fw; 686 struct sst_fw *byt_sst_fw;
883 struct sst_byt_fw_init init; 687 struct sst_byt_fw_init init;
884 int err; 688 int err;
@@ -889,39 +693,30 @@ int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata)
889 if (byt == NULL) 693 if (byt == NULL)
890 return -ENOMEM; 694 return -ENOMEM;
891 695
892 byt->dev = dev; 696 ipc = &byt->ipc;
893 INIT_LIST_HEAD(&byt->stream_list); 697 ipc->dev = dev;
894 INIT_LIST_HEAD(&byt->tx_list); 698 ipc->ops.tx_msg = byt_tx_msg;
895 INIT_LIST_HEAD(&byt->rx_list); 699 ipc->ops.shim_dbg = byt_shim_dbg;
896 INIT_LIST_HEAD(&byt->empty_list); 700 ipc->ops.tx_data_copy = byt_tx_data_copy;
897 init_waitqueue_head(&byt->boot_wait); 701 ipc->ops.reply_msg_match = byt_reply_msg_match;
898 init_waitqueue_head(&byt->wait_txq);
899 702
900 err = msg_empty_list_init(byt); 703 err = sst_ipc_init(ipc);
901 if (err < 0) 704 if (err != 0)
902 return -ENOMEM; 705 goto ipc_init_err;
903
904 /* start the IPC message thread */
905 init_kthread_worker(&byt->kworker);
906 byt->tx_thread = kthread_run(kthread_worker_fn,
907 &byt->kworker, "%s",
908 dev_name(byt->dev));
909 if (IS_ERR(byt->tx_thread)) {
910 err = PTR_ERR(byt->tx_thread);
911 dev_err(byt->dev, "error failed to create message TX task\n");
912 goto err_free_msg;
913 }
914 init_kthread_work(&byt->kwork, sst_byt_ipc_tx_msgs);
915 706
707 INIT_LIST_HEAD(&byt->stream_list);
708 init_waitqueue_head(&byt->boot_wait);
916 byt_dev.thread_context = byt; 709 byt_dev.thread_context = byt;
917 710
918 /* init SST shim */ 711 /* init SST shim */
919 byt->dsp = sst_dsp_new(dev, &byt_dev, pdata); 712 byt->dsp = sst_dsp_new(dev, &byt_dev, pdata);
920 if (byt->dsp == NULL) { 713 if (byt->dsp == NULL) {
921 err = -ENODEV; 714 err = -ENODEV;
922 goto dsp_err; 715 goto dsp_new_err;
923 } 716 }
924 717
718 ipc->dsp = byt->dsp;
719
925 /* keep the DSP in reset state for base FW loading */ 720 /* keep the DSP in reset state for base FW loading */
926 sst_dsp_reset(byt->dsp); 721 sst_dsp_reset(byt->dsp);
927 722
@@ -961,10 +756,10 @@ boot_err:
961 sst_fw_free(byt_sst_fw); 756 sst_fw_free(byt_sst_fw);
962fw_err: 757fw_err:
963 sst_dsp_free(byt->dsp); 758 sst_dsp_free(byt->dsp);
964dsp_err: 759dsp_new_err:
965 kthread_stop(byt->tx_thread); 760 sst_ipc_fini(ipc);
966err_free_msg: 761ipc_init_err:
967 kfree(byt->msg); 762 kfree(byt);
968 763
969 return err; 764 return err;
970} 765}
@@ -977,7 +772,6 @@ void sst_byt_dsp_free(struct device *dev, struct sst_pdata *pdata)
977 sst_dsp_reset(byt->dsp); 772 sst_dsp_reset(byt->dsp);
978 sst_fw_free_all(byt->dsp); 773 sst_fw_free_all(byt->dsp);
979 sst_dsp_free(byt->dsp); 774 sst_dsp_free(byt->dsp);
980 kthread_stop(byt->tx_thread); 775 sst_ipc_fini(&byt->ipc);
981 kfree(byt->msg);
982} 776}
983EXPORT_SYMBOL_GPL(sst_byt_dsp_free); 777EXPORT_SYMBOL_GPL(sst_byt_dsp_free);
diff --git a/sound/soc/intel/sst-baytrail-ipc.h b/sound/soc/intel/baytrail/sst-baytrail-ipc.h
index 8faff6dcf25d..8faff6dcf25d 100644
--- a/sound/soc/intel/sst-baytrail-ipc.h
+++ b/sound/soc/intel/baytrail/sst-baytrail-ipc.h
diff --git a/sound/soc/intel/sst-baytrail-pcm.c b/sound/soc/intel/baytrail/sst-baytrail-pcm.c
index 224c49c9f135..79547bec558b 100644
--- a/sound/soc/intel/sst-baytrail-pcm.c
+++ b/sound/soc/intel/baytrail/sst-baytrail-pcm.c
@@ -20,8 +20,8 @@
20#include <sound/pcm_params.h> 20#include <sound/pcm_params.h>
21#include <sound/soc.h> 21#include <sound/soc.h>
22#include "sst-baytrail-ipc.h" 22#include "sst-baytrail-ipc.h"
23#include "sst-dsp-priv.h" 23#include "../common/sst-dsp-priv.h"
24#include "sst-dsp.h" 24#include "../common/sst-dsp.h"
25 25
26#define BYT_PCM_COUNT 2 26#define BYT_PCM_COUNT 2
27 27
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
new file mode 100644
index 000000000000..f8237f0044eb
--- /dev/null
+++ b/sound/soc/intel/boards/Makefile
@@ -0,0 +1,15 @@
1snd-soc-sst-haswell-objs := haswell.o
2snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o
3snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o
4snd-soc-sst-broadwell-objs := broadwell.o
5snd-soc-sst-bytcr-rt5640-objs := bytcr_rt5640.o
6snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
7snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o
8
9obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
10obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
11obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o
12obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o
13obj-$(CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH) += snd-soc-sst-bytcr-rt5640.o
14obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
15obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o
diff --git a/sound/soc/intel/broadwell.c b/sound/soc/intel/boards/broadwell.c
index 9cf7d01479ad..8bafaf6ceab1 100644
--- a/sound/soc/intel/broadwell.c
+++ b/sound/soc/intel/boards/broadwell.c
@@ -22,10 +22,10 @@
22#include <sound/jack.h> 22#include <sound/jack.h>
23#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
24 24
25#include "sst-dsp.h" 25#include "../common/sst-dsp.h"
26#include "sst-haswell-ipc.h" 26#include "../haswell/sst-haswell-ipc.h"
27 27
28#include "../codecs/rt286.h" 28#include "../../codecs/rt286.h"
29 29
30static struct snd_soc_jack broadwell_headset; 30static struct snd_soc_jack broadwell_headset;
31/* Headset jack detection DAPM pins */ 31/* Headset jack detection DAPM pins */
@@ -80,15 +80,9 @@ static int broadwell_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
80{ 80{
81 struct snd_soc_codec *codec = rtd->codec; 81 struct snd_soc_codec *codec = rtd->codec;
82 int ret = 0; 82 int ret = 0;
83 ret = snd_soc_jack_new(codec, "Headset", 83 ret = snd_soc_card_jack_new(rtd->card, "Headset",
84 SND_JACK_HEADSET | SND_JACK_BTN_0, &broadwell_headset); 84 SND_JACK_HEADSET | SND_JACK_BTN_0, &broadwell_headset,
85 85 broadwell_headset_pins, ARRAY_SIZE(broadwell_headset_pins));
86 if (ret)
87 return ret;
88
89 ret = snd_soc_jack_add_pins(&broadwell_headset,
90 ARRAY_SIZE(broadwell_headset_pins),
91 broadwell_headset_pins);
92 if (ret) 86 if (ret)
93 return ret; 87 return ret;
94 88
@@ -110,9 +104,7 @@ static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
110 channels->min = channels->max = 2; 104 channels->min = channels->max = 2;
111 105
112 /* set SSP0 to 16 bit */ 106 /* set SSP0 to 16 bit */
113 snd_mask_set(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT - 107 params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
114 SNDRV_PCM_HW_PARAM_FIRST_MASK],
115 SNDRV_PCM_FORMAT_S16_LE);
116 return 0; 108 return 0;
117} 109}
118 110
@@ -227,6 +219,32 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = {
227 }, 219 },
228}; 220};
229 221
222static int broadwell_suspend(struct snd_soc_card *card){
223 struct snd_soc_codec *codec;
224
225 list_for_each_entry(codec, &card->codec_dev_list, card_list) {
226 if (!strcmp(codec->component.name, "i2c-INT343A:00")) {
227 dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n");
228 rt286_mic_detect(codec, NULL);
229 break;
230 }
231 }
232 return 0;
233}
234
235static int broadwell_resume(struct snd_soc_card *card){
236 struct snd_soc_codec *codec;
237
238 list_for_each_entry(codec, &card->codec_dev_list, card_list) {
239 if (!strcmp(codec->component.name, "i2c-INT343A:00")) {
240 dev_dbg(codec->dev, "enabling jack detect for resume.\n");
241 rt286_mic_detect(codec, &broadwell_headset);
242 break;
243 }
244 }
245 return 0;
246}
247
230/* broadwell audio machine driver for WPT + RT286S */ 248/* broadwell audio machine driver for WPT + RT286S */
231static struct snd_soc_card broadwell_rt286 = { 249static struct snd_soc_card broadwell_rt286 = {
232 .name = "broadwell-rt286", 250 .name = "broadwell-rt286",
@@ -240,6 +258,8 @@ static struct snd_soc_card broadwell_rt286 = {
240 .dapm_routes = broadwell_rt286_map, 258 .dapm_routes = broadwell_rt286_map,
241 .num_dapm_routes = ARRAY_SIZE(broadwell_rt286_map), 259 .num_dapm_routes = ARRAY_SIZE(broadwell_rt286_map),
242 .fully_routed = true, 260 .fully_routed = true,
261 .suspend_pre = broadwell_suspend,
262 .resume_post = broadwell_resume,
243}; 263};
244 264
245static int broadwell_audio_probe(struct platform_device *pdev) 265static int broadwell_audio_probe(struct platform_device *pdev)
diff --git a/sound/soc/intel/byt-max98090.c b/sound/soc/intel/boards/byt-max98090.c
index 9832afe7d22c..7ab8cc9fbfd5 100644
--- a/sound/soc/intel/byt-max98090.c
+++ b/sound/soc/intel/boards/byt-max98090.c
@@ -24,7 +24,7 @@
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/jack.h> 26#include <sound/jack.h>
27#include "../codecs/max98090.h" 27#include "../../codecs/max98090.h"
28 28
29struct byt_max98090_private { 29struct byt_max98090_private {
30 struct snd_soc_jack jack; 30 struct snd_soc_jack jack;
@@ -84,7 +84,6 @@ static struct snd_soc_jack_gpio hs_jack_gpios[] = {
84static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime) 84static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime)
85{ 85{
86 int ret; 86 int ret;
87 struct snd_soc_codec *codec = runtime->codec;
88 struct snd_soc_card *card = runtime->card; 87 struct snd_soc_card *card = runtime->card;
89 struct byt_max98090_private *drv = snd_soc_card_get_drvdata(card); 88 struct byt_max98090_private *drv = snd_soc_card_get_drvdata(card);
90 struct snd_soc_jack *jack = &drv->jack; 89 struct snd_soc_jack *jack = &drv->jack;
@@ -100,13 +99,9 @@ static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime)
100 } 99 }
101 100
102 /* Enable jack detection */ 101 /* Enable jack detection */
103 ret = snd_soc_jack_new(codec, "Headset", 102 ret = snd_soc_card_jack_new(runtime->card, "Headset",
104 SND_JACK_LINEOUT | SND_JACK_HEADSET, jack); 103 SND_JACK_LINEOUT | SND_JACK_HEADSET, jack,
105 if (ret) 104 hs_jack_pins, ARRAY_SIZE(hs_jack_pins));
106 return ret;
107
108 ret = snd_soc_jack_add_pins(jack, ARRAY_SIZE(hs_jack_pins),
109 hs_jack_pins);
110 if (ret) 105 if (ret)
111 return ret; 106 return ret;
112 107
diff --git a/sound/soc/intel/byt-rt5640.c b/sound/soc/intel/boards/byt-rt5640.c
index 354eaad886e1..ae89b9b966d9 100644
--- a/sound/soc/intel/byt-rt5640.c
+++ b/sound/soc/intel/boards/byt-rt5640.c
@@ -23,9 +23,9 @@
23#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include <sound/jack.h> 25#include <sound/jack.h>
26#include "../codecs/rt5640.h" 26#include "../../codecs/rt5640.h"
27 27
28#include "sst-dsp.h" 28#include "../common/sst-dsp.h"
29 29
30static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = { 30static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
31 SND_SOC_DAPM_HP("Headphone", NULL), 31 SND_SOC_DAPM_HP("Headphone", NULL),
diff --git a/sound/soc/intel/bytcr_dpcm_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
index 59308629043e..7f55d59024a8 100644
--- a/sound/soc/intel/bytcr_dpcm_rt5640.c
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
@@ -26,8 +26,8 @@
26#include <sound/pcm.h> 26#include <sound/pcm.h>
27#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include "../codecs/rt5640.h" 29#include "../../codecs/rt5640.h"
30#include "sst-atom-controls.h" 30#include "../atom/sst-atom-controls.h"
31 31
32static const struct snd_soc_dapm_widget byt_dapm_widgets[] = { 32static const struct snd_soc_dapm_widget byt_dapm_widgets[] = {
33 SND_SOC_DAPM_HP("Headphone", NULL), 33 SND_SOC_DAPM_HP("Headphone", NULL),
@@ -113,9 +113,7 @@ static int byt_codec_fixup(struct snd_soc_pcm_runtime *rtd,
113 channels->min = channels->max = 2; 113 channels->min = channels->max = 2;
114 114
115 /* set SSP2 to 24-bit */ 115 /* set SSP2 to 24-bit */
116 snd_mask_set(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT - 116 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
117 SNDRV_PCM_HW_PARAM_FIRST_MASK],
118 SNDRV_PCM_FORMAT_S24_LE);
119 return 0; 117 return 0;
120} 118}
121 119
diff --git a/sound/soc/intel/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c
index bd29617a9ab9..20a28b22e30f 100644
--- a/sound/soc/intel/cht_bsw_rt5645.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5645.c
@@ -27,8 +27,8 @@
27#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/jack.h> 29#include <sound/jack.h>
30#include "../codecs/rt5645.h" 30#include "../../codecs/rt5645.h"
31#include "sst-atom-controls.h" 31#include "../atom/sst-atom-controls.h"
32 32
33#define CHT_PLAT_CLK_3_HZ 19200000 33#define CHT_PLAT_CLK_3_HZ 19200000
34#define CHT_CODEC_DAI "rt5645-aif1" 34#define CHT_CODEC_DAI "rt5645-aif1"
@@ -169,17 +169,17 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
169 return ret; 169 return ret;
170 } 170 }
171 171
172 ret = snd_soc_jack_new(codec, "Headphone Jack", 172 ret = snd_soc_card_jack_new(runtime->card, "Headphone Jack",
173 SND_JACK_HEADPHONE, 173 SND_JACK_HEADPHONE, &ctx->hp_jack,
174 &ctx->hp_jack); 174 NULL, 0);
175 if (ret) { 175 if (ret) {
176 dev_err(runtime->dev, "HP jack creation failed %d\n", ret); 176 dev_err(runtime->dev, "HP jack creation failed %d\n", ret);
177 return ret; 177 return ret;
178 } 178 }
179 179
180 ret = snd_soc_jack_new(codec, "Mic Jack", 180 ret = snd_soc_card_jack_new(runtime->card, "Mic Jack",
181 SND_JACK_MICROPHONE, 181 SND_JACK_MICROPHONE, &ctx->mic_jack,
182 &ctx->mic_jack); 182 NULL, 0);
183 if (ret) { 183 if (ret) {
184 dev_err(runtime->dev, "Mic jack creation failed %d\n", ret); 184 dev_err(runtime->dev, "Mic jack creation failed %d\n", ret);
185 return ret; 185 return ret;
@@ -203,9 +203,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
203 channels->min = channels->max = 2; 203 channels->min = channels->max = 2;
204 204
205 /* set SSP2 to 24-bit */ 205 /* set SSP2 to 24-bit */
206 snd_mask_set(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT - 206 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
207 SNDRV_PCM_HW_PARAM_FIRST_MASK],
208 SNDRV_PCM_FORMAT_S24_LE);
209 return 0; 207 return 0;
210} 208}
211 209
diff --git a/sound/soc/intel/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c
index ff016621583a..2c9cc5be439e 100644
--- a/sound/soc/intel/cht_bsw_rt5672.c
+++ b/sound/soc/intel/boards/cht_bsw_rt5672.c
@@ -22,13 +22,28 @@
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include "../codecs/rt5670.h" 25#include <sound/jack.h>
26#include "sst-atom-controls.h" 26#include "../../codecs/rt5670.h"
27#include "../atom/sst-atom-controls.h"
27 28
28/* The platform clock #3 outputs 19.2Mhz clock to codec as I2S MCLK */ 29/* The platform clock #3 outputs 19.2Mhz clock to codec as I2S MCLK */
29#define CHT_PLAT_CLK_3_HZ 19200000 30#define CHT_PLAT_CLK_3_HZ 19200000
30#define CHT_CODEC_DAI "rt5670-aif1" 31#define CHT_CODEC_DAI "rt5670-aif1"
31 32
33static struct snd_soc_jack cht_bsw_headset;
34
35/* Headset jack detection DAPM pins */
36static struct snd_soc_jack_pin cht_bsw_headset_pins[] = {
37 {
38 .pin = "Headset Mic",
39 .mask = SND_JACK_MICROPHONE,
40 },
41 {
42 .pin = "Headphone",
43 .mask = SND_JACK_HEADPHONE,
44 },
45};
46
32static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card) 47static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card)
33{ 48{
34 int i; 49 int i;
@@ -50,6 +65,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
50 struct snd_soc_dapm_context *dapm = w->dapm; 65 struct snd_soc_dapm_context *dapm = w->dapm;
51 struct snd_soc_card *card = dapm->card; 66 struct snd_soc_card *card = dapm->card;
52 struct snd_soc_dai *codec_dai; 67 struct snd_soc_dai *codec_dai;
68 int ret;
53 69
54 codec_dai = cht_get_codec_dai(card); 70 codec_dai = cht_get_codec_dai(card);
55 if (!codec_dai) { 71 if (!codec_dai) {
@@ -57,17 +73,31 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
57 return -EIO; 73 return -EIO;
58 } 74 }
59 75
60 if (!SND_SOC_DAPM_EVENT_OFF(event)) 76 if (SND_SOC_DAPM_EVENT_ON(event)) {
61 return 0; 77 /* set codec PLL source to the 19.2MHz platform clock (MCLK) */
62 78 ret = snd_soc_dai_set_pll(codec_dai, 0, RT5670_PLL1_S_MCLK,
63 /* Set codec sysclk source to its internal clock because codec PLL will 79 CHT_PLAT_CLK_3_HZ, 48000 * 512);
64 * be off when idle and MCLK will also be off by ACPI when codec is 80 if (ret < 0) {
65 * runtime suspended. Codec needs clock for jack detection and button 81 dev_err(card->dev, "can't set codec pll: %d\n", ret);
66 * press. 82 return ret;
67 */ 83 }
68 snd_soc_dai_set_sysclk(codec_dai, RT5670_SCLK_S_RCCLK, 84
69 0, SND_SOC_CLOCK_IN); 85 /* set codec sysclk source to PLL */
70 86 ret = snd_soc_dai_set_sysclk(codec_dai, RT5670_SCLK_S_PLL1,
87 48000 * 512, SND_SOC_CLOCK_IN);
88 if (ret < 0) {
89 dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
90 return ret;
91 }
92 } else {
93 /* Set codec sysclk source to its internal clock because codec
94 * PLL will be off when idle and MCLK will also be off by ACPI
95 * when codec is runtime suspended. Codec needs clock for jack
96 * detection and button press.
97 */
98 snd_soc_dai_set_sysclk(codec_dai, RT5670_SCLK_S_RCCLK,
99 48000 * 512, SND_SOC_CLOCK_IN);
100 }
71 return 0; 101 return 0;
72} 102}
73 103
@@ -77,7 +107,8 @@ static const struct snd_soc_dapm_widget cht_dapm_widgets[] = {
77 SND_SOC_DAPM_MIC("Int Mic", NULL), 107 SND_SOC_DAPM_MIC("Int Mic", NULL),
78 SND_SOC_DAPM_SPK("Ext Spk", NULL), 108 SND_SOC_DAPM_SPK("Ext Spk", NULL),
79 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, 109 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
80 platform_clock_control, SND_SOC_DAPM_POST_PMD), 110 platform_clock_control, SND_SOC_DAPM_PRE_PMU |
111 SND_SOC_DAPM_POST_PMD),
81}; 112};
82 113
83static const struct snd_soc_dapm_route cht_audio_map[] = { 114static const struct snd_soc_dapm_route cht_audio_map[] = {
@@ -162,6 +193,15 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
162 | RT5670_AD_MONO_L_FILTER 193 | RT5670_AD_MONO_L_FILTER
163 | RT5670_AD_MONO_R_FILTER, 194 | RT5670_AD_MONO_R_FILTER,
164 RT5670_CLK_SEL_I2S1_ASRC); 195 RT5670_CLK_SEL_I2S1_ASRC);
196
197 ret = snd_soc_card_jack_new(runtime->card, "Headset",
198 SND_JACK_HEADSET | SND_JACK_BTN_0 |
199 SND_JACK_BTN_1 | SND_JACK_BTN_2, &cht_bsw_headset,
200 cht_bsw_headset_pins, ARRAY_SIZE(cht_bsw_headset_pins));
201 if (ret)
202 return ret;
203
204 rt5670_set_jack_detect(codec, &cht_bsw_headset);
165 return 0; 205 return 0;
166} 206}
167 207
@@ -178,9 +218,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
178 channels->min = channels->max = 2; 218 channels->min = channels->max = 2;
179 219
180 /* set SSP2 to 24-bit */ 220 /* set SSP2 to 24-bit */
181 snd_mask_set(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT - 221 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
182 SNDRV_PCM_HW_PARAM_FIRST_MASK],
183 SNDRV_PCM_FORMAT_S24_LE);
184 return 0; 222 return 0;
185} 223}
186 224
@@ -217,7 +255,7 @@ static struct snd_soc_dai_link cht_dailink[] = {
217 .codec_dai_name = "snd-soc-dummy-dai", 255 .codec_dai_name = "snd-soc-dummy-dai",
218 .codec_name = "snd-soc-dummy", 256 .codec_name = "snd-soc-dummy",
219 .platform_name = "sst-mfld-platform", 257 .platform_name = "sst-mfld-platform",
220 .ignore_suspend = 1, 258 .nonatomic = true,
221 .dynamic = 1, 259 .dynamic = 1,
222 .dpcm_playback = 1, 260 .dpcm_playback = 1,
223 .dpcm_capture = 1, 261 .dpcm_capture = 1,
@@ -240,19 +278,48 @@ static struct snd_soc_dai_link cht_dailink[] = {
240 .cpu_dai_name = "ssp2-port", 278 .cpu_dai_name = "ssp2-port",
241 .platform_name = "sst-mfld-platform", 279 .platform_name = "sst-mfld-platform",
242 .no_pcm = 1, 280 .no_pcm = 1,
281 .nonatomic = true,
243 .codec_dai_name = "rt5670-aif1", 282 .codec_dai_name = "rt5670-aif1",
244 .codec_name = "i2c-10EC5670:00", 283 .codec_name = "i2c-10EC5670:00",
245 .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF 284 .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF
246 | SND_SOC_DAIFMT_CBS_CFS, 285 | SND_SOC_DAIFMT_CBS_CFS,
247 .init = cht_codec_init, 286 .init = cht_codec_init,
248 .be_hw_params_fixup = cht_codec_fixup, 287 .be_hw_params_fixup = cht_codec_fixup,
249 .ignore_suspend = 1,
250 .dpcm_playback = 1, 288 .dpcm_playback = 1,
251 .dpcm_capture = 1, 289 .dpcm_capture = 1,
252 .ops = &cht_be_ssp2_ops, 290 .ops = &cht_be_ssp2_ops,
253 }, 291 },
254}; 292};
255 293
294static int cht_suspend_pre(struct snd_soc_card *card)
295{
296 struct snd_soc_codec *codec;
297
298 list_for_each_entry(codec, &card->codec_dev_list, card_list) {
299 if (!strcmp(codec->component.name, "i2c-10EC5670:00")) {
300 dev_dbg(codec->dev, "disabling jack detect before going to suspend.\n");
301 rt5670_jack_suspend(codec);
302 break;
303 }
304 }
305 return 0;
306}
307
308static int cht_resume_post(struct snd_soc_card *card)
309{
310 struct snd_soc_codec *codec;
311
312 list_for_each_entry(codec, &card->codec_dev_list, card_list) {
313 if (!strcmp(codec->component.name, "i2c-10EC5670:00")) {
314 dev_dbg(codec->dev, "enabling jack detect for resume.\n");
315 rt5670_jack_resume(codec);
316 break;
317 }
318 }
319
320 return 0;
321}
322
256/* SoC card */ 323/* SoC card */
257static struct snd_soc_card snd_soc_card_cht = { 324static struct snd_soc_card snd_soc_card_cht = {
258 .name = "cherrytrailcraudio", 325 .name = "cherrytrailcraudio",
@@ -264,6 +331,8 @@ static struct snd_soc_card snd_soc_card_cht = {
264 .num_dapm_routes = ARRAY_SIZE(cht_audio_map), 331 .num_dapm_routes = ARRAY_SIZE(cht_audio_map),
265 .controls = cht_mc_controls, 332 .controls = cht_mc_controls,
266 .num_controls = ARRAY_SIZE(cht_mc_controls), 333 .num_controls = ARRAY_SIZE(cht_mc_controls),
334 .suspend_pre = cht_suspend_pre,
335 .resume_post = cht_resume_post,
267}; 336};
268 337
269static int snd_cht_mc_probe(struct platform_device *pdev) 338static int snd_cht_mc_probe(struct platform_device *pdev)
@@ -285,7 +354,6 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
285static struct platform_driver snd_cht_mc_driver = { 354static struct platform_driver snd_cht_mc_driver = {
286 .driver = { 355 .driver = {
287 .name = "cht-bsw-rt5672", 356 .name = "cht-bsw-rt5672",
288 .pm = &snd_soc_pm_ops,
289 }, 357 },
290 .probe = snd_cht_mc_probe, 358 .probe = snd_cht_mc_probe,
291}; 359};
diff --git a/sound/soc/intel/haswell.c b/sound/soc/intel/boards/haswell.c
index 35edf51a52aa..22558572cb9c 100644
--- a/sound/soc/intel/haswell.c
+++ b/sound/soc/intel/boards/haswell.c
@@ -21,10 +21,10 @@
21#include <sound/soc.h> 21#include <sound/soc.h>
22#include <sound/pcm_params.h> 22#include <sound/pcm_params.h>
23 23
24#include "sst-dsp.h" 24#include "../common/sst-dsp.h"
25#include "sst-haswell-ipc.h" 25#include "../haswell/sst-haswell-ipc.h"
26 26
27#include "../codecs/rt5640.h" 27#include "../../codecs/rt5640.h"
28 28
29/* Haswell ULT platforms have a Headphone and Mic jack */ 29/* Haswell ULT platforms have a Headphone and Mic jack */
30static const struct snd_soc_dapm_widget haswell_widgets[] = { 30static const struct snd_soc_dapm_widget haswell_widgets[] = {
@@ -56,9 +56,7 @@ static int haswell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
56 channels->min = channels->max = 2; 56 channels->min = channels->max = 2;
57 57
58 /* set SSP0 to 16 bit */ 58 /* set SSP0 to 16 bit */
59 snd_mask_set(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT - 59 params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
60 SNDRV_PCM_HW_PARAM_FIRST_MASK],
61 SNDRV_PCM_FORMAT_S16_LE);
62 return 0; 60 return 0;
63} 61}
64 62
diff --git a/sound/soc/intel/mfld_machine.c b/sound/soc/intel/boards/mfld_machine.c
index 90b7a57713a0..49c09a0add79 100644
--- a/sound/soc/intel/mfld_machine.c
+++ b/sound/soc/intel/boards/mfld_machine.c
@@ -228,10 +228,13 @@ static void mfld_jack_check(unsigned int intr_status)
228{ 228{
229 struct mfld_jack_data jack_data; 229 struct mfld_jack_data jack_data;
230 230
231 if (!mfld_codec)
232 return;
233
231 jack_data.mfld_jack = &mfld_jack; 234 jack_data.mfld_jack = &mfld_jack;
232 jack_data.intr_id = intr_status; 235 jack_data.intr_id = intr_status;
233 236
234 sn95031_jack_detection(&jack_data); 237 sn95031_jack_detection(mfld_codec, &jack_data);
235 /* TODO: add american headset detection post gpiolib support */ 238 /* TODO: add american headset detection post gpiolib support */
236} 239}
237 240
@@ -240,8 +243,6 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime)
240 struct snd_soc_dapm_context *dapm = &runtime->card->dapm; 243 struct snd_soc_dapm_context *dapm = &runtime->card->dapm;
241 int ret_val; 244 int ret_val;
242 245
243 mfld_codec = runtime->codec;
244
245 /* default is earpiece pin, userspace sets it explcitly */ 246 /* default is earpiece pin, userspace sets it explcitly */
246 snd_soc_dapm_disable_pin(dapm, "Headphones"); 247 snd_soc_dapm_disable_pin(dapm, "Headphones");
247 /* default is lineout NC, userspace sets it explcitly */ 248 /* default is lineout NC, userspace sets it explcitly */
@@ -254,20 +255,15 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime)
254 snd_soc_dapm_disable_pin(dapm, "LINEINR"); 255 snd_soc_dapm_disable_pin(dapm, "LINEINR");
255 256
256 /* Headset and button jack detection */ 257 /* Headset and button jack detection */
257 ret_val = snd_soc_jack_new(mfld_codec, "Intel(R) MID Audio Jack", 258 ret_val = snd_soc_card_jack_new(runtime->card,
258 SND_JACK_HEADSET | SND_JACK_BTN_0 | 259 "Intel(R) MID Audio Jack", SND_JACK_HEADSET |
259 SND_JACK_BTN_1, &mfld_jack); 260 SND_JACK_BTN_0 | SND_JACK_BTN_1, &mfld_jack,
261 mfld_jack_pins, ARRAY_SIZE(mfld_jack_pins));
260 if (ret_val) { 262 if (ret_val) {
261 pr_err("jack creation failed\n"); 263 pr_err("jack creation failed\n");
262 return ret_val; 264 return ret_val;
263 } 265 }
264 266
265 ret_val = snd_soc_jack_add_pins(&mfld_jack,
266 ARRAY_SIZE(mfld_jack_pins), mfld_jack_pins);
267 if (ret_val) {
268 pr_err("adding jack pins failed\n");
269 return ret_val;
270 }
271 ret_val = snd_soc_jack_add_zones(&mfld_jack, 267 ret_val = snd_soc_jack_add_zones(&mfld_jack,
272 ARRAY_SIZE(mfld_zones), mfld_zones); 268 ARRAY_SIZE(mfld_zones), mfld_zones);
273 if (ret_val) { 269 if (ret_val) {
@@ -275,6 +271,8 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime)
275 return ret_val; 271 return ret_val;
276 } 272 }
277 273
274 mfld_codec = runtime->codec;
275
278 /* we want to check if anything is inserted at boot, 276 /* we want to check if anything is inserted at boot,
279 * so send a fake event to codec and it will read adc 277 * so send a fake event to codec and it will read adc
280 * to find if anything is there or not */ 278 * to find if anything is there or not */
@@ -359,8 +357,6 @@ static irqreturn_t snd_mfld_jack_detection(int irq, void *data)
359{ 357{
360 struct mfld_mc_private *mc_drv_ctx = (struct mfld_mc_private *) data; 358 struct mfld_mc_private *mc_drv_ctx = (struct mfld_mc_private *) data;
361 359
362 if (mfld_jack.codec == NULL)
363 return IRQ_HANDLED;
364 mfld_jack_check(mc_drv_ctx->interrupt_status); 360 mfld_jack_check(mc_drv_ctx->interrupt_status);
365 361
366 return IRQ_HANDLED; 362 return IRQ_HANDLED;
diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile
new file mode 100644
index 000000000000..f24154ca4e98
--- /dev/null
+++ b/sound/soc/intel/common/Makefile
@@ -0,0 +1,7 @@
1snd-soc-sst-dsp-objs := sst-dsp.o sst-firmware.o
2snd-soc-sst-acpi-objs := sst-acpi.o
3snd-soc-sst-ipc-objs := sst-ipc.o
4
5obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o
6obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o
7
diff --git a/sound/soc/intel/sst-acpi.c b/sound/soc/intel/common/sst-acpi.c
index b3d84560fbb5..42f293f9c6e2 100644
--- a/sound/soc/intel/sst-acpi.c
+++ b/sound/soc/intel/common/sst-acpi.c
@@ -142,6 +142,7 @@ static int sst_acpi_probe(struct platform_device *pdev)
142 sst_acpi->desc = desc; 142 sst_acpi->desc = desc;
143 sst_acpi->mach = mach; 143 sst_acpi->mach = mach;
144 144
145 sst_pdata->resindex_dma_base = desc->resindex_dma_base;
145 if (desc->resindex_dma_base >= 0) { 146 if (desc->resindex_dma_base >= 0) {
146 sst_pdata->dma_engine = desc->dma_engine; 147 sst_pdata->dma_engine = desc->dma_engine;
147 sst_pdata->dma_base = desc->resindex_dma_base; 148 sst_pdata->dma_base = desc->resindex_dma_base;
diff --git a/sound/soc/intel/sst-dsp-priv.h b/sound/soc/intel/common/sst-dsp-priv.h
index b9da030e312d..396d54510350 100644
--- a/sound/soc/intel/sst-dsp-priv.h
+++ b/sound/soc/intel/common/sst-dsp-priv.h
@@ -173,6 +173,16 @@ struct sst_module_runtime_context {
173}; 173};
174 174
175/* 175/*
176 * Audio DSP Module State
177 */
178enum sst_module_state {
179 SST_MODULE_STATE_UNLOADED = 0, /* default state */
180 SST_MODULE_STATE_LOADED,
181 SST_MODULE_STATE_INITIALIZED, /* and inactive */
182 SST_MODULE_STATE_ACTIVE,
183};
184
185/*
176 * Audio DSP Generic Module. 186 * Audio DSP Generic Module.
177 * 187 *
178 * Each Firmware file can consist of 1..N modules. A module can span multiple 188 * Each Firmware file can consist of 1..N modules. A module can span multiple
@@ -203,6 +213,9 @@ struct sst_module {
203 struct list_head list; /* DSP list of modules */ 213 struct list_head list; /* DSP list of modules */
204 struct list_head list_fw; /* FW list of modules */ 214 struct list_head list_fw; /* FW list of modules */
205 struct list_head runtime_list; /* list of runtime module objects*/ 215 struct list_head runtime_list; /* list of runtime module objects*/
216
217 /* state */
218 enum sst_module_state state;
206}; 219};
207 220
208/* 221/*
diff --git a/sound/soc/intel/sst-dsp.c b/sound/soc/intel/common/sst-dsp.c
index 64e94212d2d2..64e94212d2d2 100644
--- a/sound/soc/intel/sst-dsp.c
+++ b/sound/soc/intel/common/sst-dsp.c
diff --git a/sound/soc/intel/sst-dsp.h b/sound/soc/intel/common/sst-dsp.h
index f291e32f0077..96aeb2556ad4 100644
--- a/sound/soc/intel/sst-dsp.h
+++ b/sound/soc/intel/common/sst-dsp.h
@@ -28,7 +28,6 @@
28 28
29/* Supported SST DMA Devices */ 29/* Supported SST DMA Devices */
30#define SST_DMA_TYPE_DW 1 30#define SST_DMA_TYPE_DW 1
31#define SST_DMA_TYPE_MID 2
32 31
33/* autosuspend delay 5s*/ 32/* autosuspend delay 5s*/
34#define SST_RUNTIME_SUSPEND_DELAY (5 * 1000) 33#define SST_RUNTIME_SUSPEND_DELAY (5 * 1000)
@@ -206,6 +205,7 @@ struct sst_pdata {
206 const struct firmware *fw; 205 const struct firmware *fw;
207 206
208 /* DMA */ 207 /* DMA */
208 int resindex_dma_base; /* other fields invalid if equals to -1 */
209 u32 dma_base; 209 u32 dma_base;
210 u32 dma_size; 210 u32 dma_size;
211 int dma_engine; 211 int dma_engine;
diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/common/sst-firmware.c
index 5f71ef607a57..ebcca6dc48d1 100644
--- a/sound/soc/intel/sst-firmware.c
+++ b/sound/soc/intel/common/sst-firmware.c
@@ -221,8 +221,6 @@ int sst_dsp_dma_get_channel(struct sst_dsp *dsp, int chan_id)
221 dma_cap_mask_t mask; 221 dma_cap_mask_t mask;
222 int ret; 222 int ret;
223 223
224 /* The Intel MID DMA engine driver needs the slave config set but
225 * Synopsis DMA engine driver safely ignores the slave config */
226 dma_cap_zero(mask); 224 dma_cap_zero(mask);
227 dma_cap_set(DMA_SLAVE, mask); 225 dma_cap_set(DMA_SLAVE, mask);
228 dma_cap_set(DMA_MEMCPY, mask); 226 dma_cap_set(DMA_MEMCPY, mask);
@@ -271,15 +269,16 @@ int sst_dma_new(struct sst_dsp *sst)
271 const char *dma_dev_name; 269 const char *dma_dev_name;
272 int ret = 0; 270 int ret = 0;
273 271
272 if (sst->pdata->resindex_dma_base == -1)
273 /* DMA is not used, return and squelsh error messages */
274 return 0;
275
274 /* configure the correct platform data for whatever DMA engine 276 /* configure the correct platform data for whatever DMA engine
275 * is attached to the ADSP IP. */ 277 * is attached to the ADSP IP. */
276 switch (sst->pdata->dma_engine) { 278 switch (sst->pdata->dma_engine) {
277 case SST_DMA_TYPE_DW: 279 case SST_DMA_TYPE_DW:
278 dma_dev_name = "dw_dmac"; 280 dma_dev_name = "dw_dmac";
279 break; 281 break;
280 case SST_DMA_TYPE_MID:
281 dma_dev_name = "Intel MID DMA";
282 break;
283 default: 282 default:
284 dev_err(sst->dev, "error: invalid DMA engine %d\n", 283 dev_err(sst->dev, "error: invalid DMA engine %d\n",
285 sst->pdata->dma_engine); 284 sst->pdata->dma_engine);
@@ -498,6 +497,7 @@ struct sst_module *sst_module_new(struct sst_fw *sst_fw,
498 sst_module->scratch_size = template->scratch_size; 497 sst_module->scratch_size = template->scratch_size;
499 sst_module->persistent_size = template->persistent_size; 498 sst_module->persistent_size = template->persistent_size;
500 sst_module->entry = template->entry; 499 sst_module->entry = template->entry;
500 sst_module->state = SST_MODULE_STATE_UNLOADED;
501 501
502 INIT_LIST_HEAD(&sst_module->block_list); 502 INIT_LIST_HEAD(&sst_module->block_list);
503 INIT_LIST_HEAD(&sst_module->runtime_list); 503 INIT_LIST_HEAD(&sst_module->runtime_list);
diff --git a/sound/soc/intel/common/sst-ipc.c b/sound/soc/intel/common/sst-ipc.c
new file mode 100644
index 000000000000..4b62a553823c
--- /dev/null
+++ b/sound/soc/intel/common/sst-ipc.c
@@ -0,0 +1,294 @@
1/*
2 * Intel SST generic IPC Support
3 *
4 * Copyright (C) 2015, Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/types.h>
18#include <linux/kernel.h>
19#include <linux/list.h>
20#include <linux/wait.h>
21#include <linux/module.h>
22#include <linux/spinlock.h>
23#include <linux/device.h>
24#include <linux/slab.h>
25#include <linux/workqueue.h>
26#include <linux/sched.h>
27#include <linux/delay.h>
28#include <linux/platform_device.h>
29#include <linux/kthread.h>
30#include <sound/asound.h>
31
32#include "sst-dsp.h"
33#include "sst-dsp-priv.h"
34#include "sst-ipc.h"
35
36/* IPC message timeout (msecs) */
37#define IPC_TIMEOUT_MSECS 300
38
39#define IPC_EMPTY_LIST_SIZE 8
40
41/* locks held by caller */
42static struct ipc_message *msg_get_empty(struct sst_generic_ipc *ipc)
43{
44 struct ipc_message *msg = NULL;
45
46 if (!list_empty(&ipc->empty_list)) {
47 msg = list_first_entry(&ipc->empty_list, struct ipc_message,
48 list);
49 list_del(&msg->list);
50 }
51
52 return msg;
53}
54
55static int tx_wait_done(struct sst_generic_ipc *ipc,
56 struct ipc_message *msg, void *rx_data)
57{
58 unsigned long flags;
59 int ret;
60
61 /* wait for DSP completion (in all cases atm inc pending) */
62 ret = wait_event_timeout(msg->waitq, msg->complete,
63 msecs_to_jiffies(IPC_TIMEOUT_MSECS));
64
65 spin_lock_irqsave(&ipc->dsp->spinlock, flags);
66 if (ret == 0) {
67 if (ipc->ops.shim_dbg != NULL)
68 ipc->ops.shim_dbg(ipc, "message timeout");
69
70 list_del(&msg->list);
71 ret = -ETIMEDOUT;
72 } else {
73
74 /* copy the data returned from DSP */
75 if (msg->rx_size)
76 memcpy(rx_data, msg->rx_data, msg->rx_size);
77 ret = msg->errno;
78 }
79
80 list_add_tail(&msg->list, &ipc->empty_list);
81 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
82 return ret;
83}
84
85static int ipc_tx_message(struct sst_generic_ipc *ipc, u64 header,
86 void *tx_data, size_t tx_bytes, void *rx_data,
87 size_t rx_bytes, int wait)
88{
89 struct ipc_message *msg;
90 unsigned long flags;
91
92 spin_lock_irqsave(&ipc->dsp->spinlock, flags);
93
94 msg = msg_get_empty(ipc);
95 if (msg == NULL) {
96 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
97 return -EBUSY;
98 }
99
100 msg->header = header;
101 msg->tx_size = tx_bytes;
102 msg->rx_size = rx_bytes;
103 msg->wait = wait;
104 msg->errno = 0;
105 msg->pending = false;
106 msg->complete = false;
107
108 if ((tx_bytes) && (ipc->ops.tx_data_copy != NULL))
109 ipc->ops.tx_data_copy(msg, tx_data, tx_bytes);
110
111 list_add_tail(&msg->list, &ipc->tx_list);
112 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
113
114 queue_kthread_work(&ipc->kworker, &ipc->kwork);
115
116 if (wait)
117 return tx_wait_done(ipc, msg, rx_data);
118 else
119 return 0;
120}
121
122static int msg_empty_list_init(struct sst_generic_ipc *ipc)
123{
124 int i;
125
126 ipc->msg = kzalloc(sizeof(struct ipc_message) *
127 IPC_EMPTY_LIST_SIZE, GFP_KERNEL);
128 if (ipc->msg == NULL)
129 return -ENOMEM;
130
131 for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) {
132 init_waitqueue_head(&ipc->msg[i].waitq);
133 list_add(&ipc->msg[i].list, &ipc->empty_list);
134 }
135
136 return 0;
137}
138
139static void ipc_tx_msgs(struct kthread_work *work)
140{
141 struct sst_generic_ipc *ipc =
142 container_of(work, struct sst_generic_ipc, kwork);
143 struct ipc_message *msg;
144 unsigned long flags;
145 u64 ipcx;
146
147 spin_lock_irqsave(&ipc->dsp->spinlock, flags);
148
149 if (list_empty(&ipc->tx_list) || ipc->pending) {
150 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
151 return;
152 }
153
154 /* if the DSP is busy, we will TX messages after IRQ.
155 * also postpone if we are in the middle of procesing completion irq*/
156 ipcx = sst_dsp_shim_read_unlocked(ipc->dsp, SST_IPCX);
157 if (ipcx & (SST_IPCX_BUSY | SST_IPCX_DONE)) {
158 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
159 return;
160 }
161
162 msg = list_first_entry(&ipc->tx_list, struct ipc_message, list);
163 list_move(&msg->list, &ipc->rx_list);
164
165 if (ipc->ops.tx_msg != NULL)
166 ipc->ops.tx_msg(ipc, msg);
167
168 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
169}
170
171int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header,
172 void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes)
173{
174 return ipc_tx_message(ipc, header, tx_data, tx_bytes,
175 rx_data, rx_bytes, 1);
176}
177EXPORT_SYMBOL_GPL(sst_ipc_tx_message_wait);
178
179int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, u64 header,
180 void *tx_data, size_t tx_bytes)
181{
182 return ipc_tx_message(ipc, header, tx_data, tx_bytes,
183 NULL, 0, 0);
184}
185EXPORT_SYMBOL_GPL(sst_ipc_tx_message_nowait);
186
187struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc,
188 u64 header)
189{
190 struct ipc_message *msg;
191 u64 mask;
192
193 if (ipc->ops.reply_msg_match != NULL)
194 header = ipc->ops.reply_msg_match(header, &mask);
195
196 if (list_empty(&ipc->rx_list)) {
197 dev_err(ipc->dev, "error: rx list empty but received 0x%llx\n",
198 header);
199 return NULL;
200 }
201
202 list_for_each_entry(msg, &ipc->rx_list, list) {
203 if ((msg->header & mask) == header)
204 return msg;
205 }
206
207 return NULL;
208}
209EXPORT_SYMBOL_GPL(sst_ipc_reply_find_msg);
210
211/* locks held by caller */
212void sst_ipc_tx_msg_reply_complete(struct sst_generic_ipc *ipc,
213 struct ipc_message *msg)
214{
215 msg->complete = true;
216
217 if (!msg->wait)
218 list_add_tail(&msg->list, &ipc->empty_list);
219 else
220 wake_up(&msg->waitq);
221}
222EXPORT_SYMBOL_GPL(sst_ipc_tx_msg_reply_complete);
223
224void sst_ipc_drop_all(struct sst_generic_ipc *ipc)
225{
226 struct ipc_message *msg, *tmp;
227 unsigned long flags;
228 int tx_drop_cnt = 0, rx_drop_cnt = 0;
229
230 /* drop all TX and Rx messages before we stall + reset DSP */
231 spin_lock_irqsave(&ipc->dsp->spinlock, flags);
232
233 list_for_each_entry_safe(msg, tmp, &ipc->tx_list, list) {
234 list_move(&msg->list, &ipc->empty_list);
235 tx_drop_cnt++;
236 }
237
238 list_for_each_entry_safe(msg, tmp, &ipc->rx_list, list) {
239 list_move(&msg->list, &ipc->empty_list);
240 rx_drop_cnt++;
241 }
242
243 spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
244
245 if (tx_drop_cnt || rx_drop_cnt)
246 dev_err(ipc->dev, "dropped IPC msg RX=%d, TX=%d\n",
247 tx_drop_cnt, rx_drop_cnt);
248}
249EXPORT_SYMBOL_GPL(sst_ipc_drop_all);
250
251int sst_ipc_init(struct sst_generic_ipc *ipc)
252{
253 int ret;
254
255 INIT_LIST_HEAD(&ipc->tx_list);
256 INIT_LIST_HEAD(&ipc->rx_list);
257 INIT_LIST_HEAD(&ipc->empty_list);
258 init_waitqueue_head(&ipc->wait_txq);
259
260 ret = msg_empty_list_init(ipc);
261 if (ret < 0)
262 return -ENOMEM;
263
264 /* start the IPC message thread */
265 init_kthread_worker(&ipc->kworker);
266 ipc->tx_thread = kthread_run(kthread_worker_fn,
267 &ipc->kworker, "%s",
268 dev_name(ipc->dev));
269 if (IS_ERR(ipc->tx_thread)) {
270 dev_err(ipc->dev, "error: failed to create message TX task\n");
271 ret = PTR_ERR(ipc->tx_thread);
272 kfree(ipc->msg);
273 return ret;
274 }
275
276 init_kthread_work(&ipc->kwork, ipc_tx_msgs);
277 return 0;
278}
279EXPORT_SYMBOL_GPL(sst_ipc_init);
280
281void sst_ipc_fini(struct sst_generic_ipc *ipc)
282{
283 if (ipc->tx_thread)
284 kthread_stop(ipc->tx_thread);
285
286 if (ipc->msg)
287 kfree(ipc->msg);
288}
289EXPORT_SYMBOL_GPL(sst_ipc_fini);
290
291/* Module information */
292MODULE_AUTHOR("Jin Yao");
293MODULE_DESCRIPTION("Intel SST IPC generic");
294MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/intel/common/sst-ipc.h b/sound/soc/intel/common/sst-ipc.h
new file mode 100644
index 000000000000..125ea451a373
--- /dev/null
+++ b/sound/soc/intel/common/sst-ipc.h
@@ -0,0 +1,91 @@
1/*
2 * Intel SST generic IPC Support
3 *
4 * Copyright (C) 2015, Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#ifndef __SST_GENERIC_IPC_H
18#define __SST_GENERIC_IPC_H
19
20#include <linux/types.h>
21#include <linux/kernel.h>
22#include <linux/wait.h>
23#include <linux/list.h>
24#include <linux/workqueue.h>
25#include <linux/sched.h>
26#include <linux/kthread.h>
27
28#define IPC_MAX_MAILBOX_BYTES 256
29
30struct ipc_message {
31 struct list_head list;
32 u64 header;
33
34 /* direction wrt host CPU */
35 char tx_data[IPC_MAX_MAILBOX_BYTES];
36 size_t tx_size;
37 char rx_data[IPC_MAX_MAILBOX_BYTES];
38 size_t rx_size;
39
40 wait_queue_head_t waitq;
41 bool pending;
42 bool complete;
43 bool wait;
44 int errno;
45};
46
47struct sst_generic_ipc;
48
49struct sst_plat_ipc_ops {
50 void (*tx_msg)(struct sst_generic_ipc *, struct ipc_message *);
51 void (*shim_dbg)(struct sst_generic_ipc *, const char *);
52 void (*tx_data_copy)(struct ipc_message *, char *, size_t);
53 u64 (*reply_msg_match)(u64 header, u64 *mask);
54};
55
56/* SST generic IPC data */
57struct sst_generic_ipc {
58 struct device *dev;
59 struct sst_dsp *dsp;
60
61 /* IPC messaging */
62 struct list_head tx_list;
63 struct list_head rx_list;
64 struct list_head empty_list;
65 wait_queue_head_t wait_txq;
66 struct task_struct *tx_thread;
67 struct kthread_worker kworker;
68 struct kthread_work kwork;
69 bool pending;
70 struct ipc_message *msg;
71
72 struct sst_plat_ipc_ops ops;
73};
74
75int sst_ipc_tx_message_wait(struct sst_generic_ipc *ipc, u64 header,
76 void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes);
77
78int sst_ipc_tx_message_nowait(struct sst_generic_ipc *ipc, u64 header,
79 void *tx_data, size_t tx_bytes);
80
81struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc,
82 u64 header);
83
84void sst_ipc_tx_msg_reply_complete(struct sst_generic_ipc *ipc,
85 struct ipc_message *msg);
86
87void sst_ipc_drop_all(struct sst_generic_ipc *ipc);
88int sst_ipc_init(struct sst_generic_ipc *ipc);
89void sst_ipc_fini(struct sst_generic_ipc *ipc);
90
91#endif
diff --git a/sound/soc/intel/haswell/Makefile b/sound/soc/intel/haswell/Makefile
new file mode 100644
index 000000000000..9c1723112d22
--- /dev/null
+++ b/sound/soc/intel/haswell/Makefile
@@ -0,0 +1,4 @@
1snd-soc-sst-haswell-pcm-objs := \
2 sst-haswell-ipc.o sst-haswell-pcm.o sst-haswell-dsp.o
3
4obj-$(CONFIG_SND_SOC_INTEL_HASWELL) += snd-soc-sst-haswell-pcm.o
diff --git a/sound/soc/intel/sst-haswell-dsp.c b/sound/soc/intel/haswell/sst-haswell-dsp.c
index 402b728c0a06..7f94920c8a4d 100644
--- a/sound/soc/intel/sst-haswell-dsp.c
+++ b/sound/soc/intel/haswell/sst-haswell-dsp.c
@@ -28,9 +28,9 @@
28#include <linux/firmware.h> 28#include <linux/firmware.h>
29#include <linux/pm_runtime.h> 29#include <linux/pm_runtime.h>
30 30
31#include "sst-dsp.h" 31#include "../common/sst-dsp.h"
32#include "sst-dsp-priv.h" 32#include "../common/sst-dsp-priv.h"
33#include "sst-haswell-ipc.h" 33#include "../haswell/sst-haswell-ipc.h"
34 34
35#include <trace/events/hswadsp.h> 35#include <trace/events/hswadsp.h>
36 36
@@ -100,6 +100,7 @@ static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
100 && module->type != SST_HSW_MODULE_PCM 100 && module->type != SST_HSW_MODULE_PCM
101 && module->type != SST_HSW_MODULE_PCM_REFERENCE 101 && module->type != SST_HSW_MODULE_PCM_REFERENCE
102 && module->type != SST_HSW_MODULE_PCM_CAPTURE 102 && module->type != SST_HSW_MODULE_PCM_CAPTURE
103 && module->type != SST_HSW_MODULE_WAVES
103 && module->type != SST_HSW_MODULE_LPAL) 104 && module->type != SST_HSW_MODULE_LPAL)
104 return 0; 105 return 0;
105 106
@@ -139,6 +140,7 @@ static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
139 mod->type = SST_MEM_IRAM; 140 mod->type = SST_MEM_IRAM;
140 break; 141 break;
141 case SST_HSW_DRAM: 142 case SST_HSW_DRAM:
143 case SST_HSW_REGS:
142 ram = dsp->addr.lpe; 144 ram = dsp->addr.lpe;
143 mod->offset = block->ram_offset; 145 mod->offset = block->ram_offset;
144 mod->type = SST_MEM_DRAM; 146 mod->type = SST_MEM_DRAM;
@@ -169,6 +171,7 @@ static int hsw_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
169 171
170 block = (void *)block + sizeof(*block) + block->size; 172 block = (void *)block + sizeof(*block) + block->size;
171 } 173 }
174 mod->state = SST_MODULE_STATE_LOADED;
172 175
173 return 0; 176 return 0;
174} 177}
diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/haswell/sst-haswell-ipc.c
index 863a9ca34b8e..344a1e9bbce5 100644
--- a/sound/soc/intel/sst-haswell-ipc.c
+++ b/sound/soc/intel/haswell/sst-haswell-ipc.c
@@ -34,8 +34,9 @@
34#include <sound/asound.h> 34#include <sound/asound.h>
35 35
36#include "sst-haswell-ipc.h" 36#include "sst-haswell-ipc.h"
37#include "sst-dsp.h" 37#include "../common/sst-dsp.h"
38#include "sst-dsp-priv.h" 38#include "../common/sst-dsp-priv.h"
39#include "../common/sst-ipc.h"
39 40
40/* Global Message - Generic */ 41/* Global Message - Generic */
41#define IPC_GLB_TYPE_SHIFT 24 42#define IPC_GLB_TYPE_SHIFT 24
@@ -79,6 +80,15 @@
79#define IPC_LOG_ID_MASK (0xf << IPC_LOG_ID_SHIFT) 80#define IPC_LOG_ID_MASK (0xf << IPC_LOG_ID_SHIFT)
80#define IPC_LOG_ID(x) (x << IPC_LOG_ID_SHIFT) 81#define IPC_LOG_ID(x) (x << IPC_LOG_ID_SHIFT)
81 82
83/* Module Message */
84#define IPC_MODULE_OPERATION_SHIFT 20
85#define IPC_MODULE_OPERATION_MASK (0xf << IPC_MODULE_OPERATION_SHIFT)
86#define IPC_MODULE_OPERATION(x) (x << IPC_MODULE_OPERATION_SHIFT)
87
88#define IPC_MODULE_ID_SHIFT 16
89#define IPC_MODULE_ID_MASK (0xf << IPC_MODULE_ID_SHIFT)
90#define IPC_MODULE_ID(x) (x << IPC_MODULE_ID_SHIFT)
91
82/* IPC message timeout (msecs) */ 92/* IPC message timeout (msecs) */
83#define IPC_TIMEOUT_MSECS 300 93#define IPC_TIMEOUT_MSECS 300
84#define IPC_BOOT_MSECS 200 94#define IPC_BOOT_MSECS 200
@@ -115,6 +125,7 @@ enum ipc_glb_type {
115 IPC_GLB_ENTER_DX_STATE = 12, 125 IPC_GLB_ENTER_DX_STATE = 12,
116 IPC_GLB_GET_MIXER_STREAM_INFO = 13, /* Request mixer stream params */ 126 IPC_GLB_GET_MIXER_STREAM_INFO = 13, /* Request mixer stream params */
117 IPC_GLB_DEBUG_LOG_MESSAGE = 14, /* Message to or from the debug logger. */ 127 IPC_GLB_DEBUG_LOG_MESSAGE = 14, /* Message to or from the debug logger. */
128 IPC_GLB_MODULE_OPERATION = 15, /* Message to loadable fw module */
118 IPC_GLB_REQUEST_TRANSFER = 16, /* < Request Transfer for host */ 129 IPC_GLB_REQUEST_TRANSFER = 16, /* < Request Transfer for host */
119 IPC_GLB_MAX_IPC_MESSAGE_TYPE = 17, /* Maximum message number */ 130 IPC_GLB_MAX_IPC_MESSAGE_TYPE = 17, /* Maximum message number */
120}; 131};
@@ -133,6 +144,16 @@ enum ipc_glb_reply {
133 IPC_GLB_REPLY_SOURCE_NOT_STARTED = 10, /* Source was not started. */ 144 IPC_GLB_REPLY_SOURCE_NOT_STARTED = 10, /* Source was not started. */
134}; 145};
135 146
147enum ipc_module_operation {
148 IPC_MODULE_NOTIFICATION = 0,
149 IPC_MODULE_ENABLE = 1,
150 IPC_MODULE_DISABLE = 2,
151 IPC_MODULE_GET_PARAMETER = 3,
152 IPC_MODULE_SET_PARAMETER = 4,
153 IPC_MODULE_GET_INFO = 5,
154 IPC_MODULE_MAX_MESSAGE
155};
156
136/* Stream Message - Types */ 157/* Stream Message - Types */
137enum ipc_str_operation { 158enum ipc_str_operation {
138 IPC_STR_RESET = 0, 159 IPC_STR_RESET = 0,
@@ -190,23 +211,6 @@ struct sst_hsw_ipc_fw_ready {
190 u8 fw_info[IPC_MAX_MAILBOX_BYTES - 5 * sizeof(u32)]; 211 u8 fw_info[IPC_MAX_MAILBOX_BYTES - 5 * sizeof(u32)];
191} __attribute__((packed)); 212} __attribute__((packed));
192 213
193struct ipc_message {
194 struct list_head list;
195 u32 header;
196
197 /* direction wrt host CPU */
198 char tx_data[IPC_MAX_MAILBOX_BYTES];
199 size_t tx_size;
200 char rx_data[IPC_MAX_MAILBOX_BYTES];
201 size_t rx_size;
202
203 wait_queue_head_t waitq;
204 bool pending;
205 bool complete;
206 bool wait;
207 int errno;
208};
209
210struct sst_hsw_stream; 214struct sst_hsw_stream;
211struct sst_hsw; 215struct sst_hsw;
212 216
@@ -305,18 +309,19 @@ struct sst_hsw {
305 bool shutdown; 309 bool shutdown;
306 310
307 /* IPC messaging */ 311 /* IPC messaging */
308 struct list_head tx_list; 312 struct sst_generic_ipc ipc;
309 struct list_head rx_list;
310 struct list_head empty_list;
311 wait_queue_head_t wait_txq;
312 struct task_struct *tx_thread;
313 struct kthread_worker kworker;
314 struct kthread_work kwork;
315 bool pending;
316 struct ipc_message *msg;
317 313
318 /* FW log stream */ 314 /* FW log stream */
319 struct sst_hsw_log_stream log_stream; 315 struct sst_hsw_log_stream log_stream;
316
317 /* flags bit field to track module state when resume from RTD3,
318 * each bit represent state (enabled/disabled) of single module */
319 u32 enabled_modules_rtd3;
320
321 /* buffer to store parameter lines */
322 u32 param_idx_w; /* write index */
323 u32 param_idx_r; /* read index */
324 u8 param_buf[WAVES_PARAM_LINES][WAVES_PARAM_COUNT];
320}; 325};
321 326
322#define CREATE_TRACE_POINTS 327#define CREATE_TRACE_POINTS
@@ -352,6 +357,16 @@ static inline u32 msg_get_notify_reason(u32 msg)
352 return (msg & IPC_STG_TYPE_MASK) >> IPC_STG_TYPE_SHIFT; 357 return (msg & IPC_STG_TYPE_MASK) >> IPC_STG_TYPE_SHIFT;
353} 358}
354 359
360static inline u32 msg_get_module_operation(u32 msg)
361{
362 return (msg & IPC_MODULE_OPERATION_MASK) >> IPC_MODULE_OPERATION_SHIFT;
363}
364
365static inline u32 msg_get_module_id(u32 msg)
366{
367 return (msg & IPC_MODULE_ID_MASK) >> IPC_MODULE_ID_SHIFT;
368}
369
355u32 create_channel_map(enum sst_hsw_channel_config config) 370u32 create_channel_map(enum sst_hsw_channel_config config)
356{ 371{
357 switch (config) { 372 switch (config) {
@@ -417,159 +432,6 @@ static struct sst_hsw_stream *get_stream_by_id(struct sst_hsw *hsw,
417 return NULL; 432 return NULL;
418} 433}
419 434
420static void ipc_shim_dbg(struct sst_hsw *hsw, const char *text)
421{
422 struct sst_dsp *sst = hsw->dsp;
423 u32 isr, ipcd, imrx, ipcx;
424
425 ipcx = sst_dsp_shim_read_unlocked(sst, SST_IPCX);
426 isr = sst_dsp_shim_read_unlocked(sst, SST_ISRX);
427 ipcd = sst_dsp_shim_read_unlocked(sst, SST_IPCD);
428 imrx = sst_dsp_shim_read_unlocked(sst, SST_IMRX);
429
430 dev_err(hsw->dev, "ipc: --%s-- ipcx 0x%8.8x isr 0x%8.8x ipcd 0x%8.8x imrx 0x%8.8x\n",
431 text, ipcx, isr, ipcd, imrx);
432}
433
434/* locks held by caller */
435static struct ipc_message *msg_get_empty(struct sst_hsw *hsw)
436{
437 struct ipc_message *msg = NULL;
438
439 if (!list_empty(&hsw->empty_list)) {
440 msg = list_first_entry(&hsw->empty_list, struct ipc_message,
441 list);
442 list_del(&msg->list);
443 }
444
445 return msg;
446}
447
448static void ipc_tx_msgs(struct kthread_work *work)
449{
450 struct sst_hsw *hsw =
451 container_of(work, struct sst_hsw, kwork);
452 struct ipc_message *msg;
453 unsigned long flags;
454 u32 ipcx;
455
456 spin_lock_irqsave(&hsw->dsp->spinlock, flags);
457
458 if (list_empty(&hsw->tx_list) || hsw->pending) {
459 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
460 return;
461 }
462
463 /* if the DSP is busy, we will TX messages after IRQ.
464 * also postpone if we are in the middle of procesing completion irq*/
465 ipcx = sst_dsp_shim_read_unlocked(hsw->dsp, SST_IPCX);
466 if (ipcx & (SST_IPCX_BUSY | SST_IPCX_DONE)) {
467 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
468 return;
469 }
470
471 msg = list_first_entry(&hsw->tx_list, struct ipc_message, list);
472
473 list_move(&msg->list, &hsw->rx_list);
474
475 /* send the message */
476 sst_dsp_outbox_write(hsw->dsp, msg->tx_data, msg->tx_size);
477 sst_dsp_ipc_msg_tx(hsw->dsp, msg->header | SST_IPCX_BUSY);
478
479 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
480}
481
482/* locks held by caller */
483static void tx_msg_reply_complete(struct sst_hsw *hsw, struct ipc_message *msg)
484{
485 msg->complete = true;
486 trace_ipc_reply("completed", msg->header);
487
488 if (!msg->wait)
489 list_add_tail(&msg->list, &hsw->empty_list);
490 else
491 wake_up(&msg->waitq);
492}
493
494static int tx_wait_done(struct sst_hsw *hsw, struct ipc_message *msg,
495 void *rx_data)
496{
497 unsigned long flags;
498 int ret;
499
500 /* wait for DSP completion (in all cases atm inc pending) */
501 ret = wait_event_timeout(msg->waitq, msg->complete,
502 msecs_to_jiffies(IPC_TIMEOUT_MSECS));
503
504 spin_lock_irqsave(&hsw->dsp->spinlock, flags);
505 if (ret == 0) {
506 ipc_shim_dbg(hsw, "message timeout");
507
508 trace_ipc_error("error message timeout for", msg->header);
509 list_del(&msg->list);
510 ret = -ETIMEDOUT;
511 } else {
512
513 /* copy the data returned from DSP */
514 if (msg->rx_size)
515 memcpy(rx_data, msg->rx_data, msg->rx_size);
516 ret = msg->errno;
517 }
518
519 list_add_tail(&msg->list, &hsw->empty_list);
520 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
521 return ret;
522}
523
524static int ipc_tx_message(struct sst_hsw *hsw, u32 header, void *tx_data,
525 size_t tx_bytes, void *rx_data, size_t rx_bytes, int wait)
526{
527 struct ipc_message *msg;
528 unsigned long flags;
529
530 spin_lock_irqsave(&hsw->dsp->spinlock, flags);
531
532 msg = msg_get_empty(hsw);
533 if (msg == NULL) {
534 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
535 return -EBUSY;
536 }
537
538 if (tx_bytes)
539 memcpy(msg->tx_data, tx_data, tx_bytes);
540
541 msg->header = header;
542 msg->tx_size = tx_bytes;
543 msg->rx_size = rx_bytes;
544 msg->wait = wait;
545 msg->errno = 0;
546 msg->pending = false;
547 msg->complete = false;
548
549 list_add_tail(&msg->list, &hsw->tx_list);
550 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
551
552 queue_kthread_work(&hsw->kworker, &hsw->kwork);
553
554 if (wait)
555 return tx_wait_done(hsw, msg, rx_data);
556 else
557 return 0;
558}
559
560static inline int ipc_tx_message_wait(struct sst_hsw *hsw, u32 header,
561 void *tx_data, size_t tx_bytes, void *rx_data, size_t rx_bytes)
562{
563 return ipc_tx_message(hsw, header, tx_data, tx_bytes, rx_data,
564 rx_bytes, 1);
565}
566
567static inline int ipc_tx_message_nowait(struct sst_hsw *hsw, u32 header,
568 void *tx_data, size_t tx_bytes)
569{
570 return ipc_tx_message(hsw, header, tx_data, tx_bytes, NULL, 0, 0);
571}
572
573static void hsw_fw_ready(struct sst_hsw *hsw, u32 header) 435static void hsw_fw_ready(struct sst_hsw *hsw, u32 header)
574{ 436{
575 struct sst_hsw_ipc_fw_ready fw_ready; 437 struct sst_hsw_ipc_fw_ready fw_ready;
@@ -604,7 +466,7 @@ static void hsw_fw_ready(struct sst_hsw *hsw, u32 header)
604 /* log the FW version info got from the mailbox here. */ 466 /* log the FW version info got from the mailbox here. */
605 memcpy(fw_info, fw_ready.fw_info, fw_ready.fw_info_size); 467 memcpy(fw_info, fw_ready.fw_info, fw_ready.fw_info_size);
606 pinfo = &fw_info[0]; 468 pinfo = &fw_info[0];
607 for (i = 0; i < sizeof(tmp) / sizeof(char *); i++) 469 for (i = 0; i < ARRAY_SIZE(tmp); i++)
608 tmp[i] = strsep(&pinfo, " "); 470 tmp[i] = strsep(&pinfo, " ");
609 dev_info(hsw->dev, "FW loaded, mailbox readback FW info: type %s, - " 471 dev_info(hsw->dev, "FW loaded, mailbox readback FW info: type %s, - "
610 "version: %s.%s, build %s, source commit id: %s\n", 472 "version: %s.%s, build %s, source commit id: %s\n",
@@ -657,27 +519,6 @@ static void hsw_notification_work(struct work_struct *work)
657 sst_dsp_shim_update_bits(hsw->dsp, SST_IMRX, SST_IMRX_BUSY, 0); 519 sst_dsp_shim_update_bits(hsw->dsp, SST_IMRX, SST_IMRX_BUSY, 0);
658} 520}
659 521
660static struct ipc_message *reply_find_msg(struct sst_hsw *hsw, u32 header)
661{
662 struct ipc_message *msg;
663
664 /* clear reply bits & status bits */
665 header &= ~(IPC_STATUS_MASK | IPC_GLB_REPLY_MASK);
666
667 if (list_empty(&hsw->rx_list)) {
668 dev_err(hsw->dev, "error: rx list empty but received 0x%x\n",
669 header);
670 return NULL;
671 }
672
673 list_for_each_entry(msg, &hsw->rx_list, list) {
674 if (msg->header == header)
675 return msg;
676 }
677
678 return NULL;
679}
680
681static void hsw_stream_update(struct sst_hsw *hsw, struct ipc_message *msg) 522static void hsw_stream_update(struct sst_hsw *hsw, struct ipc_message *msg)
682{ 523{
683 struct sst_hsw_stream *stream; 524 struct sst_hsw_stream *stream;
@@ -716,7 +557,7 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header)
716 557
717 trace_ipc_reply("processing -->", header); 558 trace_ipc_reply("processing -->", header);
718 559
719 msg = reply_find_msg(hsw, header); 560 msg = sst_ipc_reply_find_msg(&hsw->ipc, header);
720 if (msg == NULL) { 561 if (msg == NULL) {
721 trace_ipc_error("error: can't find message header", header); 562 trace_ipc_error("error: can't find message header", header);
722 return -EIO; 563 return -EIO;
@@ -727,14 +568,14 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header)
727 case IPC_GLB_REPLY_PENDING: 568 case IPC_GLB_REPLY_PENDING:
728 trace_ipc_pending_reply("received", header); 569 trace_ipc_pending_reply("received", header);
729 msg->pending = true; 570 msg->pending = true;
730 hsw->pending = true; 571 hsw->ipc.pending = true;
731 return 1; 572 return 1;
732 case IPC_GLB_REPLY_SUCCESS: 573 case IPC_GLB_REPLY_SUCCESS:
733 if (msg->pending) { 574 if (msg->pending) {
734 trace_ipc_pending_reply("completed", header); 575 trace_ipc_pending_reply("completed", header);
735 sst_dsp_inbox_read(hsw->dsp, msg->rx_data, 576 sst_dsp_inbox_read(hsw->dsp, msg->rx_data,
736 msg->rx_size); 577 msg->rx_size);
737 hsw->pending = false; 578 hsw->ipc.pending = false;
738 } else { 579 } else {
739 /* copy data from the DSP */ 580 /* copy data from the DSP */
740 sst_dsp_outbox_read(hsw->dsp, msg->rx_data, 581 sst_dsp_outbox_read(hsw->dsp, msg->rx_data,
@@ -790,11 +631,36 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header)
790 631
791 /* wake up and return the error if we have waiters on this message ? */ 632 /* wake up and return the error if we have waiters on this message ? */
792 list_del(&msg->list); 633 list_del(&msg->list);
793 tx_msg_reply_complete(hsw, msg); 634 sst_ipc_tx_msg_reply_complete(&hsw->ipc, msg);
794 635
795 return 1; 636 return 1;
796} 637}
797 638
639static int hsw_module_message(struct sst_hsw *hsw, u32 header)
640{
641 u32 operation, module_id;
642 int handled = 0;
643
644 operation = msg_get_module_operation(header);
645 module_id = msg_get_module_id(header);
646 dev_dbg(hsw->dev, "received module message header: 0x%8.8x\n",
647 header);
648 dev_dbg(hsw->dev, "operation: 0x%8.8x module_id: 0x%8.8x\n",
649 operation, module_id);
650
651 switch (operation) {
652 case IPC_MODULE_NOTIFICATION:
653 dev_dbg(hsw->dev, "module notification received");
654 handled = 1;
655 break;
656 default:
657 handled = hsw_process_reply(hsw, header);
658 break;
659 }
660
661 return handled;
662}
663
798static int hsw_stream_message(struct sst_hsw *hsw, u32 header) 664static int hsw_stream_message(struct sst_hsw *hsw, u32 header)
799{ 665{
800 u32 stream_msg, stream_id, stage_type; 666 u32 stream_msg, stream_id, stage_type;
@@ -890,6 +756,9 @@ static int hsw_process_notification(struct sst_hsw *hsw)
890 case IPC_GLB_DEBUG_LOG_MESSAGE: 756 case IPC_GLB_DEBUG_LOG_MESSAGE:
891 handled = hsw_log_message(hsw, header); 757 handled = hsw_log_message(hsw, header);
892 break; 758 break;
759 case IPC_GLB_MODULE_OPERATION:
760 handled = hsw_module_message(hsw, header);
761 break;
893 default: 762 default:
894 dev_err(hsw->dev, "error: unexpected type %d hdr 0x%8.8x\n", 763 dev_err(hsw->dev, "error: unexpected type %d hdr 0x%8.8x\n",
895 type, header); 764 type, header);
@@ -903,6 +772,7 @@ static irqreturn_t hsw_irq_thread(int irq, void *context)
903{ 772{
904 struct sst_dsp *sst = (struct sst_dsp *) context; 773 struct sst_dsp *sst = (struct sst_dsp *) context;
905 struct sst_hsw *hsw = sst_dsp_get_thread_context(sst); 774 struct sst_hsw *hsw = sst_dsp_get_thread_context(sst);
775 struct sst_generic_ipc *ipc = &hsw->ipc;
906 u32 ipcx, ipcd; 776 u32 ipcx, ipcd;
907 int handled; 777 int handled;
908 unsigned long flags; 778 unsigned long flags;
@@ -949,7 +819,7 @@ static irqreturn_t hsw_irq_thread(int irq, void *context)
949 spin_unlock_irqrestore(&sst->spinlock, flags); 819 spin_unlock_irqrestore(&sst->spinlock, flags);
950 820
951 /* continue to send any remaining messages... */ 821 /* continue to send any remaining messages... */
952 queue_kthread_work(&hsw->kworker, &hsw->kwork); 822 queue_kthread_work(&ipc->kworker, &ipc->kwork);
953 823
954 return IRQ_HANDLED; 824 return IRQ_HANDLED;
955} 825}
@@ -959,7 +829,8 @@ int sst_hsw_fw_get_version(struct sst_hsw *hsw,
959{ 829{
960 int ret; 830 int ret;
961 831
962 ret = ipc_tx_message_wait(hsw, IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION), 832 ret = sst_ipc_tx_message_wait(&hsw->ipc,
833 IPC_GLB_TYPE(IPC_GLB_GET_FW_VERSION),
963 NULL, 0, version, sizeof(*version)); 834 NULL, 0, version, sizeof(*version));
964 if (ret < 0) 835 if (ret < 0)
965 dev_err(hsw->dev, "error: get version failed\n"); 836 dev_err(hsw->dev, "error: get version failed\n");
@@ -1023,7 +894,8 @@ int sst_hsw_stream_set_volume(struct sst_hsw *hsw,
1023 req->channel = channel; 894 req->channel = channel;
1024 } 895 }
1025 896
1026 ret = ipc_tx_message_wait(hsw, header, req, sizeof(*req), NULL, 0); 897 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, req,
898 sizeof(*req), NULL, 0);
1027 if (ret < 0) { 899 if (ret < 0) {
1028 dev_err(hsw->dev, "error: set stream volume failed\n"); 900 dev_err(hsw->dev, "error: set stream volume failed\n");
1029 return ret; 901 return ret;
@@ -1088,7 +960,8 @@ int sst_hsw_mixer_set_volume(struct sst_hsw *hsw, u32 stage_id, u32 channel,
1088 req.curve_type = hsw->curve_type; 960 req.curve_type = hsw->curve_type;
1089 req.target_volume = volume; 961 req.target_volume = volume;
1090 962
1091 ret = ipc_tx_message_wait(hsw, header, &req, sizeof(req), NULL, 0); 963 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &req,
964 sizeof(req), NULL, 0);
1092 if (ret < 0) { 965 if (ret < 0) {
1093 dev_err(hsw->dev, "error: set mixer volume failed\n"); 966 dev_err(hsw->dev, "error: set mixer volume failed\n");
1094 return ret; 967 return ret;
@@ -1146,7 +1019,7 @@ int sst_hsw_stream_free(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
1146 stream->free_req.stream_id = stream->reply.stream_hw_id; 1019 stream->free_req.stream_id = stream->reply.stream_hw_id;
1147 header = IPC_GLB_TYPE(IPC_GLB_FREE_STREAM); 1020 header = IPC_GLB_TYPE(IPC_GLB_FREE_STREAM);
1148 1021
1149 ret = ipc_tx_message_wait(hsw, header, &stream->free_req, 1022 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &stream->free_req,
1150 sizeof(stream->free_req), NULL, 0); 1023 sizeof(stream->free_req), NULL, 0);
1151 if (ret < 0) { 1024 if (ret < 0) {
1152 dev_err(hsw->dev, "error: free stream %d failed\n", 1025 dev_err(hsw->dev, "error: free stream %d failed\n",
@@ -1338,8 +1211,8 @@ int sst_hsw_stream_commit(struct sst_hsw *hsw, struct sst_hsw_stream *stream)
1338 1211
1339 header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM); 1212 header = IPC_GLB_TYPE(IPC_GLB_ALLOCATE_STREAM);
1340 1213
1341 ret = ipc_tx_message_wait(hsw, header, str_req, sizeof(*str_req), 1214 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, str_req,
1342 reply, sizeof(*reply)); 1215 sizeof(*str_req), reply, sizeof(*reply));
1343 if (ret < 0) { 1216 if (ret < 0) {
1344 dev_err(hsw->dev, "error: stream commit failed\n"); 1217 dev_err(hsw->dev, "error: stream commit failed\n");
1345 return ret; 1218 return ret;
@@ -1388,7 +1261,8 @@ int sst_hsw_mixer_get_info(struct sst_hsw *hsw)
1388 1261
1389 trace_ipc_request("get global mixer info", 0); 1262 trace_ipc_request("get global mixer info", 0);
1390 1263
1391 ret = ipc_tx_message_wait(hsw, header, NULL, 0, reply, sizeof(*reply)); 1264 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, NULL, 0,
1265 reply, sizeof(*reply));
1392 if (ret < 0) { 1266 if (ret < 0) {
1393 dev_err(hsw->dev, "error: get stream info failed\n"); 1267 dev_err(hsw->dev, "error: get stream info failed\n");
1394 return ret; 1268 return ret;
@@ -1409,9 +1283,10 @@ static int sst_hsw_stream_operations(struct sst_hsw *hsw, int type,
1409 header |= (stream_id << IPC_STR_ID_SHIFT); 1283 header |= (stream_id << IPC_STR_ID_SHIFT);
1410 1284
1411 if (wait) 1285 if (wait)
1412 return ipc_tx_message_wait(hsw, header, NULL, 0, NULL, 0); 1286 return sst_ipc_tx_message_wait(&hsw->ipc, header,
1287 NULL, 0, NULL, 0);
1413 else 1288 else
1414 return ipc_tx_message_nowait(hsw, header, NULL, 0); 1289 return sst_ipc_tx_message_nowait(&hsw->ipc, header, NULL, 0);
1415} 1290}
1416 1291
1417/* Stream ALSA trigger operations */ 1292/* Stream ALSA trigger operations */
@@ -1538,8 +1413,8 @@ int sst_hsw_device_set_config(struct sst_hsw *hsw,
1538 1413
1539 header = IPC_GLB_TYPE(IPC_GLB_SET_DEVICE_FORMATS); 1414 header = IPC_GLB_TYPE(IPC_GLB_SET_DEVICE_FORMATS);
1540 1415
1541 ret = ipc_tx_message_wait(hsw, header, &config, sizeof(config), 1416 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &config,
1542 NULL, 0); 1417 sizeof(config), NULL, 0);
1543 if (ret < 0) 1418 if (ret < 0)
1544 dev_err(hsw->dev, "error: set device formats failed\n"); 1419 dev_err(hsw->dev, "error: set device formats failed\n");
1545 1420
@@ -1559,8 +1434,8 @@ int sst_hsw_dx_set_state(struct sst_hsw *hsw,
1559 1434
1560 trace_ipc_request("PM enter Dx state", state); 1435 trace_ipc_request("PM enter Dx state", state);
1561 1436
1562 ret = ipc_tx_message_wait(hsw, header, &state_, sizeof(state_), 1437 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, &state_,
1563 dx, sizeof(*dx)); 1438 sizeof(state_), dx, sizeof(*dx));
1564 if (ret < 0) { 1439 if (ret < 0) {
1565 dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state); 1440 dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state);
1566 return ret; 1441 return ret;
@@ -1703,32 +1578,6 @@ static int sst_hsw_dx_state_restore(struct sst_hsw *hsw)
1703 return 0; 1578 return 0;
1704} 1579}
1705 1580
1706static void sst_hsw_drop_all(struct sst_hsw *hsw)
1707{
1708 struct ipc_message *msg, *tmp;
1709 unsigned long flags;
1710 int tx_drop_cnt = 0, rx_drop_cnt = 0;
1711
1712 /* drop all TX and Rx messages before we stall + reset DSP */
1713 spin_lock_irqsave(&hsw->dsp->spinlock, flags);
1714
1715 list_for_each_entry_safe(msg, tmp, &hsw->tx_list, list) {
1716 list_move(&msg->list, &hsw->empty_list);
1717 tx_drop_cnt++;
1718 }
1719
1720 list_for_each_entry_safe(msg, tmp, &hsw->rx_list, list) {
1721 list_move(&msg->list, &hsw->empty_list);
1722 rx_drop_cnt++;
1723 }
1724
1725 spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
1726
1727 if (tx_drop_cnt || rx_drop_cnt)
1728 dev_err(hsw->dev, "dropped IPC msg RX=%d, TX=%d\n",
1729 tx_drop_cnt, rx_drop_cnt);
1730}
1731
1732int sst_hsw_dsp_load(struct sst_hsw *hsw) 1581int sst_hsw_dsp_load(struct sst_hsw *hsw)
1733{ 1582{
1734 struct sst_dsp *dsp = hsw->dsp; 1583 struct sst_dsp *dsp = hsw->dsp;
@@ -1808,7 +1657,7 @@ int sst_hsw_dsp_runtime_suspend(struct sst_hsw *hsw)
1808 if (ret < 0) 1657 if (ret < 0)
1809 return ret; 1658 return ret;
1810 1659
1811 sst_hsw_drop_all(hsw); 1660 sst_ipc_drop_all(&hsw->ipc);
1812 1661
1813 return 0; 1662 return 0;
1814} 1663}
@@ -1844,6 +1693,8 @@ int sst_hsw_dsp_runtime_resume(struct sst_hsw *hsw)
1844 if (ret < 0) 1693 if (ret < 0)
1845 dev_err(dev, "error: audio DSP boot failure\n"); 1694 dev_err(dev, "error: audio DSP boot failure\n");
1846 1695
1696 sst_hsw_init_module_state(hsw);
1697
1847 ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete, 1698 ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete,
1848 msecs_to_jiffies(IPC_BOOT_MSECS)); 1699 msecs_to_jiffies(IPC_BOOT_MSECS));
1849 if (ret == 0) { 1700 if (ret == 0) {
@@ -1864,26 +1715,345 @@ int sst_hsw_dsp_runtime_resume(struct sst_hsw *hsw)
1864} 1715}
1865#endif 1716#endif
1866 1717
1867static int msg_empty_list_init(struct sst_hsw *hsw) 1718struct sst_dsp *sst_hsw_get_dsp(struct sst_hsw *hsw)
1868{ 1719{
1869 int i; 1720 return hsw->dsp;
1721}
1870 1722
1871 hsw->msg = kzalloc(sizeof(struct ipc_message) * 1723void sst_hsw_init_module_state(struct sst_hsw *hsw)
1872 IPC_EMPTY_LIST_SIZE, GFP_KERNEL); 1724{
1873 if (hsw->msg == NULL) 1725 struct sst_module *module;
1874 return -ENOMEM; 1726 enum sst_hsw_module_id id;
1727
1728 /* the base fw contains several modules */
1729 for (id = SST_HSW_MODULE_BASE_FW; id < SST_HSW_MAX_MODULE_ID; id++) {
1730 module = sst_module_get_from_id(hsw->dsp, id);
1731 if (module) {
1732 /* module waves is active only after being enabled */
1733 if (id == SST_HSW_MODULE_WAVES)
1734 module->state = SST_MODULE_STATE_INITIALIZED;
1735 else
1736 module->state = SST_MODULE_STATE_ACTIVE;
1737 }
1738 }
1739}
1740
1741bool sst_hsw_is_module_loaded(struct sst_hsw *hsw, u32 module_id)
1742{
1743 struct sst_module *module;
1744
1745 module = sst_module_get_from_id(hsw->dsp, module_id);
1746 if (module == NULL || module->state == SST_MODULE_STATE_UNLOADED)
1747 return false;
1748 else
1749 return true;
1750}
1751
1752bool sst_hsw_is_module_active(struct sst_hsw *hsw, u32 module_id)
1753{
1754 struct sst_module *module;
1755
1756 module = sst_module_get_from_id(hsw->dsp, module_id);
1757 if (module != NULL && module->state == SST_MODULE_STATE_ACTIVE)
1758 return true;
1759 else
1760 return false;
1761}
1875 1762
1876 for (i = 0; i < IPC_EMPTY_LIST_SIZE; i++) { 1763void sst_hsw_set_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id)
1877 init_waitqueue_head(&hsw->msg[i].waitq); 1764{
1878 list_add(&hsw->msg[i].list, &hsw->empty_list); 1765 hsw->enabled_modules_rtd3 |= (1 << module_id);
1766}
1767
1768void sst_hsw_set_module_disabled_rtd3(struct sst_hsw *hsw, u32 module_id)
1769{
1770 hsw->enabled_modules_rtd3 &= ~(1 << module_id);
1771}
1772
1773bool sst_hsw_is_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id)
1774{
1775 return hsw->enabled_modules_rtd3 & (1 << module_id);
1776}
1777
1778void sst_hsw_reset_param_buf(struct sst_hsw *hsw)
1779{
1780 hsw->param_idx_w = 0;
1781 hsw->param_idx_r = 0;
1782 memset((void *)hsw->param_buf, 0, sizeof(hsw->param_buf));
1783}
1784
1785int sst_hsw_store_param_line(struct sst_hsw *hsw, u8 *buf)
1786{
1787 /* save line to the first available position of param buffer */
1788 if (hsw->param_idx_w > WAVES_PARAM_LINES - 1) {
1789 dev_warn(hsw->dev, "warning: param buffer overflow!\n");
1790 return -EPERM;
1791 }
1792 memcpy(hsw->param_buf[hsw->param_idx_w], buf, WAVES_PARAM_COUNT);
1793 hsw->param_idx_w++;
1794 return 0;
1795}
1796
1797int sst_hsw_load_param_line(struct sst_hsw *hsw, u8 *buf)
1798{
1799 u8 id = 0;
1800
1801 /* read the first matching line from param buffer */
1802 while (hsw->param_idx_r < WAVES_PARAM_LINES) {
1803 id = hsw->param_buf[hsw->param_idx_r][0];
1804 hsw->param_idx_r++;
1805 if (buf[0] == id) {
1806 memcpy(buf, hsw->param_buf[hsw->param_idx_r],
1807 WAVES_PARAM_COUNT);
1808 break;
1809 }
1879 } 1810 }
1811 if (hsw->param_idx_r > WAVES_PARAM_LINES - 1) {
1812 dev_dbg(hsw->dev, "end of buffer, roll to the beginning\n");
1813 hsw->param_idx_r = 0;
1814 return 0;
1815 }
1816 return 0;
1817}
1818
1819int sst_hsw_launch_param_buf(struct sst_hsw *hsw)
1820{
1821 int ret, idx;
1880 1822
1823 if (!sst_hsw_is_module_active(hsw, SST_HSW_MODULE_WAVES)) {
1824 dev_dbg(hsw->dev, "module waves is not active\n");
1825 return 0;
1826 }
1827
1828 /* put all param lines to DSP through ipc */
1829 for (idx = 0; idx < hsw->param_idx_w; idx++) {
1830 ret = sst_hsw_module_set_param(hsw,
1831 SST_HSW_MODULE_WAVES, 0, hsw->param_buf[idx][0],
1832 WAVES_PARAM_COUNT, hsw->param_buf[idx]);
1833 if (ret < 0)
1834 return ret;
1835 }
1881 return 0; 1836 return 0;
1882} 1837}
1883 1838
1884struct sst_dsp *sst_hsw_get_dsp(struct sst_hsw *hsw) 1839int sst_hsw_module_load(struct sst_hsw *hsw,
1840 u32 module_id, u32 instance_id, char *name)
1885{ 1841{
1886 return hsw->dsp; 1842 int ret = 0;
1843 const struct firmware *fw = NULL;
1844 struct sst_fw *hsw_sst_fw;
1845 struct sst_module *module;
1846 struct device *dev = hsw->dev;
1847 struct sst_dsp *dsp = hsw->dsp;
1848
1849 dev_dbg(dev, "sst_hsw_module_load id=%d, name='%s'", module_id, name);
1850
1851 module = sst_module_get_from_id(dsp, module_id);
1852 if (module == NULL) {
1853 /* loading for the first time */
1854 if (module_id == SST_HSW_MODULE_BASE_FW) {
1855 /* for base module: use fw requested in acpi probe */
1856 fw = dsp->pdata->fw;
1857 if (!fw) {
1858 dev_err(dev, "request Base fw failed\n");
1859 return -ENODEV;
1860 }
1861 } else {
1862 /* try and load any other optional modules if they are
1863 * available. Use dev_info instead of dev_err in case
1864 * request firmware failed */
1865 ret = request_firmware(&fw, name, dev);
1866 if (ret) {
1867 dev_info(dev, "fw image %s not available(%d)\n",
1868 name, ret);
1869 return ret;
1870 }
1871 }
1872 hsw_sst_fw = sst_fw_new(dsp, fw, hsw);
1873 if (hsw_sst_fw == NULL) {
1874 dev_err(dev, "error: failed to load firmware\n");
1875 ret = -ENOMEM;
1876 goto out;
1877 }
1878 module = sst_module_get_from_id(dsp, module_id);
1879 if (module == NULL) {
1880 dev_err(dev, "error: no module %d in firmware %s\n",
1881 module_id, name);
1882 }
1883 } else
1884 dev_info(dev, "module %d (%s) already loaded\n",
1885 module_id, name);
1886out:
1887 /* release fw, but base fw should be released by acpi driver */
1888 if (fw && module_id != SST_HSW_MODULE_BASE_FW)
1889 release_firmware(fw);
1890
1891 return ret;
1892}
1893
1894int sst_hsw_module_enable(struct sst_hsw *hsw,
1895 u32 module_id, u32 instance_id)
1896{
1897 int ret;
1898 u32 header = 0;
1899 struct sst_hsw_ipc_module_config config;
1900 struct sst_module *module;
1901 struct sst_module_runtime *runtime;
1902 struct device *dev = hsw->dev;
1903 struct sst_dsp *dsp = hsw->dsp;
1904
1905 if (!sst_hsw_is_module_loaded(hsw, module_id)) {
1906 dev_dbg(dev, "module %d not loaded\n", module_id);
1907 return 0;
1908 }
1909
1910 if (sst_hsw_is_module_active(hsw, module_id)) {
1911 dev_info(dev, "module %d already enabled\n", module_id);
1912 return 0;
1913 }
1914
1915 module = sst_module_get_from_id(dsp, module_id);
1916 if (module == NULL) {
1917 dev_err(dev, "module %d not valid\n", module_id);
1918 return -ENXIO;
1919 }
1920
1921 runtime = sst_module_runtime_get_from_id(module, module_id);
1922 if (runtime == NULL) {
1923 dev_err(dev, "runtime %d not valid", module_id);
1924 return -ENXIO;
1925 }
1926
1927 header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
1928 IPC_MODULE_OPERATION(IPC_MODULE_ENABLE) |
1929 IPC_MODULE_ID(module_id);
1930 dev_dbg(dev, "module enable header: %x\n", header);
1931
1932 config.map.module_entries_count = 1;
1933 config.map.module_entries[0].module_id = module->id;
1934 config.map.module_entries[0].entry_point = module->entry;
1935
1936 config.persistent_mem.offset =
1937 sst_dsp_get_offset(dsp,
1938 runtime->persistent_offset, SST_MEM_DRAM);
1939 config.persistent_mem.size = module->persistent_size;
1940
1941 config.scratch_mem.offset =
1942 sst_dsp_get_offset(dsp,
1943 dsp->scratch_offset, SST_MEM_DRAM);
1944 config.scratch_mem.size = module->scratch_size;
1945 dev_dbg(dev, "mod %d enable p:%d @ %x, s:%d @ %x, ep: %x",
1946 config.map.module_entries[0].module_id,
1947 config.persistent_mem.size,
1948 config.persistent_mem.offset,
1949 config.scratch_mem.size, config.scratch_mem.offset,
1950 config.map.module_entries[0].entry_point);
1951
1952 ret = sst_ipc_tx_message_wait(&hsw->ipc, header,
1953 &config, sizeof(config), NULL, 0);
1954 if (ret < 0)
1955 dev_err(dev, "ipc: module enable failed - %d\n", ret);
1956 else
1957 module->state = SST_MODULE_STATE_ACTIVE;
1958
1959 return ret;
1960}
1961
1962int sst_hsw_module_disable(struct sst_hsw *hsw,
1963 u32 module_id, u32 instance_id)
1964{
1965 int ret;
1966 u32 header;
1967 struct sst_module *module;
1968 struct device *dev = hsw->dev;
1969 struct sst_dsp *dsp = hsw->dsp;
1970
1971 if (!sst_hsw_is_module_loaded(hsw, module_id)) {
1972 dev_dbg(dev, "module %d not loaded\n", module_id);
1973 return 0;
1974 }
1975
1976 if (!sst_hsw_is_module_active(hsw, module_id)) {
1977 dev_info(dev, "module %d already disabled\n", module_id);
1978 return 0;
1979 }
1980
1981 module = sst_module_get_from_id(dsp, module_id);
1982 if (module == NULL) {
1983 dev_err(dev, "module %d not valid\n", module_id);
1984 return -ENXIO;
1985 }
1986
1987 header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
1988 IPC_MODULE_OPERATION(IPC_MODULE_DISABLE) |
1989 IPC_MODULE_ID(module_id);
1990
1991 ret = sst_ipc_tx_message_wait(&hsw->ipc, header, NULL, 0, NULL, 0);
1992 if (ret < 0)
1993 dev_err(dev, "module disable failed - %d\n", ret);
1994 else
1995 module->state = SST_MODULE_STATE_INITIALIZED;
1996
1997 return ret;
1998}
1999
2000int sst_hsw_module_set_param(struct sst_hsw *hsw,
2001 u32 module_id, u32 instance_id, u32 parameter_id,
2002 u32 param_size, char *param)
2003{
2004 int ret;
2005 unsigned char *data = NULL;
2006 u32 header = 0;
2007 u32 payload_size = 0, transfer_parameter_size = 0;
2008 dma_addr_t dma_addr = 0;
2009 struct sst_hsw_transfer_parameter *parameter;
2010 struct device *dev = hsw->dev;
2011
2012 header = IPC_GLB_TYPE(IPC_GLB_MODULE_OPERATION) |
2013 IPC_MODULE_OPERATION(IPC_MODULE_SET_PARAMETER) |
2014 IPC_MODULE_ID(module_id);
2015 dev_dbg(dev, "sst_hsw_module_set_param header=%x\n", header);
2016
2017 payload_size = param_size +
2018 sizeof(struct sst_hsw_transfer_parameter) -
2019 sizeof(struct sst_hsw_transfer_list);
2020 dev_dbg(dev, "parameter size : %d\n", param_size);
2021 dev_dbg(dev, "payload size : %d\n", payload_size);
2022
2023 if (payload_size <= SST_HSW_IPC_MAX_SHORT_PARAMETER_SIZE) {
2024 /* short parameter, mailbox can contain data */
2025 dev_dbg(dev, "transfer parameter size : %d\n",
2026 transfer_parameter_size);
2027
2028 transfer_parameter_size = ALIGN(payload_size, 4);
2029 dev_dbg(dev, "transfer parameter aligned size : %d\n",
2030 transfer_parameter_size);
2031
2032 parameter = kzalloc(transfer_parameter_size, GFP_KERNEL);
2033 if (parameter == NULL)
2034 return -ENOMEM;
2035
2036 memcpy(parameter->data, param, param_size);
2037 } else {
2038 dev_warn(dev, "transfer parameter size too large!");
2039 return 0;
2040 }
2041
2042 parameter->parameter_id = parameter_id;
2043 parameter->data_size = param_size;
2044
2045 ret = sst_ipc_tx_message_wait(&hsw->ipc, header,
2046 parameter, transfer_parameter_size , NULL, 0);
2047 if (ret < 0)
2048 dev_err(dev, "ipc: module set parameter failed - %d\n", ret);
2049
2050 kfree(parameter);
2051
2052 if (data)
2053 dma_free_coherent(hsw->dsp->dma_dev,
2054 param_size, (void *)data, dma_addr);
2055
2056 return ret;
1887} 2057}
1888 2058
1889static struct sst_dsp_device hsw_dev = { 2059static struct sst_dsp_device hsw_dev = {
@@ -1891,10 +2061,48 @@ static struct sst_dsp_device hsw_dev = {
1891 .ops = &haswell_ops, 2061 .ops = &haswell_ops,
1892}; 2062};
1893 2063
2064static void hsw_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg)
2065{
2066 /* send the message */
2067 sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size);
2068 sst_dsp_ipc_msg_tx(ipc->dsp, msg->header);
2069}
2070
2071static void hsw_shim_dbg(struct sst_generic_ipc *ipc, const char *text)
2072{
2073 struct sst_dsp *sst = ipc->dsp;
2074 u32 isr, ipcd, imrx, ipcx;
2075
2076 ipcx = sst_dsp_shim_read_unlocked(sst, SST_IPCX);
2077 isr = sst_dsp_shim_read_unlocked(sst, SST_ISRX);
2078 ipcd = sst_dsp_shim_read_unlocked(sst, SST_IPCD);
2079 imrx = sst_dsp_shim_read_unlocked(sst, SST_IMRX);
2080
2081 dev_err(ipc->dev,
2082 "ipc: --%s-- ipcx 0x%8.8x isr 0x%8.8x ipcd 0x%8.8x imrx 0x%8.8x\n",
2083 text, ipcx, isr, ipcd, imrx);
2084}
2085
2086static void hsw_tx_data_copy(struct ipc_message *msg, char *tx_data,
2087 size_t tx_size)
2088{
2089 memcpy(msg->tx_data, tx_data, tx_size);
2090}
2091
2092static u64 hsw_reply_msg_match(u64 header, u64 *mask)
2093{
2094 /* clear reply bits & status bits */
2095 header &= ~(IPC_STATUS_MASK | IPC_GLB_REPLY_MASK);
2096 *mask = (u64)-1;
2097
2098 return header;
2099}
2100
1894int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata) 2101int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
1895{ 2102{
1896 struct sst_hsw_ipc_fw_version version; 2103 struct sst_hsw_ipc_fw_version version;
1897 struct sst_hsw *hsw; 2104 struct sst_hsw *hsw;
2105 struct sst_generic_ipc *ipc;
1898 int ret; 2106 int ret;
1899 2107
1900 dev_dbg(dev, "initialising Audio DSP IPC\n"); 2108 dev_dbg(dev, "initialising Audio DSP IPC\n");
@@ -1903,39 +2111,30 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
1903 if (hsw == NULL) 2111 if (hsw == NULL)
1904 return -ENOMEM; 2112 return -ENOMEM;
1905 2113
1906 hsw->dev = dev; 2114 ipc = &hsw->ipc;
1907 INIT_LIST_HEAD(&hsw->stream_list); 2115 ipc->dev = dev;
1908 INIT_LIST_HEAD(&hsw->tx_list); 2116 ipc->ops.tx_msg = hsw_tx_msg;
1909 INIT_LIST_HEAD(&hsw->rx_list); 2117 ipc->ops.shim_dbg = hsw_shim_dbg;
1910 INIT_LIST_HEAD(&hsw->empty_list); 2118 ipc->ops.tx_data_copy = hsw_tx_data_copy;
1911 init_waitqueue_head(&hsw->boot_wait); 2119 ipc->ops.reply_msg_match = hsw_reply_msg_match;
1912 init_waitqueue_head(&hsw->wait_txq);
1913
1914 ret = msg_empty_list_init(hsw);
1915 if (ret < 0)
1916 return -ENOMEM;
1917 2120
1918 /* start the IPC message thread */ 2121 ret = sst_ipc_init(ipc);
1919 init_kthread_worker(&hsw->kworker); 2122 if (ret != 0)
1920 hsw->tx_thread = kthread_run(kthread_worker_fn, 2123 goto ipc_init_err;
1921 &hsw->kworker, "%s",
1922 dev_name(hsw->dev));
1923 if (IS_ERR(hsw->tx_thread)) {
1924 ret = PTR_ERR(hsw->tx_thread);
1925 dev_err(hsw->dev, "error: failed to create message TX task\n");
1926 goto err_free_msg;
1927 }
1928 init_kthread_work(&hsw->kwork, ipc_tx_msgs);
1929 2124
2125 INIT_LIST_HEAD(&hsw->stream_list);
2126 init_waitqueue_head(&hsw->boot_wait);
1930 hsw_dev.thread_context = hsw; 2127 hsw_dev.thread_context = hsw;
1931 2128
1932 /* init SST shim */ 2129 /* init SST shim */
1933 hsw->dsp = sst_dsp_new(dev, &hsw_dev, pdata); 2130 hsw->dsp = sst_dsp_new(dev, &hsw_dev, pdata);
1934 if (hsw->dsp == NULL) { 2131 if (hsw->dsp == NULL) {
1935 ret = -ENODEV; 2132 ret = -ENODEV;
1936 goto dsp_err; 2133 goto dsp_new_err;
1937 } 2134 }
1938 2135
2136 ipc->dsp = hsw->dsp;
2137
1939 /* allocate DMA buffer for context storage */ 2138 /* allocate DMA buffer for context storage */
1940 hsw->dx_context = dma_alloc_coherent(hsw->dsp->dma_dev, 2139 hsw->dx_context = dma_alloc_coherent(hsw->dsp->dma_dev,
1941 SST_HSW_DX_CONTEXT_SIZE, &hsw->dx_context_paddr, GFP_KERNEL); 2140 SST_HSW_DX_CONTEXT_SIZE, &hsw->dx_context_paddr, GFP_KERNEL);
@@ -1947,18 +2146,22 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
1947 /* keep the DSP in reset state for base FW loading */ 2146 /* keep the DSP in reset state for base FW loading */
1948 sst_dsp_reset(hsw->dsp); 2147 sst_dsp_reset(hsw->dsp);
1949 2148
1950 hsw->sst_fw = sst_fw_new(hsw->dsp, pdata->fw, hsw); 2149 /* load base module and other modules in base firmware image */
1951 if (hsw->sst_fw == NULL) { 2150 ret = sst_hsw_module_load(hsw, SST_HSW_MODULE_BASE_FW, 0, "Base");
1952 ret = -ENODEV; 2151 if (ret < 0)
1953 dev_err(dev, "error: failed to load firmware\n");
1954 goto fw_err; 2152 goto fw_err;
1955 } 2153
2154 /* try to load module waves */
2155 sst_hsw_module_load(hsw, SST_HSW_MODULE_WAVES, 0, "intel/IntcPP01.bin");
1956 2156
1957 /* allocate scratch mem regions */ 2157 /* allocate scratch mem regions */
1958 ret = sst_block_alloc_scratch(hsw->dsp); 2158 ret = sst_block_alloc_scratch(hsw->dsp);
1959 if (ret < 0) 2159 if (ret < 0)
1960 goto boot_err; 2160 goto boot_err;
1961 2161
2162 /* init param buffer */
2163 sst_hsw_reset_param_buf(hsw);
2164
1962 /* wait for DSP boot completion */ 2165 /* wait for DSP boot completion */
1963 sst_dsp_boot(hsw->dsp); 2166 sst_dsp_boot(hsw->dsp);
1964 ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete, 2167 ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete,
@@ -1971,6 +2174,9 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
1971 goto boot_err; 2174 goto boot_err;
1972 } 2175 }
1973 2176
2177 /* init module state after boot */
2178 sst_hsw_init_module_state(hsw);
2179
1974 /* get the FW version */ 2180 /* get the FW version */
1975 sst_hsw_fw_get_version(hsw, &version); 2181 sst_hsw_fw_get_version(hsw, &version);
1976 2182
@@ -1986,17 +2192,16 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
1986 2192
1987boot_err: 2193boot_err:
1988 sst_dsp_reset(hsw->dsp); 2194 sst_dsp_reset(hsw->dsp);
1989 sst_fw_free(hsw->sst_fw); 2195 sst_fw_free_all(hsw->dsp);
1990fw_err: 2196fw_err:
1991 dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE, 2197 dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE,
1992 hsw->dx_context, hsw->dx_context_paddr); 2198 hsw->dx_context, hsw->dx_context_paddr);
1993dma_err: 2199dma_err:
1994 sst_dsp_free(hsw->dsp); 2200 sst_dsp_free(hsw->dsp);
1995dsp_err: 2201dsp_new_err:
1996 kthread_stop(hsw->tx_thread); 2202 sst_ipc_fini(ipc);
1997err_free_msg: 2203ipc_init_err:
1998 kfree(hsw->msg); 2204 kfree(hsw);
1999
2000 return ret; 2205 return ret;
2001} 2206}
2002EXPORT_SYMBOL_GPL(sst_hsw_dsp_init); 2207EXPORT_SYMBOL_GPL(sst_hsw_dsp_init);
@@ -2010,7 +2215,6 @@ void sst_hsw_dsp_free(struct device *dev, struct sst_pdata *pdata)
2010 dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE, 2215 dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE,
2011 hsw->dx_context, hsw->dx_context_paddr); 2216 hsw->dx_context, hsw->dx_context_paddr);
2012 sst_dsp_free(hsw->dsp); 2217 sst_dsp_free(hsw->dsp);
2013 kthread_stop(hsw->tx_thread); 2218 sst_ipc_fini(&hsw->ipc);
2014 kfree(hsw->msg);
2015} 2219}
2016EXPORT_SYMBOL_GPL(sst_hsw_dsp_free); 2220EXPORT_SYMBOL_GPL(sst_hsw_dsp_free);
diff --git a/sound/soc/intel/sst-haswell-ipc.h b/sound/soc/intel/haswell/sst-haswell-ipc.h
index 858096041cb1..06d71aefa1fe 100644
--- a/sound/soc/intel/sst-haswell-ipc.h
+++ b/sound/soc/intel/haswell/sst-haswell-ipc.h
@@ -37,6 +37,9 @@
37#define SST_HSW_IPC_MAX_PAYLOAD_SIZE 400 37#define SST_HSW_IPC_MAX_PAYLOAD_SIZE 400
38#define SST_HSW_MAX_INFO_SIZE 64 38#define SST_HSW_MAX_INFO_SIZE 64
39#define SST_HSW_BUILD_HASH_LENGTH 40 39#define SST_HSW_BUILD_HASH_LENGTH 40
40#define SST_HSW_IPC_MAX_SHORT_PARAMETER_SIZE 500
41#define WAVES_PARAM_COUNT 128
42#define WAVES_PARAM_LINES 160
40 43
41struct sst_hsw; 44struct sst_hsw;
42struct sst_hsw_stream; 45struct sst_hsw_stream;
@@ -187,6 +190,28 @@ enum sst_hsw_performance_action {
187 SST_HSW_PERF_STOP = 1, 190 SST_HSW_PERF_STOP = 1,
188}; 191};
189 192
193struct sst_hsw_transfer_info {
194 uint32_t destination; /* destination address */
195 uint32_t reverse:1; /* if 1 data flows from destination */
196 uint32_t size:31; /* transfer size in bytes.*/
197 uint16_t first_page_offset; /* offset to data in the first page. */
198 uint8_t packed_pages; /* page addresses. Each occupies 20 bits */
199} __attribute__((packed));
200
201struct sst_hsw_transfer_list {
202 uint32_t transfers_count;
203 struct sst_hsw_transfer_info transfers;
204} __attribute__((packed));
205
206struct sst_hsw_transfer_parameter {
207 uint32_t parameter_id;
208 uint32_t data_size;
209 union {
210 uint8_t data[1];
211 struct sst_hsw_transfer_list transfer_list;
212 };
213} __attribute__((packed));
214
190/* SST firmware module info */ 215/* SST firmware module info */
191struct sst_hsw_module_info { 216struct sst_hsw_module_info {
192 u8 name[SST_HSW_MAX_INFO_SIZE]; 217 u8 name[SST_HSW_MAX_INFO_SIZE];
@@ -215,6 +240,12 @@ struct sst_hsw_fx_enable {
215 struct sst_hsw_memory_info persistent_mem; 240 struct sst_hsw_memory_info persistent_mem;
216} __attribute__((packed)); 241} __attribute__((packed));
217 242
243struct sst_hsw_ipc_module_config {
244 struct sst_hsw_module_map map;
245 struct sst_hsw_memory_info persistent_mem;
246 struct sst_hsw_memory_info scratch_mem;
247} __attribute__((packed));
248
218struct sst_hsw_get_fx_param { 249struct sst_hsw_get_fx_param {
219 u32 parameter_id; 250 u32 parameter_id;
220 u32 param_size; 251 u32 param_size;
@@ -467,6 +498,28 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata);
467void sst_hsw_dsp_free(struct device *dev, struct sst_pdata *pdata); 498void sst_hsw_dsp_free(struct device *dev, struct sst_pdata *pdata);
468struct sst_dsp *sst_hsw_get_dsp(struct sst_hsw *hsw); 499struct sst_dsp *sst_hsw_get_dsp(struct sst_hsw *hsw);
469 500
501/* fw module function */
502void sst_hsw_init_module_state(struct sst_hsw *hsw);
503bool sst_hsw_is_module_loaded(struct sst_hsw *hsw, u32 module_id);
504bool sst_hsw_is_module_active(struct sst_hsw *hsw, u32 module_id);
505void sst_hsw_set_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id);
506void sst_hsw_set_module_disabled_rtd3(struct sst_hsw *hsw, u32 module_id);
507bool sst_hsw_is_module_enabled_rtd3(struct sst_hsw *hsw, u32 module_id);
508void sst_hsw_reset_param_buf(struct sst_hsw *hsw);
509int sst_hsw_store_param_line(struct sst_hsw *hsw, u8 *buf);
510int sst_hsw_load_param_line(struct sst_hsw *hsw, u8 *buf);
511int sst_hsw_launch_param_buf(struct sst_hsw *hsw);
512
513int sst_hsw_module_load(struct sst_hsw *hsw,
514 u32 module_id, u32 instance_id, char *name);
515int sst_hsw_module_enable(struct sst_hsw *hsw,
516 u32 module_id, u32 instance_id);
517int sst_hsw_module_disable(struct sst_hsw *hsw,
518 u32 module_id, u32 instance_id);
519int sst_hsw_module_set_param(struct sst_hsw *hsw,
520 u32 module_id, u32 instance_id, u32 parameter_id,
521 u32 param_size, char *param);
522
470/* runtime module management */ 523/* runtime module management */
471struct sst_module_runtime *sst_hsw_runtime_module_create(struct sst_hsw *hsw, 524struct sst_module_runtime *sst_hsw_runtime_module_create(struct sst_hsw *hsw,
472 int mod_id, int offset); 525 int mod_id, int offset);
diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/haswell/sst-haswell-pcm.c
index 7e21e8f85885..23ae0400d6db 100644
--- a/sound/soc/intel/sst-haswell-pcm.c
+++ b/sound/soc/intel/haswell/sst-haswell-pcm.c
@@ -29,9 +29,9 @@
29#include <sound/tlv.h> 29#include <sound/tlv.h>
30#include <sound/compress_driver.h> 30#include <sound/compress_driver.h>
31 31
32#include "sst-haswell-ipc.h" 32#include "../haswell/sst-haswell-ipc.h"
33#include "sst-dsp-priv.h" 33#include "../common/sst-dsp-priv.h"
34#include "sst-dsp.h" 34#include "../common/sst-dsp.h"
35 35
36#define HSW_PCM_COUNT 6 36#define HSW_PCM_COUNT 6
37#define HSW_VOLUME_MAX 0x7FFFFFFF /* 0dB */ 37#define HSW_VOLUME_MAX 0x7FFFFFFF /* 0dB */
@@ -137,6 +137,7 @@ struct hsw_priv_data {
137 struct device *dev; 137 struct device *dev;
138 enum hsw_pm_state pm_state; 138 enum hsw_pm_state pm_state;
139 struct snd_soc_card *soc_card; 139 struct snd_soc_card *soc_card;
140 struct sst_module_runtime *runtime_waves; /* sound effect module */
140 141
141 /* page tables */ 142 /* page tables */
142 struct snd_dma_buffer dmab[HSW_PCM_COUNT][2]; 143 struct snd_dma_buffer dmab[HSW_PCM_COUNT][2];
@@ -318,6 +319,93 @@ static int hsw_volume_get(struct snd_kcontrol *kcontrol,
318 return 0; 319 return 0;
319} 320}
320 321
322static int hsw_waves_switch_get(struct snd_kcontrol *kcontrol,
323 struct snd_ctl_elem_value *ucontrol)
324{
325 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
326 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
327 struct sst_hsw *hsw = pdata->hsw;
328 enum sst_hsw_module_id id = SST_HSW_MODULE_WAVES;
329
330 ucontrol->value.integer.value[0] =
331 (sst_hsw_is_module_active(hsw, id) ||
332 sst_hsw_is_module_enabled_rtd3(hsw, id));
333 return 0;
334}
335
336static int hsw_waves_switch_put(struct snd_kcontrol *kcontrol,
337 struct snd_ctl_elem_value *ucontrol)
338{
339 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
340 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
341 struct sst_hsw *hsw = pdata->hsw;
342 int ret = 0;
343 enum sst_hsw_module_id id = SST_HSW_MODULE_WAVES;
344 bool switch_on = (bool)ucontrol->value.integer.value[0];
345
346 /* if module is in RAM on the DSP, apply user settings to module through
347 * ipc. If module is not in RAM on the DSP, store user setting for
348 * track */
349 if (sst_hsw_is_module_loaded(hsw, id)) {
350 if (switch_on == sst_hsw_is_module_active(hsw, id))
351 return 0;
352
353 if (switch_on)
354 ret = sst_hsw_module_enable(hsw, id, 0);
355 else
356 ret = sst_hsw_module_disable(hsw, id, 0);
357 } else {
358 if (switch_on == sst_hsw_is_module_enabled_rtd3(hsw, id))
359 return 0;
360
361 if (switch_on)
362 sst_hsw_set_module_enabled_rtd3(hsw, id);
363 else
364 sst_hsw_set_module_disabled_rtd3(hsw, id);
365 }
366
367 return ret;
368}
369
370static int hsw_waves_param_get(struct snd_kcontrol *kcontrol,
371 struct snd_ctl_elem_value *ucontrol)
372{
373 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
374 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
375 struct sst_hsw *hsw = pdata->hsw;
376
377 /* return a matching line from param buffer */
378 return sst_hsw_load_param_line(hsw, ucontrol->value.bytes.data);
379}
380
381static int hsw_waves_param_put(struct snd_kcontrol *kcontrol,
382 struct snd_ctl_elem_value *ucontrol)
383{
384 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
385 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
386 struct sst_hsw *hsw = pdata->hsw;
387 int ret;
388 enum sst_hsw_module_id id = SST_HSW_MODULE_WAVES;
389 int param_id = ucontrol->value.bytes.data[0];
390 int param_size = WAVES_PARAM_COUNT;
391
392 /* clear param buffer and reset buffer index */
393 if (param_id == 0xFF) {
394 sst_hsw_reset_param_buf(hsw);
395 return 0;
396 }
397
398 /* store params into buffer */
399 ret = sst_hsw_store_param_line(hsw, ucontrol->value.bytes.data);
400 if (ret < 0)
401 return ret;
402
403 if (sst_hsw_is_module_active(hsw, id))
404 ret = sst_hsw_module_set_param(hsw, id, 0, param_id,
405 param_size, ucontrol->value.bytes.data);
406 return ret;
407}
408
321/* TLV used by both global and stream volumes */ 409/* TLV used by both global and stream volumes */
322static const DECLARE_TLV_DB_SCALE(hsw_vol_tlv, -9000, 300, 1); 410static const DECLARE_TLV_DB_SCALE(hsw_vol_tlv, -9000, 300, 1);
323 411
@@ -339,6 +427,12 @@ static const struct snd_kcontrol_new hsw_volume_controls[] = {
339 SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 4, 0, 8, 427 SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 4, 0, 8,
340 ARRAY_SIZE(volume_map) - 1, 0, 428 ARRAY_SIZE(volume_map) - 1, 0,
341 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), 429 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
430 /* enable/disable module waves */
431 SOC_SINGLE_BOOL_EXT("Waves Switch", 0,
432 hsw_waves_switch_get, hsw_waves_switch_put),
433 /* set parameters to module waves */
434 SND_SOC_BYTES_EXT("Waves Set Param", WAVES_PARAM_COUNT,
435 hsw_waves_param_get, hsw_waves_param_put),
342}; 436};
343 437
344/* Create DMA buffer page table for DSP */ 438/* Create DMA buffer page table for DSP */
@@ -807,6 +901,14 @@ static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
807 pcm_data->runtime->persistent_offset; 901 pcm_data->runtime->persistent_offset;
808 } 902 }
809 903
904 /* create runtime blocks for module waves */
905 if (sst_hsw_is_module_loaded(hsw, SST_HSW_MODULE_WAVES)) {
906 pdata->runtime_waves = sst_hsw_runtime_module_create(hsw,
907 SST_HSW_MODULE_WAVES, 0);
908 if (pdata->runtime_waves == NULL)
909 goto err;
910 }
911
810 return 0; 912 return 0;
811 913
812err: 914err:
@@ -820,14 +922,17 @@ err:
820 922
821static void hsw_pcm_free_modules(struct hsw_priv_data *pdata) 923static void hsw_pcm_free_modules(struct hsw_priv_data *pdata)
822{ 924{
925 struct sst_hsw *hsw = pdata->hsw;
823 struct hsw_pcm_data *pcm_data; 926 struct hsw_pcm_data *pcm_data;
824 int i; 927 int i;
825 928
826 for (i = 0; i < ARRAY_SIZE(mod_map); i++) { 929 for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
827 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream]; 930 pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
828
829 sst_hsw_runtime_module_free(pcm_data->runtime); 931 sst_hsw_runtime_module_free(pcm_data->runtime);
830 } 932 }
933 if (sst_hsw_is_module_loaded(hsw, SST_HSW_MODULE_WAVES)) {
934 sst_hsw_runtime_module_free(pdata->runtime_waves);
935 }
831} 936}
832 937
833static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd) 938static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
@@ -984,7 +1089,9 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
984 } 1089 }
985 1090
986 /* allocate runtime modules */ 1091 /* allocate runtime modules */
987 hsw_pcm_create_modules(priv_data); 1092 ret = hsw_pcm_create_modules(priv_data);
1093 if (ret < 0)
1094 goto err;
988 1095
989 /* enable runtime PM with auto suspend */ 1096 /* enable runtime PM with auto suspend */
990 pm_runtime_set_autosuspend_delay(platform->dev, 1097 pm_runtime_set_autosuspend_delay(platform->dev,
@@ -996,7 +1103,7 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
996 return 0; 1103 return 0;
997 1104
998err: 1105err:
999 for (;i >= 0; i--) { 1106 for (--i; i >= 0; i--) {
1000 if (hsw_dais[i].playback.channels_min) 1107 if (hsw_dais[i].playback.channels_min)
1001 snd_dma_free_pages(&priv_data->dmab[i][0]); 1108 snd_dma_free_pages(&priv_data->dmab[i][0]);
1002 if (hsw_dais[i].capture.channels_min) 1109 if (hsw_dais[i].capture.channels_min)
@@ -1101,10 +1208,18 @@ static int hsw_pcm_runtime_suspend(struct device *dev)
1101{ 1208{
1102 struct hsw_priv_data *pdata = dev_get_drvdata(dev); 1209 struct hsw_priv_data *pdata = dev_get_drvdata(dev);
1103 struct sst_hsw *hsw = pdata->hsw; 1210 struct sst_hsw *hsw = pdata->hsw;
1211 int ret;
1104 1212
1105 if (pdata->pm_state >= HSW_PM_STATE_RTD3) 1213 if (pdata->pm_state >= HSW_PM_STATE_RTD3)
1106 return 0; 1214 return 0;
1107 1215
1216 /* fw modules will be unloaded on RTD3, set flag to track */
1217 if (sst_hsw_is_module_active(hsw, SST_HSW_MODULE_WAVES)) {
1218 ret = sst_hsw_module_disable(hsw, SST_HSW_MODULE_WAVES, 0);
1219 if (ret < 0)
1220 return ret;
1221 sst_hsw_set_module_enabled_rtd3(hsw, SST_HSW_MODULE_WAVES);
1222 }
1108 sst_hsw_dsp_runtime_suspend(hsw); 1223 sst_hsw_dsp_runtime_suspend(hsw);
1109 sst_hsw_dsp_runtime_sleep(hsw); 1224 sst_hsw_dsp_runtime_sleep(hsw);
1110 pdata->pm_state = HSW_PM_STATE_RTD3; 1225 pdata->pm_state = HSW_PM_STATE_RTD3;
@@ -1139,6 +1254,19 @@ static int hsw_pcm_runtime_resume(struct device *dev)
1139 else if (ret == 1) /* no action required */ 1254 else if (ret == 1) /* no action required */
1140 return 0; 1255 return 0;
1141 1256
1257 /* check flag when resume */
1258 if (sst_hsw_is_module_enabled_rtd3(hsw, SST_HSW_MODULE_WAVES)) {
1259 ret = sst_hsw_module_enable(hsw, SST_HSW_MODULE_WAVES, 0);
1260 if (ret < 0)
1261 return ret;
1262 /* put parameters from buffer to dsp */
1263 ret = sst_hsw_launch_param_buf(hsw);
1264 if (ret < 0)
1265 return ret;
1266 /* unset flag */
1267 sst_hsw_set_module_disabled_rtd3(hsw, SST_HSW_MODULE_WAVES);
1268 }
1269
1142 pdata->pm_state = HSW_PM_STATE_D0; 1270 pdata->pm_state = HSW_PM_STATE_D0;
1143 return ret; 1271 return ret;
1144} 1272}
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index 07f77815a586..b05fb1c1a848 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -58,6 +58,12 @@
58 58
59#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12 59#define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12
60#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8 60#define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8
61#define JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24
62#define JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16
63#define JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_MASK \
64 (0xf << JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET)
65#define JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_MASK \
66 (0x1f << JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET)
61 67
62#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19) 68#define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19)
63#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16) 69#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16)
@@ -79,6 +85,7 @@
79#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET 16 85#define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET 16
80 86
81#define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12) 87#define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12)
88#define JZ_AIC_I2S_FMT_DISABLE_BIT_ICLK BIT(13)
82#define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4) 89#define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4)
83#define JZ_AIC_I2S_FMT_MSB BIT(0) 90#define JZ_AIC_I2S_FMT_MSB BIT(0)
84 91
@@ -87,6 +94,13 @@
87#define JZ_AIC_CLK_DIV_MASK 0xf 94#define JZ_AIC_CLK_DIV_MASK 0xf
88#define I2SDIV_DV_SHIFT 8 95#define I2SDIV_DV_SHIFT 8
89#define I2SDIV_DV_MASK (0xf << I2SDIV_DV_SHIFT) 96#define I2SDIV_DV_MASK (0xf << I2SDIV_DV_SHIFT)
97#define I2SDIV_IDV_SHIFT 8
98#define I2SDIV_IDV_MASK (0xf << I2SDIV_IDV_SHIFT)
99
100enum jz47xx_i2s_version {
101 JZ_I2S_JZ4740,
102 JZ_I2S_JZ4780,
103};
90 104
91struct jz4740_i2s { 105struct jz4740_i2s {
92 struct resource *mem; 106 struct resource *mem;
@@ -98,6 +112,8 @@ struct jz4740_i2s {
98 112
99 struct snd_dmaengine_dai_dma_data playback_dma_data; 113 struct snd_dmaengine_dai_dma_data playback_dma_data;
100 struct snd_dmaengine_dai_dma_data capture_dma_data; 114 struct snd_dmaengine_dai_dma_data capture_dma_data;
115
116 enum jz47xx_i2s_version version;
101}; 117};
102 118
103static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s, 119static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s,
@@ -267,13 +283,22 @@ static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
267 ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO; 283 ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO;
268 else 284 else
269 ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO; 285 ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO;
286
287 div_reg &= ~I2SDIV_DV_MASK;
288 div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
270 } else { 289 } else {
271 ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK; 290 ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
272 ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET; 291 ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
292
293 if (i2s->version >= JZ_I2S_JZ4780) {
294 div_reg &= ~I2SDIV_IDV_MASK;
295 div_reg |= (div - 1) << I2SDIV_IDV_SHIFT;
296 } else {
297 div_reg &= ~I2SDIV_DV_MASK;
298 div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
299 }
273 } 300 }
274 301
275 div_reg &= ~I2SDIV_DV_MASK;
276 div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
277 jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl); 302 jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
278 jz4740_i2s_write(i2s, JZ_REG_AIC_CLK_DIV, div_reg); 303 jz4740_i2s_write(i2s, JZ_REG_AIC_CLK_DIV, div_reg);
279 304
@@ -369,11 +394,19 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
369 snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, 394 snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
370 &i2s->capture_dma_data); 395 &i2s->capture_dma_data);
371 396
372 conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) | 397 if (i2s->version >= JZ_I2S_JZ4780) {
373 (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) | 398 conf = (7 << JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
374 JZ_AIC_CONF_OVERFLOW_PLAY_LAST | 399 (8 << JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
375 JZ_AIC_CONF_I2S | 400 JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
376 JZ_AIC_CONF_INTERNAL_CODEC; 401 JZ_AIC_CONF_I2S |
402 JZ_AIC_CONF_INTERNAL_CODEC;
403 } else {
404 conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
405 (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
406 JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
407 JZ_AIC_CONF_I2S |
408 JZ_AIC_CONF_INTERNAL_CODEC;
409 }
377 410
378 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET); 411 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
379 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf); 412 jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
@@ -422,13 +455,34 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = {
422 .resume = jz4740_i2s_resume, 455 .resume = jz4740_i2s_resume,
423}; 456};
424 457
458static struct snd_soc_dai_driver jz4780_i2s_dai = {
459 .probe = jz4740_i2s_dai_probe,
460 .remove = jz4740_i2s_dai_remove,
461 .playback = {
462 .channels_min = 1,
463 .channels_max = 2,
464 .rates = SNDRV_PCM_RATE_8000_48000,
465 .formats = JZ4740_I2S_FMTS,
466 },
467 .capture = {
468 .channels_min = 2,
469 .channels_max = 2,
470 .rates = SNDRV_PCM_RATE_8000_48000,
471 .formats = JZ4740_I2S_FMTS,
472 },
473 .ops = &jz4740_i2s_dai_ops,
474 .suspend = jz4740_i2s_suspend,
475 .resume = jz4740_i2s_resume,
476};
477
425static const struct snd_soc_component_driver jz4740_i2s_component = { 478static const struct snd_soc_component_driver jz4740_i2s_component = {
426 .name = "jz4740-i2s", 479 .name = "jz4740-i2s",
427}; 480};
428 481
429#ifdef CONFIG_OF 482#ifdef CONFIG_OF
430static const struct of_device_id jz4740_of_matches[] = { 483static const struct of_device_id jz4740_of_matches[] = {
431 { .compatible = "ingenic,jz4740-i2s" }, 484 { .compatible = "ingenic,jz4740-i2s", .data = (void *)JZ_I2S_JZ4740 },
485 { .compatible = "ingenic,jz4780-i2s", .data = (void *)JZ_I2S_JZ4780 },
432 { /* sentinel */ } 486 { /* sentinel */ }
433}; 487};
434#endif 488#endif
@@ -438,11 +492,16 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev)
438 struct jz4740_i2s *i2s; 492 struct jz4740_i2s *i2s;
439 struct resource *mem; 493 struct resource *mem;
440 int ret; 494 int ret;
495 const struct of_device_id *match;
441 496
442 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); 497 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
443 if (!i2s) 498 if (!i2s)
444 return -ENOMEM; 499 return -ENOMEM;
445 500
501 match = of_match_device(jz4740_of_matches, &pdev->dev);
502 if (match)
503 i2s->version = (enum jz47xx_i2s_version)match->data;
504
446 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 505 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
447 i2s->base = devm_ioremap_resource(&pdev->dev, mem); 506 i2s->base = devm_ioremap_resource(&pdev->dev, mem);
448 if (IS_ERR(i2s->base)) 507 if (IS_ERR(i2s->base))
@@ -460,8 +519,13 @@ static int jz4740_i2s_dev_probe(struct platform_device *pdev)
460 519
461 platform_set_drvdata(pdev, i2s); 520 platform_set_drvdata(pdev, i2s);
462 521
463 ret = devm_snd_soc_register_component(&pdev->dev, 522 if (i2s->version == JZ_I2S_JZ4780)
464 &jz4740_i2s_component, &jz4740_i2s_dai, 1); 523 ret = devm_snd_soc_register_component(&pdev->dev,
524 &jz4740_i2s_component, &jz4780_i2s_dai, 1);
525 else
526 ret = devm_snd_soc_register_component(&pdev->dev,
527 &jz4740_i2s_component, &jz4740_i2s_dai, 1);
528
465 if (ret) 529 if (ret)
466 return ret; 530 return ret;
467 531
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index d19483081f9b..3a36d60e1785 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -643,7 +643,7 @@ static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
643} 643}
644 644
645#ifdef CONFIG_OF 645#ifdef CONFIG_OF
646static struct of_device_id mvebu_audio_of_match[] = { 646static const struct of_device_id mvebu_audio_of_match[] = {
647 { .compatible = "marvell,kirkwood-audio" }, 647 { .compatible = "marvell,kirkwood-audio" },
648 { .compatible = "marvell,dove-audio" }, 648 { .compatible = "marvell,dove-audio" },
649 { .compatible = "marvell,armada370-audio" }, 649 { .compatible = "marvell,armada370-audio" },
diff --git a/sound/soc/nuc900/nuc900-audio.h b/sound/soc/nuc900/nuc900-audio.h
index 59f7e8ed1a68..d0b725705914 100644
--- a/sound/soc/nuc900/nuc900-audio.h
+++ b/sound/soc/nuc900/nuc900-audio.h
@@ -100,10 +100,7 @@
100struct nuc900_audio { 100struct nuc900_audio {
101 void __iomem *mmio; 101 void __iomem *mmio;
102 spinlock_t lock; 102 spinlock_t lock;
103 dma_addr_t dma_addr[2];
104 unsigned long buffersize[2];
105 unsigned long irq_num; 103 unsigned long irq_num;
106 struct snd_pcm_substream *substream;
107 struct resource *res; 104 struct resource *res;
108 struct clk *clk; 105 struct clk *clk;
109 struct device *dev; 106 struct device *dev;
diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c
index b809fa909e4d..5ae5ca15b6d6 100644
--- a/sound/soc/nuc900/nuc900-pcm.c
+++ b/sound/soc/nuc900/nuc900-pcm.c
@@ -42,29 +42,10 @@ static const struct snd_pcm_hardware nuc900_pcm_hardware = {
42static int nuc900_dma_hw_params(struct snd_pcm_substream *substream, 42static int nuc900_dma_hw_params(struct snd_pcm_substream *substream,
43 struct snd_pcm_hw_params *params) 43 struct snd_pcm_hw_params *params)
44{ 44{
45 struct snd_pcm_runtime *runtime = substream->runtime; 45 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
46 struct nuc900_audio *nuc900_audio = runtime->private_data;
47 unsigned long flags;
48 int ret = 0;
49
50 ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
51 if (ret < 0)
52 return ret;
53
54 spin_lock_irqsave(&nuc900_audio->lock, flags);
55
56 nuc900_audio->substream = substream;
57 nuc900_audio->dma_addr[substream->stream] = runtime->dma_addr;
58 nuc900_audio->buffersize[substream->stream] =
59 params_buffer_bytes(params);
60
61 spin_unlock_irqrestore(&nuc900_audio->lock, flags);
62
63 return ret;
64} 46}
65 47
66static void nuc900_update_dma_register(struct snd_pcm_substream *substream, 48static void nuc900_update_dma_register(struct snd_pcm_substream *substream)
67 dma_addr_t dma_addr, size_t count)
68{ 49{
69 struct snd_pcm_runtime *runtime = substream->runtime; 50 struct snd_pcm_runtime *runtime = substream->runtime;
70 struct nuc900_audio *nuc900_audio = runtime->private_data; 51 struct nuc900_audio *nuc900_audio = runtime->private_data;
@@ -78,8 +59,8 @@ static void nuc900_update_dma_register(struct snd_pcm_substream *substream,
78 mmio_len = nuc900_audio->mmio + ACTL_RDST_LENGTH; 59 mmio_len = nuc900_audio->mmio + ACTL_RDST_LENGTH;
79 } 60 }
80 61
81 AUDIO_WRITE(mmio_addr, dma_addr); 62 AUDIO_WRITE(mmio_addr, runtime->dma_addr);
82 AUDIO_WRITE(mmio_len, count); 63 AUDIO_WRITE(mmio_len, runtime->dma_bytes);
83} 64}
84 65
85static void nuc900_dma_start(struct snd_pcm_substream *substream) 66static void nuc900_dma_start(struct snd_pcm_substream *substream)
@@ -170,9 +151,7 @@ static int nuc900_dma_prepare(struct snd_pcm_substream *substream)
170 151
171 spin_lock_irqsave(&nuc900_audio->lock, flags); 152 spin_lock_irqsave(&nuc900_audio->lock, flags);
172 153
173 nuc900_update_dma_register(substream, 154 nuc900_update_dma_register(substream);
174 nuc900_audio->dma_addr[substream->stream],
175 nuc900_audio->buffersize[substream->stream]);
176 155
177 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET); 156 val = AUDIO_READ(nuc900_audio->mmio + ACTL_RESET);
178 157
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index a2cd3486ac55..6768e4f7d7d0 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -100,17 +100,19 @@ config SND_OMAP_SOC_OMAP_TWL4030
100 100
101config SND_OMAP_SOC_OMAP_ABE_TWL6040 101config SND_OMAP_SOC_OMAP_ABE_TWL6040
102 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" 102 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
103 depends on TWL6040_CORE && SND_OMAP_SOC && (ARCH_OMAP4 || COMPILE_TEST) 103 depends on TWL6040_CORE && SND_OMAP_SOC && (ARCH_OMAP4 || SOC_OMAP5 || COMPILE_TEST)
104 select SND_OMAP_SOC_DMIC 104 select SND_OMAP_SOC_DMIC
105 select SND_OMAP_SOC_MCPDM 105 select SND_OMAP_SOC_MCPDM
106 select SND_SOC_TWL6040 106 select SND_SOC_TWL6040
107 select SND_SOC_DMIC 107 select SND_SOC_DMIC
108 select COMMON_CLK_PALMAS if MFD_PALMAS
108 help 109 help
109 Say Y if you want to add support for SoC audio on OMAP boards using 110 Say Y if you want to add support for SoC audio on OMAP boards using
110 ABE and twl6040 codec. This driver currently supports: 111 ABE and twl6040 codec. This driver currently supports:
111 - SDP4430/Blaze boards 112 - SDP4430/Blaze boards
112 - PandaBoard (4430) 113 - PandaBoard (4430)
113 - PandaBoardES (4460) 114 - PandaBoardES (4460)
115 - omap5-uevm (5432)
114 116
115config SND_OMAP_SOC_OMAP3_PANDORA 117config SND_OMAP_SOC_OMAP3_PANDORA
116 tristate "SoC Audio support for OMAP3 Pandora" 118 tristate "SoC Audio support for OMAP3 Pandora"
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 706613077c15..16cc95fa4573 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -479,8 +479,8 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
479 479
480 /* Add hook switch - can be used to control the codec from userspace 480 /* Add hook switch - can be used to control the codec from userspace
481 * even if line discipline fails */ 481 * even if line discipline fails */
482 ret = snd_soc_jack_new(rtd->codec, "hook_switch", 482 ret = snd_soc_card_jack_new(card, "hook_switch", SND_JACK_HEADSET,
483 SND_JACK_HEADSET, &ams_delta_hook_switch); 483 &ams_delta_hook_switch, NULL, 0);
484 if (ret) 484 if (ret)
485 dev_warn(card->dev, 485 dev_warn(card->dev,
486 "Failed to allocate resources for hook switch, " 486 "Failed to allocate resources for hook switch, "
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 5d7f9cebe041..dcb5336b5698 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -98,12 +98,11 @@ static int n810_startup(struct snd_pcm_substream *substream)
98{ 98{
99 struct snd_pcm_runtime *runtime = substream->runtime; 99 struct snd_pcm_runtime *runtime = substream->runtime;
100 struct snd_soc_pcm_runtime *rtd = substream->private_data; 100 struct snd_soc_pcm_runtime *rtd = substream->private_data;
101 struct snd_soc_codec *codec = rtd->codec;
102 101
103 snd_pcm_hw_constraint_minmax(runtime, 102 snd_pcm_hw_constraint_minmax(runtime,
104 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); 103 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
105 104
106 n810_ext_control(&codec->dapm); 105 n810_ext_control(&rtd->card->dapm);
107 return clk_prepare_enable(sys_clkout2); 106 return clk_prepare_enable(sys_clkout2);
108} 107}
109 108
@@ -255,24 +254,6 @@ static const struct snd_kcontrol_new aic33_n810_controls[] = {
255 n810_get_input, n810_set_input), 254 n810_get_input, n810_set_input),
256}; 255};
257 256
258static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd)
259{
260 struct snd_soc_codec *codec = rtd->codec;
261 struct snd_soc_dapm_context *dapm = &codec->dapm;
262
263 /* Not connected */
264 snd_soc_dapm_nc_pin(dapm, "MONO_LOUT");
265 snd_soc_dapm_nc_pin(dapm, "HPLCOM");
266 snd_soc_dapm_nc_pin(dapm, "HPRCOM");
267 snd_soc_dapm_nc_pin(dapm, "MIC3L");
268 snd_soc_dapm_nc_pin(dapm, "MIC3R");
269 snd_soc_dapm_nc_pin(dapm, "LINE1R");
270 snd_soc_dapm_nc_pin(dapm, "LINE2L");
271 snd_soc_dapm_nc_pin(dapm, "LINE2R");
272
273 return 0;
274}
275
276/* Digital audio interface glue - connects codec <--> CPU */ 257/* Digital audio interface glue - connects codec <--> CPU */
277static struct snd_soc_dai_link n810_dai = { 258static struct snd_soc_dai_link n810_dai = {
278 .name = "TLV320AIC33", 259 .name = "TLV320AIC33",
@@ -283,7 +264,6 @@ static struct snd_soc_dai_link n810_dai = {
283 .codec_dai_name = "tlv320aic3x-hifi", 264 .codec_dai_name = "tlv320aic3x-hifi",
284 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 265 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
285 SND_SOC_DAIFMT_CBM_CFM, 266 SND_SOC_DAIFMT_CBM_CFM,
286 .init = n810_aic33_init,
287 .ops = &n810_ops, 267 .ops = &n810_ops,
288}; 268};
289 269
@@ -300,6 +280,7 @@ static struct snd_soc_card snd_soc_n810 = {
300 .num_dapm_widgets = ARRAY_SIZE(aic33_dapm_widgets), 280 .num_dapm_widgets = ARRAY_SIZE(aic33_dapm_widgets),
301 .dapm_routes = audio_map, 281 .dapm_routes = audio_map,
302 .num_dapm_routes = ARRAY_SIZE(audio_map), 282 .num_dapm_routes = ARRAY_SIZE(audio_map),
283 .fully_routed = true,
303}; 284};
304 285
305static struct platform_device *n810_snd_device; 286static struct platform_device *n810_snd_device;
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
index b9c65f1ad5a8..0843a68f277c 100644
--- a/sound/soc/omap/omap-abe-twl6040.c
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -182,17 +182,17 @@ static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd)
182 182
183 /* Headset jack detection only if it is supported */ 183 /* Headset jack detection only if it is supported */
184 if (priv->jack_detection) { 184 if (priv->jack_detection) {
185 ret = snd_soc_jack_new(codec, "Headset Jack", 185 ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
186 SND_JACK_HEADSET, &hs_jack); 186 SND_JACK_HEADSET, &hs_jack,
187 hs_jack_pins,
188 ARRAY_SIZE(hs_jack_pins));
187 if (ret) 189 if (ret)
188 return ret; 190 return ret;
189 191
190 ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
191 hs_jack_pins);
192 twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); 192 twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
193 } 193 }
194 194
195 return ret; 195 return 0;
196} 196}
197 197
198static const struct snd_soc_dapm_route dmic_audio_map[] = { 198static const struct snd_soc_dapm_route dmic_audio_map[] = {
diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c
index f7eb42aa3f38..4775da4c4db5 100644
--- a/sound/soc/omap/omap-hdmi-audio.c
+++ b/sound/soc/omap/omap-hdmi-audio.c
@@ -142,8 +142,6 @@ static int hdmi_dai_hw_params(struct snd_pcm_substream *substream,
142 142
143 iec->status[0] |= IEC958_AES0_CON_EMPHASIS_NONE; 143 iec->status[0] |= IEC958_AES0_CON_EMPHASIS_NONE;
144 144
145 iec->status[0] |= IEC958_AES1_PRO_MODE_NOTID;
146
147 iec->status[1] = IEC958_AES1_CON_GENERAL; 145 iec->status[1] = IEC958_AES1_CON_GENERAL;
148 146
149 iec->status[2] |= IEC958_AES2_CON_SOURCE_UNSPEC; 147 iec->status[2] |= IEC958_AES2_CON_SOURCE_UNSPEC;
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 1343ecbf0bd5..6bb623a2a4df 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -39,7 +39,7 @@
39#define pcm_omap1510() 0 39#define pcm_omap1510() 0
40#endif 40#endif
41 41
42static const struct snd_pcm_hardware omap_pcm_hardware = { 42static struct snd_pcm_hardware omap_pcm_hardware = {
43 .info = SNDRV_PCM_INFO_MMAP | 43 .info = SNDRV_PCM_INFO_MMAP |
44 SNDRV_PCM_INFO_MMAP_VALID | 44 SNDRV_PCM_INFO_MMAP_VALID |
45 SNDRV_PCM_INFO_INTERLEAVED | 45 SNDRV_PCM_INFO_INTERLEAVED |
@@ -53,6 +53,24 @@ static const struct snd_pcm_hardware omap_pcm_hardware = {
53 .buffer_bytes_max = 128 * 1024, 53 .buffer_bytes_max = 128 * 1024,
54}; 54};
55 55
56/* sDMA supports only 1, 2, and 4 byte transfer elements. */
57static void omap_pcm_limit_supported_formats(void)
58{
59 int i;
60
61 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
62 switch (snd_pcm_format_physical_width(i)) {
63 case 8:
64 case 16:
65 case 32:
66 omap_pcm_hardware.formats |= (1LL << i);
67 break;
68 default:
69 break;
70 }
71 }
72}
73
56/* this may get called several times by oss emulation */ 74/* this may get called several times by oss emulation */
57static int omap_pcm_hw_params(struct snd_pcm_substream *substream, 75static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
58 struct snd_pcm_hw_params *params) 76 struct snd_pcm_hw_params *params)
@@ -235,6 +253,7 @@ static struct snd_soc_platform_driver omap_soc_platform = {
235 253
236int omap_pcm_platform_register(struct device *dev) 254int omap_pcm_platform_register(struct device *dev)
237{ 255{
256 omap_pcm_limit_supported_formats();
238 return devm_snd_soc_register_platform(dev, &omap_soc_platform); 257 return devm_snd_soc_register_platform(dev, &omap_soc_platform);
239} 258}
240EXPORT_SYMBOL_GPL(omap_pcm_platform_register); 259EXPORT_SYMBOL_GPL(omap_pcm_platform_register);
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c
index fb1f6bb87cd4..3673ada43bfb 100644
--- a/sound/soc/omap/omap-twl4030.c
+++ b/sound/soc/omap/omap-twl4030.c
@@ -170,14 +170,10 @@ static int omap_twl4030_init(struct snd_soc_pcm_runtime *rtd)
170 if (priv->jack_detect > 0) { 170 if (priv->jack_detect > 0) {
171 hs_jack_gpios[0].gpio = priv->jack_detect; 171 hs_jack_gpios[0].gpio = priv->jack_detect;
172 172
173 ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, 173 ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
174 &priv->hs_jack); 174 SND_JACK_HEADSET, &priv->hs_jack,
175 if (ret) 175 hs_jack_pins,
176 return ret; 176 ARRAY_SIZE(hs_jack_pins));
177
178 ret = snd_soc_jack_add_pins(&priv->hs_jack,
179 ARRAY_SIZE(hs_jack_pins),
180 hs_jack_pins);
181 if (ret) 177 if (ret)
182 return ret; 178 return ret;
183 179
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 7f299357c2d2..c2ddf0fbfa28 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -311,9 +311,9 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
311 } 311 }
312 312
313 /* AV jack detection */ 313 /* AV jack detection */
314 err = snd_soc_jack_new(codec, "AV Jack", 314 err = snd_soc_card_jack_new(rtd->card, "AV Jack",
315 SND_JACK_HEADSET | SND_JACK_VIDEOOUT, 315 SND_JACK_HEADSET | SND_JACK_VIDEOOUT,
316 &rx51_av_jack); 316 &rx51_av_jack, NULL, 0);
317 if (err) { 317 if (err) {
318 dev_err(card->dev, "Failed to add AV Jack\n"); 318 dev_err(card->dev, "Failed to add AV Jack\n");
319 return err; 319 return err;
diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c
index 73eb5ddf9753..9f8be7cd567e 100644
--- a/sound/soc/pxa/hx4700.c
+++ b/sound/soc/pxa/hx4700.c
@@ -126,17 +126,12 @@ static const struct snd_soc_dapm_route hx4700_audio_map[] = {
126 */ 126 */
127static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd) 127static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd)
128{ 128{
129 struct snd_soc_codec *codec = rtd->codec;
130 int err; 129 int err;
131 130
132 /* Jack detection API stuff */ 131 /* Jack detection API stuff */
133 err = snd_soc_jack_new(codec, "Headphone Jack", 132 err = snd_soc_card_jack_new(rtd->card, "Headphone Jack",
134 SND_JACK_HEADPHONE, &hs_jack); 133 SND_JACK_HEADPHONE, &hs_jack, hs_jack_pin,
135 if (err) 134 ARRAY_SIZE(hs_jack_pin));
136 return err;
137
138 err = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pin),
139 hs_jack_pin);
140 if (err) 135 if (err)
141 return err; 136 return err;
142 137
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index 910336c5ebeb..c20bbc042425 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -75,17 +75,12 @@ static struct snd_soc_card palm27x_asoc;
75 75
76static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd) 76static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd)
77{ 77{
78 struct snd_soc_codec *codec = rtd->codec;
79 int err; 78 int err;
80 79
81 /* Jack detection API stuff */ 80 /* Jack detection API stuff */
82 err = snd_soc_jack_new(codec, "Headphone Jack", 81 err = snd_soc_card_jack_new(rtd->card, "Headphone Jack",
83 SND_JACK_HEADPHONE, &hs_jack); 82 SND_JACK_HEADPHONE, &hs_jack, hs_jack_pins,
84 if (err) 83 ARRAY_SIZE(hs_jack_pins));
85 return err;
86
87 err = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
88 hs_jack_pins);
89 if (err) 84 if (err)
90 return err; 85 return err;
91 86
diff --git a/sound/soc/pxa/ttc-dkb.c b/sound/soc/pxa/ttc-dkb.c
index 5001dbb9b257..1753c7d9e760 100644
--- a/sound/soc/pxa/ttc-dkb.c
+++ b/sound/soc/pxa/ttc-dkb.c
@@ -78,15 +78,12 @@ static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd)
78 struct snd_soc_codec *codec = rtd->codec; 78 struct snd_soc_codec *codec = rtd->codec;
79 79
80 /* Headset jack detection */ 80 /* Headset jack detection */
81 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE 81 snd_soc_card_jack_new(rtd->card, "Headphone Jack", SND_JACK_HEADPHONE |
82 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2, 82 SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2,
83 &hs_jack); 83 &hs_jack, hs_jack_pins, ARRAY_SIZE(hs_jack_pins));
84 snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), 84 snd_soc_card_jack_new(rtd->card, "Microphone Jack", SND_JACK_MICROPHONE,
85 hs_jack_pins); 85 &mic_jack, mic_jack_pins,
86 snd_soc_jack_new(codec, "Microphone Jack", SND_JACK_MICROPHONE, 86 ARRAY_SIZE(mic_jack_pins));
87 &mic_jack);
88 snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
89 mic_jack_pins);
90 87
91 /* headphone, microphone detection & headset short detection */ 88 /* headphone, microphone detection & headset short detection */
92 pm860x_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADPHONE, 89 pm860x_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADPHONE,
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
index 76ccb172d0a7..bcbfbe8303f7 100644
--- a/sound/soc/pxa/z2.c
+++ b/sound/soc/pxa/z2.c
@@ -143,13 +143,9 @@ static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd)
143 snd_soc_dapm_disable_pin(dapm, "MONO1"); 143 snd_soc_dapm_disable_pin(dapm, "MONO1");
144 144
145 /* Jack detection API stuff */ 145 /* Jack detection API stuff */
146 ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, 146 ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", SND_JACK_HEADSET,
147 &hs_jack); 147 &hs_jack, hs_jack_pins,
148 if (ret) 148 ARRAY_SIZE(hs_jack_pins));
149 goto err;
150
151 ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
152 hs_jack_pins);
153 if (ret) 149 if (ret)
154 goto err; 150 goto err;
155 151
diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
new file mode 100644
index 000000000000..5f58e4f1bca9
--- /dev/null
+++ b/sound/soc/qcom/Kconfig
@@ -0,0 +1,25 @@
1config SND_SOC_QCOM
2 tristate "ASoC support for QCOM platforms"
3 help
4 Say Y or M if you want to add support to use audio devices
5 in Qualcomm Technologies SOC-based platforms.
6
7config SND_SOC_LPASS_CPU
8 tristate
9 depends on SND_SOC_QCOM
10 select REGMAP_MMIO
11
12config SND_SOC_LPASS_PLATFORM
13 tristate
14 depends on SND_SOC_QCOM
15 select REGMAP_MMIO
16
17config SND_SOC_STORM
18 tristate "ASoC I2S support for Storm boards"
19 depends on (ARCH_QCOM && SND_SOC_QCOM) || COMPILE_TEST
20 select SND_SOC_LPASS_CPU
21 select SND_SOC_LPASS_PLATFORM
22 select SND_SOC_MAX98357A
23 help
24 Say Y or M if you want add support for SoC audio on the
25 Qualcomm Technologies IPQ806X-based Storm board.
diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile
new file mode 100644
index 000000000000..c5ce96c761c4
--- /dev/null
+++ b/sound/soc/qcom/Makefile
@@ -0,0 +1,11 @@
1# Platform
2snd-soc-lpass-cpu-objs := lpass-cpu.o
3snd-soc-lpass-platform-objs := lpass-platform.o
4
5obj-$(CONFIG_SND_SOC_LPASS_CPU) += snd-soc-lpass-cpu.o
6obj-$(CONFIG_SND_SOC_LPASS_PLATFORM) += snd-soc-lpass-platform.o
7
8# Machine
9snd-soc-storm-objs := storm.o
10
11obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
new file mode 100644
index 000000000000..6698d058de29
--- /dev/null
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -0,0 +1,491 @@
1/*
2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * lpass-cpu.c -- ALSA SoC CPU DAI driver for QTi LPASS
14 */
15
16#include <linux/clk.h>
17#include <linux/compiler.h>
18#include <linux/device.h>
19#include <linux/err.h>
20#include <linux/ioport.h>
21#include <linux/kernel.h>
22#include <linux/mod_devicetable.h>
23#include <linux/module.h>
24#include <linux/of.h>
25#include <linux/platform_device.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <linux/regmap.h>
29#include <sound/soc.h>
30#include <sound/soc-dai.h>
31#include "lpass-lpaif-ipq806x.h"
32#include "lpass.h"
33
34static int lpass_cpu_daiops_set_sysclk(struct snd_soc_dai *dai, int clk_id,
35 unsigned int freq, int dir)
36{
37 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
38 int ret;
39
40 ret = clk_set_rate(drvdata->mi2s_osr_clk, freq);
41 if (ret)
42 dev_err(dai->dev, "%s() error setting mi2s osrclk to %u: %d\n",
43 __func__, freq, ret);
44
45 return ret;
46}
47
48static int lpass_cpu_daiops_startup(struct snd_pcm_substream *substream,
49 struct snd_soc_dai *dai)
50{
51 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
52 int ret;
53
54 ret = clk_prepare_enable(drvdata->mi2s_osr_clk);
55 if (ret) {
56 dev_err(dai->dev, "%s() error in enabling mi2s osr clk: %d\n",
57 __func__, ret);
58 return ret;
59 }
60
61 ret = clk_prepare_enable(drvdata->mi2s_bit_clk);
62 if (ret) {
63 dev_err(dai->dev, "%s() error in enabling mi2s bit clk: %d\n",
64 __func__, ret);
65 clk_disable_unprepare(drvdata->mi2s_osr_clk);
66 return ret;
67 }
68
69 return 0;
70}
71
72static void lpass_cpu_daiops_shutdown(struct snd_pcm_substream *substream,
73 struct snd_soc_dai *dai)
74{
75 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
76
77 clk_disable_unprepare(drvdata->mi2s_bit_clk);
78 clk_disable_unprepare(drvdata->mi2s_osr_clk);
79}
80
81static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
82 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
83{
84 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
85 snd_pcm_format_t format = params_format(params);
86 unsigned int channels = params_channels(params);
87 unsigned int rate = params_rate(params);
88 unsigned int regval;
89 int bitwidth, ret;
90
91 bitwidth = snd_pcm_format_width(format);
92 if (bitwidth < 0) {
93 dev_err(dai->dev, "%s() invalid bit width given: %d\n",
94 __func__, bitwidth);
95 return bitwidth;
96 }
97
98 regval = LPAIF_I2SCTL_LOOPBACK_DISABLE |
99 LPAIF_I2SCTL_WSSRC_INTERNAL;
100
101 switch (bitwidth) {
102 case 16:
103 regval |= LPAIF_I2SCTL_BITWIDTH_16;
104 break;
105 case 24:
106 regval |= LPAIF_I2SCTL_BITWIDTH_24;
107 break;
108 case 32:
109 regval |= LPAIF_I2SCTL_BITWIDTH_32;
110 break;
111 default:
112 dev_err(dai->dev, "%s() invalid bitwidth given: %d\n",
113 __func__, bitwidth);
114 return -EINVAL;
115 }
116
117 switch (channels) {
118 case 1:
119 regval |= LPAIF_I2SCTL_SPKMODE_SD0;
120 regval |= LPAIF_I2SCTL_SPKMONO_MONO;
121 break;
122 case 2:
123 regval |= LPAIF_I2SCTL_SPKMODE_SD0;
124 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
125 break;
126 case 4:
127 regval |= LPAIF_I2SCTL_SPKMODE_QUAD01;
128 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
129 break;
130 case 6:
131 regval |= LPAIF_I2SCTL_SPKMODE_6CH;
132 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
133 break;
134 case 8:
135 regval |= LPAIF_I2SCTL_SPKMODE_8CH;
136 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
137 break;
138 default:
139 dev_err(dai->dev, "%s() invalid channels given: %u\n",
140 __func__, channels);
141 return -EINVAL;
142 }
143
144 ret = regmap_write(drvdata->lpaif_map,
145 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S), regval);
146 if (ret) {
147 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
148 __func__, ret);
149 return ret;
150 }
151
152 ret = clk_set_rate(drvdata->mi2s_bit_clk, rate * bitwidth * 2);
153 if (ret) {
154 dev_err(dai->dev, "%s() error setting mi2s bitclk to %u: %d\n",
155 __func__, rate * bitwidth * 2, ret);
156 return ret;
157 }
158
159 return 0;
160}
161
162static int lpass_cpu_daiops_hw_free(struct snd_pcm_substream *substream,
163 struct snd_soc_dai *dai)
164{
165 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
166 int ret;
167
168 ret = regmap_write(drvdata->lpaif_map,
169 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S), 0);
170 if (ret)
171 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
172 __func__, ret);
173
174 return ret;
175}
176
177static int lpass_cpu_daiops_prepare(struct snd_pcm_substream *substream,
178 struct snd_soc_dai *dai)
179{
180 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
181 int ret;
182
183 ret = regmap_update_bits(drvdata->lpaif_map,
184 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S),
185 LPAIF_I2SCTL_SPKEN_MASK, LPAIF_I2SCTL_SPKEN_ENABLE);
186 if (ret)
187 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
188 __func__, ret);
189
190 return ret;
191}
192
193static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
194 int cmd, struct snd_soc_dai *dai)
195{
196 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
197 int ret;
198
199 switch (cmd) {
200 case SNDRV_PCM_TRIGGER_START:
201 case SNDRV_PCM_TRIGGER_RESUME:
202 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
203 ret = regmap_update_bits(drvdata->lpaif_map,
204 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S),
205 LPAIF_I2SCTL_SPKEN_MASK,
206 LPAIF_I2SCTL_SPKEN_ENABLE);
207 if (ret)
208 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
209 __func__, ret);
210 break;
211 case SNDRV_PCM_TRIGGER_STOP:
212 case SNDRV_PCM_TRIGGER_SUSPEND:
213 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
214 ret = regmap_update_bits(drvdata->lpaif_map,
215 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S),
216 LPAIF_I2SCTL_SPKEN_MASK,
217 LPAIF_I2SCTL_SPKEN_DISABLE);
218 if (ret)
219 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
220 __func__, ret);
221 break;
222 }
223
224 return ret;
225}
226
227static struct snd_soc_dai_ops lpass_cpu_dai_ops = {
228 .set_sysclk = lpass_cpu_daiops_set_sysclk,
229 .startup = lpass_cpu_daiops_startup,
230 .shutdown = lpass_cpu_daiops_shutdown,
231 .hw_params = lpass_cpu_daiops_hw_params,
232 .hw_free = lpass_cpu_daiops_hw_free,
233 .prepare = lpass_cpu_daiops_prepare,
234 .trigger = lpass_cpu_daiops_trigger,
235};
236
237static int lpass_cpu_dai_probe(struct snd_soc_dai *dai)
238{
239 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
240 int ret;
241
242 /* ensure audio hardware is disabled */
243 ret = regmap_write(drvdata->lpaif_map,
244 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S), 0);
245 if (ret)
246 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
247 __func__, ret);
248
249 return ret;
250}
251
252static struct snd_soc_dai_driver lpass_cpu_dai_driver = {
253 .playback = {
254 .stream_name = "lpass-cpu-playback",
255 .formats = SNDRV_PCM_FMTBIT_S16 |
256 SNDRV_PCM_FMTBIT_S24 |
257 SNDRV_PCM_FMTBIT_S32,
258 .rates = SNDRV_PCM_RATE_8000 |
259 SNDRV_PCM_RATE_16000 |
260 SNDRV_PCM_RATE_32000 |
261 SNDRV_PCM_RATE_48000 |
262 SNDRV_PCM_RATE_96000,
263 .rate_min = 8000,
264 .rate_max = 96000,
265 .channels_min = 1,
266 .channels_max = 8,
267 },
268 .probe = &lpass_cpu_dai_probe,
269 .ops = &lpass_cpu_dai_ops,
270};
271
272static const struct snd_soc_component_driver lpass_cpu_comp_driver = {
273 .name = "lpass-cpu",
274};
275
276static bool lpass_cpu_regmap_writeable(struct device *dev, unsigned int reg)
277{
278 int i;
279
280 for (i = 0; i < LPAIF_I2S_PORT_NUM; ++i)
281 if (reg == LPAIF_I2SCTL_REG(i))
282 return true;
283
284 for (i = 0; i < LPAIF_IRQ_PORT_NUM; ++i) {
285 if (reg == LPAIF_IRQEN_REG(i))
286 return true;
287 if (reg == LPAIF_IRQCLEAR_REG(i))
288 return true;
289 }
290
291 for (i = 0; i < LPAIF_RDMA_CHAN_NUM; ++i) {
292 if (reg == LPAIF_RDMACTL_REG(i))
293 return true;
294 if (reg == LPAIF_RDMABASE_REG(i))
295 return true;
296 if (reg == LPAIF_RDMABUFF_REG(i))
297 return true;
298 if (reg == LPAIF_RDMAPER_REG(i))
299 return true;
300 }
301
302 return false;
303}
304
305static bool lpass_cpu_regmap_readable(struct device *dev, unsigned int reg)
306{
307 int i;
308
309 for (i = 0; i < LPAIF_I2S_PORT_NUM; ++i)
310 if (reg == LPAIF_I2SCTL_REG(i))
311 return true;
312
313 for (i = 0; i < LPAIF_IRQ_PORT_NUM; ++i) {
314 if (reg == LPAIF_IRQEN_REG(i))
315 return true;
316 if (reg == LPAIF_IRQSTAT_REG(i))
317 return true;
318 }
319
320 for (i = 0; i < LPAIF_RDMA_CHAN_NUM; ++i) {
321 if (reg == LPAIF_RDMACTL_REG(i))
322 return true;
323 if (reg == LPAIF_RDMABASE_REG(i))
324 return true;
325 if (reg == LPAIF_RDMABUFF_REG(i))
326 return true;
327 if (reg == LPAIF_RDMACURR_REG(i))
328 return true;
329 if (reg == LPAIF_RDMAPER_REG(i))
330 return true;
331 }
332
333 return false;
334}
335
336static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg)
337{
338 int i;
339
340 for (i = 0; i < LPAIF_IRQ_PORT_NUM; ++i)
341 if (reg == LPAIF_IRQSTAT_REG(i))
342 return true;
343
344 for (i = 0; i < LPAIF_RDMA_CHAN_NUM; ++i)
345 if (reg == LPAIF_RDMACURR_REG(i))
346 return true;
347
348 return false;
349}
350
351static const struct regmap_config lpass_cpu_regmap_config = {
352 .reg_bits = 32,
353 .reg_stride = 4,
354 .val_bits = 32,
355 .max_register = LPAIF_RDMAPER_REG(LPAIF_RDMA_CHAN_MAX),
356 .writeable_reg = lpass_cpu_regmap_writeable,
357 .readable_reg = lpass_cpu_regmap_readable,
358 .volatile_reg = lpass_cpu_regmap_volatile,
359 .cache_type = REGCACHE_FLAT,
360};
361
362static int lpass_cpu_platform_probe(struct platform_device *pdev)
363{
364 struct lpass_data *drvdata;
365 struct device_node *dsp_of_node;
366 struct resource *res;
367 int ret;
368
369 dsp_of_node = of_parse_phandle(pdev->dev.of_node, "qcom,adsp", 0);
370 if (dsp_of_node) {
371 dev_err(&pdev->dev, "%s() DSP exists and holds audio resources\n",
372 __func__);
373 return -EBUSY;
374 }
375
376 drvdata = devm_kzalloc(&pdev->dev, sizeof(struct lpass_data),
377 GFP_KERNEL);
378 if (!drvdata)
379 return -ENOMEM;
380 platform_set_drvdata(pdev, drvdata);
381
382 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-lpaif");
383 if (!res) {
384 dev_err(&pdev->dev, "%s() error getting resource\n", __func__);
385 return -ENODEV;
386 }
387
388 drvdata->lpaif = devm_ioremap_resource(&pdev->dev, res);
389 if (IS_ERR((void const __force *)drvdata->lpaif)) {
390 dev_err(&pdev->dev, "%s() error mapping reg resource: %ld\n",
391 __func__,
392 PTR_ERR((void const __force *)drvdata->lpaif));
393 return PTR_ERR((void const __force *)drvdata->lpaif);
394 }
395
396 drvdata->lpaif_map = devm_regmap_init_mmio(&pdev->dev, drvdata->lpaif,
397 &lpass_cpu_regmap_config);
398 if (IS_ERR(drvdata->lpaif_map)) {
399 dev_err(&pdev->dev, "%s() error initializing regmap: %ld\n",
400 __func__, PTR_ERR(drvdata->lpaif_map));
401 return PTR_ERR(drvdata->lpaif_map);
402 }
403
404 drvdata->mi2s_osr_clk = devm_clk_get(&pdev->dev, "mi2s-osr-clk");
405 if (IS_ERR(drvdata->mi2s_osr_clk)) {
406 dev_err(&pdev->dev, "%s() error getting mi2s-osr-clk: %ld\n",
407 __func__, PTR_ERR(drvdata->mi2s_osr_clk));
408 return PTR_ERR(drvdata->mi2s_osr_clk);
409 }
410
411 drvdata->mi2s_bit_clk = devm_clk_get(&pdev->dev, "mi2s-bit-clk");
412 if (IS_ERR(drvdata->mi2s_bit_clk)) {
413 dev_err(&pdev->dev, "%s() error getting mi2s-bit-clk: %ld\n",
414 __func__, PTR_ERR(drvdata->mi2s_bit_clk));
415 return PTR_ERR(drvdata->mi2s_bit_clk);
416 }
417
418 drvdata->ahbix_clk = devm_clk_get(&pdev->dev, "ahbix-clk");
419 if (IS_ERR(drvdata->ahbix_clk)) {
420 dev_err(&pdev->dev, "%s() error getting ahbix-clk: %ld\n",
421 __func__, PTR_ERR(drvdata->ahbix_clk));
422 return PTR_ERR(drvdata->ahbix_clk);
423 }
424
425 ret = clk_set_rate(drvdata->ahbix_clk, LPASS_AHBIX_CLOCK_FREQUENCY);
426 if (ret) {
427 dev_err(&pdev->dev, "%s() error setting rate on ahbix_clk: %d\n",
428 __func__, ret);
429 return ret;
430 }
431 dev_dbg(&pdev->dev, "%s() set ahbix_clk rate to %lu\n", __func__,
432 clk_get_rate(drvdata->ahbix_clk));
433
434 ret = clk_prepare_enable(drvdata->ahbix_clk);
435 if (ret) {
436 dev_err(&pdev->dev, "%s() error enabling ahbix_clk: %d\n",
437 __func__, ret);
438 return ret;
439 }
440
441 ret = devm_snd_soc_register_component(&pdev->dev,
442 &lpass_cpu_comp_driver, &lpass_cpu_dai_driver, 1);
443 if (ret) {
444 dev_err(&pdev->dev, "%s() error registering cpu driver: %d\n",
445 __func__, ret);
446 goto err_clk;
447 }
448
449 ret = asoc_qcom_lpass_platform_register(pdev);
450 if (ret) {
451 dev_err(&pdev->dev, "%s() error registering platform driver: %d\n",
452 __func__, ret);
453 goto err_clk;
454 }
455
456 return 0;
457
458err_clk:
459 clk_disable_unprepare(drvdata->ahbix_clk);
460 return ret;
461}
462
463static int lpass_cpu_platform_remove(struct platform_device *pdev)
464{
465 struct lpass_data *drvdata = platform_get_drvdata(pdev);
466
467 clk_disable_unprepare(drvdata->ahbix_clk);
468
469 return 0;
470}
471
472#ifdef CONFIG_OF
473static const struct of_device_id lpass_cpu_device_id[] = {
474 { .compatible = "qcom,lpass-cpu" },
475 {}
476};
477MODULE_DEVICE_TABLE(of, lpass_cpu_device_id);
478#endif
479
480static struct platform_driver lpass_cpu_platform_driver = {
481 .driver = {
482 .name = "lpass-cpu",
483 .of_match_table = of_match_ptr(lpass_cpu_device_id),
484 },
485 .probe = lpass_cpu_platform_probe,
486 .remove = lpass_cpu_platform_remove,
487};
488module_platform_driver(lpass_cpu_platform_driver);
489
490MODULE_DESCRIPTION("QTi LPASS CPU Driver");
491MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/lpass-lpaif-ipq806x.h b/sound/soc/qcom/lpass-lpaif-ipq806x.h
new file mode 100644
index 000000000000..dc423b888842
--- /dev/null
+++ b/sound/soc/qcom/lpass-lpaif-ipq806x.h
@@ -0,0 +1,172 @@
1/*
2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * lpass-lpaif-ipq806x.h -- Definitions for the QTi LPAIF in the ipq806x LPASS
14 */
15
16#ifndef __LPASS_LPAIF_H__
17#define __LPASS_LPAIF_H__
18
19#define LPAIF_BANK_OFFSET 0x1000
20
21/* LPAIF I2S */
22
23#define LPAIF_I2SCTL_REG_BASE 0x0010
24#define LPAIF_I2SCTL_REG_STRIDE 0x4
25#define LPAIF_I2SCTL_REG_ADDR(addr, port) \
26 (LPAIF_I2SCTL_REG_BASE + (addr) + (LPAIF_I2SCTL_REG_STRIDE * (port)))
27
28enum lpaif_i2s_ports {
29 LPAIF_I2S_PORT_MIN = 0,
30
31 LPAIF_I2S_PORT_CODEC_SPK = 0,
32 LPAIF_I2S_PORT_CODEC_MIC = 1,
33 LPAIF_I2S_PORT_SEC_SPK = 2,
34 LPAIF_I2S_PORT_SEC_MIC = 3,
35 LPAIF_I2S_PORT_MI2S = 4,
36
37 LPAIF_I2S_PORT_MAX = 4,
38 LPAIF_I2S_PORT_NUM = 5,
39};
40
41#define LPAIF_I2SCTL_REG(port) LPAIF_I2SCTL_REG_ADDR(0x0, (port))
42
43#define LPAIF_I2SCTL_LOOPBACK_MASK 0x8000
44#define LPAIF_I2SCTL_LOOPBACK_SHIFT 15
45#define LPAIF_I2SCTL_LOOPBACK_DISABLE (0 << LPAIF_I2SCTL_LOOPBACK_SHIFT)
46#define LPAIF_I2SCTL_LOOPBACK_ENABLE (1 << LPAIF_I2SCTL_LOOPBACK_SHIFT)
47
48#define LPAIF_I2SCTL_SPKEN_MASK 0x4000
49#define LPAIF_I2SCTL_SPKEN_SHIFT 14
50#define LPAIF_I2SCTL_SPKEN_DISABLE (0 << LPAIF_I2SCTL_SPKEN_SHIFT)
51#define LPAIF_I2SCTL_SPKEN_ENABLE (1 << LPAIF_I2SCTL_SPKEN_SHIFT)
52
53#define LPAIF_I2SCTL_SPKMODE_MASK 0x3C00
54#define LPAIF_I2SCTL_SPKMODE_SHIFT 10
55#define LPAIF_I2SCTL_SPKMODE_NONE (0 << LPAIF_I2SCTL_SPKMODE_SHIFT)
56#define LPAIF_I2SCTL_SPKMODE_SD0 (1 << LPAIF_I2SCTL_SPKMODE_SHIFT)
57#define LPAIF_I2SCTL_SPKMODE_SD1 (2 << LPAIF_I2SCTL_SPKMODE_SHIFT)
58#define LPAIF_I2SCTL_SPKMODE_SD2 (3 << LPAIF_I2SCTL_SPKMODE_SHIFT)
59#define LPAIF_I2SCTL_SPKMODE_SD3 (4 << LPAIF_I2SCTL_SPKMODE_SHIFT)
60#define LPAIF_I2SCTL_SPKMODE_QUAD01 (5 << LPAIF_I2SCTL_SPKMODE_SHIFT)
61#define LPAIF_I2SCTL_SPKMODE_QUAD23 (6 << LPAIF_I2SCTL_SPKMODE_SHIFT)
62#define LPAIF_I2SCTL_SPKMODE_6CH (7 << LPAIF_I2SCTL_SPKMODE_SHIFT)
63#define LPAIF_I2SCTL_SPKMODE_8CH (8 << LPAIF_I2SCTL_SPKMODE_SHIFT)
64
65#define LPAIF_I2SCTL_SPKMONO_MASK 0x0200
66#define LPAIF_I2SCTL_SPKMONO_SHIFT 9
67#define LPAIF_I2SCTL_SPKMONO_STEREO (0 << LPAIF_I2SCTL_SPKMONO_SHIFT)
68#define LPAIF_I2SCTL_SPKMONO_MONO (1 << LPAIF_I2SCTL_SPKMONO_SHIFT)
69
70#define LPAIF_I2SCTL_WSSRC_MASK 0x0004
71#define LPAIF_I2SCTL_WSSRC_SHIFT 2
72#define LPAIF_I2SCTL_WSSRC_INTERNAL (0 << LPAIF_I2SCTL_WSSRC_SHIFT)
73#define LPAIF_I2SCTL_WSSRC_EXTERNAL (1 << LPAIF_I2SCTL_WSSRC_SHIFT)
74
75#define LPAIF_I2SCTL_BITWIDTH_MASK 0x0003
76#define LPAIF_I2SCTL_BITWIDTH_SHIFT 0
77#define LPAIF_I2SCTL_BITWIDTH_16 (0 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
78#define LPAIF_I2SCTL_BITWIDTH_24 (1 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
79#define LPAIF_I2SCTL_BITWIDTH_32 (2 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
80
81/* LPAIF IRQ */
82
83#define LPAIF_IRQ_REG_BASE 0x3000
84#define LPAIF_IRQ_REG_STRIDE 0x1000
85#define LPAIF_IRQ_REG_ADDR(addr, port) \
86 (LPAIF_IRQ_REG_BASE + (addr) + (LPAIF_IRQ_REG_STRIDE * (port)))
87
88enum lpaif_irq_ports {
89 LPAIF_IRQ_PORT_MIN = 0,
90
91 LPAIF_IRQ_PORT_HOST = 0,
92 LPAIF_IRQ_PORT_ADSP = 1,
93
94 LPAIF_IRQ_PORT_MAX = 2,
95 LPAIF_IRQ_PORT_NUM = 3,
96};
97
98#define LPAIF_IRQEN_REG(port) LPAIF_IRQ_REG_ADDR(0x0, (port))
99#define LPAIF_IRQSTAT_REG(port) LPAIF_IRQ_REG_ADDR(0x4, (port))
100#define LPAIF_IRQCLEAR_REG(port) LPAIF_IRQ_REG_ADDR(0xC, (port))
101
102#define LPAIF_IRQ_BITSTRIDE 3
103#define LPAIF_IRQ_PER(chan) (1 << (LPAIF_IRQ_BITSTRIDE * (chan)))
104#define LPAIF_IRQ_XRUN(chan) (2 << (LPAIF_IRQ_BITSTRIDE * (chan)))
105#define LPAIF_IRQ_ERR(chan) (4 << (LPAIF_IRQ_BITSTRIDE * (chan)))
106#define LPAIF_IRQ_ALL(chan) (7 << (LPAIF_IRQ_BITSTRIDE * (chan)))
107
108/* LPAIF DMA */
109
110#define LPAIF_RDMA_REG_BASE 0x6000
111#define LPAIF_RDMA_REG_STRIDE 0x1000
112#define LPAIF_RDMA_REG_ADDR(addr, chan) \
113 (LPAIF_RDMA_REG_BASE + (addr) + (LPAIF_RDMA_REG_STRIDE * (chan)))
114
115enum lpaif_dma_channels {
116 LPAIF_RDMA_CHAN_MIN = 0,
117
118 LPAIF_RDMA_CHAN_MI2S = 0,
119 LPAIF_RDMA_CHAN_PCM0 = 1,
120 LPAIF_RDMA_CHAN_PCM1 = 2,
121
122 LPAIF_RDMA_CHAN_MAX = 4,
123 LPAIF_RDMA_CHAN_NUM = 5,
124};
125
126#define LPAIF_RDMACTL_REG(chan) LPAIF_RDMA_REG_ADDR(0x00, (chan))
127#define LPAIF_RDMABASE_REG(chan) LPAIF_RDMA_REG_ADDR(0x04, (chan))
128#define LPAIF_RDMABUFF_REG(chan) LPAIF_RDMA_REG_ADDR(0x08, (chan))
129#define LPAIF_RDMACURR_REG(chan) LPAIF_RDMA_REG_ADDR(0x0C, (chan))
130#define LPAIF_RDMAPER_REG(chan) LPAIF_RDMA_REG_ADDR(0x10, (chan))
131
132#define LPAIF_RDMACTL_BURSTEN_MASK 0x800
133#define LPAIF_RDMACTL_BURSTEN_SHIFT 11
134#define LPAIF_RDMACTL_BURSTEN_SINGLE (0 << LPAIF_RDMACTL_BURSTEN_SHIFT)
135#define LPAIF_RDMACTL_BURSTEN_INCR4 (1 << LPAIF_RDMACTL_BURSTEN_SHIFT)
136
137#define LPAIF_RDMACTL_WPSCNT_MASK 0x700
138#define LPAIF_RDMACTL_WPSCNT_SHIFT 8
139#define LPAIF_RDMACTL_WPSCNT_ONE (0 << LPAIF_RDMACTL_WPSCNT_SHIFT)
140#define LPAIF_RDMACTL_WPSCNT_TWO (1 << LPAIF_RDMACTL_WPSCNT_SHIFT)
141#define LPAIF_RDMACTL_WPSCNT_THREE (2 << LPAIF_RDMACTL_WPSCNT_SHIFT)
142#define LPAIF_RDMACTL_WPSCNT_FOUR (3 << LPAIF_RDMACTL_WPSCNT_SHIFT)
143#define LPAIF_RDMACTL_WPSCNT_SIX (5 << LPAIF_RDMACTL_WPSCNT_SHIFT)
144#define LPAIF_RDMACTL_WPSCNT_EIGHT (7 << LPAIF_RDMACTL_WPSCNT_SHIFT)
145
146#define LPAIF_RDMACTL_AUDINTF_MASK 0x0F0
147#define LPAIF_RDMACTL_AUDINTF_SHIFT 4
148#define LPAIF_RDMACTL_AUDINTF_NONE (0 << LPAIF_RDMACTL_AUDINTF_SHIFT)
149#define LPAIF_RDMACTL_AUDINTF_CODEC (1 << LPAIF_RDMACTL_AUDINTF_SHIFT)
150#define LPAIF_RDMACTL_AUDINTF_PCM (2 << LPAIF_RDMACTL_AUDINTF_SHIFT)
151#define LPAIF_RDMACTL_AUDINTF_SEC_I2S (3 << LPAIF_RDMACTL_AUDINTF_SHIFT)
152#define LPAIF_RDMACTL_AUDINTF_MI2S (4 << LPAIF_RDMACTL_AUDINTF_SHIFT)
153#define LPAIF_RDMACTL_AUDINTF_HDMI (5 << LPAIF_RDMACTL_AUDINTF_SHIFT)
154#define LPAIF_RDMACTL_AUDINTF_SEC_PCM (7 << LPAIF_RDMACTL_AUDINTF_SHIFT)
155
156#define LPAIF_RDMACTL_FIFOWM_MASK 0x00E
157#define LPAIF_RDMACTL_FIFOWM_SHIFT 1
158#define LPAIF_RDMACTL_FIFOWM_1 (0 << LPAIF_RDMACTL_FIFOWM_SHIFT)
159#define LPAIF_RDMACTL_FIFOWM_2 (1 << LPAIF_RDMACTL_FIFOWM_SHIFT)
160#define LPAIF_RDMACTL_FIFOWM_3 (2 << LPAIF_RDMACTL_FIFOWM_SHIFT)
161#define LPAIF_RDMACTL_FIFOWM_4 (3 << LPAIF_RDMACTL_FIFOWM_SHIFT)
162#define LPAIF_RDMACTL_FIFOWM_5 (4 << LPAIF_RDMACTL_FIFOWM_SHIFT)
163#define LPAIF_RDMACTL_FIFOWM_6 (5 << LPAIF_RDMACTL_FIFOWM_SHIFT)
164#define LPAIF_RDMACTL_FIFOWM_7 (6 << LPAIF_RDMACTL_FIFOWM_SHIFT)
165#define LPAIF_RDMACTL_FIFOWM_8 (7 << LPAIF_RDMACTL_FIFOWM_SHIFT)
166
167#define LPAIF_RDMACTL_ENABLE_MASK 0x1
168#define LPAIF_RDMACTL_ENABLE_SHIFT 0
169#define LPAIF_RDMACTL_ENABLE_OFF (0 << LPAIF_RDMACTL_ENABLE_SHIFT)
170#define LPAIF_RDMACTL_ENABLE_ON (1 << LPAIF_RDMACTL_ENABLE_SHIFT)
171
172#endif /* __LPASS_LPAIF_H__ */
diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c
new file mode 100644
index 000000000000..2fa6280dfb23
--- /dev/null
+++ b/sound/soc/qcom/lpass-platform.c
@@ -0,0 +1,526 @@
1/*
2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * lpass-platform.c -- ALSA SoC platform driver for QTi LPASS
14 */
15
16#include <linux/compiler.h>
17#include <linux/device.h>
18#include <linux/dma-mapping.h>
19#include <linux/err.h>
20#include <linux/export.h>
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/io.h>
24#include <linux/platform_device.h>
25#include <sound/memalloc.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <linux/regmap.h>
29#include <sound/soc.h>
30#include "lpass-lpaif-ipq806x.h"
31#include "lpass.h"
32
33#define LPASS_PLATFORM_BUFFER_SIZE (16 * 1024)
34#define LPASS_PLATFORM_PERIODS 2
35
36static struct snd_pcm_hardware lpass_platform_pcm_hardware = {
37 .info = SNDRV_PCM_INFO_MMAP |
38 SNDRV_PCM_INFO_MMAP_VALID |
39 SNDRV_PCM_INFO_INTERLEAVED |
40 SNDRV_PCM_INFO_PAUSE |
41 SNDRV_PCM_INFO_RESUME,
42 .formats = SNDRV_PCM_FMTBIT_S16 |
43 SNDRV_PCM_FMTBIT_S24 |
44 SNDRV_PCM_FMTBIT_S32,
45 .rates = SNDRV_PCM_RATE_8000_192000,
46 .rate_min = 8000,
47 .rate_max = 192000,
48 .channels_min = 1,
49 .channels_max = 8,
50 .buffer_bytes_max = LPASS_PLATFORM_BUFFER_SIZE,
51 .period_bytes_max = LPASS_PLATFORM_BUFFER_SIZE /
52 LPASS_PLATFORM_PERIODS,
53 .period_bytes_min = LPASS_PLATFORM_BUFFER_SIZE /
54 LPASS_PLATFORM_PERIODS,
55 .periods_min = LPASS_PLATFORM_PERIODS,
56 .periods_max = LPASS_PLATFORM_PERIODS,
57 .fifo_size = 0,
58};
59
60static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream)
61{
62 struct snd_pcm_runtime *runtime = substream->runtime;
63 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
64 int ret;
65
66 snd_soc_set_runtime_hwparams(substream, &lpass_platform_pcm_hardware);
67
68 runtime->dma_bytes = lpass_platform_pcm_hardware.buffer_bytes_max;
69
70 ret = snd_pcm_hw_constraint_integer(runtime,
71 SNDRV_PCM_HW_PARAM_PERIODS);
72 if (ret < 0) {
73 dev_err(soc_runtime->dev, "%s() setting constraints failed: %d\n",
74 __func__, ret);
75 return -EINVAL;
76 }
77
78 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
79
80 return 0;
81}
82
83static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream,
84 struct snd_pcm_hw_params *params)
85{
86 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
87 struct lpass_data *drvdata =
88 snd_soc_platform_get_drvdata(soc_runtime->platform);
89 snd_pcm_format_t format = params_format(params);
90 unsigned int channels = params_channels(params);
91 unsigned int regval;
92 int bitwidth;
93 int ret;
94
95 bitwidth = snd_pcm_format_width(format);
96 if (bitwidth < 0) {
97 dev_err(soc_runtime->dev, "%s() invalid bit width given: %d\n",
98 __func__, bitwidth);
99 return bitwidth;
100 }
101
102 regval = LPAIF_RDMACTL_BURSTEN_INCR4 |
103 LPAIF_RDMACTL_AUDINTF_MI2S |
104 LPAIF_RDMACTL_FIFOWM_8;
105
106 switch (bitwidth) {
107 case 16:
108 switch (channels) {
109 case 1:
110 case 2:
111 regval |= LPAIF_RDMACTL_WPSCNT_ONE;
112 break;
113 case 4:
114 regval |= LPAIF_RDMACTL_WPSCNT_TWO;
115 break;
116 case 6:
117 regval |= LPAIF_RDMACTL_WPSCNT_THREE;
118 break;
119 case 8:
120 regval |= LPAIF_RDMACTL_WPSCNT_FOUR;
121 break;
122 default:
123 dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n",
124 __func__, bitwidth, channels);
125 return -EINVAL;
126 }
127 break;
128 case 24:
129 case 32:
130 switch (channels) {
131 case 1:
132 regval |= LPAIF_RDMACTL_WPSCNT_ONE;
133 break;
134 case 2:
135 regval |= LPAIF_RDMACTL_WPSCNT_TWO;
136 break;
137 case 4:
138 regval |= LPAIF_RDMACTL_WPSCNT_FOUR;
139 break;
140 case 6:
141 regval |= LPAIF_RDMACTL_WPSCNT_SIX;
142 break;
143 case 8:
144 regval |= LPAIF_RDMACTL_WPSCNT_EIGHT;
145 break;
146 default:
147 dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n",
148 __func__, bitwidth, channels);
149 return -EINVAL;
150 }
151 break;
152 default:
153 dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n",
154 __func__, bitwidth, channels);
155 return -EINVAL;
156 }
157
158 ret = regmap_write(drvdata->lpaif_map,
159 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), regval);
160 if (ret) {
161 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
162 __func__, ret);
163 return ret;
164 }
165
166 return 0;
167}
168
169static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream)
170{
171 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
172 struct lpass_data *drvdata =
173 snd_soc_platform_get_drvdata(soc_runtime->platform);
174 int ret;
175
176 ret = regmap_write(drvdata->lpaif_map,
177 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), 0);
178 if (ret)
179 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
180 __func__, ret);
181
182 return ret;
183}
184
185static int lpass_platform_pcmops_prepare(struct snd_pcm_substream *substream)
186{
187 struct snd_pcm_runtime *runtime = substream->runtime;
188 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
189 struct lpass_data *drvdata =
190 snd_soc_platform_get_drvdata(soc_runtime->platform);
191 int ret;
192
193 ret = regmap_write(drvdata->lpaif_map,
194 LPAIF_RDMABASE_REG(LPAIF_RDMA_CHAN_MI2S),
195 runtime->dma_addr);
196 if (ret) {
197 dev_err(soc_runtime->dev, "%s() error writing to rdmabase reg: %d\n",
198 __func__, ret);
199 return ret;
200 }
201
202 ret = regmap_write(drvdata->lpaif_map,
203 LPAIF_RDMABUFF_REG(LPAIF_RDMA_CHAN_MI2S),
204 (snd_pcm_lib_buffer_bytes(substream) >> 2) - 1);
205 if (ret) {
206 dev_err(soc_runtime->dev, "%s() error writing to rdmabuff reg: %d\n",
207 __func__, ret);
208 return ret;
209 }
210
211 ret = regmap_write(drvdata->lpaif_map,
212 LPAIF_RDMAPER_REG(LPAIF_RDMA_CHAN_MI2S),
213 (snd_pcm_lib_period_bytes(substream) >> 2) - 1);
214 if (ret) {
215 dev_err(soc_runtime->dev, "%s() error writing to rdmaper reg: %d\n",
216 __func__, ret);
217 return ret;
218 }
219
220 ret = regmap_update_bits(drvdata->lpaif_map,
221 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S),
222 LPAIF_RDMACTL_ENABLE_MASK, LPAIF_RDMACTL_ENABLE_ON);
223 if (ret) {
224 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
225 __func__, ret);
226 return ret;
227 }
228
229 return 0;
230}
231
232static int lpass_platform_pcmops_trigger(struct snd_pcm_substream *substream,
233 int cmd)
234{
235 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
236 struct lpass_data *drvdata =
237 snd_soc_platform_get_drvdata(soc_runtime->platform);
238 int ret;
239
240 switch (cmd) {
241 case SNDRV_PCM_TRIGGER_START:
242 case SNDRV_PCM_TRIGGER_RESUME:
243 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
244 /* clear status before enabling interrupts */
245 ret = regmap_write(drvdata->lpaif_map,
246 LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST),
247 LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S));
248 if (ret) {
249 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
250 __func__, ret);
251 return ret;
252 }
253
254 ret = regmap_update_bits(drvdata->lpaif_map,
255 LPAIF_IRQEN_REG(LPAIF_IRQ_PORT_HOST),
256 LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S),
257 LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S));
258 if (ret) {
259 dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n",
260 __func__, ret);
261 return ret;
262 }
263
264 ret = regmap_update_bits(drvdata->lpaif_map,
265 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S),
266 LPAIF_RDMACTL_ENABLE_MASK,
267 LPAIF_RDMACTL_ENABLE_ON);
268 if (ret) {
269 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
270 __func__, ret);
271 return ret;
272 }
273 break;
274 case SNDRV_PCM_TRIGGER_STOP:
275 case SNDRV_PCM_TRIGGER_SUSPEND:
276 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
277 ret = regmap_update_bits(drvdata->lpaif_map,
278 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S),
279 LPAIF_RDMACTL_ENABLE_MASK,
280 LPAIF_RDMACTL_ENABLE_OFF);
281 if (ret) {
282 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
283 __func__, ret);
284 return ret;
285 }
286
287 ret = regmap_update_bits(drvdata->lpaif_map,
288 LPAIF_IRQEN_REG(LPAIF_IRQ_PORT_HOST),
289 LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S), 0);
290 if (ret) {
291 dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n",
292 __func__, ret);
293 return ret;
294 }
295 break;
296 }
297
298 return 0;
299}
300
301static snd_pcm_uframes_t lpass_platform_pcmops_pointer(
302 struct snd_pcm_substream *substream)
303{
304 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
305 struct lpass_data *drvdata =
306 snd_soc_platform_get_drvdata(soc_runtime->platform);
307 unsigned int base_addr, curr_addr;
308 int ret;
309
310 ret = regmap_read(drvdata->lpaif_map,
311 LPAIF_RDMABASE_REG(LPAIF_RDMA_CHAN_MI2S), &base_addr);
312 if (ret) {
313 dev_err(soc_runtime->dev, "%s() error reading from rdmabase reg: %d\n",
314 __func__, ret);
315 return ret;
316 }
317
318 ret = regmap_read(drvdata->lpaif_map,
319 LPAIF_RDMACURR_REG(LPAIF_RDMA_CHAN_MI2S), &curr_addr);
320 if (ret) {
321 dev_err(soc_runtime->dev, "%s() error reading from rdmacurr reg: %d\n",
322 __func__, ret);
323 return ret;
324 }
325
326 return bytes_to_frames(substream->runtime, curr_addr - base_addr);
327}
328
329static int lpass_platform_pcmops_mmap(struct snd_pcm_substream *substream,
330 struct vm_area_struct *vma)
331{
332 struct snd_pcm_runtime *runtime = substream->runtime;
333
334 return dma_mmap_coherent(substream->pcm->card->dev, vma,
335 runtime->dma_area, runtime->dma_addr,
336 runtime->dma_bytes);
337}
338
339static struct snd_pcm_ops lpass_platform_pcm_ops = {
340 .open = lpass_platform_pcmops_open,
341 .ioctl = snd_pcm_lib_ioctl,
342 .hw_params = lpass_platform_pcmops_hw_params,
343 .hw_free = lpass_platform_pcmops_hw_free,
344 .prepare = lpass_platform_pcmops_prepare,
345 .trigger = lpass_platform_pcmops_trigger,
346 .pointer = lpass_platform_pcmops_pointer,
347 .mmap = lpass_platform_pcmops_mmap,
348};
349
350static irqreturn_t lpass_platform_lpaif_irq(int irq, void *data)
351{
352 struct snd_pcm_substream *substream = data;
353 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
354 struct lpass_data *drvdata =
355 snd_soc_platform_get_drvdata(soc_runtime->platform);
356 unsigned int interrupts;
357 irqreturn_t ret = IRQ_NONE;
358 int rv;
359
360 rv = regmap_read(drvdata->lpaif_map,
361 LPAIF_IRQSTAT_REG(LPAIF_IRQ_PORT_HOST), &interrupts);
362 if (rv) {
363 dev_err(soc_runtime->dev, "%s() error reading from irqstat reg: %d\n",
364 __func__, rv);
365 return IRQ_NONE;
366 }
367 interrupts &= LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S);
368
369 if (interrupts & LPAIF_IRQ_PER(LPAIF_RDMA_CHAN_MI2S)) {
370 rv = regmap_write(drvdata->lpaif_map,
371 LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST),
372 LPAIF_IRQ_PER(LPAIF_RDMA_CHAN_MI2S));
373 if (rv) {
374 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
375 __func__, rv);
376 return IRQ_NONE;
377 }
378 snd_pcm_period_elapsed(substream);
379 ret = IRQ_HANDLED;
380 }
381
382 if (interrupts & LPAIF_IRQ_XRUN(LPAIF_RDMA_CHAN_MI2S)) {
383 rv = regmap_write(drvdata->lpaif_map,
384 LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST),
385 LPAIF_IRQ_XRUN(LPAIF_RDMA_CHAN_MI2S));
386 if (rv) {
387 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
388 __func__, rv);
389 return IRQ_NONE;
390 }
391 dev_warn(soc_runtime->dev, "%s() xrun warning\n", __func__);
392 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
393 ret = IRQ_HANDLED;
394 }
395
396 if (interrupts & LPAIF_IRQ_ERR(LPAIF_RDMA_CHAN_MI2S)) {
397 rv = regmap_write(drvdata->lpaif_map,
398 LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST),
399 LPAIF_IRQ_ERR(LPAIF_RDMA_CHAN_MI2S));
400 if (rv) {
401 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
402 __func__, rv);
403 return IRQ_NONE;
404 }
405 dev_err(soc_runtime->dev, "%s() bus access error\n", __func__);
406 snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
407 ret = IRQ_HANDLED;
408 }
409
410 return ret;
411}
412
413static int lpass_platform_alloc_buffer(struct snd_pcm_substream *substream,
414 struct snd_soc_pcm_runtime *soc_runtime)
415{
416 struct snd_dma_buffer *buf = &substream->dma_buffer;
417 size_t size = lpass_platform_pcm_hardware.buffer_bytes_max;
418
419 buf->dev.type = SNDRV_DMA_TYPE_DEV;
420 buf->dev.dev = soc_runtime->dev;
421 buf->private_data = NULL;
422 buf->area = dma_alloc_coherent(soc_runtime->dev, size, &buf->addr,
423 GFP_KERNEL);
424 if (!buf->area) {
425 dev_err(soc_runtime->dev, "%s: Could not allocate DMA buffer\n",
426 __func__);
427 return -ENOMEM;
428 }
429 buf->bytes = size;
430
431 return 0;
432}
433
434static void lpass_platform_free_buffer(struct snd_pcm_substream *substream,
435 struct snd_soc_pcm_runtime *soc_runtime)
436{
437 struct snd_dma_buffer *buf = &substream->dma_buffer;
438
439 if (buf->area) {
440 dma_free_coherent(soc_runtime->dev, buf->bytes, buf->area,
441 buf->addr);
442 }
443 buf->area = NULL;
444}
445
446static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
447{
448 struct snd_pcm *pcm = soc_runtime->pcm;
449 struct snd_pcm_substream *substream =
450 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
451 struct lpass_data *drvdata =
452 snd_soc_platform_get_drvdata(soc_runtime->platform);
453 int ret;
454
455 soc_runtime->dev->coherent_dma_mask = DMA_BIT_MASK(32);
456 soc_runtime->dev->dma_mask = &soc_runtime->dev->coherent_dma_mask;
457
458 ret = lpass_platform_alloc_buffer(substream, soc_runtime);
459 if (ret)
460 return ret;
461
462 ret = devm_request_irq(soc_runtime->dev, drvdata->lpaif_irq,
463 lpass_platform_lpaif_irq, IRQF_TRIGGER_RISING,
464 "lpass-irq-lpaif", substream);
465 if (ret) {
466 dev_err(soc_runtime->dev, "%s() irq request failed: %d\n",
467 __func__, ret);
468 goto err_buf;
469 }
470
471 /* ensure audio hardware is disabled */
472 ret = regmap_write(drvdata->lpaif_map,
473 LPAIF_IRQEN_REG(LPAIF_IRQ_PORT_HOST), 0);
474 if (ret) {
475 dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n",
476 __func__, ret);
477 return ret;
478 }
479 ret = regmap_write(drvdata->lpaif_map,
480 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), 0);
481 if (ret) {
482 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
483 __func__, ret);
484 return ret;
485 }
486
487 return 0;
488
489err_buf:
490 lpass_platform_free_buffer(substream, soc_runtime);
491 return ret;
492}
493
494static void lpass_platform_pcm_free(struct snd_pcm *pcm)
495{
496 struct snd_pcm_substream *substream =
497 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
498 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
499
500 lpass_platform_free_buffer(substream, soc_runtime);
501}
502
503static struct snd_soc_platform_driver lpass_platform_driver = {
504 .pcm_new = lpass_platform_pcm_new,
505 .pcm_free = lpass_platform_pcm_free,
506 .ops = &lpass_platform_pcm_ops,
507};
508
509int asoc_qcom_lpass_platform_register(struct platform_device *pdev)
510{
511 struct lpass_data *drvdata = platform_get_drvdata(pdev);
512
513 drvdata->lpaif_irq = platform_get_irq_byname(pdev, "lpass-irq-lpaif");
514 if (drvdata->lpaif_irq < 0) {
515 dev_err(&pdev->dev, "%s() error getting irq handle: %d\n",
516 __func__, drvdata->lpaif_irq);
517 return -ENODEV;
518 }
519
520 return devm_snd_soc_register_platform(&pdev->dev,
521 &lpass_platform_driver);
522}
523EXPORT_SYMBOL_GPL(asoc_qcom_lpass_platform_register);
524
525MODULE_DESCRIPTION("QTi LPASS Platform Driver");
526MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
new file mode 100644
index 000000000000..5c99b3dace86
--- /dev/null
+++ b/sound/soc/qcom/lpass.h
@@ -0,0 +1,51 @@
1/*
2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * lpass.h - Definitions for the QTi LPASS
14 */
15
16#ifndef __LPASS_H__
17#define __LPASS_H__
18
19#include <linux/clk.h>
20#include <linux/compiler.h>
21#include <linux/platform_device.h>
22#include <linux/regmap.h>
23
24#define LPASS_AHBIX_CLOCK_FREQUENCY 131072000
25
26/* Both the CPU DAI and platform drivers will access this data */
27struct lpass_data {
28
29 /* AHB-I/X bus clocks inside the low-power audio subsystem (LPASS) */
30 struct clk *ahbix_clk;
31
32 /* MI2S system clock */
33 struct clk *mi2s_osr_clk;
34
35 /* MI2S bit clock (derived from system clock by a divider */
36 struct clk *mi2s_bit_clk;
37
38 /* low-power audio interface (LPAIF) registers */
39 void __iomem *lpaif;
40
41 /* regmap backed by the low-power audio interface (LPAIF) registers */
42 struct regmap *lpaif_map;
43
44 /* interrupts from the low-power audio interface (LPAIF) */
45 int lpaif_irq;
46};
47
48/* register the platform driver from the CPU DAI driver */
49int asoc_qcom_lpass_platform_register(struct platform_device *);
50
51#endif /* __LPASS_H__ */
diff --git a/sound/soc/qcom/storm.c b/sound/soc/qcom/storm.c
new file mode 100644
index 000000000000..b8bd296190ad
--- /dev/null
+++ b/sound/soc/qcom/storm.c
@@ -0,0 +1,162 @@
1/*
2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * storm.c -- ALSA SoC machine driver for QTi ipq806x-based Storm board
14 */
15
16#include <linux/device.h>
17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/mod_devicetable.h>
20#include <linux/platform_device.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24
25#define STORM_SYSCLK_MULT 4
26
27static int storm_ops_hw_params(struct snd_pcm_substream *substream,
28 struct snd_pcm_hw_params *params)
29{
30 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
31 struct snd_soc_card *card = soc_runtime->card;
32 snd_pcm_format_t format = params_format(params);
33 unsigned int rate = params_rate(params);
34 unsigned int sysclk_freq;
35 int bitwidth, ret;
36
37 bitwidth = snd_pcm_format_width(format);
38 if (bitwidth < 0) {
39 dev_err(card->dev, "%s() invalid bit width given: %d\n",
40 __func__, bitwidth);
41 return bitwidth;
42 }
43
44 /*
45 * as the CPU DAI is the I2S bus master and no system clock is needed by
46 * the MAX98357a DAC, simply set the system clock to be a constant
47 * multiple of the bit clock for the clock divider
48 */
49 sysclk_freq = rate * bitwidth * 2 * STORM_SYSCLK_MULT;
50
51 ret = snd_soc_dai_set_sysclk(soc_runtime->cpu_dai, 0, sysclk_freq, 0);
52 if (ret) {
53 dev_err(card->dev, "%s() error setting sysclk to %u: %d\n",
54 __func__, sysclk_freq, ret);
55 return ret;
56 }
57
58 return 0;
59}
60
61static struct snd_soc_ops storm_soc_ops = {
62 .hw_params = storm_ops_hw_params,
63};
64
65static struct snd_soc_dai_link storm_dai_link = {
66 .name = "Primary",
67 .stream_name = "Primary",
68 .codec_dai_name = "HiFi",
69 .ops = &storm_soc_ops,
70};
71
72static struct snd_soc_card storm_soc_card = {
73 .name = "ipq806x-storm",
74 .dev = NULL,
75};
76
77static int storm_parse_of(struct snd_soc_card *card)
78{
79 struct snd_soc_dai_link *dai_link = card->dai_link;
80 struct device_node *np = card->dev->of_node;
81
82 dai_link->cpu_of_node = of_parse_phandle(np, "cpu", 0);
83 if (!dai_link->cpu_of_node) {
84 dev_err(card->dev, "%s() error getting cpu phandle\n",
85 __func__);
86 return -EINVAL;
87 }
88 dai_link->platform_of_node = dai_link->cpu_of_node;
89
90 dai_link->codec_of_node = of_parse_phandle(np, "codec", 0);
91 if (!dai_link->codec_of_node) {
92 dev_err(card->dev, "%s() error getting codec phandle\n",
93 __func__);
94 return -EINVAL;
95 }
96
97 return 0;
98}
99
100static int storm_platform_probe(struct platform_device *pdev)
101{
102 struct snd_soc_card *card = &storm_soc_card;
103 int ret;
104
105 if (card->dev) {
106 dev_err(&pdev->dev, "%s() error, existing soundcard\n",
107 __func__);
108 return -ENODEV;
109 }
110 card->dev = &pdev->dev;
111 platform_set_drvdata(pdev, card);
112
113 ret = snd_soc_of_parse_card_name(card, "qcom,model");
114 if (ret) {
115 dev_err(&pdev->dev, "%s() error parsing card name: %d\n",
116 __func__, ret);
117 return ret;
118 }
119
120 card->dai_link = &storm_dai_link;
121 card->num_links = 1;
122
123 ret = storm_parse_of(card);
124 if (ret) {
125 dev_err(&pdev->dev, "%s() error resolving dai links: %d\n",
126 __func__, ret);
127 return ret;
128 }
129
130 ret = devm_snd_soc_register_card(&pdev->dev, card);
131 if (ret == -EPROBE_DEFER) {
132 card->dev = NULL;
133 return ret;
134 } else if (ret) {
135 dev_err(&pdev->dev, "%s() error registering soundcard: %d\n",
136 __func__, ret);
137 return ret;
138 }
139
140 return 0;
141}
142
143#ifdef CONFIG_OF
144static const struct of_device_id storm_device_id[] = {
145 { .compatible = "google,storm-audio" },
146 {},
147};
148MODULE_DEVICE_TABLE(of, storm_device_id);
149#endif
150
151static struct platform_driver storm_platform_driver = {
152 .driver = {
153 .name = "storm-audio",
154 .of_match_table =
155 of_match_ptr(storm_device_id),
156 },
157 .probe = storm_platform_probe,
158};
159module_platform_driver(storm_platform_driver);
160
161MODULE_DESCRIPTION("QTi IPQ806x-based Storm Machine Driver");
162MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
index 59b044255b78..c72e9fb26658 100644
--- a/sound/soc/samsung/h1940_uda1380.c
+++ b/sound/soc/samsung/h1940_uda1380.c
@@ -162,13 +162,8 @@ static struct platform_device *s3c24xx_snd_device;
162 162
163static int h1940_uda1380_init(struct snd_soc_pcm_runtime *rtd) 163static int h1940_uda1380_init(struct snd_soc_pcm_runtime *rtd)
164{ 164{
165 struct snd_soc_codec *codec = rtd->codec; 165 snd_soc_card_jack_new(rtd->card, "Headphone Jack", SND_JACK_HEADPHONE,
166 166 &hp_jack, hp_jack_pins, ARRAY_SIZE(hp_jack_pins));
167 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
168 &hp_jack);
169
170 snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
171 hp_jack_pins);
172 167
173 snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), 168 snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
174 hp_jack_gpios); 169 hp_jack_gpios);
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c
index 141519c21e21..31a820eb0ac3 100644
--- a/sound/soc/samsung/littlemill.c
+++ b/sound/soc/samsung/littlemill.c
@@ -260,12 +260,12 @@ static int littlemill_late_probe(struct snd_soc_card *card)
260 if (ret < 0) 260 if (ret < 0)
261 return ret; 261 return ret;
262 262
263 ret = snd_soc_jack_new(codec, "Headset", 263 ret = snd_soc_card_jack_new(card, "Headset",
264 SND_JACK_HEADSET | SND_JACK_MECHANICAL | 264 SND_JACK_HEADSET | SND_JACK_MECHANICAL |
265 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 265 SND_JACK_BTN_0 | SND_JACK_BTN_1 |
266 SND_JACK_BTN_2 | SND_JACK_BTN_3 | 266 SND_JACK_BTN_2 | SND_JACK_BTN_3 |
267 SND_JACK_BTN_4 | SND_JACK_BTN_5, 267 SND_JACK_BTN_4 | SND_JACK_BTN_5,
268 &littlemill_headset); 268 &littlemill_headset, NULL, 0);
269 if (ret) 269 if (ret)
270 return ret; 270 return ret;
271 271
diff --git a/sound/soc/samsung/lowland.c b/sound/soc/samsung/lowland.c
index 243dea7ba38f..5f156093101e 100644
--- a/sound/soc/samsung/lowland.c
+++ b/sound/soc/samsung/lowland.c
@@ -56,16 +56,10 @@ static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd)
56 return ret; 56 return ret;
57 } 57 }
58 58
59 ret = snd_soc_jack_new(codec, "Headset", 59 ret = snd_soc_card_jack_new(rtd->card, "Headset", SND_JACK_LINEOUT |
60 SND_JACK_LINEOUT | SND_JACK_HEADSET | 60 SND_JACK_HEADSET | SND_JACK_BTN_0,
61 SND_JACK_BTN_0, 61 &lowland_headset, lowland_headset_pins,
62 &lowland_headset); 62 ARRAY_SIZE(lowland_headset_pins));
63 if (ret)
64 return ret;
65
66 ret = snd_soc_jack_add_pins(&lowland_headset,
67 ARRAY_SIZE(lowland_headset_pins),
68 lowland_headset_pins);
69 if (ret) 63 if (ret)
70 return ret; 64 return ret;
71 65
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
index 873f2cb4bebe..35e37c457f1f 100644
--- a/sound/soc/samsung/rx1950_uda1380.c
+++ b/sound/soc/samsung/rx1950_uda1380.c
@@ -211,13 +211,8 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream,
211 211
212static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd) 212static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd)
213{ 213{
214 struct snd_soc_codec *codec = rtd->codec; 214 snd_soc_card_jack_new(rtd->card, "Headphone Jack", SND_JACK_HEADPHONE,
215 215 &hp_jack, hp_jack_pins, ARRAY_SIZE(hp_jack_pins));
216 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
217 &hp_jack);
218
219 snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
220 hp_jack_pins);
221 216
222 snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), 217 snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
223 hp_jack_gpios); 218 hp_jack_gpios);
diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c
index 8291d2a5f152..dfbe2db1c407 100644
--- a/sound/soc/samsung/smartq_wm8987.c
+++ b/sound/soc/samsung/smartq_wm8987.c
@@ -151,13 +151,10 @@ static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd)
151 snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); 151 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
152 152
153 /* Headphone jack detection */ 153 /* Headphone jack detection */
154 err = snd_soc_jack_new(codec, "Headphone Jack", 154 err = snd_soc_card_jack_new(rtd->card, "Headphone Jack",
155 SND_JACK_HEADPHONE, &smartq_jack); 155 SND_JACK_HEADPHONE, &smartq_jack,
156 if (err) 156 smartq_jack_pins,
157 return err; 157 ARRAY_SIZE(smartq_jack_pins));
158
159 err = snd_soc_jack_add_pins(&smartq_jack, ARRAY_SIZE(smartq_jack_pins),
160 smartq_jack_pins);
161 if (err) 158 if (err)
162 return err; 159 return err;
163 160
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index 5ec7c52282f2..2dcb988bdff2 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -153,16 +153,10 @@ static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd)
153 pr_err("Failed to request HP_SEL GPIO: %d\n", ret); 153 pr_err("Failed to request HP_SEL GPIO: %d\n", ret);
154 gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity); 154 gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity);
155 155
156 ret = snd_soc_jack_new(codec, "Headset", 156 ret = snd_soc_card_jack_new(rtd->card, "Headset", SND_JACK_LINEOUT |
157 SND_JACK_LINEOUT | SND_JACK_HEADSET | 157 SND_JACK_HEADSET | SND_JACK_BTN_0,
158 SND_JACK_BTN_0, 158 &speyside_headset, speyside_headset_pins,
159 &speyside_headset); 159 ARRAY_SIZE(speyside_headset_pins));
160 if (ret)
161 return ret;
162
163 ret = snd_soc_jack_add_pins(&speyside_headset,
164 ARRAY_SIZE(speyside_headset_pins),
165 speyside_headset_pins);
166 if (ret) 160 if (ret)
167 return ret; 161 return ret;
168 162
diff --git a/sound/soc/samsung/tobermory.c b/sound/soc/samsung/tobermory.c
index 9c80506527c4..85ccfb7188cb 100644
--- a/sound/soc/samsung/tobermory.c
+++ b/sound/soc/samsung/tobermory.c
@@ -179,15 +179,10 @@ static int tobermory_late_probe(struct snd_soc_card *card)
179 if (ret < 0) 179 if (ret < 0)
180 return ret; 180 return ret;
181 181
182 ret = snd_soc_jack_new(codec, "Headset", 182 ret = snd_soc_card_jack_new(card, "Headset", SND_JACK_HEADSET |
183 SND_JACK_HEADSET | SND_JACK_BTN_0, 183 SND_JACK_BTN_0, &tobermory_headset,
184 &tobermory_headset); 184 tobermory_headset_pins,
185 if (ret) 185 ARRAY_SIZE(tobermory_headset_pins));
186 return ret;
187
188 ret = snd_soc_jack_add_pins(&tobermory_headset,
189 ARRAY_SIZE(tobermory_headset_pins),
190 tobermory_headset_pins);
191 if (ret) 186 if (ret)
192 return ret; 187 return ret;
193 188
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 80245b6eebd6..07114b0b0dc1 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -36,11 +36,17 @@ config SND_SOC_SH4_SIU
36 36
37config SND_SOC_RCAR 37config SND_SOC_RCAR
38 tristate "R-Car series SRU/SCU/SSIU/SSI support" 38 tristate "R-Car series SRU/SCU/SSIU/SSI support"
39 depends on DMA_OF
39 select SND_SIMPLE_CARD 40 select SND_SIMPLE_CARD
40 select REGMAP_MMIO 41 select REGMAP_MMIO
41 help 42 help
42 This option enables R-Car SUR/SCU/SSIU/SSI sound support 43 This option enables R-Car SUR/SCU/SSIU/SSI sound support
43 44
45config SND_SOC_RSRC_CARD
46 tristate "Renesas Sampling Rate Convert Sound Card"
47 help
48 This option enables simple sound if you need sampling rate convert
49
44## 50##
45## Boards 51## Boards
46## 52##
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index b87b22e88e43..0c2af21b0b82 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -1876,7 +1876,40 @@ static void fsi_handler_init(struct fsi_priv *fsi,
1876 } 1876 }
1877} 1877}
1878 1878
1879static struct of_device_id fsi_of_match[]; 1879static const struct fsi_core fsi1_core = {
1880 .ver = 1,
1881
1882 /* Interrupt */
1883 .int_st = INT_ST,
1884 .iemsk = IEMSK,
1885 .imsk = IMSK,
1886};
1887
1888static const struct fsi_core fsi2_core = {
1889 .ver = 2,
1890
1891 /* Interrupt */
1892 .int_st = CPU_INT_ST,
1893 .iemsk = CPU_IEMSK,
1894 .imsk = CPU_IMSK,
1895 .a_mclk = A_MST_CTLR,
1896 .b_mclk = B_MST_CTLR,
1897};
1898
1899static const struct of_device_id fsi_of_match[] = {
1900 { .compatible = "renesas,sh_fsi", .data = &fsi1_core},
1901 { .compatible = "renesas,sh_fsi2", .data = &fsi2_core},
1902 {},
1903};
1904MODULE_DEVICE_TABLE(of, fsi_of_match);
1905
1906static const struct platform_device_id fsi_id_table[] = {
1907 { "sh_fsi", (kernel_ulong_t)&fsi1_core },
1908 { "sh_fsi2", (kernel_ulong_t)&fsi2_core },
1909 {},
1910};
1911MODULE_DEVICE_TABLE(platform, fsi_id_table);
1912
1880static int fsi_probe(struct platform_device *pdev) 1913static int fsi_probe(struct platform_device *pdev)
1881{ 1914{
1882 struct fsi_master *master; 1915 struct fsi_master *master;
@@ -2072,40 +2105,6 @@ static struct dev_pm_ops fsi_pm_ops = {
2072 .resume = fsi_resume, 2105 .resume = fsi_resume,
2073}; 2106};
2074 2107
2075static struct fsi_core fsi1_core = {
2076 .ver = 1,
2077
2078 /* Interrupt */
2079 .int_st = INT_ST,
2080 .iemsk = IEMSK,
2081 .imsk = IMSK,
2082};
2083
2084static struct fsi_core fsi2_core = {
2085 .ver = 2,
2086
2087 /* Interrupt */
2088 .int_st = CPU_INT_ST,
2089 .iemsk = CPU_IEMSK,
2090 .imsk = CPU_IMSK,
2091 .a_mclk = A_MST_CTLR,
2092 .b_mclk = B_MST_CTLR,
2093};
2094
2095static struct of_device_id fsi_of_match[] = {
2096 { .compatible = "renesas,sh_fsi", .data = &fsi1_core},
2097 { .compatible = "renesas,sh_fsi2", .data = &fsi2_core},
2098 {},
2099};
2100MODULE_DEVICE_TABLE(of, fsi_of_match);
2101
2102static struct platform_device_id fsi_id_table[] = {
2103 { "sh_fsi", (kernel_ulong_t)&fsi1_core },
2104 { "sh_fsi2", (kernel_ulong_t)&fsi2_core },
2105 {},
2106};
2107MODULE_DEVICE_TABLE(platform, fsi_id_table);
2108
2109static struct platform_driver fsi_driver = { 2108static struct platform_driver fsi_driver = {
2110 .driver = { 2109 .driver = {
2111 .name = "fsi-pcm-audio", 2110 .name = "fsi-pcm-audio",
@@ -2119,7 +2118,7 @@ static struct platform_driver fsi_driver = {
2119 2118
2120module_platform_driver(fsi_driver); 2119module_platform_driver(fsi_driver);
2121 2120
2122MODULE_LICENSE("GPL"); 2121MODULE_LICENSE("GPL v2");
2123MODULE_DESCRIPTION("SuperH onchip FSI audio driver"); 2122MODULE_DESCRIPTION("SuperH onchip FSI audio driver");
2124MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>"); 2123MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
2125MODULE_ALIAS("platform:fsi-pcm-audio"); 2124MODULE_ALIAS("platform:fsi-pcm-audio");
diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile
index 9ac536429800..f1b445173fba 100644
--- a/sound/soc/sh/rcar/Makefile
+++ b/sound/soc/sh/rcar/Makefile
@@ -1,2 +1,5 @@
1snd-soc-rcar-objs := core.o gen.o src.o adg.o ssi.o dvc.o 1snd-soc-rcar-objs := core.o gen.o dma.o src.o adg.o ssi.o dvc.o
2obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o \ No newline at end of file 2obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o
3
4snd-soc-rsrc-card-objs := rsrc-card.o
5obj-$(CONFIG_SND_SOC_RSRC_CARD) += snd-soc-rsrc-card.o
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 7ac35c9d1cb8..fefc881dbac2 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -183,6 +183,8 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
183 183
184 rsnd_mod_bset(mod, DIV_EN, en, en); 184 rsnd_mod_bset(mod, DIV_EN, en, en);
185 185
186 dev_dbg(dev, "convert rate %d <-> %d\n", src_rate, dst_rate);
187
186 return 0; 188 return 0;
187} 189}
188 190
@@ -432,7 +434,5 @@ int rsnd_adg_probe(struct platform_device *pdev,
432 434
433 priv->adg = adg; 435 priv->adg = adg;
434 436
435 dev_dbg(dev, "adg probed\n");
436
437 return 0; 437 return 0;
438} 438}
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 110577c52317..9f48d75fa992 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -94,21 +94,20 @@
94 * 94 *
95 */ 95 */
96#include <linux/pm_runtime.h> 96#include <linux/pm_runtime.h>
97#include <linux/shdma-base.h>
98#include "rsnd.h" 97#include "rsnd.h"
99 98
100#define RSND_RATES SNDRV_PCM_RATE_8000_96000 99#define RSND_RATES SNDRV_PCM_RATE_8000_96000
101#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 100#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
102 101
103static struct rsnd_of_data rsnd_of_data_gen1 = { 102static const struct rsnd_of_data rsnd_of_data_gen1 = {
104 .flags = RSND_GEN1, 103 .flags = RSND_GEN1,
105}; 104};
106 105
107static struct rsnd_of_data rsnd_of_data_gen2 = { 106static const struct rsnd_of_data rsnd_of_data_gen2 = {
108 .flags = RSND_GEN2, 107 .flags = RSND_GEN2,
109}; 108};
110 109
111static struct of_device_id rsnd_of_match[] = { 110static const struct of_device_id rsnd_of_match[] = {
112 { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 }, 111 { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 },
113 { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 }, 112 { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 },
114 {}, 113 {},
@@ -138,249 +137,37 @@ char *rsnd_mod_name(struct rsnd_mod *mod)
138 return mod->ops->name; 137 return mod->ops->name;
139} 138}
140 139
141char *rsnd_mod_dma_name(struct rsnd_mod *mod) 140struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod)
142{ 141{
143 if (!mod || !mod->ops) 142 if (!mod || !mod->ops || !mod->ops->dma_req)
144 return "unknown"; 143 return NULL;
145
146 if (!mod->ops->dma_name)
147 return mod->ops->name;
148 144
149 return mod->ops->dma_name(mod); 145 return mod->ops->dma_req(mod);
150} 146}
151 147
152void rsnd_mod_init(struct rsnd_mod *mod, 148int rsnd_mod_init(struct rsnd_mod *mod,
153 struct rsnd_mod_ops *ops, 149 struct rsnd_mod_ops *ops,
154 struct clk *clk, 150 struct clk *clk,
155 enum rsnd_mod_type type, 151 enum rsnd_mod_type type,
156 int id) 152 int id)
157{ 153{
154 int ret = clk_prepare(clk);
155
156 if (ret)
157 return ret;
158
158 mod->id = id; 159 mod->id = id;
159 mod->ops = ops; 160 mod->ops = ops;
160 mod->type = type; 161 mod->type = type;
161 mod->clk = clk; 162 mod->clk = clk;
162}
163
164/*
165 * rsnd_dma functions
166 */
167void rsnd_dma_stop(struct rsnd_dma *dma)
168{
169 dmaengine_terminate_all(dma->chan);
170}
171
172static void rsnd_dma_complete(void *data)
173{
174 struct rsnd_dma *dma = (struct rsnd_dma *)data;
175 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
176 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
177
178 /*
179 * Renesas sound Gen1 needs 1 DMAC,
180 * Gen2 needs 2 DMAC.
181 * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri.
182 * But, Audio-DMAC-peri-peri doesn't have interrupt,
183 * and this driver is assuming that here.
184 *
185 * If Audio-DMAC-peri-peri has interrpt,
186 * rsnd_dai_pointer_update() will be called twice,
187 * ant it will breaks io->byte_pos
188 */
189
190 rsnd_dai_pointer_update(io, io->byte_per_period);
191}
192
193void rsnd_dma_start(struct rsnd_dma *dma)
194{
195 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
196 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
197 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
198 struct snd_pcm_substream *substream = io->substream;
199 struct device *dev = rsnd_priv_to_dev(priv);
200 struct dma_async_tx_descriptor *desc;
201
202 desc = dmaengine_prep_dma_cyclic(dma->chan,
203 (dma->addr) ? dma->addr :
204 substream->runtime->dma_addr,
205 snd_pcm_lib_buffer_bytes(substream),
206 snd_pcm_lib_period_bytes(substream),
207 dma->dir,
208 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
209
210 if (!desc) {
211 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
212 return;
213 }
214
215 desc->callback = rsnd_dma_complete;
216 desc->callback_param = dma;
217
218 if (dmaengine_submit(desc) < 0) {
219 dev_err(dev, "dmaengine_submit() fail\n");
220 return;
221 }
222
223 dma_async_issue_pending(dma->chan);
224}
225
226int rsnd_dma_available(struct rsnd_dma *dma)
227{
228 return !!dma->chan;
229}
230
231#define DMA_NAME_SIZE 16
232#define MOD_MAX 4 /* MEM/SSI/SRC/DVC */
233static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod)
234{
235 if (mod)
236 return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d",
237 rsnd_mod_dma_name(mod), rsnd_mod_id(mod));
238 else
239 return snprintf(dma_name, DMA_NAME_SIZE / 2, "mem");
240
241}
242
243static void rsnd_dma_of_name(struct rsnd_mod *mod_from,
244 struct rsnd_mod *mod_to,
245 char *dma_name)
246{
247 int index = 0;
248
249 index = _rsnd_dma_of_name(dma_name + index, mod_from);
250 *(dma_name + index++) = '_';
251 index = _rsnd_dma_of_name(dma_name + index, mod_to);
252}
253
254static void rsnd_dma_of_path(struct rsnd_dma *dma,
255 int is_play,
256 struct rsnd_mod **mod_from,
257 struct rsnd_mod **mod_to)
258{
259 struct rsnd_mod *this = rsnd_dma_to_mod(dma);
260 struct rsnd_dai_stream *io = rsnd_mod_to_io(this);
261 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
262 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
263 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
264 struct rsnd_mod *mod[MOD_MAX];
265 int i, index;
266 163
267 164 return ret;
268 for (i = 0; i < MOD_MAX; i++)
269 mod[i] = NULL;
270
271 /*
272 * in play case...
273 *
274 * src -> dst
275 *
276 * mem -> SSI
277 * mem -> SRC -> SSI
278 * mem -> SRC -> DVC -> SSI
279 */
280 mod[0] = NULL; /* for "mem" */
281 index = 1;
282 for (i = 1; i < MOD_MAX; i++) {
283 if (!src) {
284 mod[i] = ssi;
285 } else if (!dvc) {
286 mod[i] = src;
287 src = NULL;
288 } else {
289 if ((!is_play) && (this == src))
290 this = dvc;
291
292 mod[i] = (is_play) ? src : dvc;
293 i++;
294 mod[i] = (is_play) ? dvc : src;
295 src = NULL;
296 dvc = NULL;
297 }
298
299 if (mod[i] == this)
300 index = i;
301
302 if (mod[i] == ssi)
303 break;
304 }
305
306 if (is_play) {
307 *mod_from = mod[index - 1];
308 *mod_to = mod[index];
309 } else {
310 *mod_from = mod[index];
311 *mod_to = mod[index - 1];
312 }
313}
314
315int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
316 int is_play, int id)
317{
318 struct device *dev = rsnd_priv_to_dev(priv);
319 struct dma_slave_config cfg;
320 struct rsnd_mod *mod_from;
321 struct rsnd_mod *mod_to;
322 char dma_name[DMA_NAME_SIZE];
323 dma_cap_mask_t mask;
324 int ret;
325
326 if (dma->chan) {
327 dev_err(dev, "it already has dma channel\n");
328 return -EIO;
329 }
330
331 dma_cap_zero(mask);
332 dma_cap_set(DMA_SLAVE, mask);
333
334 rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to);
335 rsnd_dma_of_name(mod_from, mod_to, dma_name);
336
337 cfg.slave_id = id;
338 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
339 cfg.src_addr = rsnd_gen_dma_addr(priv, mod_from, is_play, 1);
340 cfg.dst_addr = rsnd_gen_dma_addr(priv, mod_to, is_play, 0);
341 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
342 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
343
344 dev_dbg(dev, "dma : %s %pad -> %pad\n",
345 dma_name, &cfg.src_addr, &cfg.dst_addr);
346
347 dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter,
348 (void *)id, dev,
349 dma_name);
350 if (!dma->chan) {
351 dev_err(dev, "can't get dma channel\n");
352 goto rsnd_dma_channel_err;
353 }
354
355 ret = dmaengine_slave_config(dma->chan, &cfg);
356 if (ret < 0)
357 goto rsnd_dma_init_err;
358
359 dma->addr = is_play ? cfg.src_addr : cfg.dst_addr;
360 dma->dir = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
361
362 return 0;
363
364rsnd_dma_init_err:
365 rsnd_dma_quit(priv, dma);
366rsnd_dma_channel_err:
367
368 /*
369 * DMA failed. try to PIO mode
370 * see
371 * rsnd_ssi_fallback()
372 * rsnd_rdai_continuance_probe()
373 */
374 return -EAGAIN;
375} 165}
376 166
377void rsnd_dma_quit(struct rsnd_priv *priv, 167void rsnd_mod_quit(struct rsnd_mod *mod)
378 struct rsnd_dma *dma)
379{ 168{
380 if (dma->chan) 169 if (mod->clk)
381 dma_release_channel(dma->chan); 170 clk_unprepare(mod->clk);
382
383 dma->chan = NULL;
384} 171}
385 172
386/* 173/*
@@ -416,7 +203,7 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod)
416({ \ 203({ \
417 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ 204 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \
418 struct device *dev = rsnd_priv_to_dev(priv); \ 205 struct device *dev = rsnd_priv_to_dev(priv); \
419 u32 mask = 1 << __rsnd_mod_shift_##func; \ 206 u32 mask = (1 << __rsnd_mod_shift_##func) & ~(1 << 31); \
420 u32 call = __rsnd_mod_call_##func << __rsnd_mod_shift_##func; \ 207 u32 call = __rsnd_mod_call_##func << __rsnd_mod_shift_##func; \
421 int ret = 0; \ 208 int ret = 0; \
422 if ((mod->status & mask) == call) { \ 209 if ((mod->status & mask) == call) { \
@@ -458,7 +245,7 @@ static int rsnd_dai_connect(struct rsnd_mod *mod,
458 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 245 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
459 struct device *dev = rsnd_priv_to_dev(priv); 246 struct device *dev = rsnd_priv_to_dev(priv);
460 247
461 dev_err(dev, "%s%d is not empty\n", 248 dev_err(dev, "%s[%d] is not empty\n",
462 rsnd_mod_name(mod), 249 rsnd_mod_name(mod),
463 rsnd_mod_id(mod)); 250 rsnd_mod_id(mod));
464 return -EIO; 251 return -EIO;
@@ -874,20 +661,28 @@ static int rsnd_dai_probe(struct platform_device *pdev,
874 drv[i].name = rdai[i].name; 661 drv[i].name = rdai[i].name;
875 drv[i].ops = &rsnd_soc_dai_ops; 662 drv[i].ops = &rsnd_soc_dai_ops;
876 if (pmod) { 663 if (pmod) {
664 snprintf(rdai[i].playback.name, RSND_DAI_NAME_SIZE,
665 "DAI%d Playback", i);
666
877 drv[i].playback.rates = RSND_RATES; 667 drv[i].playback.rates = RSND_RATES;
878 drv[i].playback.formats = RSND_FMTS; 668 drv[i].playback.formats = RSND_FMTS;
879 drv[i].playback.channels_min = 2; 669 drv[i].playback.channels_min = 2;
880 drv[i].playback.channels_max = 2; 670 drv[i].playback.channels_max = 2;
671 drv[i].playback.stream_name = rdai[i].playback.name;
881 672
882 rdai[i].playback.info = &info->dai_info[i].playback; 673 rdai[i].playback.info = &info->dai_info[i].playback;
883 rdai[i].playback.rdai = rdai + i; 674 rdai[i].playback.rdai = rdai + i;
884 rsnd_path_init(priv, &rdai[i], &rdai[i].playback); 675 rsnd_path_init(priv, &rdai[i], &rdai[i].playback);
885 } 676 }
886 if (cmod) { 677 if (cmod) {
678 snprintf(rdai[i].capture.name, RSND_DAI_NAME_SIZE,
679 "DAI%d Capture", i);
680
887 drv[i].capture.rates = RSND_RATES; 681 drv[i].capture.rates = RSND_RATES;
888 drv[i].capture.formats = RSND_FMTS; 682 drv[i].capture.formats = RSND_FMTS;
889 drv[i].capture.channels_min = 2; 683 drv[i].capture.channels_min = 2;
890 drv[i].capture.channels_max = 2; 684 drv[i].capture.channels_max = 2;
685 drv[i].capture.stream_name = rdai[i].capture.name;
891 686
892 rdai[i].capture.info = &info->dai_info[i].capture; 687 rdai[i].capture.info = &info->dai_info[i].capture;
893 rdai[i].capture.rdai = rdai + i; 688 rdai[i].capture.rdai = rdai + i;
@@ -933,6 +728,15 @@ static int rsnd_pcm_open(struct snd_pcm_substream *substream)
933static int rsnd_hw_params(struct snd_pcm_substream *substream, 728static int rsnd_hw_params(struct snd_pcm_substream *substream,
934 struct snd_pcm_hw_params *hw_params) 729 struct snd_pcm_hw_params *hw_params)
935{ 730{
731 struct snd_soc_dai *dai = rsnd_substream_to_dai(substream);
732 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
733 struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
734 int ret;
735
736 ret = rsnd_dai_call(hw_params, io, substream, hw_params);
737 if (ret)
738 return ret;
739
936 return snd_pcm_lib_malloc_pages(substream, 740 return snd_pcm_lib_malloc_pages(substream,
937 params_buffer_bytes(hw_params)); 741 params_buffer_bytes(hw_params));
938} 742}
@@ -1197,6 +1001,7 @@ static int rsnd_probe(struct platform_device *pdev)
1197 const struct rsnd_of_data *of_data, 1001 const struct rsnd_of_data *of_data,
1198 struct rsnd_priv *priv) = { 1002 struct rsnd_priv *priv) = {
1199 rsnd_gen_probe, 1003 rsnd_gen_probe,
1004 rsnd_dma_probe,
1200 rsnd_ssi_probe, 1005 rsnd_ssi_probe,
1201 rsnd_src_probe, 1006 rsnd_src_probe,
1202 rsnd_dvc_probe, 1007 rsnd_dvc_probe,
@@ -1290,6 +1095,12 @@ static int rsnd_remove(struct platform_device *pdev)
1290{ 1095{
1291 struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev); 1096 struct rsnd_priv *priv = dev_get_drvdata(&pdev->dev);
1292 struct rsnd_dai *rdai; 1097 struct rsnd_dai *rdai;
1098 void (*remove_func[])(struct platform_device *pdev,
1099 struct rsnd_priv *priv) = {
1100 rsnd_ssi_remove,
1101 rsnd_src_remove,
1102 rsnd_dvc_remove,
1103 };
1293 int ret = 0, i; 1104 int ret = 0, i;
1294 1105
1295 pm_runtime_disable(&pdev->dev); 1106 pm_runtime_disable(&pdev->dev);
@@ -1299,6 +1110,9 @@ static int rsnd_remove(struct platform_device *pdev)
1299 ret |= rsnd_dai_call(remove, &rdai->capture, priv); 1110 ret |= rsnd_dai_call(remove, &rdai->capture, priv);
1300 } 1111 }
1301 1112
1113 for (i = 0; i < ARRAY_SIZE(remove_func); i++)
1114 remove_func[i](pdev, priv);
1115
1302 snd_soc_unregister_component(&pdev->dev); 1116 snd_soc_unregister_component(&pdev->dev);
1303 snd_soc_unregister_platform(&pdev->dev); 1117 snd_soc_unregister_platform(&pdev->dev);
1304 1118
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
new file mode 100644
index 000000000000..ac3756f6af60
--- /dev/null
+++ b/sound/soc/sh/rcar/dma.c
@@ -0,0 +1,616 @@
1/*
2 * Renesas R-Car Audio DMAC support
3 *
4 * Copyright (C) 2015 Renesas Electronics Corp.
5 * Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/delay.h>
12#include <linux/of_dma.h>
13#include "rsnd.h"
14
15/*
16 * Audio DMAC peri peri register
17 */
18#define PDMASAR 0x00
19#define PDMADAR 0x04
20#define PDMACHCR 0x0c
21
22/* PDMACHCR */
23#define PDMACHCR_DE (1 << 0)
24
25struct rsnd_dma_ctrl {
26 void __iomem *base;
27 int dmapp_num;
28};
29
30#define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma)
31
32/*
33 * Audio DMAC
34 */
35static void rsnd_dmaen_complete(void *data)
36{
37 struct rsnd_dma *dma = (struct rsnd_dma *)data;
38 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
39 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
40
41 /*
42 * Renesas sound Gen1 needs 1 DMAC,
43 * Gen2 needs 2 DMAC.
44 * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri.
45 * But, Audio-DMAC-peri-peri doesn't have interrupt,
46 * and this driver is assuming that here.
47 *
48 * If Audio-DMAC-peri-peri has interrpt,
49 * rsnd_dai_pointer_update() will be called twice,
50 * ant it will breaks io->byte_pos
51 */
52
53 rsnd_dai_pointer_update(io, io->byte_per_period);
54}
55
56static void rsnd_dmaen_stop(struct rsnd_dma *dma)
57{
58 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
59
60 dmaengine_terminate_all(dmaen->chan);
61}
62
63static void rsnd_dmaen_start(struct rsnd_dma *dma)
64{
65 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
66 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
67 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
68 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
69 struct snd_pcm_substream *substream = io->substream;
70 struct device *dev = rsnd_priv_to_dev(priv);
71 struct dma_async_tx_descriptor *desc;
72 int is_play = rsnd_io_is_play(io);
73
74 desc = dmaengine_prep_dma_cyclic(dmaen->chan,
75 substream->runtime->dma_addr,
76 snd_pcm_lib_buffer_bytes(substream),
77 snd_pcm_lib_period_bytes(substream),
78 is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
79 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
80
81 if (!desc) {
82 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
83 return;
84 }
85
86 desc->callback = rsnd_dmaen_complete;
87 desc->callback_param = dma;
88
89 if (dmaengine_submit(desc) < 0) {
90 dev_err(dev, "dmaengine_submit() fail\n");
91 return;
92 }
93
94 dma_async_issue_pending(dmaen->chan);
95}
96
97struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
98 struct rsnd_mod *mod, char *name)
99{
100 struct dma_chan *chan;
101 struct device_node *np;
102 int i = 0;
103
104 for_each_child_of_node(of_node, np) {
105 if (i == rsnd_mod_id(mod))
106 break;
107 i++;
108 }
109
110 chan = of_dma_request_slave_channel(np, name);
111
112 of_node_put(np);
113 of_node_put(of_node);
114
115 return chan;
116}
117
118static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_mod *mod_from,
119 struct rsnd_mod *mod_to)
120{
121 if ((!mod_from && !mod_to) ||
122 (mod_from && mod_to))
123 return NULL;
124
125 if (mod_from)
126 return rsnd_mod_dma_req(mod_from);
127 else
128 return rsnd_mod_dma_req(mod_to);
129}
130
131static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
132 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
133{
134 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
135 struct device *dev = rsnd_priv_to_dev(priv);
136 struct dma_slave_config cfg = {};
137 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
138 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
139 int is_play = rsnd_io_is_play(io);
140 int ret;
141
142 if (dmaen->chan) {
143 dev_err(dev, "it already has dma channel\n");
144 return -EIO;
145 }
146
147 if (dev->of_node) {
148 dmaen->chan = rsnd_dmaen_request_channel(mod_from, mod_to);
149 } else {
150 dma_cap_mask_t mask;
151
152 dma_cap_zero(mask);
153 dma_cap_set(DMA_SLAVE, mask);
154
155 dmaen->chan = dma_request_channel(mask, shdma_chan_filter,
156 (void *)id);
157 }
158 if (IS_ERR_OR_NULL(dmaen->chan)) {
159 dev_err(dev, "can't get dma channel\n");
160 goto rsnd_dma_channel_err;
161 }
162
163 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
164 cfg.src_addr = dma->src_addr;
165 cfg.dst_addr = dma->dst_addr;
166 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
167 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
168
169 dev_dbg(dev, "dma : %pad -> %pad\n",
170 &cfg.src_addr, &cfg.dst_addr);
171
172 ret = dmaengine_slave_config(dmaen->chan, &cfg);
173 if (ret < 0)
174 goto rsnd_dma_init_err;
175
176 return 0;
177
178rsnd_dma_init_err:
179 rsnd_dma_quit(dma);
180rsnd_dma_channel_err:
181
182 /*
183 * DMA failed. try to PIO mode
184 * see
185 * rsnd_ssi_fallback()
186 * rsnd_rdai_continuance_probe()
187 */
188 return -EAGAIN;
189}
190
191static void rsnd_dmaen_quit(struct rsnd_dma *dma)
192{
193 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
194
195 if (dmaen->chan)
196 dma_release_channel(dmaen->chan);
197
198 dmaen->chan = NULL;
199}
200
201static struct rsnd_dma_ops rsnd_dmaen_ops = {
202 .start = rsnd_dmaen_start,
203 .stop = rsnd_dmaen_stop,
204 .init = rsnd_dmaen_init,
205 .quit = rsnd_dmaen_quit,
206};
207
208/*
209 * Audio DMAC peri peri
210 */
211static const u8 gen2_id_table_ssiu[] = {
212 0x00, /* SSI00 */
213 0x04, /* SSI10 */
214 0x08, /* SSI20 */
215 0x0c, /* SSI3 */
216 0x0d, /* SSI4 */
217 0x0e, /* SSI5 */
218 0x0f, /* SSI6 */
219 0x10, /* SSI7 */
220 0x11, /* SSI8 */
221 0x12, /* SSI90 */
222};
223static const u8 gen2_id_table_scu[] = {
224 0x2d, /* SCU_SRCI0 */
225 0x2e, /* SCU_SRCI1 */
226 0x2f, /* SCU_SRCI2 */
227 0x30, /* SCU_SRCI3 */
228 0x31, /* SCU_SRCI4 */
229 0x32, /* SCU_SRCI5 */
230 0x33, /* SCU_SRCI6 */
231 0x34, /* SCU_SRCI7 */
232 0x35, /* SCU_SRCI8 */
233 0x36, /* SCU_SRCI9 */
234};
235static const u8 gen2_id_table_cmd[] = {
236 0x37, /* SCU_CMD0 */
237 0x38, /* SCU_CMD1 */
238};
239
240static u32 rsnd_dmapp_get_id(struct rsnd_mod *mod)
241{
242 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
243 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
244 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
245 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
246 const u8 *entry = NULL;
247 int id = rsnd_mod_id(mod);
248 int size = 0;
249
250 if (mod == ssi) {
251 entry = gen2_id_table_ssiu;
252 size = ARRAY_SIZE(gen2_id_table_ssiu);
253 } else if (mod == src) {
254 entry = gen2_id_table_scu;
255 size = ARRAY_SIZE(gen2_id_table_scu);
256 } else if (mod == dvc) {
257 entry = gen2_id_table_cmd;
258 size = ARRAY_SIZE(gen2_id_table_cmd);
259 }
260
261 if (!entry)
262 return 0xFF;
263
264 if (size <= id)
265 return 0xFF;
266
267 return entry[id];
268}
269
270static u32 rsnd_dmapp_get_chcr(struct rsnd_mod *mod_from,
271 struct rsnd_mod *mod_to)
272{
273 return (rsnd_dmapp_get_id(mod_from) << 24) +
274 (rsnd_dmapp_get_id(mod_to) << 16);
275}
276
277#define rsnd_dmapp_addr(dmac, dma, reg) \
278 (dmac->base + 0x20 + reg + \
279 (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id))
280static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg)
281{
282 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
283 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
284 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
285 struct device *dev = rsnd_priv_to_dev(priv);
286
287 dev_dbg(dev, "w %p : %08x\n", rsnd_dmapp_addr(dmac, dma, reg), data);
288
289 iowrite32(data, rsnd_dmapp_addr(dmac, dma, reg));
290}
291
292static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg)
293{
294 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
295 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
296 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
297
298 return ioread32(rsnd_dmapp_addr(dmac, dma, reg));
299}
300
301static void rsnd_dmapp_stop(struct rsnd_dma *dma)
302{
303 int i;
304
305 rsnd_dmapp_write(dma, 0, PDMACHCR);
306
307 for (i = 0; i < 1024; i++) {
308 if (0 == rsnd_dmapp_read(dma, PDMACHCR))
309 return;
310 udelay(1);
311 }
312}
313
314static void rsnd_dmapp_start(struct rsnd_dma *dma)
315{
316 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
317
318 rsnd_dmapp_write(dma, dma->src_addr, PDMASAR);
319 rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR);
320 rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR);
321}
322
323static int rsnd_dmapp_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
324 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
325{
326 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
327 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
328 struct device *dev = rsnd_priv_to_dev(priv);
329
330 dmapp->dmapp_id = dmac->dmapp_num;
331 dmapp->chcr = rsnd_dmapp_get_chcr(mod_from, mod_to) | PDMACHCR_DE;
332
333 dmac->dmapp_num++;
334
335 rsnd_dmapp_stop(dma);
336
337 dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n",
338 dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr);
339
340 return 0;
341}
342
343static struct rsnd_dma_ops rsnd_dmapp_ops = {
344 .start = rsnd_dmapp_start,
345 .stop = rsnd_dmapp_stop,
346 .init = rsnd_dmapp_init,
347 .quit = rsnd_dmapp_stop,
348};
349
350/*
351 * Common DMAC Interface
352 */
353
354/*
355 * DMA read/write register offset
356 *
357 * RSND_xxx_I_N for Audio DMAC input
358 * RSND_xxx_O_N for Audio DMAC output
359 * RSND_xxx_I_P for Audio DMAC peri peri input
360 * RSND_xxx_O_P for Audio DMAC peri peri output
361 *
362 * ex) R-Car H2 case
363 * mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out
364 * SSI : 0xec541000 / 0xec241008 / 0xec24100c
365 * SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000
366 * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
367 * CMD : 0xec500000 / / 0xec008000 0xec308000
368 */
369#define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
370#define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
371
372#define RDMA_SSIU_I_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
373#define RDMA_SSIU_O_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
374
375#define RDMA_SSIU_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
376#define RDMA_SSIU_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
377
378#define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i))
379#define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i))
380
381#define RDMA_SRC_I_P(addr, i) (addr ##_reg - 0x00200000 + (0x400 * i))
382#define RDMA_SRC_O_P(addr, i) (addr ##_reg - 0x001fc000 + (0x400 * i))
383
384#define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i))
385#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i))
386
387static dma_addr_t
388rsnd_gen2_dma_addr(struct rsnd_priv *priv,
389 struct rsnd_mod *mod,
390 int is_play, int is_from)
391{
392 struct device *dev = rsnd_priv_to_dev(priv);
393 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
394 phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI);
395 phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU);
396 int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
397 int use_src = !!rsnd_io_to_mod_src(io);
398 int use_dvc = !!rsnd_io_to_mod_dvc(io);
399 int id = rsnd_mod_id(mod);
400 struct dma_addr {
401 dma_addr_t out_addr;
402 dma_addr_t in_addr;
403 } dma_addrs[3][2][3] = {
404 /* SRC */
405 {{{ 0, 0 },
406 /* Capture */
407 { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) },
408 { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } },
409 /* Playback */
410 {{ 0, 0, },
411 { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) },
412 { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) } }
413 },
414 /* SSI */
415 /* Capture */
416 {{{ RDMA_SSI_O_N(ssi, id), 0 },
417 { RDMA_SSIU_O_P(ssi, id), 0 },
418 { RDMA_SSIU_O_P(ssi, id), 0 } },
419 /* Playback */
420 {{ 0, RDMA_SSI_I_N(ssi, id) },
421 { 0, RDMA_SSIU_I_P(ssi, id) },
422 { 0, RDMA_SSIU_I_P(ssi, id) } }
423 },
424 /* SSIU */
425 /* Capture */
426 {{{ RDMA_SSIU_O_N(ssi, id), 0 },
427 { RDMA_SSIU_O_P(ssi, id), 0 },
428 { RDMA_SSIU_O_P(ssi, id), 0 } },
429 /* Playback */
430 {{ 0, RDMA_SSIU_I_N(ssi, id) },
431 { 0, RDMA_SSIU_I_P(ssi, id) },
432 { 0, RDMA_SSIU_I_P(ssi, id) } } },
433 };
434
435 /* it shouldn't happen */
436 if (use_dvc && !use_src)
437 dev_err(dev, "DVC is selected without SRC\n");
438
439 /* use SSIU or SSI ? */
440 if (is_ssi && rsnd_ssi_use_busif(mod))
441 is_ssi++;
442
443 return (is_from) ?
444 dma_addrs[is_ssi][is_play][use_src + use_dvc].out_addr :
445 dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr;
446}
447
448static dma_addr_t rsnd_dma_addr(struct rsnd_priv *priv,
449 struct rsnd_mod *mod,
450 int is_play, int is_from)
451{
452 /*
453 * gen1 uses default DMA addr
454 */
455 if (rsnd_is_gen1(priv))
456 return 0;
457
458 if (!mod)
459 return 0;
460
461 return rsnd_gen2_dma_addr(priv, mod, is_play, is_from);
462}
463
464#define MOD_MAX 4 /* MEM/SSI/SRC/DVC */
465static void rsnd_dma_of_path(struct rsnd_dma *dma,
466 int is_play,
467 struct rsnd_mod **mod_from,
468 struct rsnd_mod **mod_to)
469{
470 struct rsnd_mod *this = rsnd_dma_to_mod(dma);
471 struct rsnd_dai_stream *io = rsnd_mod_to_io(this);
472 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
473 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
474 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
475 struct rsnd_mod *mod[MOD_MAX];
476 int i, index;
477
478
479 for (i = 0; i < MOD_MAX; i++)
480 mod[i] = NULL;
481
482 /*
483 * in play case...
484 *
485 * src -> dst
486 *
487 * mem -> SSI
488 * mem -> SRC -> SSI
489 * mem -> SRC -> DVC -> SSI
490 */
491 mod[0] = NULL; /* for "mem" */
492 index = 1;
493 for (i = 1; i < MOD_MAX; i++) {
494 if (!src) {
495 mod[i] = ssi;
496 } else if (!dvc) {
497 mod[i] = src;
498 src = NULL;
499 } else {
500 if ((!is_play) && (this == src))
501 this = dvc;
502
503 mod[i] = (is_play) ? src : dvc;
504 i++;
505 mod[i] = (is_play) ? dvc : src;
506 src = NULL;
507 dvc = NULL;
508 }
509
510 if (mod[i] == this)
511 index = i;
512
513 if (mod[i] == ssi)
514 break;
515 }
516
517 if (is_play) {
518 *mod_from = mod[index - 1];
519 *mod_to = mod[index];
520 } else {
521 *mod_from = mod[index];
522 *mod_to = mod[index - 1];
523 }
524}
525
526void rsnd_dma_stop(struct rsnd_dma *dma)
527{
528 dma->ops->stop(dma);
529}
530
531void rsnd_dma_start(struct rsnd_dma *dma)
532{
533 dma->ops->start(dma);
534}
535
536void rsnd_dma_quit(struct rsnd_dma *dma)
537{
538 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
539 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
540 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
541
542 if (!dmac)
543 return;
544
545 dma->ops->quit(dma);
546}
547
548int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id)
549{
550 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
551 struct rsnd_mod *mod_from;
552 struct rsnd_mod *mod_to;
553 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
554 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
555 int is_play = rsnd_io_is_play(io);
556
557 /*
558 * DMA failed. try to PIO mode
559 * see
560 * rsnd_ssi_fallback()
561 * rsnd_rdai_continuance_probe()
562 */
563 if (!dmac)
564 return -EAGAIN;
565
566 rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to);
567
568 dma->src_addr = rsnd_dma_addr(priv, mod_from, is_play, 1);
569 dma->dst_addr = rsnd_dma_addr(priv, mod_to, is_play, 0);
570
571 /* for Gen2 */
572 if (mod_from && mod_to)
573 dma->ops = &rsnd_dmapp_ops;
574 else
575 dma->ops = &rsnd_dmaen_ops;
576
577 /* for Gen1, overwrite */
578 if (rsnd_is_gen1(priv))
579 dma->ops = &rsnd_dmaen_ops;
580
581 return dma->ops->init(priv, dma, id, mod_from, mod_to);
582}
583
584int rsnd_dma_probe(struct platform_device *pdev,
585 const struct rsnd_of_data *of_data,
586 struct rsnd_priv *priv)
587{
588 struct device *dev = rsnd_priv_to_dev(priv);
589 struct rsnd_dma_ctrl *dmac;
590 struct resource *res;
591
592 /*
593 * for Gen1
594 */
595 if (rsnd_is_gen1(priv))
596 return 0;
597
598 /*
599 * for Gen2
600 */
601 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audmapp");
602 dmac = devm_kzalloc(dev, sizeof(*dmac), GFP_KERNEL);
603 if (!dmac || !res) {
604 dev_err(dev, "dma allocate failed\n");
605 return 0; /* it will be PIO mode */
606 }
607
608 dmac->dmapp_num = 0;
609 dmac->base = devm_ioremap_resource(dev, res);
610 if (IS_ERR(dmac->base))
611 return PTR_ERR(dmac->base);
612
613 priv->dma = dmac;
614
615 return 0;
616}
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index d7f9ed959c4e..e5fcb062ad77 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -24,6 +24,9 @@ struct rsnd_dvc {
24 struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */ 24 struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */
25}; 25};
26 26
27#define rsnd_dvc_of_node(priv) \
28 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc")
29
27#define rsnd_mod_to_dvc(_mod) \ 30#define rsnd_mod_to_dvc(_mod) \
28 container_of((_mod), struct rsnd_dvc, mod) 31 container_of((_mod), struct rsnd_dvc, mod)
29 32
@@ -33,7 +36,7 @@ struct rsnd_dvc {
33 ((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \ 36 ((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \
34 i++) 37 i++)
35 38
36static const char const *dvc_ramp_rate[] = { 39static const char * const dvc_ramp_rate[] = {
37 "128 dB/1 step", /* 00000 */ 40 "128 dB/1 step", /* 00000 */
38 "64 dB/1 step", /* 00001 */ 41 "64 dB/1 step", /* 00001 */
39 "32 dB/1 step", /* 00010 */ 42 "32 dB/1 step", /* 00010 */
@@ -116,17 +119,6 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
116 rsnd_mod_write(mod, DVC_DVUER, 1); 119 rsnd_mod_write(mod, DVC_DVUER, 1);
117} 120}
118 121
119static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod,
120 struct rsnd_priv *priv)
121{
122 struct device *dev = rsnd_priv_to_dev(priv);
123
124 dev_dbg(dev, "%s[%d] (Gen2) is probed\n",
125 rsnd_mod_name(mod), rsnd_mod_id(mod));
126
127 return 0;
128}
129
130static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, 122static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod,
131 struct rsnd_priv *priv) 123 struct rsnd_priv *priv)
132{ 124{
@@ -269,9 +261,17 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
269 return 0; 261 return 0;
270} 262}
271 263
264static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_mod *mod)
265{
266 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
267
268 return rsnd_dma_request_channel(rsnd_dvc_of_node(priv),
269 mod, "tx");
270}
271
272static struct rsnd_mod_ops rsnd_dvc_ops = { 272static struct rsnd_mod_ops rsnd_dvc_ops = {
273 .name = DVC_NAME, 273 .name = DVC_NAME,
274 .probe = rsnd_dvc_probe_gen2, 274 .dma_req = rsnd_dvc_dma_req,
275 .remove = rsnd_dvc_remove_gen2, 275 .remove = rsnd_dvc_remove_gen2,
276 .init = rsnd_dvc_init, 276 .init = rsnd_dvc_init,
277 .quit = rsnd_dvc_quit, 277 .quit = rsnd_dvc_quit,
@@ -333,7 +333,7 @@ int rsnd_dvc_probe(struct platform_device *pdev,
333 struct rsnd_dvc *dvc; 333 struct rsnd_dvc *dvc;
334 struct clk *clk; 334 struct clk *clk;
335 char name[RSND_DVC_NAME_SIZE]; 335 char name[RSND_DVC_NAME_SIZE];
336 int i, nr; 336 int i, nr, ret;
337 337
338 rsnd_of_parse_dvc(pdev, of_data, priv); 338 rsnd_of_parse_dvc(pdev, of_data, priv);
339 339
@@ -366,11 +366,22 @@ int rsnd_dvc_probe(struct platform_device *pdev,
366 366
367 dvc->info = &info->dvc_info[i]; 367 dvc->info = &info->dvc_info[i];
368 368
369 rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops, 369 ret = rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops,
370 clk, RSND_MOD_DVC, i); 370 clk, RSND_MOD_DVC, i);
371 371 if (ret)
372 dev_dbg(dev, "CMD%d probed\n", i); 372 return ret;
373 } 373 }
374 374
375 return 0; 375 return 0;
376} 376}
377
378void rsnd_dvc_remove(struct platform_device *pdev,
379 struct rsnd_priv *priv)
380{
381 struct rsnd_dvc *dvc;
382 int i;
383
384 for_each_rsnd_dvc(dvc, priv, i) {
385 rsnd_mod_quit(&dvc->mod);
386 }
387}
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index de0685f2abae..8c7dc51b1c4f 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -28,6 +28,7 @@ struct rsnd_gen {
28 28
29 struct regmap *regmap[RSND_BASE_MAX]; 29 struct regmap *regmap[RSND_BASE_MAX];
30 struct regmap_field *regs[RSND_REG_MAX]; 30 struct regmap_field *regs[RSND_REG_MAX];
31 phys_addr_t res[RSND_REG_MAX];
31}; 32};
32 33
33#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) 34#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen)
@@ -118,11 +119,19 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
118 mask, data); 119 mask, data);
119} 120}
120 121
121#define rsnd_gen_regmap_init(priv, id_size, reg_id, conf) \ 122phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id)
122 _rsnd_gen_regmap_init(priv, id_size, reg_id, conf, ARRAY_SIZE(conf)) 123{
124 struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
125
126 return gen->res[reg_id];
127}
128
129#define rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf) \
130 _rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf, ARRAY_SIZE(conf))
123static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, 131static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
124 int id_size, 132 int id_size,
125 int reg_id, 133 int reg_id,
134 const char *name,
126 struct rsnd_regmap_field_conf *conf, 135 struct rsnd_regmap_field_conf *conf,
127 int conf_size) 136 int conf_size)
128{ 137{
@@ -141,8 +150,11 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
141 regc.reg_bits = 32; 150 regc.reg_bits = 32;
142 regc.val_bits = 32; 151 regc.val_bits = 32;
143 regc.reg_stride = 4; 152 regc.reg_stride = 4;
153 regc.name = name;
144 154
145 res = platform_get_resource(pdev, IORESOURCE_MEM, reg_id); 155 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
156 if (!res)
157 res = platform_get_resource(pdev, IORESOURCE_MEM, reg_id);
146 if (!res) 158 if (!res)
147 return -ENODEV; 159 return -ENODEV;
148 160
@@ -156,6 +168,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
156 168
157 gen->base[reg_id] = base; 169 gen->base[reg_id] = base;
158 gen->regmap[reg_id] = regmap; 170 gen->regmap[reg_id] = regmap;
171 gen->res[reg_id] = res->start;
159 172
160 for (i = 0; i < conf_size; i++) { 173 for (i = 0; i < conf_size; i++) {
161 174
@@ -176,125 +189,11 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
176} 189}
177 190
178/* 191/*
179 * DMA read/write register offset
180 *
181 * RSND_xxx_I_N for Audio DMAC input
182 * RSND_xxx_O_N for Audio DMAC output
183 * RSND_xxx_I_P for Audio DMAC peri peri input
184 * RSND_xxx_O_P for Audio DMAC peri peri output
185 *
186 * ex) R-Car H2 case
187 * mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out
188 * SSI : 0xec541000 / 0xec241008 / 0xec24100c
189 * SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000
190 * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
191 * CMD : 0xec500000 / / 0xec008000 0xec308000
192 */
193#define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
194#define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
195
196#define RDMA_SSIU_I_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
197#define RDMA_SSIU_O_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
198
199#define RDMA_SSIU_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
200#define RDMA_SSIU_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
201
202#define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i))
203#define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i))
204
205#define RDMA_SRC_I_P(addr, i) (addr ##_reg - 0x00200000 + (0x400 * i))
206#define RDMA_SRC_O_P(addr, i) (addr ##_reg - 0x001fc000 + (0x400 * i))
207
208#define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i))
209#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i))
210
211static dma_addr_t
212rsnd_gen2_dma_addr(struct rsnd_priv *priv,
213 struct rsnd_mod *mod,
214 int is_play, int is_from)
215{
216 struct platform_device *pdev = rsnd_priv_to_pdev(priv);
217 struct device *dev = rsnd_priv_to_dev(priv);
218 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
219 dma_addr_t ssi_reg = platform_get_resource(pdev,
220 IORESOURCE_MEM, RSND_GEN2_SSI)->start;
221 dma_addr_t src_reg = platform_get_resource(pdev,
222 IORESOURCE_MEM, RSND_GEN2_SCU)->start;
223 int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
224 int use_src = !!rsnd_io_to_mod_src(io);
225 int use_dvc = !!rsnd_io_to_mod_dvc(io);
226 int id = rsnd_mod_id(mod);
227 struct dma_addr {
228 dma_addr_t out_addr;
229 dma_addr_t in_addr;
230 } dma_addrs[3][2][3] = {
231 /* SRC */
232 {{{ 0, 0 },
233 /* Capture */
234 { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) },
235 { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } },
236 /* Playback */
237 {{ 0, 0, },
238 { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) },
239 { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) } }
240 },
241 /* SSI */
242 /* Capture */
243 {{{ RDMA_SSI_O_N(ssi, id), 0 },
244 { RDMA_SSIU_O_P(ssi, id), 0 },
245 { RDMA_SSIU_O_P(ssi, id), 0 } },
246 /* Playback */
247 {{ 0, RDMA_SSI_I_N(ssi, id) },
248 { 0, RDMA_SSIU_I_P(ssi, id) },
249 { 0, RDMA_SSIU_I_P(ssi, id) } }
250 },
251 /* SSIU */
252 /* Capture */
253 {{{ RDMA_SSIU_O_N(ssi, id), 0 },
254 { RDMA_SSIU_O_P(ssi, id), 0 },
255 { RDMA_SSIU_O_P(ssi, id), 0 } },
256 /* Playback */
257 {{ 0, RDMA_SSIU_I_N(ssi, id) },
258 { 0, RDMA_SSIU_I_P(ssi, id) },
259 { 0, RDMA_SSIU_I_P(ssi, id) } } },
260 };
261
262 /* it shouldn't happen */
263 if (use_dvc && !use_src)
264 dev_err(dev, "DVC is selected without SRC\n");
265
266 /* use SSIU or SSI ? */
267 if (is_ssi && (0 == strcmp(rsnd_mod_dma_name(mod), "ssiu")))
268 is_ssi++;
269
270 return (is_from) ?
271 dma_addrs[is_ssi][is_play][use_src + use_dvc].out_addr :
272 dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr;
273}
274
275dma_addr_t rsnd_gen_dma_addr(struct rsnd_priv *priv,
276 struct rsnd_mod *mod,
277 int is_play, int is_from)
278{
279 /*
280 * gen1 uses default DMA addr
281 */
282 if (rsnd_is_gen1(priv))
283 return 0;
284
285 if (!mod)
286 return 0;
287
288 return rsnd_gen2_dma_addr(priv, mod, is_play, is_from);
289}
290
291/*
292 * Gen2 192 * Gen2
293 */ 193 */
294static int rsnd_gen2_probe(struct platform_device *pdev, 194static int rsnd_gen2_probe(struct platform_device *pdev,
295 struct rsnd_priv *priv) 195 struct rsnd_priv *priv)
296{ 196{
297 struct device *dev = rsnd_priv_to_dev(priv);
298 struct rsnd_regmap_field_conf conf_ssiu[] = { 197 struct rsnd_regmap_field_conf conf_ssiu[] = {
299 RSND_GEN_S_REG(SSI_MODE0, 0x800), 198 RSND_GEN_S_REG(SSI_MODE0, 0x800),
300 RSND_GEN_S_REG(SSI_MODE1, 0x804), 199 RSND_GEN_S_REG(SSI_MODE1, 0x804),
@@ -368,18 +267,16 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
368 int ret_adg; 267 int ret_adg;
369 int ret_ssi; 268 int ret_ssi;
370 269
371 ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSIU, conf_ssiu); 270 ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSIU, "ssiu", conf_ssiu);
372 ret_scu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SCU, conf_scu); 271 ret_scu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SCU, "scu", conf_scu);
373 ret_adg = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_ADG, conf_adg); 272 ret_adg = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_ADG, "adg", conf_adg);
374 ret_ssi = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSI, conf_ssi); 273 ret_ssi = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSI, "ssi", conf_ssi);
375 if (ret_ssiu < 0 || 274 if (ret_ssiu < 0 ||
376 ret_scu < 0 || 275 ret_scu < 0 ||
377 ret_adg < 0 || 276 ret_adg < 0 ||
378 ret_ssi < 0) 277 ret_ssi < 0)
379 return ret_ssiu | ret_scu | ret_adg | ret_ssi; 278 return ret_ssiu | ret_scu | ret_adg | ret_ssi;
380 279
381 dev_dbg(dev, "Gen2 is probed\n");
382
383 return 0; 280 return 0;
384} 281}
385 282
@@ -390,7 +287,6 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
390static int rsnd_gen1_probe(struct platform_device *pdev, 287static int rsnd_gen1_probe(struct platform_device *pdev,
391 struct rsnd_priv *priv) 288 struct rsnd_priv *priv)
392{ 289{
393 struct device *dev = rsnd_priv_to_dev(priv);
394 struct rsnd_regmap_field_conf conf_sru[] = { 290 struct rsnd_regmap_field_conf conf_sru[] = {
395 RSND_GEN_S_REG(SRC_ROUTE_SEL, 0x00), 291 RSND_GEN_S_REG(SRC_ROUTE_SEL, 0x00),
396 RSND_GEN_S_REG(SRC_TMG_SEL0, 0x08), 292 RSND_GEN_S_REG(SRC_TMG_SEL0, 0x08),
@@ -440,16 +336,14 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
440 int ret_adg; 336 int ret_adg;
441 int ret_ssi; 337 int ret_ssi;
442 338
443 ret_sru = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SRU, conf_sru); 339 ret_sru = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SRU, "sru", conf_sru);
444 ret_adg = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, conf_adg); 340 ret_adg = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, "adg", conf_adg);
445 ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, conf_ssi); 341 ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, "ssi", conf_ssi);
446 if (ret_sru < 0 || 342 if (ret_sru < 0 ||
447 ret_adg < 0 || 343 ret_adg < 0 ||
448 ret_ssi < 0) 344 ret_ssi < 0)
449 return ret_sru | ret_adg | ret_ssi; 345 return ret_sru | ret_adg | ret_ssi;
450 346
451 dev_dbg(dev, "Gen1 is probed\n");
452
453 return 0; 347 return 0;
454} 348}
455 349
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index e7914bd610e2..4e6de6804cfb 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -170,21 +170,47 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod);
170/* 170/*
171 * R-Car DMA 171 * R-Car DMA
172 */ 172 */
173struct rsnd_dma { 173struct rsnd_dma;
174 struct sh_dmae_slave slave; 174struct rsnd_dma_ops {
175 void (*start)(struct rsnd_dma *dma);
176 void (*stop)(struct rsnd_dma *dma);
177 int (*init)(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
178 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to);
179 void (*quit)(struct rsnd_dma *dma);
180};
181
182struct rsnd_dmaen {
175 struct dma_chan *chan; 183 struct dma_chan *chan;
176 enum dma_transfer_direction dir;
177 dma_addr_t addr;
178}; 184};
179 185
186struct rsnd_dmapp {
187 int dmapp_id;
188 u32 chcr;
189};
190
191struct rsnd_dma {
192 struct rsnd_dma_ops *ops;
193 dma_addr_t src_addr;
194 dma_addr_t dst_addr;
195 union {
196 struct rsnd_dmaen en;
197 struct rsnd_dmapp pp;
198 } dma;
199};
200#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
201#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
202
180void rsnd_dma_start(struct rsnd_dma *dma); 203void rsnd_dma_start(struct rsnd_dma *dma);
181void rsnd_dma_stop(struct rsnd_dma *dma); 204void rsnd_dma_stop(struct rsnd_dma *dma);
182int rsnd_dma_available(struct rsnd_dma *dma); 205int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id);
183int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, 206void rsnd_dma_quit(struct rsnd_dma *dma);
184 int is_play, int id); 207int rsnd_dma_probe(struct platform_device *pdev,
185void rsnd_dma_quit(struct rsnd_priv *priv, 208 const struct rsnd_of_data *of_data,
186 struct rsnd_dma *dma); 209 struct rsnd_priv *priv);
210struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
211 struct rsnd_mod *mod, char *name);
187 212
213#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
188 214
189/* 215/*
190 * R-Car sound mod 216 * R-Car sound mod
@@ -198,7 +224,7 @@ enum rsnd_mod_type {
198 224
199struct rsnd_mod_ops { 225struct rsnd_mod_ops {
200 char *name; 226 char *name;
201 char* (*dma_name)(struct rsnd_mod *mod); 227 struct dma_chan* (*dma_req)(struct rsnd_mod *mod);
202 int (*probe)(struct rsnd_mod *mod, 228 int (*probe)(struct rsnd_mod *mod,
203 struct rsnd_priv *priv); 229 struct rsnd_priv *priv);
204 int (*remove)(struct rsnd_mod *mod, 230 int (*remove)(struct rsnd_mod *mod,
@@ -213,6 +239,9 @@ struct rsnd_mod_ops {
213 struct rsnd_priv *priv); 239 struct rsnd_priv *priv);
214 int (*pcm_new)(struct rsnd_mod *mod, 240 int (*pcm_new)(struct rsnd_mod *mod,
215 struct snd_soc_pcm_runtime *rtd); 241 struct snd_soc_pcm_runtime *rtd);
242 int (*hw_params)(struct rsnd_mod *mod,
243 struct snd_pcm_substream *substream,
244 struct snd_pcm_hw_params *hw_params);
216 int (*fallback)(struct rsnd_mod *mod, 245 int (*fallback)(struct rsnd_mod *mod,
217 struct rsnd_priv *priv); 246 struct rsnd_priv *priv);
218}; 247};
@@ -236,6 +265,9 @@ struct rsnd_mod {
236 * 2 0: start 1: stop 265 * 2 0: start 1: stop
237 * 3 0: pcm_new 266 * 3 0: pcm_new
238 * 4 0: fallback 267 * 4 0: fallback
268 *
269 * 31 bit is always called (see __rsnd_mod_call)
270 * 31 0: hw_params
239 */ 271 */
240#define __rsnd_mod_shift_probe 0 272#define __rsnd_mod_shift_probe 0
241#define __rsnd_mod_shift_remove 0 273#define __rsnd_mod_shift_remove 0
@@ -245,6 +277,7 @@ struct rsnd_mod {
245#define __rsnd_mod_shift_stop 2 277#define __rsnd_mod_shift_stop 2
246#define __rsnd_mod_shift_pcm_new 3 278#define __rsnd_mod_shift_pcm_new 3
247#define __rsnd_mod_shift_fallback 4 279#define __rsnd_mod_shift_fallback 4
280#define __rsnd_mod_shift_hw_params 31 /* always called */
248 281
249#define __rsnd_mod_call_probe 0 282#define __rsnd_mod_call_probe 0
250#define __rsnd_mod_call_remove 1 283#define __rsnd_mod_call_remove 1
@@ -254,28 +287,30 @@ struct rsnd_mod {
254#define __rsnd_mod_call_stop 1 287#define __rsnd_mod_call_stop 1
255#define __rsnd_mod_call_pcm_new 0 288#define __rsnd_mod_call_pcm_new 0
256#define __rsnd_mod_call_fallback 0 289#define __rsnd_mod_call_fallback 0
290#define __rsnd_mod_call_hw_params 0
257 291
258#define rsnd_mod_to_priv(mod) (rsnd_io_to_priv(rsnd_mod_to_io(mod))) 292#define rsnd_mod_to_priv(mod) (rsnd_io_to_priv(rsnd_mod_to_io(mod)))
259#define rsnd_mod_to_dma(mod) (&(mod)->dma) 293#define rsnd_mod_to_dma(mod) (&(mod)->dma)
260#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
261#define rsnd_mod_to_io(mod) ((mod)->io) 294#define rsnd_mod_to_io(mod) ((mod)->io)
262#define rsnd_mod_id(mod) ((mod)->id) 295#define rsnd_mod_id(mod) ((mod)->id)
263#define rsnd_mod_hw_start(mod) clk_prepare_enable((mod)->clk) 296#define rsnd_mod_hw_start(mod) clk_enable((mod)->clk)
264#define rsnd_mod_hw_stop(mod) clk_disable_unprepare((mod)->clk) 297#define rsnd_mod_hw_stop(mod) clk_disable((mod)->clk)
265 298
266void rsnd_mod_init(struct rsnd_mod *mod, 299int rsnd_mod_init(struct rsnd_mod *mod,
267 struct rsnd_mod_ops *ops, 300 struct rsnd_mod_ops *ops,
268 struct clk *clk, 301 struct clk *clk,
269 enum rsnd_mod_type type, 302 enum rsnd_mod_type type,
270 int id); 303 int id);
304void rsnd_mod_quit(struct rsnd_mod *mod);
271char *rsnd_mod_name(struct rsnd_mod *mod); 305char *rsnd_mod_name(struct rsnd_mod *mod);
272char *rsnd_mod_dma_name(struct rsnd_mod *mod); 306struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod);
273 307
274/* 308/*
275 * R-Car sound DAI 309 * R-Car sound DAI
276 */ 310 */
277#define RSND_DAI_NAME_SIZE 16 311#define RSND_DAI_NAME_SIZE 16
278struct rsnd_dai_stream { 312struct rsnd_dai_stream {
313 char name[RSND_DAI_NAME_SIZE];
279 struct snd_pcm_substream *substream; 314 struct snd_pcm_substream *substream;
280 struct rsnd_mod *mod[RSND_MOD_MAX]; 315 struct rsnd_mod *mod[RSND_MOD_MAX];
281 struct rsnd_dai_path_info *info; /* rcar_snd.h */ 316 struct rsnd_dai_path_info *info; /* rcar_snd.h */
@@ -331,9 +366,7 @@ int rsnd_gen_probe(struct platform_device *pdev,
331void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, 366void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
332 struct rsnd_mod *mod, 367 struct rsnd_mod *mod,
333 enum rsnd_reg reg); 368 enum rsnd_reg reg);
334dma_addr_t rsnd_gen_dma_addr(struct rsnd_priv *priv, 369phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id);
335 struct rsnd_mod *mod,
336 int is_play, int is_from);
337 370
338#define rsnd_is_gen1(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1) 371#define rsnd_is_gen1(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1)
339#define rsnd_is_gen2(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN2) 372#define rsnd_is_gen2(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN2)
@@ -389,6 +422,11 @@ struct rsnd_priv {
389 void *adg; 422 void *adg;
390 423
391 /* 424 /*
425 * below value will be filled on rsnd_dma_probe()
426 */
427 void *dma;
428
429 /*
392 * below value will be filled on rsnd_ssi_probe() 430 * below value will be filled on rsnd_ssi_probe()
393 */ 431 */
394 void *ssi; 432 void *ssi;
@@ -414,19 +452,6 @@ struct rsnd_priv {
414#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags) 452#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags)
415#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags) 453#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags)
416 454
417#define rsnd_info_is_playback(priv, type) \
418({ \
419 struct rcar_snd_info *info = rsnd_priv_to_info(priv); \
420 int i, is_play = 0; \
421 for (i = 0; i < info->dai_info_nr; i++) { \
422 if (info->dai_info[i].playback.type == (type)->info) { \
423 is_play = 1; \
424 break; \
425 } \
426 } \
427 is_play; \
428})
429
430/* 455/*
431 * rsnd_kctrl 456 * rsnd_kctrl
432 */ 457 */
@@ -480,6 +505,8 @@ int rsnd_kctrl_new_e(struct rsnd_mod *mod,
480int rsnd_src_probe(struct platform_device *pdev, 505int rsnd_src_probe(struct platform_device *pdev,
481 const struct rsnd_of_data *of_data, 506 const struct rsnd_of_data *of_data,
482 struct rsnd_priv *priv); 507 struct rsnd_priv *priv);
508void rsnd_src_remove(struct platform_device *pdev,
509 struct rsnd_priv *priv);
483struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id); 510struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id);
484unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, 511unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
485 struct rsnd_dai_stream *io, 512 struct rsnd_dai_stream *io,
@@ -498,9 +525,12 @@ int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod);
498int rsnd_ssi_probe(struct platform_device *pdev, 525int rsnd_ssi_probe(struct platform_device *pdev,
499 const struct rsnd_of_data *of_data, 526 const struct rsnd_of_data *of_data,
500 struct rsnd_priv *priv); 527 struct rsnd_priv *priv);
528void rsnd_ssi_remove(struct platform_device *pdev,
529 struct rsnd_priv *priv);
501struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); 530struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
502int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); 531int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
503int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); 532int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);
533int rsnd_ssi_use_busif(struct rsnd_mod *mod);
504 534
505/* 535/*
506 * R-Car DVC 536 * R-Car DVC
diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c
new file mode 100644
index 000000000000..a68517afe615
--- /dev/null
+++ b/sound/soc/sh/rcar/rsrc-card.c
@@ -0,0 +1,512 @@
1/*
2 * Renesas Sampling Rate Convert Sound Card for DPCM
3 *
4 * Copyright (C) 2015 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * based on ${LINUX}/sound/soc/generic/simple-card.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/clk.h>
14#include <linux/device.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/of_device.h>
18#include <linux/platform_device.h>
19#include <linux/string.h>
20#include <sound/jack.h>
21#include <sound/soc.h>
22#include <sound/soc-dai.h>
23
24struct rsrc_card_of_data {
25 const char *prefix;
26 const struct snd_soc_dapm_route *routes;
27 int num_routes;
28};
29
30static const struct snd_soc_dapm_route routes_ssi0_ak4642[] = {
31 {"ak4642 Playback", NULL, "DAI0 Playback"},
32 {"DAI0 Capture", NULL, "ak4642 Capture"},
33};
34
35static const struct rsrc_card_of_data routes_of_ssi0_ak4642 = {
36 .prefix = "ak4642",
37 .routes = routes_ssi0_ak4642,
38 .num_routes = ARRAY_SIZE(routes_ssi0_ak4642),
39};
40
41static const struct of_device_id rsrc_card_of_match[] = {
42 { .compatible = "renesas,rsrc-card,lager", .data = &routes_of_ssi0_ak4642 },
43 { .compatible = "renesas,rsrc-card,koelsch", .data = &routes_of_ssi0_ak4642 },
44 {},
45};
46MODULE_DEVICE_TABLE(of, rsrc_card_of_match);
47
48struct rsrc_card_dai {
49 const char *name;
50 unsigned int fmt;
51 unsigned int sysclk;
52 struct clk *clk;
53};
54
55#define RSRC_FB_NUM 2 /* FE/BE */
56#define IDX_CPU 0
57#define IDX_CODEC 1
58struct rsrc_card_priv {
59 struct snd_soc_card snd_card;
60 struct rsrc_card_dai_props {
61 struct rsrc_card_dai cpu_dai;
62 struct rsrc_card_dai codec_dai;
63 } dai_props[RSRC_FB_NUM];
64 struct snd_soc_codec_conf codec_conf;
65 struct snd_soc_dai_link dai_link[RSRC_FB_NUM];
66 u32 convert_rate;
67};
68
69#define rsrc_priv_to_dev(priv) ((priv)->snd_card.dev)
70#define rsrc_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i)
71#define rsrc_priv_to_props(priv, i) ((priv)->dai_props + i)
72#define rsrc_dev_to_of_data(dev) (of_match_device(rsrc_card_of_match, (dev))->data)
73
74static int rsrc_card_startup(struct snd_pcm_substream *substream)
75{
76 struct snd_soc_pcm_runtime *rtd = substream->private_data;
77 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
78 struct rsrc_card_dai_props *dai_props =
79 &priv->dai_props[rtd - rtd->card->rtd];
80 int ret;
81
82 ret = clk_prepare_enable(dai_props->cpu_dai.clk);
83 if (ret)
84 return ret;
85
86 ret = clk_prepare_enable(dai_props->codec_dai.clk);
87 if (ret)
88 clk_disable_unprepare(dai_props->cpu_dai.clk);
89
90 return ret;
91}
92
93static void rsrc_card_shutdown(struct snd_pcm_substream *substream)
94{
95 struct snd_soc_pcm_runtime *rtd = substream->private_data;
96 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
97 struct rsrc_card_dai_props *dai_props =
98 &priv->dai_props[rtd - rtd->card->rtd];
99
100 clk_disable_unprepare(dai_props->cpu_dai.clk);
101
102 clk_disable_unprepare(dai_props->codec_dai.clk);
103}
104
105static struct snd_soc_ops rsrc_card_ops = {
106 .startup = rsrc_card_startup,
107 .shutdown = rsrc_card_shutdown,
108};
109
110static int __rsrc_card_dai_init(struct snd_soc_dai *dai,
111 struct rsrc_card_dai *set)
112{
113 int ret;
114
115 if (set->fmt) {
116 ret = snd_soc_dai_set_fmt(dai, set->fmt);
117 if (ret && ret != -ENOTSUPP) {
118 dev_err(dai->dev, "set_fmt error\n");
119 goto err;
120 }
121 }
122
123 if (set->sysclk) {
124 ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0);
125 if (ret && ret != -ENOTSUPP) {
126 dev_err(dai->dev, "set_sysclk error\n");
127 goto err;
128 }
129 }
130
131 ret = 0;
132
133err:
134 return ret;
135}
136
137static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd)
138{
139 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
140 struct snd_soc_dai *codec = rtd->codec_dai;
141 struct snd_soc_dai *cpu = rtd->cpu_dai;
142 struct rsrc_card_dai_props *dai_props;
143 int num, ret;
144
145 num = rtd - rtd->card->rtd;
146 dai_props = &priv->dai_props[num];
147 ret = __rsrc_card_dai_init(codec, &dai_props->codec_dai);
148 if (ret < 0)
149 return ret;
150
151 ret = __rsrc_card_dai_init(cpu, &dai_props->cpu_dai);
152 if (ret < 0)
153 return ret;
154
155 return 0;
156}
157
158static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
159 struct snd_pcm_hw_params *params)
160{
161 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
162 struct snd_interval *rate = hw_param_interval(params,
163 SNDRV_PCM_HW_PARAM_RATE);
164
165 if (!priv->convert_rate)
166 return 0;
167
168 rate->min = rate->max = priv->convert_rate;
169
170 return 0;
171}
172
173static int
174rsrc_card_sub_parse_of(struct rsrc_card_priv *priv,
175 struct device_node *np,
176 struct rsrc_card_dai *dai,
177 struct snd_soc_dai_link *dai_link,
178 int *args_count)
179{
180 struct device *dev = rsrc_priv_to_dev(priv);
181 const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev);
182 struct of_phandle_args args;
183 struct device_node **p_node;
184 struct clk *clk;
185 const char **dai_name;
186 const char **name;
187 u32 val;
188 int ret;
189
190 if (args_count) {
191 p_node = &dai_link->cpu_of_node;
192 dai_name = &dai_link->cpu_dai_name;
193 name = &dai_link->cpu_name;
194 } else {
195 p_node = &dai_link->codec_of_node;
196 dai_name = &dai_link->codec_dai_name;
197 name = &dai_link->codec_name;
198 }
199
200 if (!np) {
201 /* use snd-soc-dummy */
202 *p_node = NULL;
203 *dai_name = "snd-soc-dummy-dai";
204 *name = "snd-soc-dummy";
205 return 0;
206 }
207
208 /*
209 * Get node via "sound-dai = <&phandle port>"
210 * it will be used as xxx_of_node on soc_bind_dai_link()
211 */
212 ret = of_parse_phandle_with_args(np, "sound-dai",
213 "#sound-dai-cells", 0, &args);
214 if (ret)
215 return ret;
216
217 *p_node = args.np;
218
219 /* Get dai->name */
220 ret = snd_soc_of_get_dai_name(np, dai_name);
221 if (ret < 0)
222 return ret;
223
224 /*
225 * FIXME
226 *
227 * rsrc assumes DPCM playback/capture
228 */
229 dai_link->dpcm_playback = 1;
230 dai_link->dpcm_capture = 1;
231
232 if (args_count) {
233 *args_count = args.args_count;
234 dai_link->dynamic = 1;
235 } else {
236 dai_link->no_pcm = 1;
237 priv->codec_conf.of_node = (*p_node);
238 priv->codec_conf.name_prefix = of_data->prefix;
239 }
240
241 /*
242 * Parse dai->sysclk come from "clocks = <&xxx>"
243 * (if system has common clock)
244 * or "system-clock-frequency = <xxx>"
245 * or device's module clock.
246 */
247 if (of_property_read_bool(np, "clocks")) {
248 clk = of_clk_get(np, 0);
249 if (IS_ERR(clk)) {
250 ret = PTR_ERR(clk);
251 return ret;
252 }
253
254 dai->sysclk = clk_get_rate(clk);
255 dai->clk = clk;
256 } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) {
257 dai->sysclk = val;
258 } else {
259 clk = of_clk_get(args.np, 0);
260 if (!IS_ERR(clk))
261 dai->sysclk = clk_get_rate(clk);
262 }
263
264 return 0;
265}
266
267static int rsrc_card_parse_daifmt(struct device_node *node,
268 struct rsrc_card_priv *priv,
269 struct device_node *codec,
270 int idx)
271{
272 struct device_node *bitclkmaster = NULL;
273 struct device_node *framemaster = NULL;
274 struct rsrc_card_dai_props *dai_props = rsrc_priv_to_props(priv, idx);
275 struct rsrc_card_dai *cpu_dai = &dai_props->cpu_dai;
276 struct rsrc_card_dai *codec_dai = &dai_props->codec_dai;
277 unsigned int daifmt;
278
279 daifmt = snd_soc_of_parse_daifmt(node, NULL,
280 &bitclkmaster, &framemaster);
281 daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
282
283 if (!bitclkmaster && !framemaster)
284 return -EINVAL;
285
286 if (codec == bitclkmaster)
287 daifmt |= (codec == framemaster) ?
288 SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
289 else
290 daifmt |= (codec == framemaster) ?
291 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
292
293 cpu_dai->fmt = daifmt;
294 codec_dai->fmt = daifmt;
295
296 of_node_put(bitclkmaster);
297 of_node_put(framemaster);
298
299 return 0;
300}
301
302static int rsrc_card_dai_link_of(struct device_node *node,
303 struct rsrc_card_priv *priv,
304 int idx)
305{
306 struct device *dev = rsrc_priv_to_dev(priv);
307 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
308 struct rsrc_card_dai_props *dai_props = rsrc_priv_to_props(priv, idx);
309 struct device_node *cpu = NULL;
310 struct device_node *codec = NULL;
311 char *name;
312 char prop[128];
313 int ret, cpu_args;
314
315 cpu = of_get_child_by_name(node, "cpu");
316 codec = of_get_child_by_name(node, "codec");
317
318 if (!cpu || !codec) {
319 ret = -EINVAL;
320 dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
321 goto dai_link_of_err;
322 }
323
324 ret = rsrc_card_parse_daifmt(node, priv, codec, idx);
325 if (ret < 0)
326 goto dai_link_of_err;
327
328 ret = rsrc_card_sub_parse_of(priv, (idx == IDX_CPU) ? cpu : NULL,
329 &dai_props->cpu_dai,
330 dai_link,
331 &cpu_args);
332 if (ret < 0)
333 goto dai_link_of_err;
334
335 ret = rsrc_card_sub_parse_of(priv, (idx == IDX_CODEC) ? codec : NULL,
336 &dai_props->codec_dai,
337 dai_link,
338 NULL);
339 if (ret < 0)
340 goto dai_link_of_err;
341
342 if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
343 ret = -EINVAL;
344 goto dai_link_of_err;
345 }
346
347 /* Simple Card assumes platform == cpu */
348 dai_link->platform_of_node = dai_link->cpu_of_node;
349
350 /* DAI link name is created from CPU/CODEC dai name */
351 name = devm_kzalloc(dev,
352 strlen(dai_link->cpu_dai_name) +
353 strlen(dai_link->codec_dai_name) + 2,
354 GFP_KERNEL);
355 if (!name) {
356 ret = -ENOMEM;
357 goto dai_link_of_err;
358 }
359
360 sprintf(name, "%s-%s", dai_link->cpu_dai_name,
361 dai_link->codec_dai_name);
362 dai_link->name = dai_link->stream_name = name;
363 dai_link->ops = &rsrc_card_ops;
364 dai_link->init = rsrc_card_dai_init;
365
366 if (idx == IDX_CODEC)
367 dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup;
368
369 dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
370 dev_dbg(dev, "\tcpu : %s / %04x / %d\n",
371 dai_link->cpu_dai_name,
372 dai_props->cpu_dai.fmt,
373 dai_props->cpu_dai.sysclk);
374 dev_dbg(dev, "\tcodec : %s / %04x / %d\n",
375 dai_link->codec_dai_name,
376 dai_props->codec_dai.fmt,
377 dai_props->codec_dai.sysclk);
378
379 /*
380 * In soc_bind_dai_link() will check cpu name after
381 * of_node matching if dai_link has cpu_dai_name.
382 * but, it will never match if name was created by
383 * fmt_single_name() remove cpu_dai_name if cpu_args
384 * was 0. See:
385 * fmt_single_name()
386 * fmt_multiple_name()
387 */
388 if (!cpu_args)
389 dai_link->cpu_dai_name = NULL;
390
391dai_link_of_err:
392 of_node_put(cpu);
393 of_node_put(codec);
394
395 return ret;
396}
397
398static int rsrc_card_parse_of(struct device_node *node,
399 struct rsrc_card_priv *priv)
400{
401 struct device *dev = rsrc_priv_to_dev(priv);
402 const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev);
403 int ret;
404 int i;
405
406 if (!node)
407 return -EINVAL;
408
409 /* Parse the card name from DT */
410 snd_soc_of_parse_card_name(&priv->snd_card, "card-name");
411
412 /* DAPM routes */
413 priv->snd_card.of_dapm_routes = of_data->routes;
414 priv->snd_card.num_of_dapm_routes = of_data->num_routes;
415
416 /* sampling rate convert */
417 of_property_read_u32(node, "convert-rate", &priv->convert_rate);
418
419 dev_dbg(dev, "New rsrc-audio-card: %s (%d)\n",
420 priv->snd_card.name ? priv->snd_card.name : "",
421 priv->convert_rate);
422
423 /* FE/BE */
424 for (i = 0; i < RSRC_FB_NUM; i++) {
425 ret = rsrc_card_dai_link_of(node, priv, i);
426 if (ret < 0)
427 return ret;
428 }
429
430 if (!priv->snd_card.name)
431 priv->snd_card.name = priv->snd_card.dai_link->name;
432
433 return 0;
434}
435
436/* Decrease the reference count of the device nodes */
437static int rsrc_card_unref(struct snd_soc_card *card)
438{
439 struct snd_soc_dai_link *dai_link;
440 int num_links;
441
442 for (num_links = 0, dai_link = card->dai_link;
443 num_links < card->num_links;
444 num_links++, dai_link++) {
445 of_node_put(dai_link->cpu_of_node);
446 of_node_put(dai_link->codec_of_node);
447 }
448 return 0;
449}
450
451static int rsrc_card_probe(struct platform_device *pdev)
452{
453 struct rsrc_card_priv *priv;
454 struct snd_soc_dai_link *dai_link;
455 struct device_node *np = pdev->dev.of_node;
456 struct device *dev = &pdev->dev;
457 int ret;
458
459 /* Allocate the private data */
460 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
461 if (!priv)
462 return -ENOMEM;
463
464 /* Init snd_soc_card */
465 priv->snd_card.owner = THIS_MODULE;
466 priv->snd_card.dev = dev;
467 dai_link = priv->dai_link;
468 priv->snd_card.dai_link = dai_link;
469 priv->snd_card.num_links = RSRC_FB_NUM;
470 priv->snd_card.codec_conf = &priv->codec_conf;
471 priv->snd_card.num_configs = 1;
472
473 ret = rsrc_card_parse_of(np, priv);
474 if (ret < 0) {
475 if (ret != -EPROBE_DEFER)
476 dev_err(dev, "parse error %d\n", ret);
477 goto err;
478 }
479
480 snd_soc_card_set_drvdata(&priv->snd_card, priv);
481
482 ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
483 if (ret >= 0)
484 return ret;
485err:
486 rsrc_card_unref(&priv->snd_card);
487
488 return ret;
489}
490
491static int rsrc_card_remove(struct platform_device *pdev)
492{
493 struct snd_soc_card *card = platform_get_drvdata(pdev);
494
495 return rsrc_card_unref(card);
496}
497
498static struct platform_driver rsrc_card = {
499 .driver = {
500 .name = "renesas-src-audio-card",
501 .of_match_table = rsrc_card_of_match,
502 },
503 .probe = rsrc_card_probe,
504 .remove = rsrc_card_remove,
505};
506
507module_platform_driver(rsrc_card);
508
509MODULE_ALIAS("platform:renesas-src-audio-card");
510MODULE_LICENSE("GPL");
511MODULE_DESCRIPTION("Renesas Sampling Rate Convert Sound Card");
512MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 81c182b4bad5..3beb32eb412a 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -22,16 +22,20 @@
22struct rsnd_src { 22struct rsnd_src {
23 struct rsnd_src_platform_info *info; /* rcar_snd.h */ 23 struct rsnd_src_platform_info *info; /* rcar_snd.h */
24 struct rsnd_mod mod; 24 struct rsnd_mod mod;
25 struct rsnd_kctrl_cfg_s sen; /* sync convert enable */
26 struct rsnd_kctrl_cfg_s sync; /* sync convert */
27 u32 convert_rate; /* sampling rate convert */
25 int err; 28 int err;
26}; 29};
27 30
28#define RSND_SRC_NAME_SIZE 16 31#define RSND_SRC_NAME_SIZE 16
29 32
30#define rsnd_src_convert_rate(p) ((p)->info->convert_rate) 33#define rsnd_enable_sync_convert(src) ((src)->sen.val)
34#define rsnd_src_of_node(priv) \
35 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src")
36
31#define rsnd_mod_to_src(_mod) \ 37#define rsnd_mod_to_src(_mod) \
32 container_of((_mod), struct rsnd_src, mod) 38 container_of((_mod), struct rsnd_src, mod)
33#define rsnd_src_dma_available(src) \
34 rsnd_dma_available(rsnd_mod_to_dma(&(src)->mod))
35 39
36#define for_each_rsnd_src(pos, priv, i) \ 40#define for_each_rsnd_src(pos, priv, i) \
37 for ((i) = 0; \ 41 for ((i) = 0; \
@@ -113,6 +117,17 @@ struct rsnd_src {
113/* 117/*
114 * Gen1/Gen2 common functions 118 * Gen1/Gen2 common functions
115 */ 119 */
120static struct dma_chan *rsnd_src_dma_req(struct rsnd_mod *mod)
121{
122 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
123 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
124 int is_play = rsnd_io_is_play(io);
125
126 return rsnd_dma_request_channel(rsnd_src_of_node(priv),
127 mod,
128 is_play ? "rx" : "tx");
129}
130
116int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, 131int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
117 int use_busif) 132 int use_busif)
118{ 133{
@@ -220,6 +235,30 @@ int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod)
220 return 0; 235 return 0;
221} 236}
222 237
238static u32 rsnd_src_convert_rate(struct rsnd_src *src)
239{
240 struct rsnd_mod *mod = &src->mod;
241 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
242 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
243 u32 convert_rate;
244
245 if (!runtime)
246 return 0;
247
248 if (!rsnd_enable_sync_convert(src))
249 return src->convert_rate;
250
251 convert_rate = src->sync.val;
252
253 if (!convert_rate)
254 convert_rate = src->convert_rate;
255
256 if (!convert_rate)
257 convert_rate = runtime->rate;
258
259 return convert_rate;
260}
261
223unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, 262unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
224 struct rsnd_dai_stream *io, 263 struct rsnd_dai_stream *io,
225 struct snd_pcm_runtime *runtime) 264 struct snd_pcm_runtime *runtime)
@@ -276,7 +315,43 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod)
276 return 0; 315 return 0;
277} 316}
278 317
279static int rsnd_src_init(struct rsnd_mod *mod) 318static int rsnd_src_hw_params(struct rsnd_mod *mod,
319 struct snd_pcm_substream *substream,
320 struct snd_pcm_hw_params *fe_params)
321{
322 struct rsnd_src *src = rsnd_mod_to_src(mod);
323 struct snd_soc_pcm_runtime *fe = substream->private_data;
324
325 /* default value (mainly for non-DT) */
326 src->convert_rate = src->info->convert_rate;
327
328 /*
329 * SRC assumes that it is used under DPCM if user want to use
330 * sampling rate convert. Then, SRC should be FE.
331 * And then, this function will be called *after* BE settings.
332 * this means, each BE already has fixuped hw_params.
333 * see
334 * dpcm_fe_dai_hw_params()
335 * dpcm_be_dai_hw_params()
336 */
337 if (fe->dai_link->dynamic) {
338 int stream = substream->stream;
339 struct snd_soc_dpcm *dpcm;
340 struct snd_pcm_hw_params *be_params;
341
342 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
343 be_params = &dpcm->hw_params;
344
345 if (params_rate(fe_params) != params_rate(be_params))
346 src->convert_rate = params_rate(be_params);
347 }
348 }
349
350 return 0;
351}
352
353static int rsnd_src_init(struct rsnd_mod *mod,
354 struct rsnd_priv *priv)
280{ 355{
281 struct rsnd_src *src = rsnd_mod_to_src(mod); 356 struct rsnd_src *src = rsnd_mod_to_src(mod);
282 357
@@ -284,6 +359,9 @@ static int rsnd_src_init(struct rsnd_mod *mod)
284 359
285 src->err = 0; 360 src->err = 0;
286 361
362 /* reset sync convert_rate */
363 src->sync.val = 0;
364
287 /* 365 /*
288 * Initialize the operation of the SRC internal circuits 366 * Initialize the operation of the SRC internal circuits
289 * see rsnd_src_start() 367 * see rsnd_src_start()
@@ -305,6 +383,11 @@ static int rsnd_src_quit(struct rsnd_mod *mod,
305 dev_warn(dev, "%s[%d] under/over flow err = %d\n", 383 dev_warn(dev, "%s[%d] under/over flow err = %d\n",
306 rsnd_mod_name(mod), rsnd_mod_id(mod), src->err); 384 rsnd_mod_name(mod), rsnd_mod_id(mod), src->err);
307 385
386 src->convert_rate = 0;
387
388 /* reset sync convert_rate */
389 src->sync.val = 0;
390
308 return 0; 391 return 0;
309} 392}
310 393
@@ -448,23 +531,12 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod)
448 return 0; 531 return 0;
449} 532}
450 533
451static int rsnd_src_probe_gen1(struct rsnd_mod *mod,
452 struct rsnd_priv *priv)
453{
454 struct device *dev = rsnd_priv_to_dev(priv);
455
456 dev_dbg(dev, "%s[%d] (Gen1) is probed\n",
457 rsnd_mod_name(mod), rsnd_mod_id(mod));
458
459 return 0;
460}
461
462static int rsnd_src_init_gen1(struct rsnd_mod *mod, 534static int rsnd_src_init_gen1(struct rsnd_mod *mod,
463 struct rsnd_priv *priv) 535 struct rsnd_priv *priv)
464{ 536{
465 int ret; 537 int ret;
466 538
467 ret = rsnd_src_init(mod); 539 ret = rsnd_src_init(mod, priv);
468 if (ret < 0) 540 if (ret < 0)
469 return ret; 541 return ret;
470 542
@@ -505,11 +577,12 @@ static int rsnd_src_stop_gen1(struct rsnd_mod *mod,
505 577
506static struct rsnd_mod_ops rsnd_src_gen1_ops = { 578static struct rsnd_mod_ops rsnd_src_gen1_ops = {
507 .name = SRC_NAME, 579 .name = SRC_NAME,
508 .probe = rsnd_src_probe_gen1, 580 .dma_req = rsnd_src_dma_req,
509 .init = rsnd_src_init_gen1, 581 .init = rsnd_src_init_gen1,
510 .quit = rsnd_src_quit, 582 .quit = rsnd_src_quit,
511 .start = rsnd_src_start_gen1, 583 .start = rsnd_src_start_gen1,
512 .stop = rsnd_src_stop_gen1, 584 .stop = rsnd_src_stop_gen1,
585 .hw_params = rsnd_src_hw_params,
513}; 586};
514 587
515/* 588/*
@@ -607,13 +680,17 @@ static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data)
607 680
608 if (rsnd_src_error_record_gen2(mod)) { 681 if (rsnd_src_error_record_gen2(mod)) {
609 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 682 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
683 struct rsnd_src *src = rsnd_mod_to_src(mod);
610 struct device *dev = rsnd_priv_to_dev(priv); 684 struct device *dev = rsnd_priv_to_dev(priv);
611 685
612 _rsnd_src_stop_gen2(mod);
613 _rsnd_src_start_gen2(mod);
614
615 dev_dbg(dev, "%s[%d] restart\n", 686 dev_dbg(dev, "%s[%d] restart\n",
616 rsnd_mod_name(mod), rsnd_mod_id(mod)); 687 rsnd_mod_name(mod), rsnd_mod_id(mod));
688
689 _rsnd_src_stop_gen2(mod);
690 if (src->err < 1024)
691 _rsnd_src_start_gen2(mod);
692 else
693 dev_warn(dev, "no more SRC restart\n");
617 } 694 }
618 695
619 return IRQ_HANDLED; 696 return IRQ_HANDLED;
@@ -627,6 +704,7 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod)
627 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 704 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
628 struct rsnd_src *src = rsnd_mod_to_src(mod); 705 struct rsnd_src *src = rsnd_mod_to_src(mod);
629 u32 convert_rate = rsnd_src_convert_rate(src); 706 u32 convert_rate = rsnd_src_convert_rate(src);
707 u32 cr, route;
630 uint ratio; 708 uint ratio;
631 int ret; 709 int ret;
632 710
@@ -647,13 +725,21 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod)
647 if (ret < 0) 725 if (ret < 0)
648 return ret; 726 return ret;
649 727
650 rsnd_mod_write(mod, SRC_SRCCR, 0x00011110); 728 cr = 0x00011110;
651 729 route = 0x0;
652 if (convert_rate) { 730 if (convert_rate) {
653 /* Gen1/Gen2 are not compatible */ 731 route = 0x1;
654 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); 732
733 if (rsnd_enable_sync_convert(src)) {
734 cr |= 0x1;
735 route |= rsnd_io_is_play(io) ?
736 (0x1 << 24) : (0x1 << 25);
737 }
655 } 738 }
656 739
740 rsnd_mod_write(mod, SRC_SRCCR, cr);
741 rsnd_mod_write(mod, SRC_ROUTE_MODE0, route);
742
657 switch (rsnd_mod_id(mod)) { 743 switch (rsnd_mod_id(mod)) {
658 case 5: 744 case 5:
659 case 6: 745 case 6:
@@ -708,24 +794,12 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
708 IRQF_SHARED, 794 IRQF_SHARED,
709 dev_name(dev), mod); 795 dev_name(dev), mod);
710 if (ret) 796 if (ret)
711 goto rsnd_src_probe_gen2_fail; 797 return ret;
712 } 798 }
713 799
714 ret = rsnd_dma_init(priv, 800 ret = rsnd_dma_init(priv,
715 rsnd_mod_to_dma(mod), 801 rsnd_mod_to_dma(mod),
716 rsnd_info_is_playback(priv, src),
717 src->info->dma_id); 802 src->info->dma_id);
718 if (ret)
719 goto rsnd_src_probe_gen2_fail;
720
721 dev_dbg(dev, "%s[%d] (Gen2) is probed\n",
722 rsnd_mod_name(mod), rsnd_mod_id(mod));
723
724 return ret;
725
726rsnd_src_probe_gen2_fail:
727 dev_err(dev, "%s[%d] (Gen2) failed\n",
728 rsnd_mod_name(mod), rsnd_mod_id(mod));
729 803
730 return ret; 804 return ret;
731} 805}
@@ -733,7 +807,7 @@ rsnd_src_probe_gen2_fail:
733static int rsnd_src_remove_gen2(struct rsnd_mod *mod, 807static int rsnd_src_remove_gen2(struct rsnd_mod *mod,
734 struct rsnd_priv *priv) 808 struct rsnd_priv *priv)
735{ 809{
736 rsnd_dma_quit(priv, rsnd_mod_to_dma(mod)); 810 rsnd_dma_quit(rsnd_mod_to_dma(mod));
737 811
738 return 0; 812 return 0;
739} 813}
@@ -743,7 +817,7 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod,
743{ 817{
744 int ret; 818 int ret;
745 819
746 ret = rsnd_src_init(mod); 820 ret = rsnd_src_init(mod, priv);
747 if (ret < 0) 821 if (ret < 0)
748 return ret; 822 return ret;
749 823
@@ -778,14 +852,91 @@ static int rsnd_src_stop_gen2(struct rsnd_mod *mod,
778 return ret; 852 return ret;
779} 853}
780 854
855static void rsnd_src_reconvert_update(struct rsnd_mod *mod)
856{
857 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
858 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
859 struct rsnd_src *src = rsnd_mod_to_src(mod);
860 u32 convert_rate = rsnd_src_convert_rate(src);
861 u32 fsrate;
862
863 if (!runtime)
864 return;
865
866 if (!convert_rate)
867 convert_rate = runtime->rate;
868
869 fsrate = 0x0400000 / convert_rate * runtime->rate;
870
871 /* update IFS */
872 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
873}
874
875static int rsnd_src_pcm_new(struct rsnd_mod *mod,
876 struct snd_soc_pcm_runtime *rtd)
877{
878 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
879 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
880 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
881 struct rsnd_src *src = rsnd_mod_to_src(mod);
882 int ret;
883
884 /*
885 * enable SRC sync convert if possible
886 */
887
888 /*
889 * Gen1 is not supported
890 */
891 if (rsnd_is_gen1(priv))
892 return 0;
893
894 /*
895 * SRC sync convert needs clock master
896 */
897 if (!rsnd_rdai_is_clk_master(rdai))
898 return 0;
899
900 /*
901 * We can't use SRC sync convert
902 * if it has DVC
903 */
904 if (rsnd_io_to_mod_dvc(io))
905 return 0;
906
907 /*
908 * enable sync convert
909 */
910 ret = rsnd_kctrl_new_s(mod, rtd,
911 rsnd_io_is_play(io) ?
912 "SRC Out Rate Switch" :
913 "SRC In Rate Switch",
914 rsnd_src_reconvert_update,
915 &src->sen, 1);
916 if (ret < 0)
917 return ret;
918
919 ret = rsnd_kctrl_new_s(mod, rtd,
920 rsnd_io_is_play(io) ?
921 "SRC Out Rate" :
922 "SRC In Rate",
923 rsnd_src_reconvert_update,
924 &src->sync, 192000);
925
926 return ret;
927}
928
781static struct rsnd_mod_ops rsnd_src_gen2_ops = { 929static struct rsnd_mod_ops rsnd_src_gen2_ops = {
782 .name = SRC_NAME, 930 .name = SRC_NAME,
931 .dma_req = rsnd_src_dma_req,
783 .probe = rsnd_src_probe_gen2, 932 .probe = rsnd_src_probe_gen2,
784 .remove = rsnd_src_remove_gen2, 933 .remove = rsnd_src_remove_gen2,
785 .init = rsnd_src_init_gen2, 934 .init = rsnd_src_init_gen2,
786 .quit = rsnd_src_quit, 935 .quit = rsnd_src_quit,
787 .start = rsnd_src_start_gen2, 936 .start = rsnd_src_start_gen2,
788 .stop = rsnd_src_stop_gen2, 937 .stop = rsnd_src_stop_gen2,
938 .hw_params = rsnd_src_hw_params,
939 .pcm_new = rsnd_src_pcm_new,
789}; 940};
790 941
791struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) 942struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
@@ -810,7 +961,7 @@ static void rsnd_of_parse_src(struct platform_device *pdev,
810 if (!of_data) 961 if (!of_data)
811 return; 962 return;
812 963
813 src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src"); 964 src_node = rsnd_src_of_node(priv);
814 if (!src_node) 965 if (!src_node)
815 return; 966 return;
816 967
@@ -850,7 +1001,7 @@ int rsnd_src_probe(struct platform_device *pdev,
850 struct rsnd_mod_ops *ops; 1001 struct rsnd_mod_ops *ops;
851 struct clk *clk; 1002 struct clk *clk;
852 char name[RSND_SRC_NAME_SIZE]; 1003 char name[RSND_SRC_NAME_SIZE];
853 int i, nr; 1004 int i, nr, ret;
854 1005
855 ops = NULL; 1006 ops = NULL;
856 if (rsnd_is_gen1(priv)) 1007 if (rsnd_is_gen1(priv))
@@ -890,10 +1041,21 @@ int rsnd_src_probe(struct platform_device *pdev,
890 1041
891 src->info = &info->src_info[i]; 1042 src->info = &info->src_info[i];
892 1043
893 rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i); 1044 ret = rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i);
894 1045 if (ret)
895 dev_dbg(dev, "SRC%d probed\n", i); 1046 return ret;
896 } 1047 }
897 1048
898 return 0; 1049 return 0;
899} 1050}
1051
1052void rsnd_src_remove(struct platform_device *pdev,
1053 struct rsnd_priv *priv)
1054{
1055 struct rsnd_src *src;
1056 int i;
1057
1058 for_each_rsnd_src(src, priv, i) {
1059 rsnd_mod_quit(&src->mod);
1060 }
1061}
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 9e7b627c08e2..7bb9c087f3dc 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -80,13 +80,13 @@ struct rsnd_ssi {
80#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) 80#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod)
81#define rsnd_dma_to_ssi(dma) rsnd_mod_to_ssi(rsnd_dma_to_mod(dma)) 81#define rsnd_dma_to_ssi(dma) rsnd_mod_to_ssi(rsnd_dma_to_mod(dma))
82#define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0) 82#define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0)
83#define rsnd_ssi_dma_available(ssi) \
84 rsnd_dma_available(rsnd_mod_to_dma(&(ssi)->mod))
85#define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent) 83#define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent)
86#define rsnd_ssi_mode_flags(p) ((p)->info->flags) 84#define rsnd_ssi_mode_flags(p) ((p)->info->flags)
87#define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id) 85#define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id)
86#define rsnd_ssi_of_node(priv) \
87 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi")
88 88
89static int rsnd_ssi_use_busif(struct rsnd_mod *mod) 89int rsnd_ssi_use_busif(struct rsnd_mod *mod)
90{ 90{
91 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 91 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
92 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 92 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
@@ -416,11 +416,14 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
416 /* 416 /*
417 * restart SSI 417 * restart SSI
418 */ 418 */
419 rsnd_ssi_stop(mod, priv);
420 rsnd_ssi_start(mod, priv);
421
422 dev_dbg(dev, "%s[%d] restart\n", 419 dev_dbg(dev, "%s[%d] restart\n",
423 rsnd_mod_name(mod), rsnd_mod_id(mod)); 420 rsnd_mod_name(mod), rsnd_mod_id(mod));
421
422 rsnd_ssi_stop(mod, priv);
423 if (ssi->err < 1024)
424 rsnd_ssi_start(mod, priv);
425 else
426 dev_warn(dev, "no more SSI restart\n");
424 } 427 }
425 428
426 rsnd_ssi_record_error(ssi, status); 429 rsnd_ssi_record_error(ssi, status);
@@ -442,12 +445,6 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
442 rsnd_ssi_interrupt, 445 rsnd_ssi_interrupt,
443 IRQF_SHARED, 446 IRQF_SHARED,
444 dev_name(dev), ssi); 447 dev_name(dev), ssi);
445 if (ret)
446 dev_err(dev, "%s[%d] (PIO) request interrupt failed\n",
447 rsnd_mod_name(mod), rsnd_mod_id(mod));
448 else
449 dev_dbg(dev, "%s[%d] (PIO) is probed\n",
450 rsnd_mod_name(mod), rsnd_mod_id(mod));
451 448
452 return ret; 449 return ret;
453} 450}
@@ -474,23 +471,11 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
474 IRQF_SHARED, 471 IRQF_SHARED,
475 dev_name(dev), ssi); 472 dev_name(dev), ssi);
476 if (ret) 473 if (ret)
477 goto rsnd_ssi_dma_probe_fail; 474 return ret;
478 475
479 ret = rsnd_dma_init( 476 ret = rsnd_dma_init(
480 priv, rsnd_mod_to_dma(mod), 477 priv, rsnd_mod_to_dma(mod),
481 rsnd_info_is_playback(priv, ssi),
482 dma_id); 478 dma_id);
483 if (ret)
484 goto rsnd_ssi_dma_probe_fail;
485
486 dev_dbg(dev, "%s[%d] (DMA) is probed\n",
487 rsnd_mod_name(mod), rsnd_mod_id(mod));
488
489 return ret;
490
491rsnd_ssi_dma_probe_fail:
492 dev_err(dev, "%s[%d] (DMA) is failed\n",
493 rsnd_mod_name(mod), rsnd_mod_id(mod));
494 479
495 return ret; 480 return ret;
496} 481}
@@ -502,7 +487,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
502 struct device *dev = rsnd_priv_to_dev(priv); 487 struct device *dev = rsnd_priv_to_dev(priv);
503 int irq = ssi->info->irq; 488 int irq = ssi->info->irq;
504 489
505 rsnd_dma_quit(priv, rsnd_mod_to_dma(mod)); 490 rsnd_dma_quit(rsnd_mod_to_dma(mod));
506 491
507 /* PIO will request IRQ again */ 492 /* PIO will request IRQ again */
508 devm_free_irq(dev, irq, ssi); 493 devm_free_irq(dev, irq, ssi);
@@ -554,14 +539,25 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,
554 return 0; 539 return 0;
555} 540}
556 541
557static char *rsnd_ssi_dma_name(struct rsnd_mod *mod) 542static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_mod *mod)
558{ 543{
559 return rsnd_ssi_use_busif(mod) ? "ssiu" : SSI_NAME; 544 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
545 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
546 int is_play = rsnd_io_is_play(io);
547 char *name;
548
549 if (rsnd_ssi_use_busif(mod))
550 name = is_play ? "rxu" : "txu";
551 else
552 name = is_play ? "rx" : "tx";
553
554 return rsnd_dma_request_channel(rsnd_ssi_of_node(priv),
555 mod, name);
560} 556}
561 557
562static struct rsnd_mod_ops rsnd_ssi_dma_ops = { 558static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
563 .name = SSI_NAME, 559 .name = SSI_NAME,
564 .dma_name = rsnd_ssi_dma_name, 560 .dma_req = rsnd_ssi_dma_req,
565 .probe = rsnd_ssi_dma_probe, 561 .probe = rsnd_ssi_dma_probe,
566 .remove = rsnd_ssi_dma_remove, 562 .remove = rsnd_ssi_dma_remove,
567 .init = rsnd_ssi_init, 563 .init = rsnd_ssi_init,
@@ -636,7 +632,7 @@ static void rsnd_of_parse_ssi(struct platform_device *pdev,
636 if (!of_data) 632 if (!of_data)
637 return; 633 return;
638 634
639 node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi"); 635 node = rsnd_ssi_of_node(priv);
640 if (!node) 636 if (!node)
641 return; 637 return;
642 638
@@ -697,7 +693,7 @@ int rsnd_ssi_probe(struct platform_device *pdev,
697 struct clk *clk; 693 struct clk *clk;
698 struct rsnd_ssi *ssi; 694 struct rsnd_ssi *ssi;
699 char name[RSND_SSI_NAME_SIZE]; 695 char name[RSND_SSI_NAME_SIZE];
700 int i, nr; 696 int i, nr, ret;
701 697
702 rsnd_of_parse_ssi(pdev, of_data, priv); 698 rsnd_of_parse_ssi(pdev, of_data, priv);
703 699
@@ -732,10 +728,23 @@ int rsnd_ssi_probe(struct platform_device *pdev,
732 else if (rsnd_ssi_pio_available(ssi)) 728 else if (rsnd_ssi_pio_available(ssi))
733 ops = &rsnd_ssi_pio_ops; 729 ops = &rsnd_ssi_pio_ops;
734 730
735 rsnd_mod_init(&ssi->mod, ops, clk, RSND_MOD_SSI, i); 731 ret = rsnd_mod_init(&ssi->mod, ops, clk, RSND_MOD_SSI, i);
732 if (ret)
733 return ret;
736 734
737 rsnd_ssi_parent_clk_setup(priv, ssi); 735 rsnd_ssi_parent_clk_setup(priv, ssi);
738 } 736 }
739 737
740 return 0; 738 return 0;
741} 739}
740
741void rsnd_ssi_remove(struct platform_device *pdev,
742 struct rsnd_priv *priv)
743{
744 struct rsnd_ssi *ssi;
745 int i;
746
747 for_each_rsnd_ssi(ssi, priv, i) {
748 rsnd_mod_quit(&ssi->mod);
749 }
750}
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 10f0886e78ec..23732523f87c 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -292,6 +292,9 @@ static const struct file_operations codec_reg_fops = {
292 292
293static void soc_init_component_debugfs(struct snd_soc_component *component) 293static void soc_init_component_debugfs(struct snd_soc_component *component)
294{ 294{
295 if (!component->card->debugfs_card_root)
296 return;
297
295 if (component->debugfs_prefix) { 298 if (component->debugfs_prefix) {
296 char *name; 299 char *name;
297 300
@@ -455,6 +458,9 @@ static const struct file_operations platform_list_fops = {
455 458
456static void soc_init_card_debugfs(struct snd_soc_card *card) 459static void soc_init_card_debugfs(struct snd_soc_card *card)
457{ 460{
461 if (!snd_soc_debugfs_root)
462 return;
463
458 card->debugfs_card_root = debugfs_create_dir(card->name, 464 card->debugfs_card_root = debugfs_create_dir(card->name,
459 snd_soc_debugfs_root); 465 snd_soc_debugfs_root);
460 if (!card->debugfs_card_root) { 466 if (!card->debugfs_card_root) {
@@ -476,6 +482,34 @@ static void soc_cleanup_card_debugfs(struct snd_soc_card *card)
476 debugfs_remove_recursive(card->debugfs_card_root); 482 debugfs_remove_recursive(card->debugfs_card_root);
477} 483}
478 484
485
486static void snd_soc_debugfs_init(void)
487{
488 snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL);
489 if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) {
490 pr_warn("ASoC: Failed to create debugfs directory\n");
491 snd_soc_debugfs_root = NULL;
492 return;
493 }
494
495 if (!debugfs_create_file("codecs", 0444, snd_soc_debugfs_root, NULL,
496 &codec_list_fops))
497 pr_warn("ASoC: Failed to create CODEC list debugfs file\n");
498
499 if (!debugfs_create_file("dais", 0444, snd_soc_debugfs_root, NULL,
500 &dai_list_fops))
501 pr_warn("ASoC: Failed to create DAI list debugfs file\n");
502
503 if (!debugfs_create_file("platforms", 0444, snd_soc_debugfs_root, NULL,
504 &platform_list_fops))
505 pr_warn("ASoC: Failed to create platform list debugfs file\n");
506}
507
508static void snd_soc_debugfs_exit(void)
509{
510 debugfs_remove_recursive(snd_soc_debugfs_root);
511}
512
479#else 513#else
480 514
481#define soc_init_codec_debugfs NULL 515#define soc_init_codec_debugfs NULL
@@ -497,6 +531,15 @@ static inline void soc_init_card_debugfs(struct snd_soc_card *card)
497static inline void soc_cleanup_card_debugfs(struct snd_soc_card *card) 531static inline void soc_cleanup_card_debugfs(struct snd_soc_card *card)
498{ 532{
499} 533}
534
535static inline void snd_soc_debugfs_init(void)
536{
537}
538
539static inline void snd_soc_debugfs_exit(void)
540{
541}
542
500#endif 543#endif
501 544
502struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, 545struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
@@ -595,15 +638,9 @@ int snd_soc_suspend(struct device *dev)
595 cpu_dai->driver->suspend(cpu_dai); 638 cpu_dai->driver->suspend(cpu_dai);
596 } 639 }
597 640
598 /* close any waiting streams and save state */ 641 /* close any waiting streams */
599 for (i = 0; i < card->num_rtd; i++) { 642 for (i = 0; i < card->num_rtd; i++)
600 struct snd_soc_dai **codec_dais = card->rtd[i].codec_dais;
601 flush_delayed_work(&card->rtd[i].delayed_work); 643 flush_delayed_work(&card->rtd[i].delayed_work);
602 for (j = 0; j < card->rtd[i].num_codecs; j++) {
603 codec_dais[j]->codec->dapm.suspend_bias_level =
604 codec_dais[j]->codec->dapm.bias_level;
605 }
606 }
607 644
608 for (i = 0; i < card->num_rtd; i++) { 645 for (i = 0; i < card->num_rtd; i++) {
609 646
@@ -1261,7 +1298,8 @@ static int soc_link_dai_widgets(struct snd_soc_card *card,
1261 capture_w = cpu_dai->capture_widget; 1298 capture_w = cpu_dai->capture_widget;
1262 if (play_w && capture_w) { 1299 if (play_w && capture_w) {
1263 ret = snd_soc_dapm_new_pcm(card, dai_link->params, 1300 ret = snd_soc_dapm_new_pcm(card, dai_link->params,
1264 capture_w, play_w); 1301 dai_link->num_params, capture_w,
1302 play_w);
1265 if (ret != 0) { 1303 if (ret != 0) {
1266 dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", 1304 dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n",
1267 play_w->name, capture_w->name, ret); 1305 play_w->name, capture_w->name, ret);
@@ -1273,7 +1311,8 @@ static int soc_link_dai_widgets(struct snd_soc_card *card,
1273 capture_w = codec_dai->capture_widget; 1311 capture_w = codec_dai->capture_widget;
1274 if (play_w && capture_w) { 1312 if (play_w && capture_w) {
1275 ret = snd_soc_dapm_new_pcm(card, dai_link->params, 1313 ret = snd_soc_dapm_new_pcm(card, dai_link->params,
1276 capture_w, play_w); 1314 dai_link->num_params, capture_w,
1315 play_w);
1277 if (ret != 0) { 1316 if (ret != 0) {
1278 dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", 1317 dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n",
1279 play_w->name, capture_w->name, ret); 1318 play_w->name, capture_w->name, ret);
@@ -1322,21 +1361,17 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1322 } 1361 }
1323 } 1362 }
1324 1363
1364 if (dai_link->dai_fmt)
1365 snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt);
1366
1325 ret = soc_post_component_init(rtd, dai_link->name); 1367 ret = soc_post_component_init(rtd, dai_link->name);
1326 if (ret) 1368 if (ret)
1327 return ret; 1369 return ret;
1328 1370
1329#ifdef CONFIG_DEBUG_FS 1371#ifdef CONFIG_DEBUG_FS
1330 /* add DPCM sysfs entries */ 1372 /* add DPCM sysfs entries */
1331 if (dai_link->dynamic) { 1373 if (dai_link->dynamic)
1332 ret = soc_dpcm_debugfs_add(rtd); 1374 soc_dpcm_debugfs_add(rtd);
1333 if (ret < 0) {
1334 dev_err(rtd->dev,
1335 "ASoC: failed to add dpcm sysfs entries: %d\n",
1336 ret);
1337 return ret;
1338 }
1339 }
1340#endif 1375#endif
1341 1376
1342 if (cpu_dai->driver->compress_dai) { 1377 if (cpu_dai->driver->compress_dai) {
@@ -1426,7 +1461,6 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
1426 1461
1427 /* unregister the rtd device */ 1462 /* unregister the rtd device */
1428 if (rtd->dev_registered) { 1463 if (rtd->dev_registered) {
1429 device_remove_file(rtd->dev, &dev_attr_codec_reg);
1430 device_unregister(rtd->dev); 1464 device_unregister(rtd->dev);
1431 rtd->dev_registered = 0; 1465 rtd->dev_registered = 0;
1432 } 1466 }
@@ -1560,6 +1594,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1560 goto base_error; 1594 goto base_error;
1561 } 1595 }
1562 1596
1597 soc_init_card_debugfs(card);
1598
1563 card->dapm.bias_level = SND_SOC_BIAS_OFF; 1599 card->dapm.bias_level = SND_SOC_BIAS_OFF;
1564 card->dapm.dev = card->dev; 1600 card->dapm.dev = card->dev;
1565 card->dapm.card = card; 1601 card->dapm.card = card;
@@ -1578,6 +1614,10 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1578 snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets, 1614 snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets,
1579 card->num_dapm_widgets); 1615 card->num_dapm_widgets);
1580 1616
1617 if (card->of_dapm_widgets)
1618 snd_soc_dapm_new_controls(&card->dapm, card->of_dapm_widgets,
1619 card->num_of_dapm_widgets);
1620
1581 /* initialise the sound card only once */ 1621 /* initialise the sound card only once */
1582 if (card->probe) { 1622 if (card->probe) {
1583 ret = card->probe(card); 1623 ret = card->probe(card);
@@ -1633,11 +1673,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1633 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, 1673 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
1634 card->num_dapm_routes); 1674 card->num_dapm_routes);
1635 1675
1636 for (i = 0; i < card->num_links; i++) { 1676 if (card->of_dapm_routes)
1637 if (card->dai_link[i].dai_fmt) 1677 snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes,
1638 snd_soc_runtime_set_dai_fmt(&card->rtd[i], 1678 card->num_of_dapm_routes);
1639 card->dai_link[i].dai_fmt);
1640 }
1641 1679
1642 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), 1680 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
1643 "%s", card->name); 1681 "%s", card->name);
@@ -1694,6 +1732,7 @@ card_probe_error:
1694 if (card->remove) 1732 if (card->remove)
1695 card->remove(card); 1733 card->remove(card);
1696 1734
1735 soc_cleanup_card_debugfs(card);
1697 snd_card_free(card->snd_card); 1736 snd_card_free(card->snd_card);
1698 1737
1699base_error: 1738base_error:
@@ -2372,8 +2411,6 @@ int snd_soc_register_card(struct snd_soc_card *card)
2372 2411
2373 snd_soc_initialize_card_lists(card); 2412 snd_soc_initialize_card_lists(card);
2374 2413
2375 soc_init_card_debugfs(card);
2376
2377 card->rtd = devm_kzalloc(card->dev, 2414 card->rtd = devm_kzalloc(card->dev,
2378 sizeof(struct snd_soc_pcm_runtime) * 2415 sizeof(struct snd_soc_pcm_runtime) *
2379 (card->num_links + card->num_aux_devs), 2416 (card->num_links + card->num_aux_devs),
@@ -2404,7 +2441,7 @@ int snd_soc_register_card(struct snd_soc_card *card)
2404 2441
2405 ret = snd_soc_instantiate_card(card); 2442 ret = snd_soc_instantiate_card(card);
2406 if (ret != 0) 2443 if (ret != 0)
2407 soc_cleanup_card_debugfs(card); 2444 return ret;
2408 2445
2409 /* deactivate pins to sleep state */ 2446 /* deactivate pins to sleep state */
2410 for (i = 0; i < card->num_rtd; i++) { 2447 for (i = 0; i < card->num_rtd; i++) {
@@ -3242,8 +3279,8 @@ int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
3242 widgets[i].name = wname; 3279 widgets[i].name = wname;
3243 } 3280 }
3244 3281
3245 card->dapm_widgets = widgets; 3282 card->of_dapm_widgets = widgets;
3246 card->num_dapm_widgets = num_widgets; 3283 card->num_of_dapm_widgets = num_widgets;
3247 3284
3248 return 0; 3285 return 0;
3249} 3286}
@@ -3327,8 +3364,8 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
3327 } 3364 }
3328 } 3365 }
3329 3366
3330 card->num_dapm_routes = num_routes; 3367 card->num_of_dapm_routes = num_routes;
3331 card->dapm_routes = routes; 3368 card->of_dapm_routes = routes;
3332 3369
3333 return 0; 3370 return 0;
3334} 3371}
@@ -3587,26 +3624,7 @@ EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_codecs);
3587 3624
3588static int __init snd_soc_init(void) 3625static int __init snd_soc_init(void)
3589{ 3626{
3590#ifdef CONFIG_DEBUG_FS 3627 snd_soc_debugfs_init();
3591 snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL);
3592 if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) {
3593 pr_warn("ASoC: Failed to create debugfs directory\n");
3594 snd_soc_debugfs_root = NULL;
3595 }
3596
3597 if (!debugfs_create_file("codecs", 0444, snd_soc_debugfs_root, NULL,
3598 &codec_list_fops))
3599 pr_warn("ASoC: Failed to create CODEC list debugfs file\n");
3600
3601 if (!debugfs_create_file("dais", 0444, snd_soc_debugfs_root, NULL,
3602 &dai_list_fops))
3603 pr_warn("ASoC: Failed to create DAI list debugfs file\n");
3604
3605 if (!debugfs_create_file("platforms", 0444, snd_soc_debugfs_root, NULL,
3606 &platform_list_fops))
3607 pr_warn("ASoC: Failed to create platform list debugfs file\n");
3608#endif
3609
3610 snd_soc_util_init(); 3628 snd_soc_util_init();
3611 3629
3612 return platform_driver_register(&soc_driver); 3630 return platform_driver_register(&soc_driver);
@@ -3616,9 +3634,9 @@ module_init(snd_soc_init);
3616static void __exit snd_soc_exit(void) 3634static void __exit snd_soc_exit(void)
3617{ 3635{
3618 snd_soc_util_exit(); 3636 snd_soc_util_exit();
3637 snd_soc_debugfs_exit();
3619 3638
3620#ifdef CONFIG_DEBUG_FS 3639#ifdef CONFIG_DEBUG_FS
3621 debugfs_remove_recursive(snd_soc_debugfs_root);
3622#endif 3640#endif
3623 platform_driver_unregister(&soc_driver); 3641 platform_driver_unregister(&soc_driver);
3624} 3642}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index b6f88202b8c9..defe0f0082b5 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -473,16 +473,6 @@ struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
473} 473}
474EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_dapm); 474EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_dapm);
475 475
476/**
477 * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
478 * @kcontrol: The kcontrol
479 */
480struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(struct snd_kcontrol *kcontrol)
481{
482 return snd_soc_dapm_to_codec(snd_soc_dapm_kcontrol_dapm(kcontrol));
483}
484EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_codec);
485
486static void dapm_reset(struct snd_soc_card *card) 476static void dapm_reset(struct snd_soc_card *card)
487{ 477{
488 struct snd_soc_dapm_widget *w; 478 struct snd_soc_dapm_widget *w;
@@ -853,6 +843,36 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w)
853 return 0; 843 return 0;
854} 844}
855 845
846/* create new dapm dai link control */
847static int dapm_new_dai_link(struct snd_soc_dapm_widget *w)
848{
849 int i, ret;
850 struct snd_kcontrol *kcontrol;
851 struct snd_soc_dapm_context *dapm = w->dapm;
852 struct snd_card *card = dapm->card->snd_card;
853
854 /* create control for links with > 1 config */
855 if (w->num_params <= 1)
856 return 0;
857
858 /* add kcontrol */
859 for (i = 0; i < w->num_kcontrols; i++) {
860 kcontrol = snd_soc_cnew(&w->kcontrol_news[i], w,
861 w->name, NULL);
862 ret = snd_ctl_add(card, kcontrol);
863 if (ret < 0) {
864 dev_err(dapm->dev,
865 "ASoC: failed to add widget %s dapm kcontrol %s: %d\n",
866 w->name, w->kcontrol_news[i].name, ret);
867 return ret;
868 }
869 kcontrol->private_data = w;
870 w->kcontrols[i] = kcontrol;
871 }
872
873 return 0;
874}
875
856/* We implement power down on suspend by checking the power state of 876/* We implement power down on suspend by checking the power state of
857 * the ALSA card - when we are suspending the ALSA state for the card 877 * the ALSA card - when we are suspending the ALSA state for the card
858 * is set to D3. 878 * is set to D3.
@@ -1898,6 +1918,9 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
1898{ 1918{
1899 struct dentry *d; 1919 struct dentry *d;
1900 1920
1921 if (!parent)
1922 return;
1923
1901 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent); 1924 dapm->debugfs_dapm = debugfs_create_dir("dapm", parent);
1902 1925
1903 if (!dapm->debugfs_dapm) { 1926 if (!dapm->debugfs_dapm) {
@@ -2719,6 +2742,9 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card)
2719 case snd_soc_dapm_out_drv: 2742 case snd_soc_dapm_out_drv:
2720 dapm_new_pga(w); 2743 dapm_new_pga(w);
2721 break; 2744 break;
2745 case snd_soc_dapm_dai_link:
2746 dapm_new_dai_link(w);
2747 break;
2722 default: 2748 default:
2723 break; 2749 break;
2724 } 2750 }
@@ -3193,7 +3219,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
3193{ 3219{
3194 struct snd_soc_dapm_path *source_p, *sink_p; 3220 struct snd_soc_dapm_path *source_p, *sink_p;
3195 struct snd_soc_dai *source, *sink; 3221 struct snd_soc_dai *source, *sink;
3196 const struct snd_soc_pcm_stream *config = w->params; 3222 const struct snd_soc_pcm_stream *config = w->params + w->params_select;
3197 struct snd_pcm_substream substream; 3223 struct snd_pcm_substream substream;
3198 struct snd_pcm_hw_params *params = NULL; 3224 struct snd_pcm_hw_params *params = NULL;
3199 u64 fmt; 3225 u64 fmt;
@@ -3285,22 +3311,97 @@ out:
3285 return ret; 3311 return ret;
3286} 3312}
3287 3313
3314static int snd_soc_dapm_dai_link_get(struct snd_kcontrol *kcontrol,
3315 struct snd_ctl_elem_value *ucontrol)
3316{
3317 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
3318
3319 ucontrol->value.integer.value[0] = w->params_select;
3320
3321 return 0;
3322}
3323
3324static int snd_soc_dapm_dai_link_put(struct snd_kcontrol *kcontrol,
3325 struct snd_ctl_elem_value *ucontrol)
3326{
3327 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
3328
3329 /* Can't change the config when widget is already powered */
3330 if (w->power)
3331 return -EBUSY;
3332
3333 if (ucontrol->value.integer.value[0] == w->params_select)
3334 return 0;
3335
3336 if (ucontrol->value.integer.value[0] >= w->num_params)
3337 return -EINVAL;
3338
3339 w->params_select = ucontrol->value.integer.value[0];
3340
3341 return 0;
3342}
3343
3288int snd_soc_dapm_new_pcm(struct snd_soc_card *card, 3344int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
3289 const struct snd_soc_pcm_stream *params, 3345 const struct snd_soc_pcm_stream *params,
3346 unsigned int num_params,
3290 struct snd_soc_dapm_widget *source, 3347 struct snd_soc_dapm_widget *source,
3291 struct snd_soc_dapm_widget *sink) 3348 struct snd_soc_dapm_widget *sink)
3292{ 3349{
3293 struct snd_soc_dapm_widget template; 3350 struct snd_soc_dapm_widget template;
3294 struct snd_soc_dapm_widget *w; 3351 struct snd_soc_dapm_widget *w;
3295 size_t len;
3296 char *link_name; 3352 char *link_name;
3297 int ret; 3353 int ret, count;
3298 3354 unsigned long private_value;
3299 len = strlen(source->name) + strlen(sink->name) + 2; 3355 const char **w_param_text;
3300 link_name = devm_kzalloc(card->dev, len, GFP_KERNEL); 3356 struct soc_enum w_param_enum[] = {
3301 if (!link_name) 3357 SOC_ENUM_SINGLE(0, 0, 0, NULL),
3358 };
3359 struct snd_kcontrol_new kcontrol_dai_link[] = {
3360 SOC_ENUM_EXT(NULL, w_param_enum[0],
3361 snd_soc_dapm_dai_link_get,
3362 snd_soc_dapm_dai_link_put),
3363 };
3364 const struct snd_soc_pcm_stream *config = params;
3365
3366 w_param_text = devm_kcalloc(card->dev, num_params,
3367 sizeof(char *), GFP_KERNEL);
3368 if (!w_param_text)
3302 return -ENOMEM; 3369 return -ENOMEM;
3303 snprintf(link_name, len, "%s-%s", source->name, sink->name); 3370
3371 link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s",
3372 source->name, sink->name);
3373 if (!link_name) {
3374 ret = -ENOMEM;
3375 goto outfree_w_param;
3376 }
3377
3378 for (count = 0 ; count < num_params; count++) {
3379 if (!config->stream_name) {
3380 dev_warn(card->dapm.dev,
3381 "ASoC: anonymous config %d for dai link %s\n",
3382 count, link_name);
3383 w_param_text[count] =
3384 devm_kasprintf(card->dev, GFP_KERNEL,
3385 "Anonymous Configuration %d",
3386 count);
3387 if (!w_param_text[count]) {
3388 ret = -ENOMEM;
3389 goto outfree_link_name;
3390 }
3391 } else {
3392 w_param_text[count] = devm_kmemdup(card->dev,
3393 config->stream_name,
3394 strlen(config->stream_name) + 1,
3395 GFP_KERNEL);
3396 if (!w_param_text[count]) {
3397 ret = -ENOMEM;
3398 goto outfree_link_name;
3399 }
3400 }
3401 config++;
3402 }
3403 w_param_enum[0].items = num_params;
3404 w_param_enum[0].texts = w_param_text;
3304 3405
3305 memset(&template, 0, sizeof(template)); 3406 memset(&template, 0, sizeof(template));
3306 template.reg = SND_SOC_NOPM; 3407 template.reg = SND_SOC_NOPM;
@@ -3309,6 +3410,30 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
3309 template.event = snd_soc_dai_link_event; 3410 template.event = snd_soc_dai_link_event;
3310 template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3411 template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
3311 SND_SOC_DAPM_PRE_PMD; 3412 SND_SOC_DAPM_PRE_PMD;
3413 template.num_kcontrols = 1;
3414 /* duplicate w_param_enum on heap so that memory persists */
3415 private_value =
3416 (unsigned long) devm_kmemdup(card->dev,
3417 (void *)(kcontrol_dai_link[0].private_value),
3418 sizeof(struct soc_enum), GFP_KERNEL);
3419 if (!private_value) {
3420 dev_err(card->dev, "ASoC: Failed to create control for %s widget\n",
3421 link_name);
3422 ret = -ENOMEM;
3423 goto outfree_link_name;
3424 }
3425 kcontrol_dai_link[0].private_value = private_value;
3426 /* duplicate kcontrol_dai_link on heap so that memory persists */
3427 template.kcontrol_news =
3428 devm_kmemdup(card->dev, &kcontrol_dai_link[0],
3429 sizeof(struct snd_kcontrol_new),
3430 GFP_KERNEL);
3431 if (!template.kcontrol_news) {
3432 dev_err(card->dev, "ASoC: Failed to create control for %s widget\n",
3433 link_name);
3434 ret = -ENOMEM;
3435 goto outfree_private_value;
3436 }
3312 3437
3313 dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name); 3438 dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name);
3314 3439
@@ -3316,15 +3441,32 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
3316 if (!w) { 3441 if (!w) {
3317 dev_err(card->dev, "ASoC: Failed to create %s widget\n", 3442 dev_err(card->dev, "ASoC: Failed to create %s widget\n",
3318 link_name); 3443 link_name);
3319 return -ENOMEM; 3444 ret = -ENOMEM;
3445 goto outfree_kcontrol_news;
3320 } 3446 }
3321 3447
3322 w->params = params; 3448 w->params = params;
3449 w->num_params = num_params;
3323 3450
3324 ret = snd_soc_dapm_add_path(&card->dapm, source, w, NULL, NULL); 3451 ret = snd_soc_dapm_add_path(&card->dapm, source, w, NULL, NULL);
3325 if (ret) 3452 if (ret)
3326 return ret; 3453 goto outfree_w;
3327 return snd_soc_dapm_add_path(&card->dapm, w, sink, NULL, NULL); 3454 return snd_soc_dapm_add_path(&card->dapm, w, sink, NULL, NULL);
3455
3456outfree_w:
3457 devm_kfree(card->dev, w);
3458outfree_kcontrol_news:
3459 devm_kfree(card->dev, (void *)template.kcontrol_news);
3460outfree_private_value:
3461 devm_kfree(card->dev, (void *)private_value);
3462outfree_link_name:
3463 devm_kfree(card->dev, link_name);
3464outfree_w_param:
3465 for (count = 0 ; count < num_params; count++)
3466 devm_kfree(card->dev, (void *)w_param_text[count]);
3467 devm_kfree(card->dev, w_param_text);
3468
3469 return ret;
3328} 3470}
3329 3471
3330int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, 3472int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 4380dcc064a5..9f60c25c4568 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -22,30 +22,42 @@
22#include <trace/events/asoc.h> 22#include <trace/events/asoc.h>
23 23
24/** 24/**
25 * snd_soc_jack_new - Create a new jack 25 * snd_soc_card_jack_new - Create a new jack
26 * @codec: ASoC codec 26 * @card: ASoC card
27 * @id: an identifying string for this jack 27 * @id: an identifying string for this jack
28 * @type: a bitmask of enum snd_jack_type values that can be detected by 28 * @type: a bitmask of enum snd_jack_type values that can be detected by
29 * this jack 29 * this jack
30 * @jack: structure to use for the jack 30 * @jack: structure to use for the jack
31 * @pins: Array of jack pins to be added to the jack or NULL
32 * @num_pins: Number of elements in the @pins array
31 * 33 *
32 * Creates a new jack object. 34 * Creates a new jack object.
33 * 35 *
34 * Returns zero if successful, or a negative error code on failure. 36 * Returns zero if successful, or a negative error code on failure.
35 * On success jack will be initialised. 37 * On success jack will be initialised.
36 */ 38 */
37int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type, 39int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,
38 struct snd_soc_jack *jack) 40 struct snd_soc_jack *jack, struct snd_soc_jack_pin *pins,
41 unsigned int num_pins)
39{ 42{
43 int ret;
44
40 mutex_init(&jack->mutex); 45 mutex_init(&jack->mutex);
41 jack->codec = codec; 46 jack->card = card;
42 INIT_LIST_HEAD(&jack->pins); 47 INIT_LIST_HEAD(&jack->pins);
43 INIT_LIST_HEAD(&jack->jack_zones); 48 INIT_LIST_HEAD(&jack->jack_zones);
44 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier); 49 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier);
45 50
46 return snd_jack_new(codec->component.card->snd_card, id, type, &jack->jack); 51 ret = snd_jack_new(card->snd_card, id, type, &jack->jack);
52 if (ret)
53 return ret;
54
55 if (num_pins)
56 return snd_soc_jack_add_pins(jack, num_pins, pins);
57
58 return 0;
47} 59}
48EXPORT_SYMBOL_GPL(snd_soc_jack_new); 60EXPORT_SYMBOL_GPL(snd_soc_card_jack_new);
49 61
50/** 62/**
51 * snd_soc_jack_report - Report the current status for a jack 63 * snd_soc_jack_report - Report the current status for a jack
@@ -63,7 +75,6 @@ EXPORT_SYMBOL_GPL(snd_soc_jack_new);
63 */ 75 */
64void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) 76void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
65{ 77{
66 struct snd_soc_codec *codec;
67 struct snd_soc_dapm_context *dapm; 78 struct snd_soc_dapm_context *dapm;
68 struct snd_soc_jack_pin *pin; 79 struct snd_soc_jack_pin *pin;
69 unsigned int sync = 0; 80 unsigned int sync = 0;
@@ -74,8 +85,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
74 if (!jack) 85 if (!jack)
75 return; 86 return;
76 87
77 codec = jack->codec; 88 dapm = &jack->card->dapm;
78 dapm = &codec->dapm;
79 89
80 mutex_lock(&jack->mutex); 90 mutex_lock(&jack->mutex);
81 91
@@ -175,12 +185,12 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
175 185
176 for (i = 0; i < count; i++) { 186 for (i = 0; i < count; i++) {
177 if (!pins[i].pin) { 187 if (!pins[i].pin) {
178 dev_err(jack->codec->dev, "ASoC: No name for pin %d\n", 188 dev_err(jack->card->dev, "ASoC: No name for pin %d\n",
179 i); 189 i);
180 return -EINVAL; 190 return -EINVAL;
181 } 191 }
182 if (!pins[i].mask) { 192 if (!pins[i].mask) {
183 dev_err(jack->codec->dev, "ASoC: No mask for pin %d" 193 dev_err(jack->card->dev, "ASoC: No mask for pin %d"
184 " (%s)\n", i, pins[i].pin); 194 " (%s)\n", i, pins[i].pin);
185 return -EINVAL; 195 return -EINVAL;
186 } 196 }
@@ -260,7 +270,7 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
260static irqreturn_t gpio_handler(int irq, void *data) 270static irqreturn_t gpio_handler(int irq, void *data)
261{ 271{
262 struct snd_soc_jack_gpio *gpio = data; 272 struct snd_soc_jack_gpio *gpio = data;
263 struct device *dev = gpio->jack->codec->component.card->dev; 273 struct device *dev = gpio->jack->card->dev;
264 274
265 trace_snd_soc_jack_irq(gpio->name); 275 trace_snd_soc_jack_irq(gpio->name);
266 276
@@ -299,7 +309,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
299 309
300 for (i = 0; i < count; i++) { 310 for (i = 0; i < count; i++) {
301 if (!gpios[i].name) { 311 if (!gpios[i].name) {
302 dev_err(jack->codec->dev, 312 dev_err(jack->card->dev,
303 "ASoC: No name for gpio at index %d\n", i); 313 "ASoC: No name for gpio at index %d\n", i);
304 ret = -EINVAL; 314 ret = -EINVAL;
305 goto undo; 315 goto undo;
@@ -320,7 +330,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
320 } else { 330 } else {
321 /* legacy GPIO number */ 331 /* legacy GPIO number */
322 if (!gpio_is_valid(gpios[i].gpio)) { 332 if (!gpio_is_valid(gpios[i].gpio)) {
323 dev_err(jack->codec->dev, 333 dev_err(jack->card->dev,
324 "ASoC: Invalid gpio %d\n", 334 "ASoC: Invalid gpio %d\n",
325 gpios[i].gpio); 335 gpios[i].gpio);
326 ret = -EINVAL; 336 ret = -EINVAL;
@@ -350,7 +360,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
350 if (gpios[i].wake) { 360 if (gpios[i].wake) {
351 ret = irq_set_irq_wake(gpiod_to_irq(gpios[i].desc), 1); 361 ret = irq_set_irq_wake(gpiod_to_irq(gpios[i].desc), 1);
352 if (ret != 0) 362 if (ret != 0)
353 dev_err(jack->codec->dev, 363 dev_err(jack->card->dev,
354 "ASoC: Failed to mark GPIO at index %d as wake source: %d\n", 364 "ASoC: Failed to mark GPIO at index %d as wake source: %d\n",
355 i, ret); 365 i, ret);
356 } 366 }
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 6b0136e7cb88..35fe58f4fa86 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1097,8 +1097,9 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
1097 stream ? "<-" : "->", be->dai_link->name); 1097 stream ? "<-" : "->", be->dai_link->name);
1098 1098
1099#ifdef CONFIG_DEBUG_FS 1099#ifdef CONFIG_DEBUG_FS
1100 dpcm->debugfs_state = debugfs_create_u32(be->dai_link->name, 0644, 1100 if (fe->debugfs_dpcm_root)
1101 fe->debugfs_dpcm_root, &dpcm->state); 1101 dpcm->debugfs_state = debugfs_create_u32(be->dai_link->name, 0644,
1102 fe->debugfs_dpcm_root, &dpcm->state);
1102#endif 1103#endif
1103 return 1; 1104 return 1;
1104} 1105}
@@ -2511,6 +2512,7 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2511 /* DAPM dai link stream work */ 2512 /* DAPM dai link stream work */
2512 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); 2513 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
2513 2514
2515 pcm->nonatomic = rtd->dai_link->nonatomic;
2514 rtd->pcm = pcm; 2516 rtd->pcm = pcm;
2515 pcm->private_data = rtd; 2517 pcm->private_data = rtd;
2516 2518
@@ -2802,10 +2804,13 @@ static const struct file_operations dpcm_state_fops = {
2802 .llseek = default_llseek, 2804 .llseek = default_llseek,
2803}; 2805};
2804 2806
2805int soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd) 2807void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd)
2806{ 2808{
2807 if (!rtd->dai_link) 2809 if (!rtd->dai_link)
2808 return 0; 2810 return;
2811
2812 if (!rtd->card->debugfs_card_root)
2813 return;
2809 2814
2810 rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name, 2815 rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name,
2811 rtd->card->debugfs_card_root); 2816 rtd->card->debugfs_card_root);
@@ -2813,13 +2818,11 @@ int soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd)
2813 dev_dbg(rtd->dev, 2818 dev_dbg(rtd->dev,
2814 "ASoC: Failed to create dpcm debugfs directory %s\n", 2819 "ASoC: Failed to create dpcm debugfs directory %s\n",
2815 rtd->dai_link->name); 2820 rtd->dai_link->name);
2816 return -EINVAL; 2821 return;
2817 } 2822 }
2818 2823
2819 rtd->debugfs_dpcm_state = debugfs_create_file("state", 0444, 2824 rtd->debugfs_dpcm_state = debugfs_create_file("state", 0444,
2820 rtd->debugfs_dpcm_root, 2825 rtd->debugfs_dpcm_root,
2821 rtd, &dpcm_state_fops); 2826 rtd, &dpcm_state_fops);
2822
2823 return 0;
2824} 2827}
2825#endif 2828#endif
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index 769aca2fc5f5..ba272e21a6fa 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -101,16 +101,12 @@ static const struct snd_kcontrol_new tegra_alc5632_controls[] = {
101 101
102static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) 102static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
103{ 103{
104 struct snd_soc_dai *codec_dai = rtd->codec_dai;
105 struct snd_soc_codec *codec = codec_dai->codec;
106 struct snd_soc_dapm_context *dapm = &codec->dapm;
107 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(rtd->card); 104 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(rtd->card);
108 105
109 snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, 106 snd_soc_card_jack_new(rtd->card, "Headset Jack", SND_JACK_HEADSET,
110 &tegra_alc5632_hs_jack); 107 &tegra_alc5632_hs_jack,
111 snd_soc_jack_add_pins(&tegra_alc5632_hs_jack, 108 tegra_alc5632_hs_jack_pins,
112 ARRAY_SIZE(tegra_alc5632_hs_jack_pins), 109 ARRAY_SIZE(tegra_alc5632_hs_jack_pins));
113 tegra_alc5632_hs_jack_pins);
114 110
115 if (gpio_is_valid(machine->gpio_hp_det)) { 111 if (gpio_is_valid(machine->gpio_hp_det)) {
116 tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det; 112 tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det;
@@ -119,7 +115,7 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
119 &tegra_alc5632_hp_jack_gpio); 115 &tegra_alc5632_hp_jack_gpio);
120 } 116 }
121 117
122 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); 118 snd_soc_dapm_force_enable_pin(&rtd->card->dapm, "MICBIAS1");
123 119
124 return 0; 120 return 0;
125} 121}
diff --git a/sound/soc/tegra/tegra_max98090.c b/sound/soc/tegra/tegra_max98090.c
index af3fb997b752..902da36581d1 100644
--- a/sound/soc/tegra/tegra_max98090.c
+++ b/sound/soc/tegra/tegra_max98090.c
@@ -133,24 +133,26 @@ static const struct snd_soc_dapm_widget tegra_max98090_dapm_widgets[] = {
133 SND_SOC_DAPM_HP("Headphones", NULL), 133 SND_SOC_DAPM_HP("Headphones", NULL),
134 SND_SOC_DAPM_SPK("Speakers", NULL), 134 SND_SOC_DAPM_SPK("Speakers", NULL),
135 SND_SOC_DAPM_MIC("Mic Jack", NULL), 135 SND_SOC_DAPM_MIC("Mic Jack", NULL),
136 SND_SOC_DAPM_MIC("Int Mic", NULL),
136}; 137};
137 138
138static const struct snd_kcontrol_new tegra_max98090_controls[] = { 139static const struct snd_kcontrol_new tegra_max98090_controls[] = {
140 SOC_DAPM_PIN_SWITCH("Headphones"),
139 SOC_DAPM_PIN_SWITCH("Speakers"), 141 SOC_DAPM_PIN_SWITCH("Speakers"),
142 SOC_DAPM_PIN_SWITCH("Mic Jack"),
143 SOC_DAPM_PIN_SWITCH("Int Mic"),
140}; 144};
141 145
142static int tegra_max98090_asoc_init(struct snd_soc_pcm_runtime *rtd) 146static int tegra_max98090_asoc_init(struct snd_soc_pcm_runtime *rtd)
143{ 147{
144 struct snd_soc_dai *codec_dai = rtd->codec_dai;
145 struct snd_soc_codec *codec = codec_dai->codec;
146 struct tegra_max98090 *machine = snd_soc_card_get_drvdata(rtd->card); 148 struct tegra_max98090 *machine = snd_soc_card_get_drvdata(rtd->card);
147 149
148 if (gpio_is_valid(machine->gpio_hp_det)) { 150 if (gpio_is_valid(machine->gpio_hp_det)) {
149 snd_soc_jack_new(codec, "Headphones", SND_JACK_HEADPHONE, 151 snd_soc_card_jack_new(rtd->card, "Headphones",
150 &tegra_max98090_hp_jack); 152 SND_JACK_HEADPHONE,
151 snd_soc_jack_add_pins(&tegra_max98090_hp_jack, 153 &tegra_max98090_hp_jack,
152 ARRAY_SIZE(tegra_max98090_hp_jack_pins), 154 tegra_max98090_hp_jack_pins,
153 tegra_max98090_hp_jack_pins); 155 ARRAY_SIZE(tegra_max98090_hp_jack_pins));
154 156
155 tegra_max98090_hp_jack_gpio.gpio = machine->gpio_hp_det; 157 tegra_max98090_hp_jack_gpio.gpio = machine->gpio_hp_det;
156 snd_soc_jack_add_gpios(&tegra_max98090_hp_jack, 158 snd_soc_jack_add_gpios(&tegra_max98090_hp_jack,
@@ -159,11 +161,11 @@ static int tegra_max98090_asoc_init(struct snd_soc_pcm_runtime *rtd)
159 } 161 }
160 162
161 if (gpio_is_valid(machine->gpio_mic_det)) { 163 if (gpio_is_valid(machine->gpio_mic_det)) {
162 snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, 164 snd_soc_card_jack_new(rtd->card, "Mic Jack",
163 &tegra_max98090_mic_jack); 165 SND_JACK_MICROPHONE,
164 snd_soc_jack_add_pins(&tegra_max98090_mic_jack, 166 &tegra_max98090_mic_jack,
165 ARRAY_SIZE(tegra_max98090_mic_jack_pins), 167 tegra_max98090_mic_jack_pins,
166 tegra_max98090_mic_jack_pins); 168 ARRAY_SIZE(tegra_max98090_mic_jack_pins));
167 169
168 tegra_max98090_mic_jack_gpio.gpio = machine->gpio_mic_det; 170 tegra_max98090_mic_jack_gpio.gpio = machine->gpio_mic_det;
169 snd_soc_jack_add_gpios(&tegra_max98090_mic_jack, 171 snd_soc_jack_add_gpios(&tegra_max98090_mic_jack,
diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c
index ed759a3076b8..773daecaa5e8 100644
--- a/sound/soc/tegra/tegra_rt5640.c
+++ b/sound/soc/tegra/tegra_rt5640.c
@@ -108,15 +108,11 @@ static const struct snd_kcontrol_new tegra_rt5640_controls[] = {
108 108
109static int tegra_rt5640_asoc_init(struct snd_soc_pcm_runtime *rtd) 109static int tegra_rt5640_asoc_init(struct snd_soc_pcm_runtime *rtd)
110{ 110{
111 struct snd_soc_dai *codec_dai = rtd->codec_dai;
112 struct snd_soc_codec *codec = codec_dai->codec;
113 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(rtd->card); 111 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(rtd->card);
114 112
115 snd_soc_jack_new(codec, "Headphones", SND_JACK_HEADPHONE, 113 snd_soc_card_jack_new(rtd->card, "Headphones", SND_JACK_HEADPHONE,
116 &tegra_rt5640_hp_jack); 114 &tegra_rt5640_hp_jack, tegra_rt5640_hp_jack_pins,
117 snd_soc_jack_add_pins(&tegra_rt5640_hp_jack, 115 ARRAY_SIZE(tegra_rt5640_hp_jack_pins));
118 ARRAY_SIZE(tegra_rt5640_hp_jack_pins),
119 tegra_rt5640_hp_jack_pins);
120 116
121 if (gpio_is_valid(machine->gpio_hp_det)) { 117 if (gpio_is_valid(machine->gpio_hp_det)) {
122 tegra_rt5640_hp_jack_gpio.gpio = machine->gpio_hp_det; 118 tegra_rt5640_hp_jack_gpio.gpio = machine->gpio_hp_det;
diff --git a/sound/soc/tegra/tegra_rt5677.c b/sound/soc/tegra/tegra_rt5677.c
index e4cf978a6e3a..1470873ecde6 100644
--- a/sound/soc/tegra/tegra_rt5677.c
+++ b/sound/soc/tegra/tegra_rt5677.c
@@ -141,15 +141,11 @@ static const struct snd_kcontrol_new tegra_rt5677_controls[] = {
141 141
142static int tegra_rt5677_asoc_init(struct snd_soc_pcm_runtime *rtd) 142static int tegra_rt5677_asoc_init(struct snd_soc_pcm_runtime *rtd)
143{ 143{
144 struct snd_soc_dai *codec_dai = rtd->codec_dai;
145 struct snd_soc_codec *codec = codec_dai->codec;
146 struct snd_soc_dapm_context *dapm = &codec->dapm;
147 struct tegra_rt5677 *machine = snd_soc_card_get_drvdata(rtd->card); 144 struct tegra_rt5677 *machine = snd_soc_card_get_drvdata(rtd->card);
148 145
149 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, 146 snd_soc_card_jack_new(rtd->card, "Headphone Jack", SND_JACK_HEADPHONE,
150 &tegra_rt5677_hp_jack); 147 &tegra_rt5677_hp_jack,
151 snd_soc_jack_add_pins(&tegra_rt5677_hp_jack, 1, 148 &tegra_rt5677_hp_jack_pins, 1);
152 &tegra_rt5677_hp_jack_pins);
153 149
154 if (gpio_is_valid(machine->gpio_hp_det)) { 150 if (gpio_is_valid(machine->gpio_hp_det)) {
155 tegra_rt5677_hp_jack_gpio.gpio = machine->gpio_hp_det; 151 tegra_rt5677_hp_jack_gpio.gpio = machine->gpio_hp_det;
@@ -158,10 +154,9 @@ static int tegra_rt5677_asoc_init(struct snd_soc_pcm_runtime *rtd)
158 } 154 }
159 155
160 156
161 snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, 157 snd_soc_card_jack_new(rtd->card, "Mic Jack", SND_JACK_MICROPHONE,
162 &tegra_rt5677_mic_jack); 158 &tegra_rt5677_mic_jack,
163 snd_soc_jack_add_pins(&tegra_rt5677_mic_jack, 1, 159 &tegra_rt5677_mic_jack_pins, 1);
164 &tegra_rt5677_mic_jack_pins);
165 160
166 if (gpio_is_valid(machine->gpio_mic_present)) { 161 if (gpio_is_valid(machine->gpio_mic_present)) {
167 tegra_rt5677_mic_jack_gpio.gpio = machine->gpio_mic_present; 162 tegra_rt5677_mic_jack_gpio.gpio = machine->gpio_mic_present;
@@ -169,7 +164,7 @@ static int tegra_rt5677_asoc_init(struct snd_soc_pcm_runtime *rtd)
169 &tegra_rt5677_mic_jack_gpio); 164 &tegra_rt5677_mic_jack_gpio);
170 } 165 }
171 166
172 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); 167 snd_soc_dapm_force_enable_pin(&rtd->card->dapm, "MICBIAS1");
173 168
174 return 0; 169 return 0;
175} 170}
@@ -331,7 +326,6 @@ static const struct of_device_id tegra_rt5677_of_match[] = {
331static struct platform_driver tegra_rt5677_driver = { 326static struct platform_driver tegra_rt5677_driver = {
332 .driver = { 327 .driver = {
333 .name = DRV_NAME, 328 .name = DRV_NAME,
334 .owner = THIS_MODULE,
335 .pm = &snd_soc_pm_ops, 329 .pm = &snd_soc_pm_ops,
336 .of_match_table = tegra_rt5677_of_match, 330 .of_match_table = tegra_rt5677_of_match,
337 }, 331 },
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index e52420dae2b4..21604009bc1a 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -171,31 +171,28 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
171{ 171{
172 struct snd_soc_dai *codec_dai = rtd->codec_dai; 172 struct snd_soc_dai *codec_dai = rtd->codec_dai;
173 struct snd_soc_codec *codec = codec_dai->codec; 173 struct snd_soc_codec *codec = codec_dai->codec;
174 struct snd_soc_dapm_context *dapm = &codec->dapm;
175 struct snd_soc_card *card = rtd->card; 174 struct snd_soc_card *card = rtd->card;
176 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 175 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
177 176
178 if (gpio_is_valid(machine->gpio_hp_det)) { 177 if (gpio_is_valid(machine->gpio_hp_det)) {
179 tegra_wm8903_hp_jack_gpio.gpio = machine->gpio_hp_det; 178 tegra_wm8903_hp_jack_gpio.gpio = machine->gpio_hp_det;
180 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, 179 snd_soc_card_jack_new(rtd->card, "Headphone Jack",
181 &tegra_wm8903_hp_jack); 180 SND_JACK_HEADPHONE, &tegra_wm8903_hp_jack,
182 snd_soc_jack_add_pins(&tegra_wm8903_hp_jack, 181 tegra_wm8903_hp_jack_pins,
183 ARRAY_SIZE(tegra_wm8903_hp_jack_pins), 182 ARRAY_SIZE(tegra_wm8903_hp_jack_pins));
184 tegra_wm8903_hp_jack_pins);
185 snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack, 183 snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack,
186 1, 184 1,
187 &tegra_wm8903_hp_jack_gpio); 185 &tegra_wm8903_hp_jack_gpio);
188 } 186 }
189 187
190 snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, 188 snd_soc_card_jack_new(rtd->card, "Mic Jack", SND_JACK_MICROPHONE,
191 &tegra_wm8903_mic_jack); 189 &tegra_wm8903_mic_jack,
192 snd_soc_jack_add_pins(&tegra_wm8903_mic_jack, 190 tegra_wm8903_mic_jack_pins,
193 ARRAY_SIZE(tegra_wm8903_mic_jack_pins), 191 ARRAY_SIZE(tegra_wm8903_mic_jack_pins));
194 tegra_wm8903_mic_jack_pins);
195 wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE, 192 wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE,
196 0); 193 0);
197 194
198 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS"); 195 snd_soc_dapm_force_enable_pin(&card->dapm, "MICBIAS");
199 196
200 return 0; 197 return 0;
201} 198}
diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c
index 2868b4839bc0..6492f8143ff1 100644
--- a/sound/soc/tegra/tegra_wm9712.c
+++ b/sound/soc/tegra/tegra_wm9712.c
@@ -46,11 +46,7 @@ static const struct snd_soc_dapm_widget tegra_wm9712_dapm_widgets[] = {
46 46
47static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd) 47static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd)
48{ 48{
49 struct snd_soc_dai *codec_dai = rtd->codec_dai; 49 return snd_soc_dapm_force_enable_pin(&rtd->card->dapm, "Mic Bias");
50 struct snd_soc_codec *codec = codec_dai->codec;
51 struct snd_soc_dapm_context *dapm = &codec->dapm;
52
53 return snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
54} 50}
55 51
56static struct snd_soc_dai_link tegra_wm9712_dai = { 52static struct snd_soc_dai_link tegra_wm9712_dai = {
diff --git a/sound/soc/ux500/mop500_ab8500.c b/sound/soc/ux500/mop500_ab8500.c
index aa65370db82a..b81a7a4c938b 100644
--- a/sound/soc/ux500/mop500_ab8500.c
+++ b/sound/soc/ux500/mop500_ab8500.c
@@ -362,7 +362,7 @@ struct snd_soc_ops mop500_ab8500_ops[] = {
362 362
363int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd) 363int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd)
364{ 364{
365 struct snd_soc_codec *codec = rtd->codec; 365 struct snd_soc_dapm_context *dapm = &rtd->card->dapm;
366 struct device *dev = rtd->card->dev; 366 struct device *dev = rtd->card->dev;
367 struct mop500_ab8500_drvdata *drvdata; 367 struct mop500_ab8500_drvdata *drvdata;
368 int ret; 368 int ret;
@@ -407,23 +407,23 @@ int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd)
407 return ret; 407 return ret;
408 } 408 }
409 409
410 ret = snd_soc_dapm_disable_pin(&codec->dapm, "Earpiece"); 410 ret = snd_soc_dapm_disable_pin(dapm, "Earpiece");
411 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Speaker Left"); 411 ret |= snd_soc_dapm_disable_pin(dapm, "Speaker Left");
412 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Speaker Right"); 412 ret |= snd_soc_dapm_disable_pin(dapm, "Speaker Right");
413 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineOut Left"); 413 ret |= snd_soc_dapm_disable_pin(dapm, "LineOut Left");
414 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineOut Right"); 414 ret |= snd_soc_dapm_disable_pin(dapm, "LineOut Right");
415 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Vibra 1"); 415 ret |= snd_soc_dapm_disable_pin(dapm, "Vibra 1");
416 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Vibra 2"); 416 ret |= snd_soc_dapm_disable_pin(dapm, "Vibra 2");
417 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Mic 1"); 417 ret |= snd_soc_dapm_disable_pin(dapm, "Mic 1");
418 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Mic 2"); 418 ret |= snd_soc_dapm_disable_pin(dapm, "Mic 2");
419 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineIn Left"); 419 ret |= snd_soc_dapm_disable_pin(dapm, "LineIn Left");
420 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineIn Right"); 420 ret |= snd_soc_dapm_disable_pin(dapm, "LineIn Right");
421 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 1"); 421 ret |= snd_soc_dapm_disable_pin(dapm, "DMic 1");
422 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 2"); 422 ret |= snd_soc_dapm_disable_pin(dapm, "DMic 2");
423 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 3"); 423 ret |= snd_soc_dapm_disable_pin(dapm, "DMic 3");
424 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 4"); 424 ret |= snd_soc_dapm_disable_pin(dapm, "DMic 4");
425 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 5"); 425 ret |= snd_soc_dapm_disable_pin(dapm, "DMic 5");
426 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 6"); 426 ret |= snd_soc_dapm_disable_pin(dapm, "DMic 6");
427 427
428 return ret; 428 return ret;
429} 429}