bool AlcEnabler::grabCodecs() { if (!that) { SYSLOG("alc @ you should call grabCodecs right before AppleHDA loading"); return false; } for (currentController = 0; currentController < controllers.size(); currentController++) { auto ctlr = controllers[currentController]; // Digital controllers normally have no detectible codecs if (!ctlr->detect) continue; auto sect = IOUtil::findEntryByPrefix("/AppleACPIPlatformExpert", "PCI", gIOServicePlane); for (size_t i = 0; sect && i < ctlr->lookup->treeSize; i++) { bool last = i+1 == ctlr->lookup->treeSize; sect = IOUtil::findEntryByPrefix(sect, ctlr->lookup->tree[i], gIOServicePlane, last ? [](IORegistryEntry *e) { auto ven = e->getProperty("IOHDACodecVendorID"); auto rev = e->getProperty("IOHDACodecRevisionID"); if (!ven || !rev) { DBGLOG("alc @ codec entry misses properties, skipping"); return false; } auto venNum = OSDynamicCast(OSNumber, ven); auto revNum = OSDynamicCast(OSNumber, rev); if (!venNum || !revNum) { SYSLOG("alc @ codec entry contains invalid properties, skipping"); return true; } auto ci = AlcEnabler::CodecInfo::create(that->currentController, venNum->unsigned64BitValue(), revNum->unsigned32BitValue()); if (ci) { if (!that->codecs.push_back(ci)) { SYSLOG("alc @ failed to store codec info for %X:%X:%X", ci->vendor, ci->codec, ci->revision); AlcEnabler::CodecInfo::deleter(ci); } } else { SYSLOG("alc @ failed to create codec info for %X %X:%X", ci->vendor, ci->codec, ci->revision); } return true; } : nullptr, last); } } return validateCodecs(); }
bool AlcEnabler::grabCodecs() { if (!that) { SYSLOG("alc @ you should call grabCodecs right before AppleHDA loading"); return false; } for (size_t lookup = 0; lookup < codecLookupSize; lookup++) { that->tmpLayout = -1; // Not using recursive lookup due to multiple possible entries auto sect = IOUtil::findEntryByPrefix("/AppleACPIPlatformExpert", "PCI", gIOServicePlane); size_t i {0}; while (sect && i < codecLookup[lookup].treeSize) { sect = IOUtil::findEntryByPrefix(sect, codecLookup[lookup].tree[i], gIOServicePlane, i+1 == codecLookup[lookup].treeSize ? [](IORegistryEntry *e) { if (that->tmpLayout < 0) { SYSLOG("alc @ invalid layout-id was previously found %d", that->tmpLayout); return; } auto ven = e->getProperty("IOHDACodecVendorID"); auto rev = e->getProperty("IOHDACodecRevisionID"); if (!ven || !rev) { SYSLOG("alc @ codec entry misses properties, skipping"); return; } auto venNum = OSDynamicCast(OSNumber, ven); auto revNum = OSDynamicCast(OSNumber, rev); if (!venNum || !revNum) { SYSLOG("alc @ codec entry contains invalid properties, skipping"); return; } auto ci = AlcEnabler::CodecInfo::create(venNum->unsigned64BitValue(), revNum->unsigned32BitValue(), that->tmpLayout); if (ci) { if (!that->codecs.push_back(ci)) { SYSLOG("alc @ failed to store codec info for %X %X", ci->vendor, ci->codec); AlcEnabler::CodecInfo::deleter(ci); } } else { SYSLOG("alc @ failed to create codec info for %X %X", ci->vendor, ci->codec); } } : nullptr); if (i == codecLookup[lookup].layoutNum) { if (sect) { auto lid = sect->getProperty("layout-id"); if (lid) { auto lidNum = OSDynamicCast(OSData, lid); if (lidNum && lidNum->getLength() > 0) { tmpLayout = static_cast<const uint8_t *>(lidNum->getBytesNoCopy())[0]; DBGLOG("alc @ found layout-id %d in %s", tmpLayout, codecLookup[lookup].tree[i]); i++; continue; } else { SYSLOG("alc @ %s contains invalid layout-id", codecLookup[lookup].tree[i]); } } } SYSLOG("alc @ no layout found in %s, aborting", codecLookup[lookup].tree[i]); break; } i++; } } return validateCodecs(); }