Linux Sound subsystem development
 help / color / mirror / Atom feed
* [PATCH 0/2] ALSA: usb-audio: Add quirks for HP Elite x3 Lap Dock
@ 2026-09-07 19:34 Rong Zhang
  2026-09-07 19:34 ` [PATCH 1/2] ALSA: usb-audio: Convert snd_usb_apply_interface_quirk() into a switch statement Rong Zhang
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Rong Zhang @ 2026-09-07 19:34 UTC (permalink / raw)
  To: Jaroslav Kysela, Takashi Iwai; +Cc: linux-sound, linux-kernel, Rong Zhang

The HP Elite x3 Lap Dock is a laptop-like external display device with a
FHD screen, a keyboard, and a MT touchpad. It can be connected via USB-C
or Miracast. As an e-waste collector, I recently brought one for 69 CNY
(10.2 USD). The price already indicates how broken the device's design
and compatibility are ;-P

When connecting via USB-C, the video source is, of course, DisplayPort
Alternate Mode. However, the audio source has nothing to do with the
DisplayPort signal and is actually from a builtin UAC device.

The builtin UAC device provides three Alternate Settings:

- 1:1 - Capture, S16_LE, 8000/32000/44100/48000Hz
- 2:1 - Playback, S16_LE, 48000Hz
- 2:2 - Playback, S24_3LE, 48000Hz

Unfortunately, the last one is broken because:

- it doesn't accept SET_CUR(SAMPLE_RATE). QUIRK_FLAG_FIXED_RATE works
  around it, however...
- it constantly produces severe harmonic distortion once the capture
  stream is also opened. The interface 2 must be closed and reopened to
  make it recover. IOW, simply closing the capture stream makes no
  difference.

Considering that S24_3LE offers no additional benefit on small speakers
compared to S16_LE, and 2:1 is always usable as an alternative, skip 2:2
to get rid of the trouble.

Setting chip->setup to any non-default value disables the fixup and
reenables 2:2 (in this case QUIRK_FLAG_FIXED_RATE is required).

Quirky device sample:

  usb 7-1.4: new full-speed USB device number 50 using xhci_hcd
  usb 7-1.4: New USB device found, idVendor=03f0, idProduct=0c56, bcdDevice= 0.00
  usb 7-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
  usb 7-1.4: Product: HP Elite x3 Lap Dock
  usb 7-1.4: Manufacturer: HP
  usb 7-1.4: Found last interface = 0
  usb 7-1.4: 1:1: add audio endpoint 0x81
  usb 7-1.4: Creating new data endpoint #81
  usb 7-1.4: 1:1 Set sample rate 48000, clock 0
  usb 7-1.4: 2:1: add audio endpoint 0x1
  usb 7-1.4: Creating new data endpoint #1
  usb 7-1.4: 2:1 Set sample rate 48000, clock 0
  usb 7-1.4: 2:2: add audio endpoint 0x1
  usb 7-1.4: 2:2 Set sample rate 48000, clock 0
  usb 7-1.4: 2:2: cannot set freq 48000 to ep 0x1
  usb 7-1.4: [9] FU [Sidetone Playback Switch] ch = 1, val = 0/1/1
  usb 7-1.4: cannot set ctl value: req = 0x4, wValue = 0x200, wIndex = 0x900, type = 4, data = 0x40/0x0
  usb 7-1.4: [9] FU [Sidetone Playback Volume] ch = 1, val = -17664/0/128
  usb 7-1.4: [2] FU [Headset Playback Switch] ch = 1, val = 0/1/1
  usb 7-1.4: [2] FU [Headset Playback Volume] ch = 2, val = -18944/0/1
  usb 7-1.4: [6] FU [Headset Capture Switch] ch = 1, val = 0/1/1
  usb 7-1.4: [6] FU [Headset Capture Volume] ch = 2, val = -18944/0/1
  input: HP HP Elite x3 Lap Dock Consumer Control as /devices/pci0000:00/0000:00:08.3/0000:c9:00.4/usb7/7-1/7-1.4/7-1.4:1.3/0003:03F0:0C56.0033/input/input129
  input: HP HP Elite x3 Lap Dock as /devices/pci0000:00/0000:00:08.3/0000:c9:00.4/usb7/7-1/7-1.4/7-1.4:1.3/0003:03F0:0C56.0033/input/input130
  hid-generic 0003:03F0:0C56.0033: input,hiddev100,hidraw8: USB HID v1.11 Device [HP HP Elite x3 Lap Dock] on usb-0000:c9:00.4-1.4/input3

Signed-off-by: Rong Zhang <i@rong.moe>
---
Rong Zhang (2):
      ALSA: usb-audio: Convert snd_usb_apply_interface_quirk() into a switch statement
      ALSA: usb-audio: Add quirks for HP Elite x3 Lap Dock

 sound/usb/quirks.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 46 insertions(+), 6 deletions(-)
---
base-commit: df2908090cda368b01ff43709f51890076c56157
change-id: 47d1988d-uac-hp-elite-x3-lap-dock-59fc42bf91c2

Thanks,
Rong


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] ALSA: usb-audio: Convert snd_usb_apply_interface_quirk() into a switch statement
  2026-09-07 19:34 [PATCH 0/2] ALSA: usb-audio: Add quirks for HP Elite x3 Lap Dock Rong Zhang
@ 2026-09-07 19:34 ` Rong Zhang
  2026-09-07 19:34 ` [PATCH 2/2] ALSA: usb-audio: Add quirks for HP Elite x3 Lap Dock Rong Zhang
  2026-09-08  7:12 ` [PATCH 0/2] " Takashi Iwai
  2 siblings, 0 replies; 4+ messages in thread
