diff --git a/class/audio/usbh_audio.c b/class/audio/usbh_audio.c index 38f3bb81..6e7d94e8 100644 --- a/class/audio/usbh_audio.c +++ b/class/audio/usbh_audio.c @@ -159,10 +159,70 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name) setup->wLength = 0; ret = usbh_control_transfer(audio_class->hport->ep0, setup, NULL); - if (ret < 0) { - return ret; + + return ret; +} + +int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, uint8_t volume) +{ + struct usb_setup_packet *setup = audio_class->hport->setup; + int ret; + uint8_t intf = 0xff; + uint8_t feature_id = 0xff; + uint16_t volume_hex; + + for (size_t i = 0; i < audio_class->module_num; i++) { + if (strcmp(name, audio_class->module[i].name) == 0) { + intf = audio_class->ctrl_intf; + feature_id = audio_class->module[i].feature_unit_id; + } } + if (intf == 0xff) { + return -ENODEV; + } + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = AUDIO_REQUEST_SET_CUR; + setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch; + setup->wIndex = (feature_id << 8) | intf; + setup->wLength = 2; + + volume_hex = -0xDB00 / 100 * volume + 0xdb00; + + memcpy(g_audio_buf, &volume_hex, 2); + ret = usbh_control_transfer(audio_class->hport->ep0, setup, NULL); + + return ret; +} + +int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_t ch, bool mute) +{ + struct usb_setup_packet *setup = audio_class->hport->setup; + int ret; + uint8_t intf = 0xff; + uint8_t feature_id = 0xff; + + for (size_t i = 0; i < audio_class->module_num; i++) { + if (strcmp(name, audio_class->module[i].name) == 0) { + intf = audio_class->ctrl_intf; + feature_id = audio_class->module[i].feature_unit_id; + } + } + + if (intf == 0xff) { + return -ENODEV; + } + + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = AUDIO_REQUEST_SET_CUR; + setup->wValue = (AUDIO_FU_CONTROL_MUTE << 8) | ch; + setup->wIndex = (feature_id << 8) | intf; + setup->wLength = 1; + + memcpy(g_audio_buf, &mute, 1); + ret = usbh_control_transfer(audio_class->hport->ep0, setup, g_audio_buf); + return ret; } diff --git a/class/audio/usbh_audio.h b/class/audio/usbh_audio.h index 48ffd72d..dcfed604 100644 --- a/class/audio/usbh_audio.h +++ b/class/audio/usbh_audio.h @@ -61,6 +61,8 @@ extern "C" { int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq); int usbh_audio_close(struct usbh_audio *audio_class, const char *name); +int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, uint8_t volume); +int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_t ch, bool mute); void usbh_audio_run(struct usbh_audio *audio_class); void usbh_audio_stop(struct usbh_audio *audio_class);