diff options
Diffstat (limited to 'LUFA/Drivers/USB/Class/Device')
-rw-r--r-- | LUFA/Drivers/USB/Class/Device/Audio.c | 63 | ||||
-rw-r--r-- | LUFA/Drivers/USB/Class/Device/Audio.h | 29 |
2 files changed, 92 insertions, 0 deletions
diff --git a/LUFA/Drivers/USB/Class/Device/Audio.c b/LUFA/Drivers/USB/Class/Device/Audio.c index 8c5c9960d..f183fdedd 100644 --- a/LUFA/Drivers/USB/Class/Device/Audio.c +++ b/LUFA/Drivers/USB/Class/Device/Audio.c @@ -45,6 +45,22 @@ void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const Audi if (USB_ControlRequest.wIndex != AudioInterfaceInfo->Config.StreamingInterfaceNumber) return; + if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE) + { + if (USB_ControlRequest.wIndex != AudioInterfaceInfo->Config.StreamingInterfaceNumber) + return; + } + else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT) + { + if (!((AudioInterfaceInfo->Config.DataINEndpointNumber && + (USB_ControlRequest.wIndex == AudioInterfaceInfo->Config.DataINEndpointNumber)) || + (AudioInterfaceInfo->Config.DataOUTEndpointNumber && + (USB_ControlRequest.wIndex == AudioInterfaceInfo->Config.DataOUTEndpointNumber)))) + { + return; + } + } + switch (USB_ControlRequest.bRequest) { case REQ_SetInterface: @@ -64,6 +80,53 @@ void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const Audi Endpoint_ClearSETUP(); Endpoint_ClearStatusStage(); } + + break; + case AUDIO_REQ_SetCurrent: + case AUDIO_REQ_SetMinimum: + case AUDIO_REQ_SetMaximum: + case AUDIO_REQ_SetResolution: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT)) + { + uint8_t EndpointProperty = USB_ControlRequest.bRequest; + uint8_t EndpointIndex = (uint8_t)USB_ControlRequest.wIndex; + uint8_t EndpointControl = (USB_ControlRequest.wValue >> 8); + + if (CALLBACK_Audio_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointIndex, EndpointControl, NULL, NULL)) + { + uint16_t ValueLength = USB_ControlRequest.wLength; + uint8_t Value[ValueLength]; + + Endpoint_ClearSETUP(); + Endpoint_Read_Control_Stream_LE(Value, ValueLength); + Endpoint_ClearIN(); + + CALLBACK_Audio_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointIndex, EndpointControl, &ValueLength, Value); + } + } + + break; + case AUDIO_REQ_GetCurrent: + case AUDIO_REQ_GetMinimum: + case AUDIO_REQ_GetMaximum: + case AUDIO_REQ_GetResolution: + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT)) + { + uint8_t EndpointProperty = USB_ControlRequest.bRequest; + uint8_t EndpointIndex = (uint8_t)USB_ControlRequest.wIndex; + uint8_t EndpointControl = (USB_ControlRequest.wValue >> 8); + uint16_t ValueLength = USB_ControlRequest.wLength; + uint8_t Value[ValueLength]; + + if (CALLBACK_Audio_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointIndex, EndpointControl, &ValueLength, Value)) + { + Endpoint_ClearSETUP(); + Endpoint_Write_Control_Stream_LE(Value, ValueLength); + Endpoint_ClearOUT(); + } + } + + break; } } diff --git a/LUFA/Drivers/USB/Class/Device/Audio.h b/LUFA/Drivers/USB/Class/Device/Audio.h index a50bd97cc..a09076341 100644 --- a/LUFA/Drivers/USB/Class/Device/Audio.h +++ b/LUFA/Drivers/USB/Class/Device/Audio.h @@ -130,6 +130,35 @@ * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. */ void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Audio class driver callback for the setting and retrieval of streaming endpoint properties. This callback must be implemented + * in the user application to handle property manipulations on streaming audio endpoints. + * + * When the DataLength parameter is NULL, this callback should only indicate whether the specified operation is valid for + * the given endpoint index, and should return as fast as possible. When non-NULL, this value may be altered for GET operations + * to indicate the size of the retreived data. + * + * \note The length of the retrieved data stored into the Data buffer on GET operations should not exceed the initial value + * of the \c DataLength parameter. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * \param[in] EndpointProperty Property of the endpoint to get or set, a value from \ref Audio_ClassRequests_t. + * \param[in] EndpointIndex Index of the streaming endpoint whose property is being referenced. + * \param[in] EndpointControl Parameter of the endpoint to get or set, a value from \ref Audio_EndpointControls_t. + * \param[in,out] DataLength For SET operations, the length of the parameter data to set. For GET operations, the maximum + * length of the retrieved data. When NULL, the function should return whether the given property + * and parameter is valid for the requested endpoint without reading or modifying the Data buffer. + * \param[in,out] Data Pointer to a location where the parameter data is stored for SET operations, or where + * the retrieved data is to be stored for GET operations. + * + * \return Boolean true if the property get/set was successful, false otherwise + */ + bool CALLBACK_Audio_GetSetEndpointProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, + const uint8_t EndpointProperty, + const uint8_t EndpointIndex, + const uint8_t EndpointControl, + uint16_t* const DataLength, + uint8_t* Data); /* Inline Functions: */ /** General management task for a given Audio class interface, required for the correct operation of the interface. This should |