From: Rong Zhang @ 2026-09-07 19:34 UTC (permalink / raw)
  To: Jaroslav Kysela, Takashi Iwai; +Cc: linux-sound, linux-kernel, Rong Zhang

A switch statement is more readable than the current if blocks.

Also sort the cases in an ascending order.

As an interesting effect, this shrinks the size of quirks.o by 64 bytes
(GCC 16 -O2 x86_64):

      text       data        bss      total filename	(before)
     15266      12279          0      27545 quirks.o

      text       data        bss      total filename	(before)
     15202      12279          0      27481 quirks.o

Signed-off-by: Rong Zhang <i@rong.moe>
---
 sound/usb/quirks.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 91938172912a..6e4808330a80 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1589,18 +1589,20 @@ int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
 				  int iface,
 				  int altno)
 {
-	/* audiophile usb: skip altsets incompatible with device_setup */
-	if (chip->usb_id == USB_ID(0x0763, 0x2003))
-		return audiophile_skip_setting_quirk(chip, iface, altno);
+	switch (chip->usb_id) {
 	/* quattro usb: skip altsets incompatible with device_setup */
-	if (chip->usb_id == USB_ID(0x0763, 0x2001))
+	case USB_ID(0x0763, 0x2001):
 		return quattro_skip_setting_quirk(chip, iface, altno);
+	/* audiophile usb: skip altsets incompatible with device_setup */
+	case USB_ID(0x0763, 0x2003):
+		return audiophile_skip_setting_quirk(chip, iface, altno);
 	/* fasttrackpro usb: skip altsets incompatible with device_setup */
-	if (chip->usb_id == USB_ID(0x0763, 0x2012))
+	case USB_ID(0x0763, 0x2012):
 		return fasttrackpro_skip_setting_quirk(chip, iface, altno);
 	/* presonus studio 1810c: skip altsets incompatible with device_setup */
-	if (chip->usb_id == USB_ID(0x194f, 0x010c))
+	case USB_ID(0x194f, 0x010c):
 		return s1810c_skip_setting_quirk(chip, iface, altno);
+	}
 
 	return 0;
 }

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] ALSA: usb-audio: Add quirks for HP Elite x3 Lap Dock
  2026-09-07 19:34 [PATCH 0/2] ALSA: usb-audio: Add quirks for HP Elite x3 Lap Dock Rong Zhang
  2026-09-07 19:34 ` [PATCH 1/2] ALSA: usb-audio: Convert snd_usb_apply_interface_quirk() into a switch statement Rong Zhang
@ 2026-09-07 19:34 ` Rong Zhang
  2026-09-08  7:12 ` [PATCH 0/2] " Takashi Iwai
  2 siblings, 0 replies; 4+ messages in thread
From: Rong Zhang @ 2026-09-07 19:34 UTC (permalink / raw)
  To: Jaroslav Kysela, Takashi Iwai; +Cc: linux-sound, linux-kernel, Rong Zhang

The HP Elite x3 Lap Dock is a laptop-like external display device with a
FHD screen, a keyboard, and a MT touchpad. It can be connected via USB-C
or Miracast. As an e-waste collector, I recently brought one for 69 CNY
(10.2 USD). The price already indicates how broken the device's design
and compatibility are ;-P

When connecting via USB-C, the video source is, of course, DisplayPort
Alternate Mode. However, the audio source has nothing to do with the
DisplayPort signal and is actually from a builtin UAC device.

The builtin UAC device provides three Alternate Settings:

- 1:1 - Capture, S16_LE, 8000/32000/44100/48000Hz
- 2:1 - Playback, S16_LE, 48000Hz
- 2:2 - Playback, S24_3LE, 48000Hz

Unfortunately, the last one is broken because:

- it doesn't accept SET_CUR(SAMPLE_RATE). QUIRK_FLAG_FIXED_RATE works
  around it, however...
- it constantly produces severe harmonic distortion once the capture
  stream is also opened. The interface 2 must be closed and reopened to
  make it recover. IOW, simply closing the capture stream makes no
  difference.

Considering that S24_3LE offers no additional benefit on small speakers
compared to S16_LE, and 2:1 is always usable as an alternative, skip 2:2
to get rid of the trouble.

Setting chip->setup to any non-default value disables the fixup and
reenables 2:2 (in this case QUIRK_FLAG_FIXED_RATE is required).

Quirky device sample:

  usb 7-1.4: new full-speed USB device number 50 using xhci_hcd
  usb 7-1.4: New USB device found, idVendor=03f0, idProduct=0c56, bcdDevice= 0.00
  usb 7-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
  usb 7-1.4: Product: HP Elite x3 Lap Dock
  usb 7-1.4: Manufacturer: HP
  usb 7-1.4: Found last interface = 0
  usb 7-1.4: 1:1: add audio endpoint 0x81
  usb 7-1.4: Creating new data endpoint #81
  usb 7-1.4: 1:1 Set sample rate 48000, clock 0
  usb 7-1.4: 2:1: add audio endpoint 0x1
  usb 7-1.4: Creating new data endpoint #1
  usb 7-1.4: 2:1 Set sample rate 48000, clock 0
  usb 7-1.4: 2:2: add audio endpoint 0x1
  usb 7-1.4: 2:2 Set sample rate 48000, clock 0
  usb 7-1.4: 2:2: cannot set freq 48000 to ep 0x1
  usb 7-1.4: [9] FU [Sidetone Playback Switch] ch = 1, val = 0/1/1
  usb 7-1.4: cannot set ctl value: req = 0x4, wValue = 0x200, wIndex = 0x900, type = 4, data = 0x40/0x0
  usb 7-1.4: [9] FU [Sidetone Playback Volume] ch = 1, val = -17664/0/128
  usb 7-1.4: [2] FU [Headset Playback Switch] ch = 1, val = 0/1/1
  usb 7-1.4: [2] FU [Headset Playback Volume] ch = 2, val = -18944/0/1
  usb 7-1.4: [6] FU [Headset Capture Switch] ch = 1, val = 0/1/1
  usb 7-1.4: [6] FU [Headset Capture Volume] ch = 2, val = -18944/0/1
  input: HP HP Elite x3 Lap Dock Consumer Control as /devices/pci0000:00/0000:00:08.3/0000:c9:00.4/usb7/7-1/7-1.4/7-1.4:1.3/0003:03F0:0C56.0033/input/input129
  input: HP HP Elite x3 Lap Dock as /devices/pci0000:00/0000:00:08.3/0000:c9:00.4/usb7/7-1/7-1.4/7-1.4:1.3/0003:03F0:0C56.0033/input/input130
  hid-generic 0003:03F0:0C56.0033: input,hiddev100,hidraw8: USB HID v1.11 Device [HP HP Elite x3 Lap Dock] on usb-0000:c9:00.4-1.4/input3

Signed-off-by: Rong Zhang <i@rong.moe>
---
 sound/usb/quirks.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 6e4808330a80..6462b8390106 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1585,11 +1585,47 @@ static int s1810c_skip_setting_quirk(struct snd_usb_audio *chip,
 	return 0;
 }
 
+static int hp_elite_x3_lap_dock_skip_setting_quirk(struct snd_usb_audio *chip,
+						   int iface, int altno)
+{
+	/*
+	 * 1:1 - Capture, S16_LE, 8000/32000/44100/48000Hz
+	 * 2:1 - Playback, S16_LE, 48000Hz
+	 * 2:2 - Playback, S24_3LE, 48000Hz
+	 *
+	 * 2:2 is broken because:
+	 * - it doesn't accept SET_CUR(SAMPLE_RATE). QUIRK_FLAG_FIXED_RATE works
+	 *   around it, however...
+	 * - it constantly produces severe harmonic distortion once the capture
+	 *   stream is also opened. The interface 2 must be closed and reopened
+	 *   to make it recover. IOW, simply closing the capture stream makes no
+	 *   difference.
+	 *
+	 * Considering that S24_3LE offers no additional benefit on small
+	 * speakers compared to S16_LE, and 2:1 is always usable as an
+	 * alternative, skip 2:2 to get rid of the trouble.
+	 *
+	 * Setting chip->setup to any non-default value disables the fixup and
+	 * reenables 2:2 (in this case QUIRK_FLAG_FIXED_RATE is required).
+	 */
+	if (!chip->setup && iface == 2 && altno == 2) {
+		usb_audio_info(chip,
+			       "%d:%d: skipping broken altsetting on HP Elite x3 Lap Dock\n",
+			       iface, altno);
+		return 1;
+	}
+
+	return 0;
+}
+
 int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
 				  int iface,
 				  int altno)
 {
 	switch (chip->usb_id) {
+	/* HP Elite x3 Lap Dock: skip broken altsets */
+	case USB_ID(0x03f0, 0x0c56):
+		return hp_elite_x3_lap_dock_skip_setting_quirk(chip, iface, altno);
 	/* quattro usb: skip altsets incompatible with device_setup */
 	case USB_ID(0x0763, 0x2001):
 		return quattro_skip_setting_quirk(chip, iface, altno);
@@ -2215,6 +2251,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
 		   QUIRK_FLAG_FORCE_IFACE_RESET | QUIRK_FLAG_IFACE_DELAY),
 	DEVICE_FLG(0x0124, 0x0c21, /* Generic USB Headphone */
 		   QUIRK_FLAG_FORCE_IFACE_RESET | QUIRK_FLAG_IFACE_DELAY),
+	DEVICE_FLG(0x03f0, 0x0c56, /* HP Elite x3 Lap Dock */
+		   QUIRK_FLAG_FIXED_RATE),
 	DEVICE_FLG(0x03f0, 0x654a, /* HP 320 FHD Webcam */
 		   QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_MIC_RES_16),
 	DEVICE_FLG(0x041e, 0x3000, /* Creative SB Extigy */

-- 
2.55.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/2] ALSA: usb-audio: Add quirks for HP Elite x3 Lap Dock
  2026-09-07 19:34 [PATCH 0/2] ALSA: usb-audio: Add quirks for HP Elite x3 Lap Dock Rong Zhang
  2026-09-07 19:34 ` [PATCH 1/2] ALSA: usb-audio: Convert snd_usb_apply_interface_quirk() into a switch statement Rong Zhang
  2026-09-07 19:34 ` [PATCH 2/2] ALSA: usb-audio: Add quirks for HP Elite x3 Lap Dock Rong Zhang
@ 2026-09-08  7:12 ` Takashi Iwai
  2 siblings, 0 replies; 4+ messages in thread
