Commit 8b87a786 authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'topic/format-kunit' into for-next

Pull ALSA core kunit test.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parents 6d5a2dda 3e39acf5
...@@ -20485,6 +20485,12 @@ F: include/uapi/sound/compress_* ...@@ -20485,6 +20485,12 @@ F: include/uapi/sound/compress_*
F: sound/core/compress_offload.c F: sound/core/compress_offload.c
F: sound/soc/soc-compress.c F: sound/soc/soc-compress.c
SOUND - CORE KUNIT TEST
M: Ivan Orlov <ivan.orlov0322@gmail.com>
L: linux-sound@vger.kernel.org
S: Supported
F: sound/core/sound_kunit.c
SOUND - DMAENGINE HELPERS SOUND - DMAENGINE HELPERS
M: Lars-Peter Clausen <lars@metafoo.de> M: Lars-Peter Clausen <lars@metafoo.de>
S: Supported S: Supported
......
...@@ -39,6 +39,22 @@ config SND_UMP_LEGACY_RAWMIDI ...@@ -39,6 +39,22 @@ config SND_UMP_LEGACY_RAWMIDI
legacy MIDI 1.0 byte streams is created for each UMP Endpoint. legacy MIDI 1.0 byte streams is created for each UMP Endpoint.
The device contains 16 substreams corresponding to UMP groups. The device contains 16 substreams corresponding to UMP groups.
config SND_CORE_TEST
tristate "Sound core KUnit test"
depends on KUNIT
default KUNIT_ALL_TESTS
help
This options enables the sound core functions KUnit test.
KUnit tests run during boot and output the results to the debug
log in TAP format (https://testanything.org/). Only useful for
kernel devs running KUnit test harness and are not for inclusion
into a production build.
For more information on KUnit and unit tests in general, refer
to the KUnit documentation in Documentation/dev-tools/kunit/.
config SND_COMPRESS_OFFLOAD config SND_COMPRESS_OFFLOAD
tristate tristate
......
...@@ -49,6 +49,8 @@ obj-$(CONFIG_SND_SEQ_DEVICE) += snd-seq-device.o ...@@ -49,6 +49,8 @@ obj-$(CONFIG_SND_SEQ_DEVICE) += snd-seq-device.o
obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o
obj-$(CONFIG_SND_UMP) += snd-ump.o obj-$(CONFIG_SND_UMP) += snd-ump.o
obj-$(CONFIG_SND_CORE_TEST) += sound_kunit.o
obj-$(CONFIG_SND_OSSEMUL) += oss/ obj-$(CONFIG_SND_OSSEMUL) += oss/
obj-$(CONFIG_SND_SEQUENCER) += seq/ obj-$(CONFIG_SND_SEQUENCER) += seq/
......
...@@ -211,6 +211,10 @@ static const char * const snd_pcm_format_names[] = { ...@@ -211,6 +211,10 @@ static const char * const snd_pcm_format_names[] = {
FORMAT(DSD_U32_LE), FORMAT(DSD_U32_LE),
FORMAT(DSD_U16_BE), FORMAT(DSD_U16_BE),
FORMAT(DSD_U32_BE), FORMAT(DSD_U32_BE),
FORMAT(S20_LE),
FORMAT(S20_BE),
FORMAT(U20_LE),
FORMAT(U20_BE),
}; };
/** /**
...@@ -221,9 +225,11 @@ static const char * const snd_pcm_format_names[] = { ...@@ -221,9 +225,11 @@ static const char * const snd_pcm_format_names[] = {
*/ */
const char *snd_pcm_format_name(snd_pcm_format_t format) const char *snd_pcm_format_name(snd_pcm_format_t format)
{ {
if ((__force unsigned int)format >= ARRAY_SIZE(snd_pcm_format_names)) unsigned int format_num = (__force unsigned int)format;
if (format_num >= ARRAY_SIZE(snd_pcm_format_names) || !snd_pcm_format_names[format_num])
return "Unknown"; return "Unknown";
return snd_pcm_format_names[(__force unsigned int)format]; return snd_pcm_format_names[format_num];
} }
EXPORT_SYMBOL_GPL(snd_pcm_format_name); EXPORT_SYMBOL_GPL(snd_pcm_format_name);
......
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Sound core KUnit test
* Author: Ivan Orlov <ivan.orlov0322@gmail.com>
*/
#include <kunit/test.h>
#include <sound/core.h>
#include <sound/pcm.h>
#define SILENCE_BUFFER_SIZE 2048
#define SILENCE(...) { __VA_ARGS__ }
#define DEFINE_FORMAT(fmt, pbits, wd, endianness, signd, silence_arr) { \
.format = SNDRV_PCM_FORMAT_##fmt, .physical_bits = pbits, \
.width = wd, .le = endianness, .sd = signd, .silence = silence_arr, \
.name = #fmt, \
}
#define WRONG_FORMAT (SNDRV_PCM_FORMAT_LAST + 1)
#define VALID_NAME "ValidName"
#define NAME_W_SPEC_CHARS "In%v@1id name"
#define NAME_W_SPACE "Test name"
#define NAME_W_SPACE_REMOVED "Testname"
#define TEST_FIRST_COMPONENT "Component1"
#define TEST_SECOND_COMPONENT "Component2"
struct snd_format_test_data {
snd_pcm_format_t format;
int physical_bits;
int width;
int le;
int sd;
unsigned char silence[8];
unsigned char *name;
};
struct avail_test_data {
snd_pcm_uframes_t buffer_size;
snd_pcm_uframes_t hw_ptr;
snd_pcm_uframes_t appl_ptr;
snd_pcm_uframes_t expected_avail;
};
static struct snd_format_test_data valid_fmt[] = {
DEFINE_FORMAT(S8, 8, 8, -1, 1, SILENCE()),
DEFINE_FORMAT(U8, 8, 8, -1, 0, SILENCE(0x80)),
DEFINE_FORMAT(S16_LE, 16, 16, 1, 1, SILENCE()),
DEFINE_FORMAT(S16_BE, 16, 16, 0, 1, SILENCE()),
DEFINE_FORMAT(U16_LE, 16, 16, 1, 0, SILENCE(0x00, 0x80)),
DEFINE_FORMAT(U16_BE, 16, 16, 0, 0, SILENCE(0x80, 0x00)),
DEFINE_FORMAT(S24_LE, 32, 24, 1, 1, SILENCE()),
DEFINE_FORMAT(S24_BE, 32, 24, 0, 1, SILENCE()),
DEFINE_FORMAT(U24_LE, 32, 24, 1, 0, SILENCE(0x00, 0x00, 0x80)),
DEFINE_FORMAT(U24_BE, 32, 24, 0, 0, SILENCE(0x00, 0x80, 0x00, 0x00)),
DEFINE_FORMAT(S32_LE, 32, 32, 1, 1, SILENCE()),
DEFINE_FORMAT(S32_BE, 32, 32, 0, 1, SILENCE()),
DEFINE_FORMAT(U32_LE, 32, 32, 1, 0, SILENCE(0x00, 0x00, 0x00, 0x80)),
DEFINE_FORMAT(U32_BE, 32, 32, 0, 0, SILENCE(0x80, 0x00, 0x00, 0x00)),
DEFINE_FORMAT(FLOAT_LE, 32, 32, 1, -1, SILENCE()),
DEFINE_FORMAT(FLOAT_BE, 32, 32, 0, -1, SILENCE()),
DEFINE_FORMAT(FLOAT64_LE, 64, 64, 1, -1, SILENCE()),
DEFINE_FORMAT(FLOAT64_BE, 64, 64, 0, -1, SILENCE()),
DEFINE_FORMAT(IEC958_SUBFRAME_LE, 32, 32, 1, -1, SILENCE()),
DEFINE_FORMAT(IEC958_SUBFRAME_BE, 32, 32, 0, -1, SILENCE()),
DEFINE_FORMAT(MU_LAW, 8, 8, -1, -1, SILENCE(0x7f)),
DEFINE_FORMAT(A_LAW, 8, 8, -1, -1, SILENCE(0x55)),
DEFINE_FORMAT(IMA_ADPCM, 4, 4, -1, -1, SILENCE()),
DEFINE_FORMAT(G723_24, 3, 3, -1, -1, SILENCE()),
DEFINE_FORMAT(G723_40, 5, 5, -1, -1, SILENCE()),
DEFINE_FORMAT(DSD_U8, 8, 8, 1, 0, SILENCE(0x69)),
DEFINE_FORMAT(DSD_U16_LE, 16, 16, 1, 0, SILENCE(0x69, 0x69)),
DEFINE_FORMAT(DSD_U32_LE, 32, 32, 1, 0, SILENCE(0x69, 0x69, 0x69, 0x69)),
DEFINE_FORMAT(DSD_U16_BE, 16, 16, 0, 0, SILENCE(0x69, 0x69)),
DEFINE_FORMAT(DSD_U32_BE, 32, 32, 0, 0, SILENCE(0x69, 0x69, 0x69, 0x69)),
DEFINE_FORMAT(S20_LE, 32, 20, 1, 1, SILENCE()),
DEFINE_FORMAT(S20_BE, 32, 20, 0, 1, SILENCE()),
DEFINE_FORMAT(U20_LE, 32, 20, 1, 0, SILENCE(0x00, 0x00, 0x08, 0x00)),
DEFINE_FORMAT(U20_BE, 32, 20, 0, 0, SILENCE(0x00, 0x08, 0x00, 0x00)),
DEFINE_FORMAT(S24_3LE, 24, 24, 1, 1, SILENCE()),
DEFINE_FORMAT(S24_3BE, 24, 24, 0, 1, SILENCE()),
DEFINE_FORMAT(U24_3LE, 24, 24, 1, 0, SILENCE(0x00, 0x00, 0x80)),
DEFINE_FORMAT(U24_3BE, 24, 24, 0, 0, SILENCE(0x80, 0x00, 0x00)),
DEFINE_FORMAT(S20_3LE, 24, 20, 1, 1, SILENCE()),
DEFINE_FORMAT(S20_3BE, 24, 20, 0, 1, SILENCE()),
DEFINE_FORMAT(U20_3LE, 24, 20, 1, 0, SILENCE(0x00, 0x00, 0x08)),
DEFINE_FORMAT(U20_3BE, 24, 20, 0, 0, SILENCE(0x08, 0x00, 0x00)),
DEFINE_FORMAT(S18_3LE, 24, 18, 1, 1, SILENCE()),
DEFINE_FORMAT(S18_3BE, 24, 18, 0, 1, SILENCE()),
DEFINE_FORMAT(U18_3LE, 24, 18, 1, 0, SILENCE(0x00, 0x00, 0x02)),
DEFINE_FORMAT(U18_3BE, 24, 18, 0, 0, SILENCE(0x02, 0x00, 0x00)),
DEFINE_FORMAT(G723_24_1B, 8, 3, -1, -1, SILENCE()),
DEFINE_FORMAT(G723_40_1B, 8, 5, -1, -1, SILENCE()),
};
static void test_phys_format_size(struct kunit *test)
{
u32 i;
for (i = 0; i < ARRAY_SIZE(valid_fmt); i++) {
KUNIT_EXPECT_EQ(test, snd_pcm_format_physical_width(valid_fmt[i].format),
valid_fmt[i].physical_bits);
}
KUNIT_EXPECT_EQ(test, snd_pcm_format_physical_width(WRONG_FORMAT), -EINVAL);
KUNIT_EXPECT_EQ(test, snd_pcm_format_physical_width(-1), -EINVAL);
}
static void test_format_width(struct kunit *test)
{
u32 i;
for (i = 0; i < ARRAY_SIZE(valid_fmt); i++) {
KUNIT_EXPECT_EQ(test, snd_pcm_format_width(valid_fmt[i].format),
valid_fmt[i].width);
}
KUNIT_EXPECT_EQ(test, snd_pcm_format_width(WRONG_FORMAT), -EINVAL);
KUNIT_EXPECT_EQ(test, snd_pcm_format_width(-1), -EINVAL);
}
static void test_format_signed(struct kunit *test)
{
u32 i;
for (i = 0; i < ARRAY_SIZE(valid_fmt); i++) {
KUNIT_EXPECT_EQ(test, snd_pcm_format_signed(valid_fmt[i].format),
valid_fmt[i].sd < 0 ? -EINVAL : valid_fmt[i].sd);
KUNIT_EXPECT_EQ(test, snd_pcm_format_unsigned(valid_fmt[i].format),
valid_fmt[i].sd < 0 ? -EINVAL : 1 - valid_fmt[i].sd);
}
KUNIT_EXPECT_EQ(test, snd_pcm_format_width(WRONG_FORMAT), -EINVAL);
KUNIT_EXPECT_EQ(test, snd_pcm_format_width(-1), -EINVAL);
}
static void test_format_endianness(struct kunit *test)
{
u32 i;
for (i = 0; i < ARRAY_SIZE(valid_fmt); i++) {
KUNIT_EXPECT_EQ(test, snd_pcm_format_little_endian(valid_fmt[i].format),
valid_fmt[i].le < 0 ? -EINVAL : valid_fmt[i].le);
KUNIT_EXPECT_EQ(test, snd_pcm_format_big_endian(valid_fmt[i].format),
valid_fmt[i].le < 0 ? -EINVAL : 1 - valid_fmt[i].le);
}
KUNIT_EXPECT_EQ(test, snd_pcm_format_little_endian(WRONG_FORMAT), -EINVAL);
KUNIT_EXPECT_EQ(test, snd_pcm_format_little_endian(-1), -EINVAL);
KUNIT_EXPECT_EQ(test, snd_pcm_format_big_endian(WRONG_FORMAT), -EINVAL);
KUNIT_EXPECT_EQ(test, snd_pcm_format_big_endian(-1), -EINVAL);
}
static void _test_fill_silence(struct kunit *test, struct snd_format_test_data *data,
u8 *buffer, size_t samples_count)
{
size_t sample_bytes = data->physical_bits >> 3;
u32 i;
KUNIT_ASSERT_EQ(test, snd_pcm_format_set_silence(data->format, buffer, samples_count), 0);
for (i = 0; i < samples_count * sample_bytes; i++)
KUNIT_EXPECT_EQ(test, buffer[i], data->silence[i % sample_bytes]);
}
static void test_format_fill_silence(struct kunit *test)
{
u32 buf_samples[] = { 10, 20, 32, 64, 129, 260 };
u8 *buffer;
u32 i, j;
buffer = kunit_kzalloc(test, SILENCE_BUFFER_SIZE, GFP_KERNEL);
for (i = 0; i < ARRAY_SIZE(buf_samples); i++) {
for (j = 0; j < ARRAY_SIZE(valid_fmt); j++)
_test_fill_silence(test, &valid_fmt[j], buffer, buf_samples[i]);
}
KUNIT_EXPECT_EQ(test, snd_pcm_format_set_silence(WRONG_FORMAT, buffer, 20), -EINVAL);
KUNIT_EXPECT_EQ(test, snd_pcm_format_set_silence(SNDRV_PCM_FORMAT_LAST, buffer, 0), 0);
}
static snd_pcm_uframes_t calculate_boundary(snd_pcm_uframes_t buffer_size)
{
snd_pcm_uframes_t boundary = buffer_size;
while (boundary * 2 <= 0x7fffffffUL - buffer_size)
boundary *= 2;
return boundary;
}
static struct avail_test_data p_avail_data[] = {
/* buf_size + hw_ptr < appl_ptr => avail = buf_size + hw_ptr - appl_ptr + boundary */
{ 128, 1000, 1129, 1073741824UL - 1 },
/*
* buf_size + hw_ptr - appl_ptr >= boundary =>
* => avail = buf_size + hw_ptr - appl_ptr - boundary
*/
{ 128, 1073741824UL, 10, 118 },
/* standard case: avail = buf_size + hw_ptr - appl_ptr */
{ 128, 1000, 1001, 127 },
};
static void test_playback_avail(struct kunit *test)
{
struct snd_pcm_runtime *r = kunit_kzalloc(test, sizeof(*r), GFP_KERNEL);
u32 i;
r->status = kunit_kzalloc(test, sizeof(*r->status), GFP_KERNEL);
r->control = kunit_kzalloc(test, sizeof(*r->control), GFP_KERNEL);
for (i = 0; i < ARRAY_SIZE(p_avail_data); i++) {
r->buffer_size = p_avail_data[i].buffer_size;
r->boundary = calculate_boundary(r->buffer_size);
r->status->hw_ptr = p_avail_data[i].hw_ptr;
r->control->appl_ptr = p_avail_data[i].appl_ptr;
KUNIT_EXPECT_EQ(test, snd_pcm_playback_avail(r), p_avail_data[i].expected_avail);
}
}
static struct avail_test_data c_avail_data[] = {
/* hw_ptr - appl_ptr < 0 => avail = hw_ptr - appl_ptr + boundary */
{ 128, 1000, 1001, 1073741824UL - 1 },
/* standard case: avail = hw_ptr - appl_ptr */
{ 128, 1001, 1000, 1 },
};
static void test_capture_avail(struct kunit *test)
{
struct snd_pcm_runtime *r = kunit_kzalloc(test, sizeof(*r), GFP_KERNEL);
u32 i;
r->status = kunit_kzalloc(test, sizeof(*r->status), GFP_KERNEL);
r->control = kunit_kzalloc(test, sizeof(*r->control), GFP_KERNEL);
for (i = 0; i < ARRAY_SIZE(c_avail_data); i++) {
r->buffer_size = c_avail_data[i].buffer_size;
r->boundary = calculate_boundary(r->buffer_size);
r->status->hw_ptr = c_avail_data[i].hw_ptr;
r->control->appl_ptr = c_avail_data[i].appl_ptr;
KUNIT_EXPECT_EQ(test, snd_pcm_capture_avail(r), c_avail_data[i].expected_avail);
}
}
static void test_card_set_id(struct kunit *test)
{
struct snd_card *card = kunit_kzalloc(test, sizeof(*card), GFP_KERNEL);
snd_card_set_id(card, VALID_NAME);
KUNIT_EXPECT_STREQ(test, card->id, VALID_NAME);
/* clear the first id character so we can set it again */
card->id[0] = '\0';
snd_card_set_id(card, NAME_W_SPEC_CHARS);
KUNIT_EXPECT_STRNEQ(test, card->id, NAME_W_SPEC_CHARS);
card->id[0] = '\0';
snd_card_set_id(card, NAME_W_SPACE);
kunit_info(test, "%s", card->id);
KUNIT_EXPECT_STREQ(test, card->id, NAME_W_SPACE_REMOVED);
}
static void test_pcm_format_name(struct kunit *test)
{
u32 i;
const char *name;
for (i = 0; i < ARRAY_SIZE(valid_fmt); i++) {
name = snd_pcm_format_name(valid_fmt[i].format);
KUNIT_ASSERT_NOT_NULL_MSG(test, name, "Don't have name for %s", valid_fmt[i].name);
KUNIT_EXPECT_STREQ(test, name, valid_fmt[i].name);
}
KUNIT_ASSERT_STREQ(test, snd_pcm_format_name(WRONG_FORMAT), "Unknown");
KUNIT_ASSERT_STREQ(test, snd_pcm_format_name(-1), "Unknown");
}
static void test_card_add_component(struct kunit *test)
{
struct snd_card *card = kunit_kzalloc(test, sizeof(*card), GFP_KERNEL);
snd_component_add(card, TEST_FIRST_COMPONENT);
KUNIT_ASSERT_STREQ(test, card->components, TEST_FIRST_COMPONENT);
snd_component_add(card, TEST_SECOND_COMPONENT);
KUNIT_ASSERT_STREQ(test, card->components, TEST_FIRST_COMPONENT " " TEST_SECOND_COMPONENT);
}
static struct kunit_case sound_utils_cases[] = {
KUNIT_CASE(test_phys_format_size),
KUNIT_CASE(test_format_width),
KUNIT_CASE(test_format_endianness),
KUNIT_CASE(test_format_signed),
KUNIT_CASE(test_format_fill_silence),
KUNIT_CASE(test_playback_avail),
KUNIT_CASE(test_capture_avail),
KUNIT_CASE(test_card_set_id),
KUNIT_CASE(test_pcm_format_name),
KUNIT_CASE(test_card_add_component),
{},
};
static struct kunit_suite sound_utils_suite = {
.name = "sound-core-test",
.test_cases = sound_utils_cases,
};
kunit_test_suite(sound_utils_suite);
MODULE_AUTHOR("Ivan Orlov");
MODULE_LICENSE("GPL");
...@@ -87,6 +87,8 @@ static const struct cs35l41_config cs35l41_config_table[] = { ...@@ -87,6 +87,8 @@ static const struct cs35l41_config cs35l41_config_table[] = {
{ "10431533", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 }, { "10431533", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
{ "10431573", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 }, { "10431573", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 1000, 4500, 24 },
{ "10431663", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 }, { "10431663", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, -1, 0, 1000, 4500, 24 },
{ "10431683", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 0, 0, 0 },
{ "104316A3", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
{ "104316D3", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 }, { "104316D3", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
{ "104316F3", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 }, { "104316F3", 2, EXTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 1, 2, 0, 0, 0, 0 },
{ "104317F3", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 }, { "104317F3", 2, INTERNAL, { CS35L41_LEFT, CS35L41_RIGHT, 0, 0 }, 0, 1, -1, 1000, 4500, 24 },
...@@ -468,6 +470,8 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = { ...@@ -468,6 +470,8 @@ static const struct cs35l41_prop_model cs35l41_prop_model_table[] = {
{ "CSC3551", "10431533", generic_dsd_config }, { "CSC3551", "10431533", generic_dsd_config },
{ "CSC3551", "10431573", generic_dsd_config }, { "CSC3551", "10431573", generic_dsd_config },
{ "CSC3551", "10431663", generic_dsd_config }, { "CSC3551", "10431663", generic_dsd_config },
{ "CSC3551", "10431683", generic_dsd_config },
{ "CSC3551", "104316A3", generic_dsd_config },
{ "CSC3551", "104316D3", generic_dsd_config }, { "CSC3551", "104316D3", generic_dsd_config },
{ "CSC3551", "104316F3", generic_dsd_config }, { "CSC3551", "104316F3", generic_dsd_config },
{ "CSC3551", "104317F3", generic_dsd_config }, { "CSC3551", "104317F3", generic_dsd_config },
......
...@@ -1729,9 +1729,11 @@ static int default_bdl_pos_adj(struct azx *chip) ...@@ -1729,9 +1729,11 @@ static int default_bdl_pos_adj(struct azx *chip)
/* some exceptions: Atoms seem problematic with value 1 */ /* some exceptions: Atoms seem problematic with value 1 */
if (chip->pci->vendor == PCI_VENDOR_ID_INTEL) { if (chip->pci->vendor == PCI_VENDOR_ID_INTEL) {
switch (chip->pci->device) { switch (chip->pci->device) {
case 0x0f04: /* Baytrail */ case PCI_DEVICE_ID_INTEL_HDA_BYT:
case 0x2284: /* Braswell */ case PCI_DEVICE_ID_INTEL_HDA_BSW:
return 32; return 32;
case PCI_DEVICE_ID_INTEL_HDA_APL:
return 64;
} }
} }
......
...@@ -1371,6 +1371,7 @@ void dolphin_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int ac ...@@ -1371,6 +1371,7 @@ void dolphin_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int ac
spec->scodecs[CS8409_CODEC1] = &dolphin_cs42l42_1; spec->scodecs[CS8409_CODEC1] = &dolphin_cs42l42_1;
spec->scodecs[CS8409_CODEC1]->codec = codec; spec->scodecs[CS8409_CODEC1]->codec = codec;
spec->num_scodecs = 2; spec->num_scodecs = 2;
spec->gen.suppress_vmaster = 1;
codec->patch_ops = cs8409_dolphin_patch_ops; codec->patch_ops = cs8409_dolphin_patch_ops;
......
...@@ -438,6 +438,10 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) ...@@ -438,6 +438,10 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000); alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000);
fallthrough; fallthrough;
case 0x10ec0215: case 0x10ec0215:
case 0x10ec0285:
case 0x10ec0289:
alc_update_coef_idx(codec, 0x36, 1<<13, 0);
fallthrough;
case 0x10ec0230: case 0x10ec0230:
case 0x10ec0233: case 0x10ec0233:
case 0x10ec0235: case 0x10ec0235:
...@@ -451,9 +455,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) ...@@ -451,9 +455,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
case 0x10ec0283: case 0x10ec0283:
case 0x10ec0286: case 0x10ec0286:
case 0x10ec0288: case 0x10ec0288:
case 0x10ec0285:
case 0x10ec0298: case 0x10ec0298:
case 0x10ec0289:
case 0x10ec0300: case 0x10ec0300:
alc_update_coef_idx(codec, 0x10, 1<<9, 0); alc_update_coef_idx(codec, 0x10, 1<<9, 0);
break; break;
...@@ -9499,6 +9501,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -9499,6 +9501,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x1247, "Acer vCopperbox", ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS), SND_PCI_QUIRK(0x1025, 0x1247, "Acer vCopperbox", ALC269VC_FIXUP_ACER_VCOPPERBOX_PINS),
SND_PCI_QUIRK(0x1025, 0x1248, "Acer Veriton N4660G", ALC269VC_FIXUP_ACER_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1025, 0x1248, "Acer Veriton N4660G", ALC269VC_FIXUP_ACER_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1025, 0x1269, "Acer SWIFT SF314-54", ALC256_FIXUP_ACER_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x1269, "Acer SWIFT SF314-54", ALC256_FIXUP_ACER_HEADSET_MIC),
SND_PCI_QUIRK(0x1025, 0x126a, "Acer Swift SF114-32", ALC256_FIXUP_ACER_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1025, 0x128f, "Acer Veriton Z6860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x128f, "Acer Veriton Z6860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x1290, "Acer Veriton Z4860G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x1291, "Acer Veriton Z4660G", ALC286_FIXUP_ACER_AIO_HEADSET_MIC),
...@@ -9578,6 +9581,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -9578,6 +9581,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS), SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
SND_PCI_QUIRK(0x1028, 0x0beb, "Dell XPS 15 9530 (2023)", ALC289_FIXUP_DELL_CS35L41_SPI_2), SND_PCI_QUIRK(0x1028, 0x0beb, "Dell XPS 15 9530 (2023)", ALC289_FIXUP_DELL_CS35L41_SPI_2),
SND_PCI_QUIRK(0x1028, 0x0c03, "Dell Precision 5340", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0c03, "Dell Precision 5340", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0c0d, "Dell Oasis", ALC289_FIXUP_RTK_AMP_DUAL_SPK),
SND_PCI_QUIRK(0x1028, 0x0c19, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS), SND_PCI_QUIRK(0x1028, 0x0c19, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
SND_PCI_QUIRK(0x1028, 0x0c1a, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS), SND_PCI_QUIRK(0x1028, 0x0c1a, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
SND_PCI_QUIRK(0x1028, 0x0c1b, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS), SND_PCI_QUIRK(0x1028, 0x0c1b, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
...@@ -9698,6 +9702,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -9698,6 +9702,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8786, "HP OMEN 15", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x8786, "HP OMEN 15", ALC285_FIXUP_HP_MUTE_LED),
SND_PCI_QUIRK(0x103c, 0x8787, "HP OMEN 15", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x8787, "HP OMEN 15", ALC285_FIXUP_HP_MUTE_LED),
SND_PCI_QUIRK(0x103c, 0x8788, "HP OMEN 15", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x8788, "HP OMEN 15", ALC285_FIXUP_HP_MUTE_LED),
SND_PCI_QUIRK(0x103c, 0x87b7, "HP Laptop 14-fq0xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x87e5, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x87e5, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x87e7, "HP ProBook 450 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x87e7, "HP ProBook 450 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED),
......
...@@ -261,6 +261,8 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, ...@@ -261,6 +261,8 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
int ret, i, cur, err, pins, clock_id; int ret, i, cur, err, pins, clock_id;
const u8 *sources; const u8 *sources;
int proto = fmt->protocol; int proto = fmt->protocol;
bool readable, writeable;
u32 bmControls;
entity_id &= 0xff; entity_id &= 0xff;
...@@ -292,11 +294,27 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, ...@@ -292,11 +294,27 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
sources = GET_VAL(selector, proto, baCSourceID); sources = GET_VAL(selector, proto, baCSourceID);
cur = 0; cur = 0;
if (proto == UAC_VERSION_3)
bmControls = le32_to_cpu(*(__le32 *)(&selector->v3.baCSourceID[0] + pins));
else
bmControls = *(__u8 *)(&selector->v2.baCSourceID[0] + pins);
readable = uac_v2v3_control_is_readable(bmControls,
UAC2_CX_CLOCK_SELECTOR);
writeable = uac_v2v3_control_is_writeable(bmControls,
UAC2_CX_CLOCK_SELECTOR);
if (pins == 1) { if (pins == 1) {
ret = 1; ret = 1;
goto find_source; goto find_source;
} }
/* for now just warn about buggy device */
if (!readable)
usb_audio_warn(chip,
"%s(): clock selector control is not readable, id %d\n",
__func__, clock_id);
/* the entity ID we are looking at is a selector. /* the entity ID we are looking at is a selector.
* find out what it currently selects */ * find out what it currently selects */
ret = uac_clock_selector_get_val(chip, clock_id); ret = uac_clock_selector_get_val(chip, clock_id);
...@@ -325,7 +343,8 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, ...@@ -325,7 +343,8 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
visited, validate); visited, validate);
if (ret > 0) { if (ret > 0) {
/* Skip setting clock selector again for some devices */ /* Skip setting clock selector again for some devices */
if (chip->quirk_flags & QUIRK_FLAG_SKIP_CLOCK_SELECTOR) if (chip->quirk_flags & QUIRK_FLAG_SKIP_CLOCK_SELECTOR ||
!writeable)
return ret; return ret;
err = uac_clock_selector_set_val(chip, entity_id, cur); err = uac_clock_selector_set_val(chip, entity_id, cur);
if (err < 0) if (err < 0)
...@@ -336,6 +355,9 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, ...@@ -336,6 +355,9 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
return ret; return ret;
find_others: find_others:
if (!writeable)
return -ENXIO;
/* The current clock source is invalid, try others. */ /* The current clock source is invalid, try others. */
for (i = 1; i <= pins; i++) { for (i = 1; i <= pins; i++) {
if (i == cur) if (i == cur)
......
...@@ -470,9 +470,11 @@ static int validate_sample_rate_table_v2v3(struct snd_usb_audio *chip, ...@@ -470,9 +470,11 @@ static int validate_sample_rate_table_v2v3(struct snd_usb_audio *chip,
int clock) int clock)
{ {
struct usb_device *dev = chip->dev; struct usb_device *dev = chip->dev;
struct usb_host_interface *alts;
unsigned int *table; unsigned int *table;
unsigned int nr_rates; unsigned int nr_rates;
int i, err; int i, err;
u32 bmControls;
/* performing the rate verification may lead to unexpected USB bus /* performing the rate verification may lead to unexpected USB bus
* behavior afterwards by some unknown reason. Do this only for the * behavior afterwards by some unknown reason. Do this only for the
...@@ -481,6 +483,24 @@ static int validate_sample_rate_table_v2v3(struct snd_usb_audio *chip, ...@@ -481,6 +483,24 @@ static int validate_sample_rate_table_v2v3(struct snd_usb_audio *chip,
if (!(chip->quirk_flags & QUIRK_FLAG_VALIDATE_RATES)) if (!(chip->quirk_flags & QUIRK_FLAG_VALIDATE_RATES))
return 0; /* don't perform the validation as default */ return 0; /* don't perform the validation as default */
alts = snd_usb_get_host_interface(chip, fp->iface, fp->altsetting);
if (!alts)
return 0;
if (fp->protocol == UAC_VERSION_3) {
struct uac3_as_header_descriptor *as = snd_usb_find_csint_desc(
alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
bmControls = le32_to_cpu(as->bmControls);
} else {
struct uac2_as_header_descriptor *as = snd_usb_find_csint_desc(
alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
bmControls = as->bmControls;
}
if (!uac_v2v3_control_is_readable(bmControls,
UAC2_AS_VAL_ALT_SETTINGS))
return 0;
table = kcalloc(fp->nr_rates, sizeof(*table), GFP_KERNEL); table = kcalloc(fp->nr_rates, sizeof(*table), GFP_KERNEL);
if (!table) if (!table)
return -ENOMEM; return -ENOMEM;
......
...@@ -1085,7 +1085,7 @@ int snd_usb_midi_v2_create(struct snd_usb_audio *chip, ...@@ -1085,7 +1085,7 @@ int snd_usb_midi_v2_create(struct snd_usb_audio *chip,
} }
if ((quirk && quirk->type != QUIRK_MIDI_STANDARD_INTERFACE) || if ((quirk && quirk->type != QUIRK_MIDI_STANDARD_INTERFACE) ||
iface->num_altsetting < 2) { iface->num_altsetting < 2) {
usb_audio_info(chip, "Quirk or no altest; falling back to MIDI 1.0\n"); usb_audio_info(chip, "Quirk or no altset; falling back to MIDI 1.0\n");
goto fallback_to_midi1; goto fallback_to_midi1;
} }
hostif = &iface->altsetting[1]; hostif = &iface->altsetting[1];
......
...@@ -2031,10 +2031,14 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { ...@@ -2031,10 +2031,14 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_IGNORE_CTL_ERROR), QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_IGNORE_CTL_ERROR),
DEVICE_FLG(0x0499, 0x1509, /* Steinberg UR22 */ DEVICE_FLG(0x0499, 0x1509, /* Steinberg UR22 */
QUIRK_FLAG_GENERIC_IMPLICIT_FB), QUIRK_FLAG_GENERIC_IMPLICIT_FB),
DEVICE_FLG(0x0499, 0x3108, /* Yamaha YIT-W12TX */
QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x04d8, 0xfeea, /* Benchmark DAC1 Pre */ DEVICE_FLG(0x04d8, 0xfeea, /* Benchmark DAC1 Pre */
QUIRK_FLAG_GET_SAMPLE_RATE), QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x04e8, 0xa051, /* Samsung USBC Headset (AKG) */ DEVICE_FLG(0x04e8, 0xa051, /* Samsung USBC Headset (AKG) */
QUIRK_FLAG_SKIP_CLOCK_SELECTOR | QUIRK_FLAG_CTL_MSG_DELAY_5M), QUIRK_FLAG_SKIP_CLOCK_SELECTOR | QUIRK_FLAG_CTL_MSG_DELAY_5M),
DEVICE_FLG(0x0525, 0xa4ad, /* Hamedal C20 usb camero */
QUIRK_FLAG_IFACE_SKIP_CLOSE),
DEVICE_FLG(0x054c, 0x0b8c, /* Sony WALKMAN NW-A45 DAC */ DEVICE_FLG(0x054c, 0x0b8c, /* Sony WALKMAN NW-A45 DAC */
QUIRK_FLAG_SET_IFACE_FIRST), QUIRK_FLAG_SET_IFACE_FIRST),
DEVICE_FLG(0x0556, 0x0014, /* Phoenix Audio TMX320VC */ DEVICE_FLG(0x0556, 0x0014, /* Phoenix Audio TMX320VC */
...@@ -2073,14 +2077,22 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { ...@@ -2073,14 +2077,22 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_GENERIC_IMPLICIT_FB), QUIRK_FLAG_GENERIC_IMPLICIT_FB),
DEVICE_FLG(0x0763, 0x2031, /* M-Audio Fast Track C600 */ DEVICE_FLG(0x0763, 0x2031, /* M-Audio Fast Track C600 */
QUIRK_FLAG_GENERIC_IMPLICIT_FB), QUIRK_FLAG_GENERIC_IMPLICIT_FB),
DEVICE_FLG(0x07fd, 0x000b, /* MOTU M Series 2nd hardware revision */
QUIRK_FLAG_CTL_MSG_DELAY_1M),
DEVICE_FLG(0x08bb, 0x2702, /* LineX FM Transmitter */ DEVICE_FLG(0x08bb, 0x2702, /* LineX FM Transmitter */
QUIRK_FLAG_IGNORE_CTL_ERROR), QUIRK_FLAG_IGNORE_CTL_ERROR),
DEVICE_FLG(0x0951, 0x16ad, /* Kingston HyperX */ DEVICE_FLG(0x0951, 0x16ad, /* Kingston HyperX */
QUIRK_FLAG_CTL_MSG_DELAY_1M), QUIRK_FLAG_CTL_MSG_DELAY_1M),
DEVICE_FLG(0x0b0e, 0x0349, /* Jabra 550a */ DEVICE_FLG(0x0b0e, 0x0349, /* Jabra 550a */
QUIRK_FLAG_CTL_MSG_DELAY_1M), QUIRK_FLAG_CTL_MSG_DELAY_1M),
DEVICE_FLG(0x0ecb, 0x205c, /* JBL Quantum610 Wireless */
QUIRK_FLAG_FIXED_RATE),
DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */
QUIRK_FLAG_FIXED_RATE),
DEVICE_FLG(0x0fd9, 0x0008, /* Hauppauge HVR-950Q */ DEVICE_FLG(0x0fd9, 0x0008, /* Hauppauge HVR-950Q */
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER), QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
DEVICE_FLG(0x1224, 0x2a25, /* Jieli Technology USB PHY 2.0 */
QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x1395, 0x740a, /* Sennheiser DECT */ DEVICE_FLG(0x1395, 0x740a, /* Sennheiser DECT */
QUIRK_FLAG_GET_SAMPLE_RATE), QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x1397, 0x0507, /* Behringer UMC202HD */ DEVICE_FLG(0x1397, 0x0507, /* Behringer UMC202HD */
...@@ -2113,6 +2125,10 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { ...@@ -2113,6 +2125,10 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY), QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
DEVICE_FLG(0x1901, 0x0191, /* GE B850V3 CP2114 audio interface */ DEVICE_FLG(0x1901, 0x0191, /* GE B850V3 CP2114 audio interface */
QUIRK_FLAG_GET_SAMPLE_RATE), QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x19f7, 0x0035, /* RODE NT-USB+ */
QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x1bcf, 0x2283, /* NexiGo N930AF FHD Webcam */
QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x2040, 0x7200, /* Hauppauge HVR-950Q */ DEVICE_FLG(0x2040, 0x7200, /* Hauppauge HVR-950Q */
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER), QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
DEVICE_FLG(0x2040, 0x7201, /* Hauppauge HVR-950Q-MXL */ DEVICE_FLG(0x2040, 0x7201, /* Hauppauge HVR-950Q-MXL */
...@@ -2155,6 +2171,12 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { ...@@ -2155,6 +2171,12 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_IGNORE_CTL_ERROR), QUIRK_FLAG_IGNORE_CTL_ERROR),
DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */ DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */
QUIRK_FLAG_GET_SAMPLE_RATE), QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x2b53, 0x0023, /* Fiero SC-01 (firmware v1.0.0 @ 48 kHz) */
QUIRK_FLAG_GENERIC_IMPLICIT_FB),
DEVICE_FLG(0x2b53, 0x0024, /* Fiero SC-01 (firmware v1.0.0 @ 96 kHz) */
QUIRK_FLAG_GENERIC_IMPLICIT_FB),
DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */
QUIRK_FLAG_GENERIC_IMPLICIT_FB),
DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */ DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */
QUIRK_FLAG_IGNORE_CTL_ERROR), QUIRK_FLAG_IGNORE_CTL_ERROR),
DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */ DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */
...@@ -2163,22 +2185,6 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { ...@@ -2163,22 +2185,6 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_ALIGN_TRANSFER), QUIRK_FLAG_ALIGN_TRANSFER),
DEVICE_FLG(0x534d, 0x2109, /* MacroSilicon MS2109 */ DEVICE_FLG(0x534d, 0x2109, /* MacroSilicon MS2109 */
QUIRK_FLAG_ALIGN_TRANSFER), QUIRK_FLAG_ALIGN_TRANSFER),
DEVICE_FLG(0x1224, 0x2a25, /* Jieli Technology USB PHY 2.0 */
QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x2b53, 0x0023, /* Fiero SC-01 (firmware v1.0.0 @ 48 kHz) */
QUIRK_FLAG_GENERIC_IMPLICIT_FB),
DEVICE_FLG(0x2b53, 0x0024, /* Fiero SC-01 (firmware v1.0.0 @ 96 kHz) */
QUIRK_FLAG_GENERIC_IMPLICIT_FB),
DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */
QUIRK_FLAG_GENERIC_IMPLICIT_FB),
DEVICE_FLG(0x0525, 0xa4ad, /* Hamedal C20 usb camero */
QUIRK_FLAG_IFACE_SKIP_CLOSE),
DEVICE_FLG(0x0ecb, 0x205c, /* JBL Quantum610 Wireless */
QUIRK_FLAG_FIXED_RATE),
DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */
QUIRK_FLAG_FIXED_RATE),
DEVICE_FLG(0x1bcf, 0x2283, /* NexiGo N930AF FHD Webcam */
QUIRK_FLAG_GET_SAMPLE_RATE),
/* Vendor matches */ /* Vendor matches */
VENDOR_FLG(0x045e, /* MS Lifecam */ VENDOR_FLG(0x045e, /* MS Lifecam */
......
...@@ -91,8 +91,6 @@ static void virtsnd_event_notify_cb(struct virtqueue *vqueue) ...@@ -91,8 +91,6 @@ static void virtsnd_event_notify_cb(struct virtqueue *vqueue)
virtsnd_event_dispatch(snd, event); virtsnd_event_dispatch(snd, event);
virtsnd_event_send(vqueue, event, true, GFP_ATOMIC); virtsnd_event_send(vqueue, event, true, GFP_ATOMIC);
} }
if (unlikely(virtqueue_is_broken(vqueue)))
break;
} while (!virtqueue_enable_cb(vqueue)); } while (!virtqueue_enable_cb(vqueue));
spin_unlock_irqrestore(&queue->lock, flags); spin_unlock_irqrestore(&queue->lock, flags);
} }
......
...@@ -303,8 +303,6 @@ void virtsnd_ctl_notify_cb(struct virtqueue *vqueue) ...@@ -303,8 +303,6 @@ void virtsnd_ctl_notify_cb(struct virtqueue *vqueue)
virtqueue_disable_cb(vqueue); virtqueue_disable_cb(vqueue);
while ((msg = virtqueue_get_buf(vqueue, &length))) while ((msg = virtqueue_get_buf(vqueue, &length)))
virtsnd_ctl_msg_complete(msg); virtsnd_ctl_msg_complete(msg);
if (unlikely(virtqueue_is_broken(vqueue)))
break;
} while (!virtqueue_enable_cb(vqueue)); } while (!virtqueue_enable_cb(vqueue));
spin_unlock_irqrestore(&queue->lock, flags); spin_unlock_irqrestore(&queue->lock, flags);
} }
...@@ -358,8 +358,6 @@ static inline void virtsnd_pcm_notify_cb(struct virtio_snd_queue *queue) ...@@ -358,8 +358,6 @@ static inline void virtsnd_pcm_notify_cb(struct virtio_snd_queue *queue)
virtqueue_disable_cb(queue->vqueue); virtqueue_disable_cb(queue->vqueue);
while ((msg = virtqueue_get_buf(queue->vqueue, &written_bytes))) while ((msg = virtqueue_get_buf(queue->vqueue, &written_bytes)))
virtsnd_pcm_msg_complete(msg, written_bytes); virtsnd_pcm_msg_complete(msg, written_bytes);
if (unlikely(virtqueue_is_broken(queue->vqueue)))
break;
} while (!virtqueue_enable_cb(queue->vqueue)); } while (!virtqueue_enable_cb(queue->vqueue));
spin_unlock_irqrestore(&queue->lock, flags); spin_unlock_irqrestore(&queue->lock, flags);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment