usbd_audio.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. /**
  2. * @file usbd_audio.c
  3. * @brief
  4. *
  5. * Copyright (c) 2022 sakumisu
  6. *
  7. * Licensed to the Apache Software Foundation (ASF) under one or more
  8. * contributor license agreements. See the NOTICE file distributed with
  9. * this work for additional information regarding copyright ownership. The
  10. * ASF licenses this file to you under the Apache License, Version 2.0 (the
  11. * "License"); you may not use this file except in compliance with the
  12. * License. You may obtain a copy of the License at
  13. *
  14. * http://www.apache.org/licenses/LICENSE-2.0
  15. *
  16. * Unless required by applicable law or agreed to in writing, software
  17. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  18. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  19. * License for the specific language governing permissions and limitations
  20. * under the License.
  21. *
  22. */
  23. #include "usbd_core.h"
  24. #include "usbd_audio.h"
  25. #if CONFIG_USBDEV_AUDIO_VERSION < 0x0200
  26. struct usbd_audio_volume_info {
  27. uint16_t vol_min;
  28. uint16_t vol_max;
  29. uint16_t vol_res;
  30. uint16_t vol_current;
  31. };
  32. struct usbd_audio_attribute_control {
  33. struct usbd_audio_volume_info volume[CONFIG_USBDEV_AUDIO_MAX_CHANNEL];
  34. uint8_t mute[CONFIG_USBDEV_AUDIO_MAX_CHANNEL];
  35. uint8_t automatic_gain[CONFIG_USBDEV_AUDIO_MAX_CHANNEL];
  36. };
  37. #else
  38. struct audio_v2_control_range2_param_block_default {
  39. uint16_t wNumSubRanges;
  40. struct
  41. {
  42. uint16_t wMin;
  43. uint16_t wMax;
  44. uint16_t wRes;
  45. } subrange[CONFIG_USBDEV_AUDIO_MAX_CHANNEL];
  46. } __PACKED;
  47. struct usbd_audio_attribute_control {
  48. uint32_t volume_bCUR;
  49. uint32_t mute_bCUR;
  50. struct audio_v2_control_range2_param_block_default volume;
  51. uint8_t mute[CONFIG_USBDEV_AUDIO_MAX_CHANNEL];
  52. uint32_t sampling_freq[CONFIG_USBDEV_AUDIO_MAX_CHANNEL];
  53. };
  54. #endif
  55. struct audio_entity_info {
  56. usb_slist_t list;
  57. uint8_t bDescriptorSubtype;
  58. uint8_t bEntityId;
  59. void *priv;
  60. };
  61. static usb_slist_t usbd_audio_entity_info_head = USB_SLIST_OBJECT_INIT(usbd_audio_entity_info_head);
  62. const uint8_t default_sampling_freq_table[] = {
  63. AUDIO_SAMPLE_FREQ_NUM(5),
  64. AUDIO_SAMPLE_FREQ_4B(8000),
  65. AUDIO_SAMPLE_FREQ_4B(8000),
  66. AUDIO_SAMPLE_FREQ_4B(0x00),
  67. AUDIO_SAMPLE_FREQ_4B(16000),
  68. AUDIO_SAMPLE_FREQ_4B(16000),
  69. AUDIO_SAMPLE_FREQ_4B(0x00),
  70. AUDIO_SAMPLE_FREQ_4B(32000),
  71. AUDIO_SAMPLE_FREQ_4B(32000),
  72. AUDIO_SAMPLE_FREQ_4B(0x00),
  73. AUDIO_SAMPLE_FREQ_4B(44100),
  74. AUDIO_SAMPLE_FREQ_4B(44100),
  75. AUDIO_SAMPLE_FREQ_4B(0x00),
  76. AUDIO_SAMPLE_FREQ_4B(48000),
  77. AUDIO_SAMPLE_FREQ_4B(48000),
  78. AUDIO_SAMPLE_FREQ_4B(0x00),
  79. // AUDIO_SAMPLE_FREQ_4B(88200),
  80. // AUDIO_SAMPLE_FREQ_4B(88200),
  81. // AUDIO_SAMPLE_FREQ_4B(0x00),
  82. // AUDIO_SAMPLE_FREQ_4B(96000),
  83. // AUDIO_SAMPLE_FREQ_4B(96000),
  84. // AUDIO_SAMPLE_FREQ_4B(0x00),
  85. // AUDIO_SAMPLE_FREQ_4B(192000),
  86. // AUDIO_SAMPLE_FREQ_4B(192000),
  87. // AUDIO_SAMPLE_FREQ_4B(0x00),
  88. };
  89. #if CONFIG_USBDEV_AUDIO_VERSION < 0x0200
  90. static int audio_custom_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
  91. {
  92. uint8_t control_selector;
  93. uint32_t sampling_freq = 0;
  94. uint8_t pitch_enable;
  95. uint8_t ep;
  96. if ((setup->bmRequestType & USB_REQUEST_RECIPIENT_MASK) == USB_REQUEST_RECIPIENT_ENDPOINT) {
  97. control_selector = HI_BYTE(setup->wValue);
  98. ep = LO_BYTE(setup->wIndex);
  99. switch (setup->bRequest) {
  100. case AUDIO_REQUEST_SET_CUR:
  101. switch (control_selector) {
  102. case AUDIO_EP_CONTROL_SAMPLING_FEQ:
  103. memcpy((uint8_t *)&sampling_freq, *data, *len);
  104. USB_LOG_DBG("Set ep:%02x %d Hz\r\n", ep, (int)sampling_freq);
  105. usbd_audio_set_sampling_freq(0, ep, sampling_freq);
  106. break;
  107. case AUDIO_EP_CONTROL_PITCH:
  108. pitch_enable = (*data)[0];
  109. usbd_audio_set_pitch(ep, pitch_enable);
  110. break;
  111. default:
  112. USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector);
  113. return -1;
  114. }
  115. break;
  116. case AUDIO_REQUEST_GET_CUR:
  117. sampling_freq = 16000;
  118. memcpy(*data, &sampling_freq, 4);
  119. *len = 4;
  120. break;
  121. default:
  122. USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest);
  123. return -1;
  124. }
  125. } else {
  126. return -1;
  127. }
  128. return 0;
  129. }
  130. #endif
  131. static int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
  132. {
  133. USB_LOG_DBG("AUDIO Class request: "
  134. "bRequest 0x%02x\r\n",
  135. setup->bRequest);
  136. struct audio_entity_info *current_entity_info = NULL;
  137. struct usbd_audio_attribute_control *current_control = NULL;
  138. usb_slist_t *i;
  139. uint8_t entity_id;
  140. uint8_t control_selector;
  141. uint8_t ch;
  142. uint8_t mute;
  143. uint16_t volume;
  144. const char *mute_string[2] = { "off", "on" };
  145. entity_id = HI_BYTE(setup->wIndex);
  146. control_selector = HI_BYTE(setup->wValue);
  147. ch = LO_BYTE(setup->wValue);
  148. ARG_UNUSED(mute_string);
  149. if (ch > (CONFIG_USBDEV_AUDIO_MAX_CHANNEL - 1)) {
  150. return -2;
  151. }
  152. usb_slist_for_each(i, &usbd_audio_entity_info_head)
  153. {
  154. struct audio_entity_info *tmp_entity_info = usb_slist_entry(i, struct audio_entity_info, list);
  155. if (tmp_entity_info->bEntityId == entity_id) {
  156. current_entity_info = tmp_entity_info;
  157. break;
  158. }
  159. }
  160. if (current_entity_info == NULL) {
  161. return -2;
  162. }
  163. current_control = (struct usbd_audio_attribute_control *)current_entity_info->priv;
  164. if (current_entity_info->bDescriptorSubtype == AUDIO_CONTROL_FEATURE_UNIT) {
  165. #if CONFIG_USBDEV_AUDIO_VERSION < 0x0200
  166. float volume2db = 0.0;
  167. switch (control_selector) {
  168. case AUDIO_FU_CONTROL_MUTE:
  169. switch (setup->bRequest) {
  170. case AUDIO_REQUEST_SET_CUR:
  171. mute = (*data)[0];
  172. current_control->mute[ch] = mute;
  173. USB_LOG_DBG("Set UnitId:%d ch[%d] mute %s\r\n", entity_id, ch, mute_string[mute]);
  174. usbd_audio_set_mute(entity_id, ch, mute);
  175. break;
  176. case AUDIO_REQUEST_GET_CUR:
  177. (*data)[0] = current_control->mute[ch];
  178. break;
  179. default:
  180. USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest);
  181. return -1;
  182. }
  183. break;
  184. case AUDIO_FU_CONTROL_VOLUME:
  185. switch (setup->bRequest) {
  186. case AUDIO_REQUEST_SET_CUR:
  187. volume = (((uint16_t)(*data)[1] << 8) | ((uint16_t)(*data)[0]));
  188. current_control->volume[ch].vol_current = volume;
  189. if (volume < 0x8000) {
  190. volume2db = 0.00390625 * volume;
  191. } else if (volume > 0x8000) {
  192. volume2db = -0.00390625 * (0xffff - volume + 1);
  193. }
  194. USB_LOG_DBG("Set UnitId:%d ch[%d] %0.4f dB\r\n", entity_id, ch, volume2db);
  195. usbd_audio_set_volume(entity_id, ch, volume2db);
  196. break;
  197. case AUDIO_REQUEST_GET_CUR:
  198. memcpy(*data, &current_control->volume[ch].vol_current, 2);
  199. *len = 2;
  200. break;
  201. case AUDIO_REQUEST_GET_MIN:
  202. memcpy(*data, &current_control->volume[ch].vol_min, 2);
  203. *len = 2;
  204. break;
  205. case AUDIO_REQUEST_GET_MAX:
  206. memcpy(*data, &current_control->volume[ch].vol_max, 2);
  207. *len = 2;
  208. break;
  209. case AUDIO_REQUEST_GET_RES:
  210. memcpy(*data, &current_control->volume[ch].vol_res, 2);
  211. *len = 2;
  212. break;
  213. case AUDIO_REQUEST_SET_RES:
  214. memcpy(&current_control->volume[ch].vol_res, *data, 2);
  215. *len = 2;
  216. break;
  217. default:
  218. USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest);
  219. return -1;
  220. }
  221. break;
  222. default:
  223. USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector);
  224. return -1;
  225. }
  226. #else
  227. switch (setup->bRequest) {
  228. case AUDIO_REQUEST_CUR:
  229. switch (control_selector) {
  230. case AUDIO_FU_CONTROL_MUTE:
  231. if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
  232. (*data)[0] = current_control->mute_bCUR;
  233. *len = 1;
  234. } else {
  235. mute = (*data)[0];
  236. USB_LOG_DBG("Set UnitId:%d ch[%d] mute %s\r\n", entity_id, ch, mute_string[mute]);
  237. usbd_audio_set_mute(entity_id, ch, mute);
  238. }
  239. break;
  240. case AUDIO_FU_CONTROL_VOLUME:
  241. if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
  242. (*data)[0] = current_control->volume_bCUR & 0XFF;
  243. (*data)[1] = (current_control->volume_bCUR >> 8) & 0xff;
  244. *len = 2;
  245. } else {
  246. volume = (((uint16_t)(*data)[1] << 8) | ((uint16_t)(*data)[0]));
  247. current_control->volume_bCUR = volume;
  248. USB_LOG_DBG("Set UnitId:%d ch[%d] %d dB\r\n", entity_id, ch, volume);
  249. usbd_audio_set_volume(entity_id, ch, volume);
  250. }
  251. break;
  252. default:
  253. USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector);
  254. return -1;
  255. }
  256. break;
  257. case AUDIO_REQUEST_RANGE:
  258. switch (control_selector) {
  259. case AUDIO_FU_CONTROL_VOLUME:
  260. if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
  261. *((uint16_t *)(*data + 0)) = current_control->volume.wNumSubRanges;
  262. *((uint16_t *)(*data + 2)) = current_control->volume.subrange[ch].wMin;
  263. *((uint16_t *)(*data + 4)) = current_control->volume.subrange[ch].wMax;
  264. *((uint16_t *)(*data + 6)) = current_control->volume.subrange[ch].wRes;
  265. *len = 8;
  266. } else {
  267. }
  268. break;
  269. default:
  270. USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector);
  271. return -1;
  272. }
  273. break;
  274. default:
  275. USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest);
  276. return -1;
  277. }
  278. #endif
  279. }
  280. #if CONFIG_USBDEV_AUDIO_VERSION >= 0x0200
  281. else if (current_entity_info->bDescriptorSubtype == AUDIO_CONTROL_CLOCK_SOURCE) {
  282. switch (setup->bRequest) {
  283. case AUDIO_REQUEST_CUR:
  284. switch (control_selector) {
  285. case AUDIO_CS_CONTROL_SAM_FREQ:
  286. if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
  287. uint32_t current_sampling_freq = current_control->sampling_freq[ch];
  288. memcpy(*data, &current_sampling_freq, sizeof(uint32_t));
  289. *len = 4;
  290. } else {
  291. uint32_t sampling_freq;
  292. memcpy(&sampling_freq, *data, setup->wLength);
  293. current_control->sampling_freq[ch] = sampling_freq;
  294. USB_LOG_DBG("Set ClockId:%d ch[%d] %d Hz\r\n", entity_id, ch, (int)sampling_freq);
  295. usbd_audio_set_sampling_freq(entity_id, ch, sampling_freq);
  296. }
  297. break;
  298. case AUDIO_CS_CONTROL_CLOCK_VALID:
  299. if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
  300. (*data)[0] = 1;
  301. *len = 1;
  302. } else {
  303. }
  304. break;
  305. default:
  306. USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector);
  307. return -1;
  308. }
  309. break;
  310. case AUDIO_REQUEST_RANGE:
  311. switch (control_selector) {
  312. case AUDIO_CS_CONTROL_SAM_FREQ:
  313. if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
  314. uint8_t *sampling_freq_table = NULL;
  315. uint16_t num;
  316. usbd_audio_get_sampling_freq_table(entity_id, &sampling_freq_table);
  317. num = (uint16_t)((uint16_t)(sampling_freq_table[1] << 8) | ((uint16_t)sampling_freq_table[0]));
  318. *data = sampling_freq_table;
  319. *len = (12 * num + 2);
  320. } else {
  321. }
  322. break;
  323. default:
  324. USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector);
  325. return -1;
  326. }
  327. break;
  328. default:
  329. USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest);
  330. return -1;
  331. }
  332. }
  333. #endif
  334. else {
  335. return -1;
  336. }
  337. return 0;
  338. }
  339. static void audio_notify_handler(uint8_t event, void *arg)
  340. {
  341. switch (event) {
  342. case USBD_EVENT_RESET:
  343. break;
  344. case USBD_EVENT_SOF:
  345. usbd_audio_sof_callback();
  346. break;
  347. case USBD_EVENT_SET_INTERFACE: {
  348. struct usb_interface_descriptor *intf = (struct usb_interface_descriptor *)arg;
  349. if (intf->bAlternateSetting == 1) {
  350. usbd_audio_open(intf->bInterfaceNumber);
  351. } else {
  352. usbd_audio_close(intf->bInterfaceNumber);
  353. }
  354. }
  355. break;
  356. default:
  357. break;
  358. }
  359. }
  360. void usbd_audio_add_interface(usbd_class_t *devclass, usbd_interface_t *intf)
  361. {
  362. static usbd_class_t *last_class = NULL;
  363. if (last_class != devclass) {
  364. last_class = devclass;
  365. usbd_class_register(devclass);
  366. }
  367. intf->class_handler = audio_class_request_handler;
  368. #if CONFIG_USBDEV_AUDIO_VERSION < 0x0200
  369. intf->custom_handler = audio_custom_request_handler;
  370. #else
  371. intf->custom_handler = NULL;
  372. #endif
  373. intf->vendor_handler = NULL;
  374. intf->notify_handler = audio_notify_handler;
  375. usbd_class_add_interface(devclass, intf);
  376. }
  377. void usbd_audio_add_entity(uint8_t entity_id, uint16_t bDescriptorSubtype)
  378. {
  379. struct audio_entity_info *entity_info = usb_malloc(sizeof(struct audio_entity_info));
  380. memset(entity_info, 0, sizeof(struct audio_entity_info));
  381. entity_info->bEntityId = entity_id;
  382. entity_info->bDescriptorSubtype = bDescriptorSubtype;
  383. if (bDescriptorSubtype == AUDIO_CONTROL_FEATURE_UNIT) {
  384. #if CONFIG_USBDEV_AUDIO_VERSION < 0x0200
  385. struct usbd_audio_attribute_control *control = usb_malloc(sizeof(struct usbd_audio_attribute_control));
  386. memset(control, 0, sizeof(struct usbd_audio_attribute_control));
  387. for (uint8_t ch = 0; ch < CONFIG_USBDEV_AUDIO_MAX_CHANNEL; ch++) {
  388. control->volume[ch].vol_min = 0xdb00;
  389. control->volume[ch].vol_max = 0x0000;
  390. control->volume[ch].vol_res = 0x0100;
  391. control->volume[ch].vol_current = 0xf600;
  392. control->mute[ch] = 0;
  393. control->automatic_gain[ch] = 0;
  394. }
  395. #else
  396. struct usbd_audio_attribute_control *control = usb_malloc(sizeof(struct usbd_audio_attribute_control));
  397. memset(control, 0, sizeof(struct usbd_audio_attribute_control));
  398. for (uint8_t ch = 0; ch < CONFIG_USBDEV_AUDIO_MAX_CHANNEL; ch++) {
  399. control->volume.wNumSubRanges = 1;
  400. control->volume.subrange[ch].wMin = 0;
  401. control->volume.subrange[ch].wMax = 100;
  402. control->volume.subrange[ch].wRes = 1;
  403. control->mute[ch] = 0;
  404. control->sampling_freq[ch] = 16000;
  405. control->volume_bCUR = 50;
  406. control->mute_bCUR = 0;
  407. }
  408. #endif
  409. entity_info->priv = control;
  410. } else if (bDescriptorSubtype == AUDIO_CONTROL_CLOCK_SOURCE) {
  411. }
  412. usb_slist_add_tail(&usbd_audio_entity_info_head, &entity_info->list);
  413. }
  414. __WEAK void usbd_audio_set_volume(uint8_t entity_id, uint8_t ch, float dB)
  415. {
  416. }
  417. __WEAK void usbd_audio_set_mute(uint8_t entity_id, uint8_t ch, uint8_t enable)
  418. {
  419. }
  420. __WEAK void usbd_audio_set_sampling_freq(uint8_t entity_id, uint8_t ep_ch, uint32_t sampling_freq)
  421. {
  422. }
  423. __WEAK void usbd_audio_get_sampling_freq_table(uint8_t entity_id, uint8_t **sampling_freq_table)
  424. {
  425. *sampling_freq_table = (uint8_t *)default_sampling_freq_table;
  426. }
  427. __WEAK void usbd_audio_set_pitch(uint8_t ep, bool enable)
  428. {
  429. }
  430. __WEAK void usbd_audio_sof_callback(void)
  431. {
  432. }