public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: "Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev, "Jan Schär" <jan@jschaer.ch>,
	"Takashi Iwai" <tiwai@suse.de>, "Sasha Levin" <sashal@kernel.org>
Subject: [PATCH 5.4 47/66] ALSA: usb-audio: Support jack detection on Dell dock
Date: Fri, 15 Nov 2024 07:37:56 +0100	[thread overview]
Message-ID: <20241115063724.541189377@linuxfoundation.org> (raw)
In-Reply-To: <20241115063722.834793938@linuxfoundation.org>

5.4-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jan Schär <jan@jschaer.ch>

[ Upstream commit 4b8ea38fabab45ad911a32a336416062553dfe9c ]

The Dell WD15 dock has a headset and a line out port. Add support for
detecting if a jack is inserted into one of these ports.
For the headset jack, additionally determine if a mic is present.

The WD15 contains an ALC4020 USB audio controller and ALC3263 audio codec
from Realtek. It is a UAC 1 device, and UAC 1 does not support jack
detection. Instead, jack detection works by sending HD Audio commands over
vendor-type USB messages.

I found out how it works by looking at USB captures on Windows.
The audio codec is very similar to the one supported by
sound/soc/codecs/rt298.c / rt298.h, some constant names and the mic
detection are adapted from there. The realtek_add_jack function is adapted
from build_connector_control in sound/usb/mixer.c.

I tested this on a WD15 dock with the latest firmware.

Signed-off-by: Jan Schär <jan@jschaer.ch>
Link: https://lore.kernel.org/r/20220627171855.42338-1-jan@jschaer.ch
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Stable-dep-of: 4413665dd6c5 ("ALSA: usb-audio: Add quirks for Dell WD19 dock")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 sound/usb/mixer_quirks.c | 167 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 167 insertions(+)

diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 1f7c80541d03b..08cbcd69b3251 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -24,6 +24,7 @@
 #include <sound/asoundef.h>
 #include <sound/core.h>
 #include <sound/control.h>
+#include <sound/hda_verbs.h>
 #include <sound/hwdep.h>
 #include <sound/info.h>
 #include <sound/tlv.h>
@@ -1792,6 +1793,169 @@ static int snd_soundblaster_e1_switch_create(struct usb_mixer_interface *mixer)
 					  NULL);
 }
 
