Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c0ebb9c authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: core: Add support to handle multi config audio device"

parents f02e84cb 54b6a080
Loading
Loading
Loading
Loading
+36 −2
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@

#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/usb/audio.h>
#include <linux/usb/audio-v3.h>
#include "usb.h"

static inline const char *plural(int n)
@@ -42,6 +44,36 @@ static int is_activesync(struct usb_interface_descriptor *desc)
		&& desc->bInterfaceProtocol == 1;
}

static int usb_audio_max_rev_config(struct usb_host_bos *bos)
{
	int desc_cnt, func_cnt, numfunc;
	int num_cfg_desc;
	struct usb_config_summary_descriptor *conf_summary;

	if (!bos || !bos->config_summary)
		goto done;

	conf_summary = bos->config_summary;
	num_cfg_desc = bos->num_config_summary_desc;

	for (desc_cnt = 0; desc_cnt < num_cfg_desc; desc_cnt++) {
		numfunc = conf_summary->bNumFunctions;
		for (func_cnt = 0; func_cnt < numfunc; func_cnt++) {
			/* look for BADD 3.0 */
			if (conf_summary->cs_info[func_cnt].bClass ==
				USB_CLASS_AUDIO &&
				conf_summary->cs_info[func_cnt].bProtocol ==
				UAC_VERSION_3 &&
				conf_summary->cs_info[func_cnt].bSubClass !=
				FULL_ADC_PROFILE)
				return conf_summary->bConfigurationValue;
		}
	}

done:
	return -EINVAL;
}

int usb_choose_configuration(struct usb_device *udev)
{
	int i;
@@ -132,7 +164,6 @@ int usb_choose_configuration(struct usb_device *udev)
			best = c;
			break;
		}

		/* If all the remaining configs are vendor-specific,
		 * choose the first one. */
		else if (!best)
@@ -145,6 +176,9 @@ int usb_choose_configuration(struct usb_device *udev)
			insufficient_power, plural(insufficient_power));

	if (best) {
		/* choose usb audio class preferred config if available */
		i = usb_audio_max_rev_config(udev->bos);
		if (i < 0)
			i = best->desc.bConfigurationValue;
		dev_dbg(&udev->dev,
			"configuration #%d chosen from %d choice%s\n",