Esempio n. 1
0
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();
}
Esempio n. 2
0
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();
}