+/*
+ * Dell WD15 dock jack detection
+ *
+ * The WD15 contains an ALC4020 USB audio controller and ALC3263 audio codec
+ * from Realtek. It is a UAC 1 device, and UAC 1 does not support jack
+ * detection. Instead, jack detection works by sending HD Audio commands over
+ * vendor-type USB messages.
+ */
+
+#define HDA_VERB_CMD(V, N, D) (((N) << 20) | ((V) << 8) | (D))
+
+#define REALTEK_HDA_VALUE 0x0038
+
+#define REALTEK_HDA_SET		62
+#define REALTEK_HDA_GET_OUT	88
+#define REALTEK_HDA_GET_IN	89
+
+#define REALTEK_LINE1			0x1a
+#define REALTEK_VENDOR_REGISTERS	0x20
+#define REALTEK_HP_OUT			0x21
+
+#define REALTEK_CBJ_CTRL2 0x50
+
+#define REALTEK_JACK_INTERRUPT_NODE 5
+
+#define REALTEK_MIC_FLAG 0x100
+
+static int realtek_hda_set(struct snd_usb_audio *chip, u32 cmd)
+{
+	struct usb_device *dev = chip->dev;
+	u32 buf = cpu_to_be32(cmd);
+
+	return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), REALTEK_HDA_SET,
+			       USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_DIR_OUT,
+			       REALTEK_HDA_VALUE, 0, &buf, sizeof(buf));
+}
+
+static int realtek_hda_get(struct snd_usb_audio *chip, u32 cmd, u32 *value)
+{
+	struct usb_device *dev = chip->dev;
+	int err;
+	u32 buf = cpu_to_be32(cmd);
+
+	err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), REALTEK_HDA_GET_OUT,
+			      USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_DIR_OUT,
+			      REALTEK_HDA_VALUE, 0, &buf, sizeof(buf));
+	if (err < 0)
+		return err;
+	err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), REALTEK_HDA_GET_IN,
+			      USB_RECIP_DEVICE | USB_TYPE_VENDOR | USB_DIR_IN,
+			      REALTEK_HDA_VALUE, 0, &buf, sizeof(buf));
+	if (err < 0)
+		return err;
+
+	*value = be32_to_cpu(buf);
+	return 0;
+}
+
+static int realtek_ctl_connector_get(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_info *cval = kcontrol->private_data;
+	struct snd_usb_audio *chip = cval->head.mixer->chip;
+	u32 pv = kcontrol->private_value;
+	u32 node_id = pv & 0xff;
+	u32 sense;
+	u32 cbj_ctrl2;
+	bool presence;
+	int err;
+
+	err = snd_usb_lock_shutdown(chip);
+	if (err < 0)
+		return err;
+	err = realtek_hda_get(chip,
+			      HDA_VERB_CMD(AC_VERB_GET_PIN_SENSE, node_id, 0),
+			      &sense);
+	if (err < 0)
+		goto err;
+	if (pv & REALTEK_MIC_FLAG) {
+		err = realtek_hda_set(chip,
+				      HDA_VERB_CMD(AC_VERB_SET_COEF_INDEX,
+						   REALTEK_VENDOR_REGISTERS,
+						   REALTEK_CBJ_CTRL2));
+		if (err < 0)
+			goto err;
+		err = realtek_hda_get(chip,
+				      HDA_VERB_CMD(AC_VERB_GET_PROC_COEF,
+						   REALTEK_VENDOR_REGISTERS, 0),
+				      &cbj_ctrl2);
+		if (err < 0)
+			goto err;
+	}
+err:
+	snd_usb_unlock_shutdown(chip);
+	if (err < 0)
+		return err;
+
+	presence = sense & AC_PINSENSE_PRESENCE;
+	if (pv & REALTEK_MIC_FLAG)
+		presence = presence && (cbj_ctrl2 & 0x0070) == 0x0070;
+	ucontrol->value.integer.value[0] = presence;
+	return 0;
+}
+
+static const struct snd_kcontrol_new realtek_connector_ctl_ro = {
+	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
+	.name = "", /* will be filled later manually */
+	.access = SNDRV_CTL_ELEM_ACCESS_READ,
+	.info = snd_ctl_boolean_mono_info,
+	.get = realtek_ctl_connector_get,
+};
+
+static int realtek_resume_jack(struct usb_mixer_elem_list *list)
+{
+	snd_ctl_notify(list->mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+		       &list->kctl->id);
+	return 0;
+}
+
+static int realtek_add_jack(struct usb_mixer_interface *mixer,
+			    char *name, u32 val)
+{
+	struct usb_mixer_elem_info *cval;
+	struct snd_kcontrol *kctl;
+
+	cval = kzalloc(sizeof(*cval), GFP_KERNEL);
+	if (!cval)
+		return -ENOMEM;
+	snd_usb_mixer_elem_init_std(&cval->head, mixer,
+				    REALTEK_JACK_INTERRUPT_NODE);
+	cval->head.resume = realtek_resume_jack;
+	cval->val_type = USB_MIXER_BOOLEAN;
+	cval->channels = 1;
+	cval->min = 0;
+	cval->max = 1;
+	kctl = snd_ctl_new1(&realtek_connector_ctl_ro, cval);
+	if (!kctl) {
+		kfree(cval);
+		return -ENOMEM;
+	}
+	kctl->private_value = val;
+	strscpy(kctl->id.name, name, sizeof(kctl->id.name));
+	kctl->private_free = snd_usb_mixer_elem_free;
+	return snd_usb_mixer_add_control(&cval->head, kctl);
+}
+
+static int dell_dock_mixer_create(struct usb_mixer_interface *mixer)
+{
+	int err;
+
+	err = realtek_add_jack(mixer, "Line Out Jack", REALTEK_LINE1);
+	if (err < 0)
+		return err;
+	err = realtek_add_jack(mixer, "Headphone Jack", REALTEK_HP_OUT);
+	if (err < 0)
+		return err;
+	err = realtek_add_jack(mixer, "Headset Mic Jack",
+			       REALTEK_HP_OUT | REALTEK_MIC_FLAG);
+	if (err < 0)
+		return err;
+	return 0;
+}
+
 static void dell_dock_init_vol(struct snd_usb_audio *chip, int ch, int id)
 {
 	u16 buf = 0;
@@ -2275,6 +2439,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
 		err = snd_soundblaster_e1_switch_create(mixer);
 		break;
 	case USB_ID(0x0bda, 0x4014): /* Dell WD15 dock */
+		err = dell_dock_mixer_create(mixer);
+		if (err < 0)
+			break;
 		err = dell_dock_mixer_init(mixer);
 		break;
 
-- 
2.43.0




  parent reply	other threads:[~2024-11-15  6:45 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-15  6:37 [PATCH 5.4 00/66] 5.4.286-rc1 review Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 01/66] arm64: dts: rockchip: Fix rt5651 compatible value on rk3399-sapphire-excavator Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 02/66] arm64: dts: rockchip: Remove hdmis 2nd interrupt on rk3328 Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 03/66] arm64: dts: rockchip: Fix bluetooth properties on Rock960 boards Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 04/66] arm64: dts: rockchip: Remove #cooling-cells from fan on Theobroma lion Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 05/66] ARM: dts: rockchip: fix rk3036 acodec node Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 06/66] ARM: dts: rockchip: drop grf reference from rk3036 hdmi Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 07/66] ARM: dts: rockchip: Fix the spi controller on rk3036 Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 08/66] ARM: dts: rockchip: Fix the realtek audio codec on rk3036-kylin Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 09/66] HID: core: zero-initialize the report buffer Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 10/66] security/keys: fix slab-out-of-bounds in key_task_permission Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 11/66] enetc: simplify the return expression of enetc_vf_set_mac_addr() Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 12/66] net: enetc: set MAC address to the VF net_device Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 13/66] sctp: properly validate chunk size in sctp_sf_ootb() Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 14/66] can: c_can: fix {rx,tx}_errors statistics Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 15/66] net: hns3: fix kernel crash when uninstalling driver Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 16/66] media: stb0899_algo: initialize cfr before using it Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 17/66] media: dvbdev: prevent the risk of out of memory access Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 18/66] media: dvb_frontend: dont play tricks with underflow values Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 19/66] media: adv7604: prevent underflow condition when reporting colorspace Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 20/66] ALSA: firewire-lib: fix return value on fail in amdtp_tscm_init() Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 21/66] media: s5p-jpeg: prevent buffer overflows Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 22/66] media: cx24116: prevent overflows on SNR calculus Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 23/66] media: v4l2-tpg: prevent the risk of a division by zero Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 24/66] pwm: imx-tpm: Use correct MODULO value for EPWM mode Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 25/66] drm/amdgpu: add missing size check in amdgpu_debugfs_gprwave_read() Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 26/66] drm/amdgpu: prevent NULL pointer dereference if ATIF is not supported Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 27/66] dm cache: correct the number of origin blocks to match the target length Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 28/66] dm cache: fix out-of-bounds access to the dirty bitset when resizing Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 29/66] dm cache: optimize dirty bit checking with find_next_bit " Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 30/66] dm cache: fix potential out-of-bounds access on the first resume Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 31/66] dm-unstriped: cast an operand to sector_t to prevent potential uint32_t overflow Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 32/66] nfs: Fix KMSAN warning in decode_getfattr_attrs() Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 33/66] btrfs: reinitialize delayed ref list after deleting it from the list Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 34/66] mtd: rawnand: protect access to rawnand devices while in suspend Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 35/66] spi: Fix deadlock when adding SPI controllers on SPI buses Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 36/66] spi: fix use-after-free of the add_lock mutex Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 37/66] net: bridge: xmit: make sure we have at least eth header len bytes Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 38/66] media: uvcvideo: Skip parsing frames of type UVC_VS_UNDEFINED in uvc_parse_format Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 39/66] fs/proc: fix compile warning about variable vmcore_mmap_ops Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 40/66] usb: musb: sunxi: Fix accessing an released usb phy Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 41/66] USB: serial: io_edgeport: fix use after free in debug printk Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 42/66] USB: serial: qcserial: add support for Sierra Wireless EM86xx Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 43/66] USB: serial: option: add Fibocom FG132 0x0112 composition Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 44/66] USB: serial: option: add Quectel RG650V Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 45/66] irqchip/gic-v3: Force propagation of the active state with a read-back Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 46/66] ocfs2: remove entry once instead of null-ptr-dereference in ocfs2_xa_remove() Greg Kroah-Hartman
