@@ -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,
@@ -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 */
@@ -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)
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(-)