1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "audio_usb_linux.h"
10 #include <linux/bitops.h>
11 #include <linux/ctype.h>
12 #include <linux/init.h>
13 #include <linux/list.h>
14 #include <linux/module.h>
15 #include <linux/moduleparam.h>
16 #include <linux/mutex.h>
17 #include <linux/slab.h>
18 #include <linux/string.h>
19 #include <linux/usb.h>
20 #include <linux/usb/audio-v2.h>
21 #include <linux/usb/audio-v3.h>
22 #include <linux/usb/audio.h>
23
24 #include "audio_driver_log.h"
25 #include "audio_usb_endpoints.h"
26 #include "audio_usb_parse_interface.h"
27 #include "audio_usb_validate_desc.h"
28 #include "devmgr_service_clnt.h"
29 #include "devsvc_manager_clnt.h"
30 #include "hdf_device_object.h"
31 #include "osal_time.h"
32
33 #define HDF_LOG_TAG HDF_AUDIO_USB
34
35 #define HDF_AUDIO_USB_CODEC_NAME "hdf_audio_codec_usb_dev0"
36 #define HDF_AUDIO_USB_PNP_SRV_NAME "audio_usb_service_0"
37 #define HDF_AUDIO_USB_DMA_NAME "usb_dma_service_0"
38 #define WAIT_FOR_HDF_START_MILLISECOND 500
39
40 #define USB_SHIFT_SIZE_16 16
41
42 #define LOAD_AUDIO_USB_DRIVER_FREQUENCY 5
43
44 #define USB_DEFAULT_SET 0
45 #define USB_DEFAULT_VAL 0
46
47 static struct AudioUsbDriver g_hdfAudioUsbDriver;
48
GetLinuxAudioUsb(void)49 struct AudioUsbDriver *GetLinuxAudioUsb(void)
50 {
51 return &g_hdfAudioUsbDriver;
52 }
53
AudioUsbGetUsbId(uint32_t vendor,uint32_t product)54 uint32_t AudioUsbGetUsbId(uint32_t vendor, uint32_t product)
55 {
56 // The usb id is composed of vendor id and product id.
57 return (((vendor) << USB_SHIFT_SIZE_16) | (product));
58 }
59
AudioUsbDriverLoad(const char * serviceName)60 static int32_t AudioUsbDriverLoad(const char *serviceName)
61 {
62 struct AudioUsbDriver *usbDriver = NULL;
63 struct DevmgrServiceClnt *hdf = NULL;
64 int32_t ret;
65
66 if (serviceName == NULL) {
67 return HDF_ERR_INVALID_PARAM;
68 }
69
70 usbDriver = GetLinuxAudioUsb();
71 if (usbDriver == NULL) {
72 ADM_LOG_ERR("get linux audio usb driver fail!");
73 return HDF_ERR_INVALID_OBJECT;
74 }
75
76 hdf = DevmgrServiceClntGetInstance();
77 if ((hdf == NULL || hdf->devMgrSvcIf == NULL || hdf->devMgrSvcIf->LoadDevice == NULL)) {
78 return HDF_ERR_INVALID_OBJECT;
79 }
80
81 ret = hdf->devMgrSvcIf->LoadDevice(hdf->devMgrSvcIf, serviceName);
82 if (ret == HDF_SUCCESS) {
83 ADM_LOG_INFO("serviceName[%s] load success", serviceName);
84 usbDriver->pnpFlag = 1;
85 } else if (ret == HDF_ERR_DEVICE_BUSY) {
86 ADM_LOG_INFO("serviceName[%s] has been loaded", serviceName);
87 } else {
88 ADM_LOG_ERR("serviceName[%s] load fail", serviceName);
89 usbDriver->pnpFlag = 0;
90 return HDF_ERR_NOT_SUPPORT;
91 }
92
93 return HDF_SUCCESS;
94 }
95
AudioUsbDriverInit(struct AudioUsbDriver * audioUsbDriver,struct usb_interface * usbIf,const struct usb_device_id * usbDevId)96 static int32_t AudioUsbDriverInit(
97 struct AudioUsbDriver *audioUsbDriver, struct usb_interface *usbIf, const struct usb_device_id *usbDevId)
98 {
99 struct usb_device *usbDev = interface_to_usbdev(usbIf);
100 struct usb_host_interface *alts = NULL;
101 uint32_t i, ifNum, protocol;
102 struct usb_host_interface *hostIface = NULL;
103 struct usb_interface_descriptor *altsd = NULL, *inteDesc = NULL;
104 struct uac1_ac_header_descriptor *h1 = NULL;
105
106 alts = &usbIf->altsetting[USB_DEFAULT_SET];
107 inteDesc = AudioUsbGetIfaceDesc(alts);
108 ifNum = inteDesc->bInterfaceNumber;
109 hostIface = &usb_ifnum_to_if(usbDev, ifNum)->altsetting[USB_DEFAULT_SET];
110 altsd = AudioUsbGetIfaceDesc(hostIface);
111 protocol = altsd->bInterfaceProtocol;
112
113 audioUsbDriver->pnpFlag = USB_DEFAULT_VAL;
114 audioUsbDriver->usbDevId = usbDevId;
115 audioUsbDriver->usbIf = usbIf;
116 audioUsbDriver->usbId =
117 AudioUsbGetUsbId(le16_to_cpu(usbDev->descriptor.idVendor), le16_to_cpu(usbDev->descriptor.idProduct));
118 audioUsbDriver->sampleRateReadError = USB_DEFAULT_VAL;
119 audioUsbDriver->ctrlIntf = alts;
120 audioUsbDriver->setup = USB_DEFAULT_VAL;
121 audioUsbDriver->dev = usbDev;
122 audioUsbDriver->ifNum = ifNum;
123 init_waitqueue_head(&audioUsbDriver->shutdownWait);
124
125 spin_lock_init(&audioUsbDriver->lock);
126
127 atomic_set(&audioUsbDriver->active, 1); /* avoid autopm during probing */
128 atomic_set(&audioUsbDriver->usageCount, USB_DEFAULT_VAL);
129 atomic_set(&audioUsbDriver->shutdown, USB_DEFAULT_VAL);
130
131 DListHeadInit(&audioUsbDriver->renderUsbFormatList);
132 DListHeadInit(&audioUsbDriver->captureUsbFormatList);
133
134 if (protocol != UAC_VERSION_1) {
135 ADM_LOG_ERR("usb version is not support");
136 return HDF_ERR_NOT_SUPPORT;
137 }
138 if (ifNum > 0) {
139 ADM_LOG_ERR("usb device is not support");
140 return HDF_ERR_NOT_SUPPORT;
141 }
142
143 h1 = AudioUsbFindCsintDesc(alts->extra, alts->extralen, NULL, UAC_HEADER);
144 if (h1 == NULL || h1->bLength < sizeof(*h1)) {
145 ADM_LOG_ERR("cannot find UAC_HEADER\n");
146 return -EINVAL;
147 }
148
149 for (i = 0; i < h1->bInCollection; i++) {
150 AudioUsbParseAudioInterface(audioUsbDriver, h1->baInterfaceNr[i]);
151 }
152 return HDF_SUCCESS;
153 }
154
LinuxAudioUsbProbe(struct usb_interface * usbIf,const struct usb_device_id * usbDevId)155 static int32_t LinuxAudioUsbProbe(struct usb_interface *usbIf, const struct usb_device_id *usbDevId)
156 {
157 int32_t ret;
158 uint32_t i;
159 ADM_LOG_INFO("entry");
160
161 (void)memset_s(&g_hdfAudioUsbDriver, sizeof(struct AudioUsbDriver), 0, sizeof(struct AudioUsbDriver));
162 ret = AudioUsbDriverInit(&g_hdfAudioUsbDriver, usbIf, usbDevId);
163 if (ret != HDF_SUCCESS) {
164 ADM_LOG_ERR("AudioUsbDriverInit is failed");
165 return HDF_FAILURE;
166 }
167
168 for (i = 0; g_hdfAudioUsbDriver.pnpFlag != 1 && i <= LOAD_AUDIO_USB_DRIVER_FREQUENCY; i++) {
169 OsalMSleep(WAIT_FOR_HDF_START_MILLISECOND);
170 if (AudioUsbDriverLoad(HDF_AUDIO_USB_PNP_SRV_NAME) == HDF_SUCCESS &&
171 AudioUsbDriverLoad(HDF_AUDIO_USB_DMA_NAME) == HDF_SUCCESS &&
172 AudioUsbDriverLoad(HDF_AUDIO_USB_CODEC_NAME) == HDF_SUCCESS) {
173 break;
174 }
175 }
176
177 ADM_LOG_INFO("success");
178 return HDF_SUCCESS;
179 }
180
LinuxAudioUsbDisconnect(struct usb_interface * usbIf)181 static void LinuxAudioUsbDisconnect(struct usb_interface *usbIf)
182 {
183 struct HdfDeviceObject *usbService = NULL;
184
185 wait_event(g_hdfAudioUsbDriver.shutdownWait, !atomic_read(&g_hdfAudioUsbDriver.usageCount));
186
187 usbService = DevSvcManagerClntGetDeviceObject(HDF_AUDIO_USB_DMA_NAME);
188 HdfDeviceObjectRelease(usbService);
189
190 usbService = DevSvcManagerClntGetDeviceObject(HDF_AUDIO_USB_CODEC_NAME);
191 HdfDeviceObjectRelease(usbService);
192
193 usbService = DevSvcManagerClntGetDeviceObject(HDF_AUDIO_USB_PNP_SRV_NAME);
194 HdfDeviceObjectRelease(usbService);
195
196 g_hdfAudioUsbDriver.pnpFlag = USB_DEFAULT_VAL; // USB_DEFAULT_VAL means disconnect
197 }
198
199 /* Element 2 to Terminating */
200 static const struct usb_device_id g_linuxAudioUsbIds[2] = {
201 {.bInterfaceClass = USB_CLASS_AUDIO,
202 .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS),
203 .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL},
204 };
205 MODULE_DEVICE_TABLE(usb, g_linuxAudioUsbIds);
206
207 static struct usb_driver g_linuxAudioUsbDriver = {
208 .name = "hdf-audio-usb",
209 .probe = LinuxAudioUsbProbe,
210 .disconnect = LinuxAudioUsbDisconnect,
211 .id_table = g_linuxAudioUsbIds,
212 .supports_autosuspend = 1,
213 };
214 module_usb_driver(g_linuxAudioUsbDriver);
215