--- /dev/null
+From 9f35a31283775e6f6af73fb2c95c686a4c0acac7 Mon Sep 17 00:00:00 2001
+From: Alexander Tsoy <alexander@tsoy.me>
+Date: Thu, 13 Feb 2020 02:54:50 +0300
+Subject: ALSA: usb-audio: Add clock validity quirk for Denon MC7000/MCX8000
+
+From: Alexander Tsoy <alexander@tsoy.me>
+
+commit 9f35a31283775e6f6af73fb2c95c686a4c0acac7 upstream.
+
+It should be safe to ignore clock validity check result if the following
+conditions are met:
+ - only one single sample rate is supported;
+ - the terminal is directly connected to the clock source;
+ - the clock type is internal.
+
+This is to deal with some Denon DJ controllers that always reports that
+clock is invalid.
+
+Tested-by: Tobias Oszlanyi <toszlanyi@yahoo.de>
+Signed-off-by: Alexander Tsoy <alexander@tsoy.me>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200212235450.697348-1-alexander@tsoy.me
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/usb/clock.c | 91 ++++++++++++++++++++++++++++++++++++-----------------
+ sound/usb/clock.h | 4 +-
+ sound/usb/format.c | 3 -
+ 3 files changed, 66 insertions(+), 32 deletions(-)
+
+--- a/sound/usb/clock.c
++++ b/sound/usb/clock.c
+@@ -151,8 +151,34 @@ static int uac_clock_selector_set_val(st
+ return ret;
+ }
+
++/*
++ * Assume the clock is valid if clock source supports only one single sample
++ * rate, the terminal is connected directly to it (there is no clock selector)
++ * and clock type is internal. This is to deal with some Denon DJ controllers
++ * that always reports that clock is invalid.
++ */
++static bool uac_clock_source_is_valid_quirk(struct snd_usb_audio *chip,
++ struct audioformat *fmt,
++ int source_id)
++{
++ if (fmt->protocol == UAC_VERSION_2) {
++ struct uac_clock_source_descriptor *cs_desc =
++ snd_usb_find_clock_source(chip->ctrl_intf, source_id);
++
++ if (!cs_desc)
++ return false;
++
++ return (fmt->nr_rates == 1 &&
++ (fmt->clock & 0xff) == cs_desc->bClockID &&
++ (cs_desc->bmAttributes & 0x3) !=
++ UAC_CLOCK_SOURCE_TYPE_EXT);
++ }
++
++ return false;
++}
++
+ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip,
+- int protocol,
++ struct audioformat *fmt,
+ int source_id)
+ {
+ int err;
+@@ -160,7 +186,7 @@ static bool uac_clock_source_is_valid(st
+ struct usb_device *dev = chip->dev;
+ u32 bmControls;
+
+- if (protocol == UAC_VERSION_3) {
++ if (fmt->protocol == UAC_VERSION_3) {
+ struct uac3_clock_source_descriptor *cs_desc =
+ snd_usb_find_clock_source_v3(chip->ctrl_intf, source_id);
+
+@@ -194,10 +220,14 @@ static bool uac_clock_source_is_valid(st
+ return false;
+ }
+
+- return data ? true : false;
++ if (data)
++ return true;
++ else
++ return uac_clock_source_is_valid_quirk(chip, fmt, source_id);
+ }
+
+-static int __uac_clock_find_source(struct snd_usb_audio *chip, int entity_id,
++static int __uac_clock_find_source(struct snd_usb_audio *chip,
++ struct audioformat *fmt, int entity_id,
+ unsigned long *visited, bool validate)
+ {
+ struct uac_clock_source_descriptor *source;
+@@ -217,7 +247,7 @@ static int __uac_clock_find_source(struc
+ source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id);
+ if (source) {
+ entity_id = source->bClockID;
+- if (validate && !uac_clock_source_is_valid(chip, UAC_VERSION_2,
++ if (validate && !uac_clock_source_is_valid(chip, fmt,
+ entity_id)) {
+ usb_audio_err(chip,
+ "clock source %d is not valid, cannot use\n",
+@@ -248,8 +278,9 @@ static int __uac_clock_find_source(struc
+ }
+
+ cur = ret;
+- ret = __uac_clock_find_source(chip, selector->baCSourceID[ret - 1],
+- visited, validate);
++ ret = __uac_clock_find_source(chip, fmt,
++ selector->baCSourceID[ret - 1],
++ visited, validate);
+ if (!validate || ret > 0 || !chip->autoclock)
+ return ret;
+
+@@ -260,8 +291,9 @@ static int __uac_clock_find_source(struc
+ if (i == cur)
+ continue;
+
+- ret = __uac_clock_find_source(chip, selector->baCSourceID[i - 1],
+- visited, true);
++ ret = __uac_clock_find_source(chip, fmt,
++ selector->baCSourceID[i - 1],
++ visited, true);
+ if (ret < 0)
+ continue;
+
+@@ -281,14 +313,16 @@ static int __uac_clock_find_source(struc
+ /* FIXME: multipliers only act as pass-thru element for now */
+ multiplier = snd_usb_find_clock_multiplier(chip->ctrl_intf, entity_id);
+ if (multiplier)
+- return __uac_clock_find_source(chip, multiplier->bCSourceID,
+- visited, validate);
++ return __uac_clock_find_source(chip, fmt,
++ multiplier->bCSourceID,
++ visited, validate);
+
+ return -EINVAL;
+ }
+
+-static int __uac3_clock_find_source(struct snd_usb_audio *chip, int entity_id,
+- unsigned long *visited, bool validate)
++static int __uac3_clock_find_source(struct snd_usb_audio *chip,
++ struct audioformat *fmt, int entity_id,
++ unsigned long *visited, bool validate)
+ {
+ struct uac3_clock_source_descriptor *source;
+ struct uac3_clock_selector_descriptor *selector;
+@@ -307,7 +341,7 @@ static int __uac3_clock_find_source(stru
+ source = snd_usb_find_clock_source_v3(chip->ctrl_intf, entity_id);
+ if (source) {
+ entity_id = source->bClockID;
+- if (validate && !uac_clock_source_is_valid(chip, UAC_VERSION_3,
++ if (validate && !uac_clock_source_is_valid(chip, fmt,
+ entity_id)) {
+ usb_audio_err(chip,
+ "clock source %d is not valid, cannot use\n",
+@@ -338,7 +372,8 @@ static int __uac3_clock_find_source(stru
+ }
+
+ cur = ret;
+- ret = __uac3_clock_find_source(chip, selector->baCSourceID[ret - 1],
++ ret = __uac3_clock_find_source(chip, fmt,
++ selector->baCSourceID[ret - 1],
+ visited, validate);
+ if (!validate || ret > 0 || !chip->autoclock)
+ return ret;
+@@ -350,8 +385,9 @@ static int __uac3_clock_find_source(stru
+ if (i == cur)
+ continue;
+
+- ret = __uac3_clock_find_source(chip, selector->baCSourceID[i - 1],
+- visited, true);
++ ret = __uac3_clock_find_source(chip, fmt,
++ selector->baCSourceID[i - 1],
++ visited, true);
+ if (ret < 0)
+ continue;
+
+@@ -372,7 +408,8 @@ static int __uac3_clock_find_source(stru
+ multiplier = snd_usb_find_clock_multiplier_v3(chip->ctrl_intf,
+ entity_id);
+ if (multiplier)
+- return __uac3_clock_find_source(chip, multiplier->bCSourceID,
++ return __uac3_clock_find_source(chip, fmt,
++ multiplier->bCSourceID,
+ visited, validate);
+
+ return -EINVAL;
+@@ -389,18 +426,18 @@ static int __uac3_clock_find_source(stru
+ *
+ * Returns the clock source UnitID (>=0) on success, or an error.
+ */
+-int snd_usb_clock_find_source(struct snd_usb_audio *chip, int protocol,
+- int entity_id, bool validate)
++int snd_usb_clock_find_source(struct snd_usb_audio *chip,
++ struct audioformat *fmt, bool validate)
+ {
+ DECLARE_BITMAP(visited, 256);
+ memset(visited, 0, sizeof(visited));
+
+- switch (protocol) {
++ switch (fmt->protocol) {
+ case UAC_VERSION_2:
+- return __uac_clock_find_source(chip, entity_id, visited,
++ return __uac_clock_find_source(chip, fmt, fmt->clock, visited,
+ validate);
+ case UAC_VERSION_3:
+- return __uac3_clock_find_source(chip, entity_id, visited,
++ return __uac3_clock_find_source(chip, fmt, fmt->clock, visited,
+ validate);
+ default:
+ return -EINVAL;
+@@ -501,8 +538,7 @@ static int set_sample_rate_v2v3(struct s
+ * automatic clock selection if the current clock is not
+ * valid.
+ */
+- clock = snd_usb_clock_find_source(chip, fmt->protocol,
+- fmt->clock, true);
++ clock = snd_usb_clock_find_source(chip, fmt, true);
+ if (clock < 0) {
+ /* We did not find a valid clock, but that might be
+ * because the current sample rate does not match an
+@@ -510,8 +546,7 @@ static int set_sample_rate_v2v3(struct s
+ * and we will do another validation after setting the
+ * rate.
+ */
+- clock = snd_usb_clock_find_source(chip, fmt->protocol,
+- fmt->clock, false);
++ clock = snd_usb_clock_find_source(chip, fmt, false);
+ if (clock < 0)
+ return clock;
+ }
+@@ -577,7 +612,7 @@ static int set_sample_rate_v2v3(struct s
+
+ validation:
+ /* validate clock after rate change */
+- if (!uac_clock_source_is_valid(chip, fmt->protocol, clock))
++ if (!uac_clock_source_is_valid(chip, fmt, clock))
+ return -ENXIO;
+ return 0;
+ }
+--- a/sound/usb/clock.h
++++ b/sound/usb/clock.h
+@@ -6,7 +6,7 @@ int snd_usb_init_sample_rate(struct snd_
+ struct usb_host_interface *alts,
+ struct audioformat *fmt, int rate);
+
+-int snd_usb_clock_find_source(struct snd_usb_audio *chip, int protocol,
+- int entity_id, bool validate);
++int snd_usb_clock_find_source(struct snd_usb_audio *chip,
++ struct audioformat *fmt, bool validate);
+
+ #endif /* __USBAUDIO_CLOCK_H */
+--- a/sound/usb/format.c
++++ b/sound/usb/format.c
+@@ -322,8 +322,7 @@ static int parse_audio_format_rates_v2v3
+ struct usb_device *dev = chip->dev;
+ unsigned char tmp[2], *data;
+ int nr_triplets, data_size, ret = 0, ret_l6;
+- int clock = snd_usb_clock_find_source(chip, fp->protocol,
+- fp->clock, false);
++ int clock = snd_usb_clock_find_source(chip, fp, false);
+
+ if (clock < 0) {
+ dev_err(&dev->dev,