From nobody Thu Oct 2 19:26:00 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F2B701DF270; Fri, 12 Sep 2025 06:22:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757658158; cv=none; b=ot88z22YaTbBEt1okxTt88xZ92LZ5H6JI70353qZEpWDS+TtRpuQHiqkz5P9ZQQ4V5HrWfN92pBn4jb5sixooUeHDoQynMYr0Rg5WxhV5kSrQCm/2/RxAPE/JQxZxNLJ8X7rtNLgDtPTDf8VGliKH51HP6+BFr5f6Hq8jfmlLqY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757658158; c=relaxed/simple; bh=5h60QxW1rFF5CEABNOJbZqEmndmkLwdnJruvnGRfsf0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Lw2f6iY9n/j3KqUwOEQ+TQGAWd33JgJvEhVFAwpDZ7wvioybElyLwI22qHN8znTGs8XJpBtP3bz71HvXBOh8MFtO1WWEzD1QJA2Sk9BEODKiZeRaHOPip8++hM+XaabP23AEvMxLEviuRl9LjkSCsdlmc4crGlOEAFYEJUIgizI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qUdUMzaV; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="qUdUMzaV" Received: by smtp.kernel.org (Postfix) with ESMTPS id AC8E4C4CEF7; Fri, 12 Sep 2025 06:22:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757658157; bh=5h60QxW1rFF5CEABNOJbZqEmndmkLwdnJruvnGRfsf0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=qUdUMzaVrLHffwntkdHyCeQyJHDKBx0zH+1oJnMYIVV+86SQH/Aby4U4k5g6zedlM aOo6ivq6qZonRUoXHQt4xnorxtLpZnvbV/PeducJ9LBtjJE/h+qsFN544CkQ+XSphE 9esL3gzcS0AzB/Dcs/LD0oGcjACsRaMCBeWNfe5QJgFRdNN9Anu6d97nVROQm0Cc9B wgerABwTrC68ulis50jBkoXhWmZah5q3xDqTzAWuhtj30Ab9rvu0ksmhtSXR/9GsTe Pc+BQm4gk8Hnxya7QOlIyXLxP93df1BaIykKn4pY/si1lWy6t5a/qJKAg+gVZwHY4X iqAV2A1eTPQvA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9B7C4CAC582; Fri, 12 Sep 2025 06:22:37 +0000 (UTC) From: Cryolitia PukNgae via B4 Relay Date: Fri, 12 Sep 2025 14:22:35 +0800 Subject: [PATCH 1/3] ALSA: usb-audio: add two-way convert between name and bit for QUIRK_FLAG_* Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250912-sound-v1-1-cc9cfd9f2d01@uniontech.com> References: <20250912-sound-v1-0-cc9cfd9f2d01@uniontech.com> In-Reply-To: <20250912-sound-v1-0-cc9cfd9f2d01@uniontech.com> To: Jaroslav Kysela , Takashi Iwai , Jonathan Corbet Cc: linux-sound@vger.kernel.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, Mingcong Bai , Kexy Biscuit , Nie Cheng , Zhan Jun , Feng Yuan , qaqland , kernel@uniontech.com, Cryolitia PukNgae X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1757658156; l=4131; i=cryolitia@uniontech.com; s=20250730; h=from:subject:message-id; bh=3kvU7Ca3Zp23CxB+cqB+zdjQhNaXptItq/K3jXkNqt8=; b=qsPx1xeYuKJMjBvo8LIrL5YRvJvUe262qQZD+AAXPGubvN2zDHrAoHDy55khM5RC1qEsI/5ac HXnct2FqYw3DUfUmjiT0WbaW7cBSwLNI89LWzlAIRfr+K89LiktVB22 X-Developer-Key: i=cryolitia@uniontech.com; a=ed25519; pk=tZ+U+kQkT45GRGewbMSB4VPmvpD+KkHC/Wv3rMOn/PU= X-Endpoint-Received: by B4 Relay for cryolitia@uniontech.com/20250730 with auth_id=474 X-Original-From: Cryolitia PukNgae Reply-To: cryolitia@uniontech.com From: Cryolitia PukNgae Also improve debug logs for applied quirks Signed-off-by: Cryolitia PukNgae --- sound/usb/quirks.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++= +--- sound/usb/quirks.h | 4 +++ sound/usb/usbaudio.h | 1 + 3 files changed, 85 insertions(+), 4 deletions(-) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index d736a4750356597bfb0f9d5ab01cdaeaac0f907c..022e5691d6797c0a17a1132b058= 56e816f822ab0 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -2446,6 +2446,64 @@ static const struct usb_audio_quirk_flags_table quir= k_flags_table[] =3D { {} /* terminator */ }; =20 +static const char *const snd_usb_audio_quirk_flag_names[] =3D { + "get_sample_rate", + "share_media_device", + "align_transfer", + "tx_length", + "playback_first", + "skip_clock_selector", + "ignore_clock_source", + "itf_usb_dsd_dac", + "ctl_msg_delay", + "ctl_msg_delay_1m", + "ctl_msg_delay_5m", + "iface_delay", + "validate_rates", + "disable_autosuspend", + "ignore_ctl_error", + "dsd_raw", + "set_iface_first", + "generic_implicit_fb", + "skip_implicit_fb", + "iface_skip_close", + "force_iface_reset", + "fixed_rate", + "mic_res_16", + "mic_res_384", + "mixer_playback_min_mute", + "mixer_capture_min_mute", + NULL +}; + +const char *snd_usb_quirk_flag_find_name(unsigned long index) +{ + unsigned long size =3D BYTES_TO_BITS(sizeof(unsigned int)); + + if (index >=3D ARRAY_SIZE(snd_usb_audio_quirk_flag_names)) + return NULL; + + return snd_usb_audio_quirk_flag_names[index]; +} + +u32 snd_usb_quirk_flags_from_name(char *name) +{ + u32 flag =3D 0; + u32 i; + + if (!name || !*name) + return 0; + + for (i =3D 0; snd_usb_audio_quirk_flag_names[i]; i++) { + if (strcmp(name, snd_usb_audio_quirk_flag_names[i]) =3D=3D 0) { + flag =3D (1U << i); + break; + } + } + + return flag; +} + void snd_usb_init_quirk_flags(struct snd_usb_audio *chip) { const struct usb_audio_quirk_flags_table *p; @@ -2454,10 +2512,28 @@ void snd_usb_init_quirk_flags(struct snd_usb_audio = *chip) if (chip->usb_id =3D=3D p->id || (!USB_ID_PRODUCT(p->id) && USB_ID_VENDOR(chip->usb_id) =3D=3D USB_ID_VENDOR(p->id))) { - usb_audio_dbg(chip, - "Set quirk_flags 0x%x for device %04x:%04x\n", - p->flags, USB_ID_VENDOR(chip->usb_id), - USB_ID_PRODUCT(chip->usb_id)); + unsigned long flags =3D p->flags; + unsigned long bit; + + for_each_set_bit(bit, &flags, + BYTES_TO_BITS(sizeof(p->flags))) { + const char *name =3D + snd_usb_audio_quirk_flag_names[bit]; + + if (name) + usb_audio_dbg(chip, + "Set quirk flag %s for device %04x:%04x\n", + name, + USB_ID_VENDOR(chip->usb_id), + USB_ID_PRODUCT(chip->usb_id)); + else + usb_audio_warn(chip, + "Set unknown quirk flag 0x%lx for device %04x:%04x\n", + bit, + USB_ID_VENDOR(chip->usb_id), + USB_ID_PRODUCT(chip->usb_id)); + } + chip->quirk_flags |=3D p->flags; return; } diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h index f9bfd5ac7bab01717de3a76227482a128bf73165..749d493eb532c071ee40cf4b284= 0bb4902ab4681 100644 --- a/sound/usb/quirks.h +++ b/sound/usb/quirks.h @@ -50,4 +50,8 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_= audio *chip, =20 void snd_usb_init_quirk_flags(struct snd_usb_audio *chip); =20 +const char *snd_usb_quirk_flag_find_name(unsigned long flag); + +u32 snd_usb_quirk_flags_from_name(char *name); + #endif /* __USBAUDIO_QUIRKS_H */ diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 30b5102e3caed01eeb86d0075c41338104c58950..0a22cb4a02344b2dcf4009c560a= 759f2da25ca67 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -252,5 +252,6 @@ extern bool snd_usb_skip_validation; #define QUIRK_FLAG_MIC_RES_384 (1U << 23) #define QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE (1U << 24) #define QUIRK_FLAG_MIXER_CAPTURE_MIN_MUTE (1U << 25) +/* Please also edit snd_usb_audio_quirk_flag_names */ =20 #endif /* __USBAUDIO_H */ --=20 2.51.0 From nobody Thu Oct 2 19:26:00 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 12D5F27F736; Fri, 12 Sep 2025 06:22:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757658158; cv=none; b=dfsuakEXLBADIMiRlaPj477OuRr+lsReq1HPkeTOBFMnGpDDsA32YMA/e9JZcg6x6MZMKeSHIZj2X9zL1EYa1n5ImQBw5LTe2dt5bkAH8fsMsfQ+lopJzt8wXmU55Wz0CKH3Yk+JmK1ap3ww1Vlu72oYTg2TFTfTBHlm2Q+79U8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757658158; c=relaxed/simple; bh=vCjPSSITIzPRQT8N5oaqQJbFO4omiAxBTAfZpvgTWcA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=asI8ZFHj7X4qnpKMLimmpnsChH8m838cCxlFp+Xfuw/P8MXXOVnF4ETMbEDg49iT46u7MXH9lSCS1ctSs7wGLBa6ro4Go6pBcWrBSoEXq1fSRyIQAYv727xzgv/8K/37vQ8cV3aGuDwEuGw0p4eyxEertw5wodClcSKKooR1n4o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mm4wKv5J; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mm4wKv5J" Received: by smtp.kernel.org (Postfix) with ESMTPS id B70C5C4CEF5; Fri, 12 Sep 2025 06:22:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757658157; bh=vCjPSSITIzPRQT8N5oaqQJbFO4omiAxBTAfZpvgTWcA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=mm4wKv5JDw67C4lVSCiX+wWpWk9iHc+riu6dl43QMX9ebduCfiaOzWdYB2Jcx/6W3 DIi58VGI9SybgknaXp4hM3x7MpEf4ohs1E/NiiJKjQ63pqA0WmDHyD9LkS5b8s3tkp +knqPIbfPRKXjnGgTtwoQrDMRHc4OJCdiQKaA5rrWZ03yC2XzLOOAzqy88EqfbVPZQ yZEKlfCOR0R5wWUxe7YoadkBqjyASg6L8wkBZrQj5txyC5UhtxOGsoEjBxAx5unCjb Dtqf23fitfUrpccjnwr6jRfezrzBUF/WaZQ0t7vfCkMJcCHwXNbHonL4ny4rh5N61c 8hO/eLi6NRYCg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id A91CFCAC594; Fri, 12 Sep 2025 06:22:37 +0000 (UTC) From: Cryolitia PukNgae via B4 Relay Date: Fri, 12 Sep 2025 14:22:36 +0800 Subject: [PATCH 2/3] ALSA: usb-audio: add module param device_quirk_flags Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250912-sound-v1-2-cc9cfd9f2d01@uniontech.com> References: <20250912-sound-v1-0-cc9cfd9f2d01@uniontech.com> In-Reply-To: <20250912-sound-v1-0-cc9cfd9f2d01@uniontech.com> To: Jaroslav Kysela , Takashi Iwai , Jonathan Corbet Cc: linux-sound@vger.kernel.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, Mingcong Bai , Kexy Biscuit , Nie Cheng , Zhan Jun , Feng Yuan , qaqland , kernel@uniontech.com, Cryolitia PukNgae X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1757658156; l=8762; i=cryolitia@uniontech.com; s=20250730; h=from:subject:message-id; bh=PKErF/ur/Uw2za/xtmSbMpGPjwDMtMdvq6Cej79B92w=; b=89LOfVHoq9hjHWiu3lHa2GF2iwvEGiuAEN1Dh0wAoRZ55I4B3dURFzuPgeE7NpTPuUtQSxcwg m5YnUsZ6JTDBOUK+hP0nuffYJngpT3jVCgwZ65niSKBALkfv5E46Tx9 X-Developer-Key: i=cryolitia@uniontech.com; a=ed25519; pk=tZ+U+kQkT45GRGewbMSB4VPmvpD+KkHC/Wv3rMOn/PU= X-Endpoint-Received: by B4 Relay for cryolitia@uniontech.com/20250730 with auth_id=474 X-Original-From: Cryolitia PukNgae Reply-To: cryolitia@uniontech.com From: Cryolitia PukNgae For apply and unapply quirk flags more flexibly though param and sysfs Signed-off-by: Cryolitia PukNgae --- sound/usb/card.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++= +++- sound/usb/quirks.c | 51 ++++++++++++++++ sound/usb/quirks.h | 2 + sound/usb/usbaudio.h | 13 ++++ 4 files changed, 230 insertions(+), 1 deletion(-) diff --git a/sound/usb/card.c b/sound/usb/card.c index 0265206a8e8cf31133e8463c98fe0497d8ace89e..e53fd868f34e93d42b1447958fc= 136658a6f9dd2 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -77,6 +77,7 @@ static unsigned int quirk_flags[SNDRV_CARDS]; =20 bool snd_usb_use_vmalloc =3D true; bool snd_usb_skip_validation; +char device_quirk_flags[MAX_QUIRK_PARAM_LEN]; =20 module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); @@ -110,6 +111,149 @@ MODULE_PARM_DESC(use_vmalloc, "Use vmalloc for PCM in= termediate buffers (default module_param_named(skip_validation, snd_usb_skip_validation, bool, 0444); MODULE_PARM_DESC(skip_validation, "Skip unit descriptor validation (defaul= t: no)."); =20 +DEFINE_MUTEX(device_quirk_mutex); /* protects device_quirk_list */ + +struct device_quirk_entry *device_quirk_list; +unsigned int device_quirk_count; + +static int device_quirks_param_set(const char *value, + const struct kernel_param *kp) +{ + char *val, *p, *field, *flag_field; + u32 mask_flags, unmask_flags, bit; + bool is_unmask; + u16 vid, pid; + size_t i; + int err; + + val =3D kstrdup(value, GFP_KERNEL); + if (!val) + return -ENOMEM; + + err =3D param_set_copystring(val, kp); + if (err) { + kfree(val); + return err; + } + + mutex_lock(&device_quirk_mutex); + + if (!*val) { + device_quirk_count =3D 0; + kfree(device_quirk_list); + device_quirk_list =3D NULL; + goto unlock; + } + + for (device_quirk_count =3D 1, i =3D 0; val[i]; i++) + if (val[i] =3D=3D ';') + device_quirk_count++; + + kfree(device_quirk_list); + + device_quirk_list =3D kcalloc(device_quirk_count, + sizeof(struct device_quirk_entry), + GFP_KERNEL); + if (!device_quirk_list) { + device_quirk_count =3D 0; + mutex_unlock(&device_quirk_mutex); + kfree(val); + return -ENOMEM; + } + + for (i =3D 0, p =3D val; p && *p;) { + /* Each entry consists of VID:PID:flags */ + field =3D strsep(&p, ":"); + if (!field) + break; + + if (strcmp(field, "*") =3D=3D 0) + vid =3D 0; + else if (kstrtou16(field, 16, &vid)) + break; + + field =3D strsep(&p, ":"); + if (!field) + break; + + if (strcmp(field, "*") =3D=3D 0) + pid =3D 0; + else if (kstrtou16(field, 16, &pid)) + break; + + field =3D strsep(&p, ";"); + if (!field || !*field) + break; + + /* Collect the flags */ + mask_flags =3D 0; + unmask_flags =3D 0; + while (field && *field) { + flag_field =3D strsep(&field, ","); + + if (!flag_field) + break; + + if (*flag_field =3D=3D '!') { + is_unmask =3D true; + flag_field++; + } else { + is_unmask =3D false; + } + + if (!kstrtou32(flag_field, 16, &bit)) { + if (is_unmask) + unmask_flags |=3D bit; + else + mask_flags |=3D bit; + + break; + } + + bit =3D snd_usb_quirk_flags_from_name(flag_field); + + if (bit) { + if (is_unmask) + unmask_flags |=3D bit; + else + mask_flags |=3D bit; + } else { + pr_warn("snd_usb_audio: unknown flag %s while parsing param device_qui= rk_flags\n", + flag_field); + } + } + device_quirk_list[i++] =3D (struct device_quirk_entry){ + .vid =3D vid, + .pid =3D pid, + .mask_flags =3D mask_flags, + .unmask_flags =3D unmask_flags, + }; + } + + if (i < device_quirk_count) + device_quirk_count =3D i; + +unlock: + mutex_unlock(&device_quirk_mutex); + kfree(val); + + return 0; +} + +static const struct kernel_param_ops device_quirks_param_ops =3D { + .set =3D device_quirks_param_set, + .get =3D param_get_string, +}; + +static struct kparam_string device_quirks_param_string =3D { + .maxlen =3D sizeof(device_quirk_flags), + .string =3D device_quirk_flags, +}; + +device_param_cb(device_quirk_flags, &device_quirks_param_ops, + &device_quirks_param_string, 0644); +MODULE_PARM_DESC(device_quirk_flags, "Add/modify USB audio quirks"); + /* * we keep the snd_usb_audio_t instances by ourselves for merging * the all interfaces on the same card as one sound device. @@ -755,6 +899,8 @@ static int snd_usb_audio_create(struct usb_interface *i= ntf, else snd_usb_init_quirk_flags(chip); =20 + snd_usb_init_dynamic_quirks(chip); + card->private_free =3D snd_usb_audio_free; =20 strscpy(card->driver, "USB-Audio"); @@ -1290,4 +1436,21 @@ static struct usb_driver usb_audio_driver =3D { .supports_autosuspend =3D 1, }; =20 -module_usb_driver(usb_audio_driver); +static int __init usb_audio_init(void) +{ + return usb_register_driver(&usb_audio_driver, THIS_MODULE, + KBUILD_MODNAME); +} + +static void __exit usb_audio_exit(void) +{ + mutex_lock(&device_quirk_mutex); + kfree(device_quirk_list); + device_quirk_list =3D NULL; + mutex_unlock(&device_quirk_mutex); + + usb_deregister(&usb_audio_driver); +} + +module_init(usb_audio_init); +module_exit(usb_audio_exit); diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 022e5691d6797c0a17a1132b05856e816f822ab0..88481e34f9b85ce223c989ee4ad= 54908eff73e2c 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -2539,3 +2539,54 @@ void snd_usb_init_quirk_flags(struct snd_usb_audio *= chip) } } } + +void snd_usb_init_dynamic_quirks(struct snd_usb_audio *chip) +{ + u16 vid =3D USB_ID_VENDOR(chip->usb_id); + u16 pid =3D USB_ID_PRODUCT(chip->usb_id); + int i, flags =3D 0; + + mutex_lock(&device_quirk_mutex); + + for (i =3D 0; i < device_quirk_count; i++) { + if (device_quirk_list[i].vid =3D=3D 0 || + (vid =3D=3D device_quirk_list[i].vid && + device_quirk_list[i].pid =3D=3D 0) || + (vid =3D=3D device_quirk_list[i].vid && + pid =3D=3D device_quirk_list[i].pid)) { + flags |=3D device_quirk_list[i].mask_flags; + flags &=3D ~device_quirk_list[i].unmask_flags; + usb_audio_dbg(chip, + "Set mask quirk flag 0x%x and unmask quirk flag 0x%x from param = for device %04x:%04x\n", + device_quirk_list[i].mask_flags, + device_quirk_list[i].unmask_flags, + USB_ID_VENDOR(chip->usb_id), + USB_ID_PRODUCT(chip->usb_id)); + break; + } + } + + mutex_unlock(&device_quirk_mutex); +} + +void snd_usb_init_dynamic_quirks(struct snd_usb_audio *chip) +{ + u16 vid =3D USB_ID_VENDOR(chip->usb_id); + u16 pid =3D USB_ID_PRODUCT(chip->usb_id); + int i; + + mutex_lock(&device_quirk_mutex); + + for (i =3D 0; i < device_quirk_count; i++) { + if (device_quirk_list[i].vid =3D=3D 0 || + (vid =3D=3D device_quirk_list[i].vid && + device_quirk_list[i].pid =3D=3D 0) || + (vid =3D=3D device_quirk_list[i].vid && + pid =3D=3D device_quirk_list[i].pid)) { + chip->quirk_flags |=3D device_quirk_list[i].mask_flags; + chip->quirk_flags &=3D ~device_quirk_list[i].unmask_flags; + } + } + + mutex_unlock(&device_quirk_mutex); +} diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h index 749d493eb532c071ee40cf4b2840bb4902ab4681..e8e32432df69f2eb16f84b8a9c7= 2f0a753a3589f 100644 --- a/sound/usb/quirks.h +++ b/sound/usb/quirks.h @@ -54,4 +54,6 @@ const char *snd_usb_quirk_flag_find_name(unsigned long fl= ag); =20 u32 snd_usb_quirk_flags_from_name(char *name); =20 +void snd_usb_init_dynamic_quirks(struct snd_usb_audio *chip); + #endif /* __USBAUDIO_QUIRKS_H */ diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 0a22cb4a02344b2dcf4009c560a759f2da25ca67..cb6cab37d749a258258394816e7= 4c939cdd471fe 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -20,6 +20,7 @@ struct media_device; struct media_intf_devnode; =20 #define MAX_CARD_INTERFACES 16 +#define MAX_QUIRK_PARAM_LEN 128 =20 /* * Structure holding assosiation between Audio Control Interface @@ -165,6 +166,11 @@ DEFINE_CLASS(snd_usb_lock, struct __snd_usb_lock, extern bool snd_usb_use_vmalloc; extern bool snd_usb_skip_validation; =20 +extern struct mutex device_quirk_mutex; +extern char device_quirk_flags[MAX_QUIRK_PARAM_LEN]; +extern unsigned int device_quirk_count; +extern struct device_quirk_entry *device_quirk_list; + /* * Driver behavior quirk flags, stored in chip->quirk_flags * @@ -254,4 +260,11 @@ extern bool snd_usb_skip_validation; #define QUIRK_FLAG_MIXER_CAPTURE_MIN_MUTE (1U << 25) /* Please also edit snd_usb_audio_quirk_flag_names */ =20 +struct device_quirk_entry { + u16 vid; + u16 pid; + u32 mask_flags; + u32 unmask_flags; +}; + #endif /* __USBAUDIO_H */ --=20 2.51.0 From nobody Thu Oct 2 19:26:00 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 12DCE27FB2A; Fri, 12 Sep 2025 06:22:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757658158; cv=none; b=ja+m9/EahfOsdMR2cak/MlZ4bR9xjDv3DqYBFGtYTr3uDXX1NzOjfwBjIwX7ieWqcgMdy88HsiTdfvjnswrjed0U7/QM8jrFaa1LJJzhtnfIvPkVyu5Yej1VNOrG1Kup1RBYlV58YquIn5SXjYirMWZu/8sFJEzJvvC99x7HZ/w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757658158; c=relaxed/simple; bh=niQWF1wkWxTNHpw5prHOgNovhde76RsAWKwkEaCR3sQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gMAUqu8O8QCyv2idUH2JbLaJZruoivp6KBxUexzLvcB92LYdU56ULwSlxLkYemT0JLPV0Xus4K2DUxx9Tjf2mod5r0RCVux8r4A7I2nE9zjcZuqp79RhdKdK/oN++dYUPm2d136EdR0nq03vK41uh9lHQU1XwAaLAzJXlvHy5oM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SpH3kVpd; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SpH3kVpd" Received: by smtp.kernel.org (Postfix) with ESMTPS id C3577C4CEF9; Fri, 12 Sep 2025 06:22:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757658157; bh=niQWF1wkWxTNHpw5prHOgNovhde76RsAWKwkEaCR3sQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=SpH3kVpd4ZyAJiD7Wm9KmLtxScmjEnrvzcsD9pAStcvnn1DArgcCAJKYQ46RoD5rW JwrPkrwCOQcfH0gPcVWghONi/hw92LHrZtqVpp2Tl3MG2BfjygSEa/ohowmsVfrYAW a1MqTb1nEMiNhGBQiQCX3bL6wJqj/6rEZ0cRiJE36/y+6Zrju022fjP/G2f4Gyo/J+ 3hAwnG0tbhMtH64U3QA6zE87z3m2C8vpthVmf7mDzY7Xq0NE8RstsLJ9Xud5A6hHMw cB6tH/moGD/ZdZ/QgT2ikh2Qu4fCMhTSQRcrCuB+6OlJlcpyyk2rCPb5dGq1TWtE6i nzb4gL/Ug2cNw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7DC0CA101F; Fri, 12 Sep 2025 06:22:37 +0000 (UTC) From: Cryolitia PukNgae via B4 Relay Date: Fri, 12 Sep 2025 14:22:37 +0800 Subject: [PATCH 3/3] ALSA: doc: add docs about device_device_quirk_flags in snd-usb-audio Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250912-sound-v1-3-cc9cfd9f2d01@uniontech.com> References: <20250912-sound-v1-0-cc9cfd9f2d01@uniontech.com> In-Reply-To: <20250912-sound-v1-0-cc9cfd9f2d01@uniontech.com> To: Jaroslav Kysela , Takashi Iwai , Jonathan Corbet Cc: linux-sound@vger.kernel.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, Mingcong Bai , Kexy Biscuit , Nie Cheng , Zhan Jun , Feng Yuan , qaqland , kernel@uniontech.com, Cryolitia PukNgae X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1757658156; l=7115; i=cryolitia@uniontech.com; s=20250730; h=from:subject:message-id; bh=s/0dZ04dkumVF/ET0AfUgOb4GzZPo7Sb5MusAYIlxoQ=; b=JI1NdkylKrFAuH6PjLVbvnMuInZ8TbCF1qsYgfuaNku646M7BZmoQpb3xuB7k2X+ZkPw92sEw zv+gkaxVPOeDTXuv2wts9Vq4jw+vZZkXX2yK2OdXlXMPf9oIdn5pH7b X-Developer-Key: i=cryolitia@uniontech.com; a=ed25519; pk=tZ+U+kQkT45GRGewbMSB4VPmvpD+KkHC/Wv3rMOn/PU= X-Endpoint-Received: by B4 Relay for cryolitia@uniontech.com/20250730 with auth_id=474 X-Original-From: Cryolitia PukNgae Reply-To: cryolitia@uniontech.com From: Cryolitia PukNgae Just briefly described about the new option. Signed-off-by: Cryolitia PukNgae --- Documentation/sound/alsa-configuration.rst | 105 ++++++++++++++++++++-----= ---- 1 file changed, 73 insertions(+), 32 deletions(-) diff --git a/Documentation/sound/alsa-configuration.rst b/Documentation/sou= nd/alsa-configuration.rst index a2fb8ed251dd0294e7a62209ca15d5c32c6adfae..060dfbd4197d3134f20d3d86300= d97b14071eee9 100644 --- a/Documentation/sound/alsa-configuration.rst +++ b/Documentation/sound/alsa-configuration.rst @@ -2296,40 +2296,81 @@ skip_validation The option is used to ignore the validation errors with the hexdump of the unit descriptor instead of a driver probe error, so that we can check its details. +device_device_quirk_flags + The option povides a refined and flexible control for applying quirk + flags. It allows to specify the quirk flags for each device, and could + be modified dynamically via sysfs. + The option accepts a string in the format of ``VID1:PID1:FLAGS1;VID2:P= ID2: + FLAGS2;...``, where ``VIDx`` and ``PIDx`` specify the device, and + ``FLAGSx`` specify the flags to be applied. ``VIDx`` and ``PIDx`` are + 4-digit hexadecimal numbers, and could be specified as ``*`` to match = any + value. ``FLAGSx`` could be a set of flags given by name, separated by + comma, or a hexadecimal number representing the bit flags. The availa= ble + flag names are listed above. An exclamation mark could be prefixed to= a + flag name to negate the flag. For example, + ``1234:abcd:mixer_playback_min_mute,!ignore_ctl_error;*:*:0x01;`` + applies the ``mixer_playback_min_mute`` flag and clears the + ``ignore_ctl_error`` flag for the device 1234:abcd, and applies + the ``skip_sample_rate`` flag for all devices. quirk_flags Contains the bit flags for various device specific workarounds. Applied to the corresponding card index. =20 - * bit 0: Skip reading sample rate for devices - * bit 1: Create Media Controller API entries - * bit 2: Allow alignment on audio sub-slot at transfer - * bit 3: Add length specifier to transfers - * bit 4: Start playback stream at first in implement feedback mode - * bit 5: Skip clock selector setup - * bit 6: Ignore errors from clock source search - * bit 7: Indicates ITF-USB DSD based DACs - * bit 8: Add a delay of 20ms at each control message handling - * bit 9: Add a delay of 1-2ms at each control message handling - * bit 10: Add a delay of 5-6ms at each control message handling - * bit 11: Add a delay of 50ms at each interface setup - * bit 12: Perform sample rate validations at probe - * bit 13: Disable runtime PM autosuspend - * bit 14: Ignore errors for mixer access - * bit 15: Support generic DSD raw U32_BE format - * bit 16: Set up the interface at first like UAC1 - * bit 17: Apply the generic implicit feedback sync mode - * bit 18: Don't apply implicit feedback sync mode - * bit 19: Don't closed interface during setting sample rate - * bit 20: Force an interface reset whenever stopping & restarting - a stream - * bit 21: Do not set PCM rate (frequency) when only one rate is - available for the given endpoint. - * bit 22: Set the fixed resolution 16 for Mic Capture Volume - * bit 23: Set the fixed resolution 384 for Mic Capture Volume - * bit 24: Set minimum volume control value as mute for devices - where the lowest playback value represents muted state instead - of minimum audible volume - * bit 25: Be similar to bit 24 but for capture streams + * bit 0: ``get_sample_rate`` + Skip reading sample rate for devices + * bit 1: ``share_media_device`` + Create Media Controller API entries + * bit 2: ``align_transfer`` + Allow alignment on audio sub-slot at transfer + * bit 3: ``tx_length`` + Add length specifier to transfers + * bit 4: ``playback_first`` + Start playback stream at first in implement feedback mode + * bit 5: ``skip_clock_selector`` + Skip clock selector setup + * bit 6: ``ignore_clock_source`` + Ignore errors from clock source search + * bit 7: ``itf_usb_dsd_dac`` + Indicates ITF-USB DSD based DACs + * bit 8: ``ctl_msg_delay`` + Add a delay of 20ms at each control message handling + * bit 9: ``ctl_msg_delay_1m`` + Add a delay of 1-2ms at each control message handling + * bit 10: ``ctl_msg_delay_5m`` + Add a delay of 5-6ms at each control message handling + * bit 11: ``iface_delay`` + Add a delay of 50ms at each interface setup + * bit 12: ``validate_rates`` + Perform sample rate validations at probe + * bit 13: ``disable_autosuspend`` + Disable runtime PM autosuspend + * bit 14: ``ignore_ctl_error`` + Ignore errors for mixer access + * bit 15: ``dsd_raw`` + Support generic DSD raw U32_BE format + * bit 16: ``set_iface_first`` + Set up the interface at first like UAC1 + * bit 17: ``generic_implicit_fb`` + Apply the generic implicit feedback sync mode + * bit 18: ``skip_implicit_fb`` + Don't apply implicit feedback sync mode + * bit 19: ``iface_skip_close`` + Don't closed interface during setting sample rate + * bit 20: ``force_iface_reset`` + Force an interface reset whenever stopping & restarting a stream + * bit 21: ``fixed_rate`` + Do not set PCM rate (frequency) when only one rate is available + for the given endpoint + * bit 22: ``mic_res_16`` + Set the fixed resolution 16 for Mic Capture Volume + * bit 23: ``mic_res_384`` + Set the fixed resolution 384 for Mic Capture Volume + * bit 24: ``mixer_playback_min_mute`` + Set minimum volume control value as mute for devices where the + lowest playback value represents muted state instead of minimum + audible volume + * bit 25: ``mixer_capture_min_mute`` + Be similar to bit 24 but for capture streams =20 This module supports multiple devices, autoprobe and hotplugging. =20 @@ -2344,8 +2385,8 @@ report it to the upstream. NB: ``quirk_alias`` option is provided only for testing / development. If you want to have a proper support, contact to upstream for adding the matching quirk in the driver code statically. -Ditto for ``quirk_flags``. If a device is known to require specific -workarounds, please report to the upstream. +Ditto for ``quirk_flags`` and ``device_device_quirk_flags``. If a device +is known to require specific workarounds, please report to the upstream. =20 Module snd-usb-caiaq -------------------- --=20 2.51.0