fix clock source process in uac2.0
This commit is contained in:
@@ -52,23 +52,22 @@ struct usbd_audio_attribute_control {
|
|||||||
uint32_t mute_bCUR;
|
uint32_t mute_bCUR;
|
||||||
struct audio_v2_control_range2_param_block_default volume;
|
struct audio_v2_control_range2_param_block_default volume;
|
||||||
uint8_t mute[CONFIG_USBDEV_AUDIO_MAX_CHANNEL];
|
uint8_t mute[CONFIG_USBDEV_AUDIO_MAX_CHANNEL];
|
||||||
uint32_t sampling_freq[CONFIG_USBDEV_AUDIO_MAX_CHANNEL];
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
struct audio_entity_info {
|
struct audio_entity_info {
|
||||||
usb_slist_t list;
|
usb_slist_t list;
|
||||||
uint8_t bDescriptorSubtype;
|
uint8_t bDescriptorSubtype;
|
||||||
uint8_t bEntityId;
|
uint8_t bEntityId;
|
||||||
void *priv;
|
void *priv[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
static usb_slist_t usbd_audio_entity_info_head = USB_SLIST_OBJECT_INIT(usbd_audio_entity_info_head);
|
static usb_slist_t usbd_audio_entity_info_head = USB_SLIST_OBJECT_INIT(usbd_audio_entity_info_head);
|
||||||
|
|
||||||
const uint8_t default_sampling_freq_table[] = {
|
const uint8_t default_sampling_freq_table[] = {
|
||||||
AUDIO_SAMPLE_FREQ_NUM(5),
|
AUDIO_SAMPLE_FREQ_NUM(1),
|
||||||
AUDIO_SAMPLE_FREQ_4B(8000),
|
// AUDIO_SAMPLE_FREQ_4B(8000),
|
||||||
AUDIO_SAMPLE_FREQ_4B(8000),
|
// AUDIO_SAMPLE_FREQ_4B(8000),
|
||||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
// AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||||
AUDIO_SAMPLE_FREQ_4B(16000),
|
AUDIO_SAMPLE_FREQ_4B(16000),
|
||||||
AUDIO_SAMPLE_FREQ_4B(16000),
|
AUDIO_SAMPLE_FREQ_4B(16000),
|
||||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||||
@@ -81,15 +80,15 @@ const uint8_t default_sampling_freq_table[] = {
|
|||||||
AUDIO_SAMPLE_FREQ_4B(48000),
|
AUDIO_SAMPLE_FREQ_4B(48000),
|
||||||
AUDIO_SAMPLE_FREQ_4B(48000),
|
AUDIO_SAMPLE_FREQ_4B(48000),
|
||||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||||
// AUDIO_SAMPLE_FREQ_4B(88200),
|
AUDIO_SAMPLE_FREQ_4B(88200),
|
||||||
// AUDIO_SAMPLE_FREQ_4B(88200),
|
AUDIO_SAMPLE_FREQ_4B(88200),
|
||||||
// AUDIO_SAMPLE_FREQ_4B(0x00),
|
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||||
// AUDIO_SAMPLE_FREQ_4B(96000),
|
AUDIO_SAMPLE_FREQ_4B(96000),
|
||||||
// AUDIO_SAMPLE_FREQ_4B(96000),
|
AUDIO_SAMPLE_FREQ_4B(96000),
|
||||||
// AUDIO_SAMPLE_FREQ_4B(0x00),
|
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||||
// AUDIO_SAMPLE_FREQ_4B(192000),
|
AUDIO_SAMPLE_FREQ_4B(192000),
|
||||||
// AUDIO_SAMPLE_FREQ_4B(192000),
|
AUDIO_SAMPLE_FREQ_4B(192000),
|
||||||
// AUDIO_SAMPLE_FREQ_4B(0x00),
|
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||||
};
|
};
|
||||||
|
|
||||||
#if CONFIG_USBDEV_AUDIO_VERSION < 0x0200
|
#if CONFIG_USBDEV_AUDIO_VERSION < 0x0200
|
||||||
@@ -144,7 +143,8 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t *
|
|||||||
setup->bRequest);
|
setup->bRequest);
|
||||||
|
|
||||||
struct audio_entity_info *current_entity_info = NULL;
|
struct audio_entity_info *current_entity_info = NULL;
|
||||||
struct usbd_audio_attribute_control *current_control = NULL;
|
struct usbd_audio_attribute_control *current_feature_control = NULL;
|
||||||
|
uint32_t *sampling_freq;
|
||||||
usb_slist_t *i;
|
usb_slist_t *i;
|
||||||
uint8_t entity_id;
|
uint8_t entity_id;
|
||||||
uint8_t control_selector;
|
uint8_t control_selector;
|
||||||
@@ -175,7 +175,8 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t *
|
|||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_control = (struct usbd_audio_attribute_control *)current_entity_info->priv;
|
current_feature_control = (struct usbd_audio_attribute_control *)current_entity_info->priv[0];
|
||||||
|
sampling_freq = (uint32_t *)current_entity_info->priv[1];
|
||||||
|
|
||||||
if (current_entity_info->bDescriptorSubtype == AUDIO_CONTROL_FEATURE_UNIT) {
|
if (current_entity_info->bDescriptorSubtype == AUDIO_CONTROL_FEATURE_UNIT) {
|
||||||
#if CONFIG_USBDEV_AUDIO_VERSION < 0x0200
|
#if CONFIG_USBDEV_AUDIO_VERSION < 0x0200
|
||||||
@@ -186,12 +187,12 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t *
|
|||||||
switch (setup->bRequest) {
|
switch (setup->bRequest) {
|
||||||
case AUDIO_REQUEST_SET_CUR:
|
case AUDIO_REQUEST_SET_CUR:
|
||||||
mute = (*data)[0];
|
mute = (*data)[0];
|
||||||
current_control->mute[ch] = mute;
|
current_feature_control->mute[ch] = mute;
|
||||||
USB_LOG_DBG("Set UnitId:%d ch[%d] mute %s\r\n", entity_id, ch, mute_string[mute]);
|
USB_LOG_DBG("Set UnitId:%d ch[%d] mute %s\r\n", entity_id, ch, mute_string[mute]);
|
||||||
usbd_audio_set_mute(entity_id, ch, mute);
|
usbd_audio_set_mute(entity_id, ch, mute);
|
||||||
break;
|
break;
|
||||||
case AUDIO_REQUEST_GET_CUR:
|
case AUDIO_REQUEST_GET_CUR:
|
||||||
(*data)[0] = current_control->mute[ch];
|
(*data)[0] = current_feature_control->mute[ch];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest);
|
USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest);
|
||||||
@@ -203,7 +204,7 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t *
|
|||||||
switch (setup->bRequest) {
|
switch (setup->bRequest) {
|
||||||
case AUDIO_REQUEST_SET_CUR:
|
case AUDIO_REQUEST_SET_CUR:
|
||||||
volume = (((uint16_t)(*data)[1] << 8) | ((uint16_t)(*data)[0]));
|
volume = (((uint16_t)(*data)[1] << 8) | ((uint16_t)(*data)[0]));
|
||||||
current_control->volume[ch].vol_current = volume;
|
current_feature_control->volume[ch].vol_current = volume;
|
||||||
|
|
||||||
if (volume < 0x8000) {
|
if (volume < 0x8000) {
|
||||||
volume2db = 0.00390625 * volume;
|
volume2db = 0.00390625 * volume;
|
||||||
@@ -215,27 +216,27 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t *
|
|||||||
usbd_audio_set_volume(entity_id, ch, volume2db);
|
usbd_audio_set_volume(entity_id, ch, volume2db);
|
||||||
break;
|
break;
|
||||||
case AUDIO_REQUEST_GET_CUR:
|
case AUDIO_REQUEST_GET_CUR:
|
||||||
memcpy(*data, ¤t_control->volume[ch].vol_current, 2);
|
memcpy(*data, ¤t_feature_control->volume[ch].vol_current, 2);
|
||||||
*len = 2;
|
*len = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AUDIO_REQUEST_GET_MIN:
|
case AUDIO_REQUEST_GET_MIN:
|
||||||
memcpy(*data, ¤t_control->volume[ch].vol_min, 2);
|
memcpy(*data, ¤t_feature_control->volume[ch].vol_min, 2);
|
||||||
*len = 2;
|
*len = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AUDIO_REQUEST_GET_MAX:
|
case AUDIO_REQUEST_GET_MAX:
|
||||||
memcpy(*data, ¤t_control->volume[ch].vol_max, 2);
|
memcpy(*data, ¤t_feature_control->volume[ch].vol_max, 2);
|
||||||
*len = 2;
|
*len = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AUDIO_REQUEST_GET_RES:
|
case AUDIO_REQUEST_GET_RES:
|
||||||
memcpy(*data, ¤t_control->volume[ch].vol_res, 2);
|
memcpy(*data, ¤t_feature_control->volume[ch].vol_res, 2);
|
||||||
*len = 2;
|
*len = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AUDIO_REQUEST_SET_RES:
|
case AUDIO_REQUEST_SET_RES:
|
||||||
memcpy(¤t_control->volume[ch].vol_res, *data, 2);
|
memcpy(¤t_feature_control->volume[ch].vol_res, *data, 2);
|
||||||
*len = 2;
|
*len = 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -253,7 +254,7 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t *
|
|||||||
switch (control_selector) {
|
switch (control_selector) {
|
||||||
case AUDIO_FU_CONTROL_MUTE:
|
case AUDIO_FU_CONTROL_MUTE:
|
||||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||||
(*data)[0] = current_control->mute_bCUR;
|
(*data)[0] = current_feature_control->mute_bCUR;
|
||||||
*len = 1;
|
*len = 1;
|
||||||
} else {
|
} else {
|
||||||
mute = (*data)[0];
|
mute = (*data)[0];
|
||||||
@@ -263,12 +264,12 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t *
|
|||||||
break;
|
break;
|
||||||
case AUDIO_FU_CONTROL_VOLUME:
|
case AUDIO_FU_CONTROL_VOLUME:
|
||||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||||
(*data)[0] = current_control->volume_bCUR & 0XFF;
|
(*data)[0] = current_feature_control->volume_bCUR & 0XFF;
|
||||||
(*data)[1] = (current_control->volume_bCUR >> 8) & 0xff;
|
(*data)[1] = (current_feature_control->volume_bCUR >> 8) & 0xff;
|
||||||
*len = 2;
|
*len = 2;
|
||||||
} else {
|
} else {
|
||||||
volume = (((uint16_t)(*data)[1] << 8) | ((uint16_t)(*data)[0]));
|
volume = (((uint16_t)(*data)[1] << 8) | ((uint16_t)(*data)[0]));
|
||||||
current_control->volume_bCUR = volume;
|
current_feature_control->volume_bCUR = volume;
|
||||||
USB_LOG_DBG("Set UnitId:%d ch[%d] %d dB\r\n", entity_id, ch, volume);
|
USB_LOG_DBG("Set UnitId:%d ch[%d] %d dB\r\n", entity_id, ch, volume);
|
||||||
usbd_audio_set_volume(entity_id, ch, volume);
|
usbd_audio_set_volume(entity_id, ch, volume);
|
||||||
}
|
}
|
||||||
@@ -282,10 +283,10 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t *
|
|||||||
switch (control_selector) {
|
switch (control_selector) {
|
||||||
case AUDIO_FU_CONTROL_VOLUME:
|
case AUDIO_FU_CONTROL_VOLUME:
|
||||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||||
*((uint16_t *)(*data + 0)) = current_control->volume.wNumSubRanges;
|
*((uint16_t *)(*data + 0)) = current_feature_control->volume.wNumSubRanges;
|
||||||
*((uint16_t *)(*data + 2)) = current_control->volume.subrange[ch].wMin;
|
*((uint16_t *)(*data + 2)) = current_feature_control->volume.subrange[ch].wMin;
|
||||||
*((uint16_t *)(*data + 4)) = current_control->volume.subrange[ch].wMax;
|
*((uint16_t *)(*data + 4)) = current_feature_control->volume.subrange[ch].wMax;
|
||||||
*((uint16_t *)(*data + 6)) = current_control->volume.subrange[ch].wRes;
|
*((uint16_t *)(*data + 6)) = current_feature_control->volume.subrange[ch].wRes;
|
||||||
*len = 8;
|
*len = 8;
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
@@ -309,15 +310,12 @@ static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t *
|
|||||||
switch (control_selector) {
|
switch (control_selector) {
|
||||||
case AUDIO_CS_CONTROL_SAM_FREQ:
|
case AUDIO_CS_CONTROL_SAM_FREQ:
|
||||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||||
uint32_t current_sampling_freq = current_control->sampling_freq[ch];
|
memcpy(*data, &sampling_freq[ch], sizeof(uint32_t));
|
||||||
memcpy(*data, ¤t_sampling_freq, sizeof(uint32_t));
|
|
||||||
*len = 4;
|
*len = 4;
|
||||||
} else {
|
} else {
|
||||||
uint32_t sampling_freq;
|
memcpy(&sampling_freq[ch], *data, setup->wLength);
|
||||||
memcpy(&sampling_freq, *data, setup->wLength);
|
USB_LOG_DBG("Set ClockId:%d ch[%d] %d Hz\r\n", entity_id, ch, (int)sampling_freq[ch]);
|
||||||
current_control->sampling_freq[ch] = sampling_freq;
|
usbd_audio_set_sampling_freq(entity_id, ch, sampling_freq[ch]);
|
||||||
USB_LOG_DBG("Set ClockId:%d ch[%d] %d Hz\r\n", entity_id, ch, (int)sampling_freq);
|
|
||||||
usbd_audio_set_sampling_freq(entity_id, ch, sampling_freq);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AUDIO_CS_CONTROL_CLOCK_VALID:
|
case AUDIO_CS_CONTROL_CLOCK_VALID:
|
||||||
@@ -439,13 +437,17 @@ void usbd_audio_add_entity(uint8_t entity_id, uint16_t bDescriptorSubtype)
|
|||||||
control->volume.subrange[ch].wMax = 100;
|
control->volume.subrange[ch].wMax = 100;
|
||||||
control->volume.subrange[ch].wRes = 1;
|
control->volume.subrange[ch].wRes = 1;
|
||||||
control->mute[ch] = 0;
|
control->mute[ch] = 0;
|
||||||
control->sampling_freq[ch] = 16000;
|
|
||||||
control->volume_bCUR = 50;
|
control->volume_bCUR = 50;
|
||||||
control->mute_bCUR = 0;
|
control->mute_bCUR = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
entity_info->priv = control;
|
entity_info->priv[0] = control;
|
||||||
} else if (bDescriptorSubtype == AUDIO_CONTROL_CLOCK_SOURCE) {
|
} else if (bDescriptorSubtype == AUDIO_CONTROL_CLOCK_SOURCE) {
|
||||||
|
uint32_t *sampling_freq = usb_malloc(sizeof(uint32_t) * CONFIG_USBDEV_AUDIO_MAX_CHANNEL);
|
||||||
|
for (size_t ch = 0; ch < CONFIG_USBDEV_AUDIO_MAX_CHANNEL; ch++) {
|
||||||
|
sampling_freq[ch] = 16000;
|
||||||
|
}
|
||||||
|
entity_info->priv[1] = sampling_freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_slist_add_tail(&usbd_audio_entity_info_head, &entity_info->list);
|
usb_slist_add_tail(&usbd_audio_entity_info_head, &entity_info->list);
|
||||||
|
|||||||
Reference in New Issue
Block a user