Merge tag 'sound-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 6 Jun 2018 16:08:38 +0000 (09:08 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 6 Jun 2018 16:08:38 +0000 (09:08 -0700)
Pull sound updates from Takashi Iwai:
 "We've got many code additions at this cycle as a result of quite a few
  new drivers. Below are highlights:

  Core stuff:
   - Fix the long-standing issue with the device registration order; the
     control device is now registered at last
   - PCM locking code cleanups for RT kernels
   - Fixes for possible races in ALSA timer resolution accesses
   - TLV offset definitions in uapi

  ASoC:
   - Many fixes for the topology stuff, including fixes for v4 ABI
     compatibility
   - Lots of cleanups / quirks for Intel platforms based on Realtek
     CODECs
   - Continued componentization works, removing legacy CODEC stuff
   - Conversion of OMAP DMA to the new, more standard SDMA-PCM driver
   - Fixes and updates to Cirrus Logic SoC drivers
   - New Qualcomm DSP support
   - New drivers for Analog SSM2305, Atmel I2S controllers, Mediatek
     MT6351, MT6797 and MT7622, Qualcomm DSPs, Realtek RT1305, RT1306
     and RT5668 and TI TSCS454

  HD-audio:
   - Finally better support for some CA0132 boards, allowing Windows
     firmware
   - HP Spectre x360 support along with a bulk of COEF stuff
   - Blacklisting power save default some known boards reported on
     Fedora

  USB-audio:
   - Continued improvements on UAC3 support; now BADD is supported
   - Fixes / improvements for Dell WD15 dock
   - Allow DMA coherent pages for PCM buffers for ARCH, MIPS & co

  Others:
   - New Xen sound frontend driver support
   - Cache implementation and other improvements for FireWire DICE
   - Conversions to octal permissions in allover places"

* tag 'sound-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (386 commits)
  ASoC: dapm: delete dapm_kcontrol_data paths list before freeing it
  ALSA: usb-audio: remove redundant check on err
  ASoC: topology: Move skl-tplg-interface.h to uapi
  ASoC: topology: Move v4 manifest header data structures to uapi
  ASoC: topology: Improve backwards compatibility with v4 topology files
  ALSA: pci/hda: Remove unused, broken, header file
  ASoC: TSCS454: Add Support
  ASoC: Intel: kbl: Move codec sysclk config to codec_init function
  ASoC: simple-card: set cpu dai clk in hw_params
  ALSA: hda - Handle kzalloc() failure in snd_hda_attach_pcm_stream()
  ALSA: oxygen: use match_string() helper
  ASoC: dapm: use match_string() helper
  ASoC: max98095: use match_string() helper
  ASoC: max98088: use match_string() helper
  ASoC: Intel: bytcr_rt5651: Set card long_name based on quirks
  ASoC: mt6797-mt6351: add hostless phone call path
  ASoC: mt6797: add Hostless DAI
  ASoC: mt6797: add PCM interface
  ASoC: mediatek: export mtk-afe symbols as needed
  ASoC: codecs: PCM1789: include gpio/consumer.h
  ...

383 files changed:
.mailmap
Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/adi,ssm2305.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/atmel-i2s.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/cs42xx8.txt
Documentation/devicetree/bindings/sound/fsl,asrc.txt
Documentation/devicetree/bindings/sound/fsl,esai.txt
Documentation/devicetree/bindings/sound/fsl,spdif.txt
Documentation/devicetree/bindings/sound/fsl-sai.txt
Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
Documentation/devicetree/bindings/sound/mt6351.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/mt6797-afe-pcm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/mt6797-mt6351.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/qcom,apq8096.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/qcom,q6adm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/qcom,q6afe.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/qcom,q6asm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/qcom,q6core.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/rt274.txt
Documentation/devicetree/bindings/sound/rt5514.txt
Documentation/devicetree/bindings/sound/rt5616.txt
Documentation/devicetree/bindings/sound/rt5640.txt
Documentation/devicetree/bindings/sound/rt5645.txt
Documentation/devicetree/bindings/sound/rt5651.txt
Documentation/devicetree/bindings/sound/rt5663.txt
Documentation/devicetree/bindings/sound/rt5668.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/sgtl5000.txt
Documentation/devicetree/bindings/sound/simple-card.txt
Documentation/devicetree/bindings/sound/ti,tas6424.txt
Documentation/devicetree/bindings/sound/tscs42xx.txt
Documentation/devicetree/bindings/sound/tscs454.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/wm8510.txt
Documentation/devicetree/bindings/sound/wm8523.txt
Documentation/devicetree/bindings/sound/wm8524.txt
Documentation/devicetree/bindings/sound/wm8580.txt
Documentation/devicetree/bindings/sound/wm8711.txt
Documentation/devicetree/bindings/sound/wm8728.txt
Documentation/devicetree/bindings/sound/wm8731.txt
Documentation/devicetree/bindings/sound/wm8737.txt
Documentation/devicetree/bindings/sound/wm8741.txt
Documentation/devicetree/bindings/sound/wm8750.txt
Documentation/devicetree/bindings/sound/wm8753.txt
Documentation/devicetree/bindings/sound/wm8770.txt
Documentation/devicetree/bindings/sound/wm8776.txt
Documentation/devicetree/bindings/sound/wm8804.txt
Documentation/devicetree/bindings/sound/wm8903.txt
Documentation/devicetree/bindings/sound/wm8960.txt
Documentation/devicetree/bindings/sound/wm8962.txt
Documentation/devicetree/bindings/sound/wm8994.txt
Documentation/sound/alsa-configuration.rst
Documentation/sound/hd-audio/models.rst
Documentation/sound/soc/codec.rst
Documentation/sound/soc/platform.rst
MAINTAINERS
arch/arm/mach-ep93xx/core.c
drivers/media/i2c/tda1997x.c
drivers/soc/qcom/Kconfig
drivers/soc/qcom/Makefile
drivers/soc/qcom/apr.c [new file with mode: 0644]
include/dt-bindings/soc/qcom,apr.h [new file with mode: 0644]
include/dt-bindings/sound/fsl-imx-audmux.h
include/dt-bindings/sound/qcom,q6afe.h [new file with mode: 0644]
include/dt-bindings/sound/qcom,q6asm.h [new file with mode: 0644]
include/dt-bindings/sound/rt5640.h [new file with mode: 0644]
include/linux/mfd/wm8350/audio.h
include/linux/mod_devicetable.h
include/linux/soc/qcom/apr.h [new file with mode: 0644]
include/linux/usb/audio-v2.h
include/linux/usb/audio-v3.h
include/sound/core.h
include/sound/emu10k1.h
include/sound/hdaudio.h
include/sound/memalloc.h
include/sound/omap-pcm.h [deleted file]
include/sound/rt5640.h [deleted file]
include/sound/rt5668.h [new file with mode: 0644]
include/sound/soc-dai.h
include/sound/soc.h
include/trace/events/asoc.h
include/uapi/linux/usb/audio.h
include/uapi/sound/asoc.h
include/uapi/sound/skl-tplg-interface.h [new file with mode: 0644]
include/uapi/sound/tlv.h
sound/Kconfig
sound/Makefile
sound/core/compress_offload.c
sound/core/device.c
sound/core/info.c
sound/core/init.c
sound/core/oss/mixer_oss.c
sound/core/oss/pcm_oss.c
sound/core/pcm.c
sound/core/pcm_compat.c
sound/core/pcm_lib.c
sound/core/pcm_local.h
sound/core/pcm_memory.c
sound/core/pcm_native.c
sound/core/seq/seq_ports.c
sound/core/seq/seq_timer.c
sound/core/timer.c
sound/core/vmaster.c
sound/drivers/aloop.c
sound/drivers/dummy.c
sound/drivers/mts64.c
sound/drivers/opl4/opl4_proc.c
sound/drivers/portman2x4.c
sound/firewire/bebob/bebob_proc.c
sound/firewire/dice/Makefile
sound/firewire/dice/dice-alesis.c [new file with mode: 0644]
sound/firewire/dice/dice-extension.c [new file with mode: 0644]
sound/firewire/dice/dice-interface.h
sound/firewire/dice/dice-midi.c
sound/firewire/dice/dice-mytek.c [new file with mode: 0644]
sound/firewire/dice/dice-pcm.c
sound/firewire/dice/dice-proc.c
sound/firewire/dice/dice-stream.c
sound/firewire/dice/dice-tcelectronic.c [new file with mode: 0644]
sound/firewire/dice/dice-transaction.c
sound/firewire/dice/dice.c
sound/firewire/dice/dice.h
sound/firewire/digi00x/digi00x-proc.c
sound/firewire/fireface/ff-proc.c
sound/firewire/fireworks/fireworks_proc.c
sound/firewire/isight.c
sound/firewire/motu/motu-proc.c
sound/firewire/oxfw/oxfw-proc.c
sound/firewire/oxfw/oxfw.c
sound/firewire/tascam/tascam-proc.c
sound/hda/hdac_regmap.c
sound/isa/cmi8328.c
sound/isa/msnd/msnd_pinnacle.c
sound/isa/sc6000.c
sound/pci/ac97/ac97_proc.c
sound/pci/ad1889.c
sound/pci/asihpi/asihpi.c
sound/pci/asihpi/hpioctl.c
sound/pci/ca0106/ca0106_proc.c
sound/pci/cmipci.c
sound/pci/cs46xx/cs46xx.c
sound/pci/cs46xx/cs46xx_lib.c
sound/pci/cs46xx/dsp_spos.c
sound/pci/cs46xx/dsp_spos_scb_lib.c
sound/pci/ctxfi/cttimer.c
sound/pci/ctxfi/xfi.c
sound/pci/echoaudio/echoaudio.c
sound/pci/echoaudio/echoaudio.h
sound/pci/emu10k1/emu10k1x.c
sound/pci/emu10k1/emufx.c
sound/pci/emu10k1/emupcm.c
sound/pci/emu10k1/emuproc.c
sound/pci/emu10k1/memory.c
sound/pci/hda/Kconfig
sound/pci/hda/hda_auto_parser.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_sysfs.c
sound/pci/hda/hp_x360_helper.c [new file with mode: 0644]
sound/pci/hda/local.h [deleted file]
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/ice1712/pontis.c
sound/pci/ice1712/prodigy_hifi.c
sound/pci/lola/lola_proc.c
sound/pci/oxygen/oxygen_mixer.c
sound/pci/pcxhr/pcxhr.c
sound/soc/Makefile
sound/soc/amd/acp-da7219-max98357a.c
sound/soc/amd/acp-pcm-dma.c
sound/soc/amd/acp.h
sound/soc/atmel/Kconfig
sound/soc/atmel/Makefile
sound/soc/atmel/atmel-i2s.c [new file with mode: 0644]
sound/soc/atmel/atmel_ssc_dai.c
sound/soc/bcm/Kconfig
sound/soc/cirrus/Kconfig
sound/soc/cirrus/edb93xx.c
sound/soc/cirrus/ep93xx-i2s.c
sound/soc/cirrus/snappercl15.c
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/adau17x1.c
sound/soc/codecs/cs35l35.c
sound/soc/codecs/cs43130.c
sound/soc/codecs/max98088.c
sound/soc/codecs/max98095.c
sound/soc/codecs/max9860.c
sound/soc/codecs/max9860.h
sound/soc/codecs/mt6351.c [new file with mode: 0644]
sound/soc/codecs/mt6351.h [new file with mode: 0644]
sound/soc/codecs/nau8810.c
sound/soc/codecs/nau8824.c
sound/soc/codecs/pcm1789.c
sound/soc/codecs/pcm512x-i2c.c
sound/soc/codecs/rt1305.c [new file with mode: 0644]
sound/soc/codecs/rt1305.h [new file with mode: 0644]
sound/soc/codecs/rt5640.c
sound/soc/codecs/rt5640.h
sound/soc/codecs/rt5645.c
sound/soc/codecs/rt5663.c
sound/soc/codecs/rt5663.h
sound/soc/codecs/rt5668.c [new file with mode: 0644]
sound/soc/codecs/rt5668.h [new file with mode: 0644]
sound/soc/codecs/rt5670.c
sound/soc/codecs/rt5677.c
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/sgtl5000.h
sound/soc/codecs/ssm2305.c [new file with mode: 0644]
sound/soc/codecs/tas6424.c
sound/soc/codecs/tas6424.h
sound/soc/codecs/tfa9879.c
sound/soc/codecs/tfa9879.h
sound/soc/codecs/tscs42xx.c
sound/soc/codecs/tscs42xx.h
sound/soc/codecs/tscs454.c [new file with mode: 0644]
sound/soc/codecs/tscs454.h [new file with mode: 0644]
sound/soc/codecs/wm2200.c
sound/soc/codecs/wm5100.c
sound/soc/codecs/wm8782.c
sound/soc/codecs/wm8904.c
sound/soc/codecs/wm_adsp.c
sound/soc/davinci/Kconfig
sound/soc/davinci/davinci-mcasp.c
sound/soc/fsl/fsl_esai.c
sound/soc/fsl/fsl_esai.h
sound/soc/fsl/fsl_sai.c
sound/soc/fsl/fsl_sai.h
sound/soc/fsl/fsl_spdif.c
sound/soc/fsl/fsl_spdif.h
sound/soc/fsl/fsl_ssi.c
sound/soc/fsl/fsl_ssi.h
sound/soc/fsl/fsl_ssi_dbg.c
sound/soc/generic/simple-card.c
sound/soc/hisilicon/hi6210-i2s.c
sound/soc/intel/Kconfig
sound/soc/intel/boards/bxt_da7219_max98357a.c
sound/soc/intel/boards/bxt_rt298.c
sound/soc/intel/boards/byt-max98090.c
sound/soc/intel/boards/bytcht_es8316.c
sound/soc/intel/boards/bytcr_rt5640.c
sound/soc/intel/boards/bytcr_rt5651.c
sound/soc/intel/boards/cht_bsw_max98090_ti.c
sound/soc/intel/boards/cht_bsw_nau8824.c
sound/soc/intel/boards/cht_bsw_rt5645.c
sound/soc/intel/boards/cht_bsw_rt5672.c
sound/soc/intel/boards/kbl_da7219_max98357a.c
sound/soc/intel/boards/kbl_rt5663_max98927.c
sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
sound/soc/intel/boards/skl_nau88l25_max98357a.c
sound/soc/intel/boards/skl_nau88l25_ssm4567.c
sound/soc/intel/boards/skl_rt286.c
sound/soc/intel/skylake/skl-debug.c
sound/soc/intel/skylake/skl-messages.c
sound/soc/intel/skylake/skl-pcm.c
sound/soc/intel/skylake/skl-sst-dsp.h
sound/soc/intel/skylake/skl-sst.c
sound/soc/intel/skylake/skl-topology.c
sound/soc/intel/skylake/skl-topology.h
sound/soc/intel/skylake/skl-tplg-interface.h [deleted file]
sound/soc/intel/skylake/skl.c
sound/soc/kirkwood/Kconfig
sound/soc/mediatek/Kconfig
sound/soc/mediatek/Makefile
sound/soc/mediatek/common/Makefile
sound/soc/mediatek/common/mtk-afe-fe-dai.c
sound/soc/mediatek/common/mtk-afe-fe-dai.h
sound/soc/mediatek/common/mtk-afe-platform-driver.c
sound/soc/mediatek/common/mtk-afe-platform-driver.h
sound/soc/mediatek/common/mtk-base-afe.h
sound/soc/mediatek/mt2701/Makefile
sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h
sound/soc/mediatek/mt2701/mt2701-afe-common.h
sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
sound/soc/mediatek/mt2701/mt2701-cs42448.c
sound/soc/mediatek/mt2701/mt2701-reg.h
sound/soc/mediatek/mt2701/mt2701-wm8960.c
sound/soc/mediatek/mt6797/Makefile [new file with mode: 0644]
sound/soc/mediatek/mt6797/mt6797-afe-clk.c [new file with mode: 0644]
sound/soc/mediatek/mt6797/mt6797-afe-clk.h [new file with mode: 0644]
sound/soc/mediatek/mt6797/mt6797-afe-common.h [new file with mode: 0644]
sound/soc/mediatek/mt6797/mt6797-afe-pcm.c [new file with mode: 0644]
sound/soc/mediatek/mt6797/mt6797-dai-adda.c [new file with mode: 0644]
sound/soc/mediatek/mt6797/mt6797-dai-hostless.c [new file with mode: 0644]
sound/soc/mediatek/mt6797/mt6797-dai-pcm.c [new file with mode: 0644]
sound/soc/mediatek/mt6797/mt6797-interconnection.h [new file with mode: 0644]
sound/soc/mediatek/mt6797/mt6797-mt6351.c [new file with mode: 0644]
sound/soc/mediatek/mt6797/mt6797-reg.h [new file with mode: 0644]
sound/soc/mediatek/mt8173/mt8173-afe-common.h
sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
sound/soc/mediatek/mt8173/mt8173-max98090.c
sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
sound/soc/mediatek/mt8173/mt8173-rt5650.c
sound/soc/omap/Kconfig
sound/soc/omap/Makefile
sound/soc/omap/n810.c
sound/soc/omap/omap-dmic.c
sound/soc/omap/omap-hdmi-audio.c
sound/soc/omap/omap-mcbsp.c
sound/soc/omap/omap-mcpdm.c
sound/soc/omap/omap-pcm.c [deleted file]
sound/soc/omap/sdma-pcm.c [new file with mode: 0644]
sound/soc/omap/sdma-pcm.h [new file with mode: 0644]
sound/soc/pxa/Kconfig
sound/soc/pxa/pxa-ssp.c
sound/soc/qcom/Kconfig
sound/soc/qcom/Makefile
sound/soc/qcom/apq8096.c [new file with mode: 0644]
sound/soc/qcom/qdsp6/Makefile [new file with mode: 0644]
sound/soc/qcom/qdsp6/q6adm.c [new file with mode: 0644]
sound/soc/qcom/qdsp6/q6adm.h [new file with mode: 0644]
sound/soc/qcom/qdsp6/q6afe-dai.c [new file with mode: 0644]
sound/soc/qcom/qdsp6/q6afe.c [new file with mode: 0644]
sound/soc/qcom/qdsp6/q6afe.h [new file with mode: 0644]
sound/soc/qcom/qdsp6/q6asm-dai.c [new file with mode: 0644]
sound/soc/qcom/qdsp6/q6asm.c [new file with mode: 0644]
sound/soc/qcom/qdsp6/q6asm.h [new file with mode: 0644]
sound/soc/qcom/qdsp6/q6core.c [new file with mode: 0644]
sound/soc/qcom/qdsp6/q6core.h [new file with mode: 0644]
sound/soc/qcom/qdsp6/q6dsp-common.c [new file with mode: 0644]
sound/soc/qcom/qdsp6/q6dsp-common.h [new file with mode: 0644]
sound/soc/qcom/qdsp6/q6dsp-errno.h [new file with mode: 0644]
sound/soc/qcom/qdsp6/q6routing.c [new file with mode: 0644]
sound/soc/qcom/qdsp6/q6routing.h [new file with mode: 0644]
sound/soc/rockchip/rk3399_gru_sound.c
sound/soc/sh/Kconfig
sound/soc/sh/rcar/cmd.c
sound/soc/sh/rcar/core.c
sound/soc/sh/rcar/dma.c
sound/soc/sh/rcar/gen.c
sound/soc/sh/rcar/rsnd.h
sound/soc/sh/rcar/ssi.c
sound/soc/soc-cache.c [deleted file]
sound/soc/soc-compress.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/soc/soc-devres.c
sound/soc/soc-io.c
sound/soc/soc-jack.c
sound/soc/soc-pcm.c
sound/soc/soc-topology.c
sound/soc/uniphier/aio-compress.c
sound/soc/uniphier/aio-core.c
sound/soc/uniphier/aio-cpu.c
sound/soc/uniphier/aio-dma.c
sound/soc/uniphier/aio-ld11.c
sound/soc/uniphier/aio-reg.h
sound/soc/uniphier/aio.h
sound/soc/uniphier/evea.c
sound/soc/zte/zx-i2s.c
sound/sound_core.c
sound/sparc/dbri.c
sound/usb/card.c
sound/usb/clock.c
sound/usb/helper.h
sound/usb/mixer.c
sound/usb/mixer.h
sound/usb/mixer_maps.c
sound/usb/mixer_quirks.c
sound/usb/mixer_quirks.h
sound/usb/mixer_scarlett.c
sound/usb/pcm.c
sound/usb/pcm.h
sound/usb/quirks-table.h
sound/usb/quirks.c
sound/usb/stream.c
sound/usb/usbaudio.h
sound/xen/Kconfig [new file with mode: 0644]
sound/xen/Makefile [new file with mode: 0644]
sound/xen/xen_snd_front.c [new file with mode: 0644]
sound/xen/xen_snd_front.h [new file with mode: 0644]
sound/xen/xen_snd_front_alsa.c [new file with mode: 0644]
sound/xen/xen_snd_front_alsa.h [new file with mode: 0644]
sound/xen/xen_snd_front_cfg.c [new file with mode: 0644]
sound/xen/xen_snd_front_cfg.h [new file with mode: 0644]
sound/xen/xen_snd_front_evtchnl.c [new file with mode: 0644]
sound/xen/xen_snd_front_evtchnl.h [new file with mode: 0644]
sound/xen/xen_snd_front_shbuf.c [new file with mode: 0644]
sound/xen/xen_snd_front_shbuf.h [new file with mode: 0644]

index 7fa9d41fbdaf945c807700300c1b3eb4289eb218..29ddeb1bf015c46f6316b6d4a436c94bdb9b3ae9 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -186,6 +186,9 @@ Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
 Uwe Kleine-König <ukl@pengutronix.de>
 Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
 Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
+Vinod Koul <vkoul@kernel.org> <vinod.koul@intel.com>
+Vinod Koul <vkoul@kernel.org> <vinod.koul@linux.intel.com>
+Vinod Koul <vkoul@kernel.org> <vkoul@infradead.org>
 Viresh Kumar <vireshk@kernel.org> <viresh.kumar@st.com>
 Viresh Kumar <vireshk@kernel.org> <viresh.linux@gmail.com>
 Viresh Kumar <vireshk@kernel.org> <viresh.kumar2@arm.com>
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt
new file mode 100644 (file)
index 0000000..bcc612c
--- /dev/null
@@ -0,0 +1,84 @@
+Qualcomm APR (Asynchronous Packet Router) binding
+
+This binding describes the Qualcomm APR. APR is a IPC protocol for
+communication between Application processor and QDSP. APR is mainly
+used for audio/voice services on the QDSP.
+
+- compatible:
+       Usage: required
+       Value type: <stringlist>
+       Definition: must be "qcom,apr-v<VERSION-NUMBER>", example "qcom,apr-v2"
+
+- reg
+       Usage: required
+       Value type: <u32>
+       Definition: Destination processor ID.
+       Possible values are :
+                       1 - APR simulator
+                       2 - PC
+                       3 - MODEM
+                       4 - ADSP
+                       5 - APPS
+                       6 - MODEM2
+                       7 - APPS2
+
+= APR SERVICES
+Each subnode of the APR node represents service tied to this apr. The name
+of the nodes are not important. The properties of these nodes are defined
+by the individual bindings for the specific service
+- All APR services MUST contain the following property:
+
+- reg
+       Usage: required
+       Value type: <u32>
+       Definition: APR Service ID
+       Possible values are :
+                       3 - DSP Core Service
+                       4 - Audio Front End Service.
+                       5 - Voice Stream Manager Service.
+                       6 - Voice processing manager.
+                       7 - Audio Stream Manager Service.
+                       8 - Audio Device Manager Service.
+                       9 - Multimode voice manager.
+                       10 - Core voice stream.
+                       11 - Core voice processor.
+                       12 - Ultrasound stream manager.
+                       13 - Listen stream manager.
+
+= EXAMPLE
+The following example represents a QDSP based sound card on a MSM8996 device
+which uses apr as communication between Apps and QDSP.
+
+       apr@4 {
+               compatible = "qcom,apr-v2";
+               reg = <APR_DOMAIN_ADSP>;
+
+               q6core@3 {
+                       compatible = "qcom,q6core";
+                       reg = <APR_SVC_ADSP_CORE>;
+               };
+
+               q6afe@4 {
+                       compatible = "qcom,q6afe";
+                       reg = <APR_SVC_AFE>;
+
+                       dais {
+                               #sound-dai-cells = <1>;
+                               hdmi@1 {
+                                       reg = <1>;
+                               };
+                       };
+               };
+
+               q6asm@7 {
+                       compatible = "qcom,q6asm";
+                       reg = <APR_SVC_ASM>;
+                       ...
+               };
+
+               q6adm@8 {
+                       compatible = "qcom,q6adm";
+                       reg = <APR_SVC_ADM>;
+                       ...
+               };
+       };
diff --git a/Documentation/devicetree/bindings/sound/adi,ssm2305.txt b/Documentation/devicetree/bindings/sound/adi,ssm2305.txt
new file mode 100644 (file)
index 0000000..a9c9d83
--- /dev/null
@@ -0,0 +1,14 @@
+Analog Devices SSM2305 Speaker Amplifier
+========================================
+
+Required properties:
+  - compatible : "adi,ssm2305"
+  - shutdown-gpios : The gpio connected to the shutdown pin.
+                     The gpio signal is ACTIVE_LOW.
+
+Example:
+
+ssm2305: analog-amplifier {
+       compatible = "adi,ssm2305";
+       shutdown-gpios = <&gpio3 20 GPIO_ACTIVE_LOW>;
+};
diff --git a/Documentation/devicetree/bindings/sound/atmel-i2s.txt b/Documentation/devicetree/bindings/sound/atmel-i2s.txt
new file mode 100644 (file)
index 0000000..735368b
--- /dev/null
@@ -0,0 +1,47 @@
+* Atmel I2S controller
+
+Required properties:
+- compatible:     Should be "atmel,sama5d2-i2s".
+- reg:            Should be the physical base address of the controller and the
+                  length of memory mapped region.
+- interrupts:     Should contain the interrupt for the controller.
+- dmas:           Should be one per channel name listed in the dma-names property,
+                  as described in atmel-dma.txt and dma.txt files.
+- dma-names:      Two dmas have to be defined, "tx" and "rx".
+                  This IP also supports one shared channel for both rx and tx;
+                  if this mode is used, one "rx-tx" name must be used.
+- clocks:         Must contain an entry for each entry in clock-names.
+                  Please refer to clock-bindings.txt.
+- clock-names:    Should be one of each entry matching the clocks phandles list:
+                  - "pclk" (peripheral clock) Required.
+                  - "gclk" (generated clock) Optional (1).
+                  - "aclk" (Audio PLL clock) Optional (1).
+                  - "muxclk" (I2S mux clock) Optional (1).
+
+Optional properties:
+- pinctrl-0:      Should specify pin control groups used for this controller.
+- princtrl-names: Should contain only one value - "default".
+
+
+(1) : Only the peripheral clock is required. The generated clock, the Audio
+      PLL clock adn the I2S mux clock are optional and should only be set
+      together, when Master Mode is required.
+
+Example:
+
+       i2s@f8050000 {
+               compatible = "atmel,sama5d2-i2s";
+               reg = <0xf8050000 0x300>;
+               interrupts = <54 IRQ_TYPE_LEVEL_HIGH 7>;
+               dmas = <&dma0
+                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                        AT91_XDMAC_DT_PERID(31))>,
+                      <&dma0
+                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                        AT91_XDMAC_DT_PERID(32))>;
+               dma-names = "tx", "rx";
+               clocks = <&i2s0_clk>, <&i2s0_gclk>, <&audio_pll_pmc>, <&i2s0muxck>;
+               clock-names = "pclk", "gclk", "aclk", "muxclk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2s0_default>;
+       };
index f631fbca6284325378e959683d737fc787035a17..8619a156d038bdd76e342351fe83af63b4105746 100644 (file)
@@ -16,7 +16,7 @@ Required properties:
 
 Example:
 
