summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/Makefile1
-rw-r--r--sound/aoa/codecs/Makefile1
-rw-r--r--sound/aoa/codecs/tas-basstreble.h1
-rw-r--r--sound/aoa/codecs/tas-gain-table.h1
-rw-r--r--sound/aoa/core/Makefile1
-rw-r--r--sound/aoa/soundbus/sysfs.c1
-rw-r--r--sound/arm/Makefile1
-rw-r--r--sound/core/Makefile1
-rw-r--r--sound/core/compress_offload.c3
-rw-r--r--sound/core/oss/Makefile1
-rw-r--r--sound/core/pcm_compat.c1
-rw-r--r--sound/core/pcm_param_trace.h1
-rw-r--r--sound/core/pcm_trace.h1
-rw-r--r--sound/core/seq/Makefile1
-rw-r--r--sound/core/seq/seq_clientmgr.c8
-rw-r--r--sound/core/seq/seq_lock.c4
-rw-r--r--sound/core/seq/seq_lock.h13
-rw-r--r--sound/core/seq/seq_ports.c7
-rw-r--r--sound/core/seq/seq_virmidi.c27
-rw-r--r--sound/core/timer_compat.c17
-rw-r--r--sound/core/vmaster.c31
-rw-r--r--sound/drivers/Makefile1
-rw-r--r--sound/drivers/opl3/Makefile1
-rw-r--r--sound/drivers/opl4/Makefile1
-rw-r--r--sound/drivers/pcsp/pcsp.h1
-rw-r--r--sound/drivers/pcsp/pcsp_input.h1
-rw-r--r--sound/drivers/pcsp/pcsp_lib.c1
-rw-r--r--sound/drivers/pcsp/pcsp_mixer.c1
-rw-r--r--sound/firewire/Makefile1
-rw-r--r--sound/firewire/amdtp-am824.h1
-rw-r--r--sound/firewire/amdtp-stream.h1
-rw-r--r--sound/firewire/bebob/Makefile1
-rw-r--r--sound/firewire/cmp.h1
-rw-r--r--sound/firewire/dice/dice-interface.h1
-rw-r--r--sound/firewire/fcp.h1
-rw-r--r--sound/firewire/iso-resources.h1
-rw-r--r--sound/firewire/lib.h1
-rw-r--r--sound/firewire/motu/Makefile1
-rw-r--r--sound/firewire/packets-buffer.h1
-rw-r--r--sound/hda/Makefile1
-rw-r--r--sound/hda/hdac_controller.c5
-rw-r--r--sound/hda/hdac_sysfs.c1
-rw-r--r--sound/hda/local.h1
-rw-r--r--sound/hda/trace.h1
-rw-r--r--sound/i2c/Makefile1
-rw-r--r--sound/i2c/other/Makefile1
-rw-r--r--sound/isa/Makefile1
-rw-r--r--sound/isa/gus/Makefile1
-rw-r--r--sound/isa/msnd/Makefile1
-rw-r--r--sound/isa/opti9xx/Makefile1
-rw-r--r--sound/isa/sb/Makefile1
-rw-r--r--sound/oss/Makefile1
-rw-r--r--sound/oss/ad1848.h1
-rw-r--r--sound/oss/bin2hex.c1
-rw-r--r--sound/oss/dmasound/dmasound.h1
-rw-r--r--sound/oss/hex2hex.c1
-rw-r--r--sound/oss/midi_ctrl.h1
-rw-r--r--sound/oss/midi_synth.h1
-rw-r--r--sound/oss/mpu401.h1
-rw-r--r--sound/oss/os.h1
-rw-r--r--sound/oss/pas2.h1
-rw-r--r--sound/oss/sb.h1
-rw-r--r--sound/oss/sb_ess.c1
-rw-r--r--sound/oss/sb_ess.h1
-rw-r--r--sound/oss/sleep.h1
-rw-r--r--sound/oss/sound_calls.h1
-rw-r--r--sound/oss/sound_firmware.h1
-rw-r--r--sound/oss/tuning.h1
-rw-r--r--sound/oss/ulaw.h1
-rw-r--r--sound/oss/v_midi.h1
-rw-r--r--sound/oss/waveartist.h1
-rw-r--r--sound/parisc/harmony.h1
-rw-r--r--sound/pci/Makefile1
-rw-r--r--sound/pci/ad1889.h1
-rw-r--r--sound/pci/asihpi/hpi_version.h1
-rw-r--r--sound/pci/asihpi/hpifunc.c1
-rw-r--r--sound/pci/asihpi/hpioctl.c12
-rw-r--r--sound/pci/au88x0/Makefile1
-rw-r--r--sound/pci/au88x0/au8810.c1
-rw-r--r--sound/pci/au88x0/au8810.h1
-rw-r--r--sound/pci/au88x0/au8820.c1
-rw-r--r--sound/pci/au88x0/au8820.h1
-rw-r--r--sound/pci/au88x0/au8830.c1
-rw-r--r--sound/pci/au88x0/au8830.h1
-rw-r--r--sound/pci/au88x0/au88x0_eq.h1
-rw-r--r--sound/pci/au88x0/au88x0_eqdata.c1
-rw-r--r--sound/pci/au88x0/au88x0_mixer.c1
-rw-r--r--sound/pci/au88x0/au88x0_wt.h1
-rw-r--r--sound/pci/azt3328.h1
-rw-r--r--sound/pci/cs5535audio/cs5535audio.h1
-rw-r--r--sound/pci/ctxfi/cttimer.h1
-rw-r--r--sound/pci/echoaudio/Makefile1
-rw-r--r--sound/pci/echoaudio/echoaudio.c6
-rw-r--r--sound/pci/emu10k1/Makefile1
-rw-r--r--sound/pci/hda/Makefile1
-rw-r--r--sound/pci/hda/dell_wmi_helper.c1
-rw-r--r--sound/pci/hda/hda_codec.c97
-rw-r--r--sound/pci/hda/hda_controller_trace.h1
-rw-r--r--sound/pci/hda/hda_intel_trace.h1
-rw-r--r--sound/pci/hda/local.h1
-rw-r--r--sound/pci/hda/patch_hdmi.c21
-rw-r--r--sound/pci/hda/patch_realtek.c19
-rw-r--r--sound/pci/hda/thinkpad_helper.c1
-rw-r--r--sound/pci/ice1712/Makefile1
-rw-r--r--sound/pci/ice1712/juli.h1
-rw-r--r--sound/pci/ice1712/maya44.h1
-rw-r--r--sound/pci/ice1712/prodigy192.h1
-rw-r--r--sound/pci/ice1712/psc724.h1
-rw-r--r--sound/pci/ice1712/quartet.h1
-rw-r--r--sound/pci/ice1712/se.h1
-rw-r--r--sound/pci/ice1712/stac946x.h1
-rw-r--r--sound/pci/ice1712/wtm.h1
-rw-r--r--sound/pci/nm256/nm256_coef.c1
-rw-r--r--sound/pci/oxygen/Makefile1
-rw-r--r--sound/pci/oxygen/ak4396.h1
-rw-r--r--sound/pci/oxygen/cm9780.h1
-rw-r--r--sound/pci/oxygen/cs2000.h1
-rw-r--r--sound/pci/oxygen/cs4245.h1
-rw-r--r--sound/pci/oxygen/cs4362a.h1
-rw-r--r--sound/pci/oxygen/cs4398.h1
-rw-r--r--sound/pci/oxygen/oxygen.h1
-rw-r--r--sound/pci/oxygen/oxygen_regs.h1
-rw-r--r--sound/pci/oxygen/pcm1796.h1
-rw-r--r--sound/pci/oxygen/wm8766.h1
-rw-r--r--sound/pci/oxygen/wm8785.h1
-rw-r--r--sound/pci/oxygen/xonar.h1
-rw-r--r--sound/pci/oxygen/xonar_dg.h1
-rw-r--r--sound/pci/rme9652/Makefile1
-rw-r--r--sound/ppc/tumbler_volume.h1
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/amd/acp.h1
-rw-r--r--sound/soc/atmel/Makefile1
-rw-r--r--sound/soc/atmel/atmel-classd.h1
-rw-r--r--sound/soc/atmel/atmel-pdmic.h1
-rw-r--r--sound/soc/au1x/Makefile1
-rw-r--r--sound/soc/blackfin/Makefile1
-rw-r--r--sound/soc/cirrus/Makefile1
-rw-r--r--sound/soc/codecs/Makefile1
-rw-r--r--sound/soc/codecs/adau-utils.h1
-rw-r--r--sound/soc/codecs/adau1373.h1
-rw-r--r--sound/soc/codecs/adau17x1.c24
-rw-r--r--sound/soc/codecs/adau17x1.h3
-rw-r--r--sound/soc/codecs/cs4271.h1
-rw-r--r--sound/soc/codecs/es8328.h1
-rw-r--r--sound/soc/codecs/hdac_hdmi.h1
-rw-r--r--sound/soc/codecs/inno_rk3036.h1
-rw-r--r--sound/soc/codecs/max98090.c2
-rw-r--r--sound/soc/codecs/msm8916-wcd-analog.c7
-rw-r--r--sound/soc/codecs/msm8916-wcd-digital.c4
-rw-r--r--sound/soc/codecs/rt5514-spi.c17
-rw-r--r--sound/soc/codecs/rt5514-spi.h3
-rw-r--r--sound/soc/codecs/rt5514.c63
-rw-r--r--sound/soc/codecs/rt5514.h3
-rw-r--r--sound/soc/codecs/rt5616.c2
-rw-r--r--sound/soc/codecs/rt5631.h1
-rw-r--r--sound/soc/codecs/rt5659.c4
-rw-r--r--sound/soc/codecs/rt5663.c3
-rw-r--r--sound/soc/codecs/tlv320aic26.h1
-rw-r--r--sound/soc/codecs/uda134x.h1
-rw-r--r--sound/soc/codecs/wm8993.h1
-rw-r--r--sound/soc/codecs/wm8998.c84
-rw-r--r--sound/soc/codecs/wm9713.h1
-rw-r--r--sound/soc/davinci/Makefile1
-rw-r--r--sound/soc/davinci/davinci-mcasp.c6
-rw-r--r--sound/soc/fsl/Makefile1
-rw-r--r--sound/soc/fsl/imx-audmux.h1
-rw-r--r--sound/soc/fsl/mpc5200_dma.h1
-rw-r--r--sound/soc/generic/Makefile1
-rw-r--r--sound/soc/img/Makefile1
-rw-r--r--sound/soc/intel/Makefile1
-rw-r--r--sound/soc/intel/atom/Makefile1
-rw-r--r--sound/soc/intel/atom/sst/Makefile1
-rw-r--r--sound/soc/intel/boards/Makefile1
-rw-r--r--sound/soc/intel/boards/cht_bsw_max98090_ti.c6
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c2
-rw-r--r--sound/soc/intel/common/Makefile1
-rw-r--r--sound/soc/intel/skylake/Makefile1
-rw-r--r--sound/soc/intel/skylake/skl-messages.c9
-rw-r--r--sound/soc/intel/skylake/skl-nhlt.c9
-rw-r--r--sound/soc/intel/skylake/skl-pcm.c3
-rw-r--r--sound/soc/intel/skylake/skl-sst-utils.c15
-rw-r--r--sound/soc/intel/skylake/skl-topology.c2
-rw-r--r--sound/soc/intel/skylake/skl-topology.h3
-rw-r--r--sound/soc/mediatek/mt8173/Makefile1
-rw-r--r--sound/soc/mxs/Makefile1
-rw-r--r--sound/soc/nuc900/Makefile1
-rw-r--r--sound/soc/omap/Makefile1
-rw-r--r--sound/soc/pxa/Makefile1
-rw-r--r--sound/soc/qcom/Makefile1
-rw-r--r--sound/soc/rockchip/Makefile1
-rw-r--r--sound/soc/rockchip/rockchip_i2s.c1
-rw-r--r--sound/soc/samsung/Makefile1
-rw-r--r--sound/soc/samsung/i2s.c6
-rw-r--r--sound/soc/sh/Makefile1
-rw-r--r--sound/soc/sh/rcar/adg.c4
-rw-r--r--sound/soc/sh/rcar/ssi.c5
-rw-r--r--sound/soc/sirf/Makefile1
-rw-r--r--sound/soc/soc-compress.c461
-rw-r--r--sound/soc/soc-core.c220
-rw-r--r--sound/soc/soc-dapm.c158
-rw-r--r--sound/soc/soc-io.c14
-rw-r--r--sound/soc/soc-pcm.c462
-rw-r--r--sound/soc/soc-topology.c5
-rw-r--r--sound/soc/spear/Makefile1
-rw-r--r--sound/soc/stm/Makefile1
-rw-r--r--sound/soc/stm/stm32_sai.c2
-rw-r--r--sound/soc/stm/stm32_sai_sub.c33
-rw-r--r--sound/soc/sunxi/Makefile1
-rw-r--r--sound/soc/sunxi/sun8i-codec.c59
-rw-r--r--sound/soc/tegra/Makefile1
-rw-r--r--sound/soc/txx9/Makefile1
-rw-r--r--sound/soc/ux500/Makefile1
-rw-r--r--sound/sparc/Makefile1
-rw-r--r--sound/spi/Makefile1
-rw-r--r--sound/synth/Makefile1
-rw-r--r--sound/synth/emux/Makefile1
-rw-r--r--sound/usb/Makefile1
-rw-r--r--sound/usb/caiaq/audio.h1
-rw-r--r--sound/usb/caiaq/control.h1
-rw-r--r--sound/usb/caiaq/device.c12
-rw-r--r--sound/usb/caiaq/device.h1
-rw-r--r--sound/usb/caiaq/input.h1
-rw-r--r--sound/usb/caiaq/midi.h1
-rw-r--r--sound/usb/card.c20
-rw-r--r--sound/usb/card.h1
-rw-r--r--sound/usb/clock.h1
-rw-r--r--sound/usb/debug.h1
-rw-r--r--sound/usb/endpoint.h1
-rw-r--r--sound/usb/format.h1
-rw-r--r--sound/usb/helper.h1
-rw-r--r--sound/usb/line6/Makefile1
-rw-r--r--sound/usb/line6/driver.c7
-rw-r--r--sound/usb/line6/podhd.c8
-rw-r--r--sound/usb/midi.h1
-rw-r--r--sound/usb/mixer.c12
-rw-r--r--sound/usb/mixer.h3
-rw-r--r--sound/usb/mixer_quirks.h1
-rw-r--r--sound/usb/mixer_scarlett.h1
-rw-r--r--sound/usb/mixer_us16x08.h1
-rw-r--r--sound/usb/pcm.h1
-rw-r--r--sound/usb/power.h1
-rw-r--r--sound/usb/proc.h1
-rw-r--r--sound/usb/quirks.c4
-rw-r--r--sound/usb/quirks.h1
-rw-r--r--sound/usb/stream.h1
-rw-r--r--sound/usb/usx2y/Makefile1
-rw-r--r--sound/usb/usx2y/us122l.h1
-rw-r--r--sound/usb/usx2y/usX2Yhwdep.h1
-rw-r--r--sound/usb/usx2y/usb_stream.c6
-rw-r--r--sound/usb/usx2y/usb_stream.h1
-rw-r--r--sound/usb/usx2y/usbusx2y.h1
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.h1
252 files changed, 1759 insertions, 482 deletions
diff --git a/sound/Makefile b/sound/Makefile
index 6de45d2c32f7..f2d1d093bcdc 100644
--- a/sound/Makefile
+++ b/sound/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# Makefile for the Linux sound card driver
#
diff --git a/sound/aoa/codecs/Makefile b/sound/aoa/codecs/Makefile
index c3ee77fc4b2d..95f4c3849d55 100644
--- a/sound/aoa/codecs/Makefile
+++ b/sound/aoa/codecs/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-aoa-codec-onyx-objs := onyx.o
snd-aoa-codec-tas-objs := tas.o
snd-aoa-codec-toonie-objs := toonie.o
diff --git a/sound/aoa/codecs/tas-basstreble.h b/sound/aoa/codecs/tas-basstreble.h
index 69b61136fd54..770935af66af 100644
--- a/sound/aoa/codecs/tas-basstreble.h
+++ b/sound/aoa/codecs/tas-basstreble.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* This file is only included exactly once!
*
diff --git a/sound/aoa/codecs/tas-gain-table.h b/sound/aoa/codecs/tas-gain-table.h
index 4cfa6757715e..77b8e7dc55fd 100644
--- a/sound/aoa/codecs/tas-gain-table.h
+++ b/sound/aoa/codecs/tas-gain-table.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
This is the program used to generate below table.
diff --git a/sound/aoa/core/Makefile b/sound/aoa/core/Makefile
index a1596e88c718..056d69683b1e 100644
--- a/sound/aoa/core/Makefile
+++ b/sound/aoa/core/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_SND_AOA) += snd-aoa.o
snd-aoa-objs := core.o \
alsa.o \
diff --git a/sound/aoa/soundbus/sysfs.c b/sound/aoa/soundbus/sysfs.c
index 5b2d51d99768..81da020bddef 100644
--- a/sound/aoa/soundbus/sysfs.c
+++ b/sound/aoa/soundbus/sysfs.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include <linux/kernel.h>
#include <linux/stat.h>
/* FIX UP */
diff --git a/sound/arm/Makefile b/sound/arm/Makefile
index 8c0c851d4641..e10d5b169565 100644
--- a/sound/arm/Makefile
+++ b/sound/arm/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
#
diff --git a/sound/core/Makefile b/sound/core/Makefile
index e2066e2ef9f8..ee4a4a6b99ba 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 1999,2001 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index fec1dfdb14ad..4490a699030b 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -948,14 +948,13 @@ static const struct file_operations snd_compr_file_ops = {
static int snd_compress_dev_register(struct snd_device *device)
{
int ret = -EINVAL;
- char str[16];
struct snd_compr *compr;
if (snd_BUG_ON(!device || !device->device_data))
return -EBADFD;
compr = device->device_data;
- pr_debug("reg %s for device %s, direction %d\n", str, compr->name,
+ pr_debug("reg device %s, direction %d\n", compr->name,
compr->direction);
/* register compressed device */
ret = snd_register_device(SNDRV_DEVICE_TYPE_COMPRESS,
diff --git a/sound/core/oss/Makefile b/sound/core/oss/Makefile
index 10a79453245f..ae25edcc3b42 100644
--- a/sound/core/oss/Makefile
+++ b/sound/core/oss/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 3a1cc7b97e46..b719d0bd833e 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -547,6 +547,7 @@ struct snd_pcm_mmap_status_x32 {
u32 pad2; /* alignment */
struct timespec tstamp;
s32 suspended_state;
+ s32 pad3;
struct timespec audio_tstamp;
} __packed;
diff --git a/sound/core/pcm_param_trace.h b/sound/core/pcm_param_trace.h
index 86c8d658a25c..08abba3133ab 100644
--- a/sound/core/pcm_param_trace.h
+++ b/sound/core/pcm_param_trace.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM snd_pcm
diff --git a/sound/core/pcm_trace.h b/sound/core/pcm_trace.h
index 3ddec1b8ae46..f18da2050772 100644
--- a/sound/core/pcm_trace.h
+++ b/sound/core/pcm_trace.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM snd_pcm
#define TRACE_INCLUDE_FILE pcm_trace
diff --git a/sound/core/seq/Makefile b/sound/core/seq/Makefile
index 68fd367ac39c..3a2177a7e50c 100644
--- a/sound/core/seq/Makefile
+++ b/sound/core/seq/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index ea2d0ae85bd3..d10c780dfd54 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -663,7 +663,7 @@ static int deliver_to_subscribers(struct snd_seq_client *client,
if (atomic)
read_lock(&grp->list_lock);
else
- down_read(&grp->list_mutex);
+ down_read_nested(&grp->list_mutex, hop);
list_for_each_entry(subs, &grp->list_head, src_list) {
/* both ports ready? */
if (atomic_read(&subs->ref_count) != 2)
@@ -1259,6 +1259,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg)
struct snd_seq_port_info *info = arg;
struct snd_seq_client_port *port;
struct snd_seq_port_callback *callback;
+ int port_idx;
/* it is not allowed to create the port for an another client */
if (info->addr.client != client->number)
@@ -1269,7 +1270,9 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg)
return -ENOMEM;
if (client->type == USER_CLIENT && info->kernel) {
- snd_seq_delete_port(client, port->addr.port);
+ port_idx = port->addr.port;
+ snd_seq_port_unlock(port);
+ snd_seq_delete_port(client, port_idx);
return -EINVAL;
}
if (client->type == KERNEL_CLIENT) {
@@ -1290,6 +1293,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg)
snd_seq_set_port_info(port, info);
snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port);
+ snd_seq_port_unlock(port);
return 0;
}
diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c
index 0ff7926a5a69..cda64b489e42 100644
--- a/sound/core/seq/seq_lock.c
+++ b/sound/core/seq/seq_lock.c
@@ -23,8 +23,6 @@
#include <sound/core.h>
#include "seq_lock.h"
-#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
-
/* wait until all locks are released */
void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
{
@@ -41,5 +39,3 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
}
}
EXPORT_SYMBOL(snd_use_lock_sync_helper);
-
-#endif
diff --git a/sound/core/seq/seq_lock.h b/sound/core/seq/seq_lock.h
index 54044bc2c9ef..a973860ebcd0 100644
--- a/sound/core/seq/seq_lock.h
+++ b/sound/core/seq/seq_lock.h
@@ -1,10 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __SND_SEQ_LOCK_H
#define __SND_SEQ_LOCK_H
#include <linux/sched.h>
-#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
-
typedef atomic_t snd_use_lock_t;
/* initialize lock */
@@ -20,14 +19,4 @@ typedef atomic_t snd_use_lock_t;
void snd_use_lock_sync_helper(snd_use_lock_t *lock, const char *file, int line);
#define snd_use_lock_sync(lockp) snd_use_lock_sync_helper(lockp, __BASE_FILE__, __LINE__)
-#else /* SMP || CONFIG_SND_DEBUG */
-
-typedef spinlock_t snd_use_lock_t; /* dummy */
-#define snd_use_lock_init(lockp) /**/
-#define snd_use_lock_use(lockp) /**/
-#define snd_use_lock_free(lockp) /**/
-#define snd_use_lock_sync(lockp) /**/
-
-#endif /* SMP || CONFIG_SND_DEBUG */
-
#endif /* __SND_SEQ_LOCK_H */
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index 0a7020c82bfc..d21ece9f8d73 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -122,7 +122,9 @@ static void port_subs_info_init(struct snd_seq_port_subs_info *grp)
}
-/* create a port, port number is returned (-1 on failure) */
+/* create a port, port number is returned (-1 on failure);
+ * the caller needs to unref the port via snd_seq_port_unlock() appropriately
+ */
struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
int port)
{
@@ -151,6 +153,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
snd_use_lock_init(&new_port->use_lock);
port_subs_info_init(&new_port->c_src);
port_subs_info_init(&new_port->c_dest);
+ snd_use_lock_use(&new_port->use_lock);
num = port >= 0 ? port : 0;
mutex_lock(&client->ports_mutex);
@@ -165,9 +168,9 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
list_add_tail(&new_port->list, &p->list);
client->num_ports++;
new_port->addr.port = num; /* store the port number in the port */
+ sprintf(new_port->name, "port-%d", num);
write_unlock_irqrestore(&client->ports_lock, flags);
mutex_unlock(&client->ports_mutex);
- sprintf(new_port->name, "port-%d", num);
return new_port;
}
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index 8d93a4021c78..f48a4cd24ffc 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -77,13 +77,17 @@ static void snd_virmidi_init_event(struct snd_virmidi *vmidi,
* decode input event and put to read buffer of each opened file
*/
static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev,
- struct snd_seq_event *ev)
+ struct snd_seq_event *ev,
+ bool atomic)
{
struct snd_virmidi *vmidi;
unsigned char msg[4];
int len;
- read_lock(&rdev->filelist_lock);
+ if (atomic)
+ read_lock(&rdev->filelist_lock);
+ else
+ down_read(&rdev->filelist_sem);
list_for_each_entry(vmidi, &rdev->filelist, list) {
if (!vmidi->trigger)
continue;
@@ -97,7 +101,10 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev,
snd_rawmidi_receive(vmidi->substream, msg, len);
}
}
- read_unlock(&rdev->filelist_lock);
+ if (atomic)
+ read_unlock(&rdev->filelist_lock);
+ else
+ up_read(&rdev->filelist_sem);
return 0;
}
@@ -115,7 +122,7 @@ int snd_virmidi_receive(struct snd_rawmidi *rmidi, struct snd_seq_event *ev)
struct snd_virmidi_dev *rdev;
rdev = rmidi->private_data;
- return snd_virmidi_dev_receive_event(rdev, ev);
+ return snd_virmidi_dev_receive_event(rdev, ev, true);
}
#endif /* 0 */
@@ -130,7 +137,7 @@ static int snd_virmidi_event_input(struct snd_seq_event *ev, int direct,
rdev = private_data;
if (!(rdev->flags & SNDRV_VIRMIDI_USE))
return 0; /* ignored */
- return snd_virmidi_dev_receive_event(rdev, ev);
+ return snd_virmidi_dev_receive_event(rdev, ev, atomic);
}
/*
@@ -209,7 +216,6 @@ static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream)
struct snd_virmidi_dev *rdev = substream->rmidi->private_data;
struct snd_rawmidi_runtime *runtime = substream->runtime;
struct snd_virmidi *vmidi;
- unsigned long flags;
vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL);
if (vmidi == NULL)
@@ -223,9 +229,11 @@ static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream)
vmidi->client = rdev->client;
vmidi->port = rdev->port;
runtime->private_data = vmidi;
- write_lock_irqsave(&rdev->filelist_lock, flags);
+ down_write(&rdev->filelist_sem);
+ write_lock_irq(&rdev->filelist_lock);
list_add_tail(&vmidi->list, &rdev->filelist);
- write_unlock_irqrestore(&rdev->filelist_lock, flags);
+ write_unlock_irq(&rdev->filelist_lock);
+ up_write(&rdev->filelist_sem);
vmidi->rdev = rdev;
return 0;
}
@@ -264,9 +272,11 @@ static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream)
struct snd_virmidi_dev *rdev = substream->rmidi->private_data;
struct snd_virmidi *vmidi = substream->runtime->private_data;
+ down_write(&rdev->filelist_sem);
write_lock_irq(&rdev->filelist_lock);
list_del(&vmidi->list);
write_unlock_irq(&rdev->filelist_lock);
+ up_write(&rdev->filelist_sem);
snd_midi_event_free(vmidi->parser);
substream->runtime->private_data = NULL;
kfree(vmidi);
@@ -520,6 +530,7 @@ int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmi
rdev->rmidi = rmidi;
rdev->device = device;
rdev->client = -1;
+ init_rwsem(&rdev->filelist_sem);
rwlock_init(&rdev->filelist_lock);
INIT_LIST_HEAD(&rdev->filelist);
rdev->seq_mode = SNDRV_VIRMIDI_SEQ_DISPATCH;
diff --git a/sound/core/timer_compat.c b/sound/core/timer_compat.c
index 6a437eb66115..59127b6ef39e 100644
--- a/sound/core/timer_compat.c
+++ b/sound/core/timer_compat.c
@@ -133,7 +133,8 @@ enum {
#endif /* CONFIG_X86_X32 */
};
-static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
+static long __snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
void __user *argp = compat_ptr(arg);
@@ -153,7 +154,7 @@ static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, uns
case SNDRV_TIMER_IOCTL_PAUSE:
case SNDRV_TIMER_IOCTL_PAUSE_OLD:
case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
- return snd_timer_user_ioctl(file, cmd, (unsigned long)argp);
+ return __snd_timer_user_ioctl(file, cmd, (unsigned long)argp);
case SNDRV_TIMER_IOCTL_GPARAMS32:
return snd_timer_user_gparams_compat(file, argp);
case SNDRV_TIMER_IOCTL_INFO32:
@@ -167,3 +168,15 @@ static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, uns
}
return -ENOIOCTLCMD;
}
+
+static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct snd_timer_user *tu = file->private_data;
+ long ret;
+
+ mutex_lock(&tu->ioctl_lock);
+ ret = __snd_timer_user_ioctl_compat(file, cmd, arg);
+ mutex_unlock(&tu->ioctl_lock);
+ return ret;
+}
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c
index 6c58e6f73a01..e43af18d4383 100644
--- a/sound/core/vmaster.c
+++ b/sound/core/vmaster.c
@@ -484,3 +484,34 @@ void snd_ctl_sync_vmaster(struct snd_kcontrol *kcontrol, bool hook_only)
master->hook(master->hook_private_data, master->val);
}
EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster);
+
+/**
+ * snd_ctl_apply_vmaster_slaves - Apply function to each vmaster slave
+ * @kctl: vmaster kctl element
+ * @func: function to apply
+ * @arg: optional function argument
+ *
+ * Apply the function @func to each slave kctl of the given vmaster kctl.
+ * Returns 0 if successful, or a negative error code.
+ */
+int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl,
+ int (*func)(struct snd_kcontrol *, void *),
+ void *arg)
+{
+ struct link_master *master;
+ struct link_slave *slave;
+ int err;
+
+ master = snd_kcontrol_chip(kctl);
+ err = master_init(master);
+ if (err < 0)
+ return err;
+ list_for_each_entry(slave, &master->slaves, list) {
+ err = func(&slave->slave, arg);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(snd_ctl_apply_vmaster_slaves);
diff --git a/sound/drivers/Makefile b/sound/drivers/Makefile
index 1a8440c8b138..615558a281c8 100644
--- a/sound/drivers/Makefile
+++ b/sound/drivers/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/drivers/opl3/Makefile b/sound/drivers/opl3/Makefile
index d72b1e7b51c4..83bca9f1fbdf 100644
--- a/sound/drivers/opl3/Makefile
+++ b/sound/drivers/opl3/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/drivers/opl4/Makefile b/sound/drivers/opl4/Makefile
index c8eaa433d71a..6e86a4092b4c 100644
--- a/sound/drivers/opl4/Makefile
+++ b/sound/drivers/opl4/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h
index fc7a2dc410a1..036ad3c99a43 100644
--- a/sound/drivers/pcsp/pcsp.h
+++ b/sound/drivers/pcsp/pcsp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* PC-Speaker driver for Linux
*
diff --git a/sound/drivers/pcsp/pcsp_input.h b/sound/drivers/pcsp/pcsp_input.h
index d692749b8c9b..e80079b38a56 100644
--- a/sound/drivers/pcsp/pcsp_input.h
+++ b/sound/drivers/pcsp/pcsp_input.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* PC-Speaker driver for Linux
*
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c
index 2f5a35f38ce1..8f0f05bbc081 100644
--- a/sound/drivers/pcsp/pcsp_lib.c
+++ b/sound/drivers/pcsp/pcsp_lib.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PC-Speaker driver for Linux
*
diff --git a/sound/drivers/pcsp/pcsp_mixer.c b/sound/drivers/pcsp/pcsp_mixer.c
index f1e1defc09b1..be2990451bcd 100644
--- a/sound/drivers/pcsp/pcsp_mixer.c
+++ b/sound/drivers/pcsp/pcsp_mixer.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PC-Speaker driver for Linux
*
diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile
index 1b98fa3fa3d4..44a7b510b75b 100644
--- a/sound/firewire/Makefile
+++ b/sound/firewire/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# To find a header included by define_trace.h.
CFLAGS_amdtp-stream.o := -I$(src)
diff --git a/sound/firewire/amdtp-am824.h b/sound/firewire/amdtp-am824.h
index b56e61fc997d..06d280783581 100644
--- a/sound/firewire/amdtp-am824.h
+++ b/sound/firewire/amdtp-am824.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef SOUND_FIREWIRE_AMDTP_AM824_H_INCLUDED
#define SOUND_FIREWIRE_AMDTP_AM824_H_INCLUDED
diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h
index ed6eafd10992..a608dae83348 100644
--- a/sound/firewire/amdtp-stream.h
+++ b/sound/firewire/amdtp-stream.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef SOUND_FIREWIRE_AMDTP_H_INCLUDED
#define SOUND_FIREWIRE_AMDTP_H_INCLUDED
diff --git a/sound/firewire/bebob/Makefile b/sound/firewire/bebob/Makefile
index dd454867240d..14bc84c51ef5 100644
--- a/sound/firewire/bebob/Makefile
+++ b/sound/firewire/bebob/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-bebob-objs := bebob_command.o bebob_stream.o bebob_proc.o bebob_midi.o \
bebob_pcm.o bebob_hwdep.o bebob_terratec.o \
bebob_yamaha_terratec.o bebob_focusrite.o bebob_maudio.o \
diff --git a/sound/firewire/cmp.h b/sound/firewire/cmp.h
index ebcb48484fca..b60b415caa8f 100644
--- a/sound/firewire/cmp.h
+++ b/sound/firewire/cmp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef SOUND_FIREWIRE_CMP_H_INCLUDED
#define SOUND_FIREWIRE_CMP_H_INCLUDED
diff --git a/sound/firewire/dice/dice-interface.h b/sound/firewire/dice/dice-interface.h
index 47f2c0a6f5d9..15a484b05298 100644
--- a/sound/firewire/dice/dice-interface.h
+++ b/sound/firewire/dice/dice-interface.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef SOUND_FIREWIRE_DICE_INTERFACE_H_INCLUDED
#define SOUND_FIREWIRE_DICE_INTERFACE_H_INCLUDED
diff --git a/sound/firewire/fcp.h b/sound/firewire/fcp.h
index 63ae4f7ce3af..512f7c40903a 100644
--- a/sound/firewire/fcp.h
+++ b/sound/firewire/fcp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef SOUND_FIREWIRE_FCP_H_INCLUDED
#define SOUND_FIREWIRE_FCP_H_INCLUDED
diff --git a/sound/firewire/iso-resources.h b/sound/firewire/iso-resources.h
index 5a9af7c61657..34f85e9e8830 100644
--- a/sound/firewire/iso-resources.h
+++ b/sound/firewire/iso-resources.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef SOUND_FIREWIRE_ISO_RESOURCES_H_INCLUDED
#define SOUND_FIREWIRE_ISO_RESOURCES_H_INCLUDED
diff --git a/sound/firewire/lib.h b/sound/firewire/lib.h
index eef70922ed89..dc815dc3933e 100644
--- a/sound/firewire/lib.h
+++ b/sound/firewire/lib.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef SOUND_FIREWIRE_LIB_H_INCLUDED
#define SOUND_FIREWIRE_LIB_H_INCLUDED
diff --git a/sound/firewire/motu/Makefile b/sound/firewire/motu/Makefile
index 728f586e754b..7c502d35103c 100644
--- a/sound/firewire/motu/Makefile
+++ b/sound/firewire/motu/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
CFLAGS_amdtp-motu.o := -I$(src)
snd-firewire-motu-objs := motu.o amdtp-motu.o motu-transaction.o motu-stream.o \
diff --git a/sound/firewire/packets-buffer.h b/sound/firewire/packets-buffer.h
index 6513c5cb6ea9..99e963c271e1 100644
--- a/sound/firewire/packets-buffer.h
+++ b/sound/firewire/packets-buffer.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef SOUND_FIREWIRE_PACKETS_BUFFER_H_INCLUDED
#define SOUND_FIREWIRE_PACKETS_BUFFER_H_INCLUDED
diff --git a/sound/hda/Makefile b/sound/hda/Makefile
index 3b9bedee2fa4..e4e726f2ce98 100644
--- a/sound/hda/Makefile
+++ b/sound/hda/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-hda-core-objs := hda_bus_type.o hdac_bus.o hdac_device.o hdac_sysfs.o \
hdac_regmap.o hdac_controller.o hdac_stream.o array.o hdmi_chmap.o
diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
index 978dc1801b3a..f6d2985b2520 100644
--- a/sound/hda/hdac_controller.c
+++ b/sound/hda/hdac_controller.c
@@ -284,6 +284,11 @@ int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus)
dev_dbg(bus->dev, "HDA capability ID: 0x%x\n",
(cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF);
+ if (cur_cap == -1) {
+ dev_dbg(bus->dev, "Invalid capability reg read\n");
+ break;
+ }
+
switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) {
case AZX_ML_CAP_ID:
dev_dbg(bus->dev, "Found ML capability\n");
diff --git a/sound/hda/hdac_sysfs.c b/sound/hda/hdac_sysfs.c
index 42d61bf41969..3c2d45ee6ab8 100644
--- a/sound/hda/hdac_sysfs.c
+++ b/sound/hda/hdac_sysfs.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* sysfs support for HD-audio core device
*/
diff --git a/sound/hda/local.h b/sound/hda/local.h
index 0d5bb159d538..7258fa8ce268 100644
--- a/sound/hda/local.h
+++ b/sound/hda/local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Local helper macros and functions for HD-audio core drivers
*/
diff --git a/sound/hda/trace.h b/sound/hda/trace.h
index e27e2c0b7b17..70af6c815089 100644
--- a/sound/hda/trace.h
+++ b/sound/hda/trace.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM hda
diff --git a/sound/i2c/Makefile b/sound/i2c/Makefile
index 36879bf88700..09978855e08e 100644
--- a/sound/i2c/Makefile
+++ b/sound/i2c/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/i2c/other/Makefile b/sound/i2c/other/Makefile
index 5526b03b95a2..1a4ce1236146 100644
--- a/sound/i2c/other/Makefile
+++ b/sound/i2c/other/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/isa/Makefile b/sound/isa/Makefile
index 9a15f1497b10..5eaddbf4a712 100644
--- a/sound/isa/Makefile
+++ b/sound/isa/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/isa/gus/Makefile b/sound/isa/gus/Makefile
index 6cd4ee03754a..c6f32ffd3420 100644
--- a/sound/isa/gus/Makefile
+++ b/sound/isa/gus/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/isa/msnd/Makefile b/sound/isa/msnd/Makefile
index 2171c0aa2f62..ec231a7b1d5e 100644
--- a/sound/isa/msnd/Makefile
+++ b/sound/isa/msnd/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-msnd-lib-objs := msnd.o msnd_midi.o msnd_pinnacle_mixer.o
snd-msnd-pinnacle-objs := msnd_pinnacle.o
diff --git a/sound/isa/opti9xx/Makefile b/sound/isa/opti9xx/Makefile
index b4d894db257a..a9dcdeb502bd 100644
--- a/sound/isa/opti9xx/Makefile
+++ b/sound/isa/opti9xx/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile
index 08b9fb974658..f174a5b3c8e4 100644
--- a/sound/isa/sb/Makefile
+++ b/sound/isa/sb/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/oss/Makefile b/sound/oss/Makefile
index 9bdbbde2173e..6564eace4749 100644
--- a/sound/oss/Makefile
+++ b/sound/oss/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# Makefile for the Linux sound card driver
#
# 18 Apr 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net>
diff --git a/sound/oss/ad1848.h b/sound/oss/ad1848.h
index b95ebe28d426..390f03e13d09 100644
--- a/sound/oss/ad1848.h
+++ b/sound/oss/ad1848.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/interrupt.h>
diff --git a/sound/oss/bin2hex.c b/sound/oss/bin2hex.c
index b59109eb0db4..26c04ce04d71 100644
--- a/sound/oss/bin2hex.c
+++ b/sound/oss/bin2hex.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h
index 01019f06fa91..c1c52b479da2 100644
--- a/sound/oss/dmasound/dmasound.h
+++ b/sound/oss/dmasound/dmasound.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _dmasound_h_
/*
* linux/sound/oss/dmasound/dmasound.h
diff --git a/sound/oss/hex2hex.c b/sound/oss/hex2hex.c
index 041ef5c52bc2..f76d729b0196 100644
--- a/sound/oss/hex2hex.c
+++ b/sound/oss/hex2hex.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* hex2hex reads stdin in Intel HEX format and produces an
* (unsigned char) array which contains the bytes and writes it
diff --git a/sound/oss/midi_ctrl.h b/sound/oss/midi_ctrl.h
index 3353e5a67c24..240d0c719f1e 100644
--- a/sound/oss/midi_ctrl.h
+++ b/sound/oss/midi_ctrl.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
static unsigned char ctrl_def_values[128] =
{
0x40,0x00,0x40,0x40, 0x40,0x40,0x40,0x7f, /* 0 to 7 */
diff --git a/sound/oss/midi_synth.h b/sound/oss/midi_synth.h
index b64ddd6c4abc..1cf676c7510e 100644
--- a/sound/oss/midi_synth.h
+++ b/sound/oss/midi_synth.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
int midi_synth_ioctl (int dev,
unsigned int cmd, void __user * arg);
int midi_synth_kill_note (int dev, int channel, int note, int velocity);
diff --git a/sound/oss/mpu401.h b/sound/oss/mpu401.h
index 0ad1e9ee74f7..6beb8c2ae405 100644
--- a/sound/oss/mpu401.h
+++ b/sound/oss/mpu401.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* From uart401.c */
int probe_uart401 (struct address_info *hw_config, struct module *owner);
diff --git a/sound/oss/os.h b/sound/oss/os.h
index 0bf89e1d679c..16f3a069b85c 100644
--- a/sound/oss/os.h
+++ b/sound/oss/os.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#define ALLOW_SELECT
#undef NO_INLINE_ASM
#define SHORT_BANNERS
diff --git a/sound/oss/pas2.h b/sound/oss/pas2.h
index d19f757dbd79..57f476238309 100644
--- a/sound/oss/pas2.h
+++ b/sound/oss/pas2.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* From pas_card.c */
int pas_set_intr(int mask);
diff --git a/sound/oss/sb.h b/sound/oss/sb.h
index 77e8891ce333..bb1d18709b36 100644
--- a/sound/oss/sb.h
+++ b/sound/oss/sb.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#define DSP_RESET (devc->base + 0x6)
#define DSP_READ (devc->base + 0xA)
#define DSP_WRITE (devc->base + 0xC)
diff --git a/sound/oss/sb_ess.c b/sound/oss/sb_ess.c
index 57f7d25a2cd3..17e3f14318cd 100644
--- a/sound/oss/sb_ess.c
+++ b/sound/oss/sb_ess.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#undef FKS_LOGGING
#undef FKS_TEST
diff --git a/sound/oss/sb_ess.h b/sound/oss/sb_ess.h
index 38aa072e01f2..1c741212bcfc 100644
--- a/sound/oss/sb_ess.h
+++ b/sound/oss/sb_ess.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Created: 9-Jan-1999 Rolf Fokkens
*/
diff --git a/sound/oss/sleep.h b/sound/oss/sleep.h
index a20fc925a5ce..fd17d44d13dd 100644
--- a/sound/oss/sleep.h
+++ b/sound/oss/sleep.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/wait.h>
/*
diff --git a/sound/oss/sound_calls.h b/sound/oss/sound_calls.h
index 87d8ad4a0340..bcd3f7340ef7 100644
--- a/sound/oss/sound_calls.h
+++ b/sound/oss/sound_calls.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* DMA buffer calls
*/
diff --git a/sound/oss/sound_firmware.h b/sound/oss/sound_firmware.h
index 2be465277ba0..ebcbded0e8c2 100644
--- a/sound/oss/sound_firmware.h
+++ b/sound/oss/sound_firmware.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/fs.h>
/**
diff --git a/sound/oss/tuning.h b/sound/oss/tuning.h
index a73e3dd39f9a..953539931237 100644
--- a/sound/oss/tuning.h
+++ b/sound/oss/tuning.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
static unsigned short semitone_tuning[24] =
{
/* 0 */ 10000, 10595, 11225, 11892, 12599, 13348, 14142, 14983,
diff --git a/sound/oss/ulaw.h b/sound/oss/ulaw.h
index 0ff8c0a3bda0..ee898a0f78ce 100644
--- a/sound/oss/ulaw.h
+++ b/sound/oss/ulaw.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
static unsigned char ulaw_dsp[] = {
3, 7, 11, 15, 19, 23, 27, 31,
35, 39, 43, 47, 51, 55, 59, 63,
diff --git a/sound/oss/v_midi.h b/sound/oss/v_midi.h
index 08e2185ee816..f4fc2bed07f8 100644
--- a/sound/oss/v_midi.h
+++ b/sound/oss/v_midi.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
typedef struct vmidi_devc {
int dev;
diff --git a/sound/oss/waveartist.h b/sound/oss/waveartist.h
index dac4ca910d95..f18d74b26483 100644
--- a/sound/oss/waveartist.h
+++ b/sound/oss/waveartist.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* linux/sound/oss/waveartist.h
*
diff --git a/sound/parisc/harmony.h b/sound/parisc/harmony.h
index 2e434523fedf..f4c29a2e32e8 100644
--- a/sound/parisc/harmony.h
+++ b/sound/parisc/harmony.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* Hewlett-Packard Harmony audio driver
* Copyright (C) 2004, Kyle McMartin <kyle@parisc-linux.org>
*/
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index 54fe325e3aa5..04cac7469139 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/pci/ad1889.h b/sound/pci/ad1889.h
index 5e6dad5341a1..d6e8d6c19adc 100644
--- a/sound/pci/ad1889.h
+++ b/sound/pci/ad1889.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* Analog Devices 1889 audio driver
* Copyright (C) 2004, Kyle McMartin <kyle@parisc-linux.org>
*/
diff --git a/sound/pci/asihpi/hpi_version.h b/sound/pci/asihpi/hpi_version.h
index 6623ab110038..016bc55457e3 100644
--- a/sound/pci/asihpi/hpi_version.h
+++ b/sound/pci/asihpi/hpi_version.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/** HPI Version Definitions
Development releases have odd minor version.
Production releases have even minor version.
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c
index f9b57647b319..1de05383126a 100644
--- a/sound/pci/asihpi/hpifunc.c
+++ b/sound/pci/asihpi/hpifunc.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include "hpi_internal.h"
#include "hpimsginit.h"
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
index 7e3aa50b21f9..5badd08e1d69 100644
--- a/sound/pci/asihpi/hpioctl.c
+++ b/sound/pci/asihpi/hpioctl.c
@@ -103,6 +103,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
void __user *puhr;
union hpi_message_buffer_v1 *hm;
union hpi_response_buffer_v1 *hr;
+ u16 msg_size;
u16 res_max_size;
u32 uncopied_bytes;
int err = 0;
@@ -127,22 +128,25 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
/* Now read the message size and data from user space. */
- if (get_user(hm->h.size, (u16 __user *)puhm)) {
+ if (get_user(msg_size, (u16 __user *)puhm)) {
err = -EFAULT;
goto out;
}
- if (hm->h.size > sizeof(*hm))
- hm->h.size = sizeof(*hm);
+ if (msg_size > sizeof(*hm))
+ msg_size = sizeof(*hm);
/* printk(KERN_INFO "message size %d\n", hm->h.wSize); */
- uncopied_bytes = copy_from_user(hm, puhm, hm->h.size);
+ uncopied_bytes = copy_from_user(hm, puhm, msg_size);
if (uncopied_bytes) {
HPI_DEBUG_LOG(ERROR, "uncopied bytes %d\n", uncopied_bytes);
err = -EFAULT;
goto out;
}
+ /* Override h.size in case it is changed between two userspace fetches */
+ hm->h.size = msg_size;
+
if (get_user(res_max_size, (u16 __user *)puhr)) {
err = -EFAULT;
goto out;
diff --git a/sound/pci/au88x0/Makefile b/sound/pci/au88x0/Makefile
index d0a66bc5d4a7..78ab11562f4d 100644
--- a/sound/pci/au88x0/Makefile
+++ b/sound/pci/au88x0/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-au8810-objs := au8810.o
snd-au8820-objs := au8820.o
snd-au8830-objs := au8830.o
diff --git a/sound/pci/au88x0/au8810.c b/sound/pci/au88x0/au8810.c
index 1b2e34069eb3..b2bfa50bfe30 100644
--- a/sound/pci/au88x0/au8810.c
+++ b/sound/pci/au88x0/au8810.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include "au8810.h"
#include "au88x0.h"
static const struct pci_device_id snd_vortex_ids[] = {
diff --git a/sound/pci/au88x0/au8810.h b/sound/pci/au88x0/au8810.h
index 79fbee3845eb..94f11032067e 100644
--- a/sound/pci/au88x0/au8810.h
+++ b/sound/pci/au88x0/au8810.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
Aureal Advantage Soundcard driver.
*/
diff --git a/sound/pci/au88x0/au8820.c b/sound/pci/au88x0/au8820.c
index 74c53fa5f06b..dbc2263b49c6 100644
--- a/sound/pci/au88x0/au8820.c
+++ b/sound/pci/au88x0/au8820.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include "au8820.h"
#include "au88x0.h"
static const struct pci_device_id snd_vortex_ids[] = {
diff --git a/sound/pci/au88x0/au8820.h b/sound/pci/au88x0/au8820.h
index cafdb9668a34..8a128e8febbb 100644
--- a/sound/pci/au88x0/au8820.h
+++ b/sound/pci/au88x0/au8820.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
Aureal Vortex Soundcard driver.
diff --git a/sound/pci/au88x0/au8830.c b/sound/pci/au88x0/au8830.c
index 56f675aad3ad..e963c4e2f026 100644
--- a/sound/pci/au88x0/au8830.c
+++ b/sound/pci/au88x0/au8830.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include "au8830.h"
#include "au88x0.h"
static const struct pci_device_id snd_vortex_ids[] = {
diff --git a/sound/pci/au88x0/au8830.h b/sound/pci/au88x0/au8830.h
index 999b29ab34ad..40f671ffd45a 100644
--- a/sound/pci/au88x0/au8830.h
+++ b/sound/pci/au88x0/au8830.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
Aureal Vortex Soundcard driver.
diff --git a/sound/pci/au88x0/au88x0_eq.h b/sound/pci/au88x0/au88x0_eq.h
index 474cd0046294..797cdae1db98 100644
--- a/sound/pci/au88x0/au88x0_eq.h
+++ b/sound/pci/au88x0/au88x0_eq.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef AU88X0_EQ_H
#define AU88X0_EQ_H
diff --git a/sound/pci/au88x0/au88x0_eqdata.c b/sound/pci/au88x0/au88x0_eqdata.c
index ce8dca8ce1e2..49a52d298b1a 100644
--- a/sound/pci/au88x0/au88x0_eqdata.c
+++ b/sound/pci/au88x0/au88x0_eqdata.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/* Data structs */
static u16 asEqCoefsZeros[50] = {
diff --git a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c
index a58298cfe7e0..60dd8a091bc3 100644
--- a/sound/pci/au88x0/au88x0_mixer.c
+++ b/sound/pci/au88x0/au88x0_mixer.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Vortex Mixer support.
*
diff --git a/sound/pci/au88x0/au88x0_wt.h b/sound/pci/au88x0/au88x0_wt.h
index 38d98f88a95c..7b2cffad8643 100644
--- a/sound/pci/au88x0/au88x0_wt.h
+++ b/sound/pci/au88x0/au88x0_wt.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/***************************************************************************
* WT register offsets.
*
diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h
index 6f46b97650cc..6f9022784499 100644
--- a/sound/pci/azt3328.h
+++ b/sound/pci/azt3328.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __SOUND_AZT3328_H
#define __SOUND_AZT3328_H
diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h
index 0579daa62215..f4fcdf93f3c8 100644
--- a/sound/pci/cs5535audio/cs5535audio.h
+++ b/sound/pci/cs5535audio/cs5535audio.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __SOUND_CS5535AUDIO_H
#define __SOUND_CS5535AUDIO_H
diff --git a/sound/pci/ctxfi/cttimer.h b/sound/pci/ctxfi/cttimer.h
index 979348229291..9c5cb403b646 100644
--- a/sound/pci/ctxfi/cttimer.h
+++ b/sound/pci/ctxfi/cttimer.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Timer handling
*/
diff --git a/sound/pci/echoaudio/Makefile b/sound/pci/echoaudio/Makefile
index 1361de77e0cd..4865b8fe7434 100644
--- a/sound/pci/echoaudio/Makefile
+++ b/sound/pci/echoaudio/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA Echoaudio soundcard drivers
# Copyright (c) 2003 by Giuliano Pochini <pochini@shiny.it>
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 7326695bca33..d68f99e076a8 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -1272,11 +1272,11 @@ static int snd_echo_mixer_info(struct snd_kcontrol *kcontrol,
chip = snd_kcontrol_chip(kcontrol);
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
uinfo->value.integer.min = ECHOGAIN_MINOUT;
uinfo->value.integer.max = ECHOGAIN_MAXOUT;
uinfo->dimen.d[0] = num_busses_out(chip);
uinfo->dimen.d[1] = num_busses_in(chip);
- uinfo->count = uinfo->dimen.d[0] * uinfo->dimen.d[1];
return 0;
}
@@ -1344,11 +1344,11 @@ static int snd_echo_vmixer_info(struct snd_kcontrol *kcontrol,
chip = snd_kcontrol_chip(kcontrol);
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
uinfo->value.integer.min = ECHOGAIN_MINOUT;
uinfo->value.integer.max = ECHOGAIN_MAXOUT;
uinfo->dimen.d[0] = num_busses_out(chip);
uinfo->dimen.d[1] = num_pipes_out(chip);
- uinfo->count = uinfo->dimen.d[0] * uinfo->dimen.d[1];
return 0;
}
@@ -1728,6 +1728,7 @@ static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 96;
uinfo->value.integer.min = ECHOGAIN_MINOUT;
uinfo->value.integer.max = 0;
#ifdef ECHOCARD_HAS_VMIXER
@@ -1737,7 +1738,6 @@ static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol,
#endif
uinfo->dimen.d[1] = 16; /* 16 channels */
uinfo->dimen.d[2] = 2; /* 0=level, 1=peak */
- uinfo->count = uinfo->dimen.d[0] * uinfo->dimen.d[1] * uinfo->dimen.d[2];
return 0;
}
diff --git a/sound/pci/emu10k1/Makefile b/sound/pci/emu10k1/Makefile
index 29b44ca27010..17d5527be319 100644
--- a/sound/pci/emu10k1/Makefile
+++ b/sound/pci/emu10k1/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 6d83c6e0396a..b57432f00056 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-hda-intel-objs := hda_intel.o
snd-hda-tegra-objs := hda_tegra.o
diff --git a/sound/pci/hda/dell_wmi_helper.c b/sound/pci/hda/dell_wmi_helper.c
index 44b1e15682b9..1b48a8c19d28 100644
--- a/sound/pci/hda/dell_wmi_helper.c
+++ b/sound/pci/hda/dell_wmi_helper.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/* Helper functions for Dell Mic Mute LED control;
* to be included from codec driver
*/
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 3db26c451837..a0989d231fd0 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1803,36 +1803,6 @@ static int check_slave_present(struct hda_codec *codec,
return 1;
}
-/* guess the value corresponding to 0dB */
-static int get_kctl_0dB_offset(struct hda_codec *codec,
- struct snd_kcontrol *kctl, int *step_to_check)
-{
- int _tlv[4];
- const int *tlv = NULL;
- int val = -1;
-
- if ((kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) &&
- kctl->tlv.c == snd_hda_mixer_amp_tlv) {
- get_ctl_amp_tlv(kctl, _tlv);
- tlv = _tlv;
- } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ)
- tlv = kctl->tlv.p;
- if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE) {
- int step = tlv[3];
- step &= ~TLV_DB_SCALE_MUTE;
- if (!step)
- return -1;
- if (*step_to_check && *step_to_check != step) {
- codec_err(codec, "Mismatching dB step for vmaster slave (%d!=%d)\n",
-- *step_to_check, step);
- return -1;
- }
- *step_to_check = step;
- val = -tlv[2] / step;
- }
- return val;
-}
-
/* call kctl->put with the given value(s) */
static int put_kctl_with_value(struct snd_kcontrol *kctl, int val)
{
@@ -1847,19 +1817,58 @@ static int put_kctl_with_value(struct snd_kcontrol *kctl, int val)
return 0;
}
-/* initialize the slave volume with 0dB */
-static int init_slave_0dB(struct hda_codec *codec,
- void *data, struct snd_kcontrol *slave)
+struct slave_init_arg {
+ struct hda_codec *codec;
+ int step;
+};
+
+/* initialize the slave volume with 0dB via snd_ctl_apply_vmaster_slaves() */
+static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg)
{
- int offset = get_kctl_0dB_offset(codec, slave, data);
- if (offset > 0)
- put_kctl_with_value(slave, offset);
+ struct slave_init_arg *arg = _arg;
+ int _tlv[4];
+ const int *tlv = NULL;
+ int step;
+ int val;
+
+ if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
+ if (kctl->tlv.c != snd_hda_mixer_amp_tlv) {
+ codec_err(arg->codec,
+ "Unexpected TLV callback for slave %s:%d\n",
+ kctl->id.name, kctl->id.index);
+ return 0; /* ignore */
+ }
+ get_ctl_amp_tlv(kctl, _tlv);
+ tlv = _tlv;
+ } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ)
+ tlv = kctl->tlv.p;
+
+ if (!tlv || tlv[0] != SNDRV_CTL_TLVT_DB_SCALE)
+ return 0;
+
+ step = tlv[3];
+ step &= ~TLV_DB_SCALE_MUTE;
+ if (!step)
+ return 0;
+ if (arg->step && arg->step != step) {
+ codec_err(arg->codec,
+ "Mismatching dB step for vmaster slave (%d!=%d)\n",
+ arg->step, step);
+ return 0;
+ }
+
+ arg->step = step;
+ val = -tlv[2] / step;
+ if (val > 0) {
+ put_kctl_with_value(kctl, val);
+ return val;
+ }
+
return 0;
}
-/* unmute the slave */
-static int init_slave_unmute(struct hda_codec *codec,
- void *data, struct snd_kcontrol *slave)
+/* unmute the slave via snd_ctl_apply_vmaster_slaves() */
+static int init_slave_unmute(struct snd_kcontrol *slave, void *_arg)
{
return put_kctl_with_value(slave, 1);
}
@@ -1919,9 +1928,13 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
/* init with master mute & zero volume */
put_kctl_with_value(kctl, 0);
if (init_slave_vol) {
- int step = 0;
- map_slaves(codec, slaves, suffix,
- tlv ? init_slave_0dB : init_slave_unmute, &step);
+ struct slave_init_arg arg = {
+ .codec = codec,
+ .step = 0,
+ };
+ snd_ctl_apply_vmaster_slaves(kctl,
+ tlv ? init_slave_0dB : init_slave_unmute,
+ &arg);
}
if (ctl_ret)
diff --git a/sound/pci/hda/hda_controller_trace.h b/sound/pci/hda/hda_controller_trace.h
index 3e18d99bfb70..bf48304e230a 100644
--- a/sound/pci/hda/hda_controller_trace.h
+++ b/sound/pci/hda/hda_controller_trace.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM hda_controller
#define TRACE_INCLUDE_FILE hda_controller_trace
diff --git a/sound/pci/hda/hda_intel_trace.h b/sound/pci/hda/hda_intel_trace.h
index 0922d8b1b17d..73a7adfa192d 100644
--- a/sound/pci/hda/hda_intel_trace.h
+++ b/sound/pci/hda/hda_intel_trace.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM hda_intel
#define TRACE_INCLUDE_FILE hda_intel_trace
diff --git a/sound/pci/hda/local.h b/sound/pci/hda/local.h
index 28cb7f98982e..3b8b7d78f9e0 100644
--- a/sound/pci/hda/local.h
+++ b/sound/pci/hda/local.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
*/
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 2b64fabd5faa..c19c81d230bd 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -906,6 +906,7 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
hda_nid_t pin_nid, u32 stream_tag, int format)
{
struct hdmi_spec *spec = codec->spec;
+ unsigned int param;
int err;
err = spec->ops.pin_hbr_setup(codec, pin_nid, is_hbr_format(format));
@@ -915,6 +916,26 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
return err;
}
+ if (is_haswell_plus(codec)) {
+
+ /*
+ * on recent platforms IEC Coding Type is required for HBR
+ * support, read current Digital Converter settings and set
+ * ICT bitfield if needed.
+ */
+ param = snd_hda_codec_read(codec, cvt_nid, 0,
+ AC_VERB_GET_DIGI_CONVERT_1, 0);
+
+ param = (param >> 16) & ~(AC_DIG3_ICT);
+
+ /* on recent platforms ICT mode is required for HBR support */
+ if (is_hbr_format(format))
+ param |= 0x1;
+
+ snd_hda_codec_write(codec, cvt_nid, 0,
+ AC_VERB_SET_DIGI_CONVERT_3, param);
+ }
+
snd_hda_codec_setup_stream(codec, cvt_nid, stream_tag, 0, format);
return 0;
}
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 0ce71111b4e3..546d515f3c1f 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -327,6 +327,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
case 0x10ec0215:
case 0x10ec0225:
case 0x10ec0233:
+ case 0x10ec0236:
case 0x10ec0255:
case 0x10ec0256:
case 0x10ec0282:
@@ -911,6 +912,7 @@ static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
{ 0x10ec0275, 0x1028, 0, "ALC3260" },
{ 0x10ec0899, 0x1028, 0, "ALC3861" },
{ 0x10ec0298, 0x1028, 0, "ALC3266" },
+ { 0x10ec0236, 0x1028, 0, "ALC3204" },
{ 0x10ec0256, 0x1028, 0, "ALC3246" },
{ 0x10ec0225, 0x1028, 0, "ALC3253" },
{ 0x10ec0295, 0x1028, 0, "ALC3254" },
@@ -3930,6 +3932,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
alc_process_coef_fw(codec, coef0255_1);
alc_process_coef_fw(codec, coef0255);
break;
+ case 0x10ec0236:
case 0x10ec0256:
alc_process_coef_fw(codec, coef0256);
alc_process_coef_fw(codec, coef0255);
@@ -4028,6 +4031,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
};
switch (codec->core.vendor_id) {
+ case 0x10ec0236:
case 0x10ec0255:
case 0x10ec0256:
alc_write_coef_idx(codec, 0x45, 0xc489);
@@ -4160,6 +4164,7 @@ static void alc_headset_mode_default(struct hda_codec *codec)
alc_process_coef_fw(codec, alc225_pre_hsmode);
alc_process_coef_fw(codec, coef0225);
break;
+ case 0x10ec0236:
case 0x10ec0255:
case 0x10ec0256:
alc_process_coef_fw(codec, coef0255);
@@ -4256,6 +4261,7 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
case 0x10ec0255:
alc_process_coef_fw(codec, coef0255);
break;
+ case 0x10ec0236:
case 0x10ec0256:
alc_process_coef_fw(codec, coef0256);
break;
@@ -4366,6 +4372,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
case 0x10ec0255:
alc_process_coef_fw(codec, coef0255);
break;
+ case 0x10ec0236:
case 0x10ec0256:
alc_process_coef_fw(codec, coef0256);
break;
@@ -4451,6 +4458,7 @@ static void alc_determine_headset_type(struct hda_codec *codec)
};
switch (codec->core.vendor_id) {
+ case 0x10ec0236:
case 0x10ec0255:
case 0x10ec0256:
alc_process_coef_fw(codec, coef0255);
@@ -4705,6 +4713,7 @@ static void alc255_set_default_jack_type(struct hda_codec *codec)
case 0x10ec0255:
alc_process_coef_fw(codec, alc255fw);
break;
+ case 0x10ec0236:
case 0x10ec0256:
alc_process_coef_fw(codec, alc256fw);
break;
@@ -6419,6 +6428,14 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
ALC225_STANDARD_PINS,
{0x12, 0xb7a60130},
{0x1b, 0x90170110}),
+ SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ {0x12, 0x90a60140},
+ {0x14, 0x90170110},
+ {0x21, 0x02211020}),
+ SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ {0x12, 0x90a60140},
+ {0x14, 0x90170150},
+ {0x21, 0x02211020}),
SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
{0x14, 0x90170110},
{0x21, 0x02211020}),
@@ -6806,6 +6823,7 @@ static int patch_alc269(struct hda_codec *codec)
case 0x10ec0255:
spec->codec_variant = ALC269_TYPE_ALC255;
break;
+ case 0x10ec0236:
case 0x10ec0256:
spec->codec_variant = ALC269_TYPE_ALC256;
spec->shutup = alc256_shutup;
@@ -7857,6 +7875,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
+ HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
diff --git a/sound/pci/hda/thinkpad_helper.c b/sound/pci/hda/thinkpad_helper.c
index 4d9d320a7971..65bb3ac6af4c 100644
--- a/sound/pci/hda/thinkpad_helper.c
+++ b/sound/pci/hda/thinkpad_helper.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/* Helper functions for Thinkpad LED control;
* to be included from codec driver
*/
diff --git a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile
index 7e50c1324556..1196f22a9b45 100644
--- a/sound/pci/ice1712/Makefile
+++ b/sound/pci/ice1712/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/pci/ice1712/juli.h b/sound/pci/ice1712/juli.h
index d9f8534fd92e..9c22d4e73ee3 100644
--- a/sound/pci/ice1712/juli.h
+++ b/sound/pci/ice1712/juli.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __SOUND_JULI_H
#define __SOUND_JULI_H
diff --git a/sound/pci/ice1712/maya44.h b/sound/pci/ice1712/maya44.h
index eafd03a8f4b5..f5a97d987a6f 100644
--- a/sound/pci/ice1712/maya44.h
+++ b/sound/pci/ice1712/maya44.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __SOUND_MAYA44_H
#define __SOUND_MAYA44_H
diff --git a/sound/pci/ice1712/prodigy192.h b/sound/pci/ice1712/prodigy192.h
index 16a53b459c72..7bfd769ba982 100644
--- a/sound/pci/ice1712/prodigy192.h
+++ b/sound/pci/ice1712/prodigy192.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __SOUND_PRODIGY192_H
#define __SOUND_PRODIGY192_H
diff --git a/sound/pci/ice1712/psc724.h b/sound/pci/ice1712/psc724.h
index 858e5fd0eebb..e6ce335ae87e 100644
--- a/sound/pci/ice1712/psc724.h
+++ b/sound/pci/ice1712/psc724.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __SOUND_PSC724_H
#define __SOUND_PSC724_H
diff --git a/sound/pci/ice1712/quartet.h b/sound/pci/ice1712/quartet.h
index 80809b72439a..a1c2fe27185d 100644
--- a/sound/pci/ice1712/quartet.h
+++ b/sound/pci/ice1712/quartet.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __SOUND_QTET_H
#define __SOUND_QTET_H
diff --git a/sound/pci/ice1712/se.h b/sound/pci/ice1712/se.h
index 0b0a9dabdcfb..61348ecef1e0 100644
--- a/sound/pci/ice1712/se.h
+++ b/sound/pci/ice1712/se.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __SOUND_SE_H
#define __SOUND_SE_H
diff --git a/sound/pci/ice1712/stac946x.h b/sound/pci/ice1712/stac946x.h
index 5b390952d0e4..58f9f17a258a 100644
--- a/sound/pci/ice1712/stac946x.h
+++ b/sound/pci/ice1712/stac946x.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __SOUND_STAC946X_H
#define __SOUND_STAC946X_H
diff --git a/sound/pci/ice1712/wtm.h b/sound/pci/ice1712/wtm.h
index 423c1a204c0b..1cfcbde15f42 100644
--- a/sound/pci/ice1712/wtm.h
+++ b/sound/pci/ice1712/wtm.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __SOUND_WTM_H
#define __SOUND_WTM_H
diff --git a/sound/pci/nm256/nm256_coef.c b/sound/pci/nm256/nm256_coef.c
index 747d5d6ccfa0..c757252119b1 100644
--- a/sound/pci/nm256/nm256_coef.c
+++ b/sound/pci/nm256/nm256_coef.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#define NM_TOTAL_COEFF_COUNT 0x3158
static char coefficients[NM_TOTAL_COEFF_COUNT * 4] = {
diff --git a/sound/pci/oxygen/Makefile b/sound/pci/oxygen/Makefile
index ab085d753661..0dfc4f840992 100644
--- a/sound/pci/oxygen/Makefile
+++ b/sound/pci/oxygen/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o
snd-oxygen-objs := oxygen.o xonar_dg_mixer.o xonar_dg.o
snd-se6x-objs := se6x.o
diff --git a/sound/pci/oxygen/ak4396.h b/sound/pci/oxygen/ak4396.h
index 551c1cf8e2e0..a51223461b11 100644
--- a/sound/pci/oxygen/ak4396.h
+++ b/sound/pci/oxygen/ak4396.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef AK4396_H_INCLUDED
#define AK4396_H_INCLUDED
diff --git a/sound/pci/oxygen/cm9780.h b/sound/pci/oxygen/cm9780.h
index 144596799676..7efb119d1763 100644
--- a/sound/pci/oxygen/cm9780.h
+++ b/sound/pci/oxygen/cm9780.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef CM9780_H_INCLUDED
#define CM9780_H_INCLUDED
diff --git a/sound/pci/oxygen/cs2000.h b/sound/pci/oxygen/cs2000.h
index c3501bdb5edc..aca04794ce28 100644
--- a/sound/pci/oxygen/cs2000.h
+++ b/sound/pci/oxygen/cs2000.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef CS2000_H_INCLUDED
#define CS2000_H_INCLUDED
diff --git a/sound/pci/oxygen/cs4245.h b/sound/pci/oxygen/cs4245.h
index 99098657695a..bb9f2c5b5819 100644
--- a/sound/pci/oxygen/cs4245.h
+++ b/sound/pci/oxygen/cs4245.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#define CS4245_CHIP_ID 0x01
#define CS4245_POWER_CTRL 0x02
#define CS4245_DAC_CTRL_1 0x03
diff --git a/sound/pci/oxygen/cs4362a.h b/sound/pci/oxygen/cs4362a.h
index 6a4fedf5e1ec..1aef15e04dfb 100644
--- a/sound/pci/oxygen/cs4362a.h
+++ b/sound/pci/oxygen/cs4362a.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* register 01h */
#define CS4362A_PDN 0x01
#define CS4362A_DAC1_DIS 0x02
diff --git a/sound/pci/oxygen/cs4398.h b/sound/pci/oxygen/cs4398.h
index 5faf5efc8826..76cb9d7af0d7 100644
--- a/sound/pci/oxygen/cs4398.h
+++ b/sound/pci/oxygen/cs4398.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* register 1 */
#define CS4398_REV_MASK 0x07
#define CS4398_PART_MASK 0xf8
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index 293d0b9a50c3..06bf7e5744d0 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef OXYGEN_H_INCLUDED
#define OXYGEN_H_INCLUDED
diff --git a/sound/pci/oxygen/oxygen_regs.h b/sound/pci/oxygen/oxygen_regs.h
index 8c191badaae8..eca9d943f5c7 100644
--- a/sound/pci/oxygen/oxygen_regs.h
+++ b/sound/pci/oxygen/oxygen_regs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef OXYGEN_REGS_H_INCLUDED
#define OXYGEN_REGS_H_INCLUDED
diff --git a/sound/pci/oxygen/pcm1796.h b/sound/pci/oxygen/pcm1796.h
index 698bf46c710c..34d07dd2d22e 100644
--- a/sound/pci/oxygen/pcm1796.h
+++ b/sound/pci/oxygen/pcm1796.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef PCM1796_H_INCLUDED
#define PCM1796_H_INCLUDED
diff --git a/sound/pci/oxygen/wm8766.h b/sound/pci/oxygen/wm8766.h
index e0e849a7eaeb..be83ad49dbb1 100644
--- a/sound/pci/oxygen/wm8766.h
+++ b/sound/pci/oxygen/wm8766.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef WM8766_H_INCLUDED
#define WM8766_H_INCLUDED
diff --git a/sound/pci/oxygen/wm8785.h b/sound/pci/oxygen/wm8785.h
index 8c23e315ae66..21b932566598 100644
--- a/sound/pci/oxygen/wm8785.h
+++ b/sound/pci/oxygen/wm8785.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef WM8785_H_INCLUDED
#define WM8785_H_INCLUDED
diff --git a/sound/pci/oxygen/xonar.h b/sound/pci/oxygen/xonar.h
index 0434c207e811..3e373880c187 100644
--- a/sound/pci/oxygen/xonar.h
+++ b/sound/pci/oxygen/xonar.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef XONAR_H_INCLUDED
#define XONAR_H_INCLUDED
diff --git a/sound/pci/oxygen/xonar_dg.h b/sound/pci/oxygen/xonar_dg.h
index d461df357aa1..7a1e8f9c48e7 100644
--- a/sound/pci/oxygen/xonar_dg.h
+++ b/sound/pci/oxygen/xonar_dg.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef XONAR_DG_H_INCLUDED
#define XONAR_DG_H_INCLUDED
diff --git a/sound/pci/rme9652/Makefile b/sound/pci/rme9652/Makefile
index dcba56040205..a3351447ddc0 100644
--- a/sound/pci/rme9652/Makefile
+++ b/sound/pci/rme9652/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/ppc/tumbler_volume.h b/sound/ppc/tumbler_volume.h
index ef8d85d58b02..549ec6a31a98 100644
--- a/sound/ppc/tumbler_volume.h
+++ b/sound/ppc/tumbler_volume.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* volume tables, taken from TAS3001c data manual */
/* volume gain values */
/* 0 = -70 dB, 175 = 18.0 dB in 0.5 dB step */
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 95f2a73f9aed..5327f4d6c668 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
snd-soc-core-objs += soc-pcm.o soc-io.o soc-devres.o soc-ops.o
snd-soc-core-$(CONFIG_SND_SOC_COMPRESS) += soc-compress.o
diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h
index 330832ef4e5e..9d338216c5ae 100644
--- a/sound/soc/amd/acp.h
+++ b/sound/soc/amd/acp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ACP_HW_H
#define __ACP_HW_H
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
index 67e10cbd4ed7..4440646416e8 100644
--- a/sound/soc/atmel/Makefile
+++ b/sound/soc/atmel/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# AT91 Platform Support
snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o
snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o
diff --git a/sound/soc/atmel/atmel-classd.h b/sound/soc/atmel/atmel-classd.h
index 73f8fdd1ca83..0f2e25aeb458 100644
--- a/sound/soc/atmel/atmel-classd.h
+++ b/sound/soc/atmel/atmel-classd.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ATMEL_CLASSD_H_
#define __ATMEL_CLASSD_H_
diff --git a/sound/soc/atmel/atmel-pdmic.h b/sound/soc/atmel/atmel-pdmic.h
index 4527ac741919..1dd35187102c 100644
--- a/sound/soc/atmel/atmel-pdmic.h
+++ b/sound/soc/atmel/atmel-pdmic.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ATMEL_PDMIC_H_
#define __ATMEL_PDMIC_H_
diff --git a/sound/soc/au1x/Makefile b/sound/soc/au1x/Makefile
index 920710514ea0..33183d7fe057 100644
--- a/sound/soc/au1x/Makefile
+++ b/sound/soc/au1x/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# Au1200/Au1550 PSC audio
snd-soc-au1xpsc-dbdma-objs := dbdma2.o
snd-soc-au1xpsc-i2s-objs := psc-i2s.o
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile
index f21e948b2e9b..ebeb6a9cedd2 100644
--- a/sound/soc/blackfin/Makefile
+++ b/sound/soc/blackfin/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# Blackfin Platform Support
snd-bf5xx-ac97-objs := bf5xx-ac97-pcm.o
snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o
diff --git a/sound/soc/cirrus/Makefile b/sound/soc/cirrus/Makefile
index 5514146cbdf0..bfb8dc409f53 100644
--- a/sound/soc/cirrus/Makefile
+++ b/sound/soc/cirrus/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# EP93xx Platform Support
snd-soc-ep93xx-objs := ep93xx-pcm.o
snd-soc-ep93xx-i2s-objs := ep93xx-i2s.o
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 77c18189c9ad..05018b7ca72b 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-soc-88pm860x-objs := 88pm860x-codec.o
snd-soc-ab8500-codec-objs := ab8500-codec.o
snd-soc-ac97-objs := ac97.o
diff --git a/sound/soc/codecs/adau-utils.h b/sound/soc/codecs/adau-utils.h
index 939b5f37762f..bf5947b35390 100644
--- a/sound/soc/codecs/adau-utils.h
+++ b/sound/soc/codecs/adau-utils.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef SOUND_SOC_CODECS_ADAU_PLL_H
#define SOUND_SOC_CODECS_ADAU_PLL_H
diff --git a/sound/soc/codecs/adau1373.h b/sound/soc/codecs/adau1373.h
index c6ab5530760c..56320d5e32d8 100644
--- a/sound/soc/codecs/adau1373.h
+++ b/sound/soc/codecs/adau1373.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ADAU1373_H__
#define __ADAU1373_H__
diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c
index 2c1bd2763864..6758f789b712 100644
--- a/sound/soc/codecs/adau17x1.c
+++ b/sound/soc/codecs/adau17x1.c
@@ -90,6 +90,27 @@ static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,
return 0;
}
+static int adau17x1_adc_fixup(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct adau *adau = snd_soc_codec_get_drvdata(codec);
+
+ /*
+ * If we are capturing, toggle the ADOSR bit in Converter Control 0 to
+ * avoid losing SNR (workaround from ADI). This must be done after
+ * the ADC(s) have been enabled. According to the data sheet, it is
+ * normally illegal to set this bit when the sampling rate is 96 kHz,
+ * but according to ADI it is acceptable for this workaround.
+ */
+ regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0,
+ ADAU17X1_CONVERTER0_ADOSR, ADAU17X1_CONVERTER0_ADOSR);
+ regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0,
+ ADAU17X1_CONVERTER0_ADOSR, 0);
+
+ return 0;
+}
+
static const char * const adau17x1_mono_stereo_text[] = {
"Stereo",
"Mono Left Channel (L+R)",
@@ -121,7 +142,8 @@ static const struct snd_soc_dapm_widget adau17x1_dapm_widgets[] = {
SND_SOC_DAPM_MUX("Right DAC Mode Mux", SND_SOC_NOPM, 0, 0,
&adau17x1_dac_mode_mux),
- SND_SOC_DAPM_ADC("Left Decimator", NULL, ADAU17X1_ADC_CONTROL, 0, 0),
+ SND_SOC_DAPM_ADC_E("Left Decimator", NULL, ADAU17X1_ADC_CONTROL, 0, 0,
+ adau17x1_adc_fixup, SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_ADC("Right Decimator", NULL, ADAU17X1_ADC_CONTROL, 1, 0),
SND_SOC_DAPM_DAC("Left DAC", NULL, ADAU17X1_DAC_CONTROL0, 0, 0),
SND_SOC_DAPM_DAC("Right DAC", NULL, ADAU17X1_DAC_CONTROL0, 1, 0),
diff --git a/sound/soc/codecs/adau17x1.h b/sound/soc/codecs/adau17x1.h
index bf04b7efee40..eaf8f933bab8 100644
--- a/sound/soc/codecs/adau17x1.h
+++ b/sound/soc/codecs/adau17x1.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ADAU17X1_H__
#define __ADAU17X1_H__
@@ -129,5 +130,7 @@ bool adau17x1_has_dsp(struct adau *adau);
#define ADAU17X1_CONVERTER0_CONVSR_MASK 0x7
+#define ADAU17X1_CONVERTER0_ADOSR BIT(3)
+
#endif
diff --git a/sound/soc/codecs/cs4271.h b/sound/soc/codecs/cs4271.h
index 9adad8eefdc9..290283a9149e 100644
--- a/sound/soc/codecs/cs4271.h
+++ b/sound/soc/codecs/cs4271.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _CS4271_PRIV_H
#define _CS4271_PRIV_H
diff --git a/sound/soc/codecs/es8328.h b/sound/soc/codecs/es8328.h
index 8930322d712b..9109f6b5b045 100644
--- a/sound/soc/codecs/es8328.h
+++ b/sound/soc/codecs/es8328.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* es8328.h -- ES8328 ALSA SoC Audio driver
*/
diff --git a/sound/soc/codecs/hdac_hdmi.h b/sound/soc/codecs/hdac_hdmi.h
index dfc3a9cf7199..b5b57a5cbbfd 100644
--- a/sound/soc/codecs/hdac_hdmi.h
+++ b/sound/soc/codecs/hdac_hdmi.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __HDAC_HDMI_H__
#define __HDAC_HDMI_H__
diff --git a/sound/soc/codecs/inno_rk3036.h b/sound/soc/codecs/inno_rk3036.h
index da759c6c7501..44bb2404198d 100644
--- a/sound/soc/codecs/inno_rk3036.h
+++ b/sound/soc/codecs/inno_rk3036.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Driver of Inno Codec for rk3036 by Rockchip Inc.
*
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index 13bcfb1ef9b4..f5075d1f79e6 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -2115,7 +2115,7 @@ static void max98090_pll_work(struct work_struct *work)
if (!snd_soc_codec_is_active(codec))
return;
- dev_info(codec->dev, "PLL unlocked\n");
+ dev_info_ratelimited(codec->dev, "PLL unlocked\n");
/* Toggle shutdown OFF then ON */
snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN,
diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c
index 549c269acc7d..a42f8ebb9670 100644
--- a/sound/soc/codecs/msm8916-wcd-analog.c
+++ b/sound/soc/codecs/msm8916-wcd-analog.c
@@ -104,7 +104,7 @@
#define CDC_A_MICB_1_VAL (0xf141)
#define MICB_MIN_VAL 1600
#define MICB_STEP_SIZE 50
-#define MICB_VOLTAGE_REGVAL(v) ((v - MICB_MIN_VAL)/MICB_STEP_SIZE)
+#define MICB_VOLTAGE_REGVAL(v) (((v - MICB_MIN_VAL)/MICB_STEP_SIZE) << 3)
#define MICB_1_VAL_MICB_OUT_VAL_MASK GENMASK(7, 3)
#define MICB_1_VAL_MICB_OUT_VAL_V2P70V ((0x16) << 3)
#define MICB_1_VAL_MICB_OUT_VAL_V1P80V ((0x4) << 3)
@@ -349,8 +349,9 @@ static void pm8916_wcd_analog_micbias_enable(struct snd_soc_codec *codec)
| MICB_1_CTL_EXT_PRECHARG_EN_ENABLE);
if (wcd->micbias_mv) {
- snd_soc_write(codec, CDC_A_MICB_1_VAL,
- MICB_VOLTAGE_REGVAL(wcd->micbias_mv));
+ snd_soc_update_bits(codec, CDC_A_MICB_1_VAL,
+ MICB_1_VAL_MICB_OUT_VAL_MASK,
+ MICB_VOLTAGE_REGVAL(wcd->micbias_mv));
/*
* Special headset needs MICBIAS as 2.7V so wait for
* 50 msec for the MICBIAS to reach 2.7 volts.
diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c
index 66df8f810f0d..a10a724eb448 100644
--- a/sound/soc/codecs/msm8916-wcd-digital.c
+++ b/sound/soc/codecs/msm8916-wcd-digital.c
@@ -238,7 +238,7 @@ static const struct soc_enum rx_mix2_inp1_chain_enum = SOC_ENUM_SINGLE(
static const struct soc_enum rx2_mix1_inp_enum[] = {
SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B1_CTL, 0, 6, rx_mix1_text),
SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B1_CTL, 3, 6, rx_mix1_text),
- SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B1_CTL, 0, 6, rx_mix1_text),
+ SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B2_CTL, 0, 6, rx_mix1_text),
};
/* RX2 MIX2 */
@@ -249,7 +249,7 @@ static const struct soc_enum rx2_mix2_inp1_chain_enum = SOC_ENUM_SINGLE(
static const struct soc_enum rx3_mix1_inp_enum[] = {
SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B1_CTL, 0, 6, rx_mix1_text),
SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B1_CTL, 3, 6, rx_mix1_text),
- SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B1_CTL, 0, 6, rx_mix1_text),
+ SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B2_CTL, 0, 6, rx_mix1_text),
};
/* DEC */
diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c
index ed6e5373916c..12f2ecf3a4fe 100644
--- a/sound/soc/codecs/rt5514-spi.c
+++ b/sound/soc/codecs/rt5514-spi.c
@@ -145,9 +145,8 @@ done:
mutex_unlock(&rt5514_dsp->dma_lock);
}
-static irqreturn_t rt5514_spi_irq(int irq, void *data)
+static void rt5514_schedule_copy(struct rt5514_dsp *rt5514_dsp)
{
- struct rt5514_dsp *rt5514_dsp = data;
u8 buf[8];
rt5514_dsp->get_size = 0;
@@ -180,6 +179,13 @@ static irqreturn_t rt5514_spi_irq(int irq, void *data)
if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit &&
rt5514_dsp->buf_rp && rt5514_dsp->buf_size)
schedule_delayed_work(&rt5514_dsp->copy_work, 0);
+}
+
+static irqreturn_t rt5514_spi_irq(int irq, void *data)
+{
+ struct rt5514_dsp *rt5514_dsp = data;
+
+ rt5514_schedule_copy(rt5514_dsp);
return IRQ_HANDLED;
}
@@ -199,12 +205,19 @@ static int rt5514_spi_hw_params(struct snd_pcm_substream *substream,
struct rt5514_dsp *rt5514_dsp =
snd_soc_platform_get_drvdata(rtd->platform);
int ret;
+ u8 buf[8];
mutex_lock(&rt5514_dsp->dma_lock);
ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
params_buffer_bytes(hw_params));
rt5514_dsp->substream = substream;
rt5514_dsp->dma_offset = 0;
+
+ /* Read IRQ status and schedule copy accordingly. */
+ rt5514_spi_burst_read(RT5514_IRQ_CTRL, (u8 *)&buf, sizeof(buf));
+ if (buf[0] & RT5514_IRQ_STATUS_BIT)
+ rt5514_schedule_copy(rt5514_dsp);
+
mutex_unlock(&rt5514_dsp->dma_lock);
return ret;
diff --git a/sound/soc/codecs/rt5514-spi.h b/sound/soc/codecs/rt5514-spi.h
index a6434ee6ff03..c1a36647c119 100644
--- a/sound/soc/codecs/rt5514-spi.h
+++ b/sound/soc/codecs/rt5514-spi.h
@@ -20,6 +20,9 @@
#define RT5514_BUFFER_VOICE_BASE 0x18000200
#define RT5514_BUFFER_VOICE_LIMIT 0x18000204
#define RT5514_BUFFER_VOICE_WP 0x1800020c
+#define RT5514_IRQ_CTRL 0x18002094
+
+#define RT5514_IRQ_STATUS_BIT (0x1 << 5)
/* SPI Command */
enum {
diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c
index 0945d212b8dc..d7956ababd11 100644
--- a/sound/soc/codecs/rt5514.c
+++ b/sound/soc/codecs/rt5514.c
@@ -338,39 +338,6 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
fw = NULL;
}
- if (rt5514->model_buf && rt5514->model_len) {
-#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
- int ret;
-
- ret = rt5514_spi_burst_write(0x4ff80000,
- rt5514->model_buf,
- ((rt5514->model_len / 8) + 1) * 8);
- if (ret) {
- dev_err(codec->dev,
- "Model load failed %d\n", ret);
- return ret;
- }
-#else
- dev_err(codec->dev,
- "No SPI driver for loading firmware\n");
-#endif
- } else {
- request_firmware(&fw, RT5514_FIRMWARE3,
- codec->dev);
- if (fw) {
-#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
- rt5514_spi_burst_write(0x4ff80000,
- fw->data,
- ((fw->size/8)+1)*8);
-#else
- dev_err(codec->dev,
- "No SPI driver to load fw\n");
-#endif
- release_firmware(fw);
- fw = NULL;
- }
- }
-
/* DSP run */
regmap_write(rt5514->i2c_regmap, 0x18002f00,
0x00055148);
@@ -385,34 +352,6 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
return 0;
}
-static int rt5514_hotword_model_put(struct snd_kcontrol *kcontrol,
- const unsigned int __user *bytes, unsigned int size)
-{
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
- struct snd_soc_codec *codec = rt5514->codec;
- int ret = 0;
-
- if (rt5514->model_buf || rt5514->model_len < size) {
- if (rt5514->model_buf)
- devm_kfree(codec->dev, rt5514->model_buf);
- rt5514->model_buf = devm_kmalloc(codec->dev, size, GFP_KERNEL);
- if (!rt5514->model_buf) {
- ret = -ENOMEM;
- goto done;
- }
- }
-
- /* Skips the TLV header. */
- bytes += 2;
-
- if (copy_from_user(rt5514->model_buf, bytes, size))
- ret = -EFAULT;
-done:
- rt5514->model_len = (ret ? 0 : size);
- return ret;
-}
-
static const struct snd_kcontrol_new rt5514_snd_controls[] = {
SOC_DOUBLE_TLV("MIC Boost Volume", RT5514_ANA_CTRL_MICBST,
RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv),
@@ -424,8 +363,6 @@ static const struct snd_kcontrol_new rt5514_snd_controls[] = {
adc_vol_tlv),
SOC_SINGLE_EXT("DSP Voice Wake Up", SND_SOC_NOPM, 0, 1, 0,
rt5514_dsp_voice_wake_up_get, rt5514_dsp_voice_wake_up_put),
- SND_SOC_BYTES_TLV("Hotword Model", 0x8504,
- NULL, rt5514_hotword_model_put),
};
/* ADC Mixer*/
diff --git a/sound/soc/codecs/rt5514.h b/sound/soc/codecs/rt5514.h
index 803311cb7e2a..2dc40e6d8b3f 100644
--- a/sound/soc/codecs/rt5514.h
+++ b/sound/soc/codecs/rt5514.h
@@ -255,7 +255,6 @@
#define RT5514_FIRMWARE1 "rt5514_dsp_fw1.bin"
#define RT5514_FIRMWARE2 "rt5514_dsp_fw2.bin"
-#define RT5514_FIRMWARE3 "rt5514_dsp_fw3.bin"
/* System Clock Source */
enum {
@@ -282,8 +281,6 @@ struct rt5514_priv {
int pll_in;
int pll_out;
int dsp_enabled;
- u8 *model_buf;
- unsigned int model_len;
};
#endif /* __RT5514_H__ */
diff --git a/sound/soc/codecs/rt5616.c b/sound/soc/codecs/rt5616.c
index c94e94fe8297..0e5f54a9bc7e 100644
--- a/sound/soc/codecs/rt5616.c
+++ b/sound/soc/codecs/rt5616.c
@@ -98,7 +98,7 @@ static const struct reg_default rt5616_reg[] = {
{ 0x8e, 0x0004 },
{ 0x8f, 0x1100 },
{ 0x90, 0x0000 },
- { 0x91, 0x0000 },
+ { 0x91, 0x0c00 },
{ 0x92, 0x0000 },
{ 0x93, 0x2000 },
{ 0x94, 0x0200 },
diff --git a/sound/soc/codecs/rt5631.h b/sound/soc/codecs/rt5631.h
index 13401581b0df..8a6b99a48c7c 100644
--- a/sound/soc/codecs/rt5631.h
+++ b/sound/soc/codecs/rt5631.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __RTCODEC5631_H__
#define __RTCODEC5631_H__
diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c
index 71216db15eab..fa66b11df8d4 100644
--- a/sound/soc/codecs/rt5659.c
+++ b/sound/soc/codecs/rt5659.c
@@ -2744,7 +2744,8 @@ static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = {
SND_SOC_DAPM_PRE_PMU),
SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5659_hp_event,
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
- SND_SOC_DAPM_PGA("LOUT Amp", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA_S("LOUT Amp", 1, RT5659_PWR_ANLG_1, RT5659_PWR_LM_BIT,
+ 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("Charge Pump", SND_SOC_NOPM, 0, 0,
rt5659_charge_pump_event, SND_SOC_DAPM_PRE_PMU |
@@ -3208,6 +3209,7 @@ static const struct snd_soc_dapm_route rt5659_dapm_routes[] = {
{ "LOUT R MIX", "OUTVOL R Switch", "OUTVOL R" },
{ "LOUT Amp", NULL, "LOUT L MIX" },
{ "LOUT Amp", NULL, "LOUT R MIX" },
+ { "LOUT Amp", NULL, "Charge Pump" },
{ "LOUT Amp", NULL, "SYS CLK DET" },
{ "LOUT L Playback", "Switch", "LOUT Amp" },
{ "LOUT R Playback", "Switch", "LOUT Amp" },
diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c
index ab9e0ebff5a7..e45b895d8279 100644
--- a/sound/soc/codecs/rt5663.c
+++ b/sound/soc/codecs/rt5663.c
@@ -1639,7 +1639,8 @@ static irqreturn_t rt5663_irq(int irq, void *data)
{
struct rt5663_priv *rt5663 = data;
- dev_dbg(rt5663->codec->dev, "%s IRQ queue work\n", __func__);
+ dev_dbg(regmap_get_device(rt5663->regmap), "%s IRQ queue work\n",
+ __func__);
queue_delayed_work(system_wq, &rt5663->jack_detect_work,
msecs_to_jiffies(250));
diff --git a/sound/soc/codecs/tlv320aic26.h b/sound/soc/codecs/tlv320aic26.h
index 629b85e75409..1f2879b7a080 100644
--- a/sound/soc/codecs/tlv320aic26.h
+++ b/sound/soc/codecs/tlv320aic26.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Texas Instruments TLV320AIC26 low power audio CODEC
* register definitions
diff --git a/sound/soc/codecs/uda134x.h b/sound/soc/codecs/uda134x.h
index e41ab38c6f69..664618c2571c 100644
--- a/sound/soc/codecs/uda134x.h
+++ b/sound/soc/codecs/uda134x.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _UDA134X_CODEC_H
#define _UDA134X_CODEC_H
diff --git a/sound/soc/codecs/wm8993.h b/sound/soc/codecs/wm8993.h
index 4478b40c86e3..91811aa158d8 100644
--- a/sound/soc/codecs/wm8993.h
+++ b/sound/soc/codecs/wm8993.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef WM8993_H
#define WM8993_H
diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c
index 44f447136e22..4b64bb46eb21 100644
--- a/sound/soc/codecs/wm8998.c
+++ b/sound/soc/codecs/wm8998.c
@@ -101,7 +101,7 @@ static int wm8998_asrc_ev(struct snd_soc_dapm_widget *w,
return 0;
}
-static int wm8998_in1mux_put(struct snd_kcontrol *kcontrol,
+static int wm8998_inmux_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
@@ -109,84 +109,38 @@ static int wm8998_in1mux_put(struct snd_kcontrol *kcontrol,
struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
struct arizona *arizona = wm8998->core.arizona;
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int mux, inmode;
- unsigned int mode_val, src_val;
+ unsigned int mode_reg, mode_index;
+ unsigned int mux, inmode, src_val, mode_val;
mux = ucontrol->value.enumerated.item[0];
if (mux > 1)
return -EINVAL;
- /* L and R registers have same shift and mask */
- inmode = arizona->pdata.inmode[2 * mux];
- src_val = mux << ARIZONA_IN1L_SRC_SHIFT;
- if (inmode & ARIZONA_INMODE_SE)
- src_val |= 1 << ARIZONA_IN1L_SRC_SE_SHIFT;
-
- switch (arizona->pdata.inmode[0]) {
- case ARIZONA_INMODE_DMIC:
- if (mux)
- mode_val = 0; /* B always analogue */
- else
- mode_val = 1 << ARIZONA_IN1_MODE_SHIFT;
-
- snd_soc_update_bits(codec, ARIZONA_IN1L_CONTROL,
- ARIZONA_IN1_MODE_MASK, mode_val);
-
- /* IN1A is digital so L and R must change together */
- /* src_val setting same for both registers */
- snd_soc_update_bits(codec,
- ARIZONA_ADC_DIGITAL_VOLUME_1L,
- ARIZONA_IN1L_SRC_MASK |
- ARIZONA_IN1L_SRC_SE_MASK, src_val);
- snd_soc_update_bits(codec,
- ARIZONA_ADC_DIGITAL_VOLUME_1R,
- ARIZONA_IN1R_SRC_MASK |
- ARIZONA_IN1R_SRC_SE_MASK, src_val);
+ switch (e->reg) {
+ case ARIZONA_ADC_DIGITAL_VOLUME_2L:
+ mode_reg = ARIZONA_IN2L_CONTROL;
+ mode_index = 1 + (2 * mux);
break;
default:
- /* both analogue */
- snd_soc_update_bits(codec,
- e->reg,
- ARIZONA_IN1L_SRC_MASK |
- ARIZONA_IN1L_SRC_SE_MASK,
- src_val);
+ mode_reg = ARIZONA_IN1L_CONTROL;
+ mode_index = (2 * mux);
break;
}
- return snd_soc_dapm_mux_update_power(dapm, kcontrol,
- ucontrol->value.enumerated.item[0],
- e, NULL);
-}
-
-static int wm8998_in2mux_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
- struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
- struct wm8998_priv *wm8998 = snd_soc_codec_get_drvdata(codec);
- struct arizona *arizona = wm8998->core.arizona;
- struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int mux, inmode, src_val, mode_val;
-
- mux = ucontrol->value.enumerated.item[0];
- if (mux > 1)
- return -EINVAL;
-
- inmode = arizona->pdata.inmode[1 + (2 * mux)];
+ inmode = arizona->pdata.inmode[mode_index];
if (inmode & ARIZONA_INMODE_DMIC)
- mode_val = 1 << ARIZONA_IN2_MODE_SHIFT;
+ mode_val = 1 << ARIZONA_IN1_MODE_SHIFT;
else
mode_val = 0;
- src_val = mux << ARIZONA_IN2L_SRC_SHIFT;
+ src_val = mux << ARIZONA_IN1L_SRC_SHIFT;
if (inmode & ARIZONA_INMODE_SE)
- src_val |= 1 << ARIZONA_IN2L_SRC_SE_SHIFT;
+ src_val |= 1 << ARIZONA_IN1L_SRC_SE_SHIFT;
- snd_soc_update_bits(codec, ARIZONA_IN2L_CONTROL,
- ARIZONA_IN2_MODE_MASK, mode_val);
+ snd_soc_update_bits(codec, mode_reg, ARIZONA_IN1_MODE_MASK, mode_val);
- snd_soc_update_bits(codec, ARIZONA_ADC_DIGITAL_VOLUME_2L,
- ARIZONA_IN2L_SRC_MASK | ARIZONA_IN2L_SRC_SE_MASK,
+ snd_soc_update_bits(codec, e->reg,
+ ARIZONA_IN1L_SRC_MASK | ARIZONA_IN1L_SRC_SE_MASK,
src_val);
return snd_soc_dapm_mux_update_power(dapm, kcontrol,
@@ -216,14 +170,14 @@ static SOC_ENUM_SINGLE_DECL(wm8998_in2mux_enum,
static const struct snd_kcontrol_new wm8998_in1mux[2] = {
SOC_DAPM_ENUM_EXT("IN1L Mux", wm8998_in1muxl_enum,
- snd_soc_dapm_get_enum_double, wm8998_in1mux_put),
+ snd_soc_dapm_get_enum_double, wm8998_inmux_put),
SOC_DAPM_ENUM_EXT("IN1R Mux", wm8998_in1muxr_enum,
- snd_soc_dapm_get_enum_double, wm8998_in1mux_put),
+ snd_soc_dapm_get_enum_double, wm8998_inmux_put),
};
static const struct snd_kcontrol_new wm8998_in2mux =
SOC_DAPM_ENUM_EXT("IN2 Mux", wm8998_in2mux_enum,
- snd_soc_dapm_get_enum_double, wm8998_in2mux_put);
+ snd_soc_dapm_get_enum_double, wm8998_inmux_put);
static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
diff --git a/sound/soc/codecs/wm9713.h b/sound/soc/codecs/wm9713.h
index 7ecffc563016..f0800dcca9b8 100644
--- a/sound/soc/codecs/wm9713.h
+++ b/sound/soc/codecs/wm9713.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* wm9713.h -- WM9713 Soc Audio driver
*/
diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile
index f883933c1a19..23c6592eb31a 100644
--- a/sound/soc/davinci/Makefile
+++ b/sound/soc/davinci/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# DAVINCI Platform Support
snd-soc-edma-objs := edma-pcm.o
snd-soc-davinci-i2s-objs := davinci-i2s.o
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index f395bbc7c354..23b0da7df1f2 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -1982,8 +1982,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
GFP_KERNEL);
if (!mcasp->chconstr[SNDRV_PCM_STREAM_PLAYBACK].list ||
- !mcasp->chconstr[SNDRV_PCM_STREAM_CAPTURE].list)
- return -ENOMEM;
+ !mcasp->chconstr[SNDRV_PCM_STREAM_CAPTURE].list) {
+ ret = -ENOMEM;
+ goto err;
+ }
ret = davinci_mcasp_set_ch_constraints(mcasp);
if (ret)
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index d28dc25c9375..c67bf1139e1e 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# MPC8610 HPCD Machine Support
snd-soc-mpc8610-hpcd-objs := mpc8610_hpcd.o
obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += snd-soc-mpc8610-hpcd.o
diff --git a/sound/soc/fsl/imx-audmux.h b/sound/soc/fsl/imx-audmux.h
index 38a4209af7c6..f75b4d3aeacc 100644
--- a/sound/soc/fsl/imx-audmux.h
+++ b/sound/soc/fsl/imx-audmux.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __IMX_AUDMUX_H
#define __IMX_AUDMUX_H
diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h
index dff253fde29a..d7ee33b5b9a8 100644
--- a/sound/soc/fsl/mpc5200_dma.h
+++ b/sound/soc/fsl/mpc5200_dma.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Freescale MPC5200 Audio DMA driver
*/
diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile
index 9e000523a3b4..9dec293a4c4d 100644
--- a/sound/soc/generic/Makefile
+++ b/sound/soc/generic/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-soc-simple-card-utils-objs := simple-card-utils.o
snd-soc-simple-card-objs := simple-card.o
snd-soc-simple-scu-card-objs := simple-scu-card.o
diff --git a/sound/soc/img/Makefile b/sound/soc/img/Makefile
index 0508c1ced636..3e7b0fd4fcbf 100644
--- a/sound/soc/img/Makefile
+++ b/sound/soc/img/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_SND_SOC_IMG_I2S_IN) += img-i2s-in.o
obj-$(CONFIG_SND_SOC_IMG_I2S_OUT) += img-i2s-out.o
obj-$(CONFIG_SND_SOC_IMG_PARALLEL_OUT) += img-parallel-out.o
diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile
index 9105594436f0..b973d457e834 100644
--- a/sound/soc/intel/Makefile
+++ b/sound/soc/intel/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# Core support
obj-$(CONFIG_SND_SOC_INTEL_COMMON) += common/
diff --git a/sound/soc/intel/atom/Makefile b/sound/soc/intel/atom/Makefile
index aa6548c6feab..1dc60471b399 100644
--- a/sound/soc/intel/atom/Makefile
+++ b/sound/soc/intel/atom/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-soc-sst-atom-hifi2-platform-objs := sst-mfld-platform-pcm.o \
sst-mfld-platform-compress.o \
sst-atom-controls.o
diff --git a/sound/soc/intel/atom/sst/Makefile b/sound/soc/intel/atom/sst/Makefile
index fd21726361b5..795d1cf8f386 100644
--- a/sound/soc/intel/atom/sst/Makefile
+++ b/sound/soc/intel/atom/sst/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-intel-sst-core-objs := sst.o sst_ipc.o sst_stream.o sst_drv_interface.o sst_loader.o sst_pvt.o
snd-intel-sst-pci-objs += sst_pci.o
snd-intel-sst-acpi-objs += sst_acpi.o
diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
index a5c5bc5732a2..69d2dfaeb00c 100644
--- a/sound/soc/intel/boards/Makefile
+++ b/sound/soc/intel/boards/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-soc-sst-haswell-objs := haswell.o
snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o
snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o
diff --git a/sound/soc/intel/boards/cht_bsw_max98090_ti.c b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
index 14dd68edfce4..d3e1c7e12004 100644
--- a/sound/soc/intel/boards/cht_bsw_max98090_ti.c
+++ b/sound/soc/intel/boards/cht_bsw_max98090_ti.c
@@ -257,7 +257,7 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
return ret;
}
- fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF
+ fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBS_CFS;
ret = snd_soc_dai_set_fmt(rtd->cpu_dai, fmt);
@@ -270,8 +270,8 @@ static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd,
rate->min = rate->max = 48000;
channels->min = channels->max = 2;
- /* set SSP2 to 24-bit */
- params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
+ /* set SSP2 to 16-bit */
+ params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
return 0;
}
diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
index e7672831bc49..6072164f2d43 100644
--- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
@@ -605,6 +605,8 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
codec = pcm->codec_dai->codec;
+ snprintf(jack_name, sizeof(jack_name),
+ "HDMI/DP,pcm=%d Jack", pcm->device);
err = snd_soc_card_jack_new(card, jack_name,
SND_JACK_AVOUT, &ctx->kabylake_hdmi[i],
NULL, 0);
diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile
index cb29653319d9..7379d8830c39 100644
--- a/sound/soc/intel/common/Makefile
+++ b/sound/soc/intel/common/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-soc-sst-dsp-objs := sst-dsp.o
snd-soc-sst-acpi-objs := sst-acpi.o
snd-soc-sst-ipc-objs := sst-ipc.o
diff --git a/sound/soc/intel/skylake/Makefile b/sound/soc/intel/skylake/Makefile
index 3380deb81015..d1ccbecd141f 100644
--- a/sound/soc/intel/skylake/Makefile
+++ b/sound/soc/intel/skylake/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o skl-messages.o \
skl-topology.o
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index f637829833e6..61b5bfa79d13 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -707,18 +707,11 @@ static void skl_set_updown_mixer_format(struct skl_sst *ctx,
struct skl_module *module = mconfig->module;
struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx];
struct skl_module_fmt *fmt = &iface->outputs[0].fmt;
- int i = 0;
skl_set_base_module_format(ctx, mconfig,
(struct skl_base_cfg *)mixer_mconfig);
mixer_mconfig->out_ch_cfg = fmt->ch_cfg;
-
- /* Select F/W default coefficient */
- mixer_mconfig->coeff_sel = 0x0;
-
- /* User coeff, don't care since we are selecting F/W defaults */
- for (i = 0; i < UP_DOWN_MIXER_MAX_COEFF; i++)
- mixer_mconfig->coeff[i] = 0xDEADBEEF;
+ mixer_mconfig->ch_map = fmt->ch_map;
}
/*
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
index e7d766d56c8e..d14c50a60289 100644
--- a/sound/soc/intel/skylake/skl-nhlt.c
+++ b/sound/soc/intel/skylake/skl-nhlt.c
@@ -20,6 +20,8 @@
#include <linux/pci.h>
#include "skl.h"
+#define NHLT_ACPI_HEADER_SIG "NHLT"
+
/* Unique identification for getting NHLT blobs */
static guid_t osc_guid =
GUID_INIT(0xA69F886E, 0x6CEB, 0x4594,
@@ -45,6 +47,13 @@ struct nhlt_acpi_table *skl_nhlt_init(struct device *dev)
memremap(nhlt_ptr->min_addr, nhlt_ptr->length,
MEMREMAP_WB);
ACPI_FREE(obj);
+ if (nhlt_table && (strncmp(nhlt_table->header.signature,
+ NHLT_ACPI_HEADER_SIG,
+ strlen(NHLT_ACPI_HEADER_SIG)) != 0)) {
+ memunmap(nhlt_table);
+ dev_err(dev, "NHLT ACPI header signature incorrect\n");
+ return NULL;
+ }
return nhlt_table;
}
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
index 4380e40c6af0..1dd97479e0c0 100644
--- a/sound/soc/intel/skylake/skl-pcm.c
+++ b/sound/soc/intel/skylake/skl-pcm.c
@@ -355,7 +355,8 @@ static void skl_pcm_close(struct snd_pcm_substream *substream,
}
mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream);
- skl_tplg_d0i3_put(skl, mconfig->d0i3_caps);
+ if (mconfig)
+ skl_tplg_d0i3_put(skl, mconfig->d0i3_caps);
kfree(dma_params);
}
diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c
index 369ef7ce981c..8ff89280d9fd 100644
--- a/sound/soc/intel/skylake/skl-sst-utils.c
+++ b/sound/soc/intel/skylake/skl-sst-utils.c
@@ -251,6 +251,7 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
struct uuid_module *module;
struct firmware stripped_fw;
unsigned int safe_file;
+ int ret = 0;
/* Get the FW pointer to derive ADSP header */
stripped_fw.data = fw->data;
@@ -299,8 +300,10 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
for (i = 0; i < num_entry; i++, mod_entry++) {
module = kzalloc(sizeof(*module), GFP_KERNEL);
- if (!module)
- return -ENOMEM;
+ if (!module) {
+ ret = -ENOMEM;
+ goto free_uuid_list;
+ }
uuid_bin = (uuid_le *)mod_entry->uuid.id;
memcpy(&module->uuid, uuid_bin, sizeof(module->uuid));
@@ -311,8 +314,8 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
size = sizeof(int) * mod_entry->instance_max_count;
module->instance_id = devm_kzalloc(ctx->dev, size, GFP_KERNEL);
if (!module->instance_id) {
- kfree(module);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto free_uuid_list;
}
list_add_tail(&module->list, &skl->uuid_list);
@@ -323,6 +326,10 @@ int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
}
return 0;
+
+free_uuid_list:
+ skl_freeup_uuid_list(skl);
+ return ret;
}
void skl_freeup_uuid_list(struct skl_sst *ctx)
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
index b590742c5a7a..a072bcf209d2 100644
--- a/sound/soc/intel/skylake/skl-topology.c
+++ b/sound/soc/intel/skylake/skl-topology.c
@@ -2391,7 +2391,7 @@ static int skl_tplg_get_token(struct device *dev,
case SKL_TKN_U32_MAX_MCPS:
case SKL_TKN_U32_OBS:
case SKL_TKN_U32_IBS:
- ret = skl_tplg_fill_res_tkn(dev, tkn_elem, res, dir, pin_index);
+ ret = skl_tplg_fill_res_tkn(dev, tkn_elem, res, pin_index, dir);
if (ret < 0)
return ret;
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
index d116599bfdd7..b6496513fe55 100644
--- a/sound/soc/intel/skylake/skl-topology.h
+++ b/sound/soc/intel/skylake/skl-topology.h
@@ -34,7 +34,7 @@
#define MAX_FIXED_DMIC_PARAMS_SIZE 727
/* Maximum number of coefficients up down mixer module */
-#define UP_DOWN_MIXER_MAX_COEFF 6
+#define UP_DOWN_MIXER_MAX_COEFF 8
#define MODULE_MAX_IN_PINS 8
#define MODULE_MAX_OUT_PINS 8
@@ -161,6 +161,7 @@ struct skl_up_down_mixer_cfg {
u32 coeff_sel;
/* Pass the user coeff in this array */
s32 coeff[UP_DOWN_MIXER_MAX_COEFF];
+ u32 ch_map;
} __packed;
struct skl_algo_cfg {
diff --git a/sound/soc/mediatek/mt8173/Makefile b/sound/soc/mediatek/mt8173/Makefile
index 0357b27d29f2..c1eed0d2653b 100644
--- a/sound/soc/mediatek/mt8173/Makefile
+++ b/sound/soc/mediatek/mt8173/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# MTK Platform Support
obj-$(CONFIG_SND_SOC_MT8173) += mt8173-afe-pcm.o
# Machine support
diff --git a/sound/soc/mxs/Makefile b/sound/soc/mxs/Makefile
index 565b5b51e8b7..ab0a9a553702 100644
--- a/sound/soc/mxs/Makefile
+++ b/sound/soc/mxs/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# MXS Platform Support
snd-soc-mxs-objs := mxs-saif.o
snd-soc-mxs-pcm-objs := mxs-pcm.o
diff --git a/sound/soc/nuc900/Makefile b/sound/soc/nuc900/Makefile
index 7e46c7150316..c7ba2b9549d2 100644
--- a/sound/soc/nuc900/Makefile
+++ b/sound/soc/nuc900/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# NUC900 series audio
snd-soc-nuc900-pcm-objs := nuc900-pcm.o
snd-soc-nuc900-ac97-objs := nuc900-ac97.o
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index db36fbd5d1a0..a6785dc4fc90 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# OMAP Platform Support
snd-soc-omap-objs := omap-pcm.o
snd-soc-omap-dmic-objs := omap-dmic.o
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 2cff67b61dc3..5b265662f04f 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# PXA Platform Support
snd-soc-pxa2xx-objs := pxa2xx-pcm.o
snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o
diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile
index 79e5c50a8f71..d5280355c24f 100644
--- a/sound/soc/qcom/Makefile
+++ b/sound/soc/qcom/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# Platform
snd-soc-lpass-cpu-objs := lpass-cpu.o
snd-soc-lpass-platform-objs := lpass-platform.o
diff --git a/sound/soc/rockchip/Makefile b/sound/soc/rockchip/Makefile
index 105f0e14a4ab..05b078e7b87f 100644
--- a/sound/soc/rockchip/Makefile
+++ b/sound/soc/rockchip/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# ROCKCHIP Platform Support
snd-soc-rockchip-i2s-objs := rockchip_i2s.o
snd-soc-rockchip-pdm-objs := rockchip_pdm.o
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index b6590467fd14..908211e1d6fc 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -692,7 +692,6 @@ static int rockchip_i2s_remove(struct platform_device *pdev)
if (!pm_runtime_status_suspended(&pdev->dev))
i2s_runtime_suspend(&pdev->dev);
- clk_disable_unprepare(i2s->mclk);
clk_disable_unprepare(i2s->hclk);
return 0;
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index b6c2ee358333..030949e1e434 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# S3c24XX Platform Support
snd-soc-s3c-dma-objs := dmaengine.o
snd-soc-idma-objs := idma.o
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 10a4da06c0a1..de783c6d2a70 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -552,8 +552,11 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
}
ret = clk_prepare_enable(i2s->op_clk);
- if (ret)
+ if (ret) {
+ clk_put(i2s->op_clk);
+ i2s->op_clk = NULL;
goto err;
+ }
i2s->rclk_srcrate = clk_get_rate(i2s->op_clk);
/* Over-ride the other's */
@@ -1285,6 +1288,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
}
}
}
+ quirks &= ~(QUIRK_SEC_DAI | QUIRK_SUPPORTS_IDMA);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pri_dai->addr = devm_ioremap_resource(&pdev->dev, res);
diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile
index aaf3dcd1ee2a..51bd7c81671c 100644
--- a/sound/soc/sh/Makefile
+++ b/sound/soc/sh/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
## DMA engines
snd-soc-dma-sh7760-objs := dma-sh7760.o
obj-$(CONFIG_SND_SOC_PCM_SH7760) += snd-soc-dma-sh7760.o
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 938baff86ef2..e11ce5036bcf 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -479,10 +479,10 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
}
if (req_rate[0] % 48000 == 0)
- adg->flags = AUDIO_OUT_48;
+ adg->flags |= AUDIO_OUT_48;
if (of_get_property(np, "clkout-lr-asynchronous", NULL))
- adg->flags = LRCLK_ASYNC;
+ adg->flags |= LRCLK_ASYNC;
/*
* This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index fffc07e72627..03c2a1f02643 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -1112,6 +1112,9 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
i = 0;
for_each_child_of_node(node, np) {
+ if (!of_device_is_available(np))
+ goto skip;
+
ssi = rsnd_ssi_get(priv, i);
snprintf(name, RSND_SSI_NAME_SIZE, "%s.%d",
@@ -1148,7 +1151,7 @@ int rsnd_ssi_probe(struct rsnd_priv *priv)
of_node_put(np);
goto rsnd_ssi_probe_done;
}
-
+skip:
i++;
}
diff --git a/sound/soc/sirf/Makefile b/sound/soc/sirf/Makefile
index dd917f20f12f..16ed11965ff9 100644
--- a/sound/soc/sirf/Makefile
+++ b/sound/soc/sirf/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-soc-sirf-audio-objs := sirf-audio.o
snd-soc-sirf-audio-port-objs := sirf-audio-port.o
snd-soc-sirf-usp-objs := sirf-usp.o
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 2cb8d3b55fbc..d9b1e6417fb9 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -30,8 +30,10 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
+ int ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@@ -44,7 +46,7 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
}
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->open) {
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->open) {
ret = platform->driver->compr_ops->open(cstream);
if (ret < 0) {
pr_err("compress asoc: can't open platform %s\n",
@@ -53,6 +55,27 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
}
}
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->open)
+ continue;
+
+ __ret = component->driver->compr_ops->open(cstream);
+ if (__ret < 0) {
+ pr_err("compress asoc: can't open platform %s\n",
+ component->name);
+ ret = __ret;
+ }
+ }
+ if (ret < 0)
+ goto machine_err;
+
if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->startup) {
ret = rtd->dai_link->compr_ops->startup(cstream);
if (ret < 0) {
@@ -68,7 +91,21 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
return 0;
machine_err:
- if (platform->driver->compr_ops && platform->driver->compr_ops->free)
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->free)
+ continue;
+
+ component->driver->compr_ops->free(cstream);
+ }
+
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
platform->driver->compr_ops->free(cstream);
plat_err:
if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
@@ -84,11 +121,13 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
struct snd_pcm_substream *fe_substream =
fe->pcm->streams[cstream->direction].substream;
struct snd_soc_platform *platform = fe->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = fe->cpu_dai;
struct snd_soc_dpcm *dpcm;
struct snd_soc_dapm_widget_list *list;
int stream;
- int ret = 0;
+ int ret = 0, __ret;
if (cstream->direction == SND_COMPRESS_PLAYBACK)
stream = SNDRV_PCM_STREAM_PLAYBACK;
@@ -107,7 +146,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->open) {
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->open) {
ret = platform->driver->compr_ops->open(cstream);
if (ret < 0) {
pr_err("compress asoc: can't open platform %s\n",
@@ -116,6 +155,27 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
}
}
+ for_each_rtdcom(fe, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->open)
+ continue;
+
+ __ret = component->driver->compr_ops->open(cstream);
+ if (__ret < 0) {
+ pr_err("compress asoc: can't open platform %s\n",
+ component->name);
+ ret = __ret;
+ }
+ }
+ if (ret < 0)
+ goto machine_err;
+
if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->startup) {
ret = fe->dai_link->compr_ops->startup(cstream);
if (ret < 0) {
@@ -167,7 +227,21 @@ fe_err:
if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
fe->dai_link->compr_ops->shutdown(cstream);
machine_err:
- if (platform->driver->compr_ops && platform->driver->compr_ops->free)
+ for_each_rtdcom(fe, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->free)
+ continue;
+
+ component->driver->compr_ops->free(cstream);
+ }
+
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
platform->driver->compr_ops->free(cstream);
plat_err:
if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
@@ -210,6 +284,8 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
int stream;
@@ -235,7 +311,21 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown)
rtd->dai_link->compr_ops->shutdown(cstream);
- if (platform->driver->compr_ops && platform->driver->compr_ops->free)
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->free)
+ continue;
+
+ component->driver->compr_ops->free(cstream);
+ }
+
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
platform->driver->compr_ops->free(cstream);
if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
@@ -267,6 +357,8 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
{
struct snd_soc_pcm_runtime *fe = cstream->private_data;
struct snd_soc_platform *platform = fe->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = fe->cpu_dai;
struct snd_soc_dpcm *dpcm;
int stream, ret;
@@ -304,9 +396,23 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
fe->dai_link->compr_ops->shutdown(cstream);
- if (platform->driver->compr_ops && platform->driver->compr_ops->free)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->free)
platform->driver->compr_ops->free(cstream);
+ for_each_rtdcom(fe, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->free)
+ continue;
+
+ component->driver->compr_ops->free(cstream);
+ }
+
if (cpu_dai->driver->cops && cpu_dai->driver->cops->shutdown)
cpu_dai->driver->cops->shutdown(cstream, cpu_dai);
@@ -319,18 +425,38 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
+ int ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
- if (platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
ret = platform->driver->compr_ops->trigger(cstream, cmd);
if (ret < 0)
goto out;
}
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->trigger)
+ continue;
+
+ __ret = component->driver->compr_ops->trigger(cstream, cmd);
+ if (__ret < 0)
+ ret = __ret;
+ }
+ if (ret < 0)
+ goto out;
+
if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger)
cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
@@ -353,16 +479,36 @@ static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
{
struct snd_soc_pcm_runtime *fe = cstream->private_data;
struct snd_soc_platform *platform = fe->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = fe->cpu_dai;
- int ret = 0, stream;
+ int ret = 0, __ret, stream;
if (cmd == SND_COMPR_TRIGGER_PARTIAL_DRAIN ||
cmd == SND_COMPR_TRIGGER_DRAIN) {
- if (platform->driver->compr_ops &&
+ if (platform &&
+ platform->driver->compr_ops &&
platform->driver->compr_ops->trigger)
return platform->driver->compr_ops->trigger(cstream,
cmd);
+
+ for_each_rtdcom(fe, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->trigger)
+ continue;
+
+ __ret = component->driver->compr_ops->trigger(cstream, cmd);
+ if (__ret < 0)
+ ret = __ret;
+ }
+ return ret;
}
if (cstream->direction == SND_COMPRESS_PLAYBACK)
@@ -379,12 +525,30 @@ static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd)
goto out;
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
ret = platform->driver->compr_ops->trigger(cstream, cmd);
if (ret < 0)
goto out;
}
+ for_each_rtdcom(fe, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->trigger)
+ continue;
+
+ __ret = component->driver->compr_ops->trigger(cstream, cmd);
+ if (__ret < 0)
+ ret = __ret;
+ }
+ if (ret < 0)
+ goto out;
+
fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
ret = dpcm_be_dai_trigger(fe, stream, cmd);
@@ -415,8 +579,10 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
+ int ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@@ -432,12 +598,30 @@ static int soc_compr_set_params(struct snd_compr_stream *cstream,
goto err;
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
ret = platform->driver->compr_ops->set_params(cstream, params);
if (ret < 0)
goto err;
}
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->set_params)
+ continue;
+
+ __ret = component->driver->compr_ops->set_params(cstream, params);
+ if (__ret < 0)
+ ret = __ret;
+ }
+ if (ret < 0)
+ goto err;
+
if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) {
ret = rtd->dai_link->compr_ops->set_params(cstream);
if (ret < 0)
@@ -471,8 +655,10 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
struct snd_pcm_substream *fe_substream =
fe->pcm->streams[cstream->direction].substream;
struct snd_soc_platform *platform = fe->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = fe->cpu_dai;
- int ret = 0, stream;
+ int ret = 0, __ret, stream;
if (cstream->direction == SND_COMPRESS_PLAYBACK)
stream = SNDRV_PCM_STREAM_PLAYBACK;
@@ -487,12 +673,30 @@ static int soc_compr_set_params_fe(struct snd_compr_stream *cstream,
goto out;
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
ret = platform->driver->compr_ops->set_params(cstream, params);
if (ret < 0)
goto out;
}
+ for_each_rtdcom(fe, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->set_params)
+ continue;
+
+ __ret = component->driver->compr_ops->set_params(cstream, params);
+ if (__ret < 0)
+ ret = __ret;
+ }
+ if (ret < 0)
+ goto out;
+
if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->set_params) {
ret = fe->dai_link->compr_ops->set_params(cstream);
if (ret < 0)
@@ -531,8 +735,10 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream,
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
+ int ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@@ -542,8 +748,27 @@ static int soc_compr_get_params(struct snd_compr_stream *cstream,
goto err;
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->get_params)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_params) {
ret = platform->driver->compr_ops->get_params(cstream, params);
+ if (ret < 0)
+ goto err;
+ }
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->get_params)
+ continue;
+
+ __ret = component->driver->compr_ops->get_params(cstream, params);
+ if (__ret < 0)
+ ret = __ret;
+ }
err:
mutex_unlock(&rtd->pcm_mutex);
@@ -555,13 +780,35 @@ static int soc_compr_get_caps(struct snd_compr_stream *cstream,
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
- int ret = 0;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
+ int ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
- if (platform->driver->compr_ops && platform->driver->compr_ops->get_caps)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_caps) {
ret = platform->driver->compr_ops->get_caps(cstream, caps);
+ if (ret < 0)
+ goto err;
+ }
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->get_caps)
+ continue;
+
+ __ret = component->driver->compr_ops->get_caps(cstream, caps);
+ if (__ret < 0)
+ ret = __ret;
+ }
+
+err:
mutex_unlock(&rtd->pcm_mutex);
return ret;
}
@@ -571,13 +818,35 @@ static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
- int ret = 0;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
+ int ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
- if (platform->driver->compr_ops && platform->driver->compr_ops->get_codec_caps)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_codec_caps) {
ret = platform->driver->compr_ops->get_codec_caps(cstream, codec);
+ if (ret < 0)
+ goto err;
+ }
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->get_codec_caps)
+ continue;
+
+ __ret = component->driver->compr_ops->get_codec_caps(cstream, codec);
+ if (__ret < 0)
+ ret = __ret;
+ }
+
+err:
mutex_unlock(&rtd->pcm_mutex);
return ret;
}
@@ -586,8 +855,10 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
+ int ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@@ -597,8 +868,27 @@ static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
goto err;
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->ack)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->ack) {
ret = platform->driver->compr_ops->ack(cstream, bytes);
+ if (ret < 0)
+ goto err;
+ }
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->ack)
+ continue;
+
+ __ret = component->driver->compr_ops->ack(cstream, bytes);
+ if (__ret < 0)
+ ret = __ret;
+ }
err:
mutex_unlock(&rtd->pcm_mutex);
@@ -610,7 +900,9 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
- int ret = 0;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
+ int ret = 0, __ret;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@@ -618,9 +910,29 @@ static int soc_compr_pointer(struct snd_compr_stream *cstream,
if (cpu_dai->driver->cops && cpu_dai->driver->cops->pointer)
cpu_dai->driver->cops->pointer(cstream, tstamp, cpu_dai);
- if (platform->driver->compr_ops && platform->driver->compr_ops->pointer)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->pointer) {
ret = platform->driver->compr_ops->pointer(cstream, tstamp);
+ if (ret < 0)
+ goto err;
+ }
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->pointer)
+ continue;
+ __ret = component->driver->compr_ops->pointer(cstream, tstamp);
+ if (__ret < 0)
+ ret = __ret;
+ }
+
+err:
mutex_unlock(&rtd->pcm_mutex);
return ret;
}
@@ -630,13 +942,34 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
- int ret = 0;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
+ int ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
- if (platform->driver->compr_ops && platform->driver->compr_ops->copy)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->copy) {
ret = platform->driver->compr_ops->copy(cstream, buf, count);
+ if (ret < 0)
+ goto err;
+ }
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->copy)
+ continue;
+ __ret = component->driver->compr_ops->copy(cstream, buf, count);
+ if (__ret < 0)
+ ret = __ret;
+ }
+err:
mutex_unlock(&rtd->pcm_mutex);
return ret;
}
@@ -646,8 +979,10 @@ static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
+ int ret = 0, __ret;
if (cpu_dai->driver->cops && cpu_dai->driver->cops->set_metadata) {
ret = cpu_dai->driver->cops->set_metadata(cstream, metadata, cpu_dai);
@@ -655,8 +990,27 @@ static int soc_compr_set_metadata(struct snd_compr_stream *cstream,
return ret;
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->set_metadata)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->set_metadata) {
ret = platform->driver->compr_ops->set_metadata(cstream, metadata);
+ if (ret < 0)
+ return ret;
+ }
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->set_metadata)
+ continue;
+
+ __ret = component->driver->compr_ops->set_metadata(cstream, metadata);
+ if (__ret < 0)
+ ret = __ret;
+ }
return ret;
}
@@ -666,8 +1020,10 @@ static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
{
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
+ int ret = 0, __ret;
if (cpu_dai->driver->cops && cpu_dai->driver->cops->get_metadata) {
ret = cpu_dai->driver->cops->get_metadata(cstream, metadata, cpu_dai);
@@ -675,8 +1031,27 @@ static int soc_compr_get_metadata(struct snd_compr_stream *cstream,
return ret;
}
- if (platform->driver->compr_ops && platform->driver->compr_ops->get_metadata)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->get_metadata) {
ret = platform->driver->compr_ops->get_metadata(cstream, metadata);
+ if (ret < 0)
+ return ret;
+ }
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->get_metadata)
+ continue;
+
+ __ret = component->driver->compr_ops->get_metadata(cstream, metadata);
+ if (__ret < 0)
+ ret = __ret;
+ }
return ret;
}
@@ -723,6 +1098,8 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
{
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_compr *compr;
@@ -798,9 +1175,25 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));
}
+
/* Add copy callback for not memory mapped DSPs */
- if (platform->driver->compr_ops && platform->driver->compr_ops->copy)
+ if (platform && platform->driver->compr_ops && platform->driver->compr_ops->copy)
+ compr->ops->copy = soc_compr_copy;
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->compr_ops ||
+ !component->driver->compr_ops->copy)
+ continue;
+
compr->ops->copy = soc_compr_copy;
+ }
+
mutex_init(&compr->lock);
ret = snd_compress_new(rtd->card->snd_card, num, direction,
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index fee4b0ef5566..533c822ca6e6 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -614,6 +614,8 @@ struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
}
EXPORT_SYMBOL_GPL(snd_soc_get_dai_substream);
+static const struct snd_soc_ops null_snd_soc_ops;
+
static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
{
@@ -626,6 +628,9 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
INIT_LIST_HEAD(&rtd->component_list);
rtd->card = card;
rtd->dai_link = dai_link;
+ if (!rtd->dai_link->ops)
+ rtd->dai_link->ops = &null_snd_soc_ops;
+
rtd->codec_dais = kzalloc(sizeof(struct snd_soc_dai *) *
dai_link->num_codecs,
GFP_KERNEL);
@@ -639,8 +644,7 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd)
{
- if (rtd && rtd->codec_dais)
- kfree(rtd->codec_dais);
+ kfree(rtd->codec_dais);
snd_soc_rtdcom_del_all(rtd);
kfree(rtd);
}
@@ -2632,7 +2636,7 @@ EXPORT_SYMBOL_GPL(snd_soc_add_dai_controls);
int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
unsigned int freq, int dir)
{
- if (dai->driver && dai->driver->ops->set_sysclk)
+ if (dai->driver->ops->set_sysclk)
return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
return snd_soc_component_set_sysclk(dai->component, clk_id, 0,
@@ -2700,7 +2704,7 @@ EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk);
int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
int div_id, int div)
{
- if (dai->driver && dai->driver->ops->set_clkdiv)
+ if (dai->driver->ops->set_clkdiv)
return dai->driver->ops->set_clkdiv(dai, div_id, div);
else
return -EINVAL;
@@ -2720,7 +2724,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
unsigned int freq_in, unsigned int freq_out)
{
- if (dai->driver && dai->driver->ops->set_pll)
+ if (dai->driver->ops->set_pll)
return dai->driver->ops->set_pll(dai, pll_id, source,
freq_in, freq_out);
@@ -2786,7 +2790,7 @@ EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);
*/
int snd_soc_dai_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
{
- if (dai->driver && dai->driver->ops->set_bclk_ratio)
+ if (dai->driver->ops->set_bclk_ratio)
return dai->driver->ops->set_bclk_ratio(dai, ratio);
else
return -EINVAL;
@@ -2860,7 +2864,7 @@ static int snd_soc_xlate_tdm_slot_mask(unsigned int slots,
int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
{
- if (dai->driver && dai->driver->ops->xlate_tdm_slot_mask)
+ if (dai->driver->ops->xlate_tdm_slot_mask)
dai->driver->ops->xlate_tdm_slot_mask(slots,
&tx_mask, &rx_mask);
else
@@ -2869,7 +2873,7 @@ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
dai->tx_mask = tx_mask;
dai->rx_mask = rx_mask;
- if (dai->driver && dai->driver->ops->set_tdm_slot)
+ if (dai->driver->ops->set_tdm_slot)
return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
slots, slot_width);
else
@@ -2893,7 +2897,7 @@ int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
unsigned int tx_num, unsigned int *tx_slot,
unsigned int rx_num, unsigned int *rx_slot)
{
- if (dai->driver && dai->driver->ops->set_channel_map)
+ if (dai->driver->ops->set_channel_map)
return dai->driver->ops->set_channel_map(dai, tx_num, tx_slot,
rx_num, rx_slot);
else
@@ -2910,7 +2914,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
*/
int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
{
- if (dai->driver && dai->driver->ops->set_tristate)
+ if (dai->driver->ops->set_tristate)
return dai->driver->ops->set_tristate(dai, tristate);
else
return -EINVAL;
@@ -3250,6 +3254,30 @@ static int snd_soc_component_stream_event(struct snd_soc_dapm_context *dapm,
return component->driver->stream_event(component, event);
}
+static int snd_soc_component_drv_pcm_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ if (component->driver->pcm_new)
+ return component->driver->pcm_new(rtd);
+
+ return 0;
+}
+
+static void snd_soc_component_drv_pcm_free(struct snd_soc_component *component,
+ struct snd_pcm *pcm)
+{
+ if (component->driver->pcm_free)
+ component->driver->pcm_free(pcm);
+}
+
+static int snd_soc_component_set_bias_level(struct snd_soc_dapm_context *dapm,
+ enum snd_soc_bias_level level)
+{
+ struct snd_soc_component *component = dapm->component;
+
+ return component->driver->set_bias_level(component, level);
+}
+
static int snd_soc_component_initialize(struct snd_soc_component *component,
const struct snd_soc_component_driver *driver, struct device *dev)
{
@@ -3270,16 +3298,21 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
component->set_sysclk = component->driver->set_sysclk;
component->set_pll = component->driver->set_pll;
component->set_jack = component->driver->set_jack;
+ component->pcm_new = snd_soc_component_drv_pcm_new;
+ component->pcm_free = snd_soc_component_drv_pcm_free;
dapm = snd_soc_component_get_dapm(component);
dapm->dev = dev;
dapm->component = component;
dapm->bias_level = SND_SOC_BIAS_OFF;
- dapm->idle_bias_off = true;
+ dapm->idle_bias_off = !driver->idle_bias_on;
+ dapm->suspend_bias_off = driver->suspend_bias_off;
if (driver->seq_notifier)
dapm->seq_notifier = snd_soc_component_seq_notifier;
if (driver->stream_event)
dapm->stream_event = snd_soc_component_stream_event;
+ if (driver->set_bias_level)
+ dapm->set_bias_level = snd_soc_component_set_bias_level;
INIT_LIST_HEAD(&component->dai_list);
mutex_init(&component->io_mutex);
@@ -3371,19 +3404,49 @@ static void snd_soc_component_del_unlocked(struct snd_soc_component *component)
list_del(&component->list);
}
-int snd_soc_register_component(struct device *dev,
- const struct snd_soc_component_driver *component_driver,
- struct snd_soc_dai_driver *dai_drv,
- int num_dai)
+#define ENDIANNESS_MAP(name) \
+ (SNDRV_PCM_FMTBIT_##name##LE | SNDRV_PCM_FMTBIT_##name##BE)
+static u64 endianness_format_map[] = {
+ ENDIANNESS_MAP(S16_),
+ ENDIANNESS_MAP(U16_),
+ ENDIANNESS_MAP(S24_),
+ ENDIANNESS_MAP(U24_),
+ ENDIANNESS_MAP(S32_),
+ ENDIANNESS_MAP(U32_),
+ ENDIANNESS_MAP(S24_3),
+ ENDIANNESS_MAP(U24_3),
+ ENDIANNESS_MAP(S20_3),
+ ENDIANNESS_MAP(U20_3),
+ ENDIANNESS_MAP(S18_3),
+ ENDIANNESS_MAP(U18_3),
+ ENDIANNESS_MAP(FLOAT_),
+ ENDIANNESS_MAP(FLOAT64_),
+ ENDIANNESS_MAP(IEC958_SUBFRAME_),
+};
+
+/*
+ * Fix up the DAI formats for endianness: codecs don't actually see
+ * the endianness of the data but we're using the CPU format
+ * definitions which do need to include endianness so we ensure that
+ * codec DAIs always have both big and little endian variants set.
+ */
+static void convert_endianness_formats(struct snd_soc_pcm_stream *stream)
{
- struct snd_soc_component *component;
- int ret;
+ int i;
- component = kzalloc(sizeof(*component), GFP_KERNEL);
- if (!component) {
- dev_err(dev, "ASoC: Failed to allocate memory\n");
- return -ENOMEM;
- }
+ for (i = 0; i < ARRAY_SIZE(endianness_format_map); i++)
+ if (stream->formats & endianness_format_map[i])
+ stream->formats |= endianness_format_map[i];
+}
+
+int snd_soc_add_component(struct device *dev,
+ struct snd_soc_component *component,
+ const struct snd_soc_component_driver *component_driver,
+ struct snd_soc_dai_driver *dai_drv,
+ int num_dai)
+{
+ int ret;
+ int i;
ret = snd_soc_component_initialize(component, component_driver, dev);
if (ret)
@@ -3392,7 +3455,15 @@ int snd_soc_register_component(struct device *dev,
component->ignore_pmdown_time = true;
component->registered_as_component = true;
- ret = snd_soc_register_dais(component, dai_drv, num_dai, true);
+ if (component_driver->endianness) {
+ for (i = 0; i < num_dai; i++) {
+ convert_endianness_formats(&dai_drv[i].playback);
+ convert_endianness_formats(&dai_drv[i].capture);
+ }
+ }
+
+ ret = snd_soc_register_dais(component, dai_drv, num_dai,
+ !component_driver->non_legacy_dai_naming);
if (ret < 0) {
dev_err(dev, "ASoC: Failed to register DAIs: %d\n", ret);
goto err_cleanup;
@@ -3408,6 +3479,22 @@ err_free:
kfree(component);
return ret;
}
+EXPORT_SYMBOL_GPL(snd_soc_add_component);
+
+int snd_soc_register_component(struct device *dev,
+ const struct snd_soc_component_driver *component_driver,
+ struct snd_soc_dai_driver *dai_drv,
+ int num_dai)
+{
+ struct snd_soc_component *component;
+
+ component = kzalloc(sizeof(*component), GFP_KERNEL);
+ if (!component)
+ return -ENOMEM;
+
+ return snd_soc_add_component(dev, component, component_driver,
+ dai_drv, num_dai);
+}
EXPORT_SYMBOL_GPL(snd_soc_register_component);
/**
@@ -3448,6 +3535,32 @@ void snd_soc_unregister_component(struct device *dev)
}
EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
+struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
+ const char *driver_name)
+{
+ struct snd_soc_component *component;
+ struct snd_soc_component *ret;
+
+ ret = NULL;
+ mutex_lock(&client_mutex);
+ list_for_each_entry(component, &component_list, list) {
+ if (dev != component->dev)
+ continue;
+
+ if (driver_name &&
+ (driver_name != component->driver->name) &&
+ (strcmp(component->driver->name, driver_name) != 0))
+ continue;
+
+ ret = component;
+ break;
+ }
+ mutex_unlock(&client_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(snd_soc_lookup_component);
+
static int snd_soc_platform_drv_probe(struct snd_soc_component *component)
{
struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
@@ -3462,6 +3575,26 @@ static void snd_soc_platform_drv_remove(struct snd_soc_component *component)
platform->driver->remove(platform);
}
+static int snd_soc_platform_drv_pcm_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
+
+ if (platform->driver->pcm_new)
+ return platform->driver->pcm_new(rtd);
+
+ return 0;
+}
+
+static void snd_soc_platform_drv_pcm_free(struct snd_soc_component *component,
+ struct snd_pcm *pcm)
+{
+ struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
+
+ if (platform->driver->pcm_free)
+ platform->driver->pcm_free(pcm);
+}
+
/**
* snd_soc_add_platform - Add a platform to the ASoC core
* @dev: The parent device for the platform
@@ -3485,6 +3618,10 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
platform->component.probe = snd_soc_platform_drv_probe;
if (platform_drv->remove)
platform->component.remove = snd_soc_platform_drv_remove;
+ if (platform_drv->pcm_new)
+ platform->component.pcm_new = snd_soc_platform_drv_pcm_new;
+ if (platform_drv->pcm_free)
+ platform->component.pcm_free = snd_soc_platform_drv_pcm_free;
#ifdef CONFIG_DEBUG_FS
platform->component.debugfs_prefix = "platform";
@@ -3582,39 +3719,6 @@ void snd_soc_unregister_platform(struct device *dev)
}
EXPORT_SYMBOL_GPL(snd_soc_unregister_platform);
-static u64 codec_format_map[] = {
- SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE,
- SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE,
- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE,
- SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE,
- SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE,
- SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE,
- SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3BE,
- SNDRV_PCM_FMTBIT_U24_3LE | SNDRV_PCM_FMTBIT_U24_3BE,
- SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE,
- SNDRV_PCM_FMTBIT_U20_3LE | SNDRV_PCM_FMTBIT_U20_3BE,
- SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE,
- SNDRV_PCM_FMTBIT_U18_3LE | SNDRV_PCM_FMTBIT_U18_3BE,
- SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE,
- SNDRV_PCM_FMTBIT_FLOAT64_LE | SNDRV_PCM_FMTBIT_FLOAT64_BE,
- SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE
- | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE,
-};
-
-/* Fix up the DAI formats for endianness: codecs don't actually see
- * the endianness of the data but we're using the CPU format
- * definitions which do need to include endianness so we ensure that
- * codec DAIs always have both big and little endian variants set.
- */
-static void fixup_codec_formats(struct snd_soc_pcm_stream *stream)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(codec_format_map); i++)
- if (stream->formats & codec_format_map[i])
- stream->formats |= codec_format_map[i];
-}
-
static int snd_soc_codec_drv_probe(struct snd_soc_component *component)
{
struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
@@ -3765,8 +3869,8 @@ int snd_soc_register_codec(struct device *dev,
codec->component.regmap = codec_drv->get_regmap(dev);
for (i = 0; i < num_dai; i++) {
- fixup_codec_formats(&dai_drv[i].playback);
- fixup_codec_formats(&dai_drv[i].capture);
+ convert_endianness_formats(&dai_drv[i].playback);
+ convert_endianness_formats(&dai_drv[i].capture);
}
ret = snd_soc_register_dais(&codec->component, dai_drv, num_dai, false);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index dcef67a9bd48..a10b21cfc31e 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -2884,7 +2884,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
{
int i, r, ret = 0;
- mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
+ mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
for (i = 0; i < num; i++) {
r = snd_soc_dapm_add_route(dapm, route);
if (r < 0) {
@@ -2915,7 +2915,7 @@ int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm,
{
int i;
- mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
+ mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
for (i = 0; i < num; i++) {
snd_soc_dapm_del_route(dapm, route);
route++;
@@ -3681,7 +3681,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
substream.stream = SNDRV_PCM_STREAM_CAPTURE;
- if (source->driver->ops && source->driver->ops->startup) {
+ if (source->driver->ops->startup) {
ret = source->driver->ops->startup(&substream, source);
if (ret < 0) {
dev_err(source->dev,
@@ -3695,7 +3695,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
goto out;
substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
- if (sink->driver->ops && sink->driver->ops->startup) {
+ if (sink->driver->ops->startup) {
ret = sink->driver->ops->startup(&substream, sink);
if (ret < 0) {
dev_err(sink->dev,
@@ -3725,13 +3725,13 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
ret = 0;
source->active--;
- if (source->driver->ops && source->driver->ops->shutdown) {
+ if (source->driver->ops->shutdown) {
substream.stream = SNDRV_PCM_STREAM_CAPTURE;
source->driver->ops->shutdown(&substream, source);
}
sink->active--;
- if (sink->driver->ops && sink->driver->ops->shutdown) {
+ if (sink->driver->ops->shutdown) {
substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
sink->driver->ops->shutdown(&substream, sink);
}
@@ -3778,18 +3778,27 @@ static int snd_soc_dapm_dai_link_put(struct snd_kcontrol *kcontrol,
return 0;
}
-int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
- const struct snd_soc_pcm_stream *params,
- unsigned int num_params,
- struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
+static void
+snd_soc_dapm_free_kcontrol(struct snd_soc_card *card,
+ unsigned long *private_value,
+ int num_params,
+ const char **w_param_text)
+{
+ int count;
+
+ devm_kfree(card->dev, (void *)*private_value);
+ for (count = 0 ; count < num_params; count++)
+ devm_kfree(card->dev, (void *)w_param_text[count]);
+ devm_kfree(card->dev, w_param_text);
+}
+
+static struct snd_kcontrol_new *
+snd_soc_dapm_alloc_kcontrol(struct snd_soc_card *card,
+ char *link_name,
+ const struct snd_soc_pcm_stream *params,
+ int num_params, const char **w_param_text,
+ unsigned long *private_value)
{
- struct snd_soc_dapm_widget template;
- struct snd_soc_dapm_widget *w;
- char *link_name;
- int ret, count;
- unsigned long private_value;
- const char **w_param_text;
struct soc_enum w_param_enum[] = {
SOC_ENUM_SINGLE(0, 0, 0, NULL),
};
@@ -3798,19 +3807,9 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
snd_soc_dapm_dai_link_get,
snd_soc_dapm_dai_link_put),
};
+ struct snd_kcontrol_new *kcontrol_news;
const struct snd_soc_pcm_stream *config = params;
-
- w_param_text = devm_kcalloc(card->dev, num_params,
- sizeof(char *), GFP_KERNEL);
- if (!w_param_text)
- return -ENOMEM;
-
- link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s",
- source->name, sink->name);
- if (!link_name) {
- ret = -ENOMEM;
- goto outfree_w_param;
- }
+ int count;
for (count = 0 ; count < num_params; count++) {
if (!config->stream_name) {
@@ -3821,57 +3820,94 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
devm_kasprintf(card->dev, GFP_KERNEL,
"Anonymous Configuration %d",
count);
- if (!w_param_text[count]) {
- ret = -ENOMEM;
- goto outfree_link_name;
- }
} else {
w_param_text[count] = devm_kmemdup(card->dev,
config->stream_name,
strlen(config->stream_name) + 1,
GFP_KERNEL);
- if (!w_param_text[count]) {
- ret = -ENOMEM;
- goto outfree_link_name;
- }
}
+ if (!w_param_text[count])
+ goto outfree_w_param;
config++;
}
+
w_param_enum[0].items = num_params;
w_param_enum[0].texts = w_param_text;
- memset(&template, 0, sizeof(template));
- template.reg = SND_SOC_NOPM;
- template.id = snd_soc_dapm_dai_link;
- template.name = link_name;
- template.event = snd_soc_dai_link_event;
- template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_PRE_PMD;
- template.num_kcontrols = 1;
- /* duplicate w_param_enum on heap so that memory persists */
- private_value =
+ *private_value =
(unsigned long) devm_kmemdup(card->dev,
(void *)(kcontrol_dai_link[0].private_value),
sizeof(struct soc_enum), GFP_KERNEL);
- if (!private_value) {
+ if (!*private_value) {
dev_err(card->dev, "ASoC: Failed to create control for %s widget\n",
link_name);
- ret = -ENOMEM;
- goto outfree_link_name;
+ goto outfree_w_param;
}
- kcontrol_dai_link[0].private_value = private_value;
+ kcontrol_dai_link[0].private_value = *private_value;
/* duplicate kcontrol_dai_link on heap so that memory persists */
- template.kcontrol_news =
- devm_kmemdup(card->dev, &kcontrol_dai_link[0],
+ kcontrol_news = devm_kmemdup(card->dev, &kcontrol_dai_link[0],
sizeof(struct snd_kcontrol_new),
GFP_KERNEL);
- if (!template.kcontrol_news) {
+ if (!kcontrol_news) {
dev_err(card->dev, "ASoC: Failed to create control for %s widget\n",
link_name);
- ret = -ENOMEM;
- goto outfree_private_value;
+ goto outfree_w_param;
}
+ return kcontrol_news;
+
+outfree_w_param:
+ snd_soc_dapm_free_kcontrol(card, private_value, num_params, w_param_text);
+ return NULL;
+}
+
+int snd_soc_dapm_new_pcm(struct snd_soc_card *card,
+ const struct snd_soc_pcm_stream *params,
+ unsigned int num_params,
+ struct snd_soc_dapm_widget *source,
+ struct snd_soc_dapm_widget *sink)
+{
+ struct snd_soc_dapm_widget template;
+ struct snd_soc_dapm_widget *w;
+ const char **w_param_text;
+ unsigned long private_value;
+ char *link_name;
+ int ret;
+
+ link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s",
+ source->name, sink->name);
+ if (!link_name)
+ return -ENOMEM;
+
+ memset(&template, 0, sizeof(template));
+ template.reg = SND_SOC_NOPM;
+ template.id = snd_soc_dapm_dai_link;
+ template.name = link_name;
+ template.event = snd_soc_dai_link_event;
+ template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD;
+ template.kcontrol_news = NULL;
+
+ /* allocate memory for control, only in case of multiple configs */
+ if (num_params > 1) {
+ w_param_text = devm_kcalloc(card->dev, num_params,
+ sizeof(char *), GFP_KERNEL);
+ if (!w_param_text) {
+ ret = -ENOMEM;
+ goto param_fail;
+ }
+ template.num_kcontrols = 1;
+ template.kcontrol_news =
+ snd_soc_dapm_alloc_kcontrol(card,
+ link_name, params, num_params,
+ w_param_text, &private_value);
+ if (!template.kcontrol_news) {
+ ret = -ENOMEM;
+ goto param_fail;
+ }
+ } else {
+ w_param_text = NULL;
+ }
dev_dbg(card->dev, "ASoC: adding %s widget\n", link_name);
w = snd_soc_dapm_new_control_unlocked(&card->dapm, &template);
@@ -3903,15 +3939,9 @@ outfree_w:
devm_kfree(card->dev, w);
outfree_kcontrol_news:
devm_kfree(card->dev, (void *)template.kcontrol_news);
-outfree_private_value:
- devm_kfree(card->dev, (void *)private_value);
-outfree_link_name:
+ snd_soc_dapm_free_kcontrol(card, &private_value, num_params, w_param_text);
+param_fail:
devm_kfree(card->dev, link_name);
-outfree_w_param:
- for (count = 0 ; count < num_params; count++)
- devm_kfree(card->dev, (void *)w_param_text[count]);
- devm_kfree(card->dev, w_param_text);
-
return ret;
}
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index 9b3939049cef..20340ade20a7 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -41,6 +41,20 @@ int snd_soc_component_read(struct snd_soc_component *component,
}
EXPORT_SYMBOL_GPL(snd_soc_component_read);
+unsigned int snd_soc_component_read32(struct snd_soc_component *component,
+ unsigned int reg)
+{
+ unsigned int val;
+ int ret;
+
+ ret = snd_soc_component_read(component, reg, &val);
+ if (ret < 0)
+ return -1;
+
+ return val;
+}
+EXPORT_SYMBOL_GPL(snd_soc_component_read32);
+
/**
* snd_soc_component_write() - Write register value
* @component: Component to write to
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 94b88b897c3b..8075856668c2 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -133,16 +133,25 @@ void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream)
*/
bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd)
{
+ struct snd_soc_rtdcom_list *rtdcom;
+ struct snd_soc_component *component;
int i;
bool ignore = true;
if (!rtd->pmdown_time || rtd->dai_link->ignore_pmdown_time)
return true;
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ ignore &= !component->driver->pmdown_time;
+ }
+
+ /* this will be removed */
for (i = 0; i < rtd->num_codecs; i++)
ignore &= rtd->codec_dais[i]->component->ignore_pmdown_time;
- return rtd->cpu_dai->component->ignore_pmdown_time && ignore;
+ return ignore;
}
/**
@@ -459,7 +468,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai;
const char *codec_dai_name = "multicodec";
- int i, ret = 0;
+ int i, ret = 0, __ret;
pinctrl_pm_select_default_state(cpu_dai->dev);
for (i = 0; i < rtd->num_codecs; i++)
@@ -474,7 +483,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
/* startup the audio subsystem */
- if (cpu_dai->driver->ops && cpu_dai->driver->ops->startup) {
+ if (cpu_dai->driver->ops->startup) {
ret = cpu_dai->driver->ops->startup(substream, cpu_dai);
if (ret < 0) {
dev_err(cpu_dai->dev, "ASoC: can't open interface"
@@ -483,7 +492,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
}
}
- if (platform->driver->ops && platform->driver->ops->open) {
+ if (platform && platform->driver->ops && platform->driver->ops->open) {
ret = platform->driver->ops->open(substream);
if (ret < 0) {
dev_err(platform->dev, "ASoC: can't open platform"
@@ -492,9 +501,32 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
}
}
+ ret = 0;
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->ops ||
+ !component->driver->ops->open)
+ continue;
+
+ __ret = component->driver->ops->open(substream);
+ if (__ret < 0) {
+ dev_err(component->dev,
+ "ASoC: can't open component %s: %d\n",
+ component->name, ret);
+ ret = __ret;
+ }
+ }
+ if (ret < 0)
+ goto component_err;
+
for (i = 0; i < rtd->num_codecs; i++) {
codec_dai = rtd->codec_dais[i];
- if (codec_dai->driver->ops && codec_dai->driver->ops->startup) {
+ if (codec_dai->driver->ops->startup) {
ret = codec_dai->driver->ops->startup(substream,
codec_dai);
if (ret < 0) {
@@ -511,7 +543,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
codec_dai->rx_mask = 0;
}
- if (rtd->dai_link->ops && rtd->dai_link->ops->startup) {
+ if (rtd->dai_link->ops->startup) {
ret = rtd->dai_link->ops->startup(substream);
if (ret < 0) {
pr_err("ASoC: %s startup failed: %d\n",
@@ -585,7 +617,7 @@ dynamic:
return 0;
config_err:
- if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
+ if (rtd->dai_link->ops->shutdown)
rtd->dai_link->ops->shutdown(substream);
machine_err:
@@ -598,7 +630,22 @@ codec_dai_err:
codec_dai->driver->ops->shutdown(substream, codec_dai);
}
- if (platform->driver->ops && platform->driver->ops->close)
+component_err:
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->ops ||
+ !component->driver->ops->close)
+ continue;
+
+ component->driver->ops->close(substream);
+ }
+
+ if (platform && platform->driver->ops && platform->driver->ops->close)
platform->driver->ops->close(substream);
platform_err:
@@ -692,12 +739,26 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
codec_dai->driver->ops->shutdown(substream, codec_dai);
}
- if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
+ if (rtd->dai_link->ops->shutdown)
rtd->dai_link->ops->shutdown(substream);
- if (platform->driver->ops && platform->driver->ops->close)
+ if (platform && platform->driver->ops && platform->driver->ops->close)
platform->driver->ops->close(substream);
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->ops ||
+ !component->driver->ops->close)
+ continue;
+
+ component->driver->ops->close(substream);
+ }
+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
if (snd_soc_runtime_ignore_pmdown_time(rtd)) {
/* powered down playback stream now */
@@ -745,13 +806,15 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai;
int i, ret = 0;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
- if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) {
+ if (rtd->dai_link->ops->prepare) {
ret = rtd->dai_link->ops->prepare(substream);
if (ret < 0) {
dev_err(rtd->card->dev, "ASoC: machine prepare error:"
@@ -760,7 +823,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
}
}
- if (platform->driver->ops && platform->driver->ops->prepare) {
+ if (platform && platform->driver->ops && platform->driver->ops->prepare) {
ret = platform->driver->ops->prepare(substream);
if (ret < 0) {
dev_err(platform->dev, "ASoC: platform prepare error:"
@@ -769,9 +832,28 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
}
}
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->ops ||
+ !component->driver->ops->prepare)
+ continue;
+
+ ret = component->driver->ops->prepare(substream);
+ if (ret < 0) {
+ dev_err(component->dev,
+ "ASoC: platform prepare error: %d\n", ret);
+ goto out;
+ }
+ }
+
for (i = 0; i < rtd->num_codecs; i++) {
codec_dai = rtd->codec_dais[i];
- if (codec_dai->driver->ops && codec_dai->driver->ops->prepare) {
+ if (codec_dai->driver->ops->prepare) {
ret = codec_dai->driver->ops->prepare(substream,
codec_dai);
if (ret < 0) {
@@ -783,7 +865,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
}
}
- if (cpu_dai->driver->ops && cpu_dai->driver->ops->prepare) {
+ if (cpu_dai->driver->ops->prepare) {
ret = cpu_dai->driver->ops->prepare(substream, cpu_dai);
if (ret < 0) {
dev_err(cpu_dai->dev,
@@ -829,7 +911,7 @@ int soc_dai_hw_params(struct snd_pcm_substream *substream,
{
int ret;
- if (dai->driver->ops && dai->driver->ops->hw_params) {
+ if (dai->driver->ops->hw_params) {
ret = dai->driver->ops->hw_params(substream, params, dai);
if (ret < 0) {
dev_err(dai->dev, "ASoC: can't set %s hw params: %d\n",
@@ -851,16 +933,13 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int i, ret = 0;
+ int i, ret = 0, __ret;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
-
- ret = soc_pcm_params_symmetry(substream, params);
- if (ret)
- goto out;
-
- if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) {
+ if (rtd->dai_link->ops->hw_params) {
ret = rtd->dai_link->ops->hw_params(substream, params);
if (ret < 0) {
dev_err(rtd->card->dev, "ASoC: machine hw_params"
@@ -915,7 +994,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
if (ret < 0)
goto interface_err;
- if (platform->driver->ops && platform->driver->ops->hw_params) {
+ if (platform && platform->driver->ops && platform->driver->ops->hw_params) {
ret = platform->driver->ops->hw_params(substream, params);
if (ret < 0) {
dev_err(platform->dev, "ASoC: %s hw params failed: %d\n",
@@ -924,18 +1003,62 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
}
}
+ ret = 0;
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->ops ||
+ !component->driver->ops->hw_params)
+ continue;
+
+ __ret = component->driver->ops->hw_params(substream, params);
+ if (__ret < 0) {
+ dev_err(component->dev,
+ "ASoC: %s hw params failed: %d\n",
+ component->name, ret);
+ ret = __ret;
+ }
+ }
+ if (ret < 0)
+ goto component_err;
+
/* store the parameters for each DAIs */
cpu_dai->rate = params_rate(params);
cpu_dai->channels = params_channels(params);
cpu_dai->sample_bits =
snd_pcm_format_physical_width(params_format(params));
+ ret = soc_pcm_params_symmetry(substream, params);
+ if (ret)
+ goto component_err;
out:
mutex_unlock(&rtd->pcm_mutex);
return ret;
+component_err:
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->ops ||
+ !component->driver->ops->hw_free)
+ continue;
+
+ component->driver->ops->hw_free(substream);
+ }
+
+ if (platform && platform->driver->ops && platform->driver->ops->hw_free)
+ platform->driver->ops->hw_free(substream);
+
platform_err:
- if (cpu_dai->driver->ops && cpu_dai->driver->ops->hw_free)
+ if (cpu_dai->driver->ops->hw_free)
cpu_dai->driver->ops->hw_free(substream, cpu_dai);
interface_err:
@@ -944,12 +1067,12 @@ interface_err:
codec_err:
while (--i >= 0) {
struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
- if (codec_dai->driver->ops && codec_dai->driver->ops->hw_free)
+ if (codec_dai->driver->ops->hw_free)
codec_dai->driver->ops->hw_free(substream, codec_dai);
codec_dai->rate = 0;
}
- if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
+ if (rtd->dai_link->ops->hw_free)
rtd->dai_link->ops->hw_free(substream);
mutex_unlock(&rtd->pcm_mutex);
@@ -963,6 +1086,8 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai;
bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
@@ -995,21 +1120,36 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
}
/* free any machine hw params */
- if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
+ if (rtd->dai_link->ops->hw_free)
rtd->dai_link->ops->hw_free(substream);
/* free any DMA resources */
- if (platform->driver->ops && platform->driver->ops->hw_free)
+ if (platform && platform->driver->ops && platform->driver->ops->hw_free)
platform->driver->ops->hw_free(substream);
+ /* free any component resources */
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->ops ||
+ !component->driver->ops->hw_free)
+ continue;
+
+ component->driver->ops->hw_free(substream);
+ }
+
/* now free hw params for the DAIs */
for (i = 0; i < rtd->num_codecs; i++) {
codec_dai = rtd->codec_dais[i];
- if (codec_dai->driver->ops && codec_dai->driver->ops->hw_free)
+ if (codec_dai->driver->ops->hw_free)
codec_dai->driver->ops->hw_free(substream, codec_dai);
}
- if (cpu_dai->driver->ops && cpu_dai->driver->ops->hw_free)
+ if (cpu_dai->driver->ops->hw_free)
cpu_dai->driver->ops->hw_free(substream, cpu_dai);
mutex_unlock(&rtd->pcm_mutex);
@@ -1020,13 +1160,15 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai;
int i, ret;
for (i = 0; i < rtd->num_codecs; i++) {
codec_dai = rtd->codec_dais[i];
- if (codec_dai->driver->ops && codec_dai->driver->ops->trigger) {
+ if (codec_dai->driver->ops->trigger) {
ret = codec_dai->driver->ops->trigger(substream,
cmd, codec_dai);
if (ret < 0)
@@ -1034,19 +1176,35 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
}
}
- if (platform->driver->ops && platform->driver->ops->trigger) {
+ if (platform && platform->driver->ops && platform->driver->ops->trigger) {
ret = platform->driver->ops->trigger(substream, cmd);
if (ret < 0)
return ret;
}
- if (cpu_dai->driver->ops && cpu_dai->driver->ops->trigger) {
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->ops ||
+ !component->driver->ops->trigger)
+ continue;
+
+ ret = component->driver->ops->trigger(substream, cmd);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (cpu_dai->driver->ops->trigger) {
ret = cpu_dai->driver->ops->trigger(substream, cmd, cpu_dai);
if (ret < 0)
return ret;
}
- if (rtd->dai_link->ops && rtd->dai_link->ops->trigger) {
+ if (rtd->dai_link->ops->trigger) {
ret = rtd->dai_link->ops->trigger(substream, cmd);
if (ret < 0)
return ret;
@@ -1065,8 +1223,7 @@ static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream,
for (i = 0; i < rtd->num_codecs; i++) {
codec_dai = rtd->codec_dais[i];
- if (codec_dai->driver->ops &&
- codec_dai->driver->ops->bespoke_trigger) {
+ if (codec_dai->driver->ops->bespoke_trigger) {
ret = codec_dai->driver->ops->bespoke_trigger(substream,
cmd, codec_dai);
if (ret < 0)
@@ -1074,7 +1231,7 @@ static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream,
}
}
- if (cpu_dai->driver->ops && cpu_dai->driver->ops->bespoke_trigger) {
+ if (cpu_dai->driver->ops->bespoke_trigger) {
ret = cpu_dai->driver->ops->bespoke_trigger(substream, cmd, cpu_dai);
if (ret < 0)
return ret;
@@ -1090,6 +1247,8 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai;
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -1098,15 +1257,31 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
snd_pcm_sframes_t codec_delay = 0;
int i;
- if (platform->driver->ops && platform->driver->ops->pointer)
+ if (platform && platform->driver->ops && platform->driver->ops->pointer)
offset = platform->driver->ops->pointer(substream);
- if (cpu_dai->driver->ops && cpu_dai->driver->ops->delay)
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->ops ||
+ !component->driver->ops->pointer)
+ continue;
+
+ /* FIXME: use 1st pointer */
+ offset = component->driver->ops->pointer(substream);
+ break;
+ }
+
+ if (cpu_dai->driver->ops->delay)
delay += cpu_dai->driver->ops->delay(substream, cpu_dai);
for (i = 0; i < rtd->num_codecs; i++) {
codec_dai = rtd->codec_dais[i];
- if (codec_dai->driver->ops && codec_dai->driver->ops->delay)
+ if (codec_dai->driver->ops->delay)
codec_delay = max(codec_delay,
codec_dai->driver->ops->delay(substream,
codec_dai));
@@ -2285,9 +2460,27 @@ static int soc_pcm_ioctl(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_platform *platform = rtd->platform;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
- if (platform->driver->ops && platform->driver->ops->ioctl)
+ if (platform && platform->driver->ops && platform->driver->ops->ioctl)
return platform->driver->ops->ioctl(substream, cmd, arg);
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ /* ignore duplication for now */
+ if (platform && (component == &platform->component))
+ continue;
+
+ if (!component->driver->ops ||
+ !component->driver->ops->ioctl)
+ continue;
+
+ /* FIXME: use 1st ioctl */
+ return component->driver->ops->ioctl(substream, cmd, arg);
+ }
+
return snd_pcm_lib_ioctl(substream, cmd, arg);
}
@@ -2632,12 +2825,163 @@ static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream)
return ret;
}
+static void soc_pcm_private_free(struct snd_pcm *pcm)
+{
+ struct snd_soc_pcm_runtime *rtd = pcm->private_data;
+ struct snd_soc_rtdcom_list *rtdcom;
+ struct snd_soc_component *component;
+
+ for_each_rtdcom(rtd, rtdcom) {
+ /* need to sync the delayed work before releasing resources */
+
+ flush_delayed_work(&rtd->delayed_work);
+ component = rtdcom->component;
+
+ if (component->pcm_free)
+ component->pcm_free(component, pcm);
+ }
+}
+
+static int soc_rtdcom_ack(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_rtdcom_list *rtdcom;
+ struct snd_soc_component *component;
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ if (!component->driver->ops ||
+ !component->driver->ops->ack)
+ continue;
+
+ /* FIXME. it returns 1st ask now */
+ return component->driver->ops->ack(substream);
+ }
+
+ return -EINVAL;
+}
+
+static int soc_rtdcom_copy_user(struct snd_pcm_substream *substream, int channel,
+ unsigned long pos, void __user *buf,
+ unsigned long bytes)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_rtdcom_list *rtdcom;
+ struct snd_soc_component *component;
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ if (!component->driver->ops ||
+ !component->driver->ops->copy_user)
+ continue;
+
+ /* FIXME. it returns 1st copy now */
+ return component->driver->ops->copy_user(substream, channel,
+ pos, buf, bytes);
+ }
+
+ return -EINVAL;
+}
+
+static int soc_rtdcom_copy_kernel(struct snd_pcm_substream *substream, int channel,
+ unsigned long pos, void *buf, unsigned long bytes)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_rtdcom_list *rtdcom;
+ struct snd_soc_component *component;
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ if (!component->driver->ops ||
+ !component->driver->ops->copy_kernel)
+ continue;
+
+ /* FIXME. it returns 1st copy now */
+ return component->driver->ops->copy_kernel(substream, channel,
+ pos, buf, bytes);
+ }
+
+ return -EINVAL;
+}
+
+static int soc_rtdcom_fill_silence(struct snd_pcm_substream *substream, int channel,
+ unsigned long pos, unsigned long bytes)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_rtdcom_list *rtdcom;
+ struct snd_soc_component *component;
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ if (!component->driver->ops ||
+ !component->driver->ops->fill_silence)
+ continue;
+
+ /* FIXME. it returns 1st silence now */
+ return component->driver->ops->fill_silence(substream, channel,
+ pos, bytes);
+ }
+
+ return -EINVAL;
+}
+
+static struct page *soc_rtdcom_page(struct snd_pcm_substream *substream,
+ unsigned long offset)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_rtdcom_list *rtdcom;
+ struct snd_soc_component *component;
+ struct page *page;
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ if (!component->driver->ops ||
+ !component->driver->ops->page)
+ continue;
+
+ /* FIXME. it returns 1st page now */
+ page = component->driver->ops->page(substream, offset);
+ if (page)
+ return page;
+ }
+
+ return NULL;
+}
+
+static int soc_rtdcom_mmap(struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_rtdcom_list *rtdcom;
+ struct snd_soc_component *component;
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ if (!component->driver->ops ||
+ !component->driver->ops->mmap)
+ continue;
+
+ /* FIXME. it returns 1st mmap now */
+ return component->driver->ops->mmap(substream, vma);
+ }
+
+ return -EINVAL;
+}
+
/* create a new pcm */
int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
{
struct snd_soc_platform *platform = rtd->platform;
struct snd_soc_dai *codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_pcm *pcm;
char new_name[64];
int ret = 0, playback = 0, capture = 0;
@@ -2732,7 +3076,28 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
rtd->ops.ioctl = soc_pcm_ioctl;
}
- if (platform->driver->ops) {
+ for_each_rtdcom(rtd, rtdcom) {
+ const struct snd_pcm_ops *ops = rtdcom->component->driver->ops;
+
+ if (!ops)
+ continue;
+
+ if (ops->ack)
+ rtd->ops.ack = soc_rtdcom_ack;
+ if (ops->copy_user)
+ rtd->ops.copy_user = soc_rtdcom_copy_user;
+ if (ops->copy_kernel)
+ rtd->ops.copy_kernel = soc_rtdcom_copy_kernel;
+ if (ops->fill_silence)
+ rtd->ops.fill_silence = soc_rtdcom_fill_silence;
+ if (ops->page)
+ rtd->ops.page = soc_rtdcom_page;
+ if (ops->mmap)
+ rtd->ops.mmap = soc_rtdcom_mmap;
+ }
+
+ /* overwrite */
+ if (platform && platform->driver->ops) {
rtd->ops.ack = platform->driver->ops->ack;
rtd->ops.copy_user = platform->driver->ops->copy_user;
rtd->ops.copy_kernel = platform->driver->ops->copy_kernel;
@@ -2747,17 +3112,22 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
if (capture)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops);
- if (platform->driver->pcm_new) {
- ret = platform->driver->pcm_new(rtd);
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ if (!component->pcm_new)
+ continue;
+
+ ret = component->pcm_new(component, rtd);
if (ret < 0) {
- dev_err(platform->dev,
+ dev_err(component->dev,
"ASoC: pcm constructor failed: %d\n",
ret);
return ret;
}
}
- pcm->private_free = platform->driver->pcm_free;
+ pcm->private_free = soc_pcm_private_free;
out:
dev_info(rtd->card->dev, "%s <-> %s mapping ok\n",
(rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name,
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c
index dd471d2c0266..01a50413c66f 100644
--- a/sound/soc/soc-topology.c
+++ b/sound/soc/soc-topology.c
@@ -1301,7 +1301,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create(
/* validate kcontrol */
if (strnlen(ec->hdr.name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) ==
SNDRV_CTL_ELEM_ID_NAME_MAXLEN)
- return NULL;
+ goto err;
se = kzalloc(sizeof(*se), GFP_KERNEL);
if (se == NULL)
@@ -1378,6 +1378,9 @@ err_se:
for (; i >= 0; i--) {
/* free values and texts */
se = (struct soc_enum *)kc[i].private_value;
+ if (!se)
+ continue;
+
kfree(se->dobj.control.dvalues);
for (j = 0; j < ec->items; j++)
kfree(se->dobj.control.dtexts[j]);
diff --git a/sound/soc/spear/Makefile b/sound/soc/spear/Makefile
index c4ea7161056c..31d9dae280e7 100644
--- a/sound/soc/spear/Makefile
+++ b/sound/soc/spear/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# SPEAR Platform Support
snd-soc-spear-pcm-objs := spear_pcm.o
snd-soc-spear-spdif-in-objs := spdif_in.o
diff --git a/sound/soc/stm/Makefile b/sound/soc/stm/Makefile
index 4ed22e648a9a..5b7f0fab0bd6 100644
--- a/sound/soc/stm/Makefile
+++ b/sound/soc/stm/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# SAI
snd-soc-stm32-sai-sub-objs := stm32_sai_sub.o
obj-$(CONFIG_SND_SOC_STM32_SAI) += snd-soc-stm32-sai-sub.o
diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c
index 1258bef4dcb3..5fe878ace605 100644
--- a/sound/soc/stm/stm32_sai.c
+++ b/sound/soc/stm/stm32_sai.c
@@ -85,7 +85,7 @@ static int stm32_sai_probe(struct platform_device *pdev)
}
/* reset */
- rst = reset_control_get_exclusive(&pdev->dev, NULL);
+ rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (!IS_ERR(rst)) {
reset_control_assert(rst);
udelay(2);
diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c
index 90d439613899..dde8ddf9e777 100644
--- a/sound/soc/stm/stm32_sai_sub.c
+++ b/sound/soc/stm/stm32_sai_sub.c
@@ -184,7 +184,6 @@ static const struct regmap_config stm32_sai_sub_regmap_config_h7 = {
static irqreturn_t stm32_sai_isr(int irq, void *devid)
{
struct stm32_sai_sub_data *sai = (struct stm32_sai_sub_data *)devid;
- struct snd_pcm_substream *substream = sai->substream;
struct platform_device *pdev = sai->pdev;
unsigned int sr, imr, flags;
snd_pcm_state_t status = SNDRV_PCM_STATE_RUNNING;
@@ -199,6 +198,11 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid)
regmap_update_bits(sai->regmap, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK,
SAI_XCLRFR_MASK);
+ if (!sai->substream) {
+ dev_err(&pdev->dev, "Device stopped. Spurious IRQ 0x%x\n", sr);
+ return IRQ_NONE;
+ }
+
if (flags & SAI_XIMR_OVRUDRIE) {
dev_err(&pdev->dev, "IRQ %s\n",
STM_SAI_IS_PLAYBACK(sai) ? "underrun" : "overrun");
@@ -227,9 +231,9 @@ static irqreturn_t stm32_sai_isr(int irq, void *devid)
}
if (status != SNDRV_PCM_STATE_RUNNING) {
- snd_pcm_stream_lock(substream);
- snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
- snd_pcm_stream_unlock(substream);
+ snd_pcm_stream_lock(sai->substream);
+ snd_pcm_stop(sai->substream, SNDRV_PCM_STATE_XRUN);
+ snd_pcm_stream_unlock(sai->substream);
}
return IRQ_HANDLED;
@@ -442,12 +446,16 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
{
struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
int cr1, cr1_mask, ret;
- int fth = STM_SAI_FIFO_TH_HALF;
- /* FIFO config */
+ /*
+ * DMA bursts increment is set to 4 words.
+ * SAI fifo threshold is set to half fifo, to keep enough space
+ * for DMA incoming bursts.
+ */
regmap_update_bits(sai->regmap, STM_SAI_CR2_REGX,
SAI_XCR2_FFLUSH | SAI_XCR2_FTH_MASK,
- SAI_XCR2_FFLUSH | SAI_XCR2_FTH_SET(fth));
+ SAI_XCR2_FFLUSH |
+ SAI_XCR2_FTH_SET(STM_SAI_FIFO_TH_HALF));
/* Mode, data format and channel config */
cr1 = SAI_XCR1_PRTCFG_SET(SAI_FREE_PROTOCOL);
@@ -481,10 +489,6 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
return ret;
}
- /* DMA config */
- sai->dma_params.maxburst = STM_SAI_FIFO_SIZE * fth / sizeof(u32);
- snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&sai->dma_params);
-
return 0;
}
@@ -727,7 +731,12 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai)
struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
sai->dma_params.addr = (dma_addr_t)(sai->phys_addr + STM_SAI_DR_REGX);
- sai->dma_params.maxburst = 1;
+ /*
+ * DMA supports 4, 8 or 16 burst sizes. Burst size 4 is the best choice,
+ * as it allows bytes, half-word and words transfers. (See DMA fifos
+ * constraints).
+ */
+ sai->dma_params.maxburst = 4;
/* Buswidth will be set by framework at runtime */
sai->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
index 1f1af6271731..4a9ef67386ca 100644
--- a/sound/soc/sunxi/Makefile
+++ b/sound/soc/sunxi/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
index abfb710df7cb..50a9e077f01b 100644
--- a/sound/soc/sunxi/sun8i-codec.c
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -73,6 +73,7 @@
#define SUN8I_SYS_SR_CTRL_AIF2_FS_MASK GENMASK(11, 8)
#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_MASK GENMASK(5, 4)
#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_MASK GENMASK(8, 6)
+#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV_MASK GENMASK(12, 9)
struct sun8i_codec {
struct device *dev;
@@ -170,11 +171,11 @@ static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
/* clock masters */
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBS_CFS: /* DAI Slave */
- value = 0x0; /* Codec Master */
+ case SND_SOC_DAIFMT_CBS_CFS: /* Codec slave, DAI master */
+ value = 0x1;
break;
- case SND_SOC_DAIFMT_CBM_CFM: /* DAI Master */
- value = 0x1; /* Codec Slave */
+ case SND_SOC_DAIFMT_CBM_CFM: /* Codec Master, DAI slave */
+ value = 0x0;
break;
default:
return -EINVAL;
@@ -226,12 +227,57 @@ static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return 0;
}
+struct sun8i_codec_clk_div {
+ u8 div;
+ u8 val;
+};
+
+static const struct sun8i_codec_clk_div sun8i_codec_bclk_div[] = {
+ { .div = 1, .val = 0 },
+ { .div = 2, .val = 1 },
+ { .div = 4, .val = 2 },
+ { .div = 6, .val = 3 },
+ { .div = 8, .val = 4 },
+ { .div = 12, .val = 5 },
+ { .div = 16, .val = 6 },
+ { .div = 24, .val = 7 },
+ { .div = 32, .val = 8 },
+ { .div = 48, .val = 9 },
+ { .div = 64, .val = 10 },
+ { .div = 96, .val = 11 },
+ { .div = 128, .val = 12 },
+ { .div = 192, .val = 13 },
+};
+
+static u8 sun8i_codec_get_bclk_div(struct sun8i_codec *scodec,
+ unsigned int rate,
+ unsigned int word_size)
+{
+ unsigned long clk_rate = clk_get_rate(scodec->clk_module);
+ unsigned int div = clk_rate / rate / word_size / 2;
+ unsigned int best_val = 0, best_diff = ~0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sun8i_codec_bclk_div); i++) {
+ const struct sun8i_codec_clk_div *bdiv = &sun8i_codec_bclk_div[i];
+ unsigned int diff = abs(bdiv->div - div);
+
+ if (diff < best_diff) {
+ best_diff = diff;
+ best_val = bdiv->val;
+ }
+ }
+
+ return best_val;
+}
+
static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
int sample_rate;
+ u8 bclk_div;
/*
* The CPU DAI handles only a sample of 16 bits. Configure the
@@ -241,6 +287,11 @@ static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_MASK,
SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_16);
+ bclk_div = sun8i_codec_get_bclk_div(scodec, params_rate(params), 16);
+ regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
+ SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV_MASK,
+ bclk_div << SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV);
+
regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_MASK,
SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_16);
diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile
index f214a3fd0024..2329b72c93e3 100644
--- a/sound/soc/tegra/Makefile
+++ b/sound/soc/tegra/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# Tegra platform Support
snd-soc-tegra-pcm-objs := tegra_pcm.o
snd-soc-tegra-utils-objs += tegra_asoc_utils.o
diff --git a/sound/soc/txx9/Makefile b/sound/soc/txx9/Makefile
index 551f16c0c4f9..37ad833eb329 100644
--- a/sound/soc/txx9/Makefile
+++ b/sound/soc/txx9/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# Platform
snd-soc-txx9aclc-objs := txx9aclc.o
snd-soc-txx9aclc-ac97-objs := txx9aclc-ac97.o
diff --git a/sound/soc/ux500/Makefile b/sound/soc/ux500/Makefile
index cce0c11a4d86..e7d6de51b32b 100644
--- a/sound/soc/ux500/Makefile
+++ b/sound/soc/ux500/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# Ux500 Platform Support
snd-soc-ux500-plat-msp-i2s-objs := ux500_msp_dai.o ux500_msp_i2s.o
diff --git a/sound/sparc/Makefile b/sound/sparc/Makefile
index 3cd89c67c2f2..e1f596571d7f 100644
--- a/sound/sparc/Makefile
+++ b/sound/sparc/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 2002 by David S. Miller <davem@redhat.com>
diff --git a/sound/spi/Makefile b/sound/spi/Makefile
index 026fb73f887f..a3834919b0f6 100644
--- a/sound/spi/Makefile
+++ b/sound/spi/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
# Makefile for SPI drivers
snd-at73c213-objs := at73c213.o
diff --git a/sound/synth/Makefile b/sound/synth/Makefile
index 11eb06ac2eca..b9f71d5dbc8c 100644
--- a/sound/synth/Makefile
+++ b/sound/synth/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/synth/emux/Makefile b/sound/synth/emux/Makefile
index d1bac923eb1b..ed28c81ac12e 100644
--- a/sound/synth/emux/Makefile
+++ b/sound/synth/emux/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
# Copyright (c) 2001 by Jaroslav Kysela <perex@perex.cz>
diff --git a/sound/usb/Makefile b/sound/usb/Makefile
index 42cb33b94f6a..05440e2df8d9 100644
--- a/sound/usb/Makefile
+++ b/sound/usb/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for ALSA
#
diff --git a/sound/usb/caiaq/audio.h b/sound/usb/caiaq/audio.h
index bdf155300a8a..869bf6264d6a 100644
--- a/sound/usb/caiaq/audio.h
+++ b/sound/usb/caiaq/audio.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef CAIAQ_AUDIO_H
#define CAIAQ_AUDIO_H
diff --git a/sound/usb/caiaq/control.h b/sound/usb/caiaq/control.h
index 501c4883aef6..cb204fd45858 100644
--- a/sound/usb/caiaq/control.h
+++ b/sound/usb/caiaq/control.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef CAIAQ_CONTROL_H
#define CAIAQ_CONTROL_H
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index 0fb6b1b79261..d8409d9ae55b 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -469,10 +469,12 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
err = snd_usb_caiaq_send_command(cdev, EP1_CMD_GET_DEVICE_INFO, NULL, 0);
if (err)
- return err;
+ goto err_kill_urb;
- if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ))
- return -ENODEV;
+ if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) {
+ err = -ENODEV;
+ goto err_kill_urb;
+ }
usb_string(usb_dev, usb_dev->descriptor.iManufacturer,
cdev->vendor_name, CAIAQ_USB_STR_LEN);
@@ -507,6 +509,10 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
setup_card(cdev);
return 0;
+
+ err_kill_urb:
+ usb_kill_urb(&cdev->ep1_in_urb);
+ return err;
}
static int snd_probe(struct usb_interface *intf,
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h
index ab0f7520a99b..50fea085765b 100644
--- a/sound/usb/caiaq/device.h
+++ b/sound/usb/caiaq/device.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef CAIAQ_DEVICE_H
#define CAIAQ_DEVICE_H
diff --git a/sound/usb/caiaq/input.h b/sound/usb/caiaq/input.h
index 6014e2713a60..c42891e7be88 100644
--- a/sound/usb/caiaq/input.h
+++ b/sound/usb/caiaq/input.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef CAIAQ_INPUT_H
#define CAIAQ_INPUT_H
diff --git a/sound/usb/caiaq/midi.h b/sound/usb/caiaq/midi.h
index 60bf3442b283..a6ae0c22484d 100644
--- a/sound/usb/caiaq/midi.h
+++ b/sound/usb/caiaq/midi.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef CAIAQ_MIDI_H
#define CAIAQ_MIDI_H
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 3dc36d913550..23d1d23aefec 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -221,6 +221,7 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
struct usb_interface_descriptor *altsd;
void *control_header;
int i, protocol;
+ int rest_bytes;
/* find audiocontrol interface */
host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
@@ -235,6 +236,15 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
return -EINVAL;
}
+ rest_bytes = (void *)(host_iface->extra + host_iface->extralen) -
+ control_header;
+
+ /* just to be sure -- this shouldn't hit at all */
+ if (rest_bytes <= 0) {
+ dev_err(&dev->dev, "invalid control header\n");
+ return -EINVAL;
+ }
+
switch (protocol) {
default:
dev_warn(&dev->dev,
@@ -245,11 +255,21 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
case UAC_VERSION_1: {
struct uac1_ac_header_descriptor *h1 = control_header;
+ if (rest_bytes < sizeof(*h1)) {
+ dev_err(&dev->dev, "too short v1 buffer descriptor\n");
+ return -EINVAL;
+ }
+
if (!h1->bInCollection) {
dev_info(&dev->dev, "skipping empty audio interface (v1)\n");
return -EINVAL;
}
+ if (rest_bytes < h1->bLength) {
+ dev_err(&dev->dev, "invalid buffer length (v1)\n");
+ return -EINVAL;
+ }
+
if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
dev_err(&dev->dev, "invalid UAC_HEADER (v1)\n");
return -EINVAL;
diff --git a/sound/usb/card.h b/sound/usb/card.h
index 111b0f009afa..ed87cc83eb47 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __USBAUDIO_CARD_H
#define __USBAUDIO_CARD_H
diff --git a/sound/usb/clock.h b/sound/usb/clock.h
index d592e4a29856..87557cae1a0b 100644
--- a/sound/usb/clock.h
+++ b/sound/usb/clock.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __USBAUDIO_CLOCK_H
#define __USBAUDIO_CLOCK_H
diff --git a/sound/usb/debug.h b/sound/usb/debug.h
index 58030176f008..7dd983c35001 100644
--- a/sound/usb/debug.h
+++ b/sound/usb/debug.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __USBAUDIO_DEBUG_H
#define __USBAUDIO_DEBUG_H
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
index 584f295d7c77..63a39d4fa8d8 100644
--- a/sound/usb/endpoint.h
+++ b/sound/usb/endpoint.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __USBAUDIO_ENDPOINT_H
#define __USBAUDIO_ENDPOINT_H
diff --git a/sound/usb/format.h b/sound/usb/format.h
index 4b8a01129f24..8c3ff9ce0824 100644
--- a/sound/usb/format.h
+++ b/sound/usb/format.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __USBAUDIO_FORMAT_H
#define __USBAUDIO_FORMAT_H
diff --git a/sound/usb/helper.h b/sound/usb/helper.h
index 805c300dd004..4463e6d6dcb3 100644
--- a/sound/usb/helper.h
+++ b/sound/usb/helper.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __USBAUDIO_HELPER_H
#define __USBAUDIO_HELPER_H
diff --git a/sound/usb/line6/Makefile b/sound/usb/line6/Makefile
index b8b3b2a543d8..4ba98eb32119 100644
--- a/sound/usb/line6/Makefile
+++ b/sound/usb/line6/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-usb-line6-y := \
capture.o \
driver.o \
diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
index 0ff5a7d2e19f..c8f723c3a033 100644
--- a/sound/usb/line6/driver.c
+++ b/sound/usb/line6/driver.c
@@ -779,9 +779,10 @@ int line6_probe(struct usb_interface *interface,
return 0;
error:
- if (line6->disconnect)
- line6->disconnect(line6);
- snd_card_free(card);
+ /* we can call disconnect callback here because no close-sync is
+ * needed yet at this point
+ */
+ line6_disconnect(interface);
return ret;
}
EXPORT_SYMBOL_GPL(line6_probe);
diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c
index 956f847a96e4..451007c27743 100644
--- a/sound/usb/line6/podhd.c
+++ b/sound/usb/line6/podhd.c
@@ -301,7 +301,8 @@ static void podhd_disconnect(struct usb_line6 *line6)
intf = usb_ifnum_to_if(line6->usbdev,
pod->line6.properties->ctrl_if);
- usb_driver_release_interface(&podhd_driver, intf);
+ if (intf)
+ usb_driver_release_interface(&podhd_driver, intf);
}
}
@@ -317,6 +318,9 @@ static int podhd_init(struct usb_line6 *line6,
line6->disconnect = podhd_disconnect;
+ init_timer(&pod->startup_timer);
+ INIT_WORK(&pod->startup_work, podhd_startup_workqueue);
+
if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) {
/* claim the data interface */
intf = usb_ifnum_to_if(line6->usbdev,
@@ -358,8 +362,6 @@ static int podhd_init(struct usb_line6 *line6,
}
/* init device and delay registering */
- init_timer(&pod->startup_timer);
- INIT_WORK(&pod->startup_work, podhd_startup_workqueue);
podhd_startup(pod);
return 0;
}
diff --git a/sound/usb/midi.h b/sound/usb/midi.h
index 5e25a3fd6c1d..8c38aec22999 100644
--- a/sound/usb/midi.h
+++ b/sound/usb/midi.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __USBMIDI_H
#define __USBMIDI_H
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 9732edf77f86..91bc8f18791e 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -2234,6 +2234,9 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
static void snd_usb_mixer_free(struct usb_mixer_interface *mixer)
{
+ /* kill pending URBs */
+ snd_usb_mixer_disconnect(mixer);
+
kfree(mixer->id_elems);
if (mixer->urb) {
kfree(mixer->urb->transfer_buffer);
@@ -2584,8 +2587,13 @@ _error:
void snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer)
{
- usb_kill_urb(mixer->urb);
- usb_kill_urb(mixer->rc_urb);
+ if (mixer->disconnected)
+ return;
+ if (mixer->urb)
+ usb_kill_urb(mixer->urb);
+ if (mixer->rc_urb)
+ usb_kill_urb(mixer->rc_urb);
+ mixer->disconnected = true;
}
#ifdef CONFIG_PM
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index 2b4b067646ab..ba27f7ade670 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __USBMIXER_H
#define __USBMIXER_H
@@ -22,6 +23,8 @@ struct usb_mixer_interface {
struct urb *rc_urb;
struct usb_ctrlrequest *rc_setup_packet;
u8 rc_buffer[6];
+
+ bool disconnected;
};
#define MAX_CHANNELS 16 /* max logical channels */
diff --git a/sound/usb/mixer_quirks.h b/sound/usb/mixer_quirks.h
index 177c329cd4dd..b5abd328a361 100644
--- a/sound/usb/mixer_quirks.h
+++ b/sound/usb/mixer_quirks.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef SND_USB_MIXER_QUIRKS_H
#define SND_USB_MIXER_QUIRKS_H
diff --git a/sound/usb/mixer_scarlett.h b/sound/usb/mixer_scarlett.h
index 19c592ab0332..bbf063b79370 100644
--- a/sound/usb/mixer_scarlett.h
+++ b/sound/usb/mixer_scarlett.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __USB_MIXER_SCARLETT_H
#define __USB_MIXER_SCARLETT_H
diff --git a/sound/usb/mixer_us16x08.h b/sound/usb/mixer_us16x08.h
index a6312fb0f962..56ff16c0698f 100644
--- a/sound/usb/mixer_us16x08.h
+++ b/sound/usb/mixer_us16x08.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __USB_MIXER_US16X08_H
#define __USB_MIXER_US16X08_H
diff --git a/sound/usb/pcm.h b/sound/usb/pcm.h
index df7a003682ad..35740d5ef268 100644
--- a/sound/usb/pcm.h
+++ b/sound/usb/pcm.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __USBAUDIO_PCM_H
#define __USBAUDIO_PCM_H
diff --git a/sound/usb/power.h b/sound/usb/power.h
index 48ee51dcb71e..b2e25f60c5a2 100644
--- a/sound/usb/power.h
+++ b/sound/usb/power.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __USBAUDIO_POWER_H
#define __USBAUDIO_POWER_H
diff --git a/sound/usb/proc.h b/sound/usb/proc.h
index a45b765e4cf1..72b1b2d28b44 100644
--- a/sound/usb/proc.h
+++ b/sound/usb/proc.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __USBAUDIO_PROC_H
#define __USBAUDIO_PROC_H
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 913552078285..4f5f18f22974 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1137,6 +1137,9 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
case USB_ID(0x047F, 0x02F7): /* Plantronics BT-600 */
case USB_ID(0x047F, 0x0415): /* Plantronics BT-300 */
case USB_ID(0x047F, 0xAA05): /* Plantronics DA45 */
+ case USB_ID(0x047F, 0xC022): /* Plantronics C310 */
+ case USB_ID(0x047F, 0xC02F): /* Plantronics P610 */
+ case USB_ID(0x047F, 0xC036): /* Plantronics C520-M */
case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */
case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */
case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */
@@ -1351,6 +1354,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */
case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */
case USB_ID(0x22d9, 0x0416): /* OPPO HA-1 */
+ case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */
if (fp->altsetting == 2)
return SNDRV_PCM_FMTBIT_DSD_U32_BE;
break;
diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h
index 192ff5ce9452..b90c8b7caab5 100644
--- a/sound/usb/quirks.h
+++ b/sound/usb/quirks.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __USBAUDIO_QUIRKS_H
#define __USBAUDIO_QUIRKS_H
diff --git a/sound/usb/stream.h b/sound/usb/stream.h
index c97f679fc84f..d92e18d5818f 100644
--- a/sound/usb/stream.h
+++ b/sound/usb/stream.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __USBAUDIO_STREAM_H
#define __USBAUDIO_STREAM_H
diff --git a/sound/usb/usx2y/Makefile b/sound/usb/usx2y/Makefile
index 748933054b6c..cc4c2f1efab2 100644
--- a/sound/usb/usx2y/Makefile
+++ b/sound/usb/usx2y/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
snd-usb-usx2y-objs := usbusx2y.o usX2Yhwdep.o usx2yhwdeppcm.o
snd-usb-us122l-objs := us122l.o
diff --git a/sound/usb/usx2y/us122l.h b/sound/usb/usx2y/us122l.h
index 3e2a2d0041ee..34bea99d343c 100644
--- a/sound/usb/usx2y/us122l.h
+++ b/sound/usb/usx2y/us122l.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef US122L_H
#define US122L_H
diff --git a/sound/usb/usx2y/usX2Yhwdep.h b/sound/usb/usx2y/usX2Yhwdep.h
index c095d5bf1220..457199b5ed03 100644
--- a/sound/usb/usx2y/usX2Yhwdep.h
+++ b/sound/usb/usx2y/usX2Yhwdep.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef USX2YHWDEP_H
#define USX2YHWDEP_H
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
index 4dab49080700..e229abd21652 100644
--- a/sound/usb/usx2y/usb_stream.c
+++ b/sound/usb/usx2y/usb_stream.c
@@ -191,7 +191,8 @@ struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
}
pg = get_order(read_size);
- sk->s = (void *) __get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO, pg);
+ sk->s = (void *) __get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO|
+ __GFP_NOWARN, pg);
if (!sk->s) {
snd_printk(KERN_WARNING "couldn't __get_free_pages()\n");
goto out;
@@ -211,7 +212,8 @@ struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
pg = get_order(write_size);
sk->write_page =
- (void *)__get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO, pg);
+ (void *)__get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO|
+ __GFP_NOWARN, pg);
if (!sk->write_page) {
snd_printk(KERN_WARNING "couldn't __get_free_pages()\n");
usb_stream_free(sk);
diff --git a/sound/usb/usx2y/usb_stream.h b/sound/usb/usx2y/usb_stream.h
index 90369001eab6..851358a8d709 100644
--- a/sound/usb/usx2y/usb_stream.h
+++ b/sound/usb/usx2y/usb_stream.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __USB_STREAM_H
#define __USB_STREAM_H
diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h
index 6ae6b0806938..e0f77172ce8f 100644
--- a/sound/usb/usx2y/usbusx2y.h
+++ b/sound/usb/usx2y/usbusx2y.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef USBUSX2Y_H
#define USBUSX2Y_H
#include "../usbaudio.h"
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.h b/sound/usb/usx2y/usx2yhwdeppcm.h
index 9c4fb84b2aa0..eb5a46466f0e 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.h
+++ b/sound/usb/usx2y/usx2yhwdeppcm.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#define MAXPACK 50
#define MAXBUFFERMS 100
#define MAXSTRIDE 3