PchHdaLib.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  1. /** @file
  2. PCH HD Audio Library implementation.
  3. Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <Uefi/UefiBaseType.h>
  7. #include <Library/DebugLib.h>
  8. #include <Library/MemoryAllocationLib.h>
  9. #include <Library/BaseMemoryLib.h>
  10. #include <Library/PcdLib.h>
  11. #include <Private/Library/PchHdaLib.h>
  12. #include <Library/PchInfoLib.h>
  13. /**
  14. Returns pointer to Endpoint ENDPOINT_DESCRIPTOR structure.
  15. @param[in] *NhltTable Endpoint for which Format address is retrieved
  16. @param[in] FormatIndex Index of Format to be retrieved
  17. @retval Pointer to ENDPOINT_DESCRIPTOR structure with given index
  18. **/
  19. ENDPOINT_DESCRIPTOR *
  20. GetNhltEndpoint (
  21. IN CONST NHLT_ACPI_TABLE *NhltTable,
  22. IN CONST UINT8 EndpointIndex
  23. )
  24. {
  25. UINT8 i;
  26. ENDPOINT_DESCRIPTOR *Endpoint;
  27. Endpoint = (ENDPOINT_DESCRIPTOR*) (NhltTable->EndpointDescriptors);
  28. if (EndpointIndex > NhltTable->EndpointCount) {
  29. return NULL;
  30. }
  31. for (i = 0; i < EndpointIndex; i++) {
  32. Endpoint = (ENDPOINT_DESCRIPTOR*) ((UINT8*) (Endpoint) + Endpoint->EndpointDescriptorLength);
  33. }
  34. return Endpoint;
  35. }
  36. /**
  37. Returns pointer to Endpoint Specific Configuration SPECIFIC_CONFIG structure.
  38. @param[in] *Endpoint Endpoint for which config address is retrieved
  39. @retval Pointer to SPECIFIC_CONFIG structure with endpoint's capabilities
  40. **/
  41. SPECIFIC_CONFIG *
  42. GetNhltEndpointDeviceCapabilities (
  43. IN CONST ENDPOINT_DESCRIPTOR *Endpoint
  44. )
  45. {
  46. return (SPECIFIC_CONFIG*) (&Endpoint->EndpointConfig);
  47. }
  48. /**
  49. Returns pointer to all Formats Configuration FORMATS_CONFIG structure.
  50. @param[in] *Endpoint Endpoint for which Formats address is retrieved
  51. @retval Pointer to FORMATS_CONFIG structure
  52. **/
  53. FORMATS_CONFIG *
  54. GetNhltEndpointFormatsConfig (
  55. IN CONST ENDPOINT_DESCRIPTOR *Endpoint
  56. )
  57. {
  58. FORMATS_CONFIG *FormatsConfig;
  59. FormatsConfig = (FORMATS_CONFIG*) ((UINT8*) (&Endpoint->EndpointConfig)
  60. + sizeof (Endpoint->EndpointConfig.CapabilitiesSize)
  61. + Endpoint->EndpointConfig.CapabilitiesSize);
  62. return FormatsConfig;
  63. }
  64. /**
  65. Returns pointer to Format Configuration FORMAT_CONFIG structure.
  66. @param[in] *Endpoint Endpoint for which Format address is retrieved
  67. @param[in] FormatIndex Index of Format to be retrieved
  68. @retval Pointer to FORMAT_CONFIG structure with given index
  69. **/
  70. FORMAT_CONFIG *
  71. GetNhltEndpointFormat (
  72. IN CONST ENDPOINT_DESCRIPTOR *Endpoint,
  73. IN CONST UINT8 FormatIndex
  74. )
  75. {
  76. UINT8 i;
  77. UINT32 Length;
  78. FORMATS_CONFIG *FormatsConfig;
  79. FORMAT_CONFIG *Format;
  80. Length = 0;
  81. FormatsConfig = GetNhltEndpointFormatsConfig (Endpoint);
  82. Format = FormatsConfig->FormatsConfiguration;
  83. if (FormatIndex > FormatsConfig->FormatsCount) {
  84. return NULL;
  85. }
  86. for (i = 0; i < FormatIndex; i++) {
  87. Length = sizeof (Format->Format) + Format->FormatConfiguration.CapabilitiesSize
  88. + sizeof (Format->FormatConfiguration.CapabilitiesSize);
  89. Format = (FORMAT_CONFIG*) ((UINT8*) (Format) + Length);
  90. }
  91. return Format;
  92. }
  93. /**
  94. Returns pointer to all Device Information DEVICES_INFO structure.
  95. @param[in] *Endpoint Endpoint for which DevicesInfo address is retrieved
  96. @retval Pointer to DEVICES_INFO structure
  97. **/
  98. DEVICES_INFO *
  99. GetNhltEndpointDevicesInfo (
  100. IN CONST ENDPOINT_DESCRIPTOR *Endpoint
  101. )
  102. {
  103. DEVICES_INFO *DevicesInfo;
  104. FORMATS_CONFIG *FormatsConfig;
  105. FORMAT_CONFIG *Format;
  106. FormatsConfig = GetNhltEndpointFormatsConfig (Endpoint);
  107. Format = GetNhltEndpointFormat (Endpoint, FormatsConfig->FormatsCount);
  108. DevicesInfo = (DEVICES_INFO*) ((UINT8*) Format);
  109. return DevicesInfo;
  110. }
  111. /**
  112. Returns pointer to Device Information DEVICES_INFO structure.
  113. @param[in] *Endpoint Endpoint for which Device Info address is retrieved
  114. @param[in] DeviceInfoIndex Index of Device Info to be retrieved
  115. @retval Pointer to DEVICE_INFO structure with given index
  116. **/
  117. DEVICE_INFO *
  118. GetNhltEndpointDeviceInfo (
  119. IN CONST ENDPOINT_DESCRIPTOR *Endpoint,
  120. IN CONST UINT8 DeviceInfoIndex
  121. )
  122. {
  123. DEVICES_INFO *DevicesInfo;
  124. DEVICE_INFO *DeviceInfo;
  125. DevicesInfo = GetNhltEndpointDevicesInfo (Endpoint);
  126. DeviceInfo = DevicesInfo->DeviceInformation;
  127. if (DevicesInfo == NULL) {
  128. return NULL;
  129. }
  130. if (DeviceInfoIndex > DevicesInfo->DeviceInfoCount) {
  131. return NULL;
  132. }
  133. DeviceInfo = (DEVICE_INFO*) ((UINT8*) (DeviceInfo) + sizeof (*DeviceInfo) * DeviceInfoIndex);
  134. return DeviceInfo;
  135. }
  136. /**
  137. Returns pointer to OED Configuration SPECIFIC_CONFIG structure.
  138. @param[in] *NhltTable NHLT table for which OED address is retrieved
  139. @retval Pointer to SPECIFIC_CONFIG structure with NHLT capabilities
  140. **/
  141. SPECIFIC_CONFIG *
  142. GetNhltOedConfig (
  143. IN CONST NHLT_ACPI_TABLE *NhltTable
  144. )
  145. {
  146. ENDPOINT_DESCRIPTOR *Endpoint;
  147. SPECIFIC_CONFIG *OedConfig;
  148. Endpoint = GetNhltEndpoint (NhltTable, (NhltTable->EndpointCount));
  149. OedConfig = (SPECIFIC_CONFIG*) ((UINT8*) (Endpoint));
  150. return OedConfig;
  151. }
  152. /**
  153. Prints Format configuration.
  154. @param[in] *Format Format to be printed
  155. @retval None
  156. **/
  157. VOID
  158. NhltFormatDump (
  159. IN CONST FORMAT_CONFIG *Format
  160. )
  161. {
  162. UINT32 i;
  163. DEBUG ((DEBUG_INFO, "------------------------------- FORMAT -------------------------------\n"));
  164. DEBUG ((DEBUG_INFO, " Format->Format.Format.wFormatTag = 0x%x\n", Format->Format.Format.wFormatTag));
  165. DEBUG ((DEBUG_INFO, " Format->Format.Format.nChannels = %d\n", Format->Format.Format.nChannels));
  166. DEBUG ((DEBUG_INFO, " Format->Format.Format.nSamplesPerSec = %d\n", Format->Format.Format.nSamplesPerSec));
  167. DEBUG ((DEBUG_INFO, " Format->Format.Format.nAvgBytesPerSec = %d\n", Format->Format.Format.nAvgBytesPerSec));
  168. DEBUG ((DEBUG_INFO, " Format->Format.Format.nBlockAlign = %d\n", Format->Format.Format.nBlockAlign));
  169. DEBUG ((DEBUG_INFO, " Format->Format.Format.wBitsPerSample = %d\n", Format->Format.Format.wBitsPerSample));
  170. DEBUG ((DEBUG_INFO, " Format->Format.Format.cbSize = %d\n", Format->Format.Format.cbSize));
  171. DEBUG ((DEBUG_INFO, " Format->Format.Samples = %d\n", Format->Format.Samples));
  172. DEBUG ((DEBUG_INFO, " Format->Format.dwChannelMask = 0x%x\n", Format->Format.dwChannelMask));
  173. DEBUG ((DEBUG_INFO, " Format->Format.SubFormat = %g\n", Format->Format.SubFormat));
  174. DEBUG ((DEBUG_INFO, " Format->FormatConfiguration.CapabilitiesSize = %d B\n", Format->FormatConfiguration.CapabilitiesSize));
  175. DEBUG ((DEBUG_VERBOSE, " Format->FormatConfiguration.Capabilities:"));
  176. for (i = 0; i < ( Format->FormatConfiguration.CapabilitiesSize ) ; i++) {
  177. if (i % 16 == 0) {
  178. DEBUG ((DEBUG_VERBOSE, "\n"));
  179. }
  180. DEBUG ((DEBUG_VERBOSE, "0x%02x, ", Format->FormatConfiguration.Capabilities[i]));
  181. }
  182. DEBUG ((DEBUG_VERBOSE, "\n"));
  183. }
  184. /**
  185. Prints Device Information.
  186. @param[in] *DeviceInfo DeviceInfo to be printed
  187. @retval None
  188. **/
  189. VOID
  190. NhltDeviceInfoDump (
  191. IN CONST DEVICE_INFO *DeviceInfo
  192. )
  193. {
  194. DEBUG ((DEBUG_INFO, "----------------------------- DEVICE INFO ----------------------------\n"));
  195. DEBUG ((DEBUG_INFO, " DeviceInfo->DeviceId = %a\n", DeviceInfo->DeviceId));
  196. DEBUG ((DEBUG_INFO, " DeviceInfo->DeviceInstanceId = 0x%x\n", DeviceInfo->DeviceInstanceId));
  197. DEBUG ((DEBUG_INFO, " DeviceInfo->DevicePortId = 0x%x\n", DeviceInfo->DevicePortId));
  198. }
  199. /**
  200. Prints Endpoint configuration.
  201. @param[in] *Endpoint Endpoint to be printed
  202. @retval None
  203. **/
  204. VOID
  205. NhltEndpointDump (
  206. IN CONST ENDPOINT_DESCRIPTOR *Endpoint
  207. )
  208. {
  209. UINT8 i;
  210. FORMATS_CONFIG *FormatsConfigs;
  211. FORMAT_CONFIG *Format;
  212. DEVICES_INFO *DevicesInfo;
  213. DEVICE_INFO *DeviceInfo;
  214. DEBUG ((DEBUG_INFO, "------------------------------ ENDPOINT ------------------------------\n"));
  215. DEBUG ((DEBUG_INFO, " Endpoint->DeviceDescriptorLength = %d B\n", Endpoint->EndpointDescriptorLength));
  216. DEBUG ((DEBUG_INFO, " Endpoint->LinkType = 0x%x\n", Endpoint->LinkType));
  217. DEBUG ((DEBUG_INFO, " Endpoint->InstanceId = 0x%x\n", Endpoint->InstanceId));
  218. DEBUG ((DEBUG_INFO, " Endpoint->HwVendorId = 0x%x\n", Endpoint->HwVendorId));
  219. DEBUG ((DEBUG_INFO, " Endpoint->HwDeviceId = 0x%x\n", Endpoint->HwDeviceId));
  220. DEBUG ((DEBUG_INFO, " Endpoint->HwRevisionId = 0x%x\n", Endpoint->HwRevisionId));
  221. DEBUG ((DEBUG_INFO, " Endpoint->HwSubsystemId = 0x%x\n", Endpoint->HwSubsystemId));
  222. DEBUG ((DEBUG_INFO, " Endpoint->DeviceType = 0x%x\n", Endpoint->DeviceType));
  223. DEBUG ((DEBUG_INFO, " Endpoint->Direction = 0x%x\n", Endpoint->Direction));
  224. DEBUG ((DEBUG_INFO, " Endpoint->VirtualBusId = 0x%x\n", Endpoint->VirtualBusId));
  225. DEBUG ((DEBUG_INFO, " Endpoint->EndpointConfig.CapabilitiesSize = %d B\n", Endpoint->EndpointConfig.CapabilitiesSize));
  226. DEBUG ((DEBUG_VERBOSE, " Endpoint->EndpointConfig.Capabilities:"));
  227. for (i = 0; i < (Endpoint->EndpointConfig.CapabilitiesSize ) ; i++) {
  228. if (i % 16 == 0) DEBUG ((DEBUG_VERBOSE, "\n"));
  229. DEBUG ((DEBUG_VERBOSE, "0x%02x, ", Endpoint->EndpointConfig.Capabilities[i]));
  230. }
  231. FormatsConfigs = GetNhltEndpointFormatsConfig (Endpoint);
  232. DEBUG ((DEBUG_INFO, "\n"));
  233. DEBUG ((DEBUG_INFO, " Endpoint->FormatsConfig.FormatsCount = %d\n", FormatsConfigs->FormatsCount));
  234. for (i = 0; i < FormatsConfigs->FormatsCount; i++) {
  235. Format = GetNhltEndpointFormat (Endpoint, i);
  236. if (Format != NULL) {
  237. NhltFormatDump (Format);
  238. }
  239. }
  240. DevicesInfo = GetNhltEndpointDevicesInfo (Endpoint);
  241. if (DevicesInfo != NULL) {
  242. DEBUG ((DEBUG_INFO, "\n"));
  243. DEBUG ((DEBUG_INFO, " Endpoint->DevicesInfo.DeviceInfoCount = %d\n", DevicesInfo->DeviceInfoCount));
  244. for (i = 0; i < DevicesInfo->DeviceInfoCount; i++) {
  245. DeviceInfo = GetNhltEndpointDeviceInfo (Endpoint, i);
  246. if (DeviceInfo != NULL) {
  247. NhltDeviceInfoDump (DeviceInfo);
  248. }
  249. }
  250. }
  251. DEBUG ((DEBUG_VERBOSE, "\n"));
  252. }
  253. /**
  254. Prints OED (Offload Engine Driver) configuration.
  255. @param[in] *OedConfig OED to be printed
  256. @retval None
  257. **/
  258. VOID
  259. NhltOedConfigDump (
  260. IN CONST SPECIFIC_CONFIG *OedConfig
  261. )
  262. {
  263. UINT8 i;
  264. DEBUG ((DEBUG_INFO, "-------------------------- OED CONFIGURATION -------------------------\n"));
  265. DEBUG ((DEBUG_INFO, " OedConfig->CapabilitiesSize = %d B\n", OedConfig->CapabilitiesSize));
  266. DEBUG ((DEBUG_VERBOSE, " OedConfig->Capabilities:"));
  267. for (i = 0; i < (OedConfig->CapabilitiesSize) ; i++) {
  268. if (i % 16 == 0) DEBUG ((DEBUG_VERBOSE, "\n"));
  269. DEBUG ((DEBUG_VERBOSE, "0x%02x, ", OedConfig->Capabilities[i]));
  270. }
  271. DEBUG ((DEBUG_VERBOSE, "\n"));
  272. }
  273. /**
  274. Prints NHLT (Non HDA-Link Table) to be exposed via ACPI (aka. OED (Offload Engine Driver) Configuration Table).
  275. @param[in] *NhltTable The NHLT table to print
  276. @retval None
  277. **/
  278. VOID
  279. NhltAcpiTableDump (
  280. IN NHLT_ACPI_TABLE *NhltTable
  281. )
  282. {
  283. DEBUG_CODE_BEGIN ();
  284. UINT8 i;
  285. DEBUG ((DEBUG_INFO, "\n"));
  286. DEBUG ((DEBUG_INFO, "--- NHLT ACPI Table Dump [OED (Offload Engine Driver) Configuration] ---\n"));
  287. DEBUG ((DEBUG_INFO, "sizeof NHLT_ACPI_TABLE = %d B\n", sizeof (NHLT_ACPI_TABLE)));
  288. DEBUG ((DEBUG_INFO, "sizeof EFI_ACPI_DESCRIPTION_HEADER = %d B\n", sizeof (EFI_ACPI_DESCRIPTION_HEADER)));
  289. DEBUG ((DEBUG_INFO, "sizeof ENDPOINT_DESCRIPTOR = %d B\n", sizeof (ENDPOINT_DESCRIPTOR)));
  290. DEBUG ((DEBUG_INFO, "sizeof SPECIFIC_CONFIG = %d B\n", sizeof (SPECIFIC_CONFIG)));
  291. DEBUG ((DEBUG_INFO, "sizeof FORMATS_CONFIG = %d B\n", sizeof (FORMATS_CONFIG)));
  292. DEBUG ((DEBUG_INFO, "sizeof FORMAT_CONFIG = %d B\n", sizeof (FORMAT_CONFIG)));
  293. DEBUG ((DEBUG_INFO, "sizeof WAVEFORMATEXTENSIBLE = %d B\n", sizeof (WAVEFORMATEXTENSIBLE)));
  294. DEBUG ((DEBUG_INFO, "sizeof DEVICES_INFO = %d B\n", sizeof (DEVICES_INFO)));
  295. DEBUG ((DEBUG_INFO, "sizeof DEVICE_INFO = %d B\n", sizeof (DEVICE_INFO)));
  296. DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.Signature = 0x%08x\n", NhltTable->Header.Signature));
  297. DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.Length = 0x%08x\n", NhltTable->Header.Length));
  298. DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.Revision = 0x%02x\n", NhltTable->Header.Revision));
  299. DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.Checksum = 0x%02x\n", NhltTable->Header.Checksum));
  300. DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.OemId = %a\n", NhltTable->Header.OemId));
  301. DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.OemTableId = 0x%lx\n", NhltTable->Header.OemTableId));
  302. DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.OemRevision = 0x%08x\n", NhltTable->Header.OemRevision));
  303. DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.CreatorId = 0x%08x\n", NhltTable->Header.CreatorId));
  304. DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.CreatorRevision = 0x%08x\n", NhltTable->Header.CreatorRevision));
  305. DEBUG ((DEBUG_INFO, "\n"));
  306. DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE EndpointCount = %d\n", NhltTable->EndpointCount));
  307. for (i = 0; i < NhltTable->EndpointCount; i++) {
  308. NhltEndpointDump (GetNhltEndpoint (NhltTable, i));
  309. }
  310. NhltOedConfigDump (GetNhltOedConfig (NhltTable));
  311. DEBUG ((DEBUG_INFO, "----------------------------------------------------------------------\n"));
  312. DEBUG_CODE_END ();
  313. }
  314. /**
  315. Constructs FORMATS_CONFIGS structure based on given formats list.
  316. @param[in][out] *Endpoint Endpoint for which format structures are created
  317. @param[in] FormatBitmask Bitmask of formats supported for given endpoint
  318. @retval Size of created FORMATS_CONFIGS structure
  319. **/
  320. UINT32
  321. NhltFormatsConstructor (
  322. IN OUT ENDPOINT_DESCRIPTOR *Endpoint,
  323. IN CONST UINT32 FormatsBitmask
  324. )
  325. {
  326. FORMATS_CONFIG *FormatsConfig;
  327. FORMAT_CONFIG *Format;
  328. UINT8 FormatIndex;
  329. UINT32 FormatsConfigLength;
  330. DEBUG ((DEBUG_INFO, "NhltFormatsConstructor() Start, FormatsBitmask = 0x%08x\n", FormatsBitmask));
  331. FormatsConfig = NULL;
  332. FormatIndex = 0;
  333. FormatsConfigLength = 0;
  334. if (!FormatsBitmask) {
  335. DEBUG ((DEBUG_WARN, "No supported format found!\n"));
  336. return 0;
  337. }
  338. FormatsConfig = GetNhltEndpointFormatsConfig (Endpoint);
  339. FormatsConfig->FormatsCount = 0;
  340. if (FormatsBitmask & B_HDA_DMIC_2CH_48KHZ_16BIT_FORMAT) {
  341. DEBUG ((DEBUG_INFO, "Format: B_HDA_DMIC_2CH_48KHZ_16BIT_FORMAT\n"));
  342. Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
  343. if (Format != NULL) {
  344. CopyMem (&(Format->Format), &Ch2_48kHz16bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
  345. Format->FormatConfiguration.CapabilitiesSize = DmicStereo16BitFormatConfigSize;
  346. CopyMem (Format->FormatConfiguration.Capabilities, DmicStereo16BitFormatConfig, DmicStereo16BitFormatConfigSize);
  347. FormatsConfigLength += sizeof (*Format)
  348. - sizeof (Format->FormatConfiguration.Capabilities)
  349. + Format->FormatConfiguration.CapabilitiesSize;
  350. FormatsConfig->FormatsCount++;
  351. }
  352. }
  353. if (FormatsBitmask & B_HDA_DMIC_2CH_48KHZ_32BIT_FORMAT) {
  354. DEBUG ((DEBUG_INFO, "Format: B_HDA_DMIC_2CH_48KHZ_32BIT_FORMAT\n"));
  355. Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
  356. if (Format != NULL) {
  357. CopyMem (&(Format->Format), &Ch2_48kHz32bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
  358. Format->FormatConfiguration.CapabilitiesSize = DmicStereo32BitFormatConfigSize;
  359. CopyMem (Format->FormatConfiguration.Capabilities, DmicStereo32BitFormatConfig, DmicStereo32BitFormatConfigSize);
  360. FormatsConfigLength += sizeof (*Format)
  361. - sizeof (Format->FormatConfiguration.Capabilities)
  362. + Format->FormatConfiguration.CapabilitiesSize;
  363. FormatsConfig->FormatsCount++;
  364. }
  365. }
  366. if (FormatsBitmask & B_HDA_DMIC_4CH_48KHZ_16BIT_FORMAT) {
  367. DEBUG ((DEBUG_INFO, "Format: B_HDA_DMIC_4CH_48KHZ_16BIT_FORMAT\n"));
  368. Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
  369. if (Format != NULL) {
  370. CopyMem (&(Format->Format), &Ch4_48kHz16bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
  371. Format->FormatConfiguration.CapabilitiesSize = DmicQuad16BitFormatConfigSize;
  372. CopyMem (Format->FormatConfiguration.Capabilities, DmicQuad16BitFormatConfig, DmicQuad16BitFormatConfigSize);
  373. FormatsConfigLength += sizeof (*Format)
  374. - sizeof (Format->FormatConfiguration.Capabilities)
  375. + Format->FormatConfiguration.CapabilitiesSize;
  376. FormatsConfig->FormatsCount++;
  377. }
  378. }
  379. if (FormatsBitmask & B_HDA_DMIC_4CH_48KHZ_32BIT_FORMAT) {
  380. DEBUG ((DEBUG_INFO, "Format: B_HDA_DMIC_4CH_48KHZ_32BIT_FORMAT\n"));
  381. Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
  382. if (Format != NULL) {
  383. CopyMem (&(Format->Format), &Ch4_48kHz32bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
  384. Format->FormatConfiguration.CapabilitiesSize = DmicQuad32BitFormatConfigSize;
  385. CopyMem (Format->FormatConfiguration.Capabilities, DmicQuad32BitFormatConfig, DmicQuad32BitFormatConfigSize);
  386. FormatsConfigLength += sizeof (*Format)
  387. - sizeof (Format->FormatConfiguration.Capabilities)
  388. + Format->FormatConfiguration.CapabilitiesSize;
  389. FormatsConfig->FormatsCount++;
  390. }
  391. }
  392. if (FormatsBitmask & B_HDA_DMIC_1CH_48KHZ_16BIT_FORMAT) {
  393. DEBUG ((DEBUG_INFO, "Format: B_HDA_DMIC_1CH_48KHZ_16BIT_FORMAT\n"));
  394. Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
  395. if (Format != NULL) {
  396. CopyMem (&(Format->Format), &Ch1_48kHz16bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
  397. Format->FormatConfiguration.CapabilitiesSize = DmicMono16BitFormatConfigSize;
  398. CopyMem (Format->FormatConfiguration.Capabilities, DmicMono16BitFormatConfig, DmicMono16BitFormatConfigSize);
  399. FormatsConfigLength += sizeof (*Format)
  400. - sizeof (Format->FormatConfiguration.Capabilities)
  401. + Format->FormatConfiguration.CapabilitiesSize;
  402. FormatsConfig->FormatsCount++;
  403. }
  404. }
  405. if (FormatsBitmask & B_HDA_BT_NARROWBAND_FORMAT) {
  406. DEBUG ((DEBUG_INFO, "Format: B_HDA_BT_NARROWBAND_FORMAT\n"));
  407. Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
  408. if (Format != NULL) {
  409. CopyMem (&(Format->Format), &NarrowbandFormat, sizeof (WAVEFORMATEXTENSIBLE));
  410. Format->FormatConfiguration.CapabilitiesSize = BtFormatConfigSize;
  411. CopyMem (Format->FormatConfiguration.Capabilities, BtFormatConfig, BtFormatConfigSize);
  412. FormatsConfigLength += sizeof (*Format)
  413. - sizeof (Format->FormatConfiguration.Capabilities)
  414. + Format->FormatConfiguration.CapabilitiesSize;
  415. FormatsConfig->FormatsCount++;
  416. }
  417. }
  418. if (FormatsBitmask & B_HDA_BT_WIDEBAND_FORMAT) {
  419. DEBUG ((DEBUG_INFO, "Format: B_HDA_BT_WIDEBAND_FORMAT\n"));
  420. Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
  421. if (Format != NULL) {
  422. CopyMem (&(Format->Format), &WidebandFormat, sizeof (WAVEFORMATEXTENSIBLE));
  423. Format->FormatConfiguration.CapabilitiesSize = BtFormatConfigSize;
  424. CopyMem (Format->FormatConfiguration.Capabilities, BtFormatConfig, BtFormatConfigSize);
  425. FormatsConfigLength += sizeof (*Format)
  426. - sizeof (Format->FormatConfiguration.Capabilities)
  427. + Format->FormatConfiguration.CapabilitiesSize;
  428. FormatsConfig->FormatsCount++;
  429. }
  430. }
  431. if (FormatsBitmask & B_HDA_BT_A2DP_FORMAT) {
  432. DEBUG ((DEBUG_INFO, "Format: B_HDA_BT_A2DP_FORMAT\n"));
  433. Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
  434. if (Format != NULL) {
  435. CopyMem (&(Format->Format), &A2dpFormat, sizeof (WAVEFORMATEXTENSIBLE));
  436. Format->FormatConfiguration.CapabilitiesSize = BtFormatConfigSize;
  437. CopyMem (Format->FormatConfiguration.Capabilities, BtFormatConfig, BtFormatConfigSize);
  438. FormatsConfigLength += sizeof (*Format)
  439. - sizeof (Format->FormatConfiguration.Capabilities)
  440. + Format->FormatConfiguration.CapabilitiesSize;
  441. FormatsConfig->FormatsCount++;
  442. }
  443. }
  444. if (FormatsBitmask & B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT) {
  445. DEBUG ((DEBUG_INFO, "Format: B_HDA_I2S_RTK274_RENDER_4CH_48KHZ_24BIT_FORMAT\n"));
  446. Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
  447. if (Format != NULL) {
  448. CopyMem (&(Format->Format), &Ch2_48kHz24bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
  449. Format->FormatConfiguration.CapabilitiesSize = I2sRtk274Render4ch48kHz24bitFormatConfigSize;
  450. CopyMem (Format->FormatConfiguration.Capabilities, I2sRtk274Render4ch48kHz24bitFormatConfig, I2sRtk274Render4ch48kHz24bitFormatConfigSize);
  451. FormatsConfigLength += sizeof (*Format)
  452. - sizeof (Format->FormatConfiguration.Capabilities)
  453. + Format->FormatConfiguration.CapabilitiesSize;
  454. FormatsConfig->FormatsCount++;
  455. }
  456. }
  457. if (FormatsBitmask & B_HDA_I2S_RTK274_CAPTURE_4CH_48KHZ_24BIT_FORMAT) {
  458. DEBUG ((DEBUG_INFO, "Format: B_HDA_I2S_RTK274_CAPTURE_4CH_48KHZ_24BIT_FORMAT\n"));
  459. Format = GetNhltEndpointFormat (Endpoint, FormatIndex++);
  460. if (Format != NULL) {
  461. CopyMem (&(Format->Format), &Ch2_48kHz24bitFormat, sizeof (WAVEFORMATEXTENSIBLE));
  462. Format->FormatConfiguration.CapabilitiesSize = I2sRtk274Capture4ch48kHz24bitFormatConfigSize;
  463. CopyMem (Format->FormatConfiguration.Capabilities, I2sRtk274Capture4ch48kHz24bitFormatConfig, I2sRtk274Capture4ch48kHz24bitFormatConfigSize);
  464. FormatsConfigLength += sizeof (*Format)
  465. - sizeof (Format->FormatConfiguration.Capabilities)
  466. + Format->FormatConfiguration.CapabilitiesSize;
  467. FormatsConfig->FormatsCount++;
  468. }
  469. }
  470. DEBUG ((DEBUG_INFO, "NhltFormatsConstructor() End, FormatsCount = %d, FormatsConfigLength = %d B\n", FormatsConfig->FormatsCount, FormatsConfigLength));
  471. return FormatsConfigLength;
  472. }
  473. /**
  474. Constructs DEVICES_INFO structure based on given device info list.
  475. @param[in][out] *Endpoint Endpoint for which device info structures are created
  476. @param[in] DevicesBitmask Bitmask of devices supported for given endpoint
  477. @retval Size of created DEVICES_INFO structure
  478. **/
  479. UINT32
  480. NhltDevicesInfoConstructor (
  481. IN OUT ENDPOINT_DESCRIPTOR *Endpoint,
  482. IN CONST UINT32 DevicesBitmask
  483. )
  484. {
  485. DEVICES_INFO *DevicesInfo;
  486. DEVICE_INFO *DeviceInfo;
  487. UINT8 DeviceIndex;
  488. UINT32 DevicesInfoLength;
  489. DEBUG ((DEBUG_INFO, "NhltDevicesInfoConstructor() Start, DevicesBitmask = 0x%08x\n", DevicesBitmask));
  490. DevicesInfo = NULL;
  491. DeviceIndex = 0;
  492. DevicesInfoLength = 0;
  493. if (!DevicesBitmask) {
  494. return 0;
  495. }
  496. DevicesInfo = GetNhltEndpointDevicesInfo (Endpoint);
  497. if (DevicesInfo == NULL) {
  498. return 0;
  499. }
  500. DevicesInfo->DeviceInfoCount = 0;
  501. if (DevicesBitmask & B_HDA_I2S_RENDER_DEVICE_INFO) {
  502. DEBUG ((DEBUG_INFO, "DeviceInfo: B_HDA_I2S_RENDER_DEVICE_INFO\n"));
  503. DeviceInfo = GetNhltEndpointDeviceInfo (Endpoint, DeviceIndex++);
  504. if (DeviceInfo != NULL) {
  505. CopyMem (DeviceInfo, &I2sRenderDeviceInfo, sizeof (DEVICE_INFO));
  506. DevicesInfo->DeviceInfoCount++;
  507. }
  508. } else if (DevicesBitmask & B_HDA_I2S_CAPTURE_DEVICE_INFO) {
  509. DEBUG ((DEBUG_INFO, "DeviceInfo: B_HDA_I2S_CAPTURE_DEVICE_INFO\n"));
  510. DeviceInfo = GetNhltEndpointDeviceInfo (Endpoint, DeviceIndex++);
  511. if (DeviceInfo != NULL) {
  512. CopyMem (DeviceInfo, &I2sCaptureDeviceInfo, sizeof (DEVICE_INFO));
  513. DevicesInfo->DeviceInfoCount++;
  514. }
  515. }
  516. DevicesInfoLength = DevicesInfo->DeviceInfoCount * sizeof (DEVICE_INFO);
  517. DEBUG ((DEBUG_INFO, "NhltDevicesInfoConstructor() End, DevicesCount = %d, DevicesInfoLength = %d B\n", DevicesInfo->DeviceInfoCount, DevicesInfoLength));
  518. return DevicesInfoLength;
  519. }
  520. /**
  521. Constructs NHLT_ENDPOINT structure based on given endpoint type.
  522. @param[in][out] *NhltTable NHLT table for which endpoint is created
  523. @param[in] EndpointType Type of endpoint to be created
  524. @param[in] EndpointFormatsBitmask Bitmask of formats supported by endpoint
  525. @param[in] EndpointDevicesBitmask Bitmask of device info for endpoint
  526. @param[in] EndpointIndex Endpoint index in NHLT table
  527. @retval Size of created NHLT_ENDPOINT structure
  528. **/
  529. UINT32
  530. NhltEndpointConstructor (
  531. IN OUT NHLT_ACPI_TABLE *NhltTable,
  532. IN NHLT_ENDPOINT EndpointType,
  533. IN UINT32 EndpointFormatsBitmask,
  534. IN UINT32 EndpointDevicesBitmask,
  535. IN UINT8 EndpointIndex
  536. )
  537. {
  538. ENDPOINT_DESCRIPTOR *Endpoint;
  539. SPECIFIC_CONFIG *EndpointConfig;
  540. CONST UINT8 *EndpointConfigBuffer;
  541. UINT32 EndpointConfigBufferSize;
  542. UINT32 EndpointDescriptorLength;
  543. DEBUG ((DEBUG_INFO, "NhltEndpointConstructor() Start, EndpointIndex = %d\n", EndpointIndex));
  544. EndpointDescriptorLength = 0;
  545. Endpoint = GetNhltEndpoint (NhltTable, EndpointIndex);
  546. if (Endpoint == NULL) {
  547. return 0;
  548. }
  549. EndpointDescriptorLength = sizeof (ENDPOINT_DESCRIPTOR)
  550. - sizeof (SPECIFIC_CONFIG)
  551. - sizeof (FORMAT_CONFIG)
  552. - sizeof (DEVICE_INFO);
  553. switch (EndpointType) {
  554. case HdaDmicX1:
  555. DEBUG ((DEBUG_INFO, "Endpoint: HdaDmicX1\n"));
  556. CopyMem (Endpoint, &HdaEndpointDmicX1, sizeof (ENDPOINT_DESCRIPTOR));
  557. EndpointConfigBuffer = DmicX1Config;
  558. EndpointConfigBufferSize = DmicX1ConfigSize;
  559. break;
  560. case HdaDmicX2:
  561. DEBUG ((DEBUG_INFO, "Endpoint: HdaDmicX2\n"));
  562. CopyMem (Endpoint, &HdaEndpointDmicX2, sizeof (ENDPOINT_DESCRIPTOR));
  563. EndpointConfigBuffer = DmicX2Config;
  564. EndpointConfigBufferSize = DmicX2ConfigSize;
  565. break;
  566. case HdaDmicX4:
  567. DEBUG ((DEBUG_INFO, "Endpoint: HdaDmicX4\n"));
  568. CopyMem (Endpoint, &HdaEndpointDmicX4, sizeof (ENDPOINT_DESCRIPTOR));
  569. EndpointConfigBuffer = DmicX4Config;
  570. EndpointConfigBufferSize = DmicX4ConfigSize;
  571. break;
  572. case HdaBtRender:
  573. DEBUG ((DEBUG_INFO, "Endpoint: HdaBtRender\n"));
  574. CopyMem (Endpoint, &HdaEndpointBtRender, sizeof (ENDPOINT_DESCRIPTOR));
  575. if (IsPchH ()) {
  576. Endpoint->VirtualBusId = 0;
  577. }
  578. EndpointConfigBuffer = BtConfig;
  579. EndpointConfigBufferSize = BtConfigSize;
  580. break;
  581. case HdaBtCapture:
  582. DEBUG ((DEBUG_INFO, "Endpoint: HdaBtCapture\n"));
  583. CopyMem (Endpoint, &HdaEndpointBtCapture, sizeof (ENDPOINT_DESCRIPTOR));
  584. if (IsPchH ()) {
  585. Endpoint->VirtualBusId = 0;
  586. }
  587. EndpointConfigBuffer = BtConfig;
  588. EndpointConfigBufferSize = BtConfigSize;
  589. break;
  590. case HdaI2sRender1:
  591. DEBUG ((DEBUG_INFO, "Endpoint: HdaI2sRender1\n"));
  592. CopyMem (Endpoint, &HdaEndpointI2sRender, sizeof (ENDPOINT_DESCRIPTOR));
  593. EndpointConfigBuffer = I2sRender1Config;
  594. EndpointConfigBufferSize = I2sRender1ConfigSize;
  595. break;
  596. case HdaI2sRender2:
  597. DEBUG ((DEBUG_INFO, "Endpoint: HdaI2sRender2\n"));
  598. CopyMem (Endpoint, &HdaEndpointI2sRender, sizeof (ENDPOINT_DESCRIPTOR));
  599. EndpointConfigBuffer = I2sRender2Config;
  600. EndpointConfigBufferSize = I2sRender2ConfigSize;
  601. break;
  602. case HdaI2sCapture:
  603. DEBUG ((DEBUG_INFO, "Endpoint: HdaI2sCapture\n"));
  604. CopyMem (Endpoint, &HdaEndpointI2sCapture, sizeof (ENDPOINT_DESCRIPTOR));
  605. EndpointConfigBuffer = I2sCaptureConfig;
  606. EndpointConfigBufferSize = I2sCaptureConfigSize;
  607. break;
  608. default:
  609. DEBUG ((DEBUG_WARN, "Unknown endpoint!\n"));
  610. return 0;
  611. }
  612. EndpointConfig = GetNhltEndpointDeviceCapabilities (Endpoint);
  613. EndpointConfig->CapabilitiesSize = EndpointConfigBufferSize;
  614. CopyMem (EndpointConfig->Capabilities, EndpointConfigBuffer, EndpointConfig->CapabilitiesSize);
  615. EndpointDescriptorLength += sizeof (*EndpointConfig)
  616. - sizeof (EndpointConfig->Capabilities)
  617. + EndpointConfig->CapabilitiesSize;
  618. EndpointDescriptorLength += NhltFormatsConstructor (Endpoint, EndpointFormatsBitmask);
  619. EndpointDescriptorLength += NhltDevicesInfoConstructor (Endpoint, EndpointDevicesBitmask);
  620. Endpoint->EndpointDescriptorLength = EndpointDescriptorLength;
  621. DEBUG ((DEBUG_INFO, "NhltEndpointConstructor() End, EndpointDescriptorLength = %d B\n", Endpoint->EndpointDescriptorLength));
  622. return Endpoint->EndpointDescriptorLength;
  623. }
  624. /**
  625. Constructs SPECIFIC_CONFIG structure for OED configuration.
  626. @param[in][out] *NhltTable NHLT table for which OED config is created
  627. @retval Size of created SPECIFIC_CONFIG structure
  628. **/
  629. UINT32
  630. NhltOedConfigConstructor (
  631. IN OUT NHLT_ACPI_TABLE *NhltTable
  632. )
  633. {
  634. SPECIFIC_CONFIG *OedConfig;
  635. UINT32 OedConfigLength;
  636. OedConfigLength = 0;
  637. OedConfig = GetNhltOedConfig (NhltTable);
  638. OedConfig->CapabilitiesSize = NhltConfigurationSize;
  639. CopyMem (OedConfig->Capabilities, (UINT8*) NhltConfiguration, NhltConfigurationSize);
  640. OedConfigLength = sizeof (*OedConfig)
  641. - sizeof (OedConfig->Capabilities)
  642. + OedConfig->CapabilitiesSize;
  643. return OedConfigLength;
  644. }
  645. /**
  646. Constructs NHLT_ACPI_TABLE structure based on given Endpoints list.
  647. @param[in] *EndpointTable List of endpoints for NHLT
  648. @param[in][out] **NhltTable NHLT table to be created
  649. @param[in][out] *NhltTableSize Size of created NHLT table
  650. @retval EFI_SUCCESS NHLT created successfully
  651. @retval EFI_BAD_BUFFER_SIZE Not enough resources to allocate NHLT
  652. **/
  653. EFI_STATUS
  654. NhltConstructor (
  655. IN PCH_HDA_NHLT_ENDPOINTS *EndpointTable,
  656. IN OUT NHLT_ACPI_TABLE **NhltTable,
  657. IN OUT UINT32 *NhltTableSize
  658. )
  659. {
  660. EFI_STATUS Status;
  661. UINT8 Index;
  662. UINT32 TableSize;
  663. UINT32 EndpointDescriptorsLength;
  664. UINT32 OedConfigLength;
  665. NHLT_ACPI_TABLE *Table;
  666. Status = EFI_SUCCESS;
  667. TableSize = PCH_HDA_NHLT_TABLE_SIZE;
  668. EndpointDescriptorsLength = 0;
  669. OedConfigLength = 0;
  670. Table = AllocateZeroPool (TableSize);
  671. if (Table == NULL) {
  672. return EFI_BAD_BUFFER_SIZE;
  673. }
  674. Table->EndpointCount = 0;
  675. for (Index = 0; Index < HdaEndpointMax; Index++) {
  676. if (EndpointTable[Index].Enable == TRUE) {
  677. EndpointDescriptorsLength += NhltEndpointConstructor (Table,
  678. EndpointTable[Index].EndpointType,
  679. EndpointTable[Index].EndpointFormatsBitmask,
  680. EndpointTable[Index].EndpointDevicesBitmask,
  681. Table->EndpointCount++);
  682. }
  683. }
  684. DEBUG ((DEBUG_INFO, "NhltConstructor: EndpointCount = %d, All EndpointDescriptorsLength = %d B\n", Table->EndpointCount, EndpointDescriptorsLength));
  685. OedConfigLength = NhltOedConfigConstructor (Table);
  686. DEBUG ((DEBUG_INFO, "NhltConstructor: OedConfigLength = %d B\n", OedConfigLength));
  687. TableSize = EndpointDescriptorsLength + OedConfigLength;
  688. *NhltTableSize = TableSize;
  689. *NhltTable = Table;
  690. return Status;
  691. }
  692. /**
  693. Constructs EFI_ACPI_DESCRIPTION_HEADER structure for NHLT table.
  694. @param[in][out] *NhltTable NHLT table for which header will be created
  695. @param[in] NhltTableSize Size of NHLT table
  696. @retval None
  697. **/
  698. VOID
  699. NhltAcpiHeaderConstructor (
  700. IN OUT NHLT_ACPI_TABLE *NhltTable,
  701. IN UINT32 NhltTableSize
  702. )
  703. {
  704. DEBUG ((DEBUG_INFO, "NhltAcpiHeaderConstructor() Start\n"));
  705. // Header
  706. NhltTable->Header.Signature = NHLT_ACPI_TABLE_SIGNATURE;
  707. NhltTable->Header.Length = (UINT32) (NhltTableSize + sizeof (NHLT_ACPI_TABLE) - sizeof (ENDPOINT_DESCRIPTOR) - sizeof (SPECIFIC_CONFIG));
  708. NhltTable->Header.Revision = 0x0;
  709. NhltTable->Header.Checksum = 0x0;
  710. CopyMem (NhltTable->Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (NhltTable->Header.OemId));
  711. NhltTable->Header.OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
  712. NhltTable->Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
  713. NhltTable->Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
  714. NhltTable->Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
  715. DEBUG ((DEBUG_INFO, "NhltAcpiHeaderConstructor(), NhltAcpiTable->Header.Length = %d B\n", NhltTable->Header.Length));
  716. }