-codec: cs42888@48 {
+cs42888: codec@48 {
        compatible = "cirrus,cs42888";
        reg = <0x48>;
        clocks = <&codec_mclk 0>;
index f5a14115b459482ea7ffa2ce43c9b84096cdb3df..1d4d9f938689f39b5214a730991ac068aec02f35 100644 (file)
@@ -31,14 +31,16 @@ Required properties:
                          it. This property is optional depending on the SoC
                          design.
 
-   - big-endian                : If this property is absent, the little endian mode
-                         will be in use as default. Otherwise, the big endian
-                         mode will be in use for all the device registers.
-
    - fsl,asrc-rate     : Defines a mutual sample rate used by DPCM Back Ends.
 
    - fsl,asrc-width    : Defines a mutual sample width used by DPCM Back Ends.
 
+Optional properties:
+
+   - big-endian                : If this property is absent, the little endian mode
+                         will be in use as default. Otherwise, the big endian
+                         mode will be in use for all the device registers.
+
 Example:
 
 asrc: asrc@2034000 {
index cacd18bb9ba63978a73d569a00db21d6389b9b21..5b9914367610315d8aaab3a614dd318de9408c6d 100644 (file)
@@ -42,6 +42,8 @@ Required properties:
                          means all the settings for Receiving would be
                          duplicated from Transmition related registers.
 
+Optional properties:
+
   - big-endian         : If this property is absent, the native endian mode
                          will be in use as default, or the big endian mode
                          will be in use for all the device registers.
index 38cfa75734415e018107c6a0a2cc128497cc059f..8b324f82a7828013c06a1688c80c7316558c47ce 100644 (file)
@@ -33,6 +33,8 @@ Required properties:
                          it. This property is optional depending on the SoC
                          design.
 
+Optional properties:
+
    - big-endian                : If this property is absent, the native endian mode
                          will be in use as default, or the big endian mode
                          will be in use for all the device registers.
index 740b467adf7d1d46f318d5a2a6bf74f35cfa80bc..dd9e59738e0820b4db57b737e34a37c11c90fd55 100644 (file)
@@ -28,9 +28,6 @@ Required properties:
                          pinctrl-names. See ../pinctrl/pinctrl-bindings.txt
                          for details of the property values.
 
-  - big-endian         : Boolean property, required if all the FTM_PWM
-                         registers are big-endian rather than little-endian.
-
   - lsb-first          : Configures whether the LSB or the MSB is transmitted
                          first for the fifo data. If this property is absent,
                          the MSB is transmitted first as default, or the LSB
@@ -48,6 +45,11 @@ Required properties:
                          receive data by following their own bit clocks and
                          frame sync clocks separately.
 
+Optional properties:
+
+  - big-endian         : Boolean property, required if all the SAI
+                         registers are big-endian rather than little-endian.
+
 Optional properties (for mx6ul):
 
   - fsl,sai-mclk-direction-output: This is a boolean property. If present,
index e2f7f49512155e1084c85ce9e3dd6b9770285a97..560762e0a1681b37ef1a66750e14474868a137c8 100644 (file)
@@ -1,7 +1,9 @@
 Mediatek AFE PCM controller for mt2701
 
 Required properties:
-- compatible = "mediatek,mt2701-audio";
+- compatible: should be one of the followings.
+             - "mediatek,mt2701-audio"
+             - "mediatek,mt7622-audio"
 - interrupts: should contain AFE and ASYS interrupts
 - interrupt-names: should be "afe" and "asys"
 - power-domains: should define the power domain
diff --git a/Documentation/devicetree/bindings/sound/mt6351.txt b/Documentation/devicetree/bindings/sound/mt6351.txt
new file mode 100644 (file)
index 0000000..7fb2cb9
--- /dev/null
@@ -0,0 +1,16 @@
+Mediatek MT6351 Audio Codec
+
+The communication between MT6351 and SoC is through Mediatek PMIC wrapper.
+For more detail, please visit Mediatek PMIC wrapper documentation.
+
+Must be a child node of PMIC wrapper.
+
+Required properties:
+
+- compatible : "mediatek,mt6351-sound".
+
+Example:
+
+mt6351_snd {
+       compatible = "mediatek,mt6351-sound";
+};
diff --git a/Documentation/devicetree/bindings/sound/mt6797-afe-pcm.txt b/Documentation/devicetree/bindings/sound/mt6797-afe-pcm.txt
new file mode 100644 (file)
index 0000000..0ae29de
--- /dev/null
@@ -0,0 +1,42 @@
+Mediatek AFE PCM controller for mt6797
+
+Required properties:
+- compatible = "mediatek,mt6797-audio";
+- reg: register location and size
+- interrupts: should contain AFE interrupt
+- power-domains: should define the power domain
+- clocks: Must contain an entry for each entry in clock-names
+- clock-names: should have these clock names:
+               "infra_sys_audio_clk",
+               "infra_sys_audio_26m",
+               "mtkaif_26m_clk",
+               "top_mux_audio",
+               "top_mux_aud_intbus",
+               "top_sys_pll3_d4",
+               "top_sys_pll1_d4",
+               "top_clk26m_clk";
+
+Example:
+
+       afe: mt6797-afe-pcm@11220000  {
+               compatible = "mediatek,mt6797-audio";
+               reg = <0 0x11220000 0 0x1000>;
+               interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_LOW>;
+               power-domains = <&scpsys MT6797_POWER_DOMAIN_AUDIO>;
+               clocks = <&infrasys CLK_INFRA_AUDIO>,
+                        <&infrasys CLK_INFRA_AUDIO_26M>,
+                        <&infrasys CLK_INFRA_AUDIO_26M_PAD_TOP>,
+                        <&topckgen CLK_TOP_MUX_AUDIO>,
+                        <&topckgen CLK_TOP_MUX_AUD_INTBUS>,
+                        <&topckgen CLK_TOP_SYSPLL3_D4>,
+                        <&topckgen CLK_TOP_SYSPLL1_D4>,
+                        <&clk26m>;
+               clock-names = "infra_sys_audio_clk",
+                             "infra_sys_audio_26m",
+                             "mtkaif_26m_clk",
+                             "top_mux_audio",
+                             "top_mux_aud_intbus",
+                             "top_sys_pll3_d4",
+                             "top_sys_pll1_d4",
+                             "top_clk26m_clk";
+       };
diff --git a/Documentation/devicetree/bindings/sound/mt6797-mt6351.txt b/Documentation/devicetree/bindings/sound/mt6797-mt6351.txt
new file mode 100644 (file)
index 0000000..1d95a88
--- /dev/null
@@ -0,0 +1,14 @@
+MT6797 with MT6351 CODEC
+
+Required properties:
+- compatible: "mediatek,mt6797-mt6351-sound"
+- mediatek,platform: the phandle of MT6797 ASoC platform
+- mediatek,audio-codec: the phandles of MT6351 codec
+
+Example:
+
+       sound {
+               compatible = "mediatek,mt6797-mt6351-sound";
+               mediatek,audio-codec = <&mt6351_snd>;
+               mediatek,platform = <&afe>;
+       };
diff --git a/Documentation/devicetree/bindings/sound/qcom,apq8096.txt b/Documentation/devicetree/bindings/sound/qcom,apq8096.txt
new file mode 100644 (file)
index 0000000..aa54e49
--- /dev/null
@@ -0,0 +1,109 @@
+* Qualcomm Technologies APQ8096 ASoC sound card driver
+
+This binding describes the APQ8096 sound card, which uses qdsp for audio.
+
+- compatible:
+       Usage: required
+       Value type: <stringlist>
+       Definition: must be "qcom,apq8096-sndcard"
+
+- qcom,audio-routing:
+       Usage: Optional
+       Value type: <stringlist>
+       Definition:  A list of the connections between audio components.
+                 Each entry is a pair of strings, the first being the
+                 connection's sink, the second being the connection's
+                 source. Valid names could be power supplies, MicBias
+                 of codec and the jacks on the board:
+                 Valid names include:
+
+               Board Connectors:
+                       "Headphone Left"
+                       "Headphone Right"
+                       "Earphone"
+                       "Line Out1"
+                       "Line Out2"
+                       "Line Out3"
+                       "Line Out4"
+                       "Analog Mic1"
+                       "Analog Mic2"
+                       "Analog Mic3"
+                       "Analog Mic4"
+                       "Analog Mic5"
+                       "Analog Mic6"
+                       "Digital Mic2"
+                       "Digital Mic3"
+
+               Audio pins and MicBias on WCD9335 Codec:
+                       "MIC_BIAS1
+                       "MIC_BIAS2"
+                       "MIC_BIAS3"
+                       "MIC_BIAS4"
+                       "AMIC1"
+                       "AMIC2"
+                       "AMIC3"
+                       "AMIC4"
+                       "AMIC5"
+                       "AMIC6"
+                       "AMIC6"
+                       "DMIC1"
+                       "DMIC2"
+                       "DMIC3"
+= dailinks
+Each subnode of sndcard represents either a dailink, and subnodes of each
+dailinks would be cpu/codec/platform dais.
+
+- link-name:
+       Usage: required
+       Value type: <string>
+       Definition: User friendly name for dai link
+
+= CPU, PLATFORM, CODEC dais subnodes
+- cpu:
+       Usage: required
+       Value type: <subnode>
+       Definition: cpu dai sub-node
+
+- codec:
+       Usage: Optional
+       Value type: <subnode>
+       Definition: codec dai sub-node
+
+- platform:
+       Usage: Optional
+       Value type: <subnode>
+       Definition: platform dai sub-node
+
+- sound-dai:
+       Usage: required
+       Value type: <phandle with arguments>
+       Definition: dai phandle/s and port of CPU/CODEC/PLATFORM node.
+
+Example:
+
+audio {
+       compatible = "qcom,apq8096-sndcard";
+       qcom,model = "DB820c";
+
+       mm1-dai-link {
+               link-name = "MultiMedia1";
+               cpu {
+                       sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA1>;
+               };
+       };
+
+       hdmi-dai-link {
+               link-name = "HDMI Playback";
+               cpu {
+                       sound-dai = <&q6afe HDMI_RX>;
+               };
+
+               platform {
+                       sound-dai = <&q6adm>;
+               };
+
+               codec {
+                       sound-dai = <&hdmi 0>;
+               };
+       };
+};
diff --git a/Documentation/devicetree/bindings/sound/qcom,q6adm.txt b/Documentation/devicetree/bindings/sound/qcom,q6adm.txt
new file mode 100644 (file)
index 0000000..cb709e5
--- /dev/null
@@ -0,0 +1,33 @@
+Qualcomm Audio Device Manager (Q6ADM) binding
+
+Q6ADM is one of the APR audio service on Q6DSP.
+Please refer to qcom,apr.txt for details of the coommon apr service bindings
+used by the apr service device.
+
+- but must contain the following property:
+
+- compatible:
+       Usage: required
+       Value type: <stringlist>
+       Definition: must be "qcom,q6adm-v<MAJOR-NUMBER>.<MINOR-NUMBER>".
+                  Or "qcom,q6adm" where the version number can be queried
+                  from DSP.
+                  example "qcom,q6adm-v2.0"
+
+
+= ADM routing
+"routing" subnode of the ADM node represents adm routing specific configuration
+
+- #sound-dai-cells
+       Usage: required
+       Value type: <u32>
+       Definition: Must be 0
+
+= EXAMPLE
+q6adm@8 {
+       compatible = "qcom,q6adm";
+       reg = <APR_SVC_ADM>;
+       q6routing: routing {
+               #sound-dai-cells = <0>;
+       };
+};
diff --git a/Documentation/devicetree/bindings/sound/qcom,q6afe.txt b/Documentation/devicetree/bindings/sound/qcom,q6afe.txt
new file mode 100644 (file)
index 0000000..bdbf87d
--- /dev/null
@@ -0,0 +1,172 @@
+Qualcomm Audio Front End (Q6AFE) binding
+
+AFE is one of the APR audio service on Q6DSP
+Please refer to qcom,apr.txt for details of the common apr service bindings
+used by all apr services. Must contain the following properties.
+
+- compatible:
+       Usage: required
+       Value type: <stringlist>
+       Definition: must be "qcom,q6afe-v<MAJOR-NUMBER>.<MINOR-NUMBER>"
+                 Or "qcom,q6afe" where the version number can be queried
+                 from DSP.
+                 example "qcom,q6afe"
+
+= AFE DAIs (Digial Audio Interface)
+"dais" subnode of the AFE node. It represents afe dais, each afe dai is a
+subnode of "dais" representing board specific dai setup.
+"dais" node should have following properties followed by dai children.
+
+- #sound-dai-cells
+       Usage: required
+       Value type: <u32>
+       Definition: Must be 1
+
+- #address-cells
+       Usage: required
+       Value type: <u32>
+       Definition: Must be 1
+
+- #size-cells
+       Usage: required
+       Value type: <u32>
+       Definition: Must be 0
+
+== AFE DAI is subnode of "dais" and represent a dai, it includes board specific
+configuration of each dai. Must contain the following properties.
+
+- reg
+       Usage: required
+       Value type: <u32>
+       Definition: Must be dai id
+
+- qcom,sd-lines
+       Usage: required for mi2s interface
+       Value type: <prop-encoded-array>
+       Definition: Must be list of serial data lines used by this dai.
+       should be one or more of the 1-4 sd lines.
+
+ - qcom,tdm-sync-mode:
+       Usage: required for tdm interface
+       Value type: <prop-encoded-array>
+       Definition: Synchronization mode.
+               0 - Short sync bit mode
+               1 - Long sync mode
+               2 - Short sync slot mode
+
+ - qcom,tdm-sync-src:
+       Usage: required for tdm interface
+       Value type: <prop-encoded-array>
+       Definition: Synchronization source.
+               0 - External source
+               1 - Internal source
+
+ - qcom,tdm-data-out:
+       Usage: required for tdm interface
+       Value type: <prop-encoded-array>
+       Definition: Data out signal to drive with other masters.
+               0 - Disable
+               1 - Enable
+
+ - qcom,tdm-invert-sync:
+       Usage: required for tdm interface
+       Value type: <prop-encoded-array>
+       Definition: Invert the sync.
+               0 - Normal
+               1 - Invert
+
+ - qcom,tdm-data-delay:
+       Usage: required for tdm interface
+       Value type: <prop-encoded-array>
+       Definition: Number of bit clock to delay data
+               with respect to sync edge.
+               0 - 0 bit clock cycle
+               1 - 1 bit clock cycle
+               2 - 2 bit clock cycle
+
+ - qcom,tdm-data-align:
+       Usage: required for tdm interface
+       Value type: <prop-encoded-array>
+       Definition: Indicate how data is packed
+               within the slot. For example, 32 slot width in case of
+               sample bit width is 24.
+               0 - MSB
+               1 - LSB
+
+= EXAMPLE
+
+q6afe@4 {
+       compatible = "qcom,q6afe";
+       reg = <APR_SVC_AFE>;
+
+       dais {
+               #sound-dai-cells = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               hdmi@1 {
+                       reg = <1>;
+               };
+
+               tdm@24 {
+                       reg = <24>;
+                       qcom,tdm-sync-mode = <1>:
+                       qcom,tdm-sync-src = <1>;
+                       qcom,tdm-data-out = <0>;
+                       qcom,tdm-invert-sync = <1>;
+                       qcom,tdm-data-delay = <1>;
+                       qcom,tdm-data-align = <0>;
+
+               };
+
+               tdm@25 {
+                       reg = <25>;
+                       qcom,tdm-sync-mode = <1>:
+                       qcom,tdm-sync-src = <1>;
+                       qcom,tdm-data-out = <0>;
+                       qcom,tdm-invert-sync = <1>;
+                       qcom,tdm-data-delay <1>:
+                       qcom,tdm-data-align = <0>;
+               };
+
+               prim-mi2s-rx@16 {
+                       reg = <16>;
+                       qcom,sd-lines = <1 3>;
+               };
+
+               prim-mi2s-tx@17 {
+                       reg = <17>;
+                       qcom,sd-lines = <2>;
+               };
+
+               sec-mi2s-rx@18 {
+                       reg = <18>;
+                       qcom,sd-lines = <1 4>;
+               };
+
+               sec-mi2s-tx@19 {
+                       reg = <19>;
+                       qcom,sd-lines = <2>;
+               };
+
+               tert-mi2s-rx@20 {
+                       reg = <20>;
+                       qcom,sd-lines = <2 4>;
+               };
+
+               tert-mi2s-tx@21 {
+                       reg = <21>;
+                       qcom,sd-lines = <1>;
+               };
+
+               quat-mi2s-rx@22 {
+                       reg = <22>;
+                       qcom,sd-lines = <1>;
+               };
+
+               quat-mi2s-tx@23 {
+                       reg = <23>;
+                       qcom,sd-lines = <2>;
+               };
+       };
+};
diff --git a/Documentation/devicetree/bindings/sound/qcom,q6asm.txt b/Documentation/devicetree/bindings/sound/qcom,q6asm.txt
new file mode 100644 (file)
index 0000000..2178eb9
--- /dev/null
@@ -0,0 +1,33 @@
+Qualcomm Audio Stream Manager (Q6ASM) binding
+
+Q6ASM is one of the APR audio service on Q6DSP.
+Please refer to qcom,apr.txt for details of the common apr service bindings
+used by the apr service device.
+
+- but must contain the following property:
+
+- compatible:
+       Usage: required
+       Value type: <stringlist>
+       Definition: must be "qcom,q6asm-v<MAJOR-NUMBER>.<MINOR-NUMBER>".
+                   Or "qcom,q6asm" where the version number can be queried
+                   from DSP.
+                   example "qcom,q6asm-v2.0"
+
+= ASM DAIs (Digial Audio Interface)
+"dais" subnode of the ASM node represents dai specific configuration
+
+- #sound-dai-cells
+       Usage: required
+       Value type: <u32>
+       Definition: Must be 1
+
+= EXAMPLE
+
+q6asm@7 {
+       compatible = "qcom,q6asm";
+       reg = <APR_SVC_ASM>;
+       q6asmdai: dais {
+               #sound-dai-cells = <1>;
+       };
+};
diff --git a/Documentation/devicetree/bindings/sound/qcom,q6core.txt b/Documentation/devicetree/bindings/sound/qcom,q6core.txt
new file mode 100644 (file)
index 0000000..7f36ff8
--- /dev/null
@@ -0,0 +1,21 @@
+Qualcomm ADSP Core service binding
+
+Q6CORE is one of the APR audio service on Q6DSP.
+Please refer to qcom,apr.txt for details of the common apr service bindings
+used by the apr service device.
+
+- but must contain the following property:
+
+- compatible:
+       Usage: required
+       Value type: <stringlist>
+       Definition: must be "qcom,q6core-v<MAJOR-NUMBER>.<MINOR-NUMBER>".
+                  Or "qcom,q6core" where the version number can be queried
+                  from DSP.
+                  example "qcom,q6core-v2.0"
+
+= EXAMPLE
+q6core@3 {
+       compatible = "qcom,q6core";
+       reg = <APR_SVC_ADSP_CORE>;
+};
index e9a6178c78cfe09c56a303495ec4d207ed53b11b..791a1bd767b9166e9330bf9a0fc4f90dfcfc62b2 100644 (file)
@@ -26,7 +26,7 @@ Pins on the device (for linking into audio routes) for RT274:
 
 Example:
 
-codec: rt274@1c {
+rt274: codec@1c {
        compatible = "realtek,rt274";
        reg = <0x1c>;
        interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
index 4f33b0d96afeb106bb457ed071ab3f4779d80ec5..b25ed08c7a5a0113761c18a17d3ceef50d0d6d96 100644 (file)
@@ -32,7 +32,7 @@ Pins on the device (for linking into audio routes) for I2C:
 
 Example:
 
-codec: rt5514@57 {
+rt5514: codec@57 {
        compatible = "realtek,rt5514";
        reg = <0x57>;
 };
index e410858185596a0fb74ec5812cef3dd3e6282762..540a4bf252e48eb4dcce34061b0b9ee537ab0d23 100644 (file)
@@ -26,7 +26,7 @@ Pins on the device (for linking into audio routes) for RT5616:
 
 Example:
 
-codec: rt5616@1b {
+rt5616: codec@1b {
        compatible = "realtek,rt5616";
        reg = <0x1b>;
 };
index 57fe64643050a5e9f41072dd0d4ae0376f5d6958..e40e4893eed8014352cb81ab86c42f21da38e123 100644 (file)
@@ -22,6 +22,41 @@ Optional properties:
 
 - realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
 
+- realtek,dmic1-data-pin
+  0: dmic1 is not used
+  1: using IN1P pin as dmic1 data pin
+  2: using GPIO3 pin as dmic1 data pin
+
+- realtek,dmic2-data-pin
+  0: dmic2 is not used
+  1: using IN1N pin as dmic2 data pin
+  2: using GPIO4 pin as dmic2 data pin
+
+- realtek,jack-detect-source
+  u32. Valid values:
+  0: jack-detect is not used
+  1: Use GPIO1 for jack-detect
+  2: Use JD1_IN4P for jack-detect
+  3: Use JD2_IN4N for jack-detect
+  4: Use GPIO2 for jack-detect
+  5: Use GPIO3 for jack-detect
+  6: Use GPIO4 for jack-detect
+
+- realtek,jack-detect-not-inverted
+  bool. Normal jack-detect switches give an inverted signal, set this bool
+  in the rare case you've a jack-detect switch which is not inverted.
+
+- realtek,over-current-threshold-microamp
+  u32, micbias over-current detection threshold in µA, valid values are
+  600, 1500 and 2000µA.
+
+- realtek,over-current-scale-factor
+  u32, micbias over-current detection scale-factor, valid values are:
+  0: Scale current by 0.5
+  1: Scale current by 0.75
+  2: Scale current by 1.0
+  3: Scale current by 1.5
+
 Pins on the device (for linking into audio routes) for RT5639/RT5640:
 
   * DMIC1
index 7cee1f518f59fc7ec2fccc1882a939b2a2589a37..a03f9a872a71667ddc2ab9197ece633ee337af96 100644 (file)
@@ -69,4 +69,4 @@ codec: rt5650@1a {
        realtek,dmic-en = "true";
        realtek,en-jd-func = "true";
        realtek,jd-mode = <3>;
-};
\ No newline at end of file
+};
index b85221864cec8a607f62dc27c41f4f37e05b941e..a41199a5cd79b5225b2b732bacfef782d9286d54 100644 (file)
@@ -50,7 +50,7 @@ Pins on the device (for linking into audio routes) for RT5651:
 
 Example:
 
-codec: rt5651@1a {
+rt5651: codec@1a {
        compatible = "realtek,rt5651";
        reg = <0x1a>;
        realtek,dmic-en = "true";
index 497bcfc58b712173b05ce876600f1595a3d20125..23386446c63d6fde5b63c35b8badd989a8ada56b 100644 (file)
@@ -47,7 +47,7 @@ Pins on the device (for linking into audio routes) for RT5663:
 
 Example:
 
-codec: rt5663@12 {
+rt5663: codec@12 {
        compatible = "realtek,rt5663";
        reg = <0x12>;
        interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
diff --git a/Documentation/devicetree/bindings/sound/rt5668.txt b/Documentation/devicetree/bindings/sound/rt5668.txt
new file mode 100644 (file)
index 0000000..c88b96e
--- /dev/null
@@ -0,0 +1,50 @@
+RT5668B audio CODEC
+
+This device supports I2C only.
+
+Required properties:
+
+- compatible : "realtek,rt5668b"
+
+- reg : The I2C address of the device.
+
+Optional properties:
+
+- interrupts : The CODEC's interrupt output.
+
+- realtek,dmic1-data-pin
+  0: dmic1 is not used
+  1: using GPIO2 pin as dmic1 data pin
+  2: using GPIO5 pin as dmic1 data pin
+
+- realtek,dmic1-clk-pin
+  0: using GPIO1 pin as dmic1 clock pin
+  1: using GPIO3 pin as dmic1 clock pin
+
+- realtek,jd-src
+  0: No JD is used
+  1: using JD1 as JD source
+
+- realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin.
+
+Pins on the device (for linking into audio routes) for RT5668B:
+
+  * DMIC L1
+  * DMIC R1
+  * IN1P
+  * HPOL
+  * HPOR
+
+Example:
+
+rt5668 {
+       compatible = "realtek,rt5668b";
+       reg = <0x1a>;
+       interrupt-parent = <&gpio>;
+       interrupts = <TEGRA_GPIO(U, 6) GPIO_ACTIVE_HIGH>;
+       realtek,ldo1-en-gpios =
+               <&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
+       realtek,dmic1-data-pin = <1>;
+       realtek,dmic1-clk-pin = <1>;
+       realtek,jd-src = <1>;
+};
index 9a36c7e2a1434ad60bb61436d5da9df29d05f8f3..0f214457476f2aa399925720ee8b42c934b89568 100644 (file)
@@ -39,7 +39,7 @@ VDDIO         1.8V            2.5V            3.3V
 
 Example:
 
-codec: sgtl5000@a {
+sgtl5000: codec@a {
        compatible = "fsl,sgtl5000";
        reg = <0x0a>;
        #sound-dai-cells = <0>;
index 17c13e74667da8d2135fa3360926909b6dbc569b..a4c72d09cd45718e6ce5197d6f8fce1e782deeac 100644 (file)
@@ -86,6 +86,11 @@ Optional CPU/CODEC subnodes properties:
                                          in dai startup() and disabled with
                                          clk_disable_unprepare() in dai
                                          shutdown().
+                                         If a clock is specified and a
+                                         multiplication factor is given with
+                                         mclk-fs, the clock will be set to the
+                                         calculated mclk frequency when the
+                                         stream starts.
 - system-clock-direction-out           : specifies clock direction as 'out' on
                                          initialization. It is useful for some aCPUs with
                                          fixed clocks.
index 1c4ada0eef4e1613d2a88f79e3d572c65e64b1e9..eacb54f34188fa6cf10f3ad101b1c70bf590a488 100644 (file)
@@ -6,6 +6,8 @@ Required properties:
        - compatible: "ti,tas6424" - TAS6424
        - reg: I2C slave address
        - sound-dai-cells: must be equal to 0
+       - standby-gpios: GPIO used to shut the TAS6424 down.
+       - mute-gpios: GPIO used to mute all the outputs
 
 Example:
 
index 2ac2f099669761354469f9550700c00b61e7c91e..7eea32e9d07838aec8d7f30b4e88b39c69da24d3 100644 (file)
@@ -8,9 +8,15 @@ Required Properties:
        - reg :         <0x71> for analog mic
                        <0x69> for digital mic
 
+       - clock-names:  Must one of  the following "mclk1", "xtal", "mclk2"
+
+       - clocks:       phandle of the clock that provides the codec sysclk
+
 Example:
 
 wookie: codec@69 {
        compatible = "tempo,tscs42A2";
        reg = <0x69>;
+       clock-names = "xtal";
+       clocks = <&audio_xtal>;
 };
diff --git a/Documentation/devicetree/bindings/sound/tscs454.txt b/Documentation/devicetree/bindings/sound/tscs454.txt
new file mode 100644 (file)
index 0000000..3ba3e2d
--- /dev/null
@@ -0,0 +1,23 @@
+TSCS454 Audio CODEC
+
+Required Properties:
+
+       - compatible :  "tempo,tscs454"
+
+       - reg :         <0x69>
+
+       - clock-names:  Must one of  the following "xtal", "mclk1", "mclk2"
+
+       - clocks:       phandle of the clock that provides the codec sysclk
+
+       Note: If clock is not provided then bit clock is assumed
+
+Example:
+
+redwood: codec@69 {
+       #sound-dai-cells = <1>;
+       compatible = "tempo,tscs454";
+       reg = <0x69>;
+       clock-names = "mclk1";
+       clocks = <&audio_mclk>;
+};
index fa1a32b85577db40322c4ee9655a9da77d983261..e6b6cc041f895b21d22cfc8a7e73277d2716fff1 100644 (file)
@@ -12,7 +12,7 @@ Required properties:
 
 Example:
 
-codec: wm8510@1a {
+wm8510: codec@1a {
        compatible = "wlf,wm8510";
        reg = <0x1a>;
 };
index 04746186b2831558c7e9f3b27589cbf4d13475da..f3a6485f4b8abf1b149c944d1f3486936f6529e0 100644 (file)
@@ -10,7 +10,7 @@ Required properties:
 
 Example:
 
-codec: wm8523@1a {
+wm8523: codec@1a {
        compatible = "wlf,wm8523";
        reg = <0x1a>;
 };
index 0f0553563fc1c265ea759d1c7348ad1c71f97c57..f6c0c263b135add1539054bb3beee8414da11c63 100644 (file)
@@ -10,7 +10,7 @@ Required properties:
 
 Example:
 
-codec: wm8524 {
+wm8524: codec {
        compatible = "wlf,wm8524";
        wlf,mute-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
 };
index 78fce9b14954ef76f9726b98486674d35b4ae934..ff3f9f5f2111f7afc832fcf6b280468dad843eb1 100644 (file)
@@ -10,7 +10,7 @@ Required properties:
 
 Example:
 
-codec: wm8580@1a {
+wm8580: codec@1a {
        compatible = "wlf,wm8580";
        reg = <0x1a>;
 };
index 8ed9998cd23c0ad1f0357152f09b4360d52ec74a..c30a1387c4bff4f08a081d1a711b43d6f8e2a53e 100644 (file)
@@ -12,7 +12,7 @@ Required properties:
 
 Example:
 
-codec: wm8711@1a {
+wm8711: codec@1a {
        compatible = "wlf,wm8711";
        reg = <0x1a>;
 };
index a8b5c3668e602537faf0bf1189fcd006286af3a4..a3608b4c78b95ce2a3998de2df43e6a3d8fbc4d5 100644 (file)
@@ -12,7 +12,7 @@ Required properties:
 
 Example:
 
-codec: wm8728@1a {
+wm8728: codec@1a {
        compatible = "wlf,wm8728";
        reg = <0x1a>;
 };
index 236690e99b87fbc81c0cb5b1823981cf1e87ff4d..f660d9bb0e698eb0a9d141541709071ff745b418 100644 (file)
@@ -12,7 +12,7 @@ Required properties:
 
 Example:
 
-codec: wm8731@1a {
+wm8731: codec@1a {
        compatible = "wlf,wm8731";
        reg = <0x1a>;
 };
index 4bc2cea3b14085cf4b95c62065db7bcdce4e771c..eda1ec6a7563a04a4b83bc3fafea57d91b4ec9a4 100644 (file)
@@ -12,7 +12,7 @@ Required properties:
 
 Example:
 
-codec: wm8737@1a {
+wm8737: codec@1a {
        compatible = "wlf,wm8737";
        reg = <0x1a>;
 };
index a133154087194cb90a2056ba6f927d67b6e49ba4..b69e196c741c4f8d13b051e16b06c904e64c25f1 100644 (file)
@@ -21,7 +21,7 @@ Optional properties:
 
 Example:
 
-codec: wm8741@1a {
+wm8741: codec@1a {
        compatible = "wlf,wm8741";
        reg = <0x1a>;
 
index 8db239fd5ecde354e559e56ef8f32194336a1586..682f221f6f38e3615d043070a26585916e096dc7 100644 (file)
@@ -12,7 +12,7 @@ Required properties:
 
 Example:
 
-codec: wm8750@1a {
+wm8750: codec@1a {
        compatible = "wlf,wm8750";
        reg = <0x1a>;
 };
index 8eee6128210552e0d8decfedeffbc0b216a9ec21..eca9e5a825a96e5ff17f682a83ffeef7f33a896b 100644 (file)
@@ -34,7 +34,7 @@ Pins on the device (for linking into audio routes):
 
 Example:
 
-codec: wm8753@1a {
+wm8753: codec@1a {
        compatible = "wlf,wm8753";
        reg = <0x1a>;
 };
index 866e00ca150b4b04e573e204a3ad39a0c057a58a..cac762a1105ded99ebe0966d2c4f0c67bbba7dc6 100644 (file)
@@ -10,7 +10,7 @@ Required properties:
 
 Example:
 
-codec: wm8770@1 {
+wm8770: codec@1 {
        compatible = "wlf,wm8770";
        reg = <1>;
 };
index 3b9ca49abc2b146a8bacafb0e182b8773b6cb4c3..01173369c3ed300a89dd86c288757ddfae0e37b7 100644 (file)
@@ -12,7 +12,7 @@ Required properties:
 
 Example:
 
-codec: wm8776@1a {
+wm8776: codec@1a {
        compatible = "wlf,wm8776";
        reg = <0x1a>;
 };
index 6fd124b1649652dfaac67bf0efbf35f0bade58e4..2c1641c17a91efc97c0a6194724da559849721cb 100644 (file)
@@ -19,7 +19,7 @@ Optional properties:
 
 Example:
 
-codec: wm8804@1a {
+wm8804: codec@1a {
        compatible = "wlf,wm8804";
        reg = <0x1a>;
 };
index afc51caf113705e4da112635385c205f290442ac..6371c2434afe75f0dbfd7228f1b905879fc0288d 100644 (file)
@@ -57,7 +57,7 @@ Pins on the device (for linking into audio routes):
 
 Example:
 
-codec: wm8903@1a {
+wm8903: codec@1a {
        compatible = "wlf,wm8903";
        reg = <0x1a>;
        interrupts = < 347 >;
index 2deb8a3da9c55662882f55abdd5da719ca5c5f6a..6d29ac3750eeea29da05a361b527580e65d6f76f 100644 (file)
@@ -23,7 +23,7 @@ Optional properties:
 
 Example:
 
-codec: wm8960@1a {
+wm8960: codec@1a {
        compatible = "wlf,wm8960";
        reg = <0x1a>;
 
index 7f82b59ec8f947f336ec6515d88839cbe7c3bb54..dcfa9a3369fde640da518de0f61466a1a54235c4 100644 (file)
@@ -24,7 +24,7 @@ Optional properties:
 
 Example:
 
-codec: wm8962@1a {
+wm8962: codec@1a {
        compatible = "wlf,wm8962";
        reg = <0x1a>;
 
index 68c4e8d96bed68c4c3d0ea09b10cbe8cb8170515..4a9dead1b7d32e67b6dd51c081574c4f59b3bb86 100644 (file)
@@ -59,7 +59,7 @@ Optional properties:
 
 Example:
 
-codec: wm8994@1a {
+wm8994: codec@1a {
        compatible = "wlf,wm8994";
        reg = <0x1a>;
 
index ab5761148163d92fecb336adfde7d323deba690f..4d83c1c0ca04fb7702bb9ac2da3013a2ed2c09bd 100644 (file)
@@ -2224,6 +2224,13 @@ quirk_alias
     Quirk alias list, pass strings like ``0123abcd:5678beef``, which
     applies the existing quirk for the device 5678:beef to a new
     device 0123:abcd.
+use_vmalloc
+    Use vmalloc() for allocations of the PCM buffers (default: yes).
+    For architectures with non-coherent memory like ARM or MIPS, the
+    mmap access may give inconsistent results with vmalloc'ed
+    buffers.  If mmap is used on such architectures, turn off this
+    option, so that the DMA-coherent buffers are allocated and used
+    instead.
 
 This module supports multiple devices, autoprobe and hotplugging.
 
index 1fee5a4f6660b9e15d10e3aed1cd1d2d94283a76..7c2d37571af080ef3e2a46da12d41971357ff6cf 100644 (file)
@@ -263,6 +263,8 @@ hp-dock
     HP dock support
 mute-led-gpio
     Mute LED control via GPIO
+hp-mic-fix
+    Fix for headset mic pin on HP boxes
 
 STAC9200
 ========
index 240770ea761e942c31041c98b47a99bbee238b69..8a9737eb7597252e97937b2e8637290e372d3ada 100644 (file)
@@ -179,12 +179,12 @@ i.e.
 
   static int wm8974_mute(struct snd_soc_dai *dai, int mute)
   {
-       struct snd_soc_codec *codec = dai->codec;
-       u16 mute_reg = snd_soc_read(codec, WM8974_DAC) & 0xffbf;
+       struct snd_soc_component *component = dai->component;
+       u16 mute_reg = snd_soc_component_read32(component, WM8974_DAC) & 0xffbf;
 
        if (mute)
-               snd_soc_write(codec, WM8974_DAC, mute_reg | 0x40);
+               snd_soc_component_write(component, WM8974_DAC, mute_reg | 0x40);
        else
-               snd_soc_write(codec, WM8974_DAC, mute_reg);
+               snd_soc_component_write(component, WM8974_DAC, mute_reg);
        return 0;
   }
index 02c93a8b9c3be8745d921687c27520b975597e30..c1badea53d3d377edc8b9a978160b8cceb5f83c9 100644 (file)
@@ -23,30 +23,26 @@ The platform DMA driver optionally supports the following ALSA operations:-
   };
 
 The platform driver exports its DMA functionality via struct
-snd_soc_platform_driver:-
+snd_soc_component_driver:-
 ::
 
-  struct snd_soc_platform_driver {
-       char *name;
+  struct snd_soc_component_driver {
+       const char *name;
 
-       int (*probe)(struct platform_device *pdev);
-       int (*remove)(struct platform_device *pdev);
-       int (*suspend)(struct platform_device *pdev, struct snd_soc_cpu_dai *cpu_dai);
-       int (*resume)(struct platform_device *pdev, struct snd_soc_cpu_dai *cpu_dai);
+       ...
+       int (*probe)(struct snd_soc_component *);
+       void (*remove)(struct snd_soc_component *);
+       int (*suspend)(struct snd_soc_component *);
+       int (*resume)(struct snd_soc_component *);
 
        /* pcm creation and destruction */
-       int (*pcm_new)(struct snd_card *, struct snd_soc_codec_dai *, struct snd_pcm *);
+       int (*pcm_new)(struct snd_soc_pcm_runtime *);
        void (*pcm_free)(struct snd_pcm *);
 
-       /*
-        * For platform caused delay reporting.
-        * Optional.
-        */
-       snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
-               struct snd_soc_dai *);
-
-       /* platform stream ops */
-       struct snd_pcm_ops *pcm_ops;
+       ...
+       const struct snd_pcm_ops *ops;
+       const struct snd_compr_ops *compr_ops;
+       ...
   };
 
 Please refer to the ALSA driver documentation for details of audio DMA.
index 8ebb000a2fbf462482c5e33696ed0133162d8b19..cfae882e63df0afba8dde963d9cf545b9207d388 100644 (file)
@@ -7082,14 +7082,13 @@ L:      linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/fbdev/i810/
 
-INTEL ASoC BDW/HSW DRIVERS
+INTEL ASoC DRIVERS
+M:     Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+M:     Liam Girdwood <liam.r.girdwood@linux.intel.com>
 M:     Jie Yang <yang.jie@linux.intel.com>
 L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
 S:     Supported
-F:     sound/soc/intel/common/sst-dsp*
-F:     sound/soc/intel/common/sst-firmware.c
-F:     sound/soc/intel/boards/broadwell.c
-F:     sound/soc/intel/haswell/
+F:     sound/soc/intel/
 
 INTEL C600 SERIES SAS CONTROLLER DRIVER
 M:     Intel SCU Linux support <intel-linux-scu@intel.com>
@@ -15542,6 +15541,13 @@ S:     Supported
 F:     arch/x86/xen/*swiotlb*
 F:     drivers/xen/*swiotlb*
 
+XEN SOUND FRONTEND DRIVER
+M:     Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
+L:     xen-devel@lists.xenproject.org (moderated for non-subscribers)
+L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
+S:     Supported
+F:     sound/xen/*
+
 XFS FILESYSTEM
 M:     Darrick J. Wong <darrick.wong@oracle.com>
 M:     linux-xfs@vger.kernel.org
index 0581ffbedddd3761b832dc5b457bb3269ee34c17..faf48a3b1fea913813681430bc55f3697a2c0028 100644 (file)
@@ -635,6 +635,7 @@ EXPORT_SYMBOL(ep93xx_keypad_release_gpio);
  *************************************************************************/
 static struct resource ep93xx_i2s_resource[] = {
        DEFINE_RES_MEM(EP93XX_I2S_PHYS_BASE, 0x100),
+       DEFINE_RES_IRQ(IRQ_EP93XX_SAI),
 };
 
 static struct platform_device ep93xx_i2s_device = {
index 3021913c28fa3ca3001820f176adcd003b1864c8..33d7fcf541fc0867a8317b90f1700868f0313b42 100644 (file)
@@ -2444,7 +2444,7 @@ static int tda1997x_pcm_startup(struct snd_pcm_substream *substream,
                                struct snd_soc_dai *dai)
 {
        struct tda1997x_state *state = snd_soc_dai_get_drvdata(dai);
-       struct snd_soc_codec *codec = dai->codec;
+       struct snd_soc_component *component = dai->component;
        struct snd_pcm_runtime *rtd = substream->runtime;
        int rate, err;
 
@@ -2452,11 +2452,11 @@ static int tda1997x_pcm_startup(struct snd_pcm_substream *substream,
        err = snd_pcm_hw_constraint_minmax(rtd, SNDRV_PCM_HW_PARAM_RATE,
                                           rate, rate);
        if (err < 0) {
-               dev_err(codec->dev, "failed to constrain samplerate to %dHz\n",
+               dev_err(component->dev, "failed to constrain samplerate to %dHz\n",
                        rate);
                return err;
        }
-       dev_info(codec->dev, "set samplerate constraint to %dHz\n", rate);
+       dev_info(component->dev, "set samplerate constraint to %dHz\n", rate);
 
        return 0;
 }
@@ -2479,20 +2479,22 @@ static struct snd_soc_dai_driver tda1997x_audio_dai = {
        .ops = &tda1997x_dai_ops,
 };
 
-static int tda1997x_codec_probe(struct snd_soc_codec *codec)
+static int tda1997x_codec_probe(struct snd_soc_component *component)
 {
        return 0;
 }
 
-static int tda1997x_codec_remove(struct snd_soc_codec *codec)
+static void tda1997x_codec_remove(struct snd_soc_component *component)
 {
-       return 0;
 }
 
-static struct snd_soc_codec_driver tda1997x_codec_driver = {
-       .probe = tda1997x_codec_probe,
-       .remove = tda1997x_codec_remove,
-       .reg_word_size = sizeof(u16),
+static struct snd_soc_component_driver tda1997x_codec_driver = {
+       .probe                  = tda1997x_codec_probe,
+       .remove                 = tda1997x_codec_remove,
+       .idle_bias_on           = 1,
+       .use_pmdown_time        = 1,
+       .endianness             = 1,
+       .non_legacy_dai_naming  = 1,
 };
 
 static int tda1997x_probe(struct i2c_client *client,
@@ -2737,7 +2739,7 @@ static int tda1997x_probe(struct i2c_client *client,
                else
                        formats = SNDRV_PCM_FMTBIT_S16_LE;
                tda1997x_audio_dai.capture.formats = formats;
-               ret = snd_soc_register_codec(&state->client->dev,
+               ret = devm_snd_soc_register_component(&state->client->dev,
                                             &tda1997x_codec_driver,
                                             &tda1997x_audio_dai, 1);
                if (ret) {
@@ -2782,7 +2784,6 @@ static int tda1997x_remove(struct i2c_client *client)
        struct tda1997x_platform_data *pdata = &state->pdata;
 
        if (pdata->audout_format) {
-               snd_soc_unregister_codec(&client->dev);
                mutex_destroy(&state->audio_lock);
        }
 
index 5c4535b545cc9564529b2c76877a24ce8cff8aff..d053f2634c67a30da9c04a9b0f484c2d6683c59e 100644 (file)
@@ -108,4 +108,13 @@ config QCOM_WCNSS_CTRL
          Client driver for the WCNSS_CTRL SMD channel, used to download nv
          firmware to a newly booted WCNSS chip.
 
+config QCOM_APR
+       tristate "Qualcomm APR Bus (Asynchronous Packet Router)"
+       depends on ARCH_QCOM
+       depends on RPMSG
+       help
+          Enable APR IPC protocol support between
+          application processor and QDSP6. APR is
+          used by audio driver to configure QDSP6
+          ASM, ADM and AFE modules.
 endmenu
index dcebf2814e6d299ce87e0d137cfc2b1af61afbc9..39de5dee55d9d3835b6c1f91d227ef2abae26fde 100644 (file)
@@ -12,3 +12,4 @@ obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
 obj-$(CONFIG_QCOM_SMP2P)       += smp2p.o
 obj-$(CONFIG_QCOM_SMSM)        += smsm.o
 obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
+obj-$(CONFIG_QCOM_APR) += apr.o
diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c
new file mode 100644 (file)
index 0000000..57af8a5
--- /dev/null
@@ -0,0 +1,378 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+// Copyright (c) 2018, Linaro Limited
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
+#include <linux/idr.h>
+#include <linux/slab.h>
+#include <linux/of_device.h>
+#include <linux/soc/qcom/apr.h>
+#include <linux/rpmsg.h>
+#include <linux/of.h>
+
+struct apr {
+       struct rpmsg_endpoint *ch;
+       struct device *dev;
+       spinlock_t svcs_lock;
+       struct idr svcs_idr;
+       int dest_domain_id;
+};
+
+/**
+ * apr_send_pkt() - Send a apr message from apr device
+ *
+ * @adev: Pointer to previously registered apr device.
+ * @pkt: Pointer to apr packet to send
+ *
+ * Return: Will be an negative on packet size on success.
+ */
+int apr_send_pkt(struct apr_device *adev, struct apr_pkt *pkt)
+{
+       struct apr *apr = dev_get_drvdata(adev->dev.parent);
+       struct apr_hdr *hdr;
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&adev->lock, flags);
+
+       hdr = &pkt->hdr;
+       hdr->src_domain = APR_DOMAIN_APPS;
+       hdr->src_svc = adev->svc_id;
+       hdr->dest_domain = adev->domain_id;
+       hdr->dest_svc = adev->svc_id;
+
+       ret = rpmsg_trysend(apr->ch, pkt, hdr->pkt_size);
+       spin_unlock_irqrestore(&adev->lock, flags);
+
+       return ret ? ret : hdr->pkt_size;
+}
+EXPORT_SYMBOL_GPL(apr_send_pkt);
+
+static void apr_dev_release(struct device *dev)
+{
+       struct apr_device *adev = to_apr_device(dev);
+
+       kfree(adev);
+}
+
+static int apr_callback(struct rpmsg_device *rpdev, void *buf,
+                                 int len, void *priv, u32 addr)
+{
+       struct apr *apr = dev_get_drvdata(&rpdev->dev);
+       uint16_t hdr_size, msg_type, ver, svc_id;
+       struct apr_device *svc = NULL;
+       struct apr_driver *adrv = NULL;
+       struct apr_resp_pkt resp;
+       struct apr_hdr *hdr;
+       unsigned long flags;
+
+       if (len <= APR_HDR_SIZE) {
+               dev_err(apr->dev, "APR: Improper apr pkt received:%p %d\n",
+                       buf, len);
+               return -EINVAL;
+       }
+
+       hdr = buf;
+       ver = APR_HDR_FIELD_VER(hdr->hdr_field);
+       if (ver > APR_PKT_VER + 1)
+               return -EINVAL;
+
+       hdr_size = APR_HDR_FIELD_SIZE_BYTES(hdr->hdr_field);
+       if (hdr_size < APR_HDR_SIZE) {
+               dev_err(apr->dev, "APR: Wrong hdr size:%d\n", hdr_size);
+               return -EINVAL;
+       }
+
+       if (hdr->pkt_size < APR_HDR_SIZE || hdr->pkt_size != len) {
+               dev_err(apr->dev, "APR: Wrong paket size\n");
+               return -EINVAL;
+       }
+
+       msg_type = APR_HDR_FIELD_MT(hdr->hdr_field);
+       if (msg_type >= APR_MSG_TYPE_MAX) {
+               dev_err(apr->dev, "APR: Wrong message type: %d\n", msg_type);
+               return -EINVAL;
+       }
+
+       if (hdr->src_domain >= APR_DOMAIN_MAX ||
+                       hdr->dest_domain >= APR_DOMAIN_MAX ||
+                       hdr->src_svc >= APR_SVC_MAX ||
+                       hdr->dest_svc >= APR_SVC_MAX) {
+               dev_err(apr->dev, "APR: Wrong APR header\n");
+               return -EINVAL;
+       }
+
+       svc_id = hdr->dest_svc;
+       spin_lock_irqsave(&apr->svcs_lock, flags);
+       svc = idr_find(&apr->svcs_idr, svc_id);
+       if (svc && svc->dev.driver)
+               adrv = to_apr_driver(svc->dev.driver);
+       spin_unlock_irqrestore(&apr->svcs_lock, flags);
+
+       if (!adrv) {
+               dev_err(apr->dev, "APR: service is not registered\n");
+               return -EINVAL;
+       }
+
+       resp.hdr = *hdr;
+       resp.payload_size = hdr->pkt_size - hdr_size;
+
+       /*
+        * NOTE: hdr_size is not same as APR_HDR_SIZE as remote can include
+        * optional headers in to apr_hdr which should be ignored
+        */
+       if (resp.payload_size > 0)
+               resp.payload = buf + hdr_size;
+
+       adrv->callback(svc, &resp);
+
+       return 0;
+}
+
+static int apr_device_match(struct device *dev, struct device_driver *drv)
+{
+       struct apr_device *adev = to_apr_device(dev);
+       struct apr_driver *adrv = to_apr_driver(drv);
+       const struct apr_device_id *id = adrv->id_table;
+
+       /* Attempt an OF style match first */
+       if (of_driver_match_device(dev, drv))
+               return 1;
+
+       if (!id)
+               return 0;
+
+       while (id->domain_id != 0 || id->svc_id != 0) {
+               if (id->domain_id == adev->domain_id &&
+                   id->svc_id == adev->svc_id)
+                       return 1;
+               id++;
+       }
+
+       return 0;
+}
+
+static int apr_device_probe(struct device *dev)
+{
+       struct apr_device *adev = to_apr_device(dev);
+       struct apr_driver *adrv = to_apr_driver(dev->driver);
+
+       return adrv->probe(adev);
+}
+
+static int apr_device_remove(struct device *dev)
+{
+       struct apr_device *adev = to_apr_device(dev);
+       struct apr_driver *adrv;
+       struct apr *apr = dev_get_drvdata(adev->dev.parent);
+
+       if (dev->driver) {
+               adrv = to_apr_driver(dev->driver);
+               if (adrv->remove)
+                       adrv->remove(adev);
+               spin_lock(&apr->svcs_lock);
+               idr_remove(&apr->svcs_idr, adev->svc_id);
+               spin_unlock(&apr->svcs_lock);
+       }
+
+       return 0;
+}
+
+static int apr_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+       struct apr_device *adev = to_apr_device(dev);
+       int ret;
+
+       ret = of_device_uevent_modalias(dev, env);
+       if (ret != -ENODEV)
+               return ret;
+
+       return add_uevent_var(env, "MODALIAS=apr:%s", adev->name);
+}
+
+struct bus_type aprbus = {
+       .name           = "aprbus",
+       .match          = apr_device_match,
+       .probe          = apr_device_probe,
+       .uevent         = apr_uevent,
+       .remove         = apr_device_remove,
+};
+EXPORT_SYMBOL_GPL(aprbus);
+
+static int apr_add_device(struct device *dev, struct device_node *np,
+                         const struct apr_device_id *id)
+{
+       struct apr *apr = dev_get_drvdata(dev);
+       struct apr_device *adev = NULL;
+       int ret;
+
+       adev = kzalloc(sizeof(*adev), GFP_KERNEL);
+       if (!adev)
+               return -ENOMEM;
+
+       spin_lock_init(&adev->lock);
+
+       adev->svc_id = id->svc_id;
+       adev->domain_id = id->domain_id;
+       adev->version = id->svc_version;
+       if (np)
+               strncpy(adev->name, np->name, APR_NAME_SIZE);
+       else
+               strncpy(adev->name, id->name, APR_NAME_SIZE);
+
+       dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name,
+                    id->domain_id, id->svc_id);
+
+       adev->dev.bus = &aprbus;
+       adev->dev.parent = dev;
+       adev->dev.of_node = np;
+       adev->dev.release = apr_dev_release;
+       adev->dev.driver = NULL;
+
+       spin_lock(&apr->svcs_lock);
+       idr_alloc(&apr->svcs_idr, adev, id->svc_id,
+                 id->svc_id + 1, GFP_ATOMIC);
+       spin_unlock(&apr->svcs_lock);
+
+       dev_info(dev, "Adding APR dev: %s\n", dev_name(&adev->dev));
+
+       ret = device_register(&adev->dev);
+       if (ret) {
+               dev_err(dev, "device_register failed: %d\n", ret);
+               put_device(&adev->dev);
+       }
+
+       return ret;
+}
+
+static void of_register_apr_devices(struct device *dev)
+{
+       struct apr *apr = dev_get_drvdata(dev);
+       struct device_node *node;
+
+       for_each_child_of_node(dev->of_node, node) {
+               struct apr_device_id id = { {0} };
+
+               if (of_property_read_u32(node, "reg", &id.svc_id))
+                       continue;
+
+               id.domain_id = apr->dest_domain_id;
+
+               if (apr_add_device(dev, node, &id))
+                       dev_err(dev, "Failed to add apr %d svc\n", id.svc_id);
+       }
+}
+
+static int apr_probe(struct rpmsg_device *rpdev)
+{
+       struct device *dev = &rpdev->dev;
+       struct apr *apr;
+       int ret;
+
+       apr = devm_kzalloc(dev, sizeof(*apr), GFP_KERNEL);
+       if (!apr)
+               return -ENOMEM;
+
+       ret = of_property_read_u32(dev->of_node, "reg", &apr->dest_domain_id);
+       if (ret) {
+               dev_err(dev, "APR Domain ID not specified in DT\n");
+               return ret;
+       }
+
+       dev_set_drvdata(dev, apr);
+       apr->ch = rpdev->ept;
+       apr->dev = dev;
+       spin_lock_init(&apr->svcs_lock);
+       idr_init(&apr->svcs_idr);
+       of_register_apr_devices(dev);
+
+       return 0;
+}
+
+static int apr_remove_device(struct device *dev, void *null)
+{
+       struct apr_device *adev = to_apr_device(dev);
+
+       device_unregister(&adev->dev);
+
+       return 0;
+}
+
+static void apr_remove(struct rpmsg_device *rpdev)
+{
+       device_for_each_child(&rpdev->dev, NULL, apr_remove_device);
+}
+
+/*
+ * __apr_driver_register() - Client driver registration with aprbus
+ *
+ * @drv:Client driver to be associated with client-device.
+ * @owner: owning module/driver
+ *
+ * This API will register the client driver with the aprbus
+ * It is called from the driver's module-init function.
+ */
+int __apr_driver_register(struct apr_driver *drv, struct module *owner)
+{
+       drv->driver.bus = &aprbus;
+       drv->driver.owner = owner;
+
+       return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(__apr_driver_register);
+
+/*
+ * apr_driver_unregister() - Undo effect of apr_driver_register
+ *
+ * @drv: Client driver to be unregistered
+ */
+void apr_driver_unregister(struct apr_driver *drv)
+{
+       driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(apr_driver_unregister);
+
+static const struct of_device_id apr_of_match[] = {
+       { .compatible = "qcom,apr"},
+       { .compatible = "qcom,apr-v2"},
+       {}
+};
+MODULE_DEVICE_TABLE(of, apr_of_match);
+
+static struct rpmsg_driver apr_driver = {
+       .probe = apr_probe,
+       .remove = apr_remove,
+       .callback = apr_callback,
+       .drv = {
+               .name = "qcom,apr",
+               .of_match_table = apr_of_match,
+       },
+};
+
+static int __init apr_init(void)
+{
+       int ret;
+
+       ret = bus_register(&aprbus);
+       if (!ret)
+               ret = register_rpmsg_driver(&apr_driver);
+       else
+               bus_unregister(&aprbus);
+
+       return ret;
+}
+
+static void __exit apr_exit(void)
+{
+       bus_unregister(&aprbus);
+       unregister_rpmsg_driver(&apr_driver);
+}
+
+subsys_initcall(apr_init);
+module_exit(apr_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Qualcomm APR Bus");
diff --git a/include/dt-bindings/soc/qcom,apr.h b/include/dt-bindings/soc/qcom,apr.h
new file mode 100644 (file)
index 0000000..0063624
--- /dev/null
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_BINDINGS_QCOM_APR_H
+#define __DT_BINDINGS_QCOM_APR_H
+
+/* Domain IDs */
+#define APR_DOMAIN_SIM         0x1
+#define APR_DOMAIN_PC          0x2
+#define APR_DOMAIN_MODEM       0x3
+#define APR_DOMAIN_ADSP                0x4
+#define APR_DOMAIN_APPS                0x5
+#define APR_DOMAIN_MAX         0x6
+
+/* ADSP service IDs */
+#define APR_SVC_ADSP_CORE      0x3
+#define APR_SVC_AFE            0x4
+#define APR_SVC_VSM            0x5
+#define APR_SVC_VPM            0x6
+#define APR_SVC_ASM            0x7
+#define APR_SVC_ADM            0x8
+#define APR_SVC_ADSP_MVM       0x09
+#define APR_SVC_ADSP_CVS       0x0A
+#define APR_SVC_ADSP_CVP       0x0B
+#define APR_SVC_USM            0x0C
+#define APR_SVC_LSM            0x0D
+#define APR_SVC_VIDC           0x16
+#define APR_SVC_MAX            0x17
+
+#endif /* __DT_BINDINGS_QCOM_APR_H */
index 751fe1416f958ea0f3f5ae56309fe7992f2134eb..15f138bebe16b229ed00230d4c3d0221475c2408 100644 (file)
 #define MX51_AUDMUX_PORT6              5
 #define MX51_AUDMUX_PORT7              6
 
+/*
+ * TFCSEL/RFCSEL (i.MX27) or TFSEL/TCSEL/RFSEL/RCSEL (i.MX31/51/53/6Q)
+ * can be sourced from Rx/Tx.
+ */
+#define IMX_AUDMUX_RXFS                        0x8
+#define IMX_AUDMUX_RXCLK               0x8
+
 /* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
 #define IMX_AUDMUX_V1_PCR_INMMASK(x)   ((x) & 0xff)
 #define IMX_AUDMUX_V1_PCR_INMEN                (1 << 8)
diff --git a/include/dt-bindings/sound/qcom,q6afe.h b/include/dt-bindings/sound/qcom,q6afe.h
new file mode 100644 (file)
index 0000000..e2d3892
--- /dev/null
@@ -0,0 +1,111 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_BINDINGS_Q6_AFE_H__
+#define __DT_BINDINGS_Q6_AFE_H__
+
+/* Audio Front End (AFE) virtual ports IDs */
+#define HDMI_RX                1
+#define SLIMBUS_0_RX    2
+#define SLIMBUS_0_TX    3
+#define SLIMBUS_1_RX    4
+#define SLIMBUS_1_TX    5
+#define SLIMBUS_2_RX    6
+#define SLIMBUS_2_TX    7
+#define SLIMBUS_3_RX    8
+#define SLIMBUS_3_TX    9
+#define SLIMBUS_4_RX    10
+#define SLIMBUS_4_TX    11
+#define SLIMBUS_5_RX    12
+#define SLIMBUS_5_TX    13
+#define SLIMBUS_6_RX    14
+#define SLIMBUS_6_TX    15
+#define PRIMARY_MI2S_RX                16
+#define PRIMARY_MI2S_TX                17
+#define SECONDARY_MI2S_RX      18
+#define SECONDARY_MI2S_TX      19
+#define TERTIARY_MI2S_RX       20
+#define TERTIARY_MI2S_TX       21
+#define QUATERNARY_MI2S_RX     22
+#define QUATERNARY_MI2S_TX     23
+#define PRIMARY_TDM_RX_0       24
+#define PRIMARY_TDM_TX_0       25
+#define PRIMARY_TDM_RX_1       26
+#define PRIMARY_TDM_TX_1       27
+#define PRIMARY_TDM_RX_2       28
+#define PRIMARY_TDM_TX_2       29
+#define PRIMARY_TDM_RX_3       30
+#define PRIMARY_TDM_TX_3       31
+#define PRIMARY_TDM_RX_4       32
+#define PRIMARY_TDM_TX_4       33
+#define PRIMARY_TDM_RX_5       34
+#define PRIMARY_TDM_TX_5       35
+#define PRIMARY_TDM_RX_6       36
+#define PRIMARY_TDM_TX_6       37
+#define PRIMARY_TDM_RX_7       38
+#define PRIMARY_TDM_TX_7       39
+#define SECONDARY_TDM_RX_0     40
+#define SECONDARY_TDM_TX_0     41
+#define SECONDARY_TDM_RX_1     42
+#define SECONDARY_TDM_TX_1     43
+#define SECONDARY_TDM_RX_2     44
+#define SECONDARY_TDM_TX_2     45
+#define SECONDARY_TDM_RX_3     46
+#define SECONDARY_TDM_TX_3     47
+#define SECONDARY_TDM_RX_4     48
+#define SECONDARY_TDM_TX_4     49
+#define SECONDARY_TDM_RX_5     50
+#define SECONDARY_TDM_TX_5     51
+#define SECONDARY_TDM_RX_6     52
+#define SECONDARY_TDM_TX_6     53
+#define SECONDARY_TDM_RX_7     54
+#define SECONDARY_TDM_TX_7     55
+#define TERTIARY_TDM_RX_0      56
+#define TERTIARY_TDM_TX_0      57
+#define TERTIARY_TDM_RX_1      58
+#define TERTIARY_TDM_TX_1      59
+#define TERTIARY_TDM_RX_2      60
+#define TERTIARY_TDM_TX_2      61
+#define TERTIARY_TDM_RX_3      62
+#define TERTIARY_TDM_TX_3      63
+#define TERTIARY_TDM_RX_4      64
+#define TERTIARY_TDM_TX_4      65
+#define TERTIARY_TDM_RX_5      66
+#define TERTIARY_TDM_TX_5      67
+#define TERTIARY_TDM_RX_6      68
+#define TERTIARY_TDM_TX_6      69
+#define TERTIARY_TDM_RX_7      70
+#define TERTIARY_TDM_TX_7      71
+#define QUATERNARY_TDM_RX_0    72
+#define QUATERNARY_TDM_TX_0    73
+#define QUATERNARY_TDM_RX_1    74
+#define QUATERNARY_TDM_TX_1    75
+#define QUATERNARY_TDM_RX_2    76
+#define QUATERNARY_TDM_TX_2    77
+#define QUATERNARY_TDM_RX_3    78
+#define QUATERNARY_TDM_TX_3    79
+#define QUATERNARY_TDM_RX_4    80
+#define QUATERNARY_TDM_TX_4    81
+#define QUATERNARY_TDM_RX_5    82
+#define QUATERNARY_TDM_TX_5    83
+#define QUATERNARY_TDM_RX_6    84
+#define QUATERNARY_TDM_TX_6    85
+#define QUATERNARY_TDM_RX_7    86
+#define QUATERNARY_TDM_TX_7    87
+#define QUINARY_TDM_RX_0       88
+#define QUINARY_TDM_TX_0       89
+#define QUINARY_TDM_RX_1       90
+#define QUINARY_TDM_TX_1       91
+#define QUINARY_TDM_RX_2       92
+#define QUINARY_TDM_TX_2       93
+#define QUINARY_TDM_RX_3       94
+#define QUINARY_TDM_TX_3       95
+#define QUINARY_TDM_RX_4       96
+#define QUINARY_TDM_TX_4       97
+#define QUINARY_TDM_RX_5       98
+#define QUINARY_TDM_TX_5       99
+#define QUINARY_TDM_RX_6       100
+#define QUINARY_TDM_TX_6       101
+#define QUINARY_TDM_RX_7       102
+#define QUINARY_TDM_TX_7       103
+
+#endif /* __DT_BINDINGS_Q6_AFE_H__ */
+
diff --git a/include/dt-bindings/sound/qcom,q6asm.h b/include/dt-bindings/sound/qcom,q6asm.h
new file mode 100644 (file)
index 0000000..1eb77d8
--- /dev/null
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_BINDINGS_Q6_ASM_H__
+#define __DT_BINDINGS_Q6_ASM_H__
+
+#define        MSM_FRONTEND_DAI_MULTIMEDIA1    0
+#define        MSM_FRONTEND_DAI_MULTIMEDIA2    1
+#define        MSM_FRONTEND_DAI_MULTIMEDIA3    2
+#define        MSM_FRONTEND_DAI_MULTIMEDIA4    3
+#define        MSM_FRONTEND_DAI_MULTIMEDIA5    4
+#define        MSM_FRONTEND_DAI_MULTIMEDIA6    5
+#define        MSM_FRONTEND_DAI_MULTIMEDIA7    6
+#define        MSM_FRONTEND_DAI_MULTIMEDIA8    7
+#define        MSM_FRONTEND_DAI_MULTIMEDIA9    8
+#define        MSM_FRONTEND_DAI_MULTIMEDIA10   9
+#define        MSM_FRONTEND_DAI_MULTIMEDIA11   10
+#define        MSM_FRONTEND_DAI_MULTIMEDIA12   11
+#define        MSM_FRONTEND_DAI_MULTIMEDIA13   12
+#define        MSM_FRONTEND_DAI_MULTIMEDIA14   13
+#define        MSM_FRONTEND_DAI_MULTIMEDIA15   14
+#define        MSM_FRONTEND_DAI_MULTIMEDIA16   15
+
+#endif /* __DT_BINDINGS_Q6_ASM_H__ */
diff --git a/include/dt-bindings/sound/rt5640.h b/include/dt-bindings/sound/rt5640.h
new file mode 100644 (file)
index 0000000..154c9b4
--- /dev/null
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_RT5640_H
+#define __DT_RT5640_H
+
+#define RT5640_DMIC1_DATA_PIN_NONE     0
+#define RT5640_DMIC1_DATA_PIN_IN1P     1
+#define RT5640_DMIC1_DATA_PIN_GPIO3    2
+
+#define RT5640_DMIC2_DATA_PIN_NONE     0
+#define RT5640_DMIC2_DATA_PIN_IN1N     1
+#define RT5640_DMIC2_DATA_PIN_GPIO4    2
+
+#define RT5640_JD_SRC_GPIO1            1
+#define RT5640_JD_SRC_JD1_IN4P         2
+#define RT5640_JD_SRC_JD2_IN4N         3
+#define RT5640_JD_SRC_GPIO2            4
+#define RT5640_JD_SRC_GPIO3            5
+#define RT5640_JD_SRC_GPIO4            6
+
+#define RT5640_OVCD_SF_0P5             0
+#define RT5640_OVCD_SF_0P75            1
+#define RT5640_OVCD_SF_1P0             2
+#define RT5640_OVCD_SF_1P5             3
+
+#endif /* __DT_RT5640_H */
index bd581c6fa0855bf9014a5cb061d5dc78df204e21..0bc41c4c0429a5bb8937aece23a0843f82a7b9b1 100644 (file)
@@ -617,11 +617,8 @@ struct wm8350_audio_platform_data {
        u32 codec_current_charge:2;     /* codec current @ vmid charge */
 };
 
-struct snd_soc_codec;
-
 struct wm8350_codec {
        struct platform_device *pdev;
-       struct snd_soc_codec *codec;
        struct wm8350_audio_platform_data *platform_data;
 };
 
index 7d361be2e24f4f428a1167efe04f79ebe0a3fde5..2014bd19f28eff41ae37b80eba324644c537e291 100644 (file)
@@ -471,6 +471,17 @@ struct slim_device_id {
        kernel_ulong_t driver_data;
 };
 
+#define APR_NAME_SIZE  32
+#define APR_MODULE_PREFIX "apr:"
+
+struct apr_device_id {
+       char name[APR_NAME_SIZE];
+       __u32 domain_id;
+       __u32 svc_id;
+       __u32 svc_version;
+       kernel_ulong_t driver_data;     /* Data private to the driver */
+};
+
 #define SPMI_NAME_SIZE 32
 #define SPMI_MODULE_PREFIX "spmi:"
 
diff --git a/include/linux/soc/qcom/apr.h b/include/linux/soc/qcom/apr.h
new file mode 100644 (file)
index 0000000..c5d52e2
--- /dev/null
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __QCOM_APR_H_
+#define __QCOM_APR_H_
+
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+#include <dt-bindings/soc/qcom,apr.h>
+
+extern struct bus_type aprbus;
+
+#define APR_HDR_LEN(hdr_len) ((hdr_len)/4)
+
+/*
+ * HEADER field
+ * version:0:3
+ * header_size : 4:7
+ * message_type : 8:9
+ * reserved: 10:15
+ */
+#define APR_HDR_FIELD(msg_type, hdr_len, ver)\
+       (((msg_type & 0x3) << 8) | ((hdr_len & 0xF) << 4) | (ver & 0xF))
+
+#define APR_HDR_SIZE sizeof(struct apr_hdr)
+#define APR_SEQ_CMD_HDR_FIELD APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
+                                           APR_HDR_LEN(APR_HDR_SIZE), \
+                                           APR_PKT_VER)
+/* Version */
+#define APR_PKT_VER            0x0
+
+/* Command and Response Types */
+#define APR_MSG_TYPE_EVENT     0x0
+#define APR_MSG_TYPE_CMD_RSP   0x1
+#define APR_MSG_TYPE_SEQ_CMD   0x2
+#define APR_MSG_TYPE_NSEQ_CMD  0x3
+#define APR_MSG_TYPE_MAX       0x04
+
+/* APR Basic Response Message */
+#define APR_BASIC_RSP_RESULT 0x000110E8
+#define APR_RSP_ACCEPTED     0x000100BE
+
+struct aprv2_ibasic_rsp_result_t {
+       uint32_t opcode;
+       uint32_t status;
+};
+
+/* hdr field Ver [0:3], Size [4:7], Message type [8:10] */
+#define APR_HDR_FIELD_VER(h)           (h & 0x000F)
+#define APR_HDR_FIELD_SIZE(h)          ((h & 0x00F0) >> 4)
+#define APR_HDR_FIELD_SIZE_BYTES(h)    (((h & 0x00F0) >> 4) * 4)
+#define APR_HDR_FIELD_MT(h)            ((h & 0x0300) >> 8)
+
+struct apr_hdr {
+       uint16_t hdr_field;
+       uint16_t pkt_size;
+       uint8_t src_svc;
+       uint8_t src_domain;
+       uint16_t src_port;
+       uint8_t dest_svc;
+       uint8_t dest_domain;
+       uint16_t dest_port;
+       uint32_t token;
+       uint32_t opcode;
+} __packed;
+
+struct apr_pkt {
+       struct apr_hdr hdr;
+       uint8_t payload[];
+};
+
+struct apr_resp_pkt {
+       struct apr_hdr hdr;
+       void *payload;
+       int payload_size;
+};
+
+/* Bits 0 to 15 -- Minor version,  Bits 16 to 31 -- Major version */
+#define APR_SVC_MAJOR_VERSION(v)       ((v >> 16) & 0xFF)
+#define APR_SVC_MINOR_VERSION(v)       (v & 0xFF)
+
+struct apr_device {
+       struct device   dev;
+       uint16_t        svc_id;
+       uint16_t        domain_id;
+       uint32_t        version;
+       char name[APR_NAME_SIZE];
+       spinlock_t      lock;
+       struct list_head node;
+};
+
+#define to_apr_device(d) container_of(d, struct apr_device, dev)
+
+struct apr_driver {
+       int     (*probe)(struct apr_device *sl);
+       int     (*remove)(struct apr_device *sl);
+       int     (*callback)(struct apr_device *a,
+                           struct apr_resp_pkt *d);
+       struct device_driver            driver;
+       const struct apr_device_id      *id_table;
+};
+
+#define to_apr_driver(d) container_of(d, struct apr_driver, driver)
+
+/*
+ * use a macro to avoid include chaining to get THIS_MODULE
+ */
+#define apr_driver_register(drv) __apr_driver_register(drv, THIS_MODULE)
+
+int __apr_driver_register(struct apr_driver *drv, struct module *owner);
+void apr_driver_unregister(struct apr_driver *drv);
+
+/**
+ * module_apr_driver() - Helper macro for registering a aprbus driver
+ * @__aprbus_driver: aprbus_driver struct
+ *
+ * Helper macro for aprbus drivers which do not do anything special in
+ * module init/exit. This eliminates a lot of boilerplate. Each module
+ * may only use this macro once, and calling it replaces module_init()
+ * and module_exit()
+ */
+#define module_apr_driver(__apr_driver) \
+       module_driver(__apr_driver, apr_driver_register, \
+                       apr_driver_unregister)
+
+int apr_send_pkt(struct apr_device *adev, struct apr_pkt *pkt);
+
+#endif /* __QCOM_APR_H_ */
index 49699255cfd3475430d655f4c9e1a52d7e840249..ba4b3e3327ff30a394d82b65f0499dd2b974853f 100644 (file)
@@ -189,6 +189,13 @@ struct uac2_iso_endpoint_descriptor {
 #define UAC2_CONTROL_DATA_OVERRUN      (3 << 2)
 #define UAC2_CONTROL_DATA_UNDERRUN     (3 << 4)
 
+/* 5.2.5.4.2 Connector Control Parameter Block */
+struct uac2_connectors_ctl_blk {
+       __u8 bNrChannels;
+       __le32 bmChannelConfig;
+       __u8 iChannelNames;
+} __attribute__((packed));
+
 /* 6.1 Interrupt Data Message */
 
 #define UAC2_INTERRUPT_DATA_MSG_VENDOR (1 << 0)
index a8959aaba0ae3d2c7da7f2fa56e5b1be1e3cb23e..a710e28b521506bbb4f38414ea0c9f9301da97a9 100644 (file)
@@ -221,6 +221,12 @@ struct uac3_iso_endpoint_descriptor {
        __le16 wLockDelay;
 } __attribute__((packed));
 
+/* 5.2.1.6.1 INSERTION CONTROL PARAMETER BLOCK */
+struct uac3_insertion_ctl_blk {
+       __u8 bSize;
+       __u8 bmConInserted;
+} __attribute__ ((packed));
+
 /* 6.1 INTERRUPT DATA MESSAGE */
 struct uac3_interrupt_data_msg {
        __u8 bInfo;
@@ -392,4 +398,38 @@ struct uac3_interrupt_data_msg {
 #define UAC3_AC_ACTIVE_INTERFACE_CONTROL       0x01
 #define UAC3_AC_POWER_DOMAIN_CONTROL           0x02
 
+/* A.23.5 TERMINAL CONTROL SELECTORS */
+#define UAC3_TE_UNDEFINED                      0x00
+#define UAC3_TE_INSERTION                      0x01
+#define UAC3_TE_OVERLOAD                       0x02
+#define UAC3_TE_UNDERFLOW                      0x03
+#define UAC3_TE_OVERFLOW                       0x04
+#define UAC3_TE_LATENCY                        0x05
+
+/* BADD predefined Unit/Terminal values */
+#define UAC3_BADD_IT_ID1       1  /* Input Terminal ID1: bTerminalID = 1 */
+#define UAC3_BADD_FU_ID2       2  /* Feature Unit ID2: bUnitID = 2 */
+#define UAC3_BADD_OT_ID3       3  /* Output Terminal ID3: bTerminalID = 3 */
+#define UAC3_BADD_IT_ID4       4  /* Input Terminal ID4: bTerminalID = 4 */
+#define UAC3_BADD_FU_ID5       5  /* Feature Unit ID5: bUnitID = 5 */
+#define UAC3_BADD_OT_ID6       6  /* Output Terminal ID6: bTerminalID = 6 */
+#define UAC3_BADD_FU_ID7       7  /* Feature Unit ID7: bUnitID = 7 */
+#define UAC3_BADD_MU_ID8       8  /* Mixer Unit ID8: bUnitID = 8 */
+#define UAC3_BADD_CS_ID9       9  /* Clock Source Entity ID9: bClockID = 9 */
+#define UAC3_BADD_PD_ID10      10 /* Power Domain ID10: bPowerDomainID = 10 */
+#define UAC3_BADD_PD_ID11      11 /* Power Domain ID11: bPowerDomainID = 11 */
+
+/* BADD wMaxPacketSize of AS endpoints */
+#define UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_16             0x0060
+#define UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_16            0x0062
+#define UAC3_BADD_EP_MAXPSIZE_SYNC_MONO_24             0x0090
+#define UAC3_BADD_EP_MAXPSIZE_ASYNC_MONO_24            0x0093
+#define UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_16           0x00C0
+#define UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_16          0x00C4
+#define UAC3_BADD_EP_MAXPSIZE_SYNC_STEREO_24           0x0120
+#define UAC3_BADD_EP_MAXPSIZE_ASYNC_STEREO_24          0x0126
+
+/* BADD sample rate is always fixed to 48kHz */
+#define UAC3_BADD_SAMPLING_RATE                                48000
+
 #endif /* __LINUX_USB_AUDIO_V3_H */
index 5f181b875c2feec545f5efaf7561362527d148c7..36a5934cf4b10fc5083cc08f420a091bb9c24075 100644 (file)
@@ -51,7 +51,6 @@ struct completion;
  */
 enum snd_device_type {
        SNDRV_DEV_LOWLEVEL,
-       SNDRV_DEV_CONTROL,
        SNDRV_DEV_INFO,
        SNDRV_DEV_BUS,
        SNDRV_DEV_CODEC,
@@ -62,6 +61,7 @@ enum snd_device_type {
        SNDRV_DEV_SEQUENCER,
        SNDRV_DEV_HWDEP,
        SNDRV_DEV_JACK,
+       SNDRV_DEV_CONTROL,      /* NOTE: this must be the last one */
 };
 
 enum snd_device_state {
index 5ebcc51c0a6a020635639e9629cd4e2afd169c68..8c1572de44c524a9897d18b7139a83c12d8da8b4 100644 (file)
@@ -1610,7 +1610,7 @@ struct snd_emu10k1_fx8010_pcm {
        struct snd_pcm_indirect pcm_rec;
        unsigned int tram_pos;
        unsigned int tram_shift;
-       struct snd_emu10k1_fx8010_irq *irq;
+       struct snd_emu10k1_fx8010_irq irq;
 };
 
 struct snd_emu10k1_fx8010 {
@@ -1902,7 +1902,7 @@ int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
                                            snd_fx8010_irq_handler_t *handler,
                                            unsigned char gpr_running,
                                            void *private_data,
-                                           struct snd_emu10k1_fx8010_irq **r_irq);
+                                           struct snd_emu10k1_fx8010_irq *irq);
 int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
                                              struct snd_emu10k1_fx8010_irq *irq);
 
index 06536e01ed94b183246f7ea4245647857d43afa7..c052afc2754721a00e8afbc40fb73875e2962423 100644 (file)
@@ -571,4 +571,9 @@ static inline unsigned int snd_array_index(struct snd_array *array, void *ptr)
        return (unsigned long)(ptr - array->list) / array->elem_size;
 }
 
+/* a helper macro to iterate for each snd_array element */
+#define snd_array_for_each(array, idx, ptr) \
+       for ((idx) = 0, (ptr) = (array)->list; (idx) < (array)->used; \
+            (ptr) = snd_array_elem(array, ++(idx)))
+
 #endif /* __SOUND_HDAUDIO_H */
index 782d1df342082da5327c4c763a571482712b8f49..9c3db3dce32b4a5e3f0bd4a14d65eaa4556341bf 100644 (file)
@@ -34,11 +34,9 @@ struct snd_dma_device {
        struct device *dev;             /* generic device */
 };
 
-#ifndef snd_dma_pci_data
 #define snd_dma_pci_data(pci)  (&(pci)->dev)
 #define snd_dma_isa_data()     NULL
 #define snd_dma_continuous_data(x)     ((struct device *)(__force unsigned long)(x))
-#endif
 
 
 /*
diff --git a/include/sound/omap-pcm.h b/include/sound/omap-pcm.h
deleted file mode 100644 (file)
index c1d2f31..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * omap-pcm.h - OMAP PCM driver
- *
- * Copyright (C) 2014 Texas Instruments, Inc.
- *
- * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- */
-
-#ifndef __OMAP_PCM_H__
-#define __OMAP_PCM_H__
-
-#if IS_ENABLED(CONFIG_SND_OMAP_SOC)
-int omap_pcm_platform_register(struct device *dev);
-#else
-static inline int omap_pcm_platform_register(struct device *dev)
-{
-       return 0;
-}
-#endif /* CONFIG_SND_OMAP_SOC */
-
-#endif /* __OMAP_PCM_H__ */
diff --git a/include/sound/rt5640.h b/include/sound/rt5640.h
deleted file mode 100644 (file)
index e3c84b9..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * linux/sound/rt5640.h -- Platform data for RT5640
- *
- * Copyright 2011 Realtek Microelectronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __LINUX_SND_RT5640_H
-#define __LINUX_SND_RT5640_H
-
-struct rt5640_platform_data {
-       /* IN1 & IN2 & IN3 can optionally be differential */
-       bool in1_diff;
-       bool in2_diff;
-       bool in3_diff;
-
-       bool dmic_en;
-       bool dmic1_data_pin; /* 0 = IN1P; 1 = GPIO3 */
-       bool dmic2_data_pin; /* 0 = IN1N; 1 = GPIO4 */
-
-       int ldo1_en; /* GPIO for LDO1_EN */
-};
-
-#endif
diff --git a/include/sound/rt5668.h b/include/sound/rt5668.h
new file mode 100644 (file)
index 0000000..f907b78
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * linux/sound/rt5668.h -- Platform data for RT5668
+ *
+ * Copyright 2018 Realtek Microelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_RT5668_H
+#define __LINUX_SND_RT5668_H
+
+enum rt5668_dmic1_data_pin {
+       RT5668_DMIC1_NULL,
+       RT5668_DMIC1_DATA_GPIO2,
+       RT5668_DMIC1_DATA_GPIO5,
+};
+
+enum rt5668_dmic1_clk_pin {
+       RT5668_DMIC1_CLK_GPIO1,
+       RT5668_DMIC1_CLK_GPIO3,
+};
+
+enum rt5668_jd_src {
+       RT5668_JD_NULL,
+       RT5668_JD1,
+};
+
+struct rt5668_platform_data {
+
+       int ldo1_en; /* GPIO for LDO1_EN */
+
+       enum rt5668_dmic1_data_pin dmic1_data_pin;
+       enum rt5668_dmic1_clk_pin dmic1_clk_pin;
+       enum rt5668_jd_src jd_src;
+};
+
+#endif
+
index 3ddb575eed54aa71e6f1ed3c4b19ce4b5e2ef1a1..e6f8c40ed43c3f1615aaad20af4e467a3bc937e5 100644 (file)
@@ -296,8 +296,8 @@ struct snd_soc_dai {
        struct snd_soc_dai_driver *driver;
 
        /* DAI runtime info */
-       unsigned int capture_active:1;          /* stream is in use */
-       unsigned int playback_active:1;         /* stream is in use */
+       unsigned int capture_active;            /* stream usage count */
+       unsigned int playback_active;           /* stream usage count */
        unsigned int probed:1;
 
        unsigned int active;
@@ -315,7 +315,6 @@ struct snd_soc_dai {
        unsigned int sample_bits;
 
        /* parent platform/codec */
-       struct snd_soc_codec *codec;
        struct snd_soc_component *component;
 
        /* CODEC TDM slot masks and params (for fixup) */
index ad266d7e95537c470837cdeae1a7afcad639d75c..1378dcd2128aa34f9fdbf9197817760bb98e96df 100644 (file)
@@ -401,11 +401,7 @@ struct snd_soc_ops;
 struct snd_soc_pcm_runtime;
 struct snd_soc_dai;
 struct snd_soc_dai_driver;
-struct snd_soc_platform;
 struct snd_soc_dai_link;
-struct snd_soc_platform_driver;
-struct snd_soc_codec;
-struct snd_soc_codec_driver;
 struct snd_soc_component;
 struct snd_soc_component_driver;
 struct soc_enum;
@@ -430,13 +426,6 @@ enum snd_soc_card_subclass {
        SND_SOC_CARD_CLASS_RUNTIME      = 1,
 };
 
-int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id,
-                            int source, unsigned int freq, int dir);
-int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
-                         unsigned int freq_in, unsigned int freq_out);
-int snd_soc_codec_set_jack(struct snd_soc_codec *codec,
-                          struct snd_soc_jack *jack, void *data);
-
 int snd_soc_register_card(struct snd_soc_card *card);
 int snd_soc_unregister_card(struct snd_soc_card *card);
 int devm_snd_soc_register_card(struct device *dev, struct snd_soc_card *card);
@@ -455,19 +444,6 @@ static inline int snd_soc_resume(struct device *dev)
 }
 #endif
 int snd_soc_poweroff(struct device *dev);
-int snd_soc_register_platform(struct device *dev,
-               const struct snd_soc_platform_driver *platform_drv);
-int devm_snd_soc_register_platform(struct device *dev,
-               const struct snd_soc_platform_driver *platform_drv);
-void snd_soc_unregister_platform(struct device *dev);
-int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
-               const struct snd_soc_platform_driver *platform_drv);
-void snd_soc_remove_platform(struct snd_soc_platform *platform);
-struct snd_soc_platform *snd_soc_lookup_platform(struct device *dev);
-int snd_soc_register_codec(struct device *dev,
-               const struct snd_soc_codec_driver *codec_drv,
-               struct snd_soc_dai_driver *dai_drv, int num_dai);
-void snd_soc_unregister_codec(struct device *dev);
 int snd_soc_add_component(struct device *dev,
                struct snd_soc_component *component,
                const struct snd_soc_component_driver *component_driver,
@@ -482,16 +458,15 @@ int devm_snd_soc_register_component(struct device *dev,
 void snd_soc_unregister_component(struct device *dev);
 struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
                                                   const char *driver_name);
-int snd_soc_cache_init(struct snd_soc_codec *codec);
-int snd_soc_cache_exit(struct snd_soc_codec *codec);
 
-int snd_soc_platform_read(struct snd_soc_platform *platform,
-                                       unsigned int reg);
-int snd_soc_platform_write(struct snd_soc_platform *platform,
-                                       unsigned int reg, unsigned int val);
 int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num);
 #ifdef CONFIG_SND_SOC_COMPRESS
 int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num);
+#else
+static inline int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
+{
+       return 0;
+}
 #endif
 
 void snd_soc_disconnect_sync(struct device *dev);
@@ -576,23 +551,7 @@ static inline void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
 }
 #endif
 
-/* codec register bit access */
-int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg,
-                               unsigned int mask, unsigned int value);
-int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
-                              unsigned int reg, unsigned int mask,
-                              unsigned int value);
-int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
-                               unsigned int mask, unsigned int value);
-
 #ifdef CONFIG_SND_SOC_AC97_BUS
-#define snd_soc_alloc_ac97_codec(codec) \
-       snd_soc_alloc_ac97_component(&codec->component)
-#define snd_soc_new_ac97_codec(codec, id, id_mask) \
-       snd_soc_new_ac97_component(&codec->component, id, id_mask)
-#define snd_soc_free_ac97_codec(ac97) \
-       snd_soc_free_ac97_component(ac97)
-
 struct snd_ac97 *snd_soc_alloc_ac97_component(struct snd_soc_component *component);
 struct snd_ac97 *snd_soc_new_ac97_component(struct snd_soc_component *component,
        unsigned int id, unsigned int id_mask);
@@ -626,10 +585,6 @@ struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
                                               const char *name);
 int snd_soc_add_component_controls(struct snd_soc_component *component,
        const struct snd_kcontrol_new *controls, unsigned int num_controls);
-int snd_soc_add_codec_controls(struct snd_soc_codec *codec,
-       const struct snd_kcontrol_new *controls, unsigned int num_controls);
-int snd_soc_add_platform_controls(struct snd_soc_platform *platform,
-       const struct snd_kcontrol_new *controls, unsigned int num_controls);
 int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
        const struct snd_kcontrol_new *controls, int num_controls);
 int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
@@ -862,8 +817,6 @@ struct snd_soc_component {
 
        unsigned int active;
 
-       unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
-       unsigned int registered_as_component:1;
        unsigned int suspended:1; /* is in suspend PM state */
 
        struct list_head list;
@@ -875,9 +828,6 @@ struct snd_soc_component {
        struct list_head dai_list;
        int num_dai;
 
-       int (*read)(struct snd_soc_component *, unsigned int, unsigned int *);
-       int (*write)(struct snd_soc_component *, unsigned int, unsigned int);
-
        struct regmap *regmap;
        int val_bytes;
 
@@ -886,10 +836,6 @@ struct snd_soc_component {
        /* attached dynamic objects */
        struct list_head dobj_list;
 
-#ifdef CONFIG_DEBUG_FS
-       struct dentry *debugfs_root;
-#endif
-
        /*
        * DO NOT use any of the fields below in drivers, they are temporary and
        * are going to be removed again soon. If you use them in driver code the
@@ -899,29 +845,11 @@ struct snd_soc_component {
        /* Don't use these, use snd_soc_component_get_dapm() */
        struct snd_soc_dapm_context dapm;
 
-       struct snd_soc_codec *codec;
-
-       int (*probe)(struct snd_soc_component *);
-       void (*remove)(struct snd_soc_component *);
-       int (*suspend)(struct snd_soc_component *);
-       int (*resume)(struct snd_soc_component *);
-       int (*pcm_new)(struct snd_soc_component *, struct snd_soc_pcm_runtime *);
-       void (*pcm_free)(struct snd_soc_component *, struct snd_pcm *);
-
-       int (*set_sysclk)(struct snd_soc_component *component,
-                         int clk_id, int source, unsigned int freq, int dir);
-       int (*set_pll)(struct snd_soc_component *component, int pll_id,
-                      int source, unsigned int freq_in, unsigned int freq_out);
-       int (*set_jack)(struct snd_soc_component *component,
-                       struct snd_soc_jack *jack,  void *data);
-       int (*set_bias_level)(struct snd_soc_component *component,
-                             enum snd_soc_bias_level level);
-
        /* machine specific init */
        int (*init)(struct snd_soc_component *component);
 
 #ifdef CONFIG_DEBUG_FS
-       void (*init_debugfs)(struct snd_soc_component *component);
+       struct dentry *debugfs_root;
        const char *debugfs_prefix;
 #endif
 };
@@ -938,97 +866,12 @@ snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd,
 #define for_each_rtdcom_safe(rtd, rtdcom1, rtdcom2) \
        list_for_each_entry_safe(rtdcom1, rtdcom2, &(rtd)->component_list, list)
 
-/* SoC Audio Codec device */
-struct snd_soc_codec {
-       struct device *dev;
-       const struct snd_soc_codec_driver *driver;
-
-       struct list_head list;
-
-       /* runtime */
-       unsigned int cache_init:1; /* codec cache has been initialized */
-
-       /* codec IO */
-       void *control_data; /* codec control (i2c/3wire) data */
-       hw_write_t hw_write;
-       void *reg_cache;
-
-       /* component */
-       struct snd_soc_component component;
-};
-
-/* codec driver */
-struct snd_soc_codec_driver {
-
-       /* driver ops */
-       int (*probe)(struct snd_soc_codec *);
-       int (*remove)(struct snd_soc_codec *);
-       int (*suspend)(struct snd_soc_codec *);
-       int (*resume)(struct snd_soc_codec *);
-       struct snd_soc_component_driver component_driver;
-
-       /* codec wide operations */
-       int (*set_sysclk)(struct snd_soc_codec *codec,
-                         int clk_id, int source, unsigned int freq, int dir);
-       int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source,
-               unsigned int freq_in, unsigned int freq_out);
-       int (*set_jack)(struct snd_soc_codec *codec,
-                       struct snd_soc_jack *jack,  void *data);
-
-       /* codec IO */
-       struct regmap *(*get_regmap)(struct device *);
-       unsigned int (*read)(struct snd_soc_codec *, unsigned int);
-       int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
-       unsigned int reg_cache_size;
-       short reg_cache_step;
-       short reg_word_size;
-       const void *reg_cache_default;
-
-       /* codec bias level */
-       int (*set_bias_level)(struct snd_soc_codec *,
-                             enum snd_soc_bias_level level);
-       bool idle_bias_off;
-       bool suspend_bias_off;
-
-       void (*seq_notifier)(struct snd_soc_dapm_context *,
-                            enum snd_soc_dapm_type, int);
-
-       bool ignore_pmdown_time;  /* Doesn't benefit from pmdown delay */
-};
-
-/* SoC platform interface */
-struct snd_soc_platform_driver {
-
-       int (*probe)(struct snd_soc_platform *);
-       int (*remove)(struct snd_soc_platform *);
-       struct snd_soc_component_driver component_driver;
-
-       /* pcm creation and destruction */
-       int (*pcm_new)(struct snd_soc_pcm_runtime *);
-       void (*pcm_free)(struct snd_pcm *);
-
-       /* platform stream pcm ops */
-       const struct snd_pcm_ops *ops;
-
-       /* platform stream compress ops */
-       const struct snd_compr_ops *compr_ops;
-};
-
 struct snd_soc_dai_link_component {
        const char *name;
        struct device_node *of_node;
        const char *dai_name;
 };
 
-struct snd_soc_platform {
-       struct device *dev;
-       const struct snd_soc_platform_driver *driver;
-
-       struct list_head list;
-
-       struct snd_soc_component component;
-};
-
 struct snd_soc_dai_link {
        /* config - must be set by machine driver */
        const char *name;                       /* Codec name */
@@ -1276,8 +1119,6 @@ struct snd_soc_pcm_runtime {
        /* runtime devices */
        struct snd_pcm *pcm;
        struct snd_compr *compr;
-       struct snd_soc_codec *codec;
-       struct snd_soc_platform *platform; /* will be removed */
        struct snd_soc_dai *codec_dai;
        struct snd_soc_dai *cpu_dai;
 
@@ -1345,32 +1186,6 @@ struct soc_enum {
        struct snd_soc_dobj dobj;
 };
 
-/**
- * snd_soc_component_to_codec() - Casts a component to the CODEC it is embedded in
- * @component: The component to cast to a CODEC
- *
- * This function must only be used on components that are known to be CODECs.
- * Otherwise the behavior is undefined.
- */
-static inline struct snd_soc_codec *snd_soc_component_to_codec(
-       struct snd_soc_component *component)
-{
-       return container_of(component, struct snd_soc_codec, component);
-}
-
-/**
- * snd_soc_component_to_platform() - Casts a component to the platform it is embedded in
- * @component: The component to cast to a platform
- *
- * This function must only be used on components that are known to be platforms.
- * Otherwise the behavior is undefined.
- */
-static inline struct snd_soc_platform *snd_soc_component_to_platform(
-       struct snd_soc_component *component)
-{
-       return container_of(component, struct snd_soc_platform, component);
-}
-
 /**
  * snd_soc_dapm_to_component() - Casts a DAPM context to the component it is
  *  embedded in
@@ -1386,33 +1201,6 @@ static inline struct snd_soc_component *snd_soc_dapm_to_component(
        return container_of(dapm, struct snd_soc_component, dapm);
 }
 
-/**
- * snd_soc_dapm_to_codec() - Casts a DAPM context to the CODEC it is embedded in
- * @dapm: The DAPM context to cast to the CODEC
- *
- * This function must only be used on DAPM contexts that are known to be part of
- * a CODEC (e.g. in a CODEC driver). Otherwise the behavior is undefined.
- */
-static inline struct snd_soc_codec *snd_soc_dapm_to_codec(
-       struct snd_soc_dapm_context *dapm)
-{
-       return snd_soc_component_to_codec(snd_soc_dapm_to_component(dapm));
-}
-
-/**
- * snd_soc_dapm_to_platform() - Casts a DAPM context to the platform it is
- *  embedded in
- * @dapm: The DAPM context to cast to the platform.
- *
- * This function must only be used on DAPM contexts that are known to be part of
- * a platform (e.g. in a platform driver). Otherwise the behavior is undefined.
- */
-static inline struct snd_soc_platform *snd_soc_dapm_to_platform(
-       struct snd_soc_dapm_context *dapm)
-{
-       return snd_soc_component_to_platform(snd_soc_dapm_to_component(dapm));
-}
-
 /**
  * snd_soc_component_get_dapm() - Returns the DAPM context associated with a
  *  component
@@ -1424,31 +1212,6 @@ static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm(
        return &component->dapm;
 }
 
-/**
- * snd_soc_codec_get_dapm() - Returns the DAPM context for the CODEC
- * @codec: The CODEC for which to get the DAPM context
- *
- * Note: Use this function instead of directly accessing the CODEC's dapm field
- */
-static inline struct snd_soc_dapm_context *snd_soc_codec_get_dapm(
-       struct snd_soc_codec *codec)
-{
-       return snd_soc_component_get_dapm(&codec->component);
-}
-
-/**
- * snd_soc_dapm_init_bias_level() - Initialize CODEC DAPM bias level
- * @codec: The CODEC for which to initialize the DAPM bias level
- * @level: The DAPM level to initialize to
- *
- * Initializes the CODEC DAPM bias level. See snd_soc_dapm_init_bias_level().
- */
-static inline void snd_soc_codec_init_bias_level(struct snd_soc_codec *codec,
-       enum snd_soc_bias_level level)
-{
-       snd_soc_dapm_init_bias_level(snd_soc_codec_get_dapm(codec), level);
-}
-
 /**
  * snd_soc_component_init_bias_level() - Initialize COMPONENT DAPM bias level
  * @component: The COMPONENT for which to initialize the DAPM bias level
@@ -1464,18 +1227,6 @@ snd_soc_component_init_bias_level(struct snd_soc_component *component,
                snd_soc_component_get_dapm(component), level);
 }
 
-/**
- * snd_soc_dapm_get_bias_level() - Get current CODEC DAPM bias level
- * @codec: The CODEC for which to get the DAPM bias level
- *
- * Returns: The current DAPM bias level of the CODEC.
- */
-static inline enum snd_soc_bias_level snd_soc_codec_get_bias_level(
-       struct snd_soc_codec *codec)
-{
-       return snd_soc_dapm_get_bias_level(snd_soc_codec_get_dapm(codec));
-}
-
 /**
  * snd_soc_component_get_bias_level() - Get current COMPONENT DAPM bias level
  * @component: The COMPONENT for which to get the DAPM bias level
@@ -1489,21 +1240,6 @@ snd_soc_component_get_bias_level(struct snd_soc_component *component)
                snd_soc_component_get_dapm(component));
 }
 
-/**
- * snd_soc_codec_force_bias_level() - Set the CODEC DAPM bias level
- * @codec: The CODEC for which to set the level
- * @level: The level to set to
- *
- * Forces the CODEC bias level to a specific state. See
- * snd_soc_dapm_force_bias_level().
- */
-static inline int snd_soc_codec_force_bias_level(struct snd_soc_codec *codec,
-       enum snd_soc_bias_level level)
-{
-       return snd_soc_dapm_force_bias_level(snd_soc_codec_get_dapm(codec),
-               level);
-}
-
 /**
  * snd_soc_component_force_bias_level() - Set the COMPONENT DAPM bias level
  * @component: The COMPONENT for which to set the level
@@ -1521,19 +1257,6 @@ snd_soc_component_force_bias_level(struct snd_soc_component *component,
                level);
 }
 
-/**
- * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
- * @kcontrol: The kcontrol
- *
- * This function must only be used on DAPM contexts that are known to be part of
- * a CODEC (e.g. in a CODEC driver). Otherwise the behavior is undefined.
- */
-static inline struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(
-       struct snd_kcontrol *kcontrol)
-{
-       return snd_soc_dapm_to_codec(snd_soc_dapm_kcontrol_dapm(kcontrol));
-}
-
 /**
  * snd_soc_dapm_kcontrol_component() - Returns the component associated to a kcontrol
  * @kcontrol: The kcontrol
@@ -1547,22 +1270,6 @@ static inline struct snd_soc_component *snd_soc_dapm_kcontrol_component(
        return snd_soc_dapm_to_component(snd_soc_dapm_kcontrol_dapm(kcontrol));
 }
 
-/* codec IO */
-unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
-int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
-       unsigned int val);
-
-/**
- * snd_soc_cache_sync() - Sync the register cache with the hardware
- * @codec: CODEC to sync
- *
- * Note: This function will call regcache_sync()
- */
-static inline int snd_soc_cache_sync(struct snd_soc_codec *codec)
-{
-       return regcache_sync(codec->component.regmap);
-}
-
 /**
  * snd_soc_component_cache_sync() - Sync the register cache with the hardware
  * @component: COMPONENT to sync
@@ -1605,37 +1312,6 @@ void snd_soc_component_init_regmap(struct snd_soc_component *component,
        struct regmap *regmap);
 void snd_soc_component_exit_regmap(struct snd_soc_component *component);
 
-/**
- * snd_soc_codec_init_regmap() - Initialize regmap instance for the CODEC
- * @codec: The CODEC for which to initialize the regmap instance
- * @regmap: The regmap instance that should be used by the CODEC
- *
- * This function allows deferred assignment of the regmap instance that is
- * associated with the CODEC. Only use this if the regmap instance is not yet
- * ready when the CODEC is registered. The function must also be called before
- * the first IO attempt of the CODEC.
- */
-static inline void snd_soc_codec_init_regmap(struct snd_soc_codec *codec,
-       struct regmap *regmap)
-{
-       snd_soc_component_init_regmap(&codec->component, regmap);
-}
-
-/**
- * snd_soc_codec_exit_regmap() - De-initialize regmap instance for the CODEC
- * @codec: The CODEC for which to de-initialize the regmap instance
- *
- * Calls regmap_exit() on the regmap instance associated to the CODEC and
- * removes the regmap instance from the CODEC.
- *
- * This function should only be used if snd_soc_codec_init_regmap() was used to
- * initialize the regmap instance.
- */
-static inline void snd_soc_codec_exit_regmap(struct snd_soc_codec *codec)
-{
-       snd_soc_component_exit_regmap(&codec->component);
-}
-
 #endif
 
 /* device driver data */
@@ -1662,28 +1338,6 @@ static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c)
        return dev_get_drvdata(c->dev);
 }
 
-static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec,
-               void *data)
-{
-       snd_soc_component_set_drvdata(&codec->component, data);
-}
-
-static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec)
-{
-       return snd_soc_component_get_drvdata(&codec->component);
-}
-
-static inline void snd_soc_platform_set_drvdata(struct snd_soc_platform *platform,
-               void *data)
-{
-       snd_soc_component_set_drvdata(&platform->component, data);
-}
-
-static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platform)
-{
-       return snd_soc_component_get_drvdata(&platform->component);
-}
-
 static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
 {
        INIT_LIST_HEAD(&card->widgets);
@@ -1735,20 +1389,15 @@ static inline bool snd_soc_component_is_active(
        return component->active != 0;
 }
 
-static inline bool snd_soc_codec_is_active(struct snd_soc_codec *codec)
-{
-       return snd_soc_component_is_active(&codec->component);
-}
-
 /**
  * snd_soc_kcontrol_component() - Returns the component that registered the
  *  control
  * @kcontrol: The control for which to get the component
  *
  * Note: This function will work correctly if the control has been registered
- * for a component. Either with snd_soc_add_codec_controls() or
- * snd_soc_add_platform_controls() or via  table based setup for either a
- * CODEC, a platform or component driver. Otherwise the behavior is undefined.
+ * for a component. With snd_soc_add_codec_controls() or via table based
+ * setup for either a CODEC or component driver. Otherwise the behavior is
+ * undefined.
  */
 static inline struct snd_soc_component *snd_soc_kcontrol_component(
        struct snd_kcontrol *kcontrol)
@@ -1756,34 +1405,6 @@ static inline struct snd_soc_component *snd_soc_kcontrol_component(
        return snd_kcontrol_chip(kcontrol);
 }
 
-/**
- * snd_soc_kcontrol_codec() - Returns the CODEC that registered the control
- * @kcontrol: The control for which to get the CODEC
- *
- * Note: This function will only work correctly if the control has been
- * registered with snd_soc_add_codec_controls() or via table based setup of
- * snd_soc_codec_driver. Otherwise the behavior is undefined.
- */
-static inline struct snd_soc_codec *snd_soc_kcontrol_codec(
-       struct snd_kcontrol *kcontrol)
-{
-       return snd_soc_component_to_codec(snd_soc_kcontrol_component(kcontrol));
-}
-
-/**
- * snd_soc_kcontrol_platform() - Returns the platform that registered the control
- * @kcontrol: The control for which to get the platform
- *
- * Note: This function will only work correctly if the control has been
- * registered with snd_soc_add_platform_controls() or via table based setup of
- * a snd_soc_platform_driver. Otherwise the behavior is undefined.
- */
-static inline struct snd_soc_platform *snd_soc_kcontrol_platform(
-       struct snd_kcontrol *kcontrol)
-{
-       return snd_soc_component_to_platform(snd_soc_kcontrol_component(kcontrol));
-}
-
 int snd_soc_util_init(void);
 void snd_soc_util_exit(void);
 
index ccd1a3bdff46e28bdd363822141d55522ca55543..40c300fe704dadbe2974593e19cf9c29b062792b 100644 (file)
@@ -12,7 +12,6 @@
 #define DAPM_ARROW(dir) (((dir) == SND_SOC_DAPM_DIR_OUT) ? "->" : "<-")
 
 struct snd_soc_jack;
-struct snd_soc_codec;
 struct snd_soc_card;
 struct snd_soc_dapm_widget;
 struct snd_soc_dapm_path;
index 3a78e71456897d2cddf08272bbed4844d72c1e7f..13d98e6e0db1a86f46cc7d77b5652bef0c8682d2 100644 (file)
@@ -285,9 +285,22 @@ static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor
 static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc,
                                              int protocol)
 {
-       return (protocol == UAC_VERSION_1) ?
-               &desc->baSourceID[desc->bNrInPins + 4] :
-               &desc->baSourceID[desc->bNrInPins + 6];
+       switch (protocol) {
+       case UAC_VERSION_1:
+               return &desc->baSourceID[desc->bNrInPins + 4];
+       case UAC_VERSION_2:
+               return &desc->baSourceID[desc->bNrInPins + 6];
+       case UAC_VERSION_3:
+               return &desc->baSourceID[desc->bNrInPins + 2];
+       default:
+               return NULL;
+       }
+}
+
+static inline __u16 uac3_mixer_unit_wClusterDescrID(struct uac_mixer_unit_descriptor *desc)
+{
+       return (desc->baSourceID[desc->bNrInPins + 1] << 8) |
+               desc->baSourceID[desc->bNrInPins];
 }
 
 static inline __u8 uac_mixer_unit_iMixer(struct uac_mixer_unit_descriptor *desc)
index 69c37ecbff7ee389cb31b7dc49be4021e9a6fd14..a74ca232f1fc1ff69bc6b7e9e6a3d17feae0108f 100644 (file)
 #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS      (1 << 1)
 #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS    (1 << 2)
 
+/* DAI clock gating */
+#define SND_SOC_TPLG_DAI_CLK_GATE_UNDEFINED    0
+#define SND_SOC_TPLG_DAI_CLK_GATE_GATED        1
+#define SND_SOC_TPLG_DAI_CLK_GATE_CONT         2
+
+/* DAI mclk_direction */
+#define SND_SOC_TPLG_MCLK_CO            0 /* for codec, mclk is output */
+#define SND_SOC_TPLG_MCLK_CI            1 /* for codec, mclk is input */
+
 /* DAI physical PCM data formats.
  * Add new formats to the end of the list.
  */
 #define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_SAMPLEBITS    (1 << 2)
 #define SND_SOC_TPLG_LNK_FLGBIT_VOICE_WAKEUP            (1 << 3)
 
+/* DAI topology BCLK parameter
+ * For the backwards capability, by default codec is bclk master
+ */
+#define SND_SOC_TPLG_BCLK_CM         0 /* codec is bclk master */
+#define SND_SOC_TPLG_BCLK_CS         1 /* codec is bclk slave */
+
+/* DAI topology FSYNC parameter
+ * For the backwards capability, by default codec is fsync master
+ */
+#define SND_SOC_TPLG_FSYNC_CM         0 /* codec is fsync master */
+#define SND_SOC_TPLG_FSYNC_CS         1 /* codec is fsync slave */
+
 /*
  * Block Header.
  * This header precedes all object and object arrays below.
@@ -312,12 +333,12 @@ struct snd_soc_tplg_hw_config {
        __le32 size;            /* in bytes of this structure */
        __le32 id;              /* unique ID - - used to match */
        __le32 fmt;             /* SND_SOC_DAI_FORMAT_ format value */
-       __u8 clock_gated;       /* 1 if clock can be gated to save power */
+       __u8 clock_gated;       /* SND_SOC_TPLG_DAI_CLK_GATE_ value */
        __u8 invert_bclk;       /* 1 for inverted BCLK, 0 for normal */
        __u8 invert_fsync;      /* 1 for inverted frame clock, 0 for normal */
-       __u8 bclk_master;       /* 1 for master of BCLK, 0 for slave */
-       __u8 fsync_master;      /* 1 for master of FSYNC, 0 for slave */
-       __u8 mclk_direction;    /* 0 for input, 1 for output */
+       __u8 bclk_master;       /* SND_SOC_TPLG_BCLK_ value */
+       __u8 fsync_master;      /* SND_SOC_TPLG_FSYNC_ value */
+       __u8 mclk_direction;    /* SND_SOC_TPLG_MCLK_ value */
        __le16 reserved;        /* for 32bit alignment */
        __le32 mclk_rate;       /* MCLK or SYSCLK freqency in Hz */
        __le32 bclk_rate;       /* BCLK freqency in Hz */
@@ -552,4 +573,61 @@ struct snd_soc_tplg_dai {
        __le32 flags;           /* SND_SOC_TPLG_DAI_FLGBIT_* */
        struct snd_soc_tplg_private priv;
 } __attribute__((packed));
+
+/*
+ * Old version of ABI structs, supported for backward compatibility.
+ */
+
+/* Manifest v4 */
+struct snd_soc_tplg_manifest_v4 {
+       __le32 size;            /* in bytes of this structure */
+       __le32 control_elems;   /* number of control elements */
+       __le32 widget_elems;    /* number of widget elements */
+       __le32 graph_elems;     /* number of graph elements */
+       __le32 pcm_elems;       /* number of PCM elements */
+       __le32 dai_link_elems;  /* number of DAI link elements */
+       struct snd_soc_tplg_private priv;
+} __packed;
+
+/* Stream Capabilities v4 */
+struct snd_soc_tplg_stream_caps_v4 {
+       __le32 size;            /* in bytes of this structure */
+       char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+       __le64 formats; /* supported formats SNDRV_PCM_FMTBIT_* */
+       __le32 rates;           /* supported rates SNDRV_PCM_RATE_* */
+       __le32 rate_min;        /* min rate */
+       __le32 rate_max;        /* max rate */
+       __le32 channels_min;    /* min channels */
+       __le32 channels_max;    /* max channels */
+       __le32 periods_min;     /* min number of periods */
+       __le32 periods_max;     /* max number of periods */
+       __le32 period_size_min; /* min period size bytes */
+       __le32 period_size_max; /* max period size bytes */
+       __le32 buffer_size_min; /* min buffer size bytes */
+       __le32 buffer_size_max; /* max buffer size bytes */
+} __packed;
+
+/* PCM v4 */
+struct snd_soc_tplg_pcm_v4 {
+       __le32 size;            /* in bytes of this structure */
+       char pcm_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+       char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+       __le32 pcm_id;          /* unique ID - used to match with DAI link */
+       __le32 dai_id;          /* unique ID - used to match */
+       __le32 playback;        /* supports playback mode */
+       __le32 capture;         /* supports capture mode */
+       __le32 compress;        /* 1 = compressed; 0 = PCM */
+       struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* for DAI link */
+       __le32 num_streams;     /* number of streams */
+       struct snd_soc_tplg_stream_caps_v4 caps[2]; /* playback and capture for DAI */
+} __packed;
+
+/* Physical link config v4 */
+struct snd_soc_tplg_link_config_v4 {
+       __le32 size;            /* in bytes of this structure */
+       __le32 id;              /* unique ID - used to match */
+       struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */
+       __le32 num_streams;     /* number of streams */
+} __packed;
+
 #endif
diff --git a/include/uapi/sound/skl-tplg-interface.h b/include/uapi/sound/skl-tplg-interface.h
new file mode 100644 (file)
index 0000000..f58cafa
--- /dev/null
@@ -0,0 +1,237 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * skl-tplg-interface.h - Intel DSP FW private data interface
+ *
+ * Copyright (C) 2015 Intel Corp
+ * Author: Jeeja KP <jeeja.kp@intel.com>
+ *         Nilofer, Samreen <samreen.nilofer@intel.com>
+ */
+
+#ifndef __HDA_TPLG_INTERFACE_H__
+#define __HDA_TPLG_INTERFACE_H__
+
+/*
+ * Default types range from 0~12. type can range from 0 to 0xff
+ * SST types start at higher to avoid any overlapping in future
+ */
+#define SKL_CONTROL_TYPE_BYTE_TLV      0x100
+#define SKL_CONTROL_TYPE_MIC_SELECT    0x102
+
+#define HDA_SST_CFG_MAX        900 /* size of copier cfg*/
+#define MAX_IN_QUEUE 8
+#define MAX_OUT_QUEUE 8
+
+#define SKL_UUID_STR_SZ 40
+/* Event types goes here */
+/* Reserve event type 0 for no event handlers */
+enum skl_event_types {
+       SKL_EVENT_NONE = 0,
+       SKL_MIXER_EVENT,
+       SKL_MUX_EVENT,
+       SKL_VMIXER_EVENT,
+       SKL_PGA_EVENT
+};
+
+/**
+ * enum skl_ch_cfg - channel configuration
+ *
+ * @SKL_CH_CFG_MONO:   One channel only
+ * @SKL_CH_CFG_STEREO: L & R
+ * @SKL_CH_CFG_2_1:    L, R & LFE
+ * @SKL_CH_CFG_3_0:    L, C & R
+ * @SKL_CH_CFG_3_1:    L, C, R & LFE
+ * @SKL_CH_CFG_QUATRO: L, R, Ls & Rs
+ * @SKL_CH_CFG_4_0:    L, C, R & Cs
+ * @SKL_CH_CFG_5_0:    L, C, R, Ls & Rs
+ * @SKL_CH_CFG_5_1:    L, C, R, Ls, Rs & LFE
+ * @SKL_CH_CFG_DUAL_MONO: One channel replicated in two
+ * @SKL_CH_CFG_I2S_DUAL_STEREO_0: Stereo(L,R) in 4 slots, 1st stream:[ L, R, -, - ]
+ * @SKL_CH_CFG_I2S_DUAL_STEREO_1: Stereo(L,R) in 4 slots, 2nd stream:[ -, -, L, R ]
+ * @SKL_CH_CFG_INVALID:        Invalid
+ */
+enum skl_ch_cfg {
+       SKL_CH_CFG_MONO = 0,
+       SKL_CH_CFG_STEREO = 1,
+       SKL_CH_CFG_2_1 = 2,
+       SKL_CH_CFG_3_0 = 3,
+       SKL_CH_CFG_3_1 = 4,
+       SKL_CH_CFG_QUATRO = 5,
+       SKL_CH_CFG_4_0 = 6,
+       SKL_CH_CFG_5_0 = 7,
+       SKL_CH_CFG_5_1 = 8,
+       SKL_CH_CFG_DUAL_MONO = 9,
+       SKL_CH_CFG_I2S_DUAL_STEREO_0 = 10,
+       SKL_CH_CFG_I2S_DUAL_STEREO_1 = 11,
+       SKL_CH_CFG_4_CHANNEL = 12,
+       SKL_CH_CFG_INVALID
+};
+
+enum skl_module_type {
+       SKL_MODULE_TYPE_MIXER = 0,
+       SKL_MODULE_TYPE_COPIER,
+       SKL_MODULE_TYPE_UPDWMIX,
+       SKL_MODULE_TYPE_SRCINT,
+       SKL_MODULE_TYPE_ALGO,
+       SKL_MODULE_TYPE_BASE_OUTFMT,
+       SKL_MODULE_TYPE_KPB,
+       SKL_MODULE_TYPE_MIC_SELECT,
+};
+
+enum skl_core_affinity {
+       SKL_AFFINITY_CORE_0 = 0,
+       SKL_AFFINITY_CORE_1,
+       SKL_AFFINITY_CORE_MAX
+};
+
+enum skl_pipe_conn_type {
+       SKL_PIPE_CONN_TYPE_NONE = 0,
+       SKL_PIPE_CONN_TYPE_FE,
+       SKL_PIPE_CONN_TYPE_BE
+};
+
+enum skl_hw_conn_type {
+       SKL_CONN_NONE = 0,
+       SKL_CONN_SOURCE = 1,
+       SKL_CONN_SINK = 2
+};
+
+enum skl_dev_type {
+       SKL_DEVICE_BT = 0x0,
+       SKL_DEVICE_DMIC = 0x1,
+       SKL_DEVICE_I2S = 0x2,
+       SKL_DEVICE_SLIMBUS = 0x3,
+       SKL_DEVICE_HDALINK = 0x4,
+       SKL_DEVICE_HDAHOST = 0x5,
+       SKL_DEVICE_NONE
+};
+
+/**
+ * enum skl_interleaving - interleaving style
+ *
+ * @SKL_INTERLEAVING_PER_CHANNEL: [s1_ch1...s1_chN,...,sM_ch1...sM_chN]
+ * @SKL_INTERLEAVING_PER_SAMPLE: [s1_ch1...sM_ch1,...,s1_chN...sM_chN]
+ */
+enum skl_interleaving {
+       SKL_INTERLEAVING_PER_CHANNEL = 0,
+       SKL_INTERLEAVING_PER_SAMPLE = 1,
+};
+
+enum skl_sample_type {
+       SKL_SAMPLE_TYPE_INT_MSB = 0,
+       SKL_SAMPLE_TYPE_INT_LSB = 1,
+       SKL_SAMPLE_TYPE_INT_SIGNED = 2,
+       SKL_SAMPLE_TYPE_INT_UNSIGNED = 3,
+       SKL_SAMPLE_TYPE_FLOAT = 4
+};
+
+enum module_pin_type {
+       /* All pins of the module takes same PCM inputs or outputs
+       * e.g. mixout
+       */
+       SKL_PIN_TYPE_HOMOGENEOUS,
+       /* All pins of the module takes different PCM inputs or outputs
+       * e.g mux
+       */
+       SKL_PIN_TYPE_HETEROGENEOUS,
+};
+
+enum skl_module_param_type {
+       SKL_PARAM_DEFAULT = 0,
+       SKL_PARAM_INIT,
+       SKL_PARAM_SET,
+       SKL_PARAM_BIND
+};
+
+struct skl_dfw_algo_data {
+       u32 set_params:2;
+       u32 rsvd:30;
+       u32 param_id;
+       u32 max;
+       char params[0];
+} __packed;
+
+enum skl_tkn_dir {
+       SKL_DIR_IN,
+       SKL_DIR_OUT
+};
+
+enum skl_tuple_type {
+       SKL_TYPE_TUPLE,
+       SKL_TYPE_DATA
+};
+
+/* v4 configuration data */
+
+struct skl_dfw_v4_module_pin {
+       u16 module_id;
+       u16 instance_id;
+} __packed;
+
+struct skl_dfw_v4_module_fmt {
+       u32 channels;
+       u32 freq;
+       u32 bit_depth;
+       u32 valid_bit_depth;
+       u32 ch_cfg;
+       u32 interleaving_style;
+       u32 sample_type;
+       u32 ch_map;
+} __packed;
+
+struct skl_dfw_v4_module_caps {
+       u32 set_params:2;
+       u32 rsvd:30;
+       u32 param_id;
+       u32 caps_size;
+       u32 caps[HDA_SST_CFG_MAX];
+} __packed;
+
+struct skl_dfw_v4_pipe {
+       u8 pipe_id;
+       u8 pipe_priority;
+       u16 conn_type:4;
+       u16 rsvd:4;
+       u16 memory_pages:8;
+} __packed;
+
+struct skl_dfw_v4_module {
+       char uuid[SKL_UUID_STR_SZ];
+
+       u16 module_id;
+       u16 instance_id;
+       u32 max_mcps;
+       u32 mem_pages;
+       u32 obs;
+       u32 ibs;
+       u32 vbus_id;
+
+       u32 max_in_queue:8;
+       u32 max_out_queue:8;
+       u32 time_slot:8;
+       u32 core_id:4;
+       u32 rsvd1:4;
+
+       u32 module_type:8;
+       u32 conn_type:4;
+       u32 dev_type:4;
+       u32 hw_conn_type:4;
+       u32 rsvd2:12;
+
+       u32 params_fixup:8;
+       u32 converter:8;
+       u32 input_pin_type:1;
+       u32 output_pin_type:1;
+       u32 is_dynamic_in_pin:1;
+       u32 is_dynamic_out_pin:1;
+       u32 is_loadable:1;
+       u32 rsvd3:11;
+
+       struct skl_dfw_v4_pipe pipe;
+       struct skl_dfw_v4_module_fmt in_fmt[MAX_IN_QUEUE];
+       struct skl_dfw_v4_module_fmt out_fmt[MAX_OUT_QUEUE];
+       struct skl_dfw_v4_module_pin in_pin[MAX_IN_QUEUE];
+       struct skl_dfw_v4_module_pin out_pin[MAX_OUT_QUEUE];
+       struct skl_dfw_v4_module_caps caps;
+} __packed;
+
+#endif
index be5371f09a626b4320d22f3302d9b66502d5e5c6..7d6d65f60a42ea20ce17e9a778621773882a39ba 100644 (file)
 #define SNDRV_CTL_TLVD_LENGTH(...) \
        ((unsigned int)sizeof((const unsigned int[]) { __VA_ARGS__ }))
 
+/* Accessor offsets for TLV data items */
+#define SNDRV_CTL_TLVO_TYPE            0
+#define SNDRV_CTL_TLVO_LEN             1
+
 #define SNDRV_CTL_TLVD_CONTAINER_ITEM(...) \
        SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_CONTAINER, __VA_ARGS__)
 #define SNDRV_CTL_TLVD_DECLARE_CONTAINER(name, ...) \
                SNDRV_CTL_TLVD_DB_SCALE_ITEM(min, step, mute) \
        }
 
+/* Accessor offsets for min, mute and step items in dB scale type TLV */
+#define SNDRV_CTL_TLVO_DB_SCALE_MIN            2
+#define SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP  3
+
 /* dB scale specified with min/max values instead of step */
 #define SNDRV_CTL_TLVD_DB_MINMAX_ITEM(min_dB, max_dB) \
        SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_MINMAX, (min_dB), (max_dB))
                SNDRV_CTL_TLVD_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \
        }
 
+/* Accessor offsets for min, max items in db-minmax types of TLV. */
+#define SNDRV_CTL_TLVO_DB_MINMAX_MIN   2
+#define SNDRV_CTL_TLVO_DB_MINMAX_MAX   3
+
 /* linear volume between min_dB and max_dB (.01dB unit) */
 #define SNDRV_CTL_TLVD_DB_LINEAR_ITEM(min_dB, max_dB) \
        SNDRV_CTL_TLVD_ITEM(SNDRV_CTL_TLVT_DB_LINEAR, (min_dB), (max_dB))
                SNDRV_CTL_TLVD_DB_LINEAR_ITEM(min_dB, max_dB) \
        }
 
+/* Accessor offsets for min, max items in db-linear type of TLV. */
+#define SNDRV_CTL_TLVO_DB_LINEAR_MIN   2
+#define SNDRV_CTL_TLVO_DB_LINEAR_MAX   3
+
 /* dB range container:
  * Items in dB range container must be ordered by their values and by their
  * dB values. This implies that larger values must correspond with larger
index 6833db9002ecb6bef9e588bd3dc1c1db3180d4de..1140e9988fc5039c7e798c629578ead709a23d97 100644 (file)
@@ -96,6 +96,8 @@ source "sound/x86/Kconfig"
 
 source "sound/synth/Kconfig"
 
+source "sound/xen/Kconfig"
+
 endif # SND
 
 endif # !UML
index 99d8c31262c8fc089836c15a8406551e044812bf..797ecdcd35e29f2fe4155f6cf473b1ad6ef97b08 100644 (file)
@@ -5,7 +5,7 @@
 obj-$(CONFIG_SOUND) += soundcore.o
 obj-$(CONFIG_DMASOUND) += oss/dmasound/
 obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \
-       firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/
+       firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/ xen/
 obj-$(CONFIG_SND_AOA) += aoa/
 
 # This one must be compilable even if sound is configured out
index 4563432badba56e37c670541bda344b6c805392b..4b01a37c836ea8be39c223f8ec551145d34f2b95 100644 (file)
@@ -1001,7 +1001,7 @@ static int snd_compress_proc_init(struct snd_compr *compr)
                                           compr->card->proc_root);
        if (!entry)
                return -ENOMEM;
-       entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
+       entry->mode = S_IFDIR | 0555;
        if (snd_info_register(entry) < 0) {
                snd_info_free_entry(entry);
                return -ENOMEM;
index cb0e46f66cc9e5c7feeff00b4a7e2d5416d0b2b2..535102d564e3a5446606bd6b039dc1e441bfb96d 100644 (file)
@@ -240,6 +240,15 @@ void snd_device_free_all(struct snd_card *card)
 
        if (snd_BUG_ON(!card))
                return;
+       list_for_each_entry_safe_reverse(dev, next, &card->devices, list) {
+               /* exception: free ctl and lowlevel stuff later */
+               if (dev->type == SNDRV_DEV_CONTROL ||
+                   dev->type == SNDRV_DEV_LOWLEVEL)
+                       continue;
+               __snd_device_free(dev);
+       }
+
+       /* free all */
        list_for_each_entry_safe_reverse(dev, next, &card->devices, list)
                __snd_device_free(dev);
 }
index 4b36767af9e15cef0b04d6308b9e8d7d57e68850..fe502bc5e6d20e8d800739bbca65a16b6085f155 100644 (file)
@@ -454,7 +454,7 @@ static struct snd_info_entry *create_subdir(struct module *mod,
        entry = snd_info_create_module_entry(mod, name, NULL);
        if (!entry)
                return NULL;
-       entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
+       entry->mode = S_IFDIR | 0555;
        if (snd_info_register(entry) < 0) {
                snd_info_free_entry(entry);
                return NULL;
@@ -470,7 +470,7 @@ int __init snd_info_init(void)
        snd_proc_root = snd_info_create_entry("asound", NULL);
        if (!snd_proc_root)
                return -ENOMEM;
-       snd_proc_root->mode = S_IFDIR | S_IRUGO | S_IXUGO;
+       snd_proc_root->mode = S_IFDIR | 0555;
        snd_proc_root->p = proc_mkdir("asound", NULL);
        if (!snd_proc_root->p)
                goto error;
@@ -716,7 +716,7 @@ snd_info_create_entry(const char *name, struct snd_info_entry *parent)
                kfree(entry);
                return NULL;
        }
-       entry->mode = S_IFREG | S_IRUGO;
+       entry->mode = S_IFREG | 0444;
        entry->content = SNDRV_INFO_CONTENT_TEXT;
        mutex_init(&entry->access);
        INIT_LIST_HEAD(&entry->children);
index 79b4df1c1dc7e735a360e6d2425ca5d52d199f78..4849c611c0fe3a94d98aa3eef778f3da5538575f 100644 (file)
@@ -703,7 +703,7 @@ card_id_store_attr(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-static DEVICE_ATTR(id, S_IRUGO | S_IWUSR, card_id_show_attr, card_id_store_attr);
+static DEVICE_ATTR(id, 0644, card_id_show_attr, card_id_store_attr);
 
 static ssize_t
 card_number_show_attr(struct device *dev,
@@ -713,7 +713,7 @@ card_number_show_attr(struct device *dev,
        return scnprintf(buf, PAGE_SIZE, "%i\n", card->number);
 }
 
-static DEVICE_ATTR(number, S_IRUGO, card_number_show_attr, NULL);
+static DEVICE_ATTR(number, 0444, card_number_show_attr, NULL);
 
 static struct attribute *card_dev_attrs[] = {
        &dev_attr_id.attr,
index 379bf486ccc74c598c6fd220d1230f56714431c6..64d904bee8bb345edf6bc9053016f38027c51ccf 100644 (file)
@@ -1247,7 +1247,7 @@ static void snd_mixer_oss_proc_init(struct snd_mixer_oss *mixer)
        if (! entry)
                return;
        entry->content = SNDRV_INFO_CONTENT_TEXT;
-       entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
+       entry->mode = S_IFREG | 0644;
        entry->c.text.read = snd_mixer_oss_proc_read;
        entry->c.text.write = snd_mixer_oss_proc_write;
        entry->private_data = mixer;
index 1980f68246cb84003a3ae29a6db61e951bf4ec54..905a53c1cde5aeb8a82918d9b44dd0e92d765956 100644 (file)
@@ -3045,7 +3045,7 @@ static void snd_pcm_oss_proc_init(struct snd_pcm *pcm)
                        continue;
                if ((entry = snd_info_create_card_entry(pcm->card, "oss", pstr->proc_root)) != NULL) {
                        entry->content = SNDRV_INFO_CONTENT_TEXT;
-                       entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
+                       entry->mode = S_IFREG | 0644;
                        entry->c.text.read = snd_pcm_oss_proc_read;
                        entry->c.text.write = snd_pcm_oss_proc_write;
                        entry->private_data = pstr;
index 66ac89aad68178592b9517a85de5bc092e55c70c..c352bfb973cc292e756dd351c2ad66604be68b56 100644 (file)
@@ -530,7 +530,7 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
                                           pcm->card->proc_root);
        if (!entry)
                return -ENOMEM;
-       entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
+       entry->mode = S_IFDIR | 0555;
        if (snd_info_register(entry) < 0) {
                snd_info_free_entry(entry);
                return -ENOMEM;
@@ -552,7 +552,7 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
        if (entry) {
                entry->c.text.read = snd_pcm_xrun_debug_read;
                entry->c.text.write = snd_pcm_xrun_debug_write;
-               entry->mode |= S_IWUSR;
+               entry->mode |= 0200;
                entry->private_data = pstr;
                if (snd_info_register(entry) < 0) {
                        snd_info_free_entry(entry);
@@ -590,7 +590,7 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
                                           substream->pstr->proc_root);
        if (!entry)
                return -ENOMEM;
-       entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
+       entry->mode = S_IFDIR | 0555;
        if (snd_info_register(entry) < 0) {
                snd_info_free_entry(entry);
                return -ENOMEM;
@@ -647,7 +647,7 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
                entry->private_data = substream;
                entry->c.text.read = NULL;
                entry->c.text.write = snd_pcm_xrun_injection_write;
-               entry->mode = S_IFREG | S_IWUSR;
+               entry->mode = S_IFREG | 0200;
                if (snd_info_register(entry) < 0) {
                        snd_info_free_entry(entry);
                        entry = NULL;
@@ -1087,7 +1087,7 @@ static ssize_t show_pcm_class(struct device *dev,
         return snprintf(buf, PAGE_SIZE, "%s\n", str);
 }
 
-static DEVICE_ATTR(pcm_class, S_IRUGO, show_pcm_class, NULL);
+static DEVICE_ATTR(pcm_class, 0444, show_pcm_class, NULL);
 static struct attribute *pcm_dev_attrs[] = {
        &dev_attr_pcm_class.attr,
        NULL
index 6491afbb5fd5704a31a72b2847d4fef2f0001e2f..39d853bfa5ac0a8b88eb802ea12b947c35557a09 100644 (file)
@@ -45,10 +45,7 @@ static int snd_pcm_ioctl_rewind_compat(struct snd_pcm_substream *substream,
 
        if (get_user(frames, src))
                return -EFAULT;
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               err = snd_pcm_playback_rewind(substream, frames);
-       else
-               err = snd_pcm_capture_rewind(substream, frames);
+       err = snd_pcm_rewind(substream, frames);
        if (put_user(err, src))
                return -EFAULT;
        return err < 0 ? err : 0;
@@ -62,10 +59,7 @@ static int snd_pcm_ioctl_forward_compat(struct snd_pcm_substream *substream,
 
        if (get_user(frames, src))
                return -EFAULT;
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               err = snd_pcm_playback_forward(substream, frames);
-       else
-               err = snd_pcm_capture_forward(substream, frames);
+       err = snd_pcm_forward(substream, frames);
        if (put_user(err, src))
                return -EFAULT;
        return err < 0 ? err : 0;
index f4a19509cccf3c481aaa641de2c47c894dd1e66c..44b5ae83308215cddd0c027048346e727ff95382 100644 (file)
@@ -191,10 +191,7 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream,
 {
        snd_pcm_uframes_t avail;
 
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               avail = snd_pcm_playback_avail(runtime);
-       else
-               avail = snd_pcm_capture_avail(runtime);
+       avail = snd_pcm_avail(substream);
        if (avail > runtime->avail_max)
                runtime->avail_max = avail;
        if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
@@ -1856,10 +1853,7 @@ static int wait_for_avail(struct snd_pcm_substream *substream,
                 * This check must happen after been added to the waitqueue
                 * and having current state be INTERRUPTIBLE.
                 */
-               if (is_playback)
-                       avail = snd_pcm_playback_avail(runtime);
-               else
-                       avail = snd_pcm_capture_avail(runtime);
+               avail = snd_pcm_avail(substream);
                if (avail >= runtime->twake)
                        break;
                snd_pcm_stream_unlock_irq(substream);
@@ -2175,10 +2169,7 @@ snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
        runtime->twake = runtime->control->avail_min ? : 1;
        if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
                snd_pcm_update_hw_ptr(substream);
-       if (is_playback)
-               avail = snd_pcm_playback_avail(runtime);
-       else
-               avail = snd_pcm_capture_avail(runtime);
+       avail = snd_pcm_avail(substream);
        while (size > 0) {
                snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
                snd_pcm_uframes_t cont;
index 16f254732b2a4e88c80588126073fab11b425370..7a499d02df6cf66ecaeb134afeacf89cc9603688 100644 (file)
@@ -36,6 +36,24 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream);
 void snd_pcm_playback_silence(struct snd_pcm_substream *substream,
                              snd_pcm_uframes_t new_hw_ptr);
 
+static inline snd_pcm_uframes_t
+snd_pcm_avail(struct snd_pcm_substream *substream)
+{
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               return snd_pcm_playback_avail(substream->runtime);
+       else
+               return snd_pcm_capture_avail(substream->runtime);
+}
+
+static inline snd_pcm_uframes_t
+snd_pcm_hw_avail(struct snd_pcm_substream *substream)
+{
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               return snd_pcm_playback_hw_avail(substream->runtime);
+       else
+               return snd_pcm_capture_hw_avail(substream->runtime);
+}
+
 #ifdef CONFIG_SND_PCM_TIMER
 void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream);
 void snd_pcm_timer_init(struct snd_pcm_substream *substream);
index ae33e456708c2871359acc796a6b31b05b47b201..4b5356a1031599afb2158f4f703dbdc1998d68cb 100644 (file)
@@ -201,7 +201,7 @@ static inline void preallocate_info_init(struct snd_pcm_substream *substream)
        if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc", substream->proc_root)) != NULL) {
                entry->c.text.read = snd_pcm_lib_preallocate_proc_read;
                entry->c.text.write = snd_pcm_lib_preallocate_proc_write;
-               entry->mode |= S_IWUSR;
+               entry->mode |= 0200;
                entry->private_data = substream;
                if (snd_info_register(entry) < 0) {
                        snd_info_free_entry(entry);
index 0e875d5a9e8621ee378014176596207d201a2363..04c6301394d053ce5751ae33087c080cddd59b71 100644 (file)
@@ -99,6 +99,57 @@ static inline void down_write_nonblock(struct rw_semaphore *lock)
                cond_resched();
 }
 
+#define PCM_LOCK_DEFAULT       0
+#define PCM_LOCK_IRQ   1
+#define PCM_LOCK_IRQSAVE       2
+
+static unsigned long __snd_pcm_stream_lock_mode(struct snd_pcm_substream *substream,
+                                               unsigned int mode)
+{
+       unsigned long flags = 0;
+       if (substream->pcm->nonatomic) {
+               down_read_nested(&snd_pcm_link_rwsem, SINGLE_DEPTH_NESTING);
+               mutex_lock(&substream->self_group.mutex);
+       } else {
+               switch (mode) {
+               case PCM_LOCK_DEFAULT:
+                       read_lock(&snd_pcm_link_rwlock);
+                       break;
+               case PCM_LOCK_IRQ:
+                       read_lock_irq(&snd_pcm_link_rwlock);
+                       break;
+               case PCM_LOCK_IRQSAVE:
+                       read_lock_irqsave(&snd_pcm_link_rwlock, flags);
+                       break;
+               }
+               spin_lock(&substream->self_group.lock);
+       }
+       return flags;
+}
+
+static void __snd_pcm_stream_unlock_mode(struct snd_pcm_substream *substream,
+                                        unsigned int mode, unsigned long flags)
+{
+       if (substream->pcm->nonatomic) {
+               mutex_unlock(&substream->self_group.mutex);
+               up_read(&snd_pcm_link_rwsem);
+       } else {
+               spin_unlock(&substream->self_group.lock);
+
+               switch (mode) {
+               case PCM_LOCK_DEFAULT:
+                       read_unlock(&snd_pcm_link_rwlock);
+                       break;
+               case PCM_LOCK_IRQ:
+                       read_unlock_irq(&snd_pcm_link_rwlock);
+                       break;
+               case PCM_LOCK_IRQSAVE:
+                       read_unlock_irqrestore(&snd_pcm_link_rwlock, flags);
+                       break;
+               }
+       }
+}
+
 /**
  * snd_pcm_stream_lock - Lock the PCM stream
  * @substream: PCM substream
@@ -109,13 +160,7 @@ static inline void down_write_nonblock(struct rw_semaphore *lock)
  */
 void snd_pcm_stream_lock(struct snd_pcm_substream *substream)
 {
-       if (substream->pcm->nonatomic) {
-               down_read_nested(&snd_pcm_link_rwsem, SINGLE_DEPTH_NESTING);
-               mutex_lock(&substream->self_group.mutex);
-       } else {
-               read_lock(&snd_pcm_link_rwlock);
-               spin_lock(&substream->self_group.lock);
-       }
+       __snd_pcm_stream_lock_mode(substream, PCM_LOCK_DEFAULT);
 }
 EXPORT_SYMBOL_GPL(snd_pcm_stream_lock);
 
@@ -127,13 +172,7 @@ EXPORT_SYMBOL_GPL(snd_pcm_stream_lock);
  */
 void snd_pcm_stream_unlock(struct snd_pcm_substream *substream)
 {
-       if (substream->pcm->nonatomic) {
-               mutex_unlock(&substream->self_group.mutex);
-               up_read(&snd_pcm_link_rwsem);
-       } else {
-               spin_unlock(&substream->self_group.lock);
-               read_unlock(&snd_pcm_link_rwlock);
-       }
+       __snd_pcm_stream_unlock_mode(substream, PCM_LOCK_DEFAULT, 0);
 }
 EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock);
 
@@ -147,9 +186,7 @@ EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock);
  */
 void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream)
 {
-       if (!substream->pcm->nonatomic)
-               local_irq_disable();
-       snd_pcm_stream_lock(substream);
+       __snd_pcm_stream_lock_mode(substream, PCM_LOCK_IRQ);
 }
 EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq);
 
@@ -161,19 +198,13 @@ EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq);
  */
 void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream)
 {
-       snd_pcm_stream_unlock(substream);
-       if (!substream->pcm->nonatomic)
-               local_irq_enable();
+       __snd_pcm_stream_unlock_mode(substream, PCM_LOCK_IRQ, 0);
 }
 EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irq);
 
 unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream)
 {
-       unsigned long flags = 0;
-       if (!substream->pcm->nonatomic)
-               local_irq_save(flags);
-       snd_pcm_stream_lock(substream);
-       return flags;
+       return __snd_pcm_stream_lock_mode(substream, PCM_LOCK_IRQSAVE);
 }
 EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave);
 
@@ -187,9 +218,7 @@ EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave);
 void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream,
                                      unsigned long flags)
 {
-       snd_pcm_stream_unlock(substream);
-       if (!substream->pcm->nonatomic)
-               local_irq_restore(flags);
+       __snd_pcm_stream_unlock_mode(substream, PCM_LOCK_IRQSAVE, flags);
 }
 EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irqrestore);
 
@@ -857,6 +886,18 @@ static int snd_pcm_sw_params_user(struct snd_pcm_substream *substream,
        return err;
 }
 
+static inline snd_pcm_uframes_t
+snd_pcm_calc_delay(struct snd_pcm_substream *substream)
+{
+       snd_pcm_uframes_t delay;
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               delay = snd_pcm_playback_hw_avail(substream->runtime);
+       else
+               delay = snd_pcm_capture_avail(substream->runtime);
+       return delay + substream->runtime->delay;
+}
+
 int snd_pcm_status(struct snd_pcm_substream *substream,
                   struct snd_pcm_status *status)
 {
@@ -908,21 +949,9 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
  _tstamp_end:
        status->appl_ptr = runtime->control->appl_ptr;
        status->hw_ptr = runtime->status->hw_ptr;
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               status->avail = snd_pcm_playback_avail(runtime);
-               if (runtime->status->state == SNDRV_PCM_STATE_RUNNING ||
-                   runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
-                       status->delay = runtime->buffer_size - status->avail;
-                       status->delay += runtime->delay;
-               } else
-                       status->delay = 0;
-       } else {
-               status->avail = snd_pcm_capture_avail(runtime);
-               if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
-                       status->delay = status->avail + runtime->delay;
-               else
-                       status->delay = 0;
-       }
+       status->avail = snd_pcm_avail(substream);
+       status->delay = snd_pcm_running(substream) ?
+               snd_pcm_calc_delay(substream) : 0;
        status->avail_max = runtime->avail_max;
        status->overrange = runtime->overrange;
        runtime->avail_max = 0;
@@ -2610,10 +2639,9 @@ static snd_pcm_sframes_t rewind_appl_ptr(struct snd_pcm_substream *substream,
        return ret < 0 ? 0 : frames;
 }
 
-static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *substream,
-                                                snd_pcm_uframes_t frames)
+static snd_pcm_sframes_t snd_pcm_rewind(struct snd_pcm_substream *substream,
+                                       snd_pcm_uframes_t frames)
 {
-       struct snd_pcm_runtime *runtime = substream->runtime;
        snd_pcm_sframes_t ret;
 
        if (frames == 0)
@@ -2623,33 +2651,14 @@ static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *subst
        ret = do_pcm_hwsync(substream);
        if (!ret)
                ret = rewind_appl_ptr(substream, frames,
-                                     snd_pcm_playback_hw_avail(runtime));
+                                     snd_pcm_hw_avail(substream));
        snd_pcm_stream_unlock_irq(substream);
        return ret;
 }
 
-static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substream,
-                                               snd_pcm_uframes_t frames)
+static snd_pcm_sframes_t snd_pcm_forward(struct snd_pcm_substream *substream,
+                                        snd_pcm_uframes_t frames)
 {
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       snd_pcm_sframes_t ret;
-
-       if (frames == 0)
-               return 0;
-
-       snd_pcm_stream_lock_irq(substream);
-       ret = do_pcm_hwsync(substream);
-       if (!ret)
-               ret = rewind_appl_ptr(substream, frames,
-                                     snd_pcm_capture_hw_avail(runtime));
-       snd_pcm_stream_unlock_irq(substream);
-       return ret;
-}
-
-static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *substream,
-                                                 snd_pcm_uframes_t frames)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
        snd_pcm_sframes_t ret;
 
        if (frames == 0)
@@ -2659,25 +2668,7 @@ static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *subs
        ret = do_pcm_hwsync(substream);
        if (!ret)
                ret = forward_appl_ptr(substream, frames,
-                                      snd_pcm_playback_avail(runtime));
-       snd_pcm_stream_unlock_irq(substream);
-       return ret;
-}
-
-static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *substream,
-                                                snd_pcm_uframes_t frames)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       snd_pcm_sframes_t ret;
-
-       if (frames == 0)
-               return 0;
-
-       snd_pcm_stream_lock_irq(substream);
-       ret = do_pcm_hwsync(substream);
-       if (!ret)
-               ret = forward_appl_ptr(substream, frames,
-                                      snd_pcm_capture_avail(runtime));
+                                      snd_pcm_avail(substream));
        snd_pcm_stream_unlock_irq(substream);
        return ret;
 }
@@ -2695,19 +2686,13 @@ static int snd_pcm_hwsync(struct snd_pcm_substream *substream)
 static int snd_pcm_delay(struct snd_pcm_substream *substream,
                         snd_pcm_sframes_t *delay)
 {
-       struct snd_pcm_runtime *runtime = substream->runtime;
        int err;
        snd_pcm_sframes_t n = 0;
 
        snd_pcm_stream_lock_irq(substream);
        err = do_pcm_hwsync(substream);
-       if (!err) {
-               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                       n = snd_pcm_playback_hw_avail(runtime);
-               else
-                       n = snd_pcm_capture_avail(runtime);
-               n += runtime->delay;
-       }
+       if (!err)
+               n = snd_pcm_calc_delay(substream);
        snd_pcm_stream_unlock_irq(substream);
        if (!err)
                *delay = n;
@@ -2834,10 +2819,7 @@ static int snd_pcm_rewind_ioctl(struct snd_pcm_substream *substream,
                return -EFAULT;
        if (put_user(0, _frames))
                return -EFAULT;
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               result = snd_pcm_playback_rewind(substream, frames);
-       else
-               result = snd_pcm_capture_rewind(substream, frames);
+       result = snd_pcm_rewind(substream, frames);
        __put_user(result, _frames);
        return result < 0 ? result : 0;
 }
@@ -2852,10 +2834,7 @@ static int snd_pcm_forward_ioctl(struct snd_pcm_substream *substream,
                return -EFAULT;
        if (put_user(0, _frames))
                return -EFAULT;
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               result = snd_pcm_playback_forward(substream, frames);
-       else
-               result = snd_pcm_capture_forward(substream, frames);
+       result = snd_pcm_forward(substream, frames);
        __put_user(result, _frames);
        return result < 0 ? result : 0;
 }
@@ -2998,7 +2977,7 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
                /* provided only for OSS; capture-only and no value returned */
                if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
                        return -EINVAL;
-               result = snd_pcm_capture_forward(substream, *frames);
+               result = snd_pcm_forward(substream, *frames);
                return result < 0 ? result : 0;
        }
        case SNDRV_PCM_IOCTL_HW_PARAMS:
@@ -3140,82 +3119,46 @@ static ssize_t snd_pcm_writev(struct kiocb *iocb, struct iov_iter *from)
        return result;
 }
 
-static __poll_t snd_pcm_playback_poll(struct file *file, poll_table * wait)
+static __poll_t snd_pcm_poll(struct file *file, poll_table *wait)
 {
        struct snd_pcm_file *pcm_file;
        struct snd_pcm_substream *substream;
        struct snd_pcm_runtime *runtime;
-        __poll_t mask;
+       __poll_t mask, ok;
        snd_pcm_uframes_t avail;
 
        pcm_file = file->private_data;
 
        substream = pcm_file->substream;
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               ok = EPOLLOUT | EPOLLWRNORM;
+       else
+               ok = EPOLLIN | EPOLLRDNORM;
        if (PCM_RUNTIME_CHECK(substream))
-               return EPOLLOUT | EPOLLWRNORM | EPOLLERR;
-       runtime = substream->runtime;
-
-       poll_wait(file, &runtime->sleep, wait);
+               return ok | EPOLLERR;
 
-       snd_pcm_stream_lock_irq(substream);
-       avail = snd_pcm_playback_avail(runtime);
-       switch (runtime->status->state) {
-       case SNDRV_PCM_STATE_RUNNING:
-       case SNDRV_PCM_STATE_PREPARED:
-       case SNDRV_PCM_STATE_PAUSED:
-               if (avail >= runtime->control->avail_min) {
-                       mask = EPOLLOUT | EPOLLWRNORM;
-                       break;
-               }
-               /* Fall through */
-       case SNDRV_PCM_STATE_DRAINING:
-               mask = 0;
-               break;
-       default:
-               mask = EPOLLOUT | EPOLLWRNORM | EPOLLERR;
-               break;
-       }
-       snd_pcm_stream_unlock_irq(substream);
-       return mask;
-}
-
-static __poll_t snd_pcm_capture_poll(struct file *file, poll_table * wait)
-{
-       struct snd_pcm_file *pcm_file;
-       struct snd_pcm_substream *substream;
-       struct snd_pcm_runtime *runtime;
-        __poll_t mask;
-       snd_pcm_uframes_t avail;
-
-       pcm_file = file->private_data;
-
-       substream = pcm_file->substream;
-       if (PCM_RUNTIME_CHECK(substream))
-               return EPOLLIN | EPOLLRDNORM | EPOLLERR;
        runtime = substream->runtime;
-
        poll_wait(file, &runtime->sleep, wait);
 
+       mask = 0;
        snd_pcm_stream_lock_irq(substream);
-       avail = snd_pcm_capture_avail(runtime);
+       avail = snd_pcm_avail(substream);
        switch (runtime->status->state) {
        case SNDRV_PCM_STATE_RUNNING:
        case SNDRV_PCM_STATE_PREPARED:
        case SNDRV_PCM_STATE_PAUSED:
-               if (avail >= runtime->control->avail_min) {
-                       mask = EPOLLIN | EPOLLRDNORM;
-                       break;
-               }
-               mask = 0;
+               if (avail >= runtime->control->avail_min)
+                       mask = ok;
                break;
        case SNDRV_PCM_STATE_DRAINING:
-               if (avail > 0) {
-                       mask = EPOLLIN | EPOLLRDNORM;
-                       break;
+               if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+                       mask = ok;
+                       if (!avail)
+                               mask |= EPOLLERR;
                }
-               /* Fall through */
+               break;
        default:
-               mask = EPOLLIN | EPOLLRDNORM | EPOLLERR;
+               mask = ok | EPOLLERR;
                break;
        }
        snd_pcm_stream_unlock_irq(substream);
@@ -3707,7 +3650,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
                .open =                 snd_pcm_playback_open,
                .release =              snd_pcm_release,
                .llseek =               no_llseek,
-               .poll =                 snd_pcm_playback_poll,
+               .poll =                 snd_pcm_poll,
                .unlocked_ioctl =       snd_pcm_ioctl,
                .compat_ioctl =         snd_pcm_ioctl_compat,
                .mmap =                 snd_pcm_mmap,
@@ -3721,7 +3664,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
                .open =                 snd_pcm_capture_open,
                .release =              snd_pcm_release,
                .llseek =               no_llseek,
-               .poll =                 snd_pcm_capture_poll,
+               .poll =                 snd_pcm_poll,
                .unlocked_ioctl =       snd_pcm_ioctl,
                .compat_ioctl =         snd_pcm_ioctl_compat,
                .mmap =                 snd_pcm_mmap,
index d21ece9f8d7365e5e621156f1e44b85aa11eb1a1..24d90abfc64dfee2dfc049e836ab2e7a5d2a7c60 100644 (file)
@@ -669,7 +669,7 @@ int snd_seq_event_port_attach(int client,
        /* Set up the port */
        memset(&portinfo, 0, sizeof(portinfo));
        portinfo.addr.client = client;
-       strlcpy(portinfo.name, portname ? portname : "Unamed port",
+       strlcpy(portinfo.name, portname ? portname : "Unnamed port",
                sizeof(portinfo.name));
 
        portinfo.capability = cap;
index 23167578231f3c002a79dd034b0e3d8c0b83eeea..f587d0e2747606e116a26e71722a0b705190bcfd 100644 (file)
@@ -371,9 +371,7 @@ static int initialize_timer(struct snd_seq_timer *tmr)
 
        tmr->ticks = 1;
        if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
-               unsigned long r = t->hw.resolution;
-               if (! r && t->hw.c_resolution)
-                       r = t->hw.c_resolution(t);
+               unsigned long r = snd_timer_resolution(tmr->timeri);
                if (r) {
                        tmr->ticks = (unsigned int)(1000000000uL / (r * freq));
                        if (! tmr->ticks)
index 0ddcae4958381758ab6189ca6ad7a97375ddf184..665089c455603c0c683144c419981f8215780e85 100644 (file)
@@ -427,25 +427,35 @@ int snd_timer_close(struct snd_timer_instance *timeri)
 }
 EXPORT_SYMBOL(snd_timer_close);
 
+static unsigned long snd_timer_hw_resolution(struct snd_timer *timer)
+{
+       if (timer->hw.c_resolution)
+               return timer->hw.c_resolution(timer);
+       else
+               return timer->hw.resolution;
+}
+
 unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
 {
        struct snd_timer * timer;
+       unsigned long ret = 0;
+       unsigned long flags;
 
        if (timeri == NULL)
                return 0;
        timer = timeri->timer;
        if (timer) {
-               if (timer->hw.c_resolution)
-                       return timer->hw.c_resolution(timer);
-               return timer->hw.resolution;
+               spin_lock_irqsave(&timer->lock, flags);
+               ret = snd_timer_hw_resolution(timer);
+               spin_unlock_irqrestore(&timer->lock, flags);
        }
-       return 0;
+       return ret;
 }
 EXPORT_SYMBOL(snd_timer_resolution);
 
 static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
 {
-       struct snd_timer *timer;
+       struct snd_timer *timer = ti->timer;
        unsigned long resolution = 0;
        struct snd_timer_instance *ts;
        struct timespec tstamp;
@@ -457,14 +467,14 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
        if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_START ||
                       event > SNDRV_TIMER_EVENT_PAUSE))
                return;
-       if (event == SNDRV_TIMER_EVENT_START ||
-           event == SNDRV_TIMER_EVENT_CONTINUE)
-               resolution = snd_timer_resolution(ti);
+       if (timer &&
+           (event == SNDRV_TIMER_EVENT_START ||
+            event == SNDRV_TIMER_EVENT_CONTINUE))
+               resolution = snd_timer_hw_resolution(timer);
        if (ti->ccallback)
                ti->ccallback(ti, event, &tstamp, resolution);
        if (ti->flags & SNDRV_TIMER_IFLG_SLAVE)
                return;
-       timer = ti->timer;
        if (timer == NULL)
                return;
        if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
@@ -771,10 +781,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
        spin_lock_irqsave(&timer->lock, flags);
 
        /* remember the current resolution */
-       if (timer->hw.c_resolution)
-               resolution = timer->hw.c_resolution(timer);
-       else
-               resolution = timer->hw.resolution;
+       resolution = snd_timer_hw_resolution(timer);
 
        /* loop for all active instances
         * Here we cannot use list_for_each_entry because the active_list of a
@@ -1014,12 +1021,8 @@ void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstam
        spin_lock_irqsave(&timer->lock, flags);
        if (event == SNDRV_TIMER_EVENT_MSTART ||
            event == SNDRV_TIMER_EVENT_MCONTINUE ||
-           event == SNDRV_TIMER_EVENT_MRESUME) {
-               if (timer->hw.c_resolution)
-                       resolution = timer->hw.c_resolution(timer);
-               else
-                       resolution = timer->hw.resolution;
-       }
+           event == SNDRV_TIMER_EVENT_MRESUME)
+               resolution = snd_timer_hw_resolution(timer);
        list_for_each_entry(ti, &timer->active_list_head, active_list) {
                if (ti->ccallback)
                        ti->ccallback(ti, event, tstamp, resolution);
@@ -1656,10 +1659,8 @@ static int snd_timer_user_gstatus(struct file *file,
        mutex_lock(&register_mutex);
        t = snd_timer_find(&tid);
        if (t != NULL) {
-               if (t->hw.c_resolution)
-                       gstatus.resolution = t->hw.c_resolution(t);
-               else
-                       gstatus.resolution = t->hw.resolution;
+               spin_lock_irq(&t->lock);
+               gstatus.resolution = snd_timer_hw_resolution(t);
                if (t->hw.precise_resolution) {
                        t->hw.precise_resolution(t, &gstatus.resolution_num,
                                                 &gstatus.resolution_den);
@@ -1667,6 +1668,7 @@ static int snd_timer_user_gstatus(struct file *file,
                        gstatus.resolution_num = gstatus.resolution;
                        gstatus.resolution_den = 1000000000uL;
                }
+               spin_unlock_irq(&t->lock);
        } else {
                err = -ENODEV;
        }
index 9e96186742d0fe26cc215de0e00ee0536d72fbab..58fa3f94722a41d4e89e7d33f00ba7b8f5b4ed14 100644 (file)
@@ -421,13 +421,15 @@ struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
        kctl->private_free = master_free;
 
        /* additional (constant) TLV read */
-       if (tlv &&
-           (tlv[0] == SNDRV_CTL_TLVT_DB_SCALE ||
-            tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX ||
-            tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX_MUTE)) {
-               kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
-               memcpy(master->tlv, tlv, sizeof(master->tlv));
-               kctl->tlv.p = master->tlv;
+       if (tlv) {
+               unsigned int type = tlv[SNDRV_CTL_TLVO_TYPE];
+               if (type == SNDRV_CTL_TLVT_DB_SCALE ||
+                   type == SNDRV_CTL_TLVT_DB_MINMAX ||
+                   type == SNDRV_CTL_TLVT_DB_MINMAX_MUTE) {
+                       kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
+                       memcpy(master->tlv, tlv, sizeof(master->tlv));
+                       kctl->tlv.p = master->tlv;
+               }
        }
 
        return kctl;
index eab7f594ebe7599d74aee47129cbb51047549286..78a2fdc38531fb9e1b7fe6770c9fc78ca129038b 100644 (file)
@@ -768,20 +768,7 @@ static int loopback_close(struct snd_pcm_substream *substream)
        return 0;
 }
 
-static const struct snd_pcm_ops loopback_playback_ops = {
-       .open =         loopback_open,
-       .close =        loopback_close,
-       .ioctl =        snd_pcm_lib_ioctl,
-       .hw_params =    loopback_hw_params,
-       .hw_free =      loopback_hw_free,
-       .prepare =      loopback_prepare,
-       .trigger =      loopback_trigger,
-       .pointer =      loopback_pointer,
-       .page =         snd_pcm_lib_get_vmalloc_page,
-       .mmap =         snd_pcm_lib_mmap_vmalloc,
-};
-
-static const struct snd_pcm_ops loopback_capture_ops = {
+static const struct snd_pcm_ops loopback_pcm_ops = {
        .open =         loopback_open,
        .close =        loopback_close,
        .ioctl =        snd_pcm_lib_ioctl,
@@ -804,8 +791,8 @@ static int loopback_pcm_new(struct loopback *loopback,
                          substreams, substreams, &pcm);
        if (err < 0)
                return err;
-       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &loopback_playback_ops);
-       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &loopback_capture_ops);
+       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &loopback_pcm_ops);
+       snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &loopback_pcm_ops);
 
        pcm->private_data = loopback;
        pcm->info_flags = 0;
index 8fb9a54fe8ba879857ce61ec25d5d2408c9a21ad..9af154db530a803943c9dc420d06e5a180d0789f 100644 (file)
@@ -1042,7 +1042,7 @@ static void dummy_proc_init(struct snd_dummy *chip)
        if (!snd_card_proc_new(chip->card, "dummy_pcm", &entry)) {
                snd_info_set_text_ops(entry, chip, dummy_proc_read);
                entry->c.text.write = dummy_proc_write;
-               entry->mode |= S_IWUSR;
+               entry->mode |= 0200;
                entry->private_data = chip;
        }
 }
index f32e813422474320551b843f2cff708594930743..b68e71ca7abdaa248e7caac57d269556da14925b 100644 (file)
@@ -41,11 +41,11 @@ static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
 static struct platform_device *platform_devices[SNDRV_CARDS]; 
 static int device_count;
 
-module_param_array(index, int, NULL, S_IRUGO);
+module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, S_IRUGO);
+module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, S_IRUGO);
+module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
 
 MODULE_AUTHOR("Matthias Koenig <mk@phasorlab.de>");
index cd2c07fa2ef4b9a8f74649d37bfc01ca836c738c..16b24091d79932bc6c21093a6259790dc3ef5e0e 100644 (file)
@@ -104,7 +104,7 @@ int snd_opl4_create_proc(struct snd_opl4 *opl4)
        if (entry) {
                if (opl4->hardware < OPL3_HW_OPL4_ML) {
                        /* OPL4 can access 4 MB external ROM/SRAM */
-                       entry->mode |= S_IWUSR;
+                       entry->mode |= 0200;
                        entry->size = 4 * 1024 * 1024;
                } else {
                        /* OPL4-ML has 1 MB internal ROM */
index ec8a94325ef628fe9a036ccaeccaa7ffc969d0c5..3cdf0a88d71bdc88aca36b0c4aae54ea5f661c4a 100644 (file)
@@ -60,11 +60,11 @@ static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
 static struct platform_device *platform_devices[SNDRV_CARDS]; 
 static int device_count;
 
-module_param_array(index, int, NULL, S_IRUGO);
+module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
-module_param_array(id, charp, NULL, S_IRUGO);
+module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
-module_param_array(enable, bool, NULL, S_IRUGO);
+module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
 
 MODULE_AUTHOR("Levent Guendogdu, Tobias Gehrig, Matthias Koenig");
index ec24f96794f50794737578c93d06261a9d93330c..8096891af9137a509e415cea4242a639a21c329b 100644 (file)
@@ -183,7 +183,7 @@ void snd_bebob_proc_init(struct snd_bebob *bebob)
                                          bebob->card->proc_root);
        if (root == NULL)
                return;
-       root->mode = S_IFDIR | S_IRUGO | S_IXUGO;
+       root->mode = S_IFDIR | 0555;
        if (snd_info_register(root) < 0) {
                snd_info_free_entry(root);
                return;
index 55b4be9b0034093bc221ff1955057f739e299520..37062a233f6a461835b60614902fba2de92bd724 100644 (file)
@@ -1,3 +1,4 @@
 snd-dice-objs := dice-transaction.o dice-stream.o dice-proc.o dice-midi.o \
-                dice-pcm.o dice-hwdep.o dice.o
+                dice-pcm.o dice-hwdep.o dice.o dice-tcelectronic.o \
+                dice-alesis.o dice-extension.o dice-mytek.o
 obj-$(CONFIG_SND_DICE) += snd-dice.o
diff --git a/sound/firewire/dice/dice-alesis.c b/sound/firewire/dice/dice-alesis.c
new file mode 100644 (file)
index 0000000..b2efb1c
--- /dev/null
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dice-alesis.c - a part of driver for DICE based devices
+ *
+ * Copyright (c) 2018 Takashi Sakamoto
+ */
+
+#include "dice.h"
+
+static const unsigned int
+alesis_io14_tx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT] = {
+       {6, 6, 4},      /* Tx0 = Analog + S/PDIF. */
+       {8, 4, 0},      /* Tx1 = ADAT1. */
+};
+
+static const unsigned int
+alesis_io26_tx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT] = {
+       {10, 10, 8},    /* Tx0 = Analog + S/PDIF. */
+       {16, 8, 0},     /* Tx1 = ADAT1 + ADAT2. */
+};
+
+int snd_dice_detect_alesis_formats(struct snd_dice *dice)
+{
+       __be32 reg;
+       u32 data;
+       int i;
+       int err;
+
+       err = snd_dice_transaction_read_tx(dice, TX_NUMBER_AUDIO, &reg,
+                                          sizeof(reg));
+       if (err < 0)
+               return err;
+       data = be32_to_cpu(reg);
+
+       if (data == 4 || data == 6) {
+               memcpy(dice->tx_pcm_chs, alesis_io14_tx_pcm_chs,
+                               MAX_STREAMS * SND_DICE_RATE_MODE_COUNT *
+                               sizeof(unsigned int));
+       } else {
+               memcpy(dice->rx_pcm_chs, alesis_io26_tx_pcm_chs,
+                               MAX_STREAMS * SND_DICE_RATE_MODE_COUNT *
+                               sizeof(unsigned int));
+       }
+
+       for (i = 0; i < SND_DICE_RATE_MODE_COUNT; ++i)
+               dice->rx_pcm_chs[0][i] = 8;
+
+       dice->tx_midi_ports[0] = 1;
+       dice->rx_midi_ports[0] = 1;
+
+       return 0;
+}
diff --git a/sound/firewire/dice/dice-extension.c b/sound/firewire/dice/dice-extension.c
new file mode 100644 (file)
index 0000000..a63fcbc
--- /dev/null
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dice-extension.c - a part of driver for DICE based devices
+ *
+ * Copyright (c) 2018 Takashi Sakamoto
+ */
+
+#include "dice.h"
+
+/* For TCD2210/2220, TCAT defines extension of application protocol. */
+
+#define DICE_EXT_APP_SPACE             0xffffe0200000uLL
+
+#define DICE_EXT_APP_CAPS_OFFSET       0x00
+#define DICE_EXT_APP_CAPS_SIZE         0x04
+#define DICE_EXT_APP_CMD_OFFSET                0x08
+#define DICE_EXT_APP_CMD_SIZE          0x0c
+#define DICE_EXT_APP_MIXER_OFFSET      0x10
+#define DICE_EXT_APP_MIXER_SIZE                0x14
+#define DICE_EXT_APP_PEAK_OFFSET       0x18
+#define DICE_EXT_APP_PEAK_SIZE         0x1c
+#define DICE_EXT_APP_ROUTER_OFFSET     0x20
+#define DICE_EXT_APP_ROUTER_SIZE       0x24
+#define DICE_EXT_APP_STREAM_OFFSET     0x28
+#define DICE_EXT_APP_STREAM_SIZE       0x2c
+#define DICE_EXT_APP_CURRENT_OFFSET    0x30
+#define DICE_EXT_APP_CURRENT_SIZE      0x34
+#define DICE_EXT_APP_STANDALONE_OFFSET 0x38
+#define DICE_EXT_APP_STANDALONE_SIZE   0x3c
+#define DICE_EXT_APP_APPLICATION_OFFSET        0x40
+#define DICE_EXT_APP_APPLICATION_SIZE  0x44
+
+#define EXT_APP_STREAM_TX_NUMBER       0x0000
+#define EXT_APP_STREAM_RX_NUMBER       0x0004
+#define EXT_APP_STREAM_ENTRIES         0x0008
+#define EXT_APP_STREAM_ENTRY_SIZE      0x010c
+#define  EXT_APP_NUMBER_AUDIO          0x0000
+#define  EXT_APP_NUMBER_MIDI           0x0004
+#define  EXT_APP_NAMES                 0x0008
+#define   EXT_APP_NAMES_SIZE           256
+#define  EXT_APP_AC3                   0x0108
+
+#define EXT_APP_CONFIG_LOW_ROUTER      0x0000
+#define EXT_APP_CONFIG_LOW_STREAM      0x1000
+#define EXT_APP_CONFIG_MIDDLE_ROUTER   0x2000
+#define EXT_APP_CONFIG_MIDDLE_STREAM   0x3000
+#define EXT_APP_CONFIG_HIGH_ROUTER     0x4000
+#define EXT_APP_CONFIG_HIGH_STREAM     0x5000
+
+static inline int read_transaction(struct snd_dice *dice, u64 section_addr,
+                                  u32 offset, void *buf, size_t len)
+{
+       return snd_fw_transaction(dice->unit,
+                                 len == 4 ? TCODE_READ_QUADLET_REQUEST :
+                                            TCODE_READ_BLOCK_REQUEST,
+                                 section_addr + offset, buf, len, 0);
+}
+
+static int read_stream_entries(struct snd_dice *dice, u64 section_addr,
+                              u32 base_offset, unsigned int stream_count,
+                              unsigned int mode,
+                              unsigned int pcm_channels[MAX_STREAMS][3],
+                              unsigned int midi_ports[MAX_STREAMS])
+{
+       u32 entry_offset;
+       __be32 reg[2];
+       int err;
+       int i;
+
+       for (i = 0; i < stream_count; ++i) {
+               entry_offset = base_offset + i * EXT_APP_STREAM_ENTRY_SIZE;
+               err = read_transaction(dice, section_addr,
+                                   entry_offset + EXT_APP_NUMBER_AUDIO,
+                                   reg, sizeof(reg));
+               if (err < 0)
+                       return err;
+               pcm_channels[i][mode] = be32_to_cpu(reg[0]);
+               midi_ports[i] = max(midi_ports[i], be32_to_cpu(reg[1]));
+       }
+
+       return 0;
+}
+
+static int detect_stream_formats(struct snd_dice *dice, u64 section_addr)
+{
+       u32 base_offset;
+       __be32 reg[2];
+       unsigned int stream_count;
+       int mode;
+       int err = 0;
+
+       for (mode = 0; mode < SND_DICE_RATE_MODE_COUNT; ++mode) {
+               unsigned int cap;
+
+               /*
+                * Some models report stream formats at highest mode, however
+                * they don't support the mode. Check clock capabilities.
+                */
+               if (mode == 2) {
+                       cap = CLOCK_CAP_RATE_176400 | CLOCK_CAP_RATE_192000;
+               } else if (mode == 1) {
+                       cap = CLOCK_CAP_RATE_88200 | CLOCK_CAP_RATE_96000;
+               } else {
+                       cap = CLOCK_CAP_RATE_32000 | CLOCK_CAP_RATE_44100 |
+                             CLOCK_CAP_RATE_48000;
+               }
+               if (!(cap & dice->clock_caps))
+                       continue;
+
+               base_offset = 0x2000 * mode + 0x1000;
+
+               err = read_transaction(dice, section_addr,
+                                      base_offset + EXT_APP_STREAM_TX_NUMBER,
+                                      &reg, sizeof(reg));
+               if (err < 0)
+                       break;
+
+               base_offset += EXT_APP_STREAM_ENTRIES;
+               stream_count = be32_to_cpu(reg[0]);
+               err = read_stream_entries(dice, section_addr, base_offset,
+                                         stream_count, mode,
+                                         dice->tx_pcm_chs,
+                                         dice->tx_midi_ports);
+               if (err < 0)
+                       break;
+
+               base_offset += stream_count * EXT_APP_STREAM_ENTRY_SIZE;
+               stream_count = be32_to_cpu(reg[1]);
+               err = read_stream_entries(dice, section_addr, base_offset,
+                                         stream_count,
+                                         mode, dice->rx_pcm_chs,
+                                         dice->rx_midi_ports);
+               if (err < 0)
+                       break;
+       }
+
+       return err;
+}
+
+int snd_dice_detect_extension_formats(struct snd_dice *dice)
+{
+       __be32 *pointers;
+       unsigned int i;
+       u64 section_addr;
+       int err;
+
+       pointers = kmalloc_array(9, sizeof(__be32) * 2, GFP_KERNEL);
+       if (pointers == NULL)
+               return -ENOMEM;
+
+       err = snd_fw_transaction(dice->unit, TCODE_READ_BLOCK_REQUEST,
+                                DICE_EXT_APP_SPACE, pointers,
+                                9 * sizeof(__be32) * 2, 0);
+       if (err < 0)
+               goto end;
+
+       /* Check two of them for offset have the same value or not. */
+       for (i = 0; i < 9; ++i) {
+               int j;
+
+               for (j = i + 1; j < 9; ++j) {
+                       if (pointers[i * 2] == pointers[j * 2])
+                               goto end;
+               }
+       }
+
+       section_addr = DICE_EXT_APP_SPACE + be32_to_cpu(pointers[12]) * 4;
+       err = detect_stream_formats(dice, section_addr);
+end:
+       kfree(pointers);
+       return err;
+}
index 15a484b0529837ba9b197a86121391a2650bda0b..9cad3d6082296548cedb934c081a4092f4de699d 100644 (file)
  */
 #define GLOBAL_SAMPLE_RATE             0x05c
 
+/*
+ * Some old firmware versions do not have the following global registers.
+ * Windows drivers produced by TCAT lost backward compatibility in its
+ * early release because they can handle firmware only which supports the
+ * following registers.
+ */
+
 /*
  * The version of the DICE driver specification that this device conforms to;
  * read-only.
  */
 #define GLOBAL_VERSION                 0x060
 
-/* Some old firmware versions do not have the following global registers: */
-
 /*
  * Supported sample rates and clock sources; read-only.
  */
index 8ff6da3c51f72c1a3b6d0b0a671eabe43018e5d3..84eca8a51a02fa9057a2c3153ad4d9f3c29b3a29 100644 (file)
@@ -101,27 +101,18 @@ int snd_dice_create_midi(struct snd_dice *dice)
                .close          = midi_close,
                .trigger        = midi_playback_trigger,
        };
-       __be32 reg;
        struct snd_rawmidi *rmidi;
        struct snd_rawmidi_str *str;
        unsigned int midi_in_ports, midi_out_ports;
+       int i;
        int err;
 
-       /*
-        * Use the number of MIDI conformant data channel at current sampling
-        * transfer frequency.
-        */
-       err = snd_dice_transaction_read_tx(dice, TX_NUMBER_MIDI,
-                                          &reg, sizeof(reg));
-       if (err < 0)
-               return err;
-       midi_in_ports = be32_to_cpu(reg);
-
-       err = snd_dice_transaction_read_rx(dice, RX_NUMBER_MIDI,
-                                          &reg, sizeof(reg));
-       if (err < 0)
-               return err;
-       midi_out_ports = be32_to_cpu(reg);
+       midi_in_ports = 0;
+       midi_out_ports = 0;
+       for (i = 0; i < MAX_STREAMS; ++i) {
+               midi_in_ports = max(midi_in_ports, dice->tx_midi_ports[i]);
+               midi_out_ports = max(midi_out_ports, dice->rx_midi_ports[i]);
+       }
 
        if (midi_in_ports + midi_out_ports == 0)
                return 0;
diff --git a/sound/firewire/dice/dice-mytek.c b/sound/firewire/dice/dice-mytek.c
new file mode 100644 (file)
index 0000000..eb7d549
--- /dev/null
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dice-mytek.c - a part of driver for DICE based devices
+ *
+ * Copyright (c) 2018 Melvin Vermeeren
+ */
+
+#include "dice.h"
+
+struct dice_mytek_spec {
+       unsigned int tx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT];
+       unsigned int rx_pcm_chs[MAX_STREAMS][SND_DICE_RATE_MODE_COUNT];
+};
+
+static const struct dice_mytek_spec stereo_192_dsd_dac = {
+       /* AES, TOSLINK, SPDIF, ADAT inputs on device */
+       .tx_pcm_chs = {{8, 8, 8}, {0, 0, 0} },
+       /* PCM 44.1-192, native DSD64/DSD128 to device */
+       .rx_pcm_chs = {{4, 4, 4}, {0, 0, 0} }
+};
+
+/*
+ * Mytek has a few other firewire-capable devices, though newer models appear
+ * to lack the port more often than not. As I don't have access to any of them
+ * they are missing here. An example is the Mytek 8x192 ADDA, which is DICE.
+ */
+
+int snd_dice_detect_mytek_formats(struct snd_dice *dice)
+{
+       int i;
+       const struct dice_mytek_spec *dev;
+
+       dev = &stereo_192_dsd_dac;
+
+       memcpy(dice->tx_pcm_chs, dev->tx_pcm_chs,
+              MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int));
+       memcpy(dice->rx_pcm_chs, dev->rx_pcm_chs,
+              MAX_STREAMS * SND_DICE_RATE_MODE_COUNT * sizeof(unsigned int));
+
+       for (i = 0; i < MAX_STREAMS; ++i) {
+               dice->tx_midi_ports[i] = 0;
+               dice->rx_midi_ports[i] = 0;
+       }
+
+       return 0;
+}
index 7cb9e9713ac31e68efff4a20934ad1096277fe40..80351b29fe0d51e787845bb7620d625080cf509a 100644 (file)
 
 #include "dice.h"
 
+static int dice_rate_constraint(struct snd_pcm_hw_params *params,
+                               struct snd_pcm_hw_rule *rule)
+{
+       struct snd_pcm_substream *substream = rule->private;
+       struct snd_dice *dice = substream->private_data;
+       unsigned int index = substream->pcm->device;
+
+       const struct snd_interval *c =
+               hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+       struct snd_interval *r =
+               hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+       struct snd_interval rates = {
+               .min = UINT_MAX, .max = 0, .integer = 1
+       };
+       unsigned int *pcm_channels;
+       enum snd_dice_rate_mode mode;
+       unsigned int i, rate;
+
+       if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+               pcm_channels = dice->tx_pcm_chs[index];
+       else
+               pcm_channels = dice->rx_pcm_chs[index];
+
+       for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
+               rate = snd_dice_rates[i];
+               if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
+                       continue;
+
+               if (!snd_interval_test(c, pcm_channels[mode]))
+                       continue;
+
+               rates.min = min(rates.min, rate);
+               rates.max = max(rates.max, rate);
+       }
+
+       return snd_interval_refine(r, &rates);
+}
+
+static int dice_channels_constraint(struct snd_pcm_hw_params *params,
+                                   struct snd_pcm_hw_rule *rule)
+{
+       struct snd_pcm_substream *substream = rule->private;
+       struct snd_dice *dice = substream->private_data;
+       unsigned int index = substream->pcm->device;
+
+       const struct snd_interval *r =
+               hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);
+       struct snd_interval *c =
+               hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+       struct snd_interval channels = {
+               .min = UINT_MAX, .max = 0, .integer = 1
+       };
+       unsigned int *pcm_channels;
+       enum snd_dice_rate_mode mode;
+       unsigned int i, rate;
+
+       if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+               pcm_channels = dice->tx_pcm_chs[index];
+       else
+               pcm_channels = dice->rx_pcm_chs[index];
+
+       for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
+               rate = snd_dice_rates[i];
+               if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
+                       continue;
+
+               if (!snd_interval_test(r, rate))
+                       continue;
+
+               channels.min = min(channels.min, pcm_channels[mode]);
+               channels.max = max(channels.max, pcm_channels[mode]);
+       }
+
+       return snd_interval_refine(c, &channels);
+}
+
 static int limit_channels_and_rates(struct snd_dice *dice,
                                    struct snd_pcm_runtime *runtime,
                                    enum amdtp_stream_direction dir,
-                                   unsigned int index, unsigned int size)
+                                   unsigned int index)
 {
        struct snd_pcm_hardware *hw = &runtime->hw;
-       struct amdtp_stream *stream;
-       unsigned int rate;
-       __be32 reg;
-       int err;
-
-       /*
-        * Retrieve current Multi Bit Linear Audio data channel and limit to
-        * it.
-        */
-       if (dir == AMDTP_IN_STREAM) {
-               stream = &dice->tx_stream[index];
-               err = snd_dice_transaction_read_tx(dice,
-                               size * index + TX_NUMBER_AUDIO,
-                               &reg, sizeof(reg));
-       } else {
-               stream = &dice->rx_stream[index];
-               err = snd_dice_transaction_read_rx(dice,
-                               size * index + RX_NUMBER_AUDIO,
-                               &reg, sizeof(reg));
+       unsigned int *pcm_channels;
+       unsigned int i;
+
+       if (dir == AMDTP_IN_STREAM)
+               pcm_channels = dice->tx_pcm_chs[index];
+       else
+               pcm_channels = dice->rx_pcm_chs[index];
+
+       hw->channels_min = UINT_MAX;
+       hw->channels_max = 0;
+
+       for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
+               enum snd_dice_rate_mode mode;
+               unsigned int rate, channels;
+
+               rate = snd_dice_rates[i];
+               if (snd_dice_stream_get_rate_mode(dice, rate, &mode) < 0)
+                       continue;
+               hw->rates |= snd_pcm_rate_to_rate_bit(rate);
+
+               channels = pcm_channels[mode];
+               if (channels == 0)
+                       continue;
+               hw->channels_min = min(hw->channels_min, channels);
+               hw->channels_max = max(hw->channels_max, channels);
        }
-       if (err < 0)
-               return err;
 
-       hw->channels_min = hw->channels_max = be32_to_cpu(reg);
-
-       /* Retrieve current sampling transfer frequency and limit to it. */
-       err = snd_dice_transaction_get_rate(dice, &rate);
-       if (err < 0)
-               return err;
-
-       hw->rates = snd_pcm_rate_to_rate_bit(rate);
        snd_pcm_limit_hw_rates(runtime);
 
        return 0;
@@ -56,36 +128,34 @@ static int init_hw_info(struct snd_dice *dice,
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_pcm_hardware *hw = &runtime->hw;
+       unsigned int index = substream->pcm->device;
        enum amdtp_stream_direction dir;
        struct amdtp_stream *stream;
-       __be32 reg[2];
-       unsigned int count, size;
        int err;
 
        if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
                hw->formats = AM824_IN_PCM_FORMAT_BITS;
                dir = AMDTP_IN_STREAM;
-               stream = &dice->tx_stream[substream->pcm->device];
-               err = snd_dice_transaction_read_tx(dice, TX_NUMBER, reg,
-                                                  sizeof(reg));
+               stream = &dice->tx_stream[index];
        } else {
                hw->formats = AM824_OUT_PCM_FORMAT_BITS;
                dir = AMDTP_OUT_STREAM;
-               stream = &dice->rx_stream[substream->pcm->device];
-               err = snd_dice_transaction_read_rx(dice, RX_NUMBER, reg,
-                                                  sizeof(reg));
+               stream = &dice->rx_stream[index];
        }
 
+       err = limit_channels_and_rates(dice, substream->runtime, dir,
+                                      index);
        if (err < 0)
                return err;
 
-       count = min_t(unsigned int, be32_to_cpu(reg[0]), MAX_STREAMS);
-       if (substream->pcm->device >= count)
-               return -ENXIO;
-
-       size = be32_to_cpu(reg[1]) * 4;
-       err = limit_channels_and_rates(dice, substream->runtime, dir,
-                                      substream->pcm->device, size);
+       err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+                                 dice_rate_constraint, substream,
+                                 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+       if (err < 0)
+               return err;
+       err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+                                 dice_channels_constraint, substream,
+                                 SNDRV_PCM_HW_PARAM_RATE, -1);
        if (err < 0)
                return err;
 
@@ -95,6 +165,8 @@ static int init_hw_info(struct snd_dice *dice,
 static int pcm_open(struct snd_pcm_substream *substream)
 {
        struct snd_dice *dice = substream->private_data;
+       unsigned int source;
+       bool internal;
        int err;
 
        err = snd_dice_stream_lock_try(dice);
@@ -105,6 +177,43 @@ static int pcm_open(struct snd_pcm_substream *substream)
        if (err < 0)
                goto err_locked;
 
+       err = snd_dice_transaction_get_clock_source(dice, &source);
+       if (err < 0)
+               goto err_locked;
+       switch (source) {
+       case CLOCK_SOURCE_AES1:
+       case CLOCK_SOURCE_AES2:
+       case CLOCK_SOURCE_AES3:
+       case CLOCK_SOURCE_AES4:
+       case CLOCK_SOURCE_AES_ANY:
+       case CLOCK_SOURCE_ADAT:
+       case CLOCK_SOURCE_TDIF:
+       case CLOCK_SOURCE_WC:
+               internal = false;
+               break;
+       default:
+               internal = true;
+               break;
+       }
+
+       /*
+        * When source of clock is not internal or any PCM streams are running,
+        * available sampling rate is limited at current sampling rate.
+        */
+       if (!internal ||
+           amdtp_stream_pcm_running(&dice->tx_stream[0]) ||
+           amdtp_stream_pcm_running(&dice->tx_stream[1]) ||
+           amdtp_stream_pcm_running(&dice->rx_stream[0]) ||
+           amdtp_stream_pcm_running(&dice->rx_stream[1])) {
+               unsigned int rate;
+
+               err = snd_dice_transaction_get_rate(dice, &rate);
+               if (err < 0)
+                       goto err_locked;
+               substream->runtime->hw.rate_min = rate;
+               substream->runtime->hw.rate_max = rate;
+       }
+
        snd_pcm_set_sync(substream);
 end:
        return err;
@@ -318,37 +427,19 @@ int snd_dice_create_pcm(struct snd_dice *dice)
                .page      = snd_pcm_lib_get_vmalloc_page,
                .mmap      = snd_pcm_lib_mmap_vmalloc,
        };
-       __be32 reg;
        struct snd_pcm *pcm;
-       unsigned int i, max_capture, max_playback, capture, playback;
+       unsigned int capture, playback;
+       int i, j;
        int err;
 
-       /* Check whether PCM substreams are required. */
-       if (dice->force_two_pcms) {
-               max_capture = max_playback = 2;
-       } else {
-               max_capture = max_playback = 0;
-               err = snd_dice_transaction_read_tx(dice, TX_NUMBER, &reg,
-                                                  sizeof(reg));
-               if (err < 0)
-                       return err;
-               max_capture = min_t(unsigned int, be32_to_cpu(reg), MAX_STREAMS);
-
-               err = snd_dice_transaction_read_rx(dice, RX_NUMBER, &reg,
-                                                  sizeof(reg));
-               if (err < 0)
-                       return err;
-               max_playback = min_t(unsigned int, be32_to_cpu(reg), MAX_STREAMS);
-       }
-
        for (i = 0; i < MAX_STREAMS; i++) {
                capture = playback = 0;
-               if (i < max_capture)
-                       capture = 1;
-               if (i < max_playback)
-                       playback = 1;
-               if (capture == 0 && playback == 0)
-                       break;
+               for (j = 0; j < SND_DICE_RATE_MODE_COUNT; ++j) {
+                       if (dice->tx_pcm_chs[i][j] > 0)
+                               capture = 1;
+                       if (dice->rx_pcm_chs[i][j] > 0)
+                               playback = 1;
+               }
 
                err = snd_pcm_new(dice->card, "DICE", i, playback, capture,
                                  &pcm);
index f5c1d1bced59fee2e0012d9a5f96b85553bb53f8..bb870fc73f99f08ac34d4a921c88c8f26a63b4b7 100644 (file)
@@ -148,12 +148,12 @@ static void dice_proc_read(struct snd_info_entry *entry,
                                   >> CLOCK_RATE_SHIFT));
        snd_iprintf(buffer, "  ext status: %08x\n", buf.global.extended_status);
        snd_iprintf(buffer, "  sample rate: %u\n", buf.global.sample_rate);
-       snd_iprintf(buffer, "  version: %u.%u.%u.%u\n",
-                   (buf.global.version >> 24) & 0xff,
-                   (buf.global.version >> 16) & 0xff,
-                   (buf.global.version >>  8) & 0xff,
-                   (buf.global.version >>  0) & 0xff);
        if (quadlets >= 90) {
+               snd_iprintf(buffer, "  version: %u.%u.%u.%u\n",
+                           (buf.global.version >> 24) & 0xff,
+                           (buf.global.version >> 16) & 0xff,
+                           (buf.global.version >>  8) & 0xff,
+                           (buf.global.version >>  0) & 0xff);
                snd_iprintf(buffer, "  clock caps:");
                for (i = 0; i <= 6; ++i)
                        if (buf.global.clock_caps & (1 << i))
@@ -243,10 +243,74 @@ static void dice_proc_read(struct snd_info_entry *entry,
        }
 }
 
-void snd_dice_create_proc(struct snd_dice *dice)
+static void dice_proc_read_formation(struct snd_info_entry *entry,
+                                    struct snd_info_buffer *buffer)
+{
+       static const char *const rate_labels[] = {
+               [SND_DICE_RATE_MODE_LOW]        = "low",
+               [SND_DICE_RATE_MODE_MIDDLE]     = "middle",
+               [SND_DICE_RATE_MODE_HIGH]       = "high",
+       };
+       struct snd_dice *dice = entry->private_data;
+       int i, j;
+
+       snd_iprintf(buffer, "Output stream from unit:\n");
+       for (i = 0; i < SND_DICE_RATE_MODE_COUNT; ++i)
+               snd_iprintf(buffer, "\t%s", rate_labels[i]);
+       snd_iprintf(buffer, "\tMIDI\n");
+       for (i = 0; i < MAX_STREAMS; ++i) {
+               snd_iprintf(buffer, "Tx %u:", i);
+               for (j = 0; j < SND_DICE_RATE_MODE_COUNT; ++j)
+                       snd_iprintf(buffer, "\t%u", dice->tx_pcm_chs[i][j]);
+               snd_iprintf(buffer, "\t%u\n", dice->tx_midi_ports[i]);
+       }
+
+       snd_iprintf(buffer, "Input stream to unit:\n");
+       for (i = 0; i < SND_DICE_RATE_MODE_COUNT; ++i)
+               snd_iprintf(buffer, "\t%s", rate_labels[i]);
+       snd_iprintf(buffer, "\n");
+       for (i = 0; i < MAX_STREAMS; ++i) {
+               snd_iprintf(buffer, "Rx %u:", i);
+               for (j = 0; j < SND_DICE_RATE_MODE_COUNT; ++j)
+                       snd_iprintf(buffer, "\t%u", dice->rx_pcm_chs[i][j]);
+               snd_iprintf(buffer, "\t%u\n", dice->rx_midi_ports[i]);
+       }
+}
+
+static void add_node(struct snd_dice *dice, struct snd_info_entry *root,
+                    const char *name,
+                    void (*op)(struct snd_info_entry *entry,
+                               struct snd_info_buffer *buffer))
 {
        struct snd_info_entry *entry;
 
-       if (!snd_card_proc_new(dice->card, "dice", &entry))
-               snd_info_set_text_ops(entry, dice, dice_proc_read);
+       entry = snd_info_create_card_entry(dice->card, name, root);
+       if (!entry)
+               return;
+
+       snd_info_set_text_ops(entry, dice, op);
+       if (snd_info_register(entry) < 0)
+               snd_info_free_entry(entry);
+}
+
+void snd_dice_create_proc(struct snd_dice *dice)
+{
+       struct snd_info_entry *root;
+
+       /*
+        * All nodes are automatically removed at snd_card_disconnect(),
+        * by following to link list.
+        */
+       root = snd_info_create_card_entry(dice->card, "firewire",
+                                         dice->card->proc_root);
+       if (!root)
+               return;
+       root->mode = S_IFDIR | 0555;
+       if (snd_info_register(root) < 0) {
+               snd_info_free_entry(root);
+               return;
+       }
+
+       add_node(dice, root, "dice", dice_proc_read);
+       add_node(dice, root, "formation", dice_proc_read_formation);
 }
index 928a255bfc351406058b1c2bd8a43d785f63ef97..c3c892c5c7ff1644a5161a2739b79dd1404cefe7 100644 (file)
@@ -30,13 +30,43 @@ const unsigned int snd_dice_rates[SND_DICE_RATES_COUNT] = {
        [6] = 192000,
 };
 
+int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,
+                                 enum snd_dice_rate_mode *mode)
+{
+       /* Corresponding to each entry in snd_dice_rates. */
+       static const enum snd_dice_rate_mode modes[] = {
+               [0] = SND_DICE_RATE_MODE_LOW,
+               [1] = SND_DICE_RATE_MODE_LOW,
+               [2] = SND_DICE_RATE_MODE_LOW,
+               [3] = SND_DICE_RATE_MODE_MIDDLE,
+               [4] = SND_DICE_RATE_MODE_MIDDLE,
+               [5] = SND_DICE_RATE_MODE_HIGH,
+               [6] = SND_DICE_RATE_MODE_HIGH,
+       };
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(snd_dice_rates); i++) {
+               if (!(dice->clock_caps & BIT(i)))
+                       continue;
+               if (snd_dice_rates[i] != rate)
+                       continue;
+
+               *mode = modes[i];
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
 /*
  * This operation has an effect to synchronize GLOBAL_STATUS/GLOBAL_SAMPLE_RATE
  * to GLOBAL_STATUS. Especially, just after powering on, these are different.
  */
-static int ensure_phase_lock(struct snd_dice *dice)
+static int ensure_phase_lock(struct snd_dice *dice, unsigned int rate)
 {
        __be32 reg, nominal;
+       u32 data;
+       int i;
        int err;
 
        err = snd_dice_transaction_read_global(dice, GLOBAL_CLOCK_SELECT,
@@ -44,9 +74,21 @@ static int ensure_phase_lock(struct snd_dice *dice)
        if (err < 0)
                return err;
 
+       data = be32_to_cpu(reg);
+
+       data &= ~CLOCK_RATE_MASK;
+       for (i = 0; i < ARRAY_SIZE(snd_dice_rates); ++i) {
+               if (snd_dice_rates[i] == rate)
+                       break;
+       }
+       if (i == ARRAY_SIZE(snd_dice_rates))
+               return -EINVAL;
+       data |= i << CLOCK_RATE_SHIFT;
+
        if (completion_done(&dice->clock_accepted))
                reinit_completion(&dice->clock_accepted);
 
+       reg = cpu_to_be32(data);
        err = snd_dice_transaction_write_global(dice, GLOBAL_CLOCK_SELECT,
                                                &reg, sizeof(reg));
        if (err < 0