summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2023-03-22 14:58:07 +0800
committersakumisu <[email protected]>2023-03-22 14:58:07 +0800
commite9ad3bdc21c9f223edad45679cb863bd3f8b0e09 (patch)
tree36cddc19d5e42909110ae9becb597fc26397195e
parent9c5af19cb1cc9be52fe5c7f2964031e006b71556 (diff)
add volume and mute control
-rw-r--r--class/audio/usbh_audio.c64
-rw-r--r--class/audio/usbh_audio.h2
2 files changed, 64 insertions, 2 deletions
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);