Skip to content

Commit

Permalink
usb: gadget: f_uac2: allow changing terminal types through configfs
Browse files Browse the repository at this point in the history
Add "c_terminal_type" and "p_terminal_type" configfs entries
in order to allow the user to change the capture and playback terminal
type codes.

These fields affect the type of audio device that Windows detects, so
being able to modify this is useful when it would be advantageous for
a gadget to be detected as something other than a generic
speaker/microphone.

The fields default to microphone for the capture type field and speaker
for the playback type field as was the case before.

Signed-off-by: James Gruber <jimmyjgruber@gmail.com>
Link: https://lore.kernel.org/r/20230914222746.155126-1-jimmyjgruber@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
James Gruber authored and Greg Kroah-Hartman committed Oct 5, 2023
1 parent af31320 commit de2eb28
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 2 deletions.
2 changes: 2 additions & 0 deletions Documentation/ABI/testing/configfs-usb-gadget-uac2
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ Description:
req_number the number of pre-allocated requests
for both capture and playback
function_name name of the interface
c_terminal_type code of the capture terminal type
p_terminal_type code of the playback terminal type
===================== =======================================
2 changes: 2 additions & 0 deletions Documentation/usb/gadget-testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,8 @@ The uac2 function provides these attributes in its function directory:
req_number the number of pre-allocated request for both capture
and playback
function_name name of the interface
c_terminal_type code of the capture terminal type
p_terminal_type code of the playback terminal type
================ ====================================================

The attributes have sane default values.
Expand Down
16 changes: 14 additions & 2 deletions drivers/usb/gadget/function/f_uac2.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ static struct uac2_input_terminal_descriptor io_in_it_desc = {

.bDescriptorSubtype = UAC_INPUT_TERMINAL,
/* .bTerminalID = DYNAMIC */
.wTerminalType = cpu_to_le16(UAC_INPUT_TERMINAL_MICROPHONE),
/* .wTerminalType = DYNAMIC */
.bAssocTerminal = 0,
/* .bCSourceID = DYNAMIC */
.iChannelNames = 0,
Expand Down Expand Up @@ -240,7 +240,7 @@ static struct uac2_output_terminal_descriptor io_out_ot_desc = {

.bDescriptorSubtype = UAC_OUTPUT_TERMINAL,
/* .bTerminalID = DYNAMIC */
.wTerminalType = cpu_to_le16(UAC_OUTPUT_TERMINAL_SPEAKER),
/* .wTerminalType = DYNAMIC */
.bAssocTerminal = 0,
/* .bSourceID = DYNAMIC */
/* .bCSourceID = DYNAMIC */
Expand Down Expand Up @@ -977,6 +977,9 @@ static void setup_descriptor(struct f_uac2_opts *opts)
iad_desc.bInterfaceCount++;
}

io_in_it_desc.wTerminalType = cpu_to_le16(opts->c_terminal_type);
io_out_ot_desc.wTerminalType = cpu_to_le16(opts->p_terminal_type);

setup_headers(opts, fs_audio_desc, USB_SPEED_FULL);
setup_headers(opts, hs_audio_desc, USB_SPEED_HIGH);
setup_headers(opts, ss_audio_desc, USB_SPEED_SUPER);
Expand Down Expand Up @@ -2095,6 +2098,9 @@ UAC2_ATTRIBUTE(s16, c_volume_res);
UAC2_ATTRIBUTE(u32, fb_max);
UAC2_ATTRIBUTE_STRING(function_name);

UAC2_ATTRIBUTE(s16, p_terminal_type);
UAC2_ATTRIBUTE(s16, c_terminal_type);

static struct configfs_attribute *f_uac2_attrs[] = {
&f_uac2_opts_attr_p_chmask,
&f_uac2_opts_attr_p_srate,
Expand Down Expand Up @@ -2122,6 +2128,9 @@ static struct configfs_attribute *f_uac2_attrs[] = {

&f_uac2_opts_attr_function_name,

&f_uac2_opts_attr_p_terminal_type,
&f_uac2_opts_attr_c_terminal_type,

NULL,
};

Expand Down Expand Up @@ -2180,6 +2189,9 @@ static struct usb_function_instance *afunc_alloc_inst(void)

snprintf(opts->function_name, sizeof(opts->function_name), "Source/Sink");

opts->p_terminal_type = UAC2_DEF_P_TERM_TYPE;
opts->c_terminal_type = UAC2_DEF_C_TERM_TYPE;

return &opts->func_inst;
}

Expand Down
8 changes: 8 additions & 0 deletions drivers/usb/gadget/function/u_uac2.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
#define UAC2_DEF_REQ_NUM 2
#define UAC2_DEF_INT_REQ_NUM 10

#define UAC2_DEF_P_TERM_TYPE 0x301
/* UAC_OUTPUT_TERMINAL_SPEAKER */
#define UAC2_DEF_C_TERM_TYPE 0x201
/* UAC_INPUT_TERMINAL_MICROPHONE*/

struct f_uac2_opts {
struct usb_function_instance func_inst;
int p_chmask;
Expand Down Expand Up @@ -65,6 +70,9 @@ struct f_uac2_opts {

char function_name[32];

s16 p_terminal_type;
s16 c_terminal_type;

struct mutex lock;
int refcnt;
};
Expand Down

0 comments on commit de2eb28

Please sign in to comment.