2024-11-15  6:37 ` Greg Kroah-Hartman [this message]
2024-11-15  6:37 ` [PATCH 5.4 48/66] ALSA: usb-audio: Add quirks for Dell WD19 dock Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 49/66] NFSD: Fix NFSv4s PUTPUBFH operation Greg Kroah-Hartman
2024-11-15  6:37 ` [PATCH 5.4 50/66] ftrace: Fix possible use-after-free issue in ftrace_location() Greg Kroah-Hartman
2024-11-15 15:24   ` Steven Rostedt
2025-01-07  8:51   ` Koichiro Den
2025-01-07 16:14     ` Steven Rostedt
2025-01-08  2:35       ` Koichiro Den
2024-11-15  6:38 ` [PATCH 5.4 51/66] hv_sock: Initializing vsk->trans to NULL to prevent a dangling pointer Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 5.4 52/66] vsock/virtio: Initialization of the dangling pointer occurring in vsk->trans Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 5.4 53/66] ALSA: usb-audio: Add endianness annotations Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 5.4 54/66] 9p: Avoid creating multiple slab caches with the same name Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 5.4 55/66] HID: multitouch: Add quirk for HONOR MagicBook Art 14 touchpad Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 5.4 56/66] bpf: use kvzmalloc to allocate BPF verifier environment Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 5.4 57/66] sound: Make CONFIG_SND depend on INDIRECT_IOMEM instead of UML Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 5.4 58/66] powerpc/powernv: Free name on error in opal_event_init() Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 5.4 59/66] fs: Fix uninitialized value issue in from_kuid and from_kgid Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 5.4 60/66] net: usb: qmi_wwan: add Fibocom FG132 0x0112 composition Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 5.4 61/66] md/raid10: improve code of mrdev in raid10_sync_request Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 5.4 62/66] mm: clarify a confusing comment for remap_pfn_range() Greg Kroah-Hartman
2024-11-15  7:00   ` Harshvardhan Jha
2024-11-15  8:28     ` Greg Kroah-Hartman
2024-11-15  8:33       ` Harshvardhan Jha
2024-11-15  9:21         ` Greg Kroah-Hartman
2024-11-15  9:36           ` Harshvardhan Jha
2024-11-15  6:38 ` [PATCH 5.4 63/66] mm: fix ambiguous comments for better code readability Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 5.4 64/66] mm/memory.c: make remap_pfn_range() reject unaligned addr Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 5.4 65/66] mm: add remap_pfn_range_notrack Greg Kroah-Hartman
2024-11-15  6:38 ` [PATCH 5.4 66/66] 9p: fix slab cache name creation for real Greg Kroah-Hartman
2024-11-15 15:59 ` [PATCH 5.4 00/66] 5.4.286-rc1 review Harshit Mogalapalli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241115063724.541189377@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=jan@jschaer.ch \
    --cc=patches@lists.linux.dev \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox