Statistics
| Branch: | Tag: | Revision:

root / LUFA / Drivers / USB / Class / Host / Audio.c @ 978b99e5

History | View | Annotate | Download (8.67 KB)

1
/*
2
             LUFA Library
3
     Copyright (C) Dean Camera, 2011.
4

5
  dean [at] fourwalledcubicle [dot] com
6
           www.lufa-lib.org
7
*/
8

    
9
/*
10
  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
11

12
  Permission to use, copy, modify, distribute, and sell this
13
  software and its documentation for any purpose is hereby granted
14
  without fee, provided that the above copyright notice appear in
15
  all copies and that both that the copyright notice and this
16
  permission notice and warranty disclaimer appear in supporting
17
  documentation, and that the name of the author not be used in
18
  advertising or publicity pertaining to distribution of the
19
  software without specific, written prior permission.
20

21
  The author disclaim all warranties with regard to this
22
  software, including all implied warranties of merchantability
23
  and fitness.  In no event shall the author be liable for any
24
  special, indirect or consequential damages or any damages
25
  whatsoever resulting from loss of use, data or profits, whether
26
  in an action of contract, negligence or other tortious action,
27
  arising out of or in connection with the use or performance of
28
  this software.
29
*/
30

    
31
#define  __INCLUDE_FROM_USB_DRIVER
32
#include "../../Core/USBMode.h"
33

    
34
#if defined(USB_CAN_BE_HOST)
35

    
36
#define  __INCLUDE_FROM_AUDIO_DRIVER
37
#define  __INCLUDE_FROM_AUDIO_HOST_C
38
#include "Audio.h"
39

    
40
uint8_t Audio_Host_ConfigurePipes(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
41
                                  uint16_t ConfigDescriptorSize,
42
                                  void* ConfigDescriptorData)
43
{
44
        USB_Descriptor_Endpoint_t*  DataINEndpoint          = NULL;
45
        USB_Descriptor_Endpoint_t*  DataOUTEndpoint         = NULL;
46
        USB_Descriptor_Interface_t* AudioControlInterface   = NULL;
47
        USB_Descriptor_Interface_t* AudioStreamingInterface = NULL;
48

    
49
        memset(&AudioInterfaceInfo->State, 0x00, sizeof(AudioInterfaceInfo->State));
50

    
51
        if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration)
52
          return AUDIO_ENUMERROR_InvalidConfigDescriptor;
53

    
54
        while ((AudioInterfaceInfo->Config.DataINPipeNumber  && !(DataINEndpoint)) ||
55
               (AudioInterfaceInfo->Config.DataOUTPipeNumber && !(DataOUTEndpoint)))
56
        {
57
                if (!(AudioControlInterface) ||
58
                    USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
59
                                              DCOMP_Audio_Host_NextAudioInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
60
                {
61
                        if (!(AudioControlInterface) ||
62
                            USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
63
                                                      DCOMP_Audio_Host_NextAudioStreamInterface) != DESCRIPTOR_SEARCH_COMP_Found)
64
                        {
65
                                if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
66
                                                              DCOMP_Audio_Host_NextAudioControlInterface) != DESCRIPTOR_SEARCH_COMP_Found)
67
                                {
68
                                        return AUDIO_ENUMERROR_NoCompatibleInterfaceFound;
69
                                }
70

    
71
                                AudioControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);                        
72

    
73
                                if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
74
                                                              DCOMP_Audio_Host_NextAudioStreamInterface) != DESCRIPTOR_SEARCH_COMP_Found)
75
                                {
76
                                        return AUDIO_ENUMERROR_NoCompatibleInterfaceFound;
77
                                }
78
                        }
79

    
80
                        AudioStreamingInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t);
81
                        
82
                        DataINEndpoint  = NULL;
83
                        DataOUTEndpoint = NULL;
84

    
85
                        continue;
86
                }
87

    
88
                USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t);
89

    
90
                if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN)
91
                  DataINEndpoint  = EndpointData;
92
                else
93
                  DataOUTEndpoint = EndpointData;
94
        }
95

    
96
        for (uint8_t PipeNum = 1; PipeNum < PIPE_TOTAL_PIPES; PipeNum++)
97
        {
98
                uint16_t Size;
99
                uint8_t  Type;
100
                uint8_t  Token;
101
                uint8_t  EndpointAddress;
102
                bool     DoubleBanked;
103

    
104
                if (PipeNum == AudioInterfaceInfo->Config.DataINPipeNumber)
105
                {
106
                        Size            = le16_to_cpu(DataINEndpoint->EndpointSize);
107
                        EndpointAddress = DataINEndpoint->EndpointAddress;
108
                        Token           = PIPE_TOKEN_IN;
109
                        Type            = EP_TYPE_ISOCHRONOUS;
110
                        DoubleBanked    = true;
111

    
112
                        AudioInterfaceInfo->State.DataINPipeSize = DataINEndpoint->EndpointSize;
113
                }
114
                else if (PipeNum == AudioInterfaceInfo->Config.DataOUTPipeNumber)
115
                {
116
                        Size            = le16_to_cpu(DataOUTEndpoint->EndpointSize);
117
                        EndpointAddress = DataOUTEndpoint->EndpointAddress;
118
                        Token           = PIPE_TOKEN_OUT;
119
                        Type            = EP_TYPE_ISOCHRONOUS;
120
                        DoubleBanked    = true;
121

    
122
                        AudioInterfaceInfo->State.DataOUTPipeSize = DataOUTEndpoint->EndpointSize;
123
                }
124
                else
125
                {
126
                        continue;
127
                }
128
                
129
                if (!(Pipe_ConfigurePipe(PipeNum, Type, Token, EndpointAddress, Size,
130
                                         DoubleBanked ? PIPE_BANK_DOUBLE : PIPE_BANK_SINGLE)))
131
                {
132
                        return AUDIO_ENUMERROR_PipeConfigurationFailed;
133
                }
134
        }
135

    
136
        AudioInterfaceInfo->State.ControlInterfaceNumber    = AudioControlInterface->InterfaceNumber;
137
        AudioInterfaceInfo->State.StreamingInterfaceNumber  = AudioStreamingInterface->InterfaceNumber;
138
        AudioInterfaceInfo->State.EnabledStreamingAltIndex  = AudioStreamingInterface->AlternateSetting;
139
        AudioInterfaceInfo->State.IsActive = true;
140
        
141
        return AUDIO_ENUMERROR_NoError;
142
}
143

    
144
static uint8_t DCOMP_Audio_Host_NextAudioControlInterface(void* CurrentDescriptor)
145
{
146
        USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
147

    
148
        if (Header->Type == DTYPE_Interface)
149
        {
150
                USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
151

    
152
                if ((Interface->Class    == AUDIO_CSCP_AudioClass) &&
153
                    (Interface->SubClass == AUDIO_CSCP_ControlSubclass) &&
154
                    (Interface->Protocol == AUDIO_CSCP_ControlProtocol))
155
                {
156
                        return DESCRIPTOR_SEARCH_Found;
157
                }
158
        }
159

    
160
        return DESCRIPTOR_SEARCH_NotFound;
161
}
162

    
163
static uint8_t DCOMP_Audio_Host_NextAudioStreamInterface(void* CurrentDescriptor)
164
{
165
        USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
166

    
167
        if (Header->Type == DTYPE_Interface)
168
        {
169
                USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t);
170

    
171
                if ((Interface->Class    == AUDIO_CSCP_AudioClass) &&
172
                    (Interface->SubClass == AUDIO_CSCP_AudioStreamingSubclass) &&
173
                    (Interface->Protocol == AUDIO_CSCP_StreamingProtocol))
174
                {
175
                        return DESCRIPTOR_SEARCH_Found;
176
                }
177
        }
178

    
179
        return DESCRIPTOR_SEARCH_NotFound;
180
}
181

    
182
static uint8_t DCOMP_Audio_Host_NextAudioInterfaceDataEndpoint(void* CurrentDescriptor)
183
{
184
        USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t);
185

    
186
        if (Header->Type == DTYPE_Endpoint)
187
        {
188
                USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t);
189

    
190
                if ((Endpoint->Attributes & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS)
191
                  return DESCRIPTOR_SEARCH_Found;
192
        }
193
        else if (Header->Type == DTYPE_Interface)
194
        {
195
                return DESCRIPTOR_SEARCH_Fail;
196
        }
197

    
198
        return DESCRIPTOR_SEARCH_NotFound;
199
}
200

    
201
uint8_t Audio_Host_StartStopStreaming(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
202
                                                  const bool EnableStreaming)
203
{
204
        if (!(AudioInterfaceInfo->State.IsActive))
205
          return HOST_SENDCONTROL_DeviceDisconnected;
206

    
207
        return USB_Host_SetInterfaceAltSetting(AudioInterfaceInfo->State.StreamingInterfaceNumber,
208
                                               EnableStreaming ? AudioInterfaceInfo->State.EnabledStreamingAltIndex : 0);
209
}
210

    
211
uint8_t Audio_Host_GetSetEndpointProperty(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo,
212
                                                      const uint8_t DataPipeIndex,
213
                                                      const uint8_t EndpointProperty,
214
                                                      const uint8_t EndpointControl,
215
                                                      const uint16_t DataLength,
216
                                                      void* const Data)
217
{
218
        if (!(AudioInterfaceInfo->State.IsActive))
219
          return HOST_SENDCONTROL_DeviceDisconnected;
220

    
221
        uint8_t RequestType;
222
        uint8_t EndpointAddress;
223

    
224
        if (EndpointProperty & 0x80)
225
          RequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT);
226
        else
227
          RequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT);
228
          
229
        Pipe_SelectPipe(DataPipeIndex);
230
        EndpointAddress = Pipe_GetBoundEndpointAddress();
231

    
232
        USB_ControlRequest = (USB_Request_Header_t)
233
                {
234
                        .bmRequestType = RequestType,
235
                        .bRequest      = EndpointProperty,
236
                        .wValue        = ((uint16_t)EndpointControl << 8),
237
                        .wIndex        = EndpointAddress,
238
                        .wLength       = DataLength,
239
                };
240

    
241
        Pipe_SelectPipe(PIPE_CONTROLPIPE);
242

    
243
        return USB_Host_SendControlRequest(Data);
244
}
245

    
246
#endif
247