Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: gadget: f_uac1: allow changing interface name via configfs

This adds "function_name" configfs entry to change string value
of the iInterface field. This field will be shown in Windows' audio
settings panel, so being able to change it is useful. It will default
to "AC Interface" just as before if unchanged.

Signed-off-by: Yunhao Tian <t123yh.xyz@gmail.com>
Link: https://lore.kernel.org/r/20220122112446.1415547-1-t123yh.xyz@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Yunhao Tian and committed by
Greg Kroah-Hartman
dfb05b5d d1d11dd1

+49 -1
+1
Documentation/ABI/testing/configfs-usb-gadget-uac1
··· 29 29 (in 1/256 dB) 30 30 req_number the number of pre-allocated requests 31 31 for both capture and playback 32 + function_name name of the interface 32 33 ===================== =======================================
+1
Documentation/usb/gadget-testing.rst
··· 745 745 p_volume_res playback volume control resolution (in 1/256 dB) 746 746 req_number the number of pre-allocated request for both capture 747 747 and playback 748 + function_name name of the interface 748 749 ================ ==================================================== 749 750 750 751 The attributes have sane default values.
+45 -1
drivers/usb/gadget/function/f_uac1.c
··· 309 309 }; 310 310 311 311 static struct usb_string strings_uac1[] = { 312 - [STR_AC_IF].s = "AC Interface", 312 + /* [STR_AC_IF].s = DYNAMIC, */ 313 313 [STR_USB_OUT_IT].s = "Playback Input terminal", 314 314 [STR_USB_OUT_IT_CH_NAMES].s = "Playback Channels", 315 315 [STR_IO_OUT_OT].s = "Playback Output terminal", ··· 1192 1192 1193 1193 audio_opts = container_of(f->fi, struct f_uac1_opts, func_inst); 1194 1194 1195 + strings_uac1[STR_AC_IF].s = audio_opts->function_name; 1196 + 1195 1197 us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1)); 1196 1198 if (IS_ERR(us)) 1197 1199 return PTR_ERR(us); ··· 1553 1551 \ 1554 1552 CONFIGFS_ATTR(f_uac1_opts_, name) 1555 1553 1554 + #define UAC1_ATTRIBUTE_STRING(name) \ 1555 + static ssize_t f_uac1_opts_##name##_show(struct config_item *item, \ 1556 + char *page) \ 1557 + { \ 1558 + struct f_uac1_opts *opts = to_f_uac1_opts(item); \ 1559 + int result; \ 1560 + \ 1561 + mutex_lock(&opts->lock); \ 1562 + result = snprintf(page, sizeof(opts->name), "%s", opts->name); \ 1563 + mutex_unlock(&opts->lock); \ 1564 + \ 1565 + return result; \ 1566 + } \ 1567 + \ 1568 + static ssize_t f_uac1_opts_##name##_store(struct config_item *item, \ 1569 + const char *page, size_t len) \ 1570 + { \ 1571 + struct f_uac1_opts *opts = to_f_uac1_opts(item); \ 1572 + int ret = 0; \ 1573 + \ 1574 + mutex_lock(&opts->lock); \ 1575 + if (opts->refcnt) { \ 1576 + ret = -EBUSY; \ 1577 + goto end; \ 1578 + } \ 1579 + \ 1580 + ret = snprintf(opts->name, min(sizeof(opts->name), len), \ 1581 + "%s", page); \ 1582 + \ 1583 + end: \ 1584 + mutex_unlock(&opts->lock); \ 1585 + return ret; \ 1586 + } \ 1587 + \ 1588 + CONFIGFS_ATTR(f_uac1_opts_, name) 1589 + 1556 1590 UAC1_ATTRIBUTE(u32, c_chmask); 1557 1591 UAC1_RATE_ATTRIBUTE(c_srate); 1558 1592 UAC1_ATTRIBUTE(u32, c_ssize); ··· 1608 1570 UAC1_ATTRIBUTE(s16, c_volume_min); 1609 1571 UAC1_ATTRIBUTE(s16, c_volume_max); 1610 1572 UAC1_ATTRIBUTE(s16, c_volume_res); 1573 + UAC1_ATTRIBUTE_STRING(function_name); 1611 1574 1612 1575 static struct configfs_attribute *f_uac1_attrs[] = { 1613 1576 &f_uac1_opts_attr_c_chmask, ··· 1630 1591 &f_uac1_opts_attr_c_volume_min, 1631 1592 &f_uac1_opts_attr_c_volume_max, 1632 1593 &f_uac1_opts_attr_c_volume_res, 1594 + 1595 + &f_uac1_opts_attr_function_name, 1633 1596 1634 1597 NULL, 1635 1598 }; ··· 1684 1643 opts->c_volume_res = UAC1_DEF_RES_DB; 1685 1644 1686 1645 opts->req_number = UAC1_DEF_REQ_NUM; 1646 + 1647 + snprintf(opts->function_name, sizeof(opts->function_name), "AC Interface"); 1648 + 1687 1649 return &opts->func_inst; 1688 1650 } 1689 1651
+2
drivers/usb/gadget/function/u_uac1.h
··· 52 52 int req_number; 53 53 unsigned bound:1; 54 54 55 + char function_name[32]; 56 + 55 57 struct mutex lock; 56 58 int refcnt; 57 59 };