aboutsummaryrefslogtreecommitdiffstats
path: root/LUFA/Drivers/USB/Class/Device
diff options
context:
space:
mode:
Diffstat (limited to 'LUFA/Drivers/USB/Class/Device')
-rw-r--r--LUFA/Drivers/USB/Class/Device/Audio.c63
-rw-r--r--LUFA/Drivers/USB/Class/Device/Audio.h29
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