FAILED: patch "[PATCH] ALSA: usb-audio: Add clock validity quirk for Denon" failed to apply to 5.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 9f35a31283775e6f6af73fb2c95c686a4c0acac7 Mon Sep 17 00:00:00 2001
From: Alexander Tsoy <[email protected]>
Date: Thu, 13 Feb 2020 02:54:50 +0300
Subject: [PATCH] ALSA: usb-audio: Add clock validity quirk for Denon
MC7000/MCX8000
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.
sound/usb/clock.c +63 -28
@@ -151,8 +151,34 @@ static int uac_clock_selector_set_val(struct snd_usb_audio *chip, int selector_ireturn 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(struct snd_usb_audio *chip,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(struct snd_usb_audio *chip,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(struct snd_usb_audio *chip, int entity_id, 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(struct snd_usb_audio *chip, int entity_id, } 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(struct snd_usb_audio *chip, int entity_id,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(struct snd_usb_audio *chip, int entity_id,/* 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(struct snd_usb_audio *chip, int entity_id, 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(struct snd_usb_audio *chip, int entity_id, } 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(struct snd_usb_audio *chip, int entity_id,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(struct snd_usb_audio *chip, int entity_id, 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(struct snd_usb_audio *chip, int entity_id,* * 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 snd_usb_audio *chip, int iface,* 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 snd_usb_audio *chip, int iface,* 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 snd_usb_audio *chip, int iface, 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 ; }
sound/usb/clock.h +2 -2
@@ -6,7 +6,7 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,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 */
sound/usb/format.c +1 -2
@@ -336,8 +336,7 @@ static int parse_audio_format_rates_v2v3(struct snd_usb_audio *chip,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,
Quoted 6 lines · On Mon, 17 Feb 2020 12:50:17 +0100, <[email protected]> wrote:
The patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
Could you cherry-pick the commit 1d4961d9eb1aaa498dfb44779b7e4b95d79112d0
ALSA: usb-audio: sound: usb: usb true/false for bool return type
as prerequisite? This is just a bool value replacement that conflicts with the given patch.
thanks,
Takashi
Quoted 271 lines
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
9f35a31283775e6f6af73fb2c95c686a4c0acac7Mon Sep 17 00:00:00 2001From: Alexander Tsoy <[email protected]>
Date: Thu, 13 Feb 2020 02:54:50 +0300
Subject: [PATCH] ALSA: usb-audio: Add clock validity quirk for Denon
MC7000/MCX8000It 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 <[email protected]>Signed-off-by Alexander Tsoy <[email protected]>Cc <[email protected]>Signed-off-by Takashi Iwai <[email protected]>sound/usb/clock.c +63
-28@@ -151,8 +151,34 @@ static int uac_clock_selector_set_val(struct snd_usb_audio *chip, int selector_ireturn 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(struct snd_usb_audio *chip,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(struct snd_usb_audio *chip,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(struct snd_usb_audio *chip, int entity_id, 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(struct snd_usb_audio *chip, int entity_id, } 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(struct snd_usb_audio *chip, int entity_id,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(struct snd_usb_audio *chip, int entity_id,/* 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(struct snd_usb_audio *chip, int entity_id, 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(struct snd_usb_audio *chip, int entity_id, } 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(struct snd_usb_audio *chip, int entity_id,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(struct snd_usb_audio *chip, int entity_id, 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(struct snd_usb_audio *chip, int entity_id,* * 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 snd_usb_audio *chip, int iface,* 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 snd_usb_audio *chip, int iface,* 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 snd_usb_audio *chip, int iface, 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 ; }sound/usb/clock.h +2
-2@@ -6,7 +6,7 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,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 */ sound/usb/format.c +1
-2@@ -336,8 +336,7 @@ static int parse_audio_format_rates_v2v3(struct snd_usb_audio *chip,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,
Greg KH
maintainerQuoted 9 lines · Takashi Iwai
Quoted 6 lines · On Mon, 17 Feb 2020 12:50:17 +0100, <[email protected]> wrote:
The patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
Quoted 6 lines
Could you cherry-pick the commit
1d4961d9eb1aaa498dfb44779b7e4b95d79112d0
ALSA: usb-audio: sound: usb: usb true/false for bool return typeas prerequisite? This is just a bool value replacement that conflicts with the given patch.
That worked, thanks!
greg k-h