diff mbox series

[RFC,13/15] ALSA: usb: Add getters to obtain endpoint information

Message ID 20250409110731.3752332-14-cezary.rojewski@intel.com (mailing list archive)
State RFC
Headers show
Series ALSA/ASoC: USB Audio Offload | expand

Commit Message

Cezary Rojewski April 9, 2025, 11:07 a.m. UTC
Intel's Audio Link Hub (ALH) requires information about the data and
feedback endpoints to manage the offloaded PCM stream properly.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 include/sound/usb.h |  4 ++++
 sound/usb/card.h    |  4 ++--
 sound/usb/stream.c  | 51 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/include/sound/usb.h b/include/sound/usb.h
index b20badfda6a6..8f6e26d4de48 100644
--- a/include/sound/usb.h
+++ b/include/sound/usb.h
@@ -96,6 +96,10 @@  int snd_usb_bind_card(struct snd_usb_audio *chip, struct snd_card *card,
 		      struct usb_driver *driver);
 int snd_usb_bind_pcm(struct list_head *stream_entry, struct snd_pcm *pcm);
 void snd_usb_pcm_hw_init(struct list_head *stream_entry, int dir, struct snd_pcm_hardware *hw);
+void snd_usb_pcm_get_epaddr(struct list_head *stream_entry, int dir, u8 *data_epaddr,
+			    u8 *fb_epaddr);
+void snd_usb_pcm_get_epinfo(struct list_head *stream_entry, int dir, u16 *data_maxp, u16 *fb_maxp,
+			    u8 *fb_syncinterval);
 
 /* USB interface operations, see struct usb_driver. */
 int snd_usb_probe(struct usb_interface *iface, const struct usb_device_id *usb_id,
diff --git a/sound/usb/card.h b/sound/usb/card.h
index 6ec95b2edf86..00c6e9046296 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -21,10 +21,10 @@  struct audioformat {
 	unsigned char ep_idx;		/* endpoint array index */
 	unsigned char altset_idx;	/* array index of alternate setting */
 	unsigned char attributes;	/* corresponding attributes of cs endpoint */
-	unsigned char endpoint;		/* endpoint */
+	unsigned char endpoint;		/* bEndpointAddress of data endpoint */
 	unsigned char ep_attr;		/* endpoint attributes */
 	bool implicit_fb;		/* implicit feedback endpoint */
-	unsigned char sync_ep;		/* sync endpoint number */
+	unsigned char sync_ep;		/* bEndpointAddress of feedback endpoint */
 	unsigned char sync_iface;	/* sync EP interface */
 	unsigned char sync_altsetting;	/* sync EP alternate setting */
 	unsigned char sync_ep_idx;	/* sync EP array index */
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index 601dc9ed020a..8f8a049f5b43 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -623,6 +623,57 @@  static int snd_usb_add_audio_stream_v3(struct snd_usb_audio *chip,
 	return snd_usb_parse_pcm(chip, stream, fp, pd);
 }
 
+/**
+ * snd_usb_pcm_get_epaddr - Obtain addresses of the stream endpoints.
+ *
+ * @stream_entry: The USB stream
+ * @dir: Substream's direction
+ * @data_epaddr: returned bEndpointAddress of the data endpoint
+ * @fb_epaddr: returned bEndpointAddress of the feedback endpoint
+ */
+void snd_usb_pcm_get_epaddr(struct list_head *stream_entry, int dir, u8 *data_epaddr,
+			    u8 *fb_epaddr)
+{
+	struct snd_usb_substream *subs;
+	struct snd_usb_stream *as;
+	struct audioformat *fp;
+
+	as = list_entry(stream_entry, struct snd_usb_stream, list);
+	subs = &as->substream[dir];
+	fp = list_first_entry(&subs->fmt_list, struct audioformat, list);
+
+	*data_epaddr = fp->endpoint;
+	*fb_epaddr = fp->sync_ep;
+}
+EXPORT_SYMBOL_GPL(snd_usb_pcm_get_epaddr);
+
+/**
+ * snd_usb_pcm_get_epinfo - Obtain runtime information of the stream endpoints.
+ *
+ * @stream_entry: The USB stream
+ * @dir: Substream's direction
+ * @data_maxp: returned wMaxPacketSize of the data endpoint
+ * @fb_maxp: returned wMaxPacketSize of the feedback endpoint
+ * @fb_syncinterval: returned synchronization interval of the feedback endpoint
+ */
+void snd_usb_pcm_get_epinfo(struct list_head *stream_entry, int dir, u16 *data_maxp, u16 *fb_maxp,
+			    u8 *fb_syncinterval)
+{
+	struct snd_usb_substream *subs;
+	struct snd_usb_stream *as;
+
+	as = list_entry(stream_entry, struct snd_usb_stream, list);
+	subs = &as->substream[dir];
+
+	if (subs->data_endpoint)
+		*data_maxp = subs->data_endpoint->maxpacksize;
+	if (subs->sync_endpoint) {
+		*fb_maxp = subs->sync_endpoint->maxpacksize;
+		*fb_syncinterval = subs->sync_endpoint->syncinterval;
+	}
+}
+EXPORT_SYMBOL_GPL(snd_usb_pcm_get_epinfo);
+
 static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip,
 					 struct usb_host_interface *alts,
 					 int protocol, int iface_no)