From: Takashi Iwai @ 2026-09-08  7:12 UTC (permalink / raw)
  To: Rong Zhang; +Cc: Jaroslav Kysela, Takashi Iwai, linux-sound, linux-kernel

On Mon, 07 Sep 2026 21:34:38 +0200,
Rong Zhang wrote:
> 
> The HP Elite x3 Lap Dock is a laptop-like external display device with a
> FHD screen, a keyboard, and a MT touchpad. It can be connected via USB-C
> or Miracast. As an e-waste collector, I recently brought one for 69 CNY
> (10.2 USD). The price already indicates how broken the device's design
> and compatibility are ;-P
> 
> When connecting via USB-C, the video source is, of course, DisplayPort
> Alternate Mode. However, the audio source has nothing to do with the
> DisplayPort signal and is actually from a builtin UAC device.
> 
> The builtin UAC device provides three Alternate Settings:
> 
> - 1:1 - Capture, S16_LE, 8000/32000/44100/48000Hz
> - 2:1 - Playback, S16_LE, 48000Hz
> - 2:2 - Playback, S24_3LE, 48000Hz
> 
> Unfortunately, the last one is broken because:
> 
> - it doesn't accept SET_CUR(SAMPLE_RATE). QUIRK_FLAG_FIXED_RATE works
>   around it, however...
> - it constantly produces severe harmonic distortion once the capture
>   stream is also opened. The interface 2 must be closed and reopened to
>   make it recover. IOW, simply closing the capture stream makes no
>   difference.
> 
> Considering that S24_3LE offers no additional benefit on small speakers
> compared to S16_LE, and 2:1 is always usable as an alternative, skip 2:2
> to get rid of the trouble.
> 
> Setting chip->setup to any non-default value disables the fixup and
> reenables 2:2 (in this case QUIRK_FLAG_FIXED_RATE is required).
> 
> Quirky device sample:
> 
>   usb 7-1.4: new full-speed USB device number 50 using xhci_hcd
>   usb 7-1.4: New USB device found, idVendor=03f0, idProduct=0c56, bcdDevice= 0.00
>   usb 7-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
>   usb 7-1.4: Product: HP Elite x3 Lap Dock
>   usb 7-1.4: Manufacturer: HP
>   usb 7-1.4: Found last interface = 0
>   usb 7-1.4: 1:1: add audio endpoint 0x81
>   usb 7-1.4: Creating new data endpoint #81
>   usb 7-1.4: 1:1 Set sample rate 48000, clock 0
>   usb 7-1.4: 2:1: add audio endpoint 0x1
>   usb 7-1.4: Creating new data endpoint #1
>   usb 7-1.4: 2:1 Set sample rate 48000, clock 0
>   usb 7-1.4: 2:2: add audio endpoint 0x1
>   usb 7-1.4: 2:2 Set sample rate 48000, clock 0
>   usb 7-1.4: 2:2: cannot set freq 48000 to ep 0x1
>   usb 7-1.4: [9] FU [Sidetone Playback Switch] ch = 1, val = 0/1/1
>   usb 7-1.4: cannot set ctl value: req = 0x4, wValue = 0x200, wIndex = 0x900, type = 4, data = 0x40/0x0
>   usb 7-1.4: [9] FU [Sidetone Playback Volume] ch = 1, val = -17664/0/128
>   usb 7-1.4: [2] FU [Headset Playback Switch] ch = 1, val = 0/1/1
>   usb 7-1.4: [2] FU [Headset Playback Volume] ch = 2, val = -18944/0/1
>   usb 7-1.4: [6] FU [Headset Capture Switch] ch = 1, val = 0/1/1
>   usb 7-1.4: [6] FU [Headset Capture Volume] ch = 2, val = -18944/0/1
>   input: HP HP Elite x3 Lap Dock Consumer Control as /devices/pci0000:00/0000:00:08.3/0000:c9:00.4/usb7/7-1/7-1.4/7-1.4:1.3/0003:03F0:0C56.0033/input/input129
>   input: HP HP Elite x3 Lap Dock as /devices/pci0000:00/0000:00:08.3/0000:c9:00.4/usb7/7-1/7-1.4/7-1.4:1.3/0003:03F0:0C56.0033/input/input130
>   hid-generic 0003:03F0:0C56.0033: input,hiddev100,hidraw8: USB HID v1.11 Device [HP HP Elite x3 Lap Dock] on usb-0000:c9:00.4-1.4/input3
> 
> Signed-off-by: Rong Zhang <i@rong.moe>
> ---
> Rong Zhang (2):
>       ALSA: usb-audio: Convert snd_usb_apply_interface_quirk() into a switch statement
>       ALSA: usb-audio: Add quirks for HP Elite x3 Lap Dock

Applied both to for-next branch.  Thanks.


Takashi

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-09-08  7:12 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-07 19:34 [PATCH 0/2] ALSA: usb-audio: Add quirks for HP Elite x3 Lap Dock Rong Zhang
2026-09-07 19:34 ` [PATCH 1/2] ALSA: usb-audio: Convert snd_usb_apply_interface_quirk() into a switch statement Rong Zhang
2026-09-07 19:34 ` [PATCH 2/2] ALSA: usb-audio: Add quirks for HP Elite x3 Lap Dock Rong Zhang
2026-09-08  7:12 ` [PATCH 0/2] " Takashi Iwai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox