Merge "usb: core: Add support to handle multi config audio device"
This commit is contained in:
commit
6c27d8d8b7
4 changed files with 69 additions and 2 deletions
|
@ -949,6 +949,14 @@ int usb_get_bos_descriptor(struct usb_device *dev)
|
|||
dev->bos->ss_id =
|
||||
(struct usb_ss_container_id_descriptor *)buffer;
|
||||
break;
|
||||
case USB_CAP_TYPE_CONFIG_SUMMARY:
|
||||
/* one such desc per configuration */
|
||||
if (!dev->bos->num_config_summary_desc)
|
||||
dev->bos->config_summary =
|
||||
(struct usb_config_summary_descriptor *)buffer;
|
||||
|
||||
dev->bos->num_config_summary_desc++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,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)
|
||||
|
@ -40,6 +42,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;
|
||||
|
@ -130,7 +162,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)
|
||||
|
@ -143,7 +174,10 @@ int usb_choose_configuration(struct usb_device *udev)
|
|||
insufficient_power, plural(insufficient_power));
|
||||
|
||||
if (best) {
|
||||
i = best->desc.bConfigurationValue;
|
||||
/* 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",
|
||||
i, num_configs, plural(num_configs));
|
||||
|
|
|
@ -330,6 +330,8 @@ struct usb_host_bos {
|
|||
struct usb_ss_cap_descriptor *ss_cap;
|
||||
struct usb_ssp_cap_descriptor *ssp_cap;
|
||||
struct usb_ss_container_id_descriptor *ss_id;
|
||||
struct usb_config_summary_descriptor *config_summary;
|
||||
unsigned int num_config_summary_desc;
|
||||
};
|
||||
|
||||
int __usb_get_extra_descriptor(char *buffer, unsigned size,
|
||||
|
|
|
@ -894,6 +894,29 @@ struct usb_ssp_cap_descriptor {
|
|||
#define USB_SSP_SUBLINK_SPEED_LSM (0xff << 16) /* Lanespeed mantissa */
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* Configuration Summary descriptors: Defines a list of functions in the
|
||||
* configuration. This descriptor may be used by Host software to decide
|
||||
* which Configuration to use to obtain the desired functionality.
|
||||
*/
|
||||
#define USB_CAP_TYPE_CONFIG_SUMMARY 0x10
|
||||
|
||||
struct function_class_info {
|
||||
__u8 bClass;
|
||||
__u8 bSubClass;
|
||||
__u8 bProtocol;
|
||||
};
|
||||
|
||||
struct usb_config_summary_descriptor {
|
||||
__u8 bLength;
|
||||
__u8 bDescriptorType;
|
||||
__u8 bDevCapabilityType;
|
||||
__u16 bcdVersion;
|
||||
__u8 bConfigurationValue;
|
||||
__u8 bMaxPower;
|
||||
__u8 bNumFunctions;
|
||||
struct function_class_info cs_info[];
|
||||
} __attribute__((packed));
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue