├── .github └── workflows │ └── main.yml ├── .gitignore ├── PinConfigurator.png ├── PinConfigurator.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── headsoft.xcuserdatad │ │ ├── IDEFindNavigatorScopes.plist │ │ └── UserInterfaceState.xcuserstate ├── xcshareddata │ └── xcschemes │ │ └── PinConfigurator.xcscheme └── xcuserdata │ └── headsoft.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── PinConfigurator ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-1024.png │ │ ├── Icon-128.png │ │ ├── Icon-16.png │ │ ├── Icon-256.png │ │ ├── Icon-32.png │ │ ├── Icon-512.png │ │ └── Icon-64.png │ └── Contents.json ├── AudioDevice.h ├── AudioDevice.m ├── AudioNode.h ├── AudioNode.m ├── Base.lproj │ ├── Credits.rtf │ └── MainMenu.xib ├── HdaCodec.h ├── HdaCodec.m ├── HdaCodecDump.h ├── HdaCodecDump.m ├── HdaVerbs.h ├── IORegTools.h ├── IORegTools.m ├── Info.plist ├── MiscTools.h ├── MiscTools.m ├── NSColor+Pin.h ├── NSColor+Pin.m ├── NSPinCellView.h ├── NSPinCellView.m ├── NSString+Pin.h ├── NSString+Pin.m └── main.m ├── README.md └── Resources └── Audio ├── Codecs.plist ├── Controllers.plist └── Vendors.plist /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | release: 8 | types: [published] 9 | 10 | env: 11 | PROJECT_TYPE: APP 12 | 13 | jobs: 14 | build: 15 | name: Build 16 | runs-on: macos-latest 17 | env: 18 | JOB_TYPE: BUILD 19 | steps: 20 | - uses: actions/checkout@v4 21 | - name: Extract Version 22 | id: extract_version 23 | run: | 24 | VERSION=$(grep -m 1 -E '^\s*MARKETING_VERSION' PinConfigurator.xcodeproj/project.pbxproj | awk -F' = ' '{ print $2 }' | tr -d ';' | xargs) 25 | echo "VERSION=$VERSION" >> $GITHUB_ENV 26 | - name: Build Debug 27 | run: xcodebuild -jobs 1 -configuration Debug -arch x86_64 SYMROOT=$PWD/build 28 | - name: Build Release 29 | run: xcodebuild -jobs 1 -configuration Release -arch x86_64 SYMROOT=$PWD/build 30 | - name: Zip Build 31 | run: zip -r PinConfigurator.zip build/Release build/Debug 32 | - name: Upload to Artifacts 33 | uses: actions/upload-artifact@v4 34 | with: 35 | name: Artifacts 36 | path: PinConfigurator.zip 37 | - name: Upload to Release 38 | uses: svenstaro/upload-release-action@v2 39 | with: 40 | repo_token: ${{ secrets.GITHUB_TOKEN }} 41 | file: PinConfigurator.zip 42 | tag: ${{ env.VERSION }} 43 | overwrite: true 44 | file_glob: true 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /PinConfigurator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benbaker76/PinConfigurator/3b5450de36eafabfd3fd35bbd290aa970310d021/PinConfigurator.png -------------------------------------------------------------------------------- /PinConfigurator.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E226E20A2210F649009224CF /* IORegTools.m in Sources */ = {isa = PBXBuildFile; fileRef = E226E2092210F648009224CF /* IORegTools.m */; }; 11 | E227591B220C77FA00377EF5 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E227591A220C77FA00377EF5 /* AppDelegate.m */; }; 12 | E227591D220C77FB00377EF5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E227591C220C77FB00377EF5 /* Assets.xcassets */; }; 13 | E2275920220C77FB00377EF5 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = E227591E220C77FB00377EF5 /* MainMenu.xib */; }; 14 | E2275923220C77FB00377EF5 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E2275922220C77FB00377EF5 /* main.m */; }; 15 | E24E3F7B221352ED0079D7DB /* AudioDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = E24E3F79221352ED0079D7DB /* AudioDevice.m */; }; 16 | E25A0CFA22158DF600057B76 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = E25A0CF822158DF600057B76 /* Credits.rtf */; }; 17 | E28353B1220C835300454571 /* AudioNode.m in Sources */ = {isa = PBXBuildFile; fileRef = E28353B0220C835300454571 /* AudioNode.m */; }; 18 | E28353B5220C877D00454571 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E28353B4220C877D00454571 /* AppKit.framework */; }; 19 | E28353BB220C9CDB00454571 /* NSString+Pin.m in Sources */ = {isa = PBXBuildFile; fileRef = E28353BA220C9CDB00454571 /* NSString+Pin.m */; }; 20 | E28353C1220CAB2100454571 /* NSColor+Pin.m in Sources */ = {isa = PBXBuildFile; fileRef = E28353C0220CAB2100454571 /* NSColor+Pin.m */; }; 21 | E28B558B22130052004FCE24 /* Audio in Resources */ = {isa = PBXBuildFile; fileRef = E28B558A22130052004FCE24 /* Audio */; }; 22 | E2AEBFD9220CE9780037EA73 /* MiscTools.m in Sources */ = {isa = PBXBuildFile; fileRef = E2AEBFD8220CE9780037EA73 /* MiscTools.m */; }; 23 | E2B22A73221870C5003FC976 /* HdaCodec.m in Sources */ = {isa = PBXBuildFile; fileRef = E2B22A72221870C5003FC976 /* HdaCodec.m */; }; 24 | E2B848E0240B30AD00CD051F /* NSPinCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = E2B848DE240B30AD00CD051F /* NSPinCellView.m */; }; 25 | E2D61C6A22872E9D004A059A /* HdaCodecDump.m in Sources */ = {isa = PBXBuildFile; fileRef = E2D61C6822872E9D004A059A /* HdaCodecDump.m */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | E226E2082210F648009224CF /* IORegTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IORegTools.h; sourceTree = ""; }; 30 | E226E2092210F648009224CF /* IORegTools.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = IORegTools.m; sourceTree = ""; }; 31 | E2275916220C77FA00377EF5 /* PinConfigurator.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PinConfigurator.app; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | E2275919220C77FA00377EF5 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 33 | E227591A220C77FA00377EF5 /* AppDelegate.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = AppDelegate.m; sourceTree = ""; }; 34 | E227591C220C77FB00377EF5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 35 | E227591F220C77FB00377EF5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 36 | E2275921220C77FB00377EF5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 37 | E2275922220C77FB00377EF5 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 38 | E22E8FE22215D115003478ED /* HdaVerbs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HdaVerbs.h; sourceTree = ""; }; 39 | E24E3F79221352ED0079D7DB /* AudioDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioDevice.m; sourceTree = ""; }; 40 | E24E3F7A221352ED0079D7DB /* AudioDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDevice.h; sourceTree = ""; }; 41 | E25A0CF922158DF600057B76 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = Base; path = Base.lproj/Credits.rtf; sourceTree = ""; }; 42 | E28353B0220C835300454571 /* AudioNode.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = AudioNode.m; sourceTree = ""; }; 43 | E28353B2220C836700454571 /* AudioNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AudioNode.h; sourceTree = ""; }; 44 | E28353B4220C877D00454571 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 45 | E28353B9220C9CDB00454571 /* NSString+Pin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSString+Pin.h"; sourceTree = ""; }; 46 | E28353BA220C9CDB00454571 /* NSString+Pin.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSString+Pin.m"; sourceTree = ""; }; 47 | E28353BF220CAB2100454571 /* NSColor+Pin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSColor+Pin.h"; sourceTree = ""; }; 48 | E28353C0220CAB2100454571 /* NSColor+Pin.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSColor+Pin.m"; sourceTree = ""; }; 49 | E28B558A22130052004FCE24 /* Audio */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Audio; path = Resources/Audio; sourceTree = SOURCE_ROOT; }; 50 | E2AEBFD7220CE9780037EA73 /* MiscTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MiscTools.h; sourceTree = ""; }; 51 | E2AEBFD8220CE9780037EA73 /* MiscTools.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = MiscTools.m; sourceTree = ""; }; 52 | E2B22A72221870C5003FC976 /* HdaCodec.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = HdaCodec.m; sourceTree = ""; }; 53 | E2B22A74221870D5003FC976 /* HdaCodec.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HdaCodec.h; sourceTree = ""; }; 54 | E2B848DE240B30AD00CD051F /* NSPinCellView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSPinCellView.m; sourceTree = ""; }; 55 | E2B848DF240B30AD00CD051F /* NSPinCellView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSPinCellView.h; sourceTree = ""; }; 56 | E2D61C6822872E9D004A059A /* HdaCodecDump.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HdaCodecDump.m; sourceTree = ""; }; 57 | E2D61C6922872E9D004A059A /* HdaCodecDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HdaCodecDump.h; sourceTree = ""; }; 58 | /* End PBXFileReference section */ 59 | 60 | /* Begin PBXFrameworksBuildPhase section */ 61 | E2275913220C77FA00377EF5 /* Frameworks */ = { 62 | isa = PBXFrameworksBuildPhase; 63 | buildActionMask = 2147483647; 64 | files = ( 65 | E28353B5220C877D00454571 /* AppKit.framework in Frameworks */, 66 | ); 67 | runOnlyForDeploymentPostprocessing = 0; 68 | }; 69 | /* End PBXFrameworksBuildPhase section */ 70 | 71 | /* Begin PBXGroup section */ 72 | E227590D220C77FA00377EF5 = { 73 | isa = PBXGroup; 74 | children = ( 75 | E28B55872212FFFB004FCE24 /* Resources */, 76 | E2275918220C77FA00377EF5 /* PinConfigurator */, 77 | E2275917220C77FA00377EF5 /* Products */, 78 | E28353B3220C877D00454571 /* Frameworks */, 79 | ); 80 | sourceTree = ""; 81 | }; 82 | E2275917220C77FA00377EF5 /* Products */ = { 83 | isa = PBXGroup; 84 | children = ( 85 | E2275916220C77FA00377EF5 /* PinConfigurator.app */, 86 | ); 87 | name = Products; 88 | sourceTree = ""; 89 | }; 90 | E2275918220C77FA00377EF5 /* PinConfigurator */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | E2275919220C77FA00377EF5 /* AppDelegate.h */, 94 | E227591A220C77FA00377EF5 /* AppDelegate.m */, 95 | E227591C220C77FB00377EF5 /* Assets.xcassets */, 96 | E24E3F7A221352ED0079D7DB /* AudioDevice.h */, 97 | E24E3F79221352ED0079D7DB /* AudioDevice.m */, 98 | E28353B2220C836700454571 /* AudioNode.h */, 99 | E28353B0220C835300454571 /* AudioNode.m */, 100 | E25A0CF822158DF600057B76 /* Credits.rtf */, 101 | E2B22A74221870D5003FC976 /* HdaCodec.h */, 102 | E2B22A72221870C5003FC976 /* HdaCodec.m */, 103 | E2D61C6922872E9D004A059A /* HdaCodecDump.h */, 104 | E2D61C6822872E9D004A059A /* HdaCodecDump.m */, 105 | E22E8FE22215D115003478ED /* HdaVerbs.h */, 106 | E2275921220C77FB00377EF5 /* Info.plist */, 107 | E226E2082210F648009224CF /* IORegTools.h */, 108 | E226E2092210F648009224CF /* IORegTools.m */, 109 | E2275922220C77FB00377EF5 /* main.m */, 110 | E227591E220C77FB00377EF5 /* MainMenu.xib */, 111 | E2AEBFD7220CE9780037EA73 /* MiscTools.h */, 112 | E2AEBFD8220CE9780037EA73 /* MiscTools.m */, 113 | E28353BF220CAB2100454571 /* NSColor+Pin.h */, 114 | E28353C0220CAB2100454571 /* NSColor+Pin.m */, 115 | E2B848DF240B30AD00CD051F /* NSPinCellView.h */, 116 | E2B848DE240B30AD00CD051F /* NSPinCellView.m */, 117 | E28353B9220C9CDB00454571 /* NSString+Pin.h */, 118 | E28353BA220C9CDB00454571 /* NSString+Pin.m */, 119 | ); 120 | path = PinConfigurator; 121 | sourceTree = ""; 122 | }; 123 | E28353B3220C877D00454571 /* Frameworks */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | E28353B4220C877D00454571 /* AppKit.framework */, 127 | ); 128 | name = Frameworks; 129 | sourceTree = ""; 130 | }; 131 | E28B55872212FFFB004FCE24 /* Resources */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | E28B558A22130052004FCE24 /* Audio */, 135 | ); 136 | path = Resources; 137 | sourceTree = ""; 138 | }; 139 | /* End PBXGroup section */ 140 | 141 | /* Begin PBXNativeTarget section */ 142 | E2275915220C77FA00377EF5 /* PinConfigurator */ = { 143 | isa = PBXNativeTarget; 144 | buildConfigurationList = E2275927220C77FB00377EF5 /* Build configuration list for PBXNativeTarget "PinConfigurator" */; 145 | buildPhases = ( 146 | E2275912220C77FA00377EF5 /* Sources */, 147 | E2275913220C77FA00377EF5 /* Frameworks */, 148 | E2275914220C77FA00377EF5 /* Resources */, 149 | ); 150 | buildRules = ( 151 | ); 152 | dependencies = ( 153 | ); 154 | name = PinConfigurator; 155 | productName = PinConfigurator; 156 | productReference = E2275916220C77FA00377EF5 /* PinConfigurator.app */; 157 | productType = "com.apple.product-type.application"; 158 | }; 159 | /* End PBXNativeTarget section */ 160 | 161 | /* Begin PBXProject section */ 162 | E227590E220C77FA00377EF5 /* Project object */ = { 163 | isa = PBXProject; 164 | attributes = { 165 | LastUpgradeCheck = 1330; 166 | ORGANIZATIONNAME = "Ben Baker"; 167 | TargetAttributes = { 168 | E2275915220C77FA00377EF5 = { 169 | CreatedOnToolsVersion = 10.1; 170 | }; 171 | }; 172 | }; 173 | buildConfigurationList = E2275911220C77FA00377EF5 /* Build configuration list for PBXProject "PinConfigurator" */; 174 | compatibilityVersion = "Xcode 9.3"; 175 | developmentRegion = en; 176 | hasScannedForEncodings = 0; 177 | knownRegions = ( 178 | en, 179 | Base, 180 | ); 181 | mainGroup = E227590D220C77FA00377EF5; 182 | productRefGroup = E2275917220C77FA00377EF5 /* Products */; 183 | projectDirPath = ""; 184 | projectRoot = ""; 185 | targets = ( 186 | E2275915220C77FA00377EF5 /* PinConfigurator */, 187 | ); 188 | }; 189 | /* End PBXProject section */ 190 | 191 | /* Begin PBXResourcesBuildPhase section */ 192 | E2275914220C77FA00377EF5 /* Resources */ = { 193 | isa = PBXResourcesBuildPhase; 194 | buildActionMask = 2147483647; 195 | files = ( 196 | E28B558B22130052004FCE24 /* Audio in Resources */, 197 | E227591D220C77FB00377EF5 /* Assets.xcassets in Resources */, 198 | E2275920220C77FB00377EF5 /* MainMenu.xib in Resources */, 199 | E25A0CFA22158DF600057B76 /* Credits.rtf in Resources */, 200 | ); 201 | runOnlyForDeploymentPostprocessing = 0; 202 | }; 203 | /* End PBXResourcesBuildPhase section */ 204 | 205 | /* Begin PBXSourcesBuildPhase section */ 206 | E2275912220C77FA00377EF5 /* Sources */ = { 207 | isa = PBXSourcesBuildPhase; 208 | buildActionMask = 2147483647; 209 | files = ( 210 | E28353C1220CAB2100454571 /* NSColor+Pin.m in Sources */, 211 | E226E20A2210F649009224CF /* IORegTools.m in Sources */, 212 | E2275923220C77FB00377EF5 /* main.m in Sources */, 213 | E2D61C6A22872E9D004A059A /* HdaCodecDump.m in Sources */, 214 | E2B22A73221870C5003FC976 /* HdaCodec.m in Sources */, 215 | E2B848E0240B30AD00CD051F /* NSPinCellView.m in Sources */, 216 | E227591B220C77FA00377EF5 /* AppDelegate.m in Sources */, 217 | E2AEBFD9220CE9780037EA73 /* MiscTools.m in Sources */, 218 | E24E3F7B221352ED0079D7DB /* AudioDevice.m in Sources */, 219 | E28353BB220C9CDB00454571 /* NSString+Pin.m in Sources */, 220 | E28353B1220C835300454571 /* AudioNode.m in Sources */, 221 | ); 222 | runOnlyForDeploymentPostprocessing = 0; 223 | }; 224 | /* End PBXSourcesBuildPhase section */ 225 | 226 | /* Begin PBXVariantGroup section */ 227 | E227591E220C77FB00377EF5 /* MainMenu.xib */ = { 228 | isa = PBXVariantGroup; 229 | children = ( 230 | E227591F220C77FB00377EF5 /* Base */, 231 | ); 232 | name = MainMenu.xib; 233 | sourceTree = ""; 234 | }; 235 | E25A0CF822158DF600057B76 /* Credits.rtf */ = { 236 | isa = PBXVariantGroup; 237 | children = ( 238 | E25A0CF922158DF600057B76 /* Base */, 239 | ); 240 | name = Credits.rtf; 241 | sourceTree = ""; 242 | }; 243 | /* End PBXVariantGroup section */ 244 | 245 | /* Begin XCBuildConfiguration section */ 246 | E2275925220C77FB00377EF5 /* Debug */ = { 247 | isa = XCBuildConfiguration; 248 | buildSettings = { 249 | ALWAYS_SEARCH_USER_PATHS = NO; 250 | CLANG_ANALYZER_NONNULL = YES; 251 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 252 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 253 | CLANG_CXX_LIBRARY = "libc++"; 254 | CLANG_ENABLE_MODULES = YES; 255 | CLANG_ENABLE_OBJC_ARC = NO; 256 | CLANG_ENABLE_OBJC_WEAK = YES; 257 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 258 | CLANG_WARN_BOOL_CONVERSION = YES; 259 | CLANG_WARN_COMMA = YES; 260 | CLANG_WARN_CONSTANT_CONVERSION = YES; 261 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 262 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 263 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 264 | CLANG_WARN_EMPTY_BODY = YES; 265 | CLANG_WARN_ENUM_CONVERSION = YES; 266 | CLANG_WARN_INFINITE_RECURSION = YES; 267 | CLANG_WARN_INT_CONVERSION = YES; 268 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 269 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 270 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 271 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 272 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 273 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 274 | CLANG_WARN_STRICT_PROTOTYPES = YES; 275 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 276 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 277 | CLANG_WARN_UNREACHABLE_CODE = YES; 278 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 279 | CODE_SIGN_IDENTITY = "-"; 280 | COPY_PHASE_STRIP = NO; 281 | DEBUG_INFORMATION_FORMAT = dwarf; 282 | ENABLE_STRICT_OBJC_MSGSEND = YES; 283 | ENABLE_TESTABILITY = YES; 284 | GCC_C_LANGUAGE_STANDARD = gnu11; 285 | GCC_DYNAMIC_NO_PIC = NO; 286 | GCC_NO_COMMON_BLOCKS = YES; 287 | GCC_OPTIMIZATION_LEVEL = 0; 288 | GCC_PREPROCESSOR_DEFINITIONS = ( 289 | "DEBUG=1", 290 | "$(inherited)", 291 | ); 292 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 293 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 294 | GCC_WARN_UNDECLARED_SELECTOR = YES; 295 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 296 | GCC_WARN_UNUSED_FUNCTION = YES; 297 | GCC_WARN_UNUSED_VARIABLE = YES; 298 | MACOSX_DEPLOYMENT_TARGET = 10.13; 299 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 300 | MTL_FAST_MATH = YES; 301 | ONLY_ACTIVE_ARCH = YES; 302 | SDKROOT = macosx; 303 | }; 304 | name = Debug; 305 | }; 306 | E2275926220C77FB00377EF5 /* Release */ = { 307 | isa = XCBuildConfiguration; 308 | buildSettings = { 309 | ALWAYS_SEARCH_USER_PATHS = NO; 310 | CLANG_ANALYZER_NONNULL = YES; 311 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 312 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 313 | CLANG_CXX_LIBRARY = "libc++"; 314 | CLANG_ENABLE_MODULES = YES; 315 | CLANG_ENABLE_OBJC_ARC = NO; 316 | CLANG_ENABLE_OBJC_WEAK = YES; 317 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 318 | CLANG_WARN_BOOL_CONVERSION = YES; 319 | CLANG_WARN_COMMA = YES; 320 | CLANG_WARN_CONSTANT_CONVERSION = YES; 321 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 322 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 323 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 324 | CLANG_WARN_EMPTY_BODY = YES; 325 | CLANG_WARN_ENUM_CONVERSION = YES; 326 | CLANG_WARN_INFINITE_RECURSION = YES; 327 | CLANG_WARN_INT_CONVERSION = YES; 328 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 329 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 330 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 331 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 332 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 333 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 334 | CLANG_WARN_STRICT_PROTOTYPES = YES; 335 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 336 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 337 | CLANG_WARN_UNREACHABLE_CODE = YES; 338 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 339 | CODE_SIGN_IDENTITY = "-"; 340 | COPY_PHASE_STRIP = NO; 341 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 342 | ENABLE_NS_ASSERTIONS = NO; 343 | ENABLE_STRICT_OBJC_MSGSEND = YES; 344 | GCC_C_LANGUAGE_STANDARD = gnu11; 345 | GCC_NO_COMMON_BLOCKS = YES; 346 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 347 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 348 | GCC_WARN_UNDECLARED_SELECTOR = YES; 349 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 350 | GCC_WARN_UNUSED_FUNCTION = YES; 351 | GCC_WARN_UNUSED_VARIABLE = YES; 352 | MACOSX_DEPLOYMENT_TARGET = 10.13; 353 | MTL_ENABLE_DEBUG_INFO = NO; 354 | MTL_FAST_MATH = YES; 355 | SDKROOT = macosx; 356 | }; 357 | name = Release; 358 | }; 359 | E2275928220C77FB00377EF5 /* Debug */ = { 360 | isa = XCBuildConfiguration; 361 | buildSettings = { 362 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 363 | CLANG_ENABLE_OBJC_ARC = NO; 364 | CODE_SIGN_ENTITLEMENTS = ""; 365 | CODE_SIGN_IDENTITY = "-"; 366 | CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; 367 | CODE_SIGN_STYLE = Automatic; 368 | COMBINE_HIDPI_IMAGES = YES; 369 | CURRENT_PROJECT_VERSION = 0229; 370 | ENABLE_STRICT_OBJC_MSGSEND = NO; 371 | INFOPLIST_FILE = PinConfigurator/Info.plist; 372 | LD_RUNPATH_SEARCH_PATHS = ( 373 | "$(inherited)", 374 | "@executable_path/../Frameworks", 375 | ); 376 | MACOSX_DEPLOYMENT_TARGET = 10.13; 377 | MARKETING_VERSION = 2.2.9; 378 | PRODUCT_BUNDLE_IDENTIFIER = com.Headsoft.PinConfigurator; 379 | PRODUCT_NAME = "$(TARGET_NAME)"; 380 | }; 381 | name = Debug; 382 | }; 383 | E2275929220C77FB00377EF5 /* Release */ = { 384 | isa = XCBuildConfiguration; 385 | buildSettings = { 386 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 387 | CLANG_ENABLE_OBJC_ARC = NO; 388 | CODE_SIGN_ENTITLEMENTS = ""; 389 | CODE_SIGN_IDENTITY = "-"; 390 | CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; 391 | CODE_SIGN_STYLE = Automatic; 392 | COMBINE_HIDPI_IMAGES = YES; 393 | CURRENT_PROJECT_VERSION = 0229; 394 | ENABLE_STRICT_OBJC_MSGSEND = NO; 395 | INFOPLIST_FILE = PinConfigurator/Info.plist; 396 | LD_RUNPATH_SEARCH_PATHS = ( 397 | "$(inherited)", 398 | "@executable_path/../Frameworks", 399 | ); 400 | MACOSX_DEPLOYMENT_TARGET = 10.13; 401 | MARKETING_VERSION = 2.2.9; 402 | PRODUCT_BUNDLE_IDENTIFIER = com.Headsoft.PinConfigurator; 403 | PRODUCT_NAME = "$(TARGET_NAME)"; 404 | }; 405 | name = Release; 406 | }; 407 | /* End XCBuildConfiguration section */ 408 | 409 | /* Begin XCConfigurationList section */ 410 | E2275911220C77FA00377EF5 /* Build configuration list for PBXProject "PinConfigurator" */ = { 411 | isa = XCConfigurationList; 412 | buildConfigurations = ( 413 | E2275925220C77FB00377EF5 /* Debug */, 414 | E2275926220C77FB00377EF5 /* Release */, 415 | ); 416 | defaultConfigurationIsVisible = 0; 417 | defaultConfigurationName = Release; 418 | }; 419 | E2275927220C77FB00377EF5 /* Build configuration list for PBXNativeTarget "PinConfigurator" */ = { 420 | isa = XCConfigurationList; 421 | buildConfigurations = ( 422 | E2275928220C77FB00377EF5 /* Debug */, 423 | E2275929220C77FB00377EF5 /* Release */, 424 | ); 425 | defaultConfigurationIsVisible = 0; 426 | defaultConfigurationName = Release; 427 | }; 428 | /* End XCConfigurationList section */ 429 | }; 430 | rootObject = E227590E220C77FA00377EF5 /* Project object */; 431 | } 432 | -------------------------------------------------------------------------------- /PinConfigurator.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PinConfigurator.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /PinConfigurator.xcodeproj/project.xcworkspace/xcuserdata/headsoft.xcuserdatad/IDEFindNavigatorScopes.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /PinConfigurator.xcodeproj/project.xcworkspace/xcuserdata/headsoft.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benbaker76/PinConfigurator/3b5450de36eafabfd3fd35bbd290aa970310d021/PinConfigurator.xcodeproj/project.xcworkspace/xcuserdata/headsoft.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /PinConfigurator.xcodeproj/xcshareddata/xcschemes/PinConfigurator.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /PinConfigurator.xcodeproj/xcuserdata/headsoft.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /PinConfigurator.xcodeproj/xcuserdata/headsoft.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PinConfigurator.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | E2275915220C77FA00377EF5 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /PinConfigurator/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // PinConfigurator 4 | // 5 | // Created by Ben Baker on 2/7/19. 6 | // Copyright © 2019 Ben Baker. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AudioNode.h" 11 | #import "AudioDevice.h" 12 | #import "HdaCodec.h" 13 | 14 | enum 15 | { 16 | kNodeNone = 0, 17 | kNodeFixHeadphone = (1 << 0), 18 | kNodeRemoveDisabled = (1 << 1), 19 | kNodeRemoveATAPI = (1 << 2), 20 | kNodeIndexToZero = (1 << 3), 21 | kNodeMiscToZero = (1 << 4), 22 | kNodeMakeGroupUnique = (1 << 5), 23 | kNodeChangeLocation = (1 << 6), 24 | kNodeLineOutToSpeaker = (1 << 7), 25 | kNodeEnableDSP = (1 << 8), 26 | kNodeDisableExtMic = (1 << 9), 27 | kNodeRemoveHDMI = (1 << 10) 28 | } NodeOptions; 29 | 30 | @interface AppDelegate : NSObject 31 | { 32 | HdaCodec *_hdaCodec; 33 | NSMutableArray *_originalNodeArray; 34 | NSMutableArray *_nodeArray; 35 | NSArray *_hdaConfigDefaultArray; 36 | 37 | NSString *_fileName; 38 | NSString *_pinConfigsFileName; 39 | NSString *_codecName; 40 | int _codecAddress; 41 | unsigned int _codecID; 42 | int _layoutID; 43 | 44 | NSMutableArray *_audioDeviceArray; 45 | AudioDevice *_audioDevice; 46 | 47 | NSDictionary *_controllersDictionary; 48 | NSDictionary *_vendorsDictionary; 49 | NSArray *_codecsArray; 50 | NSMutableArray *_codecIDArray; 51 | 52 | NSString *_hdaCodecString; 53 | NSMutableArray *_selectCodecArray; 54 | 55 | bool _sortNodes; 56 | uint32_t _nodeOptions; 57 | } 58 | 59 | @property (assign) IBOutlet NSWindow *mainWindow; 60 | @property (assign) IBOutlet NSButton *addOKButton; 61 | @property (assign) IBOutlet NSPopUpButton *codecAddressPopUpButton; 62 | @property (assign) IBOutlet NSButton *getConfigDataButton; 63 | @property (assign) IBOutlet NSButton *quotesButton; 64 | @property (assign) IBOutlet NSPopUpButton *colorPopUpButton; 65 | @property (assign) IBOutlet NSPopUpButton *connectorPopUpButton; 66 | @property (assign) IBOutlet NSPopUpButton *devicePopUpButton; 67 | @property (assign) IBOutlet NSPopUpButton *groupPopUpButton; 68 | @property (assign) IBOutlet NSPopUpButton *grossLocationPopUpButton; 69 | @property (assign) IBOutlet NSPopUpButton *geometricLocationPopUpButton; 70 | @property (assign) IBOutlet NSPopUpButton *miscPopUpButton; 71 | @property (assign) IBOutlet NSPopUpButton *portPopUpButton; 72 | @property (assign) IBOutlet NSPopUpButton *positionPopUpButton; 73 | @property (assign) IBOutlet NSPopUpButton *eapdPopUpButton; 74 | @property (assign) IBOutlet NSTextField *nodeIDTextField; 75 | @property (assign) IBOutlet NSTextField *pinDefaultTextField; 76 | @property (assign) IBOutlet NSTextField *configDataTextField; 77 | @property (assign) IBOutlet NSOutlineView *pinConfigOutlineView; 78 | @property (assign) IBOutlet NSOutlineView *importPinOutlineView; 79 | @property (assign) IBOutlet NSOutlineView *importIORegOutlineView; 80 | @property (assign) IBOutlet NSOutlineView *selectCodecOutlineView; 81 | @property (assign) IBOutlet NSTextField *addNodeTextField; 82 | @property (assign) IBOutlet NSPanel *addNodePanel; 83 | @property (assign) IBOutlet NSPanel *importPinConfigPanel; 84 | @property (assign) IBOutlet NSPanel *importIORegPanel; 85 | @property (assign) IBOutlet NSPanel *selectCodecPanel; 86 | @property (assign) IBOutlet NSSegmentedControl *editNodeSegmentedControl; 87 | @property (assign) IBOutlet NSTextField *layoutIDTextField; 88 | @property (assign) IBOutlet NSMenu *optionsMenu; 89 | @property (assign) IBOutlet NSMenu *verbSanitizeOptionsMenu; 90 | 91 | @property (retain) NSMutableArray *originalNodeArray; 92 | @property (retain) NSMutableArray *nodeArray; 93 | 94 | - (IBAction)compileConfigList:(id)sender; 95 | - (IBAction)editNodeCancel:(id)sender; 96 | - (IBAction)editNodeOK:(id)sender; 97 | - (IBAction)editNodePinStringAction:(id)sender; 98 | - (IBAction)editNodeComboAction:(id)sender; 99 | - (IBAction)editNodeAction:(id)sender; 100 | - (IBAction)openDocument:(id)sender; 101 | - (IBAction)exportVerbsTxt:(id)sender; 102 | - (IBAction)exportHdaCodecTxt:(id)sender; 103 | - (IBAction)exportPlatformsXml:(id)sender; 104 | - (IBAction)importPinConfigsKext:(id)sender; 105 | - (IBAction)exportPinConfigsKext:(id)sender; 106 | - (IBAction)importIORegistry:(id)sender; 107 | - (IBAction)importClipboard:(id)sender; 108 | - (IBAction)print:(id)sender; 109 | - (IBAction)importPinSelect:(id)sender; 110 | - (IBAction)importPinCancel:(id)sender; 111 | - (IBAction)importIORegSelect:(id)sender; 112 | - (IBAction)importIORegCancel:(id)sender; 113 | - (IBAction)selectCodecCancel:(id)sender; 114 | - (IBAction)selectCodecSelect:(id)sender; 115 | - (IBAction)layoutIDAction:(id)sender; 116 | - (IBAction)removeDisabledAction:(id)sender; 117 | - (IBAction)verbSanitizeAction:(id)sender; 118 | 119 | @end 120 | 121 | -------------------------------------------------------------------------------- /PinConfigurator/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "Icon-16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "Icon-32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "Icon-32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "Icon-64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "Icon-128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "Icon-256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "Icon-256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "Icon-512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "Icon-512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "Icon-1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /PinConfigurator/Assets.xcassets/AppIcon.appiconset/Icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benbaker76/PinConfigurator/3b5450de36eafabfd3fd35bbd290aa970310d021/PinConfigurator/Assets.xcassets/AppIcon.appiconset/Icon-1024.png -------------------------------------------------------------------------------- /PinConfigurator/Assets.xcassets/AppIcon.appiconset/Icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benbaker76/PinConfigurator/3b5450de36eafabfd3fd35bbd290aa970310d021/PinConfigurator/Assets.xcassets/AppIcon.appiconset/Icon-128.png -------------------------------------------------------------------------------- /PinConfigurator/Assets.xcassets/AppIcon.appiconset/Icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benbaker76/PinConfigurator/3b5450de36eafabfd3fd35bbd290aa970310d021/PinConfigurator/Assets.xcassets/AppIcon.appiconset/Icon-16.png -------------------------------------------------------------------------------- /PinConfigurator/Assets.xcassets/AppIcon.appiconset/Icon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benbaker76/PinConfigurator/3b5450de36eafabfd3fd35bbd290aa970310d021/PinConfigurator/Assets.xcassets/AppIcon.appiconset/Icon-256.png -------------------------------------------------------------------------------- /PinConfigurator/Assets.xcassets/AppIcon.appiconset/Icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benbaker76/PinConfigurator/3b5450de36eafabfd3fd35bbd290aa970310d021/PinConfigurator/Assets.xcassets/AppIcon.appiconset/Icon-32.png -------------------------------------------------------------------------------- /PinConfigurator/Assets.xcassets/AppIcon.appiconset/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benbaker76/PinConfigurator/3b5450de36eafabfd3fd35bbd290aa970310d021/PinConfigurator/Assets.xcassets/AppIcon.appiconset/Icon-512.png -------------------------------------------------------------------------------- /PinConfigurator/Assets.xcassets/AppIcon.appiconset/Icon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benbaker76/PinConfigurator/3b5450de36eafabfd3fd35bbd290aa970310d021/PinConfigurator/Assets.xcassets/AppIcon.appiconset/Icon-64.png -------------------------------------------------------------------------------- /PinConfigurator/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PinConfigurator/AudioDevice.h: -------------------------------------------------------------------------------- 1 | // 2 | // AudioDevice.h 3 | // Hackintool 4 | // 5 | // Created by Ben Baker on 2/12/19. 6 | // Copyright © 2019 Ben Baker. All rights reserved. 7 | // 8 | 9 | #ifndef AudioDevice_h 10 | #define AudioDevice_h 11 | 12 | #import 13 | #import 14 | 15 | @interface AudioDevice : NSObject 16 | { 17 | } 18 | 19 | @property (nonatomic, retain) NSString *bundleID; 20 | @property (nonatomic, retain) NSString *deviceClass; 21 | @property uint32_t deviceID; 22 | @property uint32_t revisionID; 23 | @property uint32_t layoutID; 24 | @property uint32_t alcLayoutID; 25 | @property uint32_t subDeviceID; 26 | @property uint32_t codecAddress; 27 | @property uint32_t codecID; 28 | @property uint32_t codecRevisionID; 29 | @property uint32_t audioDeviceModelID; 30 | @property (nonatomic, retain) NSString *audioDeviceName; 31 | @property (nonatomic, retain) NSString *audioDeviceManufacturerName; 32 | @property (nonatomic, retain) NSString *vendorName; 33 | @property (nonatomic, retain) NSString *deviceName; 34 | @property (nonatomic, retain) NSString *subVendorName; 35 | @property (nonatomic, retain) NSString *subDeviceName; 36 | @property (nonatomic, retain) NSString *codecVendorName; 37 | @property (nonatomic, retain) NSString *codecName; 38 | @property (nonatomic, retain) NSMutableArray *layoutIDArray; 39 | @property (nonatomic, retain) NSMutableArray *revisionArray; 40 | @property (nonatomic, retain) NSData *digitalAudioCapabilities; 41 | @property (nonatomic, retain) NSMutableDictionary *hdaConfigDefaultDictionary; 42 | @property uint32_t minKernel; 43 | @property uint32_t maxKernel; 44 | 45 | -(id) initWithDeviceBundleID:(NSString *)bundleID deviceClass:(NSString *)deviceClass audioDeviceName:(NSString *)audioDeviceName audioDeviceManufacturerName:(NSString *)audioDeviceManufacturerName audioDeviceModelID:(uint32_t)audioDeviceModelID deviceID:(uint32_t)deviceID revisionID:(uint32_t)revisionID alcLayoutID:(uint32_t)alcLayoutID subDeviceID:(uint32_t)subDeviceID; 46 | 47 | @end 48 | 49 | #endif /* AudioDevice_h */ 50 | -------------------------------------------------------------------------------- /PinConfigurator/AudioDevice.m: -------------------------------------------------------------------------------- 1 | // 2 | // AudioDevice.m 3 | // Hackintool 4 | // 5 | // Created by Ben Baker on 2/12/19. 6 | // Copyright © 2019 Ben Baker. All rights reserved. 7 | // 8 | 9 | #import "AudioDevice.h" 10 | 11 | @implementation AudioDevice 12 | 13 | -(id) initWithDeviceBundleID:(NSString *)bundleID deviceClass:(NSString *)deviceClass audioDeviceName:(NSString *)audioDeviceName audioDeviceManufacturerName:(NSString *)audioDeviceManufacturerName audioDeviceModelID:(uint32_t)audioDeviceModelID deviceID:(uint32_t)deviceID revisionID:(uint32_t)revisionID alcLayoutID:(uint32_t)alcLayoutID subDeviceID:(uint32_t)subDeviceID 14 | { 15 | if (self = [super init]) 16 | { 17 | self.bundleID = bundleID; 18 | self.deviceClass = deviceClass; 19 | self.audioDeviceName = audioDeviceName; 20 | self.audioDeviceManufacturerName = audioDeviceManufacturerName; 21 | self.audioDeviceModelID = audioDeviceModelID; 22 | self.deviceID = deviceID; 23 | self.revisionID = revisionID; 24 | self.alcLayoutID = alcLayoutID; 25 | self.subDeviceID = subDeviceID; 26 | } 27 | 28 | return self; 29 | } 30 | 31 | - (void)dealloc 32 | { 33 | [_bundleID release]; 34 | [_deviceClass release]; 35 | [_vendorName release]; 36 | [_deviceName release]; 37 | [_codecVendorName release]; 38 | [_codecName release]; 39 | [_layoutIDArray release]; 40 | [_revisionArray release]; 41 | [_digitalAudioCapabilities release]; 42 | [_hdaConfigDefaultDictionary release]; 43 | 44 | [super dealloc]; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /PinConfigurator/AudioNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // AudioNode.h 3 | // PinConfigurator 4 | // 5 | // Created by Ben Baker on 2/7/19. 6 | // Copyright © 2019 Ben Baker. All rights reserved. 7 | // 8 | 9 | #ifndef AudioNode_h 10 | #define AudioNode_h 11 | 12 | #import 13 | 14 | #define LONIBBLE(n) ((char)(n) & 0xF) 15 | #define HINIBBLE(n) ((char)(((char)(n) >> 4) & 0xF)) 16 | 17 | enum 18 | { 19 | kHdaPinCapabilitiesImpendance = (1 << 0), 20 | kHdaPinCapabilitiesTrigger = (1 << 1), 21 | kHdaPinCapabilitiesPresense = (1 << 2), 22 | kHdaPinCapabilitiesHeadphone = (1 << 3), 23 | kHdaPinCapabilitiesOutput = (1 << 4), 24 | kHdaPinCapabilitiesInput = (1 << 5), 25 | kHdaPinCapabilitiesBalanced = (1 << 6), 26 | kHdaPinCapabilitiesHDMI = (1 << 7), 27 | kHdaPinCapabilitiesEAPD = (1 << 16), 28 | kHdaPinCapabilitiesDisplayPort = (1 << 24), 29 | kHdaPinCapabilitiesHBR = (1 << 27) 30 | }; 31 | 32 | enum 33 | { 34 | kHdaConfigDefaultConnUnknown = 0x0, 35 | kHdaConfigDefaultConn18Stereo = 0x1, 36 | kHdaConfigDefaultConn14Stereo = 0x2, 37 | kHdaConfigDefaultConnATAPI = 0x3, 38 | kHdaConfigDefaultConnRCA = 0x4, 39 | kHdaConfigDefaultConnOptical = 0x5, 40 | kHdaConfigDefaultConnDigitalOther = 0x6, 41 | kHdaConfigDefaultConnAnalogOther = 0x7, 42 | kHdaConfigDefaultConnMultiAnalog = 0x8, 43 | kHdaConfigDefaultConnXLR = 0x9, 44 | kHdaConfigDefaultConnRJ11 = 0xA, 45 | kHdaConfigDefaultConnCombo = 0xB, 46 | kHdaConfigDefaultConnOther = 0xF, 47 | }; 48 | 49 | enum 50 | { 51 | kHdaConfigDefaultDeviceLineOut = 0x0, 52 | kHdaConfigDefaultDeviceSpeaker = 0x1, 53 | kHdaConfigDefaultDeviceHeadphoneOut = 0x2, 54 | kHdaConfigDefaultDeviceCD = 0x3, 55 | kHdaConfigDefaultDeviceSPDIFOut = 0x4, 56 | kHdaConfigDefaultDeviceOtherDigitalOut = 0x5, 57 | kHdaConfigDefaultDeviceModemLine = 0x6, 58 | kHdaConfigDefaultDeviceModemHandset = 0x7, 59 | kHdaConfigDefaultDeviceLineIn = 0x8, 60 | kHdaConfigDefaultDeviceAux = 0x9, 61 | kHdaConfigDefaultDeviceMicIn = 0xA, 62 | kHdaConfigDefaultDeviceTelephony = 0xB, 63 | kHdaConfigDefaultDeviceSPDIFIn = 0xC, 64 | kHdaConfigDefaultDeviceOtherDigitalIn = 0xD, 65 | kHdaConfigDefaultDeviceOther = 0xF, 66 | }; 67 | 68 | enum 69 | { 70 | kHdaConfigDefaultLocSpecNA = 0x0, 71 | kHdaConfigDefaultLocSpecRear = 0x1, 72 | kHdaConfigDefaultLocSpecFront = 0x2, 73 | kHdaConfigDefaultLocSpecLeft = 0x3, 74 | kHdaConfigDefaultLocSpecRight = 0x4, 75 | kHdaConfigDefaultLocSpecTop = 0x5, 76 | kHdaConfigDefaultLocSpecBottom = 0x6, 77 | kHdaConfigDefaultLocSpecSpecial7 = 0x7, 78 | kHdaConfigDefaultLocSpecSpecial8 = 0x8, 79 | kHdaConfigDefaultLocSpecSpecial9 = 0x9, 80 | 81 | }; 82 | 83 | enum 84 | { 85 | kHdaConfigDefaultLocSurfExternal = 0x0, 86 | kHdaConfigDefaultLocSurfRearPanel = 0x0, 87 | kHdaConfigDefaultLocSurfDriveBay = 0x0, 88 | kHdaConfigDefaultLocSurfInternal = 0x1, 89 | kHdaConfigDefaultLocSurfRiser = 0x1, 90 | kHdaConfigDefaultLocSurfDigitalDisplay = 0x1, 91 | kHdaConfigDefaultLocSurfATAPI = 0x1, 92 | kHdaConfigDefaultLocSurfSeparate = 0x2, 93 | kHdaConfigDefaultLocSurfSpecial = 0x2, 94 | kHdaConfigDefaultLocSurfOther = 0x3, 95 | kHdaConfigDefaultLocSurfMobileLidInside = 0x3, 96 | kHdaConfigDefaultLocSurfMobileLidOutside = 0x3, 97 | }; 98 | 99 | enum 100 | { 101 | kHdaConfigDefaultPortConnJack = 0x0, 102 | kHdaConfigDefaultPortConnNone = 0x1, 103 | kHdaConfigDefaultPortConnFixedDevice = 0x2, 104 | kHdaConfigDefaultPortConnIntJack = 0x3, 105 | }; 106 | 107 | enum 108 | { 109 | kHdaWidgetTypeOutput = 0x0, 110 | kHdaWidgetTypeInput = 0x1, 111 | kHdaWidgetTypeMixer = 0x2, 112 | kHdaWidgetTypeSelector = 0x3, 113 | kHdaWidgetTypePinComplex = 0x4, 114 | kHdaWidgetTypePower = 0x5, 115 | kHdaWidgetTypeVolumeKnob = 0x6, 116 | kHdaWidgetTypeBeepGen = 0x7, 117 | kHdaWidgetTypeVendor = 0xF, 118 | }; 119 | 120 | @interface AudioNode : NSObject 121 | { 122 | } 123 | 124 | - (id)initWithNid:(uint8_t)nid; 125 | - (id)initWithNid:(uint8_t)nid pinDefault:(uint32_t)pinDefault; 126 | - (void) setDefaults:(uint8_t)nid; 127 | - (void) dealloc; 128 | - (NSString *) description; 129 | - (uint32_t) pinDefault; 130 | - (NSString *) pinDefaultString; 131 | - (uint32_t) verb70C:(uint8_t)address; 132 | - (uint32_t) verb71C:(uint8_t)address; 133 | - (uint32_t) verb71D:(uint8_t)address; 134 | - (uint32_t) verb71E:(uint8_t)address; 135 | - (uint32_t) verb71F:(uint8_t)address; 136 | - (NSString *) wakeConfigString:(uint8_t)address; 137 | - (NSString *) pinConfigString:(uint8_t)address; 138 | - (void) updatePinDefault:(uint32_t)pinDefault; 139 | - (void) updatePinCommand:(uint32_t)command data:(uint8_t)data; 140 | - (NSComparisonResult) compareDevice:(AudioNode *)other; 141 | - (BOOL) isIn; 142 | - (BOOL) isOut; 143 | - (BOOL) isDigital; 144 | - (BOOL) hasJack; 145 | - (uint8_t) grossLocation; 146 | - (uint8_t) geometricLocation; 147 | - (void) setGrossLocation:(uint8_t)grossLocation; 148 | - (void) setGeometricLocation:(uint8_t)geometricLocation; 149 | - (NSColor *)jackColor; 150 | - (NSString *)directionString; 151 | 152 | @property (nonatomic) uint8_t nid; 153 | @property uint8_t port; 154 | @property uint8_t location; 155 | @property uint8_t device; 156 | @property uint8_t connector; 157 | @property uint8_t color; 158 | @property uint8_t misc; 159 | @property uint8_t group; 160 | @property uint8_t index; 161 | @property uint8_t eapd; 162 | //@property uint32_t pinCaps; 163 | @property (retain) NSString *name; 164 | @property (retain) NSString *nodeString; 165 | 166 | @end 167 | 168 | #endif 169 | -------------------------------------------------------------------------------- /PinConfigurator/AudioNode.m: -------------------------------------------------------------------------------- 1 | // 2 | // AudioNode.m 3 | // PinConfigurator 4 | // 5 | // Created by Ben Baker on 2/7/19. 6 | // Copyright © 2019 Ben Baker. All rights reserved. 7 | // 8 | 9 | #import "AudioNode.h" 10 | #import "NSString+Pin.h" 11 | #import "NSColor+Pin.h" 12 | #import "HdaVerbs.h" 13 | #import 14 | 15 | @implementation AudioNode 16 | 17 | - (id)init 18 | { 19 | self = [super init]; 20 | 21 | if (self) 22 | [self setDefaults:0]; 23 | 24 | return self; 25 | } 26 | 27 | - (id)initWithNid:(uint8_t)nID 28 | { 29 | self = [self init]; 30 | 31 | if (self) 32 | [self setDefaults:nID]; 33 | 34 | return self; 35 | } 36 | 37 | - (id)initWithNid:(uint8_t)nid pinDefault:(uint32_t)pinDefault 38 | { 39 | self = [self initWithNid:nid]; 40 | 41 | if (self) 42 | [self updatePinDefault:pinDefault]; 43 | 44 | return self; 45 | } 46 | 47 | - (void) setDefaults:(uint8_t)nid 48 | { 49 | [self setNid:nid]; 50 | self.name = nil; 51 | self.port = 4; 52 | self.location = 0; 53 | self.device = 0; 54 | self.connector = 0; 55 | self.color = 0; 56 | self.misc = 0; 57 | self.group = 0xF; 58 | self.index = 0; 59 | self.eapd = 0; 60 | } 61 | 62 | - (void) dealloc 63 | { 64 | [_name release]; 65 | [_nodeString release]; 66 | 67 | [super dealloc]; 68 | } 69 | 70 | - (id)copyWithZone:(nullable NSZone *)zone 71 | { 72 | AudioNode *audioNode = [[AudioNode alloc] initWithNid:_nid]; 73 | 74 | [audioNode setName:_name]; 75 | [audioNode setPort:_port]; 76 | [audioNode setLocation:_location]; 77 | [audioNode setDevice:_device]; 78 | [audioNode setConnector:_connector]; 79 | [audioNode setColor:_color]; 80 | [audioNode setMisc:_misc]; 81 | [audioNode setGroup:_group]; 82 | [audioNode setIndex:_index]; 83 | [audioNode setEapd:_eapd]; 84 | [audioNode setNodeString:_nodeString]; 85 | 86 | return audioNode; 87 | } 88 | 89 | - (NSString *) description 90 | { 91 | NSString *direction = (_device <= 5 ? @"[Out]" : @" [In]"); 92 | NSString *color = [NSString pinColor:_color]; 93 | NSString *connector = [NSString pinConnector:_connector]; 94 | NSString *port = [NSString pinPort:_port]; 95 | NSString *location = [NSString pinLocation:[self grossLocation] geometricLocation:[self geometricLocation]]; 96 | NSString *defaultDevice = [NSString pinDefaultDevice:_device]; 97 | NSString *pinDefault = [self pinDefaultString]; 98 | return [NSString stringWithFormat:@"%@ %@ 0x%@ %@, %@, %@, %@, %@, %d.%d", _name, direction, pinDefault, defaultDevice, location, port, connector, color, _group, _index]; 99 | } 100 | 101 | - (uint32_t) pinDefault 102 | { 103 | return ((_port << 30) | (_location << 24) | (_device << 20) | (_connector << 16) | (_color << 12) | (_misc << 8) | (_group << 4) | _index); 104 | } 105 | 106 | - (NSString *) pinDefaultString 107 | { 108 | return [NSString stringWithFormat:@"%08X", [self pinDefault]]; 109 | } 110 | 111 | - (uint32_t) verb70C:(uint8_t)address 112 | { 113 | return (((address & 0xF) << 28) | ((_nid & 0xFF) << 20) | (0x70C << 8) | (_eapd & 0x3)); 114 | } 115 | 116 | - (uint32_t) verb71C:(uint8_t)address 117 | { 118 | return (((address & 0xF) << 28) | ((_nid & 0xFF) << 20) | (0x71C << 8) | ((_group & 0xF) << 4) | (_index & 0xF)); 119 | } 120 | 121 | - (uint32_t) verb71D:(uint8_t)address 122 | { 123 | return (((address & 0xF) << 28) | ((_nid & 0xFF) << 20) | (0x71D << 8) | ((_color & 0xF) << 4) | (_misc & 0xF)); 124 | } 125 | 126 | - (uint32_t) verb71E:(uint8_t)address 127 | { 128 | return (((address & 0xF) << 28) | ((_nid & 0xFF) << 20) | (0x71E << 8) | ((_device & 0xF) << 4) | (_connector & 0xF)); 129 | } 130 | 131 | - (uint32_t) verb71F:(uint8_t)address 132 | { 133 | return (((address & 0xF) << 28) | ((_nid & 0xFF) << 20) | (0x71F << 8) | ((_port & 0x3) << 6) | (_location & 0x3F)); 134 | } 135 | 136 | - (NSString *) wakeConfigString:(uint8_t)address 137 | { 138 | return [NSString stringWithFormat:@" %08X", [self verb70C:address]]; 139 | } 140 | 141 | - (NSString *) pinConfigString:(uint8_t)address 142 | { 143 | NSString *configString = [NSString stringWithFormat:@"%08X %08X %08X %08X", [self verb71C:address], [self verb71D:address], [self verb71E:address], [self verb71F:address]]; 144 | 145 | if (_eapd & HDA_EAPD_BTL_ENABLE_EAPD) 146 | configString = [configString stringByAppendingString:[self wakeConfigString:address]]; 147 | 148 | return configString; 149 | } 150 | 151 | - (void) updatePinDefault:(uint32_t)pinDefault 152 | { 153 | _index = pinDefault & 0xF; 154 | _group = (pinDefault >> 4) & 0xF; 155 | _misc = (pinDefault >> 8) & 0xF; 156 | _color = (pinDefault >> 12) & 0xF; 157 | _connector = (pinDefault >> 16) & 0xF; 158 | _device = (pinDefault >> 20) & 0xF; 159 | _location = (pinDefault >> 24) & 0x3F; 160 | _port = (pinDefault >> 30) & 0x3; 161 | } 162 | 163 | - (void) updatePinCommand:(uint32_t)command data:(uint8_t)data 164 | { 165 | switch(command) 166 | { 167 | case 0x71C: 168 | _group = HINIBBLE(data); 169 | _index = LONIBBLE(data); 170 | break; 171 | case 0x71D: 172 | _color = HINIBBLE(data); 173 | _misc = LONIBBLE(data); 174 | break; 175 | case 0x71E: 176 | _device = HINIBBLE(data); 177 | _connector = LONIBBLE(data); 178 | break; 179 | case 0x71F: 180 | _port = (data >> 6) & 0x3; 181 | _location = data & 0x3F; 182 | break; 183 | } 184 | } 185 | 186 | - (NSComparisonResult) compareDevice:(AudioNode *)other 187 | { 188 | int result = [self group] - [other group]; 189 | 190 | if (result == 0) 191 | result = [self index] - [other index]; 192 | 193 | if (result == 0) 194 | return NSOrderedSame; 195 | 196 | return (result < 0 ? NSOrderedAscending : NSOrderedDescending); 197 | } 198 | 199 | - (void) setNid:(uint8_t)nid 200 | { 201 | _nid = nid; 202 | [self setNodeString:[NSString stringWithFormat:@"%02d (0x%02X)", _nid, _nid]]; 203 | } 204 | 205 | - (BOOL) isIn 206 | { 207 | return (_device > kHdaConfigDefaultDeviceModemHandset && _device <= kHdaConfigDefaultDeviceOtherDigitalIn); 208 | } 209 | 210 | - (BOOL) isOut 211 | { 212 | return (_device <= kHdaConfigDefaultDeviceModemHandset); 213 | } 214 | 215 | - (BOOL) isDigital 216 | { 217 | return (_device == kHdaConfigDefaultDeviceSPDIFOut || _device == kHdaConfigDefaultDeviceOtherDigitalOut || _device == kHdaConfigDefaultDeviceSPDIFIn || _device == kHdaConfigDefaultDeviceOtherDigitalIn); 218 | } 219 | 220 | - (BOOL) hasJack 221 | { 222 | return ([self geometricLocation] == 1 || [self geometricLocation] == 2); 223 | } 224 | 225 | - (uint8_t) grossLocation 226 | { 227 | return (_location >> 4) & 0x3; 228 | } 229 | 230 | - (uint8_t) geometricLocation 231 | { 232 | return (_location & 0xF); 233 | } 234 | 235 | - (void) setGrossLocation:(uint8_t)grossLocation 236 | { 237 | _location = ((grossLocation & 0x3) << 4) | (_location & 0xF); 238 | } 239 | 240 | - (void) setGeometricLocation:(uint8_t)geometricLocation 241 | { 242 | _location = (_location & 0x30) | (geometricLocation & 0xF); 243 | } 244 | 245 | - (NSColor *)jackColor 246 | { 247 | return [NSColor pinColor:_color]; 248 | } 249 | 250 | - (NSString *)directionString 251 | { 252 | return [NSString pinDirection:_device]; 253 | } 254 | 255 | @end 256 | -------------------------------------------------------------------------------- /PinConfigurator/Base.lproj/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf400 2 | {\fonttbl\f0\fswiss\fcharset0 Helvetica;} 3 | {\colortbl;\red255\green255\blue255;\red0\green0\blue0;} 4 | {\*\expandedcolortbl;;\cssrgb\c0\c0\c0\cname textColor;} 5 | {\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1} 6 | {\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid101\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid2}} 7 | {\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}} 8 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 9 | 10 | \f0\fs24 \cf2 Original by:\ 11 | saxmms\ 12 | \ 13 | Version 2 by:\ 14 | headkaze\ 15 | \ 16 | Credits:\ 17 | \pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 18 | \ls1\ilvl0\cf2 {\listtext \uc0\u8226 }HDA controllers / codec lists by the VoodooHDA project\ 19 | {\listtext \uc0\u8226 }GetDumpXml code by Alejandro\ 20 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 21 | \cf2 \ 22 | Thanks:\ 23 | \pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\pardirnatural\partightenfactor0 24 | \ls2\ilvl0\cf2 {\listtext \uc0\u8226 }ctich, Rodion2010, insanelyDeepak, Slice\ 25 | {\listtext \uc0\u8226 }{\field{\*\fldinst{HYPERLINK "https://applelife.ru/"}}{\fldrslt \cf0 AppleLife.ru}}, {\field{\*\fldinst{HYPERLINK "https://www.insanelymac.com/"}}{\fldrslt \cf0 InsanelyMac.com}} & {\field{\*\fldinst{HYPERLINK "https://www.tonymacx86.com/"}}{\fldrslt \cf0 tonymacx86.com}}\ 26 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 27 | \cf2 \ 28 | Website:\ 29 | {\field{\*\fldinst{HYPERLINK "http://headsoft.com.au/"}}{\fldrslt \cf0 headsoft.com.au}}\ 30 | } -------------------------------------------------------------------------------- /PinConfigurator/HdaCodec.h: -------------------------------------------------------------------------------- 1 | // 2 | // HdaCodec.h 3 | // PinConfigurator 4 | // 5 | // Created by Ben Baker on 2/16/19. 6 | // Copyright © 2019 Ben Baker. All rights reserved. 7 | // 8 | 9 | #ifndef HdaCodec_h 10 | #define HdaCodec_h 11 | 12 | #import 13 | #import 14 | 15 | #define HDA_PARSE_MAXDEPTH 10 16 | #define HDA_MAX_CONNS 32 17 | #define HDA_MAX_NAMELEN 32 18 | 19 | @interface HdaWidget : NSObject 20 | { 21 | } 22 | 23 | - (id)initWithNodeID:(uint8_t)nodeID; 24 | - (NSString *)typeString; 25 | - (uint32_t)type; 26 | - (BOOL)isStereo; 27 | - (BOOL)isDigital; 28 | - (BOOL)isAmpIn; 29 | - (BOOL)isAmpOut; 30 | - (BOOL)isLRSwap; 31 | - (BOOL) hasConnectionList; 32 | - (NSString *)defaultPortConnectionString; 33 | - (uint32_t)defaultPortConnection; 34 | - (NSString *)defaultDeviceString; 35 | - (uint32_t)defaultDevice; 36 | - (NSString *)defaultSurfaceString; 37 | - (uint32_t)defaultSurface; 38 | - (NSString *)defaultLocationString; 39 | - (uint32_t)defaultLocation; 40 | - (NSString *)defaultConnectionTypeString; 41 | - (uint32_t)defaultConnectionType; 42 | - (NSString *)defaultColorString; 43 | - (uint32_t)defaultColor; 44 | - (uint8_t)defaultAssociation; 45 | - (uint8_t)defaultSequence; 46 | - (NSString *)capabilitiesString; 47 | - (NSString *)controlString; 48 | - (NSString *)eapdString; 49 | - (BOOL) hasImpendance; 50 | - (BOOL) hasTrigger; 51 | - (BOOL) hasPresence; 52 | - (BOOL) hasHeadphone; 53 | - (BOOL) hasOutput; 54 | - (BOOL) hasInput; 55 | - (BOOL) hasBalanced; 56 | - (BOOL) hasHDMI; 57 | - (BOOL) hasEAPD; 58 | - (BOOL) hasDisplayPort; 59 | - (BOOL) hasHBR; 60 | - (BOOL) isInputDevice; 61 | - (BOOL) isOutputDevice; 62 | - (BOOL) isEnabled; 63 | - (void) dealloc; 64 | 65 | @property uint8_t nodeID; 66 | @property (retain) NSString *name; 67 | @property uint32_t capabilities; 68 | @property uint8_t defaultUnSol; 69 | @property uint8_t defaultEapd; 70 | @property (retain) NSMutableArray *connections; 71 | @property uint32_t supportedPowerStates; 72 | @property uint32_t defaultPowerState; 73 | @property uint32_t ampInCapabilities; 74 | @property uint32_t ampOutCapabilities; 75 | @property (retain) NSMutableArray *ampInLeftDefaultGainMute; 76 | @property (retain) NSMutableArray *ampInRightDefaultGainMute; 77 | @property uint8_t ampOutLeftDefaultGainMute; 78 | @property uint8_t ampOutRightDefaultGainMute; 79 | @property uint32_t supportedPcmRates; 80 | @property uint32_t supportedFormats; 81 | @property uint16_t defaultConvFormat; 82 | @property uint8_t defaultConvStreamChannel; 83 | @property uint8_t defaultConvChannelCount; 84 | @property uint32_t pinCapabilities; 85 | @property uint8_t defaultPinControl; 86 | @property uint32_t defaultConfiguration; 87 | @property uint32_t volumeCapabilities; 88 | @property uint8_t defaultVolume; 89 | @property uint32_t bindAssoc; 90 | @property uint32_t bindSeqMask; 91 | @property uint8_t connectionSelect; 92 | 93 | @end 94 | 95 | @interface HdaCodec : NSObject 96 | { 97 | } 98 | 99 | - (id) initWithName:(NSString *)name audioFuncID:(uint32_t)audioFuncID unsol:(uint32_t)unsol vendorID:(uint32_t)vendorID revisionID:(uint32_t)revisionID rates:(uint32_t)rates formats:(uint32_t)formats ampInCaps:(uint32_t)ampInCaps ampOutCaps:(uint32_t)ampOutCaps; 100 | - (void) dealloc; 101 | - (NSString *) sampleRatesString; 102 | - (NSString *) bitRatesString; 103 | - (NSString *) streamFormatString; 104 | - (NSString *) ampCapsString:(uint32_t)ampCaps; 105 | - (NSMutableString *)codecString; 106 | + (bool)getHdaCodecArray_Linux:(NSString *)hdaCodecString hdaCodecArray:(NSMutableArray **)hdaCodecArray; 107 | + (bool)parseHdaCodecString_Linux:(NSString *)hdaCodecString index:(uint32_t)index hdaCodec:(HdaCodec *)hdaCodec; 108 | + (uint32_t)parseHdaCodecString:(NSString *)hdaCodecString index:(uint32_t)index hdaCodec:(HdaCodec **)hdaCodec hdaCodecArray:(NSMutableArray **)hdaCodecArray; 109 | + (bool)parseHdaCodecData:(uint8_t *)hdaCodecData length:(uint32_t)length hdaCodec:(HdaCodec **)hdaCodec; 110 | + (bool)getWidget:(NSArray *)widgets nodeID:(uint8_t)nodeID hdaWidget:(HdaWidget **)hdaWidget; 111 | + (void)createPlatformsXml:(HdaCodec *)hdaCodec; 112 | 113 | @property (retain) NSString *name; 114 | @property uint32_t address; 115 | @property uint32_t audioFuncID; 116 | @property uint32_t unsol; 117 | @property uint32_t vendorID; 118 | @property uint32_t revisionID; 119 | @property uint32_t rates; 120 | @property uint32_t formats; 121 | @property uint32_t ampInCaps; 122 | @property uint32_t ampOutCaps; 123 | @property (retain) NSMutableArray *widgets; 124 | 125 | @end 126 | 127 | #endif /* HdaCodec_h */ 128 | -------------------------------------------------------------------------------- /PinConfigurator/HdaCodec.m: -------------------------------------------------------------------------------- 1 | // 2 | // HdaCodec.m 3 | // PinConfigurator 4 | // 5 | // Created by Ben Baker on 2/16/19. 6 | // Copyright © 2019 Ben Baker. All rights reserved. 7 | // 8 | 9 | #import "HdaCodec.h" 10 | #import "HdaCodecDump.h" 11 | #import "MiscTools.h" 12 | 13 | @implementation HdaWidget 14 | 15 | -(id) initWithNodeID:(uint8_t)nodeID 16 | { 17 | if (self = [super init]) 18 | { 19 | self.nodeID = nodeID; 20 | self.bindAssoc = -1; 21 | self.bindSeqMask = 0x0; 22 | self.connectionSelect = -1; 23 | } 24 | 25 | return self; 26 | } 27 | 28 | - (void)dealloc 29 | { 30 | [_name release]; 31 | [_connections release]; 32 | [_ampInLeftDefaultGainMute release]; 33 | [_ampInRightDefaultGainMute release]; 34 | 35 | [super dealloc]; 36 | } 37 | 38 | - (NSString *)typeString 39 | { 40 | NSArray *typeArray = @[@"Audio Output", @"Audio Input", @"Audio Mixer", 41 | @"Audio Selector", @"Pin Complex", @"Power Widget", 42 | @"Volume Knob Widget", @"Beep Generator Widget", 43 | @"Reserved", @"Reserved", @"Reserved", @"Reserved", 44 | @"Reserved", @"Reserved", @"Reserved", 45 | @"Vendor Defined Widget"]; 46 | 47 | return typeArray[[self type]]; 48 | } 49 | 50 | - (uint32_t)type 51 | { 52 | return HDA_PARAMETER_WIDGET_CAPS_TYPE(_capabilities); 53 | } 54 | 55 | - (BOOL)isStereo 56 | { 57 | return (_capabilities & HDA_PARAMETER_WIDGET_CAPS_STEREO) != 0; 58 | } 59 | 60 | - (BOOL)isDigital 61 | { 62 | return (_capabilities & HDA_PARAMETER_WIDGET_CAPS_DIGITAL) != 0; 63 | } 64 | 65 | - (BOOL)isAmpIn 66 | { 67 | return (_capabilities & HDA_PARAMETER_WIDGET_CAPS_IN_AMP) != 0; 68 | } 69 | 70 | - (BOOL)isAmpOut 71 | { 72 | return (_capabilities & HDA_PARAMETER_WIDGET_CAPS_OUT_AMP) != 0; 73 | } 74 | 75 | - (BOOL)isLRSwap 76 | { 77 | return (_capabilities & HDA_PARAMETER_WIDGET_CAPS_L_R_SWAP) != 0; 78 | } 79 | 80 | - (BOOL) hasConnectionList 81 | { 82 | return (_capabilities & HDA_PARAMETER_WIDGET_CAPS_CONN_LIST) != 0; 83 | } 84 | 85 | - (NSString *)defaultPortConnectionString 86 | { 87 | NSArray *portConnectionArray = @[@"Jack", @"None", @"Fixed", @"Int Jack"]; 88 | 89 | return portConnectionArray[[self defaultPortConnection]]; 90 | } 91 | 92 | - (uint32_t)defaultPortConnection 93 | { 94 | return HDA_VERB_GET_CONFIGURATION_DEFAULT_PORT_CONN(_defaultConfiguration); 95 | } 96 | 97 | - (NSString *)defaultDeviceString 98 | { 99 | NSArray *defaultDeviceArray = @[@"Line Out", @"Speaker", @"HP Out", @"CD", @"SPDIF Out", 100 | @"Digital Out", @"Modem Line", @"Modem Handset", @"Line In", @"Aux", 101 | @"Mic", @"Telephone", @"SPDIF In", @"Digital In", @"Reserved", @"Other"]; 102 | 103 | return defaultDeviceArray[[self defaultDevice]]; 104 | } 105 | 106 | - (uint32_t)defaultDevice 107 | { 108 | return HDA_VERB_GET_CONFIGURATION_DEFAULT_DEVICE(_defaultConfiguration); 109 | } 110 | 111 | - (NSString *)defaultSurfaceString 112 | { 113 | NSArray *surfaceArray = @[@"Ext", @"Int", @"Ext", @"Other"]; 114 | 115 | return surfaceArray[[self defaultSurface]]; 116 | } 117 | 118 | - (uint32_t)defaultSurface 119 | { 120 | return HDA_VERB_GET_CONFIGURATION_DEFAULT_SURF(_defaultConfiguration); 121 | } 122 | 123 | - (NSString *)defaultLocationString 124 | { 125 | NSArray *locationArray = @[@"N/A", @"Rear", @"Front", @"Left", @"Right", @"Top", @"Bottom", @"Special", 126 | @"Special", @"Special", @"Reserved", @"Reserved", @"Reserved", @"Reserved"]; 127 | 128 | return locationArray[[self defaultLocation]]; 129 | } 130 | 131 | - (uint32_t)defaultLocation 132 | { 133 | return HDA_VERB_GET_CONFIGURATION_DEFAULT_LOC(_defaultConfiguration); 134 | } 135 | 136 | - (NSString *)defaultConnectionTypeString 137 | { 138 | NSArray *connectionTypeArray = @[@"Unknown", @"1/8", @"1/4", @"ATAPI", @"RCA", @"Optical", @"Digital", 139 | @"Analog", @"Multi", @"XLR", @"RJ11", @"Combo", @"Other", @"Other", @"Other", @"Other"]; 140 | 141 | return connectionTypeArray[[self defaultConnectionType]]; 142 | } 143 | 144 | - (uint32_t)defaultConnectionType 145 | { 146 | return HDA_VERB_GET_CONFIGURATION_DEFAULT_CONN_TYPE(_defaultConfiguration); 147 | } 148 | 149 | - (NSString *)defaultColorString 150 | { 151 | NSArray *colorArray = @[@"Unknown", @"Black", @"Grey", @"Blue", @"Green", @"Red", @"Orange", 152 | @"Yellow", @"Purple", @"Pink", @"Reserved", @"Reserved", @"Reserved", 153 | @"Reserved", @"White", @"Other"]; 154 | 155 | return colorArray[[self defaultColor]]; 156 | } 157 | 158 | - (uint32_t)defaultColor 159 | { 160 | return HDA_VERB_GET_CONFIGURATION_DEFAULT_COLOR(_defaultConfiguration); 161 | } 162 | 163 | - (uint8_t)defaultAssociation 164 | { 165 | return HDA_VERB_GET_CONFIGURATION_DEFAULT_ASSOCIATION(_defaultConfiguration); 166 | } 167 | 168 | - (uint8_t)defaultSequence 169 | { 170 | return HDA_VERB_GET_CONFIGURATION_DEFAULT_SEQUENCE(_defaultConfiguration); 171 | } 172 | 173 | - (NSString *)capabilitiesString 174 | { 175 | NSMutableString *outputString = [NSMutableString string]; 176 | 177 | if ([self isStereo]) 178 | [outputString appendFormat:@" Stereo"]; 179 | else 180 | [outputString appendFormat:@" Mono"]; 181 | if ([self isDigital]) 182 | [outputString appendFormat:@" Digital"]; 183 | if ([self isAmpIn]) 184 | [outputString appendFormat:@" Amp-In"]; 185 | if ([self isAmpOut]) 186 | [outputString appendFormat:@" Amp-Out"]; 187 | if ([self isLRSwap]) 188 | [outputString appendFormat:@" R/L"]; 189 | 190 | return outputString; 191 | } 192 | 193 | - (NSString *)controlString 194 | { 195 | NSMutableString *outputString = [NSMutableString string]; 196 | 197 | if (_defaultPinControl & HDA_PIN_WIDGET_CONTROL_VREF_EN) 198 | [outputString appendFormat:@" VREF"]; 199 | if (_defaultPinControl & HDA_PIN_WIDGET_CONTROL_IN_EN) 200 | [outputString appendFormat:@" IN"]; 201 | if (_defaultPinControl & HDA_PIN_WIDGET_CONTROL_OUT_EN) 202 | [outputString appendFormat:@" OUT"]; 203 | if (_defaultPinControl & HDA_PIN_WIDGET_CONTROL_HP_EN) 204 | [outputString appendFormat:@" HP"]; 205 | 206 | return outputString; 207 | } 208 | 209 | - (NSString *)pinCapString 210 | { 211 | NSMutableString *outputString = [NSMutableString string]; 212 | 213 | if ([self hasInput]) 214 | [outputString appendFormat:@" IN"]; 215 | if ([self hasOutput]) 216 | [outputString appendFormat:@" OUT"]; 217 | if ([self hasHeadphone]) 218 | [outputString appendFormat:@" HP"]; 219 | if ([self hasEAPD]) 220 | [outputString appendFormat:@" EAPD"]; 221 | if ([self hasTrigger]) 222 | [outputString appendFormat:@" Trigger"]; 223 | if ([self hasPresence]) 224 | [outputString appendFormat:@" Detect"]; 225 | if ([self hasHBR]) 226 | [outputString appendFormat:@" HBR"]; 227 | if ([self hasHDMI]) 228 | [outputString appendFormat:@" HDMI"]; 229 | if ([self hasDisplayPort]) 230 | [outputString appendFormat:@" DP"]; 231 | 232 | return outputString; 233 | } 234 | 235 | - (NSString *)eapdString 236 | { 237 | NSMutableString *outputString = [NSMutableString string]; 238 | 239 | if (_defaultEapd & HDA_EAPD_BTL_ENABLE_BTL) 240 | [outputString appendFormat:@" BTL"]; 241 | if (_defaultEapd & HDA_EAPD_BTL_ENABLE_EAPD) 242 | [outputString appendFormat:@" EAPD"]; 243 | if (_defaultEapd & HDA_EAPD_BTL_ENABLE_L_R_SWAP) 244 | [outputString appendFormat:@" R/L"]; 245 | 246 | return outputString; 247 | } 248 | 249 | - (BOOL) hasImpendance 250 | { 251 | return (_pinCapabilities & HDA_PARAMETER_PIN_CAPS_IMPEDANCE) != 0; 252 | } 253 | 254 | - (BOOL) hasTrigger 255 | { 256 | return (_pinCapabilities & HDA_PARAMETER_PIN_CAPS_TRIGGER) != 0; 257 | } 258 | 259 | - (BOOL) hasPresence 260 | { 261 | return (_pinCapabilities & HDA_PARAMETER_PIN_CAPS_PRESENCE) != 0; 262 | } 263 | 264 | - (BOOL) hasHeadphone 265 | { 266 | return (_pinCapabilities & HDA_PARAMETER_PIN_CAPS_HEADPHONE) != 0; 267 | } 268 | 269 | - (BOOL) hasOutput 270 | { 271 | return (_pinCapabilities & HDA_PARAMETER_PIN_CAPS_OUTPUT) != 0; 272 | } 273 | 274 | - (BOOL) hasInput 275 | { 276 | return (_pinCapabilities & HDA_PARAMETER_PIN_CAPS_INPUT) != 0; 277 | } 278 | 279 | - (BOOL) hasBalanced 280 | { 281 | return (_pinCapabilities & HDA_PARAMETER_PIN_CAPS_BALANCED) != 0; 282 | } 283 | 284 | - (BOOL) hasHDMI 285 | { 286 | return (_pinCapabilities & HDA_PARAMETER_PIN_CAPS_HDMI) != 0; 287 | } 288 | 289 | - (BOOL) hasEAPD 290 | { 291 | return (_pinCapabilities & HDA_PARAMETER_PIN_CAPS_EAPD) != 0; 292 | } 293 | 294 | - (BOOL) hasDisplayPort 295 | { 296 | return (_pinCapabilities & HDA_PARAMETER_PIN_CAPS_DISPLAYPORT) != 0; 297 | } 298 | 299 | - (BOOL) hasHBR 300 | { 301 | return (_pinCapabilities & HDA_PARAMETER_PIN_CAPS_HBR) != 0; 302 | } 303 | 304 | - (BOOL) isInputDevice 305 | { 306 | return ([self defaultDevice] > 7 && [self defaultDevice] <= 0xD); 307 | } 308 | 309 | - (BOOL) isOutputDevice 310 | { 311 | return ([self defaultDevice] <= 7); 312 | } 313 | 314 | - (BOOL) isEnabled 315 | { 316 | if ([self type] == HDA_WIDGET_TYPE_POWER || [self type] == HDA_WIDGET_TYPE_VOLUME_KNOB) 317 | return false; 318 | 319 | if ([self type] != HDA_WIDGET_TYPE_PIN_COMPLEX || [self defaultPortConnection] == HDA_CONFIG_DEFAULT_PORT_CONN_NONE || [self defaultAssociation] == 0) 320 | return false; 321 | 322 | return true; 323 | } 324 | 325 | @end 326 | 327 | @implementation HdaCodec 328 | 329 | - (id) initWithName:(NSString *)name audioFuncID:(uint32_t)audioFuncID unsol:(uint32_t)unsol vendorID:(uint32_t)vendorID revisionID:(uint32_t)revisionID rates:(uint32_t)rates formats:(uint32_t)formats ampInCaps:(uint32_t)ampInCaps ampOutCaps:(uint32_t)ampOutCaps 330 | { 331 | if (self = [super init]) 332 | { 333 | self.name = name; 334 | self.audioFuncID = audioFuncID; 335 | self.unsol = unsol; 336 | self.vendorID = vendorID; 337 | self.revisionID = revisionID; 338 | self.rates = rates; 339 | self.formats = formats; 340 | self.ampInCaps = ampInCaps; 341 | self.ampOutCaps = ampOutCaps; 342 | } 343 | 344 | return self; 345 | } 346 | 347 | - (void)dealloc 348 | { 349 | [_name release]; 350 | [_widgets release]; 351 | 352 | [super dealloc]; 353 | } 354 | 355 | - (NSString *) sampleRatesString 356 | { 357 | NSMutableString *outputString = [NSMutableString string]; 358 | 359 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_8KHZ) 360 | [outputString appendFormat:@" 8000"]; 361 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_11KHZ) 362 | [outputString appendFormat:@" 11025"]; 363 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_16KHZ) 364 | [outputString appendFormat:@" 16000"]; 365 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_22KHZ) 366 | [outputString appendFormat:@" 22050"]; 367 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_32KHZ) 368 | [outputString appendFormat:@" 32000"]; 369 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_44KHZ) 370 | [outputString appendFormat:@" 44100"]; 371 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_48KHZ) 372 | [outputString appendFormat:@" 48000"]; 373 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_88KHZ) 374 | [outputString appendFormat:@" 88200"]; 375 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_96KHZ) 376 | [outputString appendFormat:@" 96000"]; 377 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_176KHZ) 378 | [outputString appendFormat:@" 176400"]; 379 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_192KHZ) 380 | [outputString appendFormat:@" 192000"]; 381 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_384KHZ) 382 | [outputString appendFormat:@" 384000"]; 383 | 384 | return outputString; 385 | } 386 | 387 | - (NSString *) bitRatesString 388 | { 389 | NSMutableString *outputString = [NSMutableString string]; 390 | 391 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_8BIT) 392 | [outputString appendFormat:@" 8"]; 393 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_16BIT) 394 | [outputString appendFormat:@" 16"]; 395 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_20BIT) 396 | [outputString appendFormat:@" 20"]; 397 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_24BIT) 398 | [outputString appendFormat:@" 24"]; 399 | if (_rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_32BIT) 400 | [outputString appendFormat:@" 32"]; 401 | 402 | return outputString; 403 | } 404 | 405 | - (NSString *) streamFormatString 406 | { 407 | NSMutableString *outputString = [NSMutableString string]; 408 | 409 | if (_formats & HDA_PARAMETER_SUPPORTED_STREAM_FORMATS_PCM) 410 | [outputString appendFormat:@" PCM"]; 411 | if (_formats & HDA_PARAMETER_SUPPORTED_STREAM_FORMATS_FLOAT32) 412 | [outputString appendFormat:@" FLOAT32"]; 413 | if (_formats & HDA_PARAMETER_SUPPORTED_STREAM_FORMATS_AC3) 414 | [outputString appendFormat:@" AC3"]; 415 | 416 | return outputString; 417 | } 418 | 419 | - (NSString *) ampCapsString:(uint32_t)ampCaps 420 | { 421 | if (!ampCaps) 422 | return @"N/A"; 423 | 424 | return [NSString stringWithFormat:@"ofs=0x%02X, nsteps=0x%02X, stepsize=0x%02X, mute=%u", 425 | HDA_PARAMETER_AMP_CAPS_OFFSET(ampCaps), HDA_PARAMETER_AMP_CAPS_NUM_STEPS(ampCaps), 426 | HDA_PARAMETER_AMP_CAPS_STEP_SIZE(ampCaps), (ampCaps & HDA_PARAMETER_AMP_CAPS_MUTE) != 0]; 427 | } 428 | 429 | - (NSMutableString *)codecString 430 | { 431 | // https://github.com/Digilent/linux-Digilent-Dev/blob/master/sound/pci/hda/hda_proc.c 432 | 433 | NSMutableString *outputString = [NSMutableString string]; 434 | 435 | [outputString appendFormat:@"HdaCodecDump Start\n"]; 436 | [outputString appendFormat:@"Codec: %@\n", _name]; 437 | [outputString appendFormat:@"Address: %d\n", _address]; 438 | [outputString appendFormat:@"AFG Function Id: 0x%02X (unsol %u)\n", _audioFuncID, _unsol]; 439 | [outputString appendFormat:@"Vendor ID: 0x%08X\n", _vendorID]; 440 | [outputString appendFormat:@"Revision ID: 0x%08X\n", _revisionID]; 441 | 442 | if ((_rates != 0) || (_formats != 0)) 443 | { 444 | [outputString appendFormat:@"Default PCM:\n"]; 445 | [outputString appendFormat:@" rates [0x%04X]:", (uint16_t)_rates]; 446 | [outputString appendFormat:@"%@\n", [self sampleRatesString]]; 447 | 448 | [outputString appendFormat:@" bits [0x%04X]:", (uint16_t)(_rates >> 16)]; 449 | [outputString appendFormat:@"%@\n", [self bitRatesString]]; 450 | 451 | [outputString appendFormat:@" formats [0x%08X]:", _formats]; 452 | [outputString appendFormat:@"%@\n", [self streamFormatString]]; 453 | } 454 | else 455 | [outputString appendFormat:@"Default PCM: N/A\n"]; 456 | 457 | [outputString appendFormat:@"Default Amp-In caps: "]; 458 | [outputString appendFormat:@"%@\n", [self ampCapsString:_ampInCaps]]; 459 | [outputString appendFormat:@"Default Amp-Out caps: "]; 460 | [outputString appendFormat:@"%@\n", [self ampCapsString:_ampOutCaps]]; 461 | 462 | for (HdaWidget *hdaWidget in _widgets) 463 | { 464 | [outputString appendFormat:@"Node 0x%02X [%@] wcaps 0x%08X:", hdaWidget.nodeID, hdaWidget.typeString, hdaWidget.capabilities]; 465 | [outputString appendFormat:@"%@\n", [hdaWidget capabilitiesString]]; 466 | 467 | if ([hdaWidget isAmpIn]) 468 | { 469 | [outputString appendFormat:@" Amp-In caps: "]; 470 | [outputString appendFormat:@"%@\n", [self ampCapsString:hdaWidget.ampInCapabilities]]; 471 | [outputString appendFormat:@" Amp-In vals:"]; 472 | 473 | for (uint32_t i = 0; i < [hdaWidget.ampInLeftDefaultGainMute count]; i++) 474 | { 475 | if ([hdaWidget isStereo]) 476 | [outputString appendFormat:@" [0x%02X 0x%02X]", [hdaWidget.ampInLeftDefaultGainMute[i] intValue], [hdaWidget.ampInRightDefaultGainMute[i] intValue]]; 477 | else 478 | [outputString appendFormat:@" [0x%02X]", [hdaWidget.ampInLeftDefaultGainMute[i] intValue]]; 479 | } 480 | 481 | [outputString appendFormat:@"\n"]; 482 | } 483 | 484 | if ([hdaWidget isAmpOut]) 485 | { 486 | [outputString appendFormat:@" Amp-Out caps: "]; 487 | [outputString appendFormat:@"%@\n", [self ampCapsString:hdaWidget.ampOutCapabilities]]; 488 | [outputString appendFormat:@" Amp-Out vals:"]; 489 | 490 | if ([hdaWidget isStereo]) 491 | [outputString appendFormat:@" [0x%02X 0x%02X]\n", hdaWidget.ampOutLeftDefaultGainMute, hdaWidget.ampOutRightDefaultGainMute]; 492 | else 493 | [outputString appendFormat:@" [0x%02X]\n", hdaWidget.ampOutLeftDefaultGainMute]; 494 | } 495 | 496 | if (hdaWidget.type == HDA_WIDGET_TYPE_PIN_COMPLEX) 497 | { 498 | [outputString appendFormat:@" Pincap 0x%08X:", hdaWidget.pinCapabilities]; 499 | [outputString appendFormat:@"%@\n", [hdaWidget pinCapString]]; 500 | 501 | if ([hdaWidget hasEAPD]) 502 | { 503 | [outputString appendFormat:@" EAPD 0x%02X:", hdaWidget.defaultEapd]; 504 | [outputString appendFormat:@"%@\n", [hdaWidget eapdString]]; 505 | } 506 | 507 | [outputString appendFormat:@" Pin Default 0x%08X: [%@] %@ at %@ %@\n", hdaWidget.defaultConfiguration, [hdaWidget defaultPortConnectionString], [hdaWidget defaultDeviceString], [hdaWidget defaultSurfaceString], [hdaWidget defaultLocationString]]; 508 | [outputString appendFormat:@" Conn = %@, Color = %@\n", [hdaWidget defaultConnectionTypeString], [hdaWidget defaultColorString]]; 509 | [outputString appendFormat:@" DefAssociation = 0x%1X, Sequence = 0x%1X\n", [hdaWidget defaultAssociation], [hdaWidget defaultSequence]]; 510 | [outputString appendFormat:@" Pin-ctls: 0x%02X:", hdaWidget.defaultPinControl]; 511 | [outputString appendFormat:@"%@\n", [hdaWidget controlString]]; 512 | } 513 | 514 | if ([hdaWidget hasConnectionList]) 515 | { 516 | [outputString appendFormat:@" Connection: %u\n ", (uint32_t)[hdaWidget.connections count]]; 517 | 518 | for (int i = 0; i < [hdaWidget.connections count]; i++) 519 | { 520 | NSNumber *connection = hdaWidget.connections[i]; 521 | [outputString appendFormat:@" 0x%02X%@", [connection intValue], hdaWidget.connectionSelect == i ? @"*" : @""]; 522 | } 523 | 524 | [outputString appendFormat:@"\n"]; 525 | } 526 | } 527 | 528 | return outputString; 529 | } 530 | 531 | + (bool)stringContains:(NSString *)valueString checkString:(NSString *)checkString 532 | { 533 | return ([valueString rangeOfString:checkString options:NSCaseInsensitiveSearch].location != NSNotFound); 534 | } 535 | 536 | + (bool)parseHdaCodecNode_Voodoo:(NSString *)hdaNodeString hdaCodec:(HdaCodec *)hdaCodec 537 | { 538 | // nid: 20 539 | // Name: pin: Speaker (ATAPI) 540 | // Widget cap: 0x0040018d 541 | // UNSOL STEREO 542 | // Association: 0 (0x00000001) 543 | // Pin cap: 0x00010014 544 | // PDC OUT EAPD 545 | // Pin config: 0x99130110 546 | // Pin control: 0x00000040 OUT 547 | // EAPD: 0x00000002 548 | // Output amp: 0x80000000 549 | // mute=1 step=0 size=0 offset=0 550 | // Output val: [0x00 0x00] 551 | // connections: 2 enabled 1 552 | 553 | NSArray *lineArray = [hdaNodeString componentsSeparatedByString:@"\n"]; 554 | HdaWidget *hdaWidget = nil; 555 | NSMutableArray *itemArray; 556 | 557 | for (int i = 0; i < [lineArray count]; i++) 558 | { 559 | NSString *line = lineArray[i]; 560 | 561 | // ============================================================================= 562 | // nid: 20 563 | // ============================================================================= 564 | if (getRegExArray(@"(.*)nid: (.*)", line, 2, &itemArray)) 565 | { 566 | if (hdaWidget != nil) 567 | [hdaWidget release]; 568 | 569 | hdaWidget = [[HdaWidget alloc] initWithNodeID:getInt(itemArray[1])]; 570 | [hdaCodec.widgets addObject:hdaWidget]; 571 | } 572 | 573 | // ============================================================================= 574 | // Widget cap: 0x0040018f 575 | // ============================================================================= 576 | if (getRegExArray(@"(.*)Widget cap: (.*)", line, 2, &itemArray)) 577 | hdaWidget.capabilities = getInt(itemArray[1]); 578 | 579 | // ============================================================================= 580 | // EAPD: 0x00000002 581 | // ============================================================================= 582 | if (getRegExArray(@"(.*)EAPD: (.*)", line, 2, &itemArray)) 583 | hdaWidget.defaultEapd = getInt(itemArray[1]); 584 | 585 | // ============================================================================= 586 | // Pin cap: 0x00010014 587 | // ============================================================================= 588 | if (getRegExArray(@"(.*)Pin cap: (.*)", line, 2, &itemArray)) 589 | hdaWidget.pinCapabilities = getInt(itemArray[1]); 590 | 591 | // ============================================================================= 592 | // Pin config: 0x99130110 593 | // ============================================================================= 594 | if (getRegExArray(@"(.*)Pin config: (.*)", line, 2, &itemArray)) 595 | hdaWidget.defaultConfiguration = getInt(itemArray[1]); 596 | 597 | // ============================================================================= 598 | // Pin control: 0x00000000 599 | // ============================================================================= 600 | if (getRegExArray(@"(.*)Pin control: (.*)", line, 2, &itemArray)) 601 | hdaWidget.defaultPinControl = getInt(itemArray[1]); 602 | 603 | // ============================================================================= 604 | // Output amp: 0x80000000 605 | // ============================================================================= 606 | if (getRegExArray(@"(.*)Output amp: (.*)", line, 2, &itemArray)) 607 | hdaWidget.ampOutCapabilities = getInt(itemArray[1]); 608 | 609 | // ============================================================================= 610 | // Output val: [0x80 0x80] 611 | // ============================================================================= 612 | if (getRegExArray(@"(.*)Output val: (.*)", line, 2, &itemArray)) 613 | { 614 | NSMutableArray *ampOutArray = [[itemArray[1] componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"[]"]] mutableCopy]; 615 | [ampOutArray removeObjectsInArray:@[@" ", @""]]; 616 | 617 | for (NSString *ampOutValue in ampOutArray) 618 | { 619 | NSArray *stereoArray = [ampOutValue componentsSeparatedByString:@" "]; 620 | 621 | if ([stereoArray count] > 0) 622 | { 623 | hdaWidget.ampOutLeftDefaultGainMute = getInt(stereoArray[0]); 624 | 625 | if ([stereoArray count] == 2) 626 | hdaWidget.ampOutRightDefaultGainMute = getInt(stereoArray[1]); 627 | } 628 | 629 | break; 630 | } 631 | 632 | [ampOutArray release]; 633 | } 634 | 635 | // ============================================================================= 636 | // Input amp: 0x002f0300 637 | // ============================================================================= 638 | if (getRegExArray(@"(.*)Input amp: (.*)", line, 2, &itemArray)) 639 | hdaWidget.ampInCapabilities = getInt(itemArray[1]); 640 | 641 | // ============================================================================= 642 | // Input val: [0x00 0x00] [0x00 0x00] 643 | // ============================================================================= 644 | if (getRegExArray(@"(.*)Input val: (.*)", line, 2, &itemArray)) 645 | { 646 | hdaWidget.ampInLeftDefaultGainMute = [NSMutableArray array]; 647 | hdaWidget.ampInRightDefaultGainMute = [NSMutableArray array]; 648 | NSMutableArray *ampInArray = [[itemArray[1] componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"[]"]] mutableCopy]; 649 | [ampInArray removeObjectsInArray:@[@" ", @""]]; 650 | 651 | for (NSString *ampInValue in ampInArray) 652 | { 653 | NSArray *stereoArray = [ampInValue componentsSeparatedByString:@" "]; 654 | 655 | if ([stereoArray count] > 0) 656 | { 657 | [hdaWidget.ampInLeftDefaultGainMute addObject:[NSNumber numberWithInteger:getInt(stereoArray[0])]]; 658 | 659 | if ([stereoArray count] == 2) 660 | [hdaWidget.ampInRightDefaultGainMute addObject:[NSNumber numberWithInteger:getInt(stereoArray[1])]]; 661 | } 662 | } 663 | 664 | [ampInArray release]; 665 | } 666 | 667 | // ============================================================================= 668 | // connections: 2 enabled 2 669 | // | 670 | // + <- nid=12 [audio mixer] (selected) 671 | // + <- nid=13 [audio mixer] [DISABLED] 672 | // ============================================================================= 673 | if (getRegExArray(@"(.*)connections: (.*) enabled (.*)", line, 3, &itemArray)) 674 | { 675 | if ((i += 2) >= [lineArray count]) 676 | break; 677 | 678 | line = lineArray[i]; 679 | hdaWidget.connections = [NSMutableArray array]; 680 | 681 | while (getRegExArray(@"(.*)<- nid=(.*) \\[(.*)\\](.*)", line, 4, &itemArray)) 682 | { 683 | bool selected = [HdaCodec stringContains:itemArray[3] checkString:@"selected"]; 684 | //bool disabled = [HdaCodec stringContains:itemArray[3] checkString:@"disabled"]; 685 | uint32_t connection = getInt(itemArray[1]); 686 | [hdaWidget.connections addObject:[NSNumber numberWithInteger:connection]]; 687 | 688 | if (selected) 689 | hdaWidget.connectionSelect = (uint8_t)(hdaWidget.connections.count - 1); 690 | 691 | if (++i >= [lineArray count]) 692 | break; 693 | 694 | line = lineArray[i]; 695 | } 696 | 697 | continue; 698 | } 699 | } 700 | 701 | if (hdaWidget != nil) 702 | [hdaWidget release]; 703 | 704 | return true; 705 | } 706 | 707 | + (bool)parseHdaCodecString_Voodoo:(NSString *)hdaCodecString hdaCodec:(HdaCodec *)hdaCodec 708 | { 709 | // Probing codec #0... 710 | // HDA Codec #0: Realtek ALC269 711 | // HDA Codec ID: 0x10ec0269 712 | // Vendor: 0x10ec 713 | // Device: 0x0269 714 | // Revision: 0x01 715 | // Stepping: 0x00 716 | // PCI Subvendor: 0x035d1025 717 | // startNode=1 endNode=2 718 | // Found audio FG nid=1 startNode=2 endNode=36 total=34 719 | 720 | NSRange nodeRange = [hdaCodecString rangeOfString:@"nid:"]; 721 | 722 | if (nodeRange.location == NSNotFound) 723 | return false; 724 | 725 | NSString *headerString = [hdaCodecString substringWithRange:NSMakeRange(0, nodeRange.location)]; 726 | NSString *allNodesString = [hdaCodecString substringFromIndex:nodeRange.location]; 727 | NSArray *nodeArray = [allNodesString componentsSeparatedByString:@"nid:"]; 728 | NSArray *headerLineArray = [headerString componentsSeparatedByString:@"\n"]; 729 | NSMutableArray *itemArray; 730 | 731 | for (NSString *line in headerLineArray) 732 | { 733 | //NSLog(@"%@", line); 734 | 735 | // ============================================================================= 736 | // HDA Codec #0: Realtek ALC269 737 | // ============================================================================= 738 | if (getRegExArray(@"(.*)HDA Codec #(.*): (.*)", line, 3, &itemArray)) 739 | { 740 | hdaCodec.address = getInt(itemArray[1]); 741 | hdaCodec.name = itemArray[2]; 742 | } 743 | 744 | // ============================================================================= 745 | // HDA Codec ID: 0x10ec0269 746 | // ============================================================================= 747 | if (getRegExArray(@"(.*)HDA Codec ID: (.*)", line, 2, &itemArray)) 748 | hdaCodec.vendorID = getInt(itemArray[1]); 749 | 750 | // ============================================================================= 751 | // Revision: 0x01 752 | // ============================================================================= 753 | if (getRegExArray(@"(.*)Revision: (.*)", line, 2, &itemArray)) 754 | hdaCodec.revisionID |= getInt(itemArray[1]) << 16; 755 | } 756 | 757 | hdaCodec.widgets = [NSMutableArray array]; 758 | 759 | for (NSString *nodeString in nodeArray) 760 | { 761 | NSString *newNodeString = [@"nid:" stringByAppendingString:nodeString]; 762 | 763 | [HdaCodec parseHdaCodecNode_Voodoo:newNodeString hdaCodec:hdaCodec]; 764 | } 765 | 766 | return true; 767 | } 768 | 769 | + (bool)parseHdaCodecNode_Linux:(NSString *)hdaNodeString hdaCodec:(HdaCodec *)hdaCodec 770 | { 771 | // Node 0x14 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out 772 | // Control: name="Speaker Playback Switch", index=0, device=0 773 | // ControlAmp: chs=3, dir=Out, idx=0, ofs=0 774 | // Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1 775 | // Amp-Out vals: [0x00 0x00] 776 | // Pincap 0x00010014: OUT EAPD Detect 777 | // EAPD 0x2: EAPD 778 | // Pin Default 0x90170110: [Fixed] Speaker at Int N/A 779 | // Conn = Analog, Color = Unknown 780 | // DefAssociation = 0x1, Sequence = 0x0 781 | // Misc = NO_PRESENCE 782 | // Pin-ctls: 0x40: OUT 783 | // Unsolicited: tag=00, enabled=0 784 | // Power states: D0 D1 D2 D3 EPSS 785 | // Power: setting=D0, actual=D0 786 | // Connection: 1 787 | // 0x02 788 | 789 | NSArray *lineArray = [hdaNodeString componentsSeparatedByString:@"\n"]; 790 | HdaWidget *hdaWidget = nil; 791 | NSMutableArray *itemArray; 792 | 793 | for (int i = 0; i < [lineArray count]; i++) 794 | { 795 | NSString *line = lineArray[i]; 796 | //NSLog(@"%@", line); 797 | 798 | // ============================================================================= 799 | // Node 0x14 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out 800 | // ============================================================================= 801 | if (getRegExArray(@"Node (.*) \\[(.*)\\] wcaps (.*):(.*)", line, 4, &itemArray)) 802 | { 803 | if (hdaWidget != nil) 804 | [hdaWidget release]; 805 | 806 | hdaWidget = [[HdaWidget alloc] initWithNodeID:getInt(itemArray[0])]; 807 | [hdaCodec.widgets addObject:hdaWidget]; 808 | 809 | hdaWidget.capabilities = getInt(itemArray[2]); 810 | } 811 | 812 | // ============================================================================= 813 | // Control: name="Speaker Playback Switch", index=0, device=0 814 | // ============================================================================= 815 | if (getRegExArray(@"Control: name=\"(.*)\", index=(.*), device=(.*)", line, 3, &itemArray)) 816 | hdaWidget.name = itemArray[0]; 817 | 818 | // ============================================================================= 819 | // Amp-In caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1 820 | // ============================================================================= 821 | if (getRegExArray(@"(.*)Amp-In caps: ofs=(.*), nsteps=(.*), stepsize=(.*), mute=(.*)", line, 5, &itemArray)) 822 | { 823 | hdaWidget.ampInCapabilities |= getInt(itemArray[1]); 824 | hdaWidget.ampInCapabilities |= getInt(itemArray[2]) << 8; 825 | hdaWidget.ampInCapabilities |= getInt(itemArray[3]) << 16; 826 | hdaWidget.ampInCapabilities |= getInt(itemArray[4]) ? HDA_PARAMETER_AMP_CAPS_MUTE : 0; 827 | } 828 | 829 | // ============================================================================= 830 | // Amp-In vals: [0x00 0x00] 831 | // ============================================================================= 832 | if (getRegExArray(@"(.*)Amp-In vals: (.*)", line, 2, &itemArray)) 833 | { 834 | hdaWidget.ampInLeftDefaultGainMute = [NSMutableArray array]; 835 | hdaWidget.ampInRightDefaultGainMute = [NSMutableArray array]; 836 | NSMutableArray *ampInArray = [[itemArray[1] componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"[]"]] mutableCopy]; 837 | [ampInArray removeObjectsInArray:@[@" ", @""]]; 838 | 839 | for (NSString *ampInValue in ampInArray) 840 | { 841 | NSArray *stereoArray = [ampInValue componentsSeparatedByString:@" "]; 842 | 843 | if ([stereoArray count] > 0) 844 | { 845 | [hdaWidget.ampInLeftDefaultGainMute addObject:[NSNumber numberWithInteger:getInt(stereoArray[0])]]; 846 | 847 | if ([stereoArray count] == 2) 848 | [hdaWidget.ampInRightDefaultGainMute addObject:[NSNumber numberWithInteger:getInt(stereoArray[1])]]; 849 | } 850 | } 851 | 852 | [ampInArray release]; 853 | } 854 | 855 | // ============================================================================= 856 | // Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1 857 | // ============================================================================= 858 | if (getRegExArray(@"(.*)Amp-Out caps: ofs=(.*), nsteps=(.*), stepsize=(.*), mute=(.*)", line, 5, &itemArray)) 859 | { 860 | hdaWidget.ampOutCapabilities |= getInt(itemArray[1]); 861 | hdaWidget.ampOutCapabilities |= getInt(itemArray[2]) << 8; 862 | hdaWidget.ampOutCapabilities |= getInt(itemArray[3]) << 16; 863 | hdaWidget.ampOutCapabilities |= getInt(itemArray[4]) ? HDA_PARAMETER_AMP_CAPS_MUTE : 0; 864 | } 865 | 866 | // ============================================================================= 867 | // Amp-Out vals: [0x00 0x00] 868 | // ============================================================================= 869 | if (getRegExArray(@"(.*)Amp-Out vals: (.*)", line, 2, &itemArray)) 870 | { 871 | NSMutableArray *ampOutArray = [[itemArray[1] componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"[]"]] mutableCopy]; 872 | [ampOutArray removeObjectsInArray:@[@" ", @""]]; 873 | 874 | for (NSString *ampOutValue in ampOutArray) 875 | { 876 | NSArray *stereoArray = [ampOutValue componentsSeparatedByString:@" "]; 877 | 878 | if ([stereoArray count] > 0) 879 | { 880 | hdaWidget.ampOutLeftDefaultGainMute = getInt(stereoArray[0]); 881 | 882 | if ([stereoArray count] == 2) 883 | hdaWidget.ampOutRightDefaultGainMute = getInt(stereoArray[1]); 884 | } 885 | 886 | break; 887 | } 888 | 889 | [ampOutArray release]; 890 | } 891 | 892 | // ============================================================================= 893 | // Connection: 2 894 | // 0x02 0x03 895 | // ============================================================================= 896 | if (getRegExArray(@"(.*)Connection: (.*)", line, 2, &itemArray)) 897 | { 898 | if (++i >= [lineArray count]) 899 | break; 900 | 901 | line = lineArray[i]; 902 | hdaWidget.connections = [NSMutableArray array]; 903 | NSMutableArray *connectionArray = [[line componentsSeparatedByString:@" "] mutableCopy]; 904 | [connectionArray removeObject:@""]; 905 | 906 | for (int j = 0; j < [connectionArray count]; j++) 907 | { 908 | bool selected = [connectionArray[j] hasSuffix:@"*"]; 909 | uint32_t connection = getInt(connectionArray[j]); 910 | [hdaWidget.connections addObject:[NSNumber numberWithInteger:connection]]; 911 | 912 | if (selected) 913 | hdaWidget.connectionSelect = (uint8_t)(hdaWidget.connections.count - 1); 914 | } 915 | 916 | [connectionArray release]; 917 | 918 | continue; 919 | } 920 | 921 | // ============================================================================= 922 | // Pincap 0x00010014: OUT EAPD Detect 923 | // ============================================================================= 924 | if (getRegExArray(@"(.*)Pincap (.*):(.*)", line, 3, &itemArray)) 925 | hdaWidget.pinCapabilities = getInt(itemArray[1]); 926 | 927 | // ============================================================================= 928 | // EAPD 0x2: EAPD 929 | // ============================================================================= 930 | if (getRegExArray(@"(.*)EAPD (.*):(.*)", line, 3, &itemArray)) 931 | hdaWidget.defaultEapd = getInt(itemArray[1]); 932 | 933 | // ============================================================================= 934 | // Pin Default 0x90170110: [Fixed] Speaker at Int N/A 935 | // ============================================================================= 936 | if (getRegExArray(@"(.*)Pin Default (.*):(.*)", line, 3, &itemArray)) 937 | hdaWidget.defaultConfiguration = getInt(itemArray[1]); 938 | 939 | // ============================================================================= 940 | // Pin-ctls: 0x40: OUT 941 | // ============================================================================= 942 | if (getRegExArray(@"(.*)Pin-ctls: (.*):(.*)", line, 3, &itemArray)) 943 | hdaWidget.defaultPinControl = getInt(itemArray[1]); 944 | } 945 | 946 | if (hdaWidget != nil) 947 | [hdaWidget release]; 948 | 949 | return true; 950 | } 951 | 952 | + (bool)parseHdaCodecHeader_Linux:(NSString *)headerString hdaCodec:(HdaCodec *)hdaCodec 953 | { 954 | // Codec: Realtek Generic 955 | // Address: 0 956 | // AFG Function Id: 0x1 (unsol 1) 957 | // Vendor Id: 0x10ec1220 958 | // 959 | 960 | NSArray *headerLineArray = [headerString componentsSeparatedByString:@"\n"]; 961 | NSMutableArray *itemArray; 962 | 963 | for (NSString *headerLine in headerLineArray) 964 | { 965 | // ============================================================================= 966 | // Codec: Realtek Generic 967 | // ============================================================================= 968 | if (getRegExArray(@"Codec: (.*)", headerLine, 1, &itemArray)) 969 | hdaCodec.name = itemArray[0]; 970 | 971 | // ============================================================================= 972 | // Address: 0 973 | // ============================================================================= 974 | if (getRegExArray(@"Address: (.*)", headerLine, 1, &itemArray)) 975 | hdaCodec.address = getInt(itemArray[0]); 976 | 977 | // ============================================================================= 978 | // Vendor Id: 0x10EC0283 979 | // ============================================================================= 980 | if (getRegExArray(@"Vendor Id: (.*)", headerLine, 1, &itemArray)) 981 | hdaCodec.vendorID = getInt(itemArray[0]); 982 | 983 | // ============================================================================= 984 | // Revision Id: 0x00100003 985 | // ============================================================================= 986 | if (getRegExArray(@"Revision Id: (.*)", headerLine, 1, &itemArray)) 987 | hdaCodec.revisionID = getInt(itemArray[0]); 988 | 989 | // ============================================================================= 990 | // AFG Function Id: 0x1 (unsol 1) 991 | // ============================================================================= 992 | if (getRegExArray(@"AFG Function Id: (.*) \\(unsol (.*)\\)", headerLine, 2, &itemArray)) 993 | { 994 | hdaCodec.audioFuncID = getInt(itemArray[0]); 995 | hdaCodec.unsol = getInt(itemArray[1]); 996 | } 997 | 998 | // ============================================================================= 999 | // rates [0x0560]: 44100 48000 96000 192000 1000 | // bits [0x000E]: 16 20 24 1001 | // formats [0x00000001]: PCM 1002 | // ============================================================================= 1003 | if (getRegExArray(@"(.*)rates \\[(.*)\\]:(.*)", headerLine, 3, &itemArray)) 1004 | hdaCodec.rates = getInt(itemArray[1]); 1005 | 1006 | if (getRegExArray(@"(.*)bits \\[(.*)\\]:(.*)", headerLine, 3, &itemArray)) 1007 | hdaCodec.rates |= getInt(itemArray[1]) << 16; 1008 | 1009 | if (getRegExArray(@"(.*)formats \\(.*)\\]:(.*)", headerLine, 3, &itemArray)) 1010 | hdaCodec.formats = getInt(itemArray[1]); 1011 | } 1012 | 1013 | return true; 1014 | } 1015 | 1016 | + (bool)getHdaCodecArray_Linux:(NSString *)hdaCodecString hdaCodecArray:(NSMutableArray **)hdaCodecArray 1017 | { 1018 | [*hdaCodecArray removeAllObjects]; 1019 | hdaCodecString = [hdaCodecString stringByReplacingOccurrencesOfString:@"\r" withString:@""]; 1020 | 1021 | NSArray *codecArray = [hdaCodecString componentsSeparatedByString:@"Codec:"]; 1022 | uint32_t codecCount = (uint32_t)[codecArray count] - 1; 1023 | 1024 | for (int i = 0; i < codecCount; i++) 1025 | { 1026 | hdaCodecString = codecArray[i + 1]; 1027 | 1028 | NSRange nodeRange = [hdaCodecString rangeOfString:@"Node"]; 1029 | 1030 | if (nodeRange.location == NSNotFound) 1031 | continue; 1032 | 1033 | NSString *headerString = [hdaCodecString substringWithRange:NSMakeRange(0, nodeRange.location)]; 1034 | headerString = [@"Codec:" stringByAppendingString:headerString]; 1035 | HdaCodec *hdaCodec = [[HdaCodec alloc] init]; 1036 | 1037 | [HdaCodec parseHdaCodecHeader_Linux:headerString hdaCodec:hdaCodec]; 1038 | 1039 | //NSLog(@"Codec: %@ Address: 0x%02X Vendor Id: 0x%08X Revision Id: 0x%08X", hdaCodec.name, hdaCodec.address, hdaCodec.vendorID, hdaCodec.revisionID); 1040 | 1041 | [*hdaCodecArray addObject:hdaCodec]; 1042 | } 1043 | 1044 | return true; 1045 | } 1046 | 1047 | + (bool)parseHdaCodecString_Linux:(NSString *)hdaCodecString index:(uint32_t)index hdaCodec:(HdaCodec *)hdaCodec 1048 | { 1049 | // Codec: Realtek Generic 1050 | // Address: 0 1051 | // AFG Function Id: 0x1 (unsol 1) 1052 | // Vendor Id: 0x10ec1220 1053 | // 1054 | 1055 | hdaCodecString = [hdaCodecString stringByReplacingOccurrencesOfString:@"\r" withString:@""]; 1056 | NSArray *codecArray = [hdaCodecString componentsSeparatedByString:@"Codec:"]; 1057 | hdaCodecString = codecArray[index + 1]; 1058 | NSRange nodeRange = [hdaCodecString rangeOfString:@"Node"]; 1059 | 1060 | if (nodeRange.location == NSNotFound) 1061 | return false; 1062 | 1063 | NSString *headerString = [hdaCodecString substringWithRange:NSMakeRange(0, nodeRange.location)]; 1064 | headerString = [@"Codec:" stringByAppendingString:headerString]; 1065 | NSString *allNodesString = [hdaCodecString substringFromIndex:nodeRange.location]; 1066 | NSArray *nodeArray = [allNodesString componentsSeparatedByString:@"Node"]; 1067 | 1068 | [HdaCodec parseHdaCodecHeader_Linux:headerString hdaCodec:hdaCodec]; 1069 | 1070 | hdaCodec.widgets = [NSMutableArray array]; 1071 | 1072 | for (NSString *nodeString in nodeArray) 1073 | { 1074 | if ([nodeString isEqualToString:@""]) 1075 | continue; 1076 | 1077 | NSString *newNodeString = [@"Node" stringByAppendingString:nodeString]; 1078 | 1079 | [HdaCodec parseHdaCodecNode_Linux:newNodeString hdaCodec:hdaCodec]; 1080 | } 1081 | 1082 | return true; 1083 | } 1084 | 1085 | + (uint32_t)parseHdaCodecString:(NSString *)hdaCodecString index:(uint32_t)index hdaCodec:(HdaCodec **)hdaCodec hdaCodecArray:(NSMutableArray **)hdaCodecArray 1086 | { 1087 | *hdaCodec = [[HdaCodec alloc] init]; 1088 | 1089 | if ([hdaCodecString rangeOfString:@"Codec"].location == NSNotFound) 1090 | return 0; 1091 | 1092 | if ([hdaCodecString rangeOfString:@"Pin config:"].location != NSNotFound) 1093 | return [HdaCodec parseHdaCodecString_Voodoo:hdaCodecString hdaCodec:*hdaCodec]; 1094 | else if ([hdaCodecString rangeOfString:@"[Pin Complex]"].location != NSNotFound) 1095 | { 1096 | [HdaCodec getHdaCodecArray_Linux:hdaCodecString hdaCodecArray:hdaCodecArray]; 1097 | 1098 | if ([*hdaCodecArray count] > 1) 1099 | return (uint32_t)[*hdaCodecArray count]; 1100 | 1101 | return [HdaCodec parseHdaCodecString_Linux:hdaCodecString index:index hdaCodec:*hdaCodec]; 1102 | } 1103 | 1104 | return 0; 1105 | } 1106 | 1107 | + (bool)parseHdaCodecData:(uint8_t *)hdaCodecData length:(uint32_t)length hdaCodec:(HdaCodec **)hdaCodec 1108 | { 1109 | if (length < sizeof(HdaCodecEntry)) 1110 | return false; 1111 | 1112 | uint8_t *pHdaCodecData = hdaCodecData; 1113 | HdaCodecEntry *hdaCodecEntry = (HdaCodecEntry *)pHdaCodecData; 1114 | 1115 | if (hdaCodecEntry->Header[0] != 'H' || hdaCodecEntry->Header[1] != 'D' || hdaCodecEntry->Header[2] != 'C') 1116 | return false; 1117 | 1118 | uint32_t widgetCount = hdaCodecEntry->WidgetCount; 1119 | *hdaCodec = [[HdaCodec alloc] initWithName:[NSString stringWithCString:(const char *)hdaCodecEntry->Name encoding:NSASCIIStringEncoding] audioFuncID:hdaCodecEntry->AudioFuncID unsol:hdaCodecEntry->Unsol vendorID:hdaCodecEntry->VendorID revisionID:hdaCodecEntry->RevisionID rates:hdaCodecEntry->Rates formats:hdaCodecEntry->Formats ampInCaps:hdaCodecEntry->AmpInCaps ampOutCaps:hdaCodecEntry->AmpOutCaps]; 1120 | 1121 | (*hdaCodec).widgets = [NSMutableArray array]; 1122 | 1123 | pHdaCodecData += sizeof(HdaCodecEntry); 1124 | 1125 | HdaWidgetEntry *hdaWidgetEntry = (HdaWidgetEntry *)pHdaCodecData; 1126 | 1127 | for (uint32_t w = 0; w < widgetCount; w++) 1128 | { 1129 | HdaWidget *hdaWidget = [[HdaWidget alloc] initWithNodeID:hdaWidgetEntry->NodeId]; 1130 | 1131 | hdaWidget.capabilities = hdaWidgetEntry->Capabilities; 1132 | hdaWidget.defaultUnSol = hdaWidgetEntry->DefaultUnSol; 1133 | hdaWidget.defaultEapd = hdaWidgetEntry->DefaultEapd; 1134 | hdaWidget.connectionSelect = hdaWidgetEntry->ConnectionSelect; 1135 | hdaWidget.connections = (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_CONN_LIST ? [NSMutableArray array] : nil); 1136 | hdaWidget.supportedPowerStates = hdaWidgetEntry->SupportedPowerStates; 1137 | hdaWidget.defaultPowerState = hdaWidgetEntry->DefaultPowerState; 1138 | hdaWidget.ampInCapabilities = hdaWidgetEntry->AmpInCapabilities; 1139 | hdaWidget.ampOutCapabilities = hdaWidgetEntry->AmpOutCapabilities; 1140 | hdaWidget.ampInLeftDefaultGainMute = (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_IN_AMP ? [NSMutableArray array] : nil); 1141 | hdaWidget.ampInRightDefaultGainMute = (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_IN_AMP && hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_STEREO ? [NSMutableArray array] : nil); 1142 | hdaWidget.ampOutLeftDefaultGainMute = hdaWidgetEntry->AmpOutLeftDefaultGainMute; 1143 | hdaWidget.ampOutRightDefaultGainMute = hdaWidgetEntry->AmpOutRightDefaultGainMute; 1144 | hdaWidget.supportedPcmRates = hdaWidgetEntry->SupportedPcmRates; 1145 | hdaWidget.supportedFormats = hdaWidgetEntry->SupportedFormats; 1146 | hdaWidget.defaultConvFormat = hdaWidgetEntry->DefaultConvFormat; 1147 | hdaWidget.defaultConvStreamChannel = hdaWidgetEntry->DefaultConvStreamChannel; 1148 | hdaWidget.defaultConvChannelCount = hdaWidgetEntry->DefaultConvChannelCount; 1149 | hdaWidget.pinCapabilities = hdaWidgetEntry->PinCapabilities; 1150 | hdaWidget.defaultPinControl = hdaWidgetEntry->DefaultPinControl; 1151 | hdaWidget.defaultConfiguration = hdaWidgetEntry->DefaultConfiguration; 1152 | hdaWidget.volumeCapabilities = hdaWidgetEntry->VolumeCapabilities; 1153 | hdaWidget.defaultVolume = hdaWidgetEntry->DefaultVolume; 1154 | 1155 | uint32_t connectionListLength = HDA_PARAMETER_CONN_LIST_LENGTH_LEN(hdaWidgetEntry->ConnectionListLength); 1156 | 1157 | for (uint8_t i = 0; i < connectionListLength; i++) 1158 | { 1159 | if (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_IN_AMP) 1160 | { 1161 | [hdaWidget.ampInLeftDefaultGainMute addObject:[NSNumber numberWithInteger:hdaWidgetEntry->AmpInLeftDefaultGainMute[i]]]; 1162 | 1163 | if (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_STEREO) 1164 | [hdaWidget.ampInRightDefaultGainMute addObject:[NSNumber numberWithInteger:hdaWidgetEntry->AmpInRightDefaultGainMute[i]]]; 1165 | } 1166 | 1167 | if (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_CONN_LIST) 1168 | [hdaWidget.connections addObject:[NSNumber numberWithShort:hdaWidgetEntry->Connections[i]]]; 1169 | } 1170 | 1171 | [(*hdaCodec).widgets addObject:hdaWidget]; 1172 | 1173 | [hdaWidget release]; 1174 | 1175 | pHdaCodecData += sizeof(HdaWidgetEntry); 1176 | 1177 | hdaWidgetEntry = (HdaWidgetEntry *)pHdaCodecData; 1178 | } 1179 | 1180 | return true; 1181 | } 1182 | 1183 | /* + (HdaWidget *)getWidget:(NSArray *)widgets nid:(uint8_t)nid 1184 | { 1185 | for (HdaWidget *hdaWidget in widgets) 1186 | { 1187 | if (hdaWidget.nodeID == nid) 1188 | return hdaWidget; 1189 | } 1190 | 1191 | return nil; 1192 | } */ 1193 | 1194 | + (bool)getWidget:(NSArray *)widgets nodeID:(uint8_t)nodeID hdaWidget:(HdaWidget **)hdaWidget 1195 | { 1196 | for (*hdaWidget in widgets) 1197 | if ((*hdaWidget).nodeID == nodeID) 1198 | return true; 1199 | 1200 | return false; 1201 | } 1202 | 1203 | + (bool)getSelectedWidget:(NSArray *)widgets widgetIn:(HdaWidget *)widgetIn widgetOut:(HdaWidget **)widgetOut 1204 | { 1205 | if (widgetIn.connections == nil || widgetIn.connectionSelect >= [widgetIn.connections count]) 1206 | return false; 1207 | 1208 | //NSLog(@"hdaWidget.nodeID: %02X widgetIn.connectionSelect: %02X", widgetIn.nodeID, widgetIn.connectionSelect); 1209 | 1210 | for (HdaWidget *hdaWidget in widgets) 1211 | { 1212 | if (hdaWidget.nodeID == [widgetIn.connections[widgetIn.connectionSelect] intValue]) 1213 | { 1214 | *widgetOut = hdaWidget; 1215 | 1216 | return true; 1217 | } 1218 | } 1219 | 1220 | return false; 1221 | } 1222 | 1223 | /* + (void)sortConnections:(HdaWidget *)hdaWidget 1224 | { 1225 | NSArray *sortedArray; 1226 | sortedArray = [hdaWidget.connections sortedArrayUsingComparator:^NSComparisonResult(id a, id b) 1227 | { 1228 | NSNumber *connectionA = [NSNumber numberWithInt:[(NSNumber *)a intValue]]; 1229 | NSNumber *connectionB = [NSNumber numberWithInt:[(NSNumber *)b intValue]]; 1230 | NSNumber *selectedA = [NSNumber numberWithBool:(([(NSNumber *)a intValue] >> 8) & 0x1) != 0]; 1231 | NSNumber *selectedB = [NSNumber numberWithBool:(([(NSNumber *)b intValue] >> 8) & 0x1) != 0]; 1232 | NSComparisonResult connectionComparison = [connectionA compare:connectionB]; 1233 | NSComparisonResult selectedComparison = [selectedA compare:selectedB]; 1234 | 1235 | if (selectedComparison != NSOrderedSame) 1236 | return selectedComparison; 1237 | 1238 | return connectionComparison; 1239 | }]; 1240 | } */ 1241 | 1242 | + (void)addNodeToPlatformXml:(NSMutableArray *)chain0 hdaWidget:(HdaWidget *)hdaWidget 1243 | { 1244 | NSMutableDictionary *chain = [[NSMutableDictionary alloc] init]; 1245 | [chain0 addObject:chain]; 1246 | [chain release]; 1247 | NSNumber *nodeID = @(hdaWidget.nodeID); 1248 | [chain setObject:nodeID forKey:@"NodeID"]; 1249 | 1250 | if(hdaWidget.type != HDA_WIDGET_TYPE_PIN_COMPLEX && ([hdaWidget isAmpIn] || [hdaWidget isAmpOut])) 1251 | { 1252 | NSMutableDictionary *amp = [[NSMutableDictionary alloc] init]; 1253 | [chain setObject:amp forKey:@"Amp"]; 1254 | 1255 | NSMutableArray *channels = [[NSMutableArray alloc] init]; 1256 | [amp setObject:channels forKey:@"Channels"]; 1257 | 1258 | NSNumber *muteInputAmp = [NSNumber numberWithBool:(hdaWidget.ampInCapabilities & HDA_PARAMETER_AMP_CAPS_MUTE) != 0]; 1259 | [amp setObject:muteInputAmp forKey:@"MuteInputAmp"]; 1260 | NSNumber *publishMute = [NSNumber numberWithBool:(hdaWidget.ampOutCapabilities & HDA_PARAMETER_AMP_CAPS_MUTE) != 0]; 1261 | [amp setObject:publishMute forKey:@"PublishMute"]; 1262 | NSNumber *publishVolume = [NSNumber numberWithBool:(hdaWidget.ampOutCapabilities & ~HDA_PARAMETER_AMP_CAPS_MUTE) != 0]; 1263 | [amp setObject:publishVolume forKey:@"PublishVolume"]; 1264 | NSNumber *volumeInputAmp = [NSNumber numberWithBool:(hdaWidget.ampInCapabilities & ~HDA_PARAMETER_AMP_CAPS_MUTE) != 0]; 1265 | [amp setObject:volumeInputAmp forKey:@"VolumeInputAmp"]; 1266 | 1267 | NSMutableDictionary *bind0 = [[NSMutableDictionary alloc] init]; 1268 | [channels addObject:bind0]; 1269 | [bind0 release]; 1270 | NSNumber *bind1 = [NSNumber numberWithInteger:1]; 1271 | [bind0 setObject:bind1 forKey:@"Bind"]; 1272 | NSNumber *channel1 = [NSNumber numberWithInteger:1]; 1273 | [bind0 setObject:channel1 forKey:@"Channel"]; 1274 | 1275 | NSMutableDictionary *channel0 = [[NSMutableDictionary alloc] init]; 1276 | [channels addObject:channel0]; 1277 | [channel0 release]; 1278 | NSNumber *bind2 = [NSNumber numberWithInteger:2]; 1279 | [channel0 setObject:bind2 forKey:@"Bind"]; 1280 | NSNumber *channel2 = [NSNumber numberWithInteger:2]; 1281 | [channel0 setObject:channel2 forKey:@"Channel"]; 1282 | 1283 | [channels release]; 1284 | [amp release]; 1285 | } 1286 | 1287 | if (hdaWidget.type == HDA_WIDGET_TYPE_PIN_COMPLEX && ([hdaWidget isAmpIn] || [hdaWidget isAmpOut]) && (hdaWidget.ampInCapabilities & 0x7F00)) 1288 | { 1289 | NSNumber *boost =@(1); // параметр step 1290 | [chain setObject:boost forKey:@"Boost"]; 1291 | } 1292 | } 1293 | 1294 | + (void)createPlatformsXml:(HdaCodec *)hdaCodec 1295 | { 1296 | // https://osxlatitude.com/forums/topic/1946-complete-applehda-patching-guide/ 1297 | // https://osxlatitude.com/forums/topic/1946-complete-applehda-patching-guide/?tab=comments#comment-14127 1298 | // https://osxlatitude.com/forums/topic/1967-applehda-binary-patching/ 1299 | // 1300 | // http://web.mit.edu/custer/Desktop/custer/MacData/afs/sipb/project/freebsd/head/sys/dev/sound/pci/hda/hdaa.c 1301 | // http://web.mit.edu/custer/Desktop/custer/MacData/afs/sipb/project/freebsd/head/sys/dev/sound/pci/hda/hdaa.h 1302 | 1303 | NSMutableDictionary *root = [[NSMutableDictionary alloc] init]; 1304 | NSMutableArray *commonPeripheralDSP = [[NSMutableArray alloc] init]; 1305 | [root setObject:commonPeripheralDSP forKey:@"CommonPeripheralDSP"]; 1306 | 1307 | NSMutableDictionary *dict0 = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:0], @"DeviceID", @"Headphone", @"DeviceType", nil]; 1308 | NSMutableDictionary *dict1 = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:0], @"DeviceID", @"Microphone", @"DeviceType", nil]; 1309 | 1310 | [commonPeripheralDSP addObject:dict0]; 1311 | [commonPeripheralDSP addObject:dict1]; 1312 | 1313 | NSMutableArray *pathMaps = [[NSMutableArray alloc] init]; 1314 | [root setObject:pathMaps forKey:@"PathMaps"]; 1315 | NSMutableDictionary *pathMaps0 = [[NSMutableDictionary alloc] init]; 1316 | [pathMaps addObject:pathMaps0]; 1317 | [pathMaps0 release]; 1318 | NSNumber *pathMapID = @(1); 1319 | [pathMaps0 setObject:pathMapID forKey:@"PathMapID"]; 1320 | NSMutableArray *pathMap = [[NSMutableArray alloc] init]; 1321 | [pathMaps0 setObject:pathMap forKey:@"PathMap"]; 1322 | 1323 | // Input Devices 1324 | // Pin Complex -> Audio Selector/Mixer -> Audio Input 1325 | // (or) 1326 | // Pin Complex -> Audio Input 1327 | 1328 | NSMutableArray *assocElement = [[NSMutableArray alloc] init]; 1329 | [pathMap addObject:assocElement]; //1 1330 | [assocElement release]; 1331 | NSMutableArray *assocElement1 = [[NSMutableArray alloc] init]; 1332 | [assocElement addObject:assocElement1]; //2 1333 | [assocElement1 release]; 1334 | NSMutableArray *chain0 = [[NSMutableArray alloc] init]; 1335 | [assocElement1 addObject:chain0]; //3 1336 | [chain0 release]; 1337 | 1338 | //NSMutableArray *pinConnectionArray = [NSMutableArray array]; 1339 | 1340 | for (HdaWidget *audioInputWidget in hdaCodec.widgets) 1341 | { 1342 | //NSLog(@"%02X isOutputDevice: %02X pinComplexWidget.isAmpOut: %02X pinComplexWidget.type: %02X", audioInputWidget.nodeID, audioInputWidget.isOutputDevice, audioInputWidget.isAmpOut, audioInputWidget.type); 1343 | 1344 | if(!audioInputWidget.isAmpIn) // || !audioInputWidget.isInputDevice) 1345 | continue; 1346 | 1347 | HdaWidget *audioMixerWidget = nil, *pinComplexWidget = nil; 1348 | bool audioMixerFound = false, pinComplexFound = false; 1349 | 1350 | for (NSNumber *connection in audioInputWidget.connections) 1351 | { 1352 | if (![HdaCodec getWidget:hdaCodec.widgets nodeID:[connection intValue] hdaWidget:&audioMixerWidget]) 1353 | continue; 1354 | 1355 | if (!audioInputWidget.isAmpIn || (audioMixerWidget.type != HDA_WIDGET_TYPE_MIXER && audioMixerWidget.type != HDA_WIDGET_TYPE_SELECTOR)) 1356 | continue; 1357 | 1358 | audioMixerFound = true; 1359 | 1360 | break; 1361 | } 1362 | 1363 | for (NSNumber *connection in audioMixerWidget.connections) 1364 | { 1365 | if (![HdaCodec getWidget:hdaCodec.widgets nodeID:[connection intValue] hdaWidget:&pinComplexWidget]) 1366 | continue; 1367 | 1368 | //!pinComplexWidget.isEnabled || !pinComplexWidget.isInputDevice || 1369 | if (!pinComplexWidget.isAmpIn || pinComplexWidget.type != HDA_WIDGET_TYPE_PIN_COMPLEX) 1370 | continue; 1371 | 1372 | pinComplexFound = true; 1373 | 1374 | break; 1375 | } 1376 | 1377 | if (audioMixerFound && pinComplexFound) 1378 | { 1379 | [HdaCodec addNodeToPlatformXml:chain0 hdaWidget:pinComplexWidget]; 1380 | [HdaCodec addNodeToPlatformXml:chain0 hdaWidget:audioMixerWidget]; 1381 | [HdaCodec addNodeToPlatformXml:chain0 hdaWidget:audioInputWidget]; 1382 | 1383 | NSLog(@"Input 0x%02X->0x%02X->0x%02X", pinComplexWidget.nodeID, audioMixerWidget.nodeID, audioInputWidget.nodeID); 1384 | } 1385 | else if (pinComplexFound) 1386 | { 1387 | [HdaCodec addNodeToPlatformXml:chain0 hdaWidget:pinComplexWidget]; 1388 | [HdaCodec addNodeToPlatformXml:chain0 hdaWidget:audioInputWidget]; 1389 | 1390 | NSLog(@"Input 0x%02X->0x%02X", pinComplexWidget.nodeID, audioInputWidget.nodeID); 1391 | } 1392 | //else 1393 | // NSLog(@"Input 0x%02X (Error!)", audioInputWidget.nodeID); 1394 | } 1395 | 1396 | // Output Devices 1397 | // Pin Complex -> Audio Mixer -> Audio Output 1398 | // (or) 1399 | // Pin Complex -> Audio Output 1400 | 1401 | assocElement = [[NSMutableArray alloc] init]; 1402 | [pathMap addObject:assocElement]; //1 1403 | [assocElement release]; 1404 | assocElement1 = [[NSMutableArray alloc] init]; 1405 | [assocElement addObject:assocElement1]; //2 1406 | [assocElement1 release]; 1407 | chain0 = [[NSMutableArray alloc] init]; 1408 | [assocElement1 addObject:chain0]; //3 1409 | [chain0 release]; 1410 | 1411 | //[pinConnectionArray removeAllObjects]; 1412 | 1413 | for (HdaWidget *pinComplexWidget in hdaCodec.widgets) 1414 | { 1415 | //NSLog(@"%02X pinComplexWidget.isEnabled: %02X isOutputDevice: %02X pinComplexWidget.isAmpOut: %02X pinComplexWidget.type: %02X", pinComplexWidget.nodeID, pinComplexWidget.isEnabled, pinComplexWidget.isOutputDevice, pinComplexWidget.isAmpOut, pinComplexWidget.type); 1416 | 1417 | // !pinComplexWidget.isEnabled || !pinComplexWidget.isOutputDevice || 1418 | if (!pinComplexWidget.isAmpOut || pinComplexWidget.type != HDA_WIDGET_TYPE_PIN_COMPLEX) 1419 | continue; 1420 | 1421 | HdaWidget *audioMixerWidget = nil, *audioOutputWidget = nil; 1422 | bool audioMixerFound = false, audioOutputFound = false; 1423 | 1424 | for (NSNumber *connection in pinComplexWidget.connections) 1425 | { 1426 | if (![HdaCodec getWidget:hdaCodec.widgets nodeID:[connection intValue] hdaWidget:&audioMixerWidget]) 1427 | continue; 1428 | 1429 | if (!pinComplexWidget.isAmpOut || audioMixerWidget.type != HDA_WIDGET_TYPE_MIXER) 1430 | continue; 1431 | 1432 | audioMixerFound = true; 1433 | 1434 | break; 1435 | } 1436 | 1437 | for (NSNumber *connection in audioMixerWidget.connections) 1438 | { 1439 | if (![HdaCodec getWidget:hdaCodec.widgets nodeID:[connection intValue] hdaWidget:&audioOutputWidget]) 1440 | continue; 1441 | 1442 | if (!audioOutputWidget.isAmpOut) 1443 | continue; 1444 | 1445 | audioOutputFound = true; 1446 | 1447 | break; 1448 | } 1449 | 1450 | if (audioMixerFound && audioOutputFound) 1451 | { 1452 | [HdaCodec addNodeToPlatformXml:chain0 hdaWidget:pinComplexWidget]; 1453 | [HdaCodec addNodeToPlatformXml:chain0 hdaWidget:audioMixerWidget]; 1454 | [HdaCodec addNodeToPlatformXml:chain0 hdaWidget:audioOutputWidget]; 1455 | 1456 | NSLog(@"Output 0x%02X->0x%02X->0x%02X", pinComplexWidget.nodeID, audioMixerWidget.nodeID, audioOutputWidget.nodeID); 1457 | } 1458 | else if (audioOutputFound) 1459 | { 1460 | [HdaCodec addNodeToPlatformXml:chain0 hdaWidget:pinComplexWidget]; 1461 | [HdaCodec addNodeToPlatformXml:chain0 hdaWidget:audioOutputWidget]; 1462 | 1463 | NSLog(@"Output 0x%02X->0x%02X", pinComplexWidget.nodeID, audioOutputWidget.nodeID); 1464 | } 1465 | //else 1466 | // NSLog(@"Output 0x%02X (Error!)", pinComplexWidget.nodeID); 1467 | } 1468 | 1469 | NSString *folder = [NSString stringWithFormat:@"DumpXML_%@", hdaCodec.name]; 1470 | NSArray *dirPath = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES); 1471 | NSString *dir = [dirPath objectAtIndex:0]; 1472 | NSString *fullPath = [dir stringByAppendingPathComponent:folder]; 1473 | 1474 | if (![[NSFileManager defaultManager] fileExistsAtPath:fullPath]) 1475 | [[NSFileManager defaultManager] createDirectoryAtPath:fullPath withIntermediateDirectories:NO attributes:nil error:nil]; 1476 | 1477 | fullPath = [fullPath stringByAppendingFormat:@"/Platforms.xml"]; 1478 | [root writeToFile: fullPath atomically:YES]; 1479 | 1480 | [pathMap release]; 1481 | [pathMaps release]; 1482 | [commonPeripheralDSP release]; 1483 | [root release]; 1484 | } 1485 | 1486 | @end 1487 | 1488 | -------------------------------------------------------------------------------- /PinConfigurator/HdaCodecDump.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: HdaCodecDump.h 3 | * 4 | * Copyright (c) 2018 John Davis 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef _EFI_HDA_CODEC_DUMP_H_ 26 | #define _EFI_HDA_CODEC_DUMP_H_ 27 | 28 | #import 29 | #include "HdaVerbs.h" 30 | #include 31 | #include 32 | 33 | #define HDA_MAX_CONNS 32 34 | #define HDA_MAX_NAMELEN 32 35 | 36 | typedef struct { 37 | uint8_t NodeId; 38 | uint8_t Type; 39 | uint32_t Capabilities; 40 | uint8_t DefaultUnSol; 41 | uint32_t ConnectionListLength; 42 | uint8_t ConnectionSelect; 43 | uint16_t Connections[HDA_MAX_CONNS]; 44 | uint32_t SupportedPowerStates; 45 | uint32_t DefaultPowerState; 46 | uint8_t AmpOverride; 47 | uint32_t AmpInCapabilities; 48 | uint32_t AmpOutCapabilities; 49 | uint8_t AmpInLeftDefaultGainMute[HDA_MAX_CONNS]; 50 | uint8_t AmpInRightDefaultGainMute[HDA_MAX_CONNS]; 51 | uint8_t AmpOutLeftDefaultGainMute; 52 | uint8_t AmpOutRightDefaultGainMute; 53 | uint32_t SupportedPcmRates; 54 | uint32_t SupportedFormats; 55 | uint16_t DefaultConvFormat; 56 | uint8_t DefaultConvStreamChannel; 57 | uint8_t DefaultConvChannelCount; 58 | uint32_t PinCapabilities; 59 | uint8_t DefaultEapd; 60 | uint8_t DefaultPinControl; 61 | uint32_t DefaultConfiguration; 62 | uint32_t VolumeCapabilities; 63 | uint8_t DefaultVolume; 64 | } HdaWidgetEntry; 65 | 66 | typedef struct { 67 | uint8_t Header[4]; 68 | uint8_t Name[HDA_MAX_NAMELEN]; 69 | uint8_t CodecAddress; 70 | uint8_t AudioFuncID; 71 | uint8_t Unsol; 72 | uint32_t VendorID; 73 | uint32_t RevisionID; 74 | uint32_t Rates; 75 | uint32_t Formats; 76 | uint32_t AmpInCaps; 77 | uint32_t AmpOutCaps; 78 | uint32_t WidgetCount; 79 | } HdaCodecEntry; 80 | 81 | int HdaCodecDump(uint8_t *hdaCodecData, uint32_t length, NSMutableString **outputString); 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /PinConfigurator/HdaCodecDump.m: -------------------------------------------------------------------------------- 1 | /* 2 | * File: HdaCodecDump.m 3 | * 4 | * Copyright (c) 2018 John Davis 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "HdaCodecDump.h" 26 | 27 | void HdaCodecDumpPrintRatesFormats(NSMutableString *outputString, uint32_t rates, uint32_t formats) { 28 | // Print sample rates. 29 | [outputString appendFormat:@" rates [0x%04X]:", (uint16_t)rates]; 30 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_8KHZ) 31 | [outputString appendFormat:@" 8000"]; 32 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_11KHZ) 33 | [outputString appendFormat:@" 11025"]; 34 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_16KHZ) 35 | [outputString appendFormat:@" 16000"]; 36 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_22KHZ) 37 | [outputString appendFormat:@" 22050"]; 38 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_32KHZ) 39 | [outputString appendFormat:@" 32000"]; 40 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_44KHZ) 41 | [outputString appendFormat:@" 44100"]; 42 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_48KHZ) 43 | [outputString appendFormat:@" 48000"]; 44 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_88KHZ) 45 | [outputString appendFormat:@" 88200"]; 46 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_96KHZ) 47 | [outputString appendFormat:@" 96000"]; 48 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_176KHZ) 49 | [outputString appendFormat:@" 176400"]; 50 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_192KHZ) 51 | [outputString appendFormat:@" 192000"]; 52 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_384KHZ) 53 | [outputString appendFormat:@" 384000"]; 54 | [outputString appendFormat:@"\n"]; 55 | 56 | // Print bits. 57 | [outputString appendFormat:@" bits [0x%04X]:", (uint16_t)(rates >> 16)]; 58 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_8BIT) 59 | [outputString appendFormat:@" 8"]; 60 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_16BIT) 61 | [outputString appendFormat:@" 16"]; 62 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_20BIT) 63 | [outputString appendFormat:@" 20"]; 64 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_24BIT) 65 | [outputString appendFormat:@" 24"]; 66 | if (rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_32BIT) 67 | [outputString appendFormat:@" 32"]; 68 | [outputString appendFormat:@"\n"]; 69 | 70 | // Print formats. 71 | [outputString appendFormat:@" formats [0x%08X]:", formats]; 72 | if (formats & HDA_PARAMETER_SUPPORTED_STREAM_FORMATS_PCM) 73 | [outputString appendFormat:@" PCM"]; 74 | if (formats & HDA_PARAMETER_SUPPORTED_STREAM_FORMATS_FLOAT32) 75 | [outputString appendFormat:@" FLOAT32"]; 76 | if (formats & HDA_PARAMETER_SUPPORTED_STREAM_FORMATS_AC3) 77 | [outputString appendFormat:@" AC3"]; 78 | [outputString appendFormat:@"\n"]; 79 | } 80 | 81 | void HdaCodecDumpPrintAmpCaps(NSMutableString *outputString, uint32_t ampCaps) 82 | { 83 | if (ampCaps) 84 | { 85 | [outputString appendFormat:@"ofs=0x%02X, nsteps=0x%02X, stepsize=0x%02X, mute=%u\n", 86 | HDA_PARAMETER_AMP_CAPS_OFFSET(ampCaps), HDA_PARAMETER_AMP_CAPS_NUM_STEPS(ampCaps), 87 | HDA_PARAMETER_AMP_CAPS_STEP_SIZE(ampCaps), (ampCaps & HDA_PARAMETER_AMP_CAPS_MUTE) != 0]; 88 | } else 89 | [outputString appendFormat:@"N/A\n"]; 90 | } 91 | 92 | int HdaCodecDumpPrintWidgets(NSMutableString *outputString, uint8_t *pData, uint32_t widgetCount) { 93 | uint32_t totalWidgetSize = 0; 94 | HdaWidgetEntry *hdaWidgetEntry = (HdaWidgetEntry *)pData; 95 | // Print each widget. 96 | for (uint32_t w = 0; w < widgetCount; w++) { 97 | // Determine name of widget. 98 | NSArray *widgetNames = @[@"Audio Output", @"Audio Input", @"Audio Mixer", 99 | @"Audio Selector", @"Pin Complex", @"Power Widget", 100 | @"Volume Knob Widget", @"Beep Generator Widget", 101 | @"Reserved", @"Reserved", @"Reserved", @"Reserved", 102 | @"Reserved", @"Reserved", @"Reserved", 103 | @"Vendor Defined Widget"]; 104 | 105 | // Print header and capabilities. 106 | [outputString appendFormat:@"Node 0x%02X [%@] wcaps 0x%08X:", hdaWidgetEntry->NodeId, 107 | widgetNames[HDA_PARAMETER_WIDGET_CAPS_TYPE(hdaWidgetEntry->Capabilities)], hdaWidgetEntry->Capabilities]; 108 | if (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_STEREO) 109 | [outputString appendFormat:@" Stereo"]; 110 | else 111 | [outputString appendFormat:@" Mono"]; 112 | if (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_DIGITAL) 113 | [outputString appendFormat:@" Digital"]; 114 | if (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_IN_AMP) 115 | [outputString appendFormat:@" Amp-In"]; 116 | if (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_OUT_AMP) 117 | [outputString appendFormat:@" Amp-Out"]; 118 | if (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_L_R_SWAP) 119 | [outputString appendFormat:@" R/L"]; 120 | [outputString appendFormat:@"\n"]; 121 | 122 | uint32_t connectionListLength = HDA_PARAMETER_CONN_LIST_LENGTH_LEN(hdaWidgetEntry->ConnectionListLength); 123 | uint32_t ampInSize = 0; 124 | 125 | // Print input amp info. 126 | if (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_IN_AMP) { 127 | uint8_t *pAmpIn = pData + sizeof(HdaWidgetEntry); 128 | ampInSize = (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_STEREO ? connectionListLength * 2 : connectionListLength); 129 | 130 | // Print caps. 131 | [outputString appendFormat:@" Amp-In caps: "]; 132 | HdaCodecDumpPrintAmpCaps(outputString, hdaWidgetEntry->AmpInCapabilities); 133 | 134 | // Print default values. 135 | [outputString appendFormat:@" Amp-In vals:"]; 136 | for (uint8_t i = 0; i < connectionListLength; i++) 137 | { 138 | if (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_STEREO) 139 | [outputString appendFormat:@" [0x%02X 0x%02X]", pAmpIn[i], pAmpIn[connectionListLength + i]]; 140 | else 141 | [outputString appendFormat:@" [0x%02X]", pAmpIn[i]]; 142 | } 143 | 144 | [outputString appendFormat:@"\n"]; 145 | } 146 | 147 | // Print output amp info. 148 | if (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_OUT_AMP) { 149 | // Print caps. 150 | [outputString appendFormat:@" Amp-Out caps: "]; 151 | HdaCodecDumpPrintAmpCaps(outputString, hdaWidgetEntry->AmpOutCapabilities); 152 | 153 | // Print default values. 154 | [outputString appendFormat:@" Amp-Out vals:"]; 155 | if (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_STEREO) 156 | [outputString appendFormat:@" [0x%02X 0x%02X]\n", hdaWidgetEntry->AmpOutLeftDefaultGainMute, hdaWidgetEntry->AmpOutRightDefaultGainMute]; 157 | else 158 | [outputString appendFormat:@" [0x%02X]\n", hdaWidgetEntry->AmpOutLeftDefaultGainMute]; 159 | } 160 | 161 | // Print pin complexe info. 162 | if (HDA_PARAMETER_WIDGET_CAPS_TYPE(hdaWidgetEntry->Capabilities) == HDA_WIDGET_TYPE_PIN_COMPLEX) { 163 | // Print pin capabilities. 164 | [outputString appendFormat:@" Pincap 0x%08X:", hdaWidgetEntry->PinCapabilities]; 165 | if (hdaWidgetEntry->PinCapabilities & HDA_PARAMETER_PIN_CAPS_INPUT) 166 | [outputString appendFormat:@" IN"]; 167 | if (hdaWidgetEntry->PinCapabilities & HDA_PARAMETER_PIN_CAPS_OUTPUT) 168 | [outputString appendFormat:@" OUT"]; 169 | if (hdaWidgetEntry->PinCapabilities & HDA_PARAMETER_PIN_CAPS_HEADPHONE) 170 | [outputString appendFormat:@" HP"]; 171 | if (hdaWidgetEntry->PinCapabilities & HDA_PARAMETER_PIN_CAPS_EAPD) 172 | [outputString appendFormat:@" EAPD"]; 173 | if (hdaWidgetEntry->PinCapabilities & HDA_PARAMETER_PIN_CAPS_TRIGGER) 174 | [outputString appendFormat:@" Trigger"]; 175 | if (hdaWidgetEntry->PinCapabilities & HDA_PARAMETER_PIN_CAPS_PRESENCE) 176 | [outputString appendFormat:@" Detect"]; 177 | if (hdaWidgetEntry->PinCapabilities & HDA_PARAMETER_PIN_CAPS_HBR) 178 | [outputString appendFormat:@" HBR"]; 179 | if (hdaWidgetEntry->PinCapabilities & HDA_PARAMETER_PIN_CAPS_HDMI) 180 | [outputString appendFormat:@" HDMI"]; 181 | if (hdaWidgetEntry->PinCapabilities & HDA_PARAMETER_PIN_CAPS_DISPLAYPORT) 182 | [outputString appendFormat:@" DP"]; 183 | [outputString appendFormat:@"\n"]; 184 | 185 | // Print EAPD info. 186 | if (hdaWidgetEntry->PinCapabilities & HDA_PARAMETER_PIN_CAPS_EAPD) { 187 | [outputString appendFormat:@" EAPD 0x%02X:", hdaWidgetEntry->DefaultEapd]; 188 | if (hdaWidgetEntry->DefaultEapd & HDA_EAPD_BTL_ENABLE_BTL) 189 | [outputString appendFormat:@" BTL"]; 190 | if (hdaWidgetEntry->DefaultEapd & HDA_EAPD_BTL_ENABLE_EAPD) 191 | [outputString appendFormat:@" EAPD"]; 192 | if (hdaWidgetEntry->DefaultEapd & HDA_EAPD_BTL_ENABLE_L_R_SWAP) 193 | [outputString appendFormat:@" R/L"]; 194 | [outputString appendFormat:@"\n"]; 195 | } 196 | 197 | // Create pin default names. 198 | NSArray *portConnectivities = @[@"Jack", @"None", @"Fixed", @"Int Jack"]; 199 | NSArray *defaultDevices = @[@"Line Out", @"Speaker", @"HP Out", @"CD", @"SPDIF Out", 200 | @"Digital Out", @"Modem Line", @"Modem Handset", @"Line In", @"Aux", 201 | @"Mic", @"Telephone", @"SPDIF In", @"Digital In", @"Reserved", @"Other"]; 202 | NSArray *surfaces = @[@"Ext", @"Int", @"Ext", @"Other"]; 203 | NSArray *locations = @[@"N/A", @"Rear", @"Front", @"Left", @"Right", @"Top", @"Bottom", @"Special", 204 | @"Special", @"Special", @"Reserved", @"Reserved", @"Reserved", @"Reserved"]; 205 | NSArray *connTypes = @[@"Unknown", @"1/8", @"1/4", @"ATAPI", @"RCA", @"Optical", @"Digital", 206 | @"Analog", @"Multi", @"XLR", @"RJ11", @"Combo", @"Other", @"Other", @"Other", @"Other"]; 207 | NSArray *colors = @[@"Unknown", @"Black", @"Grey", @"Blue", @"Green", @"Red", @"Orange", 208 | @"Yellow", @"Purple", @"Pink", @"Reserved", @"Reserved", @"Reserved", 209 | @"Reserved", @"White", @"Other"]; 210 | 211 | // Print pin default header. 212 | [outputString appendFormat:@" Pin Default 0x%08X: [%@] %@ at %@ %@\n", hdaWidgetEntry->DefaultConfiguration, 213 | portConnectivities[HDA_VERB_GET_CONFIGURATION_DEFAULT_PORT_CONN(hdaWidgetEntry->DefaultConfiguration)], 214 | defaultDevices[HDA_VERB_GET_CONFIGURATION_DEFAULT_DEVICE(hdaWidgetEntry->DefaultConfiguration)], 215 | surfaces[HDA_VERB_GET_CONFIGURATION_DEFAULT_SURF(hdaWidgetEntry->DefaultConfiguration)], 216 | locations[HDA_VERB_GET_CONFIGURATION_DEFAULT_LOC(hdaWidgetEntry->DefaultConfiguration)]]; 217 | 218 | // Print connection type and color. 219 | [outputString appendFormat:@" Conn = %@, Color = %@\n", 220 | connTypes[HDA_VERB_GET_CONFIGURATION_DEFAULT_CONN_TYPE(hdaWidgetEntry->DefaultConfiguration)], 221 | colors[HDA_VERB_GET_CONFIGURATION_DEFAULT_COLOR(hdaWidgetEntry->DefaultConfiguration)]]; 222 | 223 | // Print default association and sequence. 224 | [outputString appendFormat:@" DefAssociation = 0x%1X, Sequence = 0x%1X\n", 225 | HDA_VERB_GET_CONFIGURATION_DEFAULT_ASSOCIATION(hdaWidgetEntry->DefaultConfiguration), 226 | HDA_VERB_GET_CONFIGURATION_DEFAULT_SEQUENCE(hdaWidgetEntry->DefaultConfiguration)]; 227 | 228 | // Print default pin control. 229 | [outputString appendFormat:@"Pin-ctls: 0x%02X:", hdaWidgetEntry->DefaultPinControl]; 230 | if (hdaWidgetEntry->DefaultPinControl & HDA_PIN_WIDGET_CONTROL_VREF_EN) 231 | [outputString appendFormat:@" VREF"]; 232 | if (hdaWidgetEntry->DefaultPinControl & HDA_PIN_WIDGET_CONTROL_IN_EN) 233 | [outputString appendFormat:@" IN"]; 234 | if (hdaWidgetEntry->DefaultPinControl & HDA_PIN_WIDGET_CONTROL_OUT_EN) 235 | [outputString appendFormat:@" OUT"]; 236 | if (hdaWidgetEntry->DefaultPinControl & HDA_PIN_WIDGET_CONTROL_HP_EN) 237 | [outputString appendFormat:@" HP"]; 238 | [outputString appendFormat:@"\n"]; 239 | } 240 | 241 | uint32_t connectionListSize = 0; 242 | 243 | // Print connections. 244 | if (hdaWidgetEntry->Capabilities & HDA_PARAMETER_WIDGET_CAPS_CONN_LIST) { 245 | uint16_t *pConnections = (uint16_t *)(pData + sizeof(HdaWidgetEntry) + ampInSize); 246 | connectionListSize = connectionListLength * sizeof(uint16_t); 247 | [outputString appendFormat:@" Connection: %u\n ", connectionListLength]; 248 | for (uint8_t i = 0; i < connectionListLength; i++) 249 | [outputString appendFormat:@" 0x%02X", pConnections[i]]; 250 | [outputString appendFormat:@"\n"]; 251 | } 252 | 253 | uint32_t widgetSize = sizeof(HdaWidgetEntry) + ampInSize + connectionListSize; 254 | 255 | pData += widgetSize; 256 | totalWidgetSize += widgetSize; 257 | 258 | hdaWidgetEntry = (HdaWidgetEntry *)pData; 259 | } 260 | 261 | return totalWidgetSize; 262 | } 263 | 264 | int HdaCodecDump(uint8_t *hdaCodecData, uint32_t length, NSMutableString **outputString) 265 | { 266 | uint8_t *pHdaCodecData = hdaCodecData; 267 | 268 | if (length < sizeof(HdaCodecEntry)) 269 | return 1; 270 | 271 | if (pHdaCodecData[0] != 'H' || pHdaCodecData[1] != 'D' || pHdaCodecData[2] != 'A') 272 | return 1; 273 | 274 | pHdaCodecData += 4; 275 | 276 | while ((pHdaCodecData - hdaCodecData) < length) 277 | { 278 | HdaCodecEntry *hdaCodecEntry = (HdaCodecEntry *)pHdaCodecData; 279 | uint32_t widgetCount = hdaCodecEntry->WidgetCount; 280 | 281 | [*outputString appendFormat:@"HdaCodecDump start\n"]; 282 | [*outputString appendFormat:@"Codec: %s\n", hdaCodecEntry->Name]; 283 | 284 | [*outputString appendFormat:@"AFG Function Id: 0x%02X (unsol %u)\n", hdaCodecEntry->AudioFuncID, hdaCodecEntry->Unsol]; 285 | [*outputString appendFormat:@"Vendor ID: 0x%08X\n", hdaCodecEntry->VendorID]; 286 | [*outputString appendFormat:@"Revision ID: 0x%08X\n", hdaCodecEntry->RevisionID]; 287 | 288 | if ((hdaCodecEntry->Rates != 0) || (hdaCodecEntry->Formats != 0)) { 289 | [*outputString appendFormat:@"Default PCM:\n"]; 290 | HdaCodecDumpPrintRatesFormats(*outputString, hdaCodecEntry->Rates, hdaCodecEntry->Formats); 291 | } else 292 | [*outputString appendFormat:@"Default PCM: N/A\n"]; 293 | 294 | [*outputString appendFormat:@"Default Amp-In caps: "]; 295 | HdaCodecDumpPrintAmpCaps(*outputString, hdaCodecEntry->AmpInCaps); 296 | [*outputString appendFormat:@"Default Amp-Out caps: "]; 297 | HdaCodecDumpPrintAmpCaps(*outputString, hdaCodecEntry->AmpOutCaps); 298 | 299 | pHdaCodecData += sizeof(HdaCodecEntry); 300 | 301 | uint32_t widgetSize = HdaCodecDumpPrintWidgets(*outputString, pHdaCodecData, widgetCount); 302 | 303 | pHdaCodecData += widgetSize; 304 | } 305 | 306 | //printf("%s", [*outputString UTF8String]); 307 | 308 | return 0; 309 | } 310 | -------------------------------------------------------------------------------- /PinConfigurator/HdaVerbs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: HdaVerbs.h 3 | * 4 | * Copyright (c) 2018 John Davis 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #ifndef _EFI_HDA_VERBS_H_ 26 | #define _EFI_HDA_VERBS_H_ 27 | 28 | #define BIT0 0x00000001 29 | #define BIT1 0x00000002 30 | #define BIT2 0x00000004 31 | #define BIT3 0x00000008 32 | #define BIT4 0x00000010 33 | #define BIT5 0x00000020 34 | #define BIT6 0x00000040 35 | #define BIT7 0x00000080 36 | #define BIT8 0x00000100 37 | #define BIT9 0x00000200 38 | #define BIT10 0x00000400 39 | #define BIT11 0x00000800 40 | #define BIT12 0x00001000 41 | #define BIT13 0x00002000 42 | #define BIT14 0x00004000 43 | #define BIT15 0x00008000 44 | #define BIT16 0x00010000 45 | #define BIT17 0x00020000 46 | #define BIT18 0x00040000 47 | #define BIT19 0x00080000 48 | #define BIT20 0x00100000 49 | #define BIT21 0x00200000 50 | #define BIT22 0x00400000 51 | #define BIT23 0x00800000 52 | #define BIT24 0x01000000 53 | #define BIT25 0x02000000 54 | #define BIT26 0x04000000 55 | #define BIT27 0x08000000 56 | #define BIT28 0x10000000 57 | #define BIT29 0x20000000 58 | #define BIT30 0x40000000 59 | #define BIT31 0x80000000 60 | 61 | // Root node ID. 62 | #define HDA_NID_ROOT 0 63 | 64 | // Macro for building verbs. 4-bit verbs will be zero when masked against 0xFF0. 65 | #define HDA_CODEC_VERB(Verb, Payload) ((UINT32)((((Verb) & 0xFFF) & 0xFF0) ? \ 66 | ((((Verb) & 0xFFF) << 8) | ((Payload) & 0xFF)) : /* 12-bit verbs */ \ 67 | ((((Verb) & 0xF) << 16) | ((Payload) & 0xFFFF)))) /* 4-bit verbs */ 68 | 69 | // Get/Set Converter Format. 70 | #define HDA_VERB_GET_CONVERTER_FORMAT 0xA 71 | #define HDA_VERB_SET_CONVERTER_FORMAT 0x2 72 | #define HDA_CONVERTER_FORMAT_CHAN(a) ((uint8_t)((a) & 0xF)) 73 | #define HDA_CONVERTER_FORMAT_BITS(a) ((uint8_t)(((a) >> 4) & 0x3)) 74 | #define HDA_CONVERTER_FORMAT_BITS_8 0x0 75 | #define HDA_CONVERTER_FORMAT_BITS_16 0x1 76 | #define HDA_CONVERTER_FORMAT_BITS_20 0x2 77 | #define HDA_CONVERTER_FORMAT_BITS_24 0x3 78 | #define HDA_CONVERTER_FORMAT_BITS_32 0x4 79 | #define HDA_CONVERTER_FORMAT_DIV(a) ((uint8_t)(((a) >> 8) & 0x3)) 80 | #define HDA_CONVERTER_FORMAT_MULT(a) ((uint8_t)(((a) >> 11) & 0x3)) 81 | #define HDA_CONVERTER_FORMAT_BASE_44KHZ BIT14 82 | #define HDA_CONVERTER_FORMAT_SET(chan, bits, div, mult, base) \ 83 | ((UINT16)(((chan) & 0xF) | (((bits) & 0x3) << 4) | (((div) & 0x3) << 8) | \ 84 | (((mult) & 0x3) << 11) | ((base) ? HDA_CONVERTER_FORMAT_BASE_44KHZ : 0))) 85 | 86 | // Get Amplifier Gain/Mute. 87 | #define HDA_VERB_GET_AMP_GAIN_MUTE 0xB 88 | #define HDA_VERB_GET_AMP_GAIN_MUTE_PAYLOAD(index, left, out) ((UINT16)(index | (left ? BIT13 : 0) | (out ? BIT15 : 0))) 89 | #define HDA_VERB_GET_AMP_GAIN_MUTE_GAIN(a) ((uint8_t)(a & 0x7F)) 90 | #define HDA_VERB_GET_AMP_GAIN_MUTE_MUTE BIT7 91 | 92 | // Set Amplifier Gain/Mute. 93 | #define HDA_VERB_SET_AMP_GAIN_MUTE 0x3 94 | #define HDA_VERB_SET_AMP_GAIN_MUTE_PAYLOAD(index, gain, mute, right, left, in, out) \ 95 | ((UINT16)((gain & 0x7F) | (mute ? BIT7 : 0) | (index & 0xFF) << 8) \ 96 | | (right ? BIT12 : 0) | (left ? BIT13 : 0) | (in ? BIT14 : 0) | (out ? BIT15 : 0)) 97 | 98 | // Get/Set Processing Coefficient. 99 | #define HDA_VERB_GET_PROCESSING_COEFFICIENT 0xC 100 | #define HDA_VERB_SET_PROCESSING_COEFFICIENT 0x4 101 | 102 | // Get/Set Coefficient Index. 103 | #define HDA_VERB_GET_COEFFICIENT_INDEX 0xD 104 | #define HDA_VERB_SET_COEFFICIENT_INDEX 0x5 105 | 106 | // Get/Set Connection Select Control. 107 | #define HDA_VERB_GET_CONN_SELECT_CONTROL 0xF01 108 | #define HDA_VERB_SET_CONN_SELECT_CONTROL 0x701 109 | 110 | // Get Connection List Entry. 111 | #define HDA_VERB_GET_CONN_LIST_ENTRY 0xF02 112 | #define HDA_VERB_GET_CONN_LIST_ENTRY_SHORT(a, i) ((uint8_t)(a >> (8 * (i)))) 113 | #define HDA_VERB_GET_CONN_LIST_ENTRY_LONG(a, i) ((UINT16)(a >> (16 * (i)))) 114 | 115 | // Get/Set Processing State. 116 | #define HDA_VERB_GET_PROCESSING_STATE 0xF03 117 | #define HDA_VERB_SET_PROCESSING_STATE 0x703 118 | #define HDA_PROCESSING_STATE_OFF 0x00 119 | #define HDA_PROCESSING_STATE_ON 0x01 120 | #define HDA_PROCESSING_STATE_BENIGN 0x02 121 | 122 | // Get/Set Input Converter SDI Select. 123 | #define HDA_VERB_GET_INPUT_CONV_SDI_SELECT 0xF04 124 | #define HDA_VERB_SET_INPUT_CONV_SDI_SELECT 0x704 125 | 126 | // Get/Set Power State. 127 | #define HDA_VERB_GET_POWER_STATE 0xF05 128 | #define HDA_VERB_SET_POWER_STATE 0x705 129 | 130 | // Get/Set Converter Stream, Channel. 131 | #define HDA_VERB_GET_CONVERTER_STREAM_CHANNEL 0xF06 132 | #define HDA_VERB_SET_CONVERTER_STREAM_CHANNEL 0x706 133 | #define HDA_VERB_GET_CONVERTER_STREAM_CHAN(a) ((uint8_t)(a & 0xF)) 134 | #define HDA_VERB_GET_CONVERTER_STREAM_STR(a) ((uint8_t)((a >> 4) & 0xF)) 135 | #define HDA_VERB_SET_CONVERTER_STREAM_PAYLOAD(c, s) ((uint8_t)(((c) & 0xF) | (((s) & 0xF) << 4))) 136 | 137 | // Get/Set Pin Widget Control. 138 | #define HDA_VERB_GET_PIN_WIDGET_CONTROL 0xF07 139 | #define HDA_VERB_SET_PIN_WIDGET_CONTROL 0x707 140 | #define HDA_PIN_WIDGET_CONTROL_VREF(a) ((uint8_t)(a & 0x3)) 141 | #define HDA_PIN_WIDGET_CONTROL_VREF_EN BIT2 142 | #define HDA_PIN_WIDGET_CONTROL_IN_EN BIT5 143 | #define HDA_PIN_WIDGET_CONTROL_OUT_EN BIT6 144 | #define HDA_PIN_WIDGET_CONTROL_HP_EN BIT7 145 | #define HDA_VERB_SET_PIN_WIDGET_CONTROL_PAYLOAD(vref, vrefEn, in, out, hp) \ 146 | ((uint8_t)(HDA_PIN_WIDGET_CONTROL_VREF(vref) | (vrefEn ? HDA_PIN_WIDGET_CONTROL_VREF_EN : 0) \ 147 | | (in ? HDA_PIN_WIDGET_CONTROL_IN_EN : 0) | (out ? HDA_PIN_WIDGET_CONTROL_OUT_EN : 0) \ 148 | | (hp ? HDA_PIN_WIDGET_CONTROL_HP_EN : 0))) 149 | 150 | // Get/Set Unsolicited Response. 151 | #define HDA_VERB_GET_UNSOL_RESPONSE 0xF08 152 | #define HDA_VERB_SET_UNSOL_RESPONSE 0x708 153 | #define HDA_UNSOL_RESPONSE_EN BIT7 154 | 155 | 156 | // Get/Set Digital Converter Control. 157 | #define HDA_VERB_GET_DIGITAL_CONV_CONTROL 0xF0D 158 | #define HDA_VERB_SET_DIGITAL_CONV_CONTROL1 0x70D 159 | #define HDA_VERB_SET_DIGITAL_CONV_CONTROL2 0x70E 160 | #define HDA_VERB_SET_DIGITAL_CONV_CONTROL3 0x73E 161 | #define HDA_VERB_SET_DIGITAL_CONV_CONTROL4 0x73F 162 | #define HDA_DIGITAL_CONV_CONTROL_DIGEN BIT0 163 | #define HDA_DIGITAL_CONV_CONTROL_V BIT1 164 | #define HDA_DIGITAL_CONV_CONTROL_VCFG BIT2 165 | #define HDA_DIGITAL_CONV_CONTROL_PRE BIT3 166 | #define HDA_DIGITAL_CONV_CONTROL_NO_CP BIT4 167 | #define HDA_DIGITAL_CONV_CONTROL_NO_AUDIO BIT5 168 | #define HDA_DIGITAL_CONV_CONTROL_PRO BIT6 169 | #define HDA_DIGITAL_CONV_CONTROL_L BIT7 170 | #define HDA_DIGITAL_CONV_CONTROL_CC(a) ((uint8_t)((a >> 8) & 0x7F)) 171 | #define HDA_DIGITAL_CONV_CONTROL_ICT ((uint8_t)((a >> 16) & 0xF)) 172 | #define HDA_DIGITAL_CONV_CONTROL_KAE BIT23 173 | 174 | // Get/Execute Pin Sense. 175 | #define HDA_VERB_GET_PIN_SENSE 0xF09 176 | #define HDA_VERB_EXE_PIN_SENSE 0x709 177 | #define HDA_PIN_SENSE_PD BIT31 178 | 179 | // Get/Set Beep Generation. 180 | #define HDA_VERB_GET_BEEP_GENERATION 0xF0A 181 | #define HDA_VERB_SET_BEEP_GENERATION 0x70A 182 | 183 | // Get/Set EAPD/BTL Enable. 184 | #define HDA_VERB_GET_EAPD_BTL_ENABLE 0xF0C 185 | #define HDA_VERB_SET_EAPD_BTL_ENABLE 0x70C 186 | #define HDA_EAPD_BTL_ENABLE_BTL BIT0 187 | #define HDA_EAPD_BTL_ENABLE_EAPD BIT1 188 | #define HDA_EAPD_BTL_ENABLE_L_R_SWAP BIT2 189 | 190 | // Get/Set Volume Knob. 191 | #define HDA_VERB_GET_VOLUME_KNOB 0xF0F 192 | #define HDA_VERB_SET_VOLUME_KNOB 0x70F 193 | #define HDA_VOLUME_KNOB_DIRECT BIT7 194 | 195 | // Get/Set GPI Data. 196 | #define HDA_VERB_GET_GPI_DATA 0xF10 197 | #define HDA_VERB_SET_GPI_DATA 0x710 198 | 199 | // Get/Set GPI Wake Enable Mask. 200 | #define HDA_VERB_GET_GPI_WAKE_ENABLE_MASK 0xF11 201 | #define HDA_VERB_SET_GPI_WAKE_ENABLE_MASK 0x711 202 | 203 | // Get/Set GPI Unsolicited Enable Mask. 204 | #define HDA_VERB_GET_GPI_UNSOL_ENABLE_MASK 0xF12 205 | #define HDA_VERB_SET_GPI_UNSOL_ENABLE_MASK 0x712 206 | 207 | // Get/Set GPI Sticky Mask. 208 | #define HDA_VERB_GET_GPI_STICK_MASK 0xF13 209 | #define HDA_VERB_SET_GPI_STICK_MASK 0x713 210 | 211 | // Get/Set GPO Data. 212 | #define HDA_VERB_GET_GPO_DATA 0xF14 213 | #define HDA_VERB_SET_GPO_DATA 0x714 214 | 215 | // Get/Set GPIO Data. 216 | #define HDA_VERB_GET_GPIO_DATA 0xF15 217 | #define HDA_VERB_SET_GPIO_DATA 0x715 218 | 219 | // Get/Set GPIO Enable Mask. 220 | #define HDA_VERB_GET_GPIO_ENABLE_MASK 0xF16 221 | #define HDA_VERB_SET_GPIO_ENABLE_MASK 0x716 222 | 223 | // Get/Set GPIO Direction. 224 | #define HDA_VERB_GET_GPIO_DIRECTION 0xF17 225 | #define HDA_VERB_SET_GPIO_DIRECTION 0x717 226 | 227 | // Get/Set GPIO Wake Enable Mask. 228 | #define HDA_VERB_GET_GPIO_WAKE_ENABLE_MASK 0xF18 229 | #define HDA_VERB_SET_GPIO_WAKE_ENABLE_MASK 0x718 230 | 231 | // Get/Set GPIO Unsolicited Enable Mask. 232 | #define HDA_VERB_GET_GPIO_UNSOL_ENABLE_MASK 0xF19 233 | #define HDA_VERB_SET_GPIO_UNSOL_ENABLE_MASK 0x719 234 | 235 | // Get/Set GPIO Sticky Mask. 236 | #define HDA_VERB_GET_GPIO_STICKY_MASK 0xF1A 237 | #define HDA_VERB_SET_GPIO_STICKY_MASK 0x71A 238 | 239 | // Get/Set Implementation Identification. 240 | #define HDA_VERB_GET_IMPLEMENTATION_ID 0xF20 241 | #define HDA_VERB_SET_IMPLEMENTATION_ID1 0x720 242 | #define HDA_VERB_SET_IMPLEMENTATION_ID2 0x721 243 | #define HDA_VERB_SET_IMPLEMENTATION_ID3 0x722 244 | #define HDA_VERB_SET_IMPLEMENTATION_ID4 0x723 245 | 246 | // 247 | // Get/Set Configuration Default. 248 | // 249 | #define HDA_VERB_GET_CONFIGURATION_DEFAULT 0xF1C 250 | #define HDA_VERB_SET_CONFIGURATION_DEFAULT0 0x71C 251 | #define HDA_VERB_SET_CONFIGURATION_DEFAULT1 0x71D 252 | #define HDA_VERB_SET_CONFIGURATION_DEFAULT2 0x71E 253 | #define HDA_VERB_SET_CONFIGURATION_DEFAULT3 0x71F 254 | 255 | // Configuration Default sequence. 256 | #define HDA_VERB_GET_CONFIGURATION_DEFAULT_SEQUENCE(a) \ 257 | ((uint8_t)(a & 0xF)) 258 | 259 | // Configuration Default default associaton. 260 | #define HDA_VERB_GET_CONFIGURATION_DEFAULT_ASSOCIATION(a) \ 261 | ((uint8_t)((a >> 4) & 0xF)) 262 | 263 | // Configuration Default misc. 264 | #define HDA_CONFIG_DEFAULT_MISC_JACK_DETECT_OVERRIDE BIT8 265 | 266 | // Configuration Default color. 267 | #define HDA_VERB_GET_CONFIGURATION_DEFAULT_COLOR(a) \ 268 | ((uint8_t)((a >> 12) & 0xF)) 269 | #define HDA_CONFIG_DEFAULT_COLOR_UNKNOWN 0x0 270 | #define HDA_CONFIG_DEFAULT_COLOR_BLACK 0x1 271 | #define HDA_CONFIG_DEFAULT_COLOR_GREY 0x2 272 | #define HDA_CONFIG_DEFAULT_COLOR_BLUE 0x3 273 | #define HDA_CONFIG_DEFAULT_COLOR_GREEN 0x4 274 | #define HDA_CONFIG_DEFAULT_COLOR_RED 0x5 275 | #define HDA_CONFIG_DEFAULT_COLOR_ORANGE 0x6 276 | #define HDA_CONFIG_DEFAULT_COLOR_YELLOW 0x7 277 | #define HDA_CONFIG_DEFAULT_COLOR_PURPLE 0x8 278 | #define HDA_CONFIG_DEFAULT_COLOR_PINK 0x9 279 | #define HDA_CONFIG_DEFAULT_COLOR_WHITE 0xE 280 | #define HDA_CONFIG_DEFAULT_COLOR_OTHER 0xF 281 | 282 | // Configuration Default connection type. 283 | #define HDA_VERB_GET_CONFIGURATION_DEFAULT_CONN_TYPE(a) \ 284 | ((uint8_t)((a >> 16) & 0xF)) 285 | #define HDA_CONFIG_DEFAULT_CONN_UNKNOWN 0x0 286 | #define HDA_CONFIG_DEFAULT_CONN_1_8_STEREO 0x1 287 | #define HDA_CONFIG_DEFAULT_CONN_1_4_STEREO 0x2 288 | #define HDA_CONFIG_DEFAULT_CONN_ATAPI 0x3 289 | #define HDA_CONFIG_DEFAULT_CONN_RCA 0x4 290 | #define HDA_CONFIG_DEFAULT_CONN_OPTICAL 0x5 291 | #define HDA_CONFIG_DEFAULT_CONN_DIGITAL_OTHER 0x6 292 | #define HDA_CONFIG_DEFAULT_CONN_ANALOG_OTHER 0x7 293 | #define HDA_CONFIG_DEFAULT_CONN_MULTI_ANALOG 0x8 294 | #define HDA_CONFIG_DEFAULT_CONN_XLR 0x9 295 | #define HDA_CONFIG_DEFAULT_CONN_RJ11 0xA 296 | #define HDA_CONFIG_DEFAULT_CONN_COMBO 0xB 297 | #define HDA_CONFIG_DEFAULT_CONN_OTHER 0xF 298 | 299 | // Configuration Default default device. 300 | #define HDA_VERB_GET_CONFIGURATION_DEFAULT_DEVICE(a) \ 301 | ((uint8_t)((a >> 20) & 0xF)) 302 | #define HDA_CONFIG_DEFAULT_DEVICE_LINE_OUT 0x0 303 | #define HDA_CONFIG_DEFAULT_DEVICE_SPEAKER 0x1 304 | #define HDA_CONFIG_DEFAULT_DEVICE_HEADPHONE_OUT 0x2 305 | #define HDA_CONFIG_DEFAULT_DEVICE_CD 0x3 306 | #define HDA_CONFIG_DEFAULT_DEVICE_SPDIF_OUT 0x4 307 | #define HDA_CONFIG_DEFAULT_DEVICE_OTHER_DIGITAL_OUT 0x5 308 | #define HDA_CONFIG_DEFAULT_DEVICE_MODEM_LINE 0x6 309 | #define HDA_CONFIG_DEFAULT_DEVICE_MODEM_HANDSET 0x7 310 | #define HDA_CONFIG_DEFAULT_DEVICE_LINE_IN 0x8 311 | #define HDA_CONFIG_DEFAULT_DEVICE_AUX 0x9 312 | #define HDA_CONFIG_DEFAULT_DEVICE_MIC_IN 0xA 313 | #define HDA_CONFIG_DEFAULT_DEVICE_TELEPHONY 0xB 314 | #define HDA_CONFIG_DEFAULT_DEVICE_SPDIF_IN 0xC 315 | #define HDA_CONFIG_DEFAULT_DEVICE_OTHER_DIGITAL_IN 0xD 316 | #define HDA_CONFIG_DEFAULT_DEVICE_OTHER 0xF 317 | 318 | // Configuration Default location. 319 | #define HDA_VERB_GET_CONFIGURATION_DEFAULT_LOC(a) \ 320 | ((uint8_t)((a >> 24) & 0xF)) 321 | #define HDA_CONFIG_DEFAULT_LOC_SPEC_NA 0x0 322 | #define HDA_CONFIG_DEFAULT_LOC_SPEC_REAR 0x1 323 | #define HDA_CONFIG_DEFAULT_LOC_SPEC_FRONT 0x2 324 | #define HDA_CONFIG_DEFAULT_LOC_SPEC_LEFT 0x3 325 | #define HDA_CONFIG_DEFAULT_LOC_SPEC_RIGHT 0x4 326 | #define HDA_CONFIG_DEFAULT_LOC_SPEC_TOP 0x5 327 | #define HDA_CONFIG_DEFAULT_LOC_SPEC_BOTTOM 0x6 328 | 329 | #define HDA_VERB_GET_CONFIGURATION_DEFAULT_SURF(a) \ 330 | ((uint8_t)((a >> 28) & 0x3)) 331 | #define HDA_CONFIG_DEFAULT_LOC_SURF_EXTERNAL 0x0 332 | #define HDA_CONFIG_DEFAULT_LOC_SURF_INTERNAL 0x1 333 | #define HDA_CONFIG_DEFAULT_LOC_SURF_SEPARATE 0x2 334 | #define HDA_CONFIG_DEFAULT_LOC_SURF_OTHER 0x3 335 | 336 | // Configuration Default port connectivity. 337 | #define HDA_VERB_GET_CONFIGURATION_DEFAULT_PORT_CONN(a) \ 338 | ((uint8_t)((a >> 30) & 0x3)) 339 | #define HDA_CONFIG_DEFAULT_PORT_CONN_JACK 0x0 340 | #define HDA_CONFIG_DEFAULT_PORT_CONN_NONE 0x1 341 | #define HDA_CONFIG_DEFAULT_PORT_CONN_FIXED_DEVICE 0x2 342 | #define HDA_CONFIG_DEFAULT_PORT_CONN_INT_JACK 0x3 343 | 344 | // Configuration Default payload set. 345 | #define HDA_VERB_SET_CONFIGURATION_DEFAULT_PAYLOAD(seq, assoc, jacko, color, connType, device, loc, surf, portConn) \ 346 | ((UINT32)(((seq) & 0xF) | (((assoc) & 0xF) << 4) | (jacko ? HDA_CONFIG_DEFAULT_MISC_JACK_DETECT_OVERRIDE : 0) \ 347 | | (((color) & 0xF) << 12) | (((connType) & 0xF) << 16) | (((device) & 0xF) << 20) | (((loc) & 0x3) << 24) \ 348 | | (((surf) & 0x3) << 28) | (((portConn) & 0x3) << 30))) 349 | 350 | // Get/Set Stripe Control. 351 | #define HDA_VERB_GET_STRIPE_CONTROL 0xF24 352 | #define HDA_VERB_SET_STRIPE_CONTROL 0x724 353 | 354 | // Get/Set Converter Channel Count. 355 | #define HDA_VERB_GET_CONVERTER_CHANNEL_COUNT 0xF2D 356 | #define HDA_VERB_SET_CONVERTER_CHANNEL_COUNT 0x72D 357 | 358 | // Get Data Island Packet - Size Info. 359 | #define HDA_VERB_GET_DATA_ISLAND_PACKET_SIZE 0xF2E 360 | 361 | // Get EDID-Like Data (ELD). 362 | #define HDA_VERB_GET_EDID_LIKE_DATA 0xF2F 363 | 364 | // Get/Set Data Island Packet - Index. 365 | #define HDA_VERB_GET_DATA_ISLAND_PACKET_INDEX 0xF30 366 | #define HDA_VERB_SET_DATA_ISLAND_PACKET_INDEX 0x730 367 | 368 | // Get/Set Data Island Packet – Data. 369 | #define HDA_VERB_GET_DATA_ISLAND_PACKET_DATA 0xF31 370 | #define HDA_VERB_SET_DATA_ISLAND_PACKET_DATA 0x731 371 | 372 | // Get/Set Data Island Packet – Transmit Control. 373 | #define HDA_VERB_GET_DATA_ISLAND_PACKET_XMIT 0xF32 374 | #define HDA_VERB_SET_DATA_ISLAND_PACKET_XMIT 0x732 375 | 376 | // Get/Set Content Protection Control (CP_CONTROL). 377 | #define HDA_VERB_GET_CP_CONTROL 0xF33 378 | #define HDA_VERB_SET_CP_CONTROL 0x733 379 | 380 | // Get/Set ASP Channel Mapping. 381 | #define HDA_VERB_GET_ASP_MAPPING 0xF34 382 | #define HDA_VERB_SET_ASP_MAPPING 0x734 383 | 384 | // Execute Function Reset. 385 | #define HDA_VERB_EXE_FUNC_RESET 0x7FF 386 | 387 | // Get Parameter. 388 | #define HDA_VERB_GET_PARAMETER 0xF00 389 | 390 | // 391 | // Parameters. 392 | // 393 | // Vendor ID. 394 | #define HDA_PARAMETER_VENDOR_ID 0x00 395 | #define HDA_PARAMETER_VENDOR_ID_DEV(a) ((UINT16)a) 396 | #define HDA_PARAMETER_VENDOR_ID_VEN(a) ((UINT16)(a >> 16)) 397 | 398 | // Revision ID. 399 | #define HDA_PARAMETER_REVISION_ID 0x02 400 | #define HDA_PARAMETER_REVISION_ID_STEPPING(a) ((uint8_t)a) 401 | #define HDA_PARAMETER_REVISION_ID_REV_ID(a) ((uint8_t)(a >> 8)) 402 | #define HDA_PARAMETER_REVISION_ID_MINOR_REV(a) ((uint8_t)((a >> 16) & 0xF)) 403 | #define HDA_PARAMETER_REVISION_ID_MAJOR_REV(a) ((uint8_t)((a >> 20) & 0xF)) 404 | 405 | // Subordinate Node Count. 406 | #define HDA_PARAMETER_SUBNODE_COUNT 0x04 407 | #define HDA_PARAMETER_SUBNODE_COUNT_TOTAL(a) ((uint8_t)a); 408 | #define HDA_PARAMETER_SUBNODE_COUNT_START(a) ((uint8_t)(a >> 16)); 409 | 410 | // Function Group Type. 411 | #define HDA_PARAMETER_FUNC_GROUP_TYPE 0x05 412 | #define HDA_PARAMETER_FUNC_GROUP_TYPE_NODETYPE(a) ((uint8_t)a) 413 | #define HDA_PARAMETER_FUNC_GROUP_TYPE_UNSOL BIT8 414 | #define HDA_FUNC_GROUP_TYPE_AUDIO 0x01 415 | #define HDA_FUNC_GROUP_TYPE_MODEM 0x02 416 | 417 | // Audio Function Group Capabilities. 418 | #define HDA_PARAMETER_FUNC_GROUP_CAPS 0x08 419 | #define HDA_PARAMETER_FUNC_GROUP_CAPS_OUT_DELAY(a) ((uint8_t)(a & 0xF)) 420 | #define HDA_PARAMETER_FUNC_GROUP_CAPS_IN_DELAY(a) ((uint8_t)((a >> 8) & 0xF)) 421 | #define HDA_PARAMETER_FUNC_GROUP_CAPS_BEEP_GEN BIT16 422 | 423 | // Audio Widget Capabilities. 424 | #define HDA_PARAMETER_WIDGET_CAPS 0x09 425 | #define HDA_PARAMETER_WIDGET_CAPS_STEREO BIT0 426 | #define HDA_PARAMETER_WIDGET_CAPS_IN_AMP BIT1 427 | #define HDA_PARAMETER_WIDGET_CAPS_OUT_AMP BIT2 428 | #define HDA_PARAMETER_WIDGET_CAPS_AMP_OVERRIDE BIT3 429 | #define HDA_PARAMETER_WIDGET_CAPS_FORMAT_OVERRIDE BIT4 430 | #define HDA_PARAMETER_WIDGET_CAPS_STRIPE BIT5 431 | #define HDA_PARAMETER_WIDGET_CAPS_PROC_WIDGET BIT6 432 | #define HDA_PARAMETER_WIDGET_CAPS_UNSOL_CAPABLE BIT7 433 | #define HDA_PARAMETER_WIDGET_CAPS_CONN_LIST BIT8 434 | #define HDA_PARAMETER_WIDGET_CAPS_DIGITAL BIT9 435 | #define HDA_PARAMETER_WIDGET_CAPS_POWER_CNTRL BIT10 436 | #define HDA_PARAMETER_WIDGET_CAPS_L_R_SWAP BIT11 437 | #define HDA_PARAMETER_WIDGET_CAPS_CP_CAPS BIT12 438 | #define HDA_PARAMETER_WIDGET_CAPS_CHAN_COUNT(a) ((uint8_t)(((a >> 12) & 0xE) | (a & 0x1))) 439 | #define HDA_PARAMETER_WIDGET_CAPS_DELAY(a) ((uint8_t)((a >> 16) & 0xF)) 440 | #define HDA_PARAMETER_WIDGET_CAPS_TYPE(a) ((uint8_t)((a >> 20) & 0xF)) 441 | 442 | // Widget types. 443 | #define HDA_WIDGET_TYPE_OUTPUT 0x0 444 | #define HDA_WIDGET_TYPE_INPUT 0x1 445 | #define HDA_WIDGET_TYPE_MIXER 0x2 446 | #define HDA_WIDGET_TYPE_SELECTOR 0x3 447 | #define HDA_WIDGET_TYPE_PIN_COMPLEX 0x4 448 | #define HDA_WIDGET_TYPE_POWER 0x5 449 | #define HDA_WIDGET_TYPE_VOLUME_KNOB 0x6 450 | #define HDA_WIDGET_TYPE_BEEP_GEN 0x7 451 | #define HDA_WIDGET_TYPE_VENDOR 0xF 452 | 453 | // Supported PCM Size, Rates. 454 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES 0x0A 455 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_8KHZ BIT0 456 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_11KHZ BIT1 457 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_16KHZ BIT2 458 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_22KHZ BIT3 459 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_32KHZ BIT4 460 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_44KHZ BIT5 461 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_48KHZ BIT6 462 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_88KHZ BIT7 463 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_96KHZ BIT8 464 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_176KHZ BIT9 465 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_192KHZ BIT10 466 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_384KHZ BIT11 467 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_8BIT BIT16 468 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_16BIT BIT17 469 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_20BIT BIT18 470 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_24BIT BIT19 471 | #define HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_32BIT BIT20 472 | 473 | // Supported Stream Formats. 474 | #define HDA_PARAMETER_SUPPORTED_STREAM_FORMATS 0x0B 475 | #define HDA_PARAMETER_SUPPORTED_STREAM_FORMATS_PCM BIT0 476 | #define HDA_PARAMETER_SUPPORTED_STREAM_FORMATS_FLOAT32 BIT1 477 | #define HDA_PARAMETER_SUPPORTED_STREAM_FORMATS_AC3 BIT2 478 | 479 | // Pin Capabilities. 480 | #define HDA_PARAMETER_PIN_CAPS 0x0C 481 | #define HDA_PARAMETER_PIN_CAPS_IMPEDANCE BIT0 482 | #define HDA_PARAMETER_PIN_CAPS_TRIGGER BIT1 483 | #define HDA_PARAMETER_PIN_CAPS_PRESENCE BIT2 484 | #define HDA_PARAMETER_PIN_CAPS_HEADPHONE BIT3 485 | #define HDA_PARAMETER_PIN_CAPS_OUTPUT BIT4 486 | #define HDA_PARAMETER_PIN_CAPS_INPUT BIT5 487 | #define HDA_PARAMETER_PIN_CAPS_BALANCED BIT6 488 | #define HDA_PARAMETER_PIN_CAPS_HDMI BIT7 489 | #define HDA_PARAMETER_PIN_CAPS_VREF(a) ((uint8_t)(a >> 8)) 490 | #define HDA_PARAMETER_PIN_CAPS_EAPD BIT16 491 | #define HDA_PARAMETER_PIN_CAPS_DISPLAYPORT BIT24 492 | #define HDA_PARAMETER_PIN_CAPS_HBR BIT27 493 | 494 | // Amplifier Capabilities (input and output). 495 | #define HDA_PARAMETER_AMP_CAPS_INPUT 0x0D 496 | #define HDA_PARAMETER_AMP_CAPS_OUTPUT 0x12 497 | #define HDA_PARAMETER_AMP_CAPS_OFFSET(a) ((uint8_t)(a & 0x7F)) 498 | #define HDA_PARAMETER_AMP_CAPS_NUM_STEPS(a) ((uint8_t)((a >> 8) & 0x7F)) 499 | #define HDA_PARAMETER_AMP_CAPS_STEP_SIZE(a) ((uint8_t)((a >> 16) & 0x7F)) 500 | #define HDA_PARAMETER_AMP_CAPS_MUTE BIT31 501 | 502 | // Connection List Length. 503 | #define HDA_PARAMETER_CONN_LIST_LENGTH 0x0E 504 | #define HDA_PARAMETER_CONN_LIST_LENGTH_LEN(a) ((uint8_t)(a & 0x7F)) 505 | #define HDA_PARAMETER_CONN_LIST_LENGTH_LONG BIT7 506 | 507 | // Supported Power States. 508 | #define HDA_PARAMETER_SUPPORTED_POWER_STATES 0x0F 509 | #define HDA_PARAMETER_SUPPORTED_POWER_STATES_D0 BIT0 510 | #define HDA_PARAMETER_SUPPORTED_POWER_STATES_D1 BIT1 511 | #define HDA_PARAMETER_SUPPORTED_POWER_STATES_D2 BIT2 512 | #define HDA_PARAMETER_SUPPORTED_POWER_STATES_D3 BIT3 513 | #define HDA_PARAMETER_SUPPORTED_POWER_STATES_D3_COLD BIT4 514 | #define HDA_PARAMETER_SUPPORTED_POWER_STATES_S3_D3_COLD BIT29 515 | #define HDA_PARAMETER_SUPPORTED_POWER_STATES_CLKSTOP BIT30 516 | #define HDA_PARAMETER_SUPPORTED_POWER_STATES_EPSS BIT31 517 | 518 | // Processing Capabilities. 519 | #define HDA_PARAMETER_PROCESSING_CAPS 0x10 520 | #define HDA_PARAMETER_PROCESSING_CAPS_BENIGN BIT0 521 | #define HDA_PARAMETER_PROCESSING_CAPS_NUM_COEFF(a) ((uint8_t)(a >> 8)) 522 | 523 | // GPIO Count. 524 | #define HDA_PARAMETER_GPIO_COUNT 0x11 525 | #define HDA_PARAMETER_GPIO_COUNT_NUM_GPIOS(a) ((uint8_t)a) 526 | #define HDA_PARAMETER_GPIO_COUNT_NUM_GPOS(a) ((uint8_t)(a >> 8)) 527 | #define HDA_PARAMETER_GPIO_COUNT_NUM_GPIS(a) ((uint8_t)(a >> 16)) 528 | #define HDA_PARAMETER_GPIO_COUNT_GPI_UNSOL BIT30 529 | #define HDA_PARAMETER_GPIO_COUNT_GPI_WAKE BIT31 530 | 531 | // Volume Knob Capabilities. 532 | #define HDA_PARAMETER_VOLUME_KNOB_CAPS 0x13 533 | #define HDA_PARAMETER_VOLUME_KNOB_CAPS_NUM_STEPS(a) ((uint8_t)(a & 0x7F)) 534 | #define HDA_PARAMETER_VOLUME_KNOB_CAPS_DELTA BIT7 535 | 536 | #endif 537 | -------------------------------------------------------------------------------- /PinConfigurator/IORegTools.h: -------------------------------------------------------------------------------- 1 | // 2 | // IORegTools.h 3 | // Hackintool 4 | // 5 | // Created by Ben Baker on 1/29/19. 6 | // Copyright © 2019 Ben Baker. All rights reserved. 7 | // 8 | 9 | #ifndef IORegTools_h 10 | #define IORegTools_h 11 | 12 | #import 13 | 14 | uint32_t propertyToUInt32(id value); 15 | bool getIORegAudioDeviceArray(NSMutableArray **audioDeviceArray); 16 | 17 | #endif /* IORegTools_hpp */ 18 | -------------------------------------------------------------------------------- /PinConfigurator/IORegTools.m: -------------------------------------------------------------------------------- 1 | // 2 | // IORegTools.m 3 | // Hackintool 4 | // 5 | // Created by Ben Baker on 1/29/19. 6 | // Copyright © 2019 Ben Baker. All rights reserved. 7 | // 8 | 9 | #include "IORegTools.h" 10 | #include "MiscTools.h" 11 | #include "AudioDevice.h" 12 | #include 13 | 14 | bool getIORegChild(io_service_t device, NSArray *nameArray, io_service_t *foundDevice, uint32_t *foundIndex, bool recursive) 15 | { 16 | io_iterator_t childIterator; 17 | kern_return_t kr = IORegistryEntryCreateIterator(device, kIOServicePlane, (recursive ? kIORegistryIterateRecursively : 0), &childIterator); 18 | 19 | if (kr != KERN_SUCCESS) 20 | return false; 21 | 22 | for (io_service_t childDevice; IOIteratorIsValid(childIterator) && (childDevice = IOIteratorNext(childIterator)); IOObjectRelease(childDevice)) 23 | { 24 | for (int i = 0; i < [nameArray count]; i++) 25 | { 26 | if (IOObjectConformsTo(childDevice, [[nameArray objectAtIndex:i] UTF8String])) 27 | { 28 | *foundDevice = childDevice; 29 | *foundIndex = i; 30 | 31 | IOObjectRelease(childIterator); 32 | 33 | return true; 34 | } 35 | } 36 | } 37 | 38 | return false; 39 | } 40 | 41 | bool getIORegParent(io_service_t device, NSString *name, io_service_t *foundDevice, bool recursive) 42 | { 43 | io_iterator_t parentIterator; 44 | kern_return_t kr = IORegistryEntryCreateIterator(device, kIOServicePlane, (recursive ? kIORegistryIterateRecursively : 0) | kIORegistryIterateParents, &parentIterator); 45 | 46 | if (kr != KERN_SUCCESS) 47 | return false; 48 | 49 | for (io_service_t parentDevice; IOIteratorIsValid(parentIterator) && (parentDevice = IOIteratorNext(parentIterator)); IOObjectRelease(parentDevice)) 50 | { 51 | if (IOObjectConformsTo(parentDevice, [name UTF8String])) 52 | { 53 | *foundDevice = parentDevice; 54 | 55 | IOObjectRelease(parentIterator); 56 | 57 | return true; 58 | } 59 | } 60 | 61 | return false; 62 | } 63 | 64 | uint32_t propertyToUInt32(id value) 65 | { 66 | if (value == nil) 67 | return 0; 68 | 69 | if ([value isKindOfClass:[NSNumber class]]) 70 | return [value unsignedIntValue]; 71 | else if ([value isKindOfClass:[NSData class]]) 72 | { 73 | NSData *data = (NSData *)value; 74 | uint32_t retVal = 0; 75 | 76 | memcpy(&retVal, data.bytes, MIN(data.length, 4)); 77 | 78 | return retVal; 79 | } 80 | 81 | return 0; 82 | } 83 | 84 | bool getIORegAudioDeviceArray(NSMutableArray **audioDeviceArray) 85 | { 86 | *audioDeviceArray = [[NSMutableArray array] retain]; 87 | io_iterator_t pciIterator; 88 | 89 | kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOPCIDevice"), &pciIterator); 90 | 91 | if (kr != KERN_SUCCESS) 92 | return false; 93 | 94 | io_iterator_t iterator; 95 | 96 | for (io_service_t pciDevice; IOIteratorIsValid(pciIterator) && (pciDevice = IOIteratorNext(pciIterator)); IOObjectRelease(pciDevice)) 97 | { 98 | kern_return_t kr = IORegistryEntryCreateIterator(pciDevice, kIOServicePlane, kIORegistryIterateRecursively, &iterator); 99 | 100 | if (kr != KERN_SUCCESS) 101 | continue; 102 | 103 | for (io_service_t device; IOIteratorIsValid(iterator) && (device = IOIteratorNext(iterator)); IOObjectRelease(device)) 104 | { 105 | if (IOObjectConformsTo(device, "IOPCIDevice")) 106 | { 107 | IOObjectRelease(device); 108 | break; 109 | } 110 | 111 | if (!IOObjectConformsTo(device, "IOAudioDevice")) 112 | continue; 113 | 114 | io_name_t className {}; 115 | kr = IOObjectGetClass(device, className); 116 | 117 | if (kr != KERN_SUCCESS) 118 | continue; 119 | 120 | CFMutableDictionaryRef propertyDictionaryRef = 0; 121 | 122 | kr = IORegistryEntryCreateCFProperties(device, &propertyDictionaryRef, kCFAllocatorDefault, kNilOptions); 123 | 124 | if (kr == KERN_SUCCESS) 125 | { 126 | NSMutableDictionary *propertyDictionary = (__bridge NSMutableDictionary *)propertyDictionaryRef; 127 | 128 | NSString *bundleID = [propertyDictionary objectForKey:@"CFBundleIdentifier"]; 129 | NSString *audioDeviceName = [propertyDictionary objectForKey:@"IOAudioDeviceName"]; 130 | NSString *audioDeviceModelID = [propertyDictionary objectForKey:@"IOAudioDeviceModelID"]; 131 | NSString *audioDeviceManufacturerName = [propertyDictionary objectForKey:@"IOAudioDeviceManufacturerName"]; 132 | uint32_t audioDeviceDeviceID = 0, audioDeviceVendorID = 0; 133 | uint32_t audioDeviceDeviceIDNew = 0; 134 | 135 | if (audioDeviceModelID != nil) 136 | { 137 | NSArray *modelIDArray = [audioDeviceModelID componentsSeparatedByString:@":"]; 138 | 139 | if ([modelIDArray count] == 3) 140 | { 141 | NSScanner *deviceIDScanner = [NSScanner scannerWithString:[modelIDArray objectAtIndex:1]]; 142 | NSScanner *productIDScanner = [NSScanner scannerWithString:[modelIDArray objectAtIndex:2]]; 143 | 144 | [deviceIDScanner setScanLocation:0]; 145 | [deviceIDScanner scanHexInt:&audioDeviceVendorID]; 146 | 147 | [productIDScanner setScanLocation:0]; 148 | [productIDScanner scanHexInt:&audioDeviceDeviceID]; 149 | 150 | audioDeviceDeviceIDNew = (audioDeviceVendorID << 16) | audioDeviceDeviceID; 151 | } 152 | } 153 | 154 | io_service_t parentDevice; 155 | 156 | if (getIORegParent(device, @"IOPCIDevice", &parentDevice, true)) 157 | { 158 | CFMutableDictionaryRef parentPropertyDictionaryRef = 0; 159 | 160 | kr = IORegistryEntryCreateCFProperties(parentDevice, &parentPropertyDictionaryRef, kCFAllocatorDefault, kNilOptions); 161 | 162 | if (kr == KERN_SUCCESS) 163 | { 164 | NSMutableDictionary *parentPropertyDictionary = (__bridge NSMutableDictionary *)parentPropertyDictionaryRef; 165 | 166 | uint32_t deviceID = propertyToUInt32([parentPropertyDictionary objectForKey:@"device-id"]); 167 | uint32_t vendorID = propertyToUInt32([parentPropertyDictionary objectForKey:@"vendor-id"]); 168 | uint32_t revisionID = propertyToUInt32([parentPropertyDictionary objectForKey:@"revision-id"]); 169 | uint32_t alcLayoutID = propertyToUInt32([parentPropertyDictionary objectForKey:@"alc-layout-id"]); 170 | uint32_t subSystemID = propertyToUInt32([parentPropertyDictionary objectForKey:@"subsystem-id"]); 171 | uint32_t subSystemVendorID = propertyToUInt32([parentPropertyDictionary objectForKey:@"subsystem-vendor-id"]); 172 | 173 | uint32_t deviceIDNew = (vendorID << 16) | deviceID; 174 | uint32_t subDeviceIDNew = (subSystemVendorID << 16) | subSystemID; 175 | 176 | AudioDevice *audioDevice = [[AudioDevice alloc] initWithDeviceBundleID:bundleID deviceClass:[NSString stringWithUTF8String:className] audioDeviceName:audioDeviceName audioDeviceManufacturerName:audioDeviceManufacturerName audioDeviceModelID:audioDeviceDeviceIDNew deviceID:deviceIDNew revisionID:revisionID alcLayoutID:alcLayoutID subDeviceID:subDeviceIDNew]; 177 | 178 | io_service_t codecDevice; 179 | 180 | if (getIORegParent(device, @"IOHDACodecDevice", &codecDevice, true)) 181 | { 182 | CFMutableDictionaryRef codecPropertyDictionaryRef = 0; 183 | 184 | kr = IORegistryEntryCreateCFProperties(codecDevice, &codecPropertyDictionaryRef, kCFAllocatorDefault, kNilOptions); 185 | 186 | if (kr == KERN_SUCCESS) 187 | { 188 | NSMutableDictionary *codecPropertyDictionary = (__bridge NSMutableDictionary *)codecPropertyDictionaryRef; 189 | 190 | audioDevice.digitalAudioCapabilities = [codecPropertyDictionary objectForKey:@"DigitalAudioCapabilities"]; 191 | audioDevice.codecAddress = propertyToUInt32([codecPropertyDictionary objectForKey:@"IOHDACodecAddress"]); 192 | audioDevice.codecID = propertyToUInt32([codecPropertyDictionary objectForKey:@"IOHDACodecVendorID"]); 193 | audioDevice.revisionID = propertyToUInt32([codecPropertyDictionary objectForKey:@"IOHDACodecRevisionID"]); 194 | } 195 | } 196 | 197 | if (getIORegParent(device, @"AppleHDACodec", &codecDevice, true)) 198 | { 199 | CFMutableDictionaryRef codecPropertyDictionaryRef = 0; 200 | 201 | kr = IORegistryEntryCreateCFProperties(codecDevice, &codecPropertyDictionaryRef, kCFAllocatorDefault, kNilOptions); 202 | 203 | if (kr == KERN_SUCCESS) 204 | { 205 | NSMutableDictionary *codecPropertyDictionary = (__bridge NSMutableDictionary *)codecPropertyDictionaryRef; 206 | 207 | NSArray *hdaConfigDefaultArray = [codecPropertyDictionary objectForKey:@"HDAConfigDefault"]; 208 | 209 | if (hdaConfigDefaultArray != nil && [hdaConfigDefaultArray count] > 0) 210 | audioDevice.hdaConfigDefaultDictionary = [hdaConfigDefaultArray objectAtIndex:0]; 211 | } 212 | } 213 | 214 | [*audioDeviceArray addObject:audioDevice]; 215 | 216 | [audioDevice release]; 217 | } 218 | 219 | IOObjectRelease(parentDevice); 220 | } 221 | } 222 | } 223 | 224 | IOObjectRelease(iterator); 225 | } 226 | 227 | IOObjectRelease(pciIterator); 228 | 229 | return ([*audioDeviceArray count] > 0); 230 | } 231 | -------------------------------------------------------------------------------- /PinConfigurator/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSMainNibFile 26 | MainMenu 27 | NSPrincipalClass 28 | NSApplication 29 | 30 | 31 | -------------------------------------------------------------------------------- /PinConfigurator/MiscTools.h: -------------------------------------------------------------------------------- 1 | // 2 | // MiscTools.h 3 | // Hackintool 4 | // 5 | // Created by Ben Baker on 1/29/19. 6 | // Copyright © 2019 Ben Baker. All rights reserved. 7 | // 8 | 9 | #ifndef MiscTools_h 10 | #define MiscTools_h 11 | 12 | #import 13 | 14 | NSData *stringToData(NSString *dataString, int size); 15 | NSData *stringToData(NSString *dataString); 16 | uint32_t getReverseBytes(uint32_t value); 17 | NSData *getReverseData(NSData *data); 18 | NSData *getNSDataUInt32(uint32_t uint32Value, bool reverseBytes); 19 | NSData *getNSDataUInt32(uint32_t uint32Value); 20 | uint32_t getUInt32FromData(NSData *data); 21 | bool getRegExArray(NSString *regExPattern, NSString *valueString, uint32_t itemCount, NSMutableArray **itemArray); 22 | uint32_t getInt(NSString *valueString); 23 | uint32_t getHexInt(NSString *valueString); 24 | 25 | #endif /* MiscTools_hpp */ 26 | -------------------------------------------------------------------------------- /PinConfigurator/MiscTools.m: -------------------------------------------------------------------------------- 1 | // 2 | // MiscTools.m 3 | // Hackintool 4 | // 5 | // Created by Ben Baker on 1/29/19. 6 | // Copyright © 2019 Ben Baker. All rights reserved. 7 | // 8 | 9 | #include "MiscTools.h" 10 | 11 | NSData *stringToData(NSString *dataString, int size) 12 | { 13 | NSString *hexChars = @"0123456789abcdefABCDEF"; 14 | NSCharacterSet *hexCharSet = [NSCharacterSet characterSetWithCharactersInString:hexChars]; 15 | NSCharacterSet *invalidHexCharSet = [hexCharSet invertedSet]; 16 | NSString *cleanDataString = [dataString stringByReplacingOccurrencesOfString:@"0x" withString:@""]; 17 | cleanDataString = [[cleanDataString componentsSeparatedByCharactersInSet:invalidHexCharSet] componentsJoinedByString:@""]; 18 | 19 | NSMutableData *result = [[NSMutableData alloc] init]; 20 | 21 | for (int i = 0; i + size <= cleanDataString.length; i += size) 22 | { 23 | NSRange range = NSMakeRange(i, size); 24 | NSString *hexString = [cleanDataString substringWithRange:range]; 25 | NSScanner *scanner = [NSScanner scannerWithString:hexString]; 26 | unsigned int intValue; 27 | [scanner scanHexInt:&intValue]; 28 | unsigned char uc = (unsigned char)intValue; 29 | [result appendBytes:&uc length:1]; 30 | } 31 | 32 | NSData *resultData = [NSData dataWithData:result]; 33 | [result release]; 34 | 35 | return resultData; 36 | } 37 | 38 | NSData *stringToData(NSString *dataString) 39 | { 40 | return stringToData(dataString, 2); 41 | } 42 | 43 | uint32_t getReverseBytes(uint32_t value) 44 | { 45 | return ((value >> 24) & 0xFF) | ((value << 8) & 0xFF0000) | ((value >> 8) & 0xFF00) | ((value << 24) & 0xFF000000); 46 | } 47 | 48 | NSData *getReverseData(NSData *data) 49 | { 50 | const char *bytes = (const char *)[data bytes]; 51 | int idx = (int)[data length] - 1; 52 | char *reversedBytes = (char *)calloc(sizeof(char), [data length]); 53 | 54 | for (int i = 0; i < [data length]; i++) 55 | reversedBytes[idx--] = bytes[i]; 56 | 57 | NSData *reversedData = [NSData dataWithBytes:reversedBytes length:[data length]]; 58 | free(reversedBytes); 59 | 60 | return reversedData; 61 | } 62 | 63 | NSData *getNSDataUInt32(uint32_t uint32Value, bool reverseBytes) 64 | { 65 | NSData *data = [NSData dataWithBytes:&uint32Value length:sizeof(uint32Value)]; 66 | 67 | if (reverseBytes) 68 | return getReverseData(data); 69 | 70 | return data; 71 | } 72 | 73 | NSData *getNSDataUInt32(uint32_t uint32Value) 74 | { 75 | return getNSDataUInt32(uint32Value, false); 76 | } 77 | 78 | uint32_t getUInt32FromData(NSData *data) 79 | { 80 | if (data == nil) 81 | return 0; 82 | 83 | if ([data length] != 4) 84 | return 0; 85 | 86 | return *(const uint32_t *)[data bytes]; 87 | } 88 | 89 | bool getRegExArray(NSString *regExPattern, NSString *valueString, uint32_t itemCount, NSMutableArray **itemArray) 90 | { 91 | NSError *regError = nil; 92 | NSRegularExpression *regEx = [NSRegularExpression regularExpressionWithPattern:regExPattern options:NSRegularExpressionCaseInsensitive error:®Error]; 93 | 94 | if (regError) 95 | return false; 96 | 97 | NSTextCheckingResult *match = [regEx firstMatchInString:valueString options:0 range:NSMakeRange(0, [valueString length])]; 98 | 99 | if (match == nil || [match numberOfRanges] != itemCount + 1) 100 | return false; 101 | 102 | *itemArray = [NSMutableArray array]; 103 | 104 | for (int i = 1; i < match.numberOfRanges; i++) 105 | [*itemArray addObject:[valueString substringWithRange:[match rangeAtIndex:i]]]; 106 | 107 | return true; 108 | } 109 | 110 | uint32_t getInt(NSString *valueString) 111 | { 112 | uint32_t value; 113 | 114 | NSCharacterSet *whitespaceCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@" "]; 115 | valueString = [valueString stringByTrimmingCharactersInSet:whitespaceCharacterSet]; 116 | 117 | if ([valueString hasPrefix:@"0x"]) 118 | { 119 | NSScanner *scanner = [NSScanner scannerWithString:valueString]; 120 | [scanner scanHexInt:&value]; 121 | } 122 | else 123 | { 124 | NSScanner *scanner = [NSScanner scannerWithString:valueString]; 125 | [scanner scanInt:(int *)&value]; 126 | } 127 | 128 | return value; 129 | } 130 | 131 | uint32_t getHexInt(NSString *valueString) 132 | { 133 | uint32_t value; 134 | 135 | NSScanner *scanner = [NSScanner scannerWithString:valueString]; 136 | [scanner scanHexInt:&value]; 137 | 138 | return value; 139 | } 140 | 141 | -------------------------------------------------------------------------------- /PinConfigurator/NSColor+Pin.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSColor+Pin.h 3 | // PinConfigurator 4 | // 5 | // Created by Ben Baker on 2/7/19. 6 | // Copyright © 2019 Ben Baker. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface NSColor (Pin) 14 | 15 | + (NSColor *)pinColor:(uint8_t)value; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /PinConfigurator/NSColor+Pin.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSColor+Pin.m 3 | // PinConfigurator 4 | // 5 | // Created by Ben Baker on 2/7/19. 6 | // Copyright © 2019 Ben Baker. All rights reserved. 7 | // 8 | 9 | #import "NSColor+Pin.h" 10 | 11 | @implementation NSColor (Pin) 12 | 13 | + (NSColor *)pinColor:(uint8_t)value 14 | { 15 | NSArray *colorArray = @[[NSColor blackColor], [NSColor blackColor], [NSColor grayColor], [NSColor blueColor], [NSColor greenColor], [NSColor redColor], [NSColor orangeColor], [NSColor yellowColor], [NSColor purpleColor], [NSColor magentaColor], [NSColor blackColor], [NSColor blackColor], [NSColor blackColor], [NSColor blackColor], [NSColor whiteColor], [NSColor blackColor]]; 16 | 17 | return colorArray[value & 0xF]; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /PinConfigurator/NSPinCellView.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSPinCell.h 3 | // PinConfigurator 4 | // 5 | // Created by Ben Baker on 8/8/18. 6 | // Copyright © 2018 Ben Baker. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AudioNode.h" 11 | 12 | @interface NSPinCellView : NSTableCellView 13 | { 14 | } 15 | 16 | @property (retain) AudioNode *item; 17 | @property BOOL isSelected; 18 | 19 | - (void)setItem:(AudioNode *)device isSelected:(BOOL)isSelected; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /PinConfigurator/NSPinCellView.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSPinCell.m 3 | // PinConfigurator 4 | // 5 | // Created by Ben Baker on 8/8/18. 6 | // Copyright © 2018 Ben Baker. All rights reserved. 7 | // 8 | 9 | #import "NSPinCellView.h" 10 | 11 | @implementation NSPinCellView 12 | 13 | @synthesize item = _item; 14 | @synthesize isSelected = _isSelected; 15 | 16 | - (id)initWithCoder:(NSCoder *)decoder { 17 | self = [super initWithCoder:decoder]; 18 | 19 | if (self) { 20 | } 21 | 22 | return self; 23 | } 24 | 25 | - (void)dealloc { 26 | [_item release]; 27 | 28 | [super dealloc]; 29 | } 30 | 31 | - (void)setItem:(AudioNode *)device isSelected:(BOOL)isSelected 32 | { 33 | _item = device; 34 | _isSelected = isSelected; 35 | } 36 | 37 | - (void)drawRect:(NSRect)dirtyRect { 38 | if (!_item) 39 | return; 40 | 41 | [[NSGraphicsContext currentContext] saveGraphicsState]; 42 | 43 | _isSelected = [self isSelected]; 44 | NSRect rect = NSMakeRect(dirtyRect.origin.x + 3.0, dirtyRect.origin.y + 3.0, 10, 10); 45 | NSColor *jackColor = [_item jackColor]; 46 | [jackColor set]; 47 | 48 | if ([_item hasJack]) 49 | { 50 | NSBezierPath *bezierPath = [NSBezierPath bezierPathWithOvalInRect:rect]; 51 | [bezierPath setLineWidth:3]; 52 | 53 | if ([jackColor isEqual:[NSColor whiteColor]] && ![self isSelected]) 54 | [[NSColor lightGrayColor] set]; 55 | 56 | [bezierPath stroke]; 57 | } 58 | else 59 | { 60 | NSRectFill(rect); 61 | } 62 | 63 | [[NSGraphicsContext currentContext] restoreGraphicsState]; 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /PinConfigurator/NSString+Pin.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Pin.h 3 | // PinConfigurator 4 | // 5 | // Created by Ben Baker on 2/7/19. 6 | // Copyright © 2019 Ben Baker. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface NSString (Pin) 14 | 15 | + (NSString *)pinDirection:(uint8_t)value; 16 | + (NSString *)pinColor:(uint8_t)value; 17 | + (NSString *)pinMisc:(uint8_t)value; 18 | + (NSString *)pinDefaultDevice:(uint8_t)value; 19 | + (NSString *)pinConnector:(uint8_t)value; 20 | + (NSString *)pinPort:(uint8_t)value; 21 | + (NSString *)pinGrossLocation:(uint8_t)value; 22 | + (NSString *)pinLocation:(uint8_t)grossLocation geometricLocation:(uint8_t)geometricLocation; 23 | + (NSString *)pinEAPD:(uint8_t)value;; 24 | + (NSString *)pinConfigDescription:(uint8_t *)value; 25 | + (NSString *)pinDefaultDescription:(uint8_t *)value; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /PinConfigurator/NSString+Pin.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Pin.m 3 | // PinConfigurator 4 | // 5 | // Created by Ben Baker on 2/7/19. 6 | // Copyright © 2019 Ben Baker. All rights reserved. 7 | // 8 | 9 | #import "NSString+Pin.h" 10 | #import "AudioNode.h" 11 | 12 | @implementation NSString (Pin) 13 | 14 | #define GetLocalizedString(key) \ 15 | [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil] 16 | 17 | const char *gPinColorArray[] = { "Unknown", "Black", "Gray", "Blue", "Green", "Red", "Orange", "Yellow", "Purple", "Pink", "Reserved1", "Unknown", "Unknown", "Reserved2", "White", "Other" }; 18 | const char *gPinMisc[] = { "Jack Detect Override", "Reserved", "Reserved", "Reserved" }; 19 | const char *gPinDefaultDeviceArray[] = { "Line Out", "Speaker", "HP Out", "CD", "SPDIF Out", "Digital Other Out", "Modem Line Side", "Modem Handset Side", "Line In", "AUX", "Mic In", "Telephony", "SPDIF In", "Digital Other In", "Reserved", "Other" }; 20 | const char *gPinConnector[] = { "Unknown", "1/8\" Stereo/Mono", "1/4\" Stereo/Mono", "ATAPI Internal", "RCA", "Optical", "Other Digital", "Other Analog", "Multichannel Analog", "XLR/Professional", "RJ-11 (Modem)", "Combination", "Unknown", "Unknown", "Unknown", "Other" }; 21 | const char *gPinPort[] = { "Jack", "No Connection", "Fixed", "Jack + Internal" }; 22 | const char *gPinGeometricLocation[] = { "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom", "Special", "Special", "Special", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved" }; 23 | const char *gPinGrossLocation[] = { "External", "Internal", "Separate", "Other" }; 24 | const char *gPinGrossSpecial7[] = { "Rear Panel", "Riser", "Special", "Mobile Lid-Inside" }; 25 | const char *gPinGrossSpecial8[] = { "Drive Bay", "Digital Display", "Special", "Mobile Lid-Outside" }; 26 | const char *gPinGrossSpecial9[] = { "Special", "ATAPI", "Special", "Special" }; 27 | const char *gPinEAPD[] = { "BTL", "EAPD", "L/R Swap" }; 28 | 29 | + (NSString *)pinDirection:(uint8_t)value; 30 | { 31 | NSString *pinDirection = @"--"; 32 | 33 | if (value <= kHdaConfigDefaultDeviceModemHandset) 34 | pinDirection = GetLocalizedString(@"Out"); 35 | else if (value > kHdaConfigDefaultDeviceModemHandset && value <= kHdaConfigDefaultDeviceOtherDigitalIn) 36 | pinDirection = GetLocalizedString(@"In"); 37 | 38 | return pinDirection; 39 | } 40 | 41 | + (NSString *)pinColor:(uint8_t)value 42 | { 43 | return GetLocalizedString([NSString stringWithUTF8String:gPinColorArray[value & 0xF]]); 44 | } 45 | 46 | + (NSString *)pinMisc:(uint8_t)value 47 | { 48 | return GetLocalizedString([NSString stringWithUTF8String:gPinMisc[value & 0x3]]); 49 | } 50 | 51 | + (NSString *)pinDefaultDevice:(uint8_t)value 52 | { 53 | return GetLocalizedString([NSString stringWithUTF8String:gPinDefaultDeviceArray[value & 0xF]]); 54 | } 55 | 56 | + (NSString *)pinConnector:(uint8_t)value 57 | { 58 | return GetLocalizedString([NSString stringWithUTF8String:gPinConnector[value & 0xF]]); 59 | } 60 | 61 | + (NSString *)pinPort:(uint8_t)value 62 | { 63 | return GetLocalizedString([NSString stringWithUTF8String:gPinPort[value & 0x3]]); 64 | } 65 | 66 | + (NSString *)pinGrossLocation:(uint8_t)value; 67 | { 68 | return GetLocalizedString([NSString stringWithUTF8String:gPinGrossLocation[value]]); 69 | } 70 | 71 | + (NSString *)pinLocation:(uint8_t)grossLocation geometricLocation:(uint8_t)geometricLocation; 72 | { 73 | if (geometricLocation == 0x7) 74 | return GetLocalizedString([NSString stringWithUTF8String:gPinGrossSpecial7[grossLocation]]); 75 | else if (geometricLocation == 0x8) 76 | return GetLocalizedString([NSString stringWithUTF8String:gPinGrossSpecial8[grossLocation]]); 77 | else if (geometricLocation == 0x9) 78 | return GetLocalizedString([NSString stringWithUTF8String:gPinGrossSpecial9[grossLocation]]); 79 | 80 | return GetLocalizedString([NSString stringWithUTF8String:gPinGeometricLocation[geometricLocation]]); 81 | } 82 | 83 | + (NSString *)pinEAPD:(uint8_t)value; 84 | { 85 | return GetLocalizedString([NSString stringWithUTF8String:gPinEAPD[value & 0x7]]); 86 | } 87 | 88 | + (NSString *)pinConfigDescription:(uint8_t *)value 89 | { 90 | if (!value || strlen((const char *)value) != 8) 91 | return @"Invalid pin config"; 92 | 93 | uint8_t cad = value[0] - 48; 94 | const char *name = (const char *)&value[2]; 95 | uint8_t command = value[5]; 96 | uint8_t port = strtol((const char *)&value[6], 0, 16); 97 | uint8_t connector = strtol((const char *)&value[7], 0, 16); 98 | uint8_t grossLocation = (connector >> 4); 99 | uint8_t geometricLocation = (connector & 0xF); 100 | NSString *configDescription = 0; 101 | uint32_t hid = (uint32_t)strtol(name, 0, 16); 102 | 103 | switch (command) 104 | { 105 | case 0x43: 106 | case 0x63: 107 | configDescription = [NSString stringWithFormat:@" command: %c \n\t group: %c \n\t index: %c", command, value[6], value[7]]; 108 | break; 109 | case 0x44: 110 | case 0x64: 111 | configDescription = [NSString stringWithFormat:@" command: %c \n\t color: %@ (%c) \n\t misc: %c", command, [NSString pinColor:port], value[6], value[7]]; 112 | break; 113 | case 0x45: 114 | case 0x65: 115 | configDescription = [NSString stringWithFormat:@" command: %c \n\t device: %@ (%c)\n\t conn: %@ (%c)", command, [NSString pinDefaultDevice:port], value[6], [NSString pinConnector:connector], value[7]]; 116 | break; 117 | case 0x46: 118 | case 0x66: 119 | configDescription = [NSString stringWithFormat:@" command: %c \n\t port: %@ (%c) \n\tlocation: %@ (%c)", command, [NSString pinPort:port], value[6], [NSString pinLocation:grossLocation geometricLocation:geometricLocation], value[7]]; 120 | break; 121 | default: 122 | break; 123 | } 124 | 125 | return [NSString stringWithFormat:@"{\n\t cad: %d \n\t hid: %d (%s)\n\t%@\n}", cad, hid, name, configDescription]; 126 | } 127 | 128 | + (NSString *)pinDefaultDescription:(uint8_t *)value 129 | { 130 | return @""; 131 | } 132 | 133 | @end 134 | -------------------------------------------------------------------------------- /PinConfigurator/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PinConfigurator 4 | // 5 | // Created by Ben Baker on 2/7/19. 6 | // Copyright © 2019 Ben Baker. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | return NSApplicationMain(argc, argv); 13 | } 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PinConfigurator 2 | HDA Audio Codec verb configuration application. See section `7.3.3.31 Configuration Default` of the [High Definition Audio Specification](https://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/high-definition-audio-specification.pdf) 3 | 4 | ## About 5 | 6 | The original [Pin Configurator](https://www.applelife.ru/threads/pin-configurator.18051/) was released back in 2009 by saxmms. The app crashes when running on 10.14.4 and the source was not available so I had to reverse it from the binary which took many hours of work. I've also re-written most of it and added some new features (see "Updates in v2+" section) but the original is by saxmms so big thanks to him. 7 | 8 | ## Purpose 9 | 10 | - Parse pin configs from ConfigData, VoodooHDA and Linux, the program will determine the type of dump itself and select all the necessary ones 11 | - Add, delete and edit nodes 12 | - "Compile" a new ConfigData with a replaceable Codec address (the first digit of the configs pin) 13 | - Attempt to make ApplyFix 14 | 15 | ## Updates in v2+ 16 | 17 | - Added icon / support for Dark Mode / 64-bit 18 | - Re-written Voodoo / Linux / ConfigData codec dump file parsing 19 | - Added support for importing / exporting EAPD (70c) verbs 20 | - Changed the "Apply Fix" method to work the same as verbit (thanks to Signal64 / THe KiNG) 21 | - Create default node for "Headphone Mic Boost Volume" (insanelyDeepak) 22 | - Added Import / Export PinConfigs.kext 23 | - Added Import IORegistry pin configuration 24 | - Added Import [HdaCodecDump.efi](https://github.com/acidanthera/OpenCorePkg/tree/master/Application/HdaCodecDump) format 25 | - Added Export verbs.txt 26 | - Added Export HdaCodec.txt (Linux-style codec dump format) 27 | - Can open Clover r4887+ audio codec dumps (press F8 from Clover menu to dump to EFI/CLOVER/misc folder) 28 | - Fixed HDA Audio spec issues (eg. Split location into gross / geometric values, made misc and EAPD bit fields) 29 | 30 | ## Instructions 31 | 32 | - File->Open... your Voodoo, Linux or Config Data (Pin Configurator will detect format) 33 | - Select Patch->Apply Verbit Fix menu to sanitize verb data 34 | - Select File->Export->PinsConfig.kext to export your pin data to PinConfigs.kext/Contents/Info.plist 35 | 36 | ## What Patch->Apply Verbit Fix does now 37 | 38 | - Fix "Headphone Mic Boost Volume" (insanelyDeepak) 39 | - Remove 0x411111F0 / 0x400000F0 40 | - Remove CD at INT ATAPI 41 | - 0x71C: Index should always be 0 42 | - 0x71C: Group should be unique 43 | - 0x71D: Set all Misc to 0 (Jack Detect) 44 | - 0x71F: Front Panel change Location from 2 to 1 45 | - 0x71E: Line Out must be set to Speaker for Headphone autodetect to work correctly (Rodion2010) 46 | - 0x71E / 0x71F: First Microphone Port set to Fixed / Location set to Internal, N/A and Connector set to Unknown (Enables DSP Noise Reduction - Rodion2010) 47 | - 0x71E: Second Microphone Device set to Line In / Connector set to Unknown (Ext Mic doesn't work on Hackintoshes - Rodion2010) 48 | - 0x71E: Remove if Device set to Digital Other Out (HDMI) 49 | 50 | ## Additional Information 51 | 52 | The letters G and P (the last two columns) are Group (Default Association) and Position (Index, Sequence), i.e. group and device number of the group. 53 | Switch excludes from the list of nodes disabled at the level of "iron" (port = 4) 54 | 55 | ## Screenshot 56 | 57 | ![](PinConfigurator.png) 58 | 59 | ## Credits 60 | - saxmms for writing the original software on which this project is based 61 | - [Ben Baker](https://github.com/benbaker76) for reversing the software, updating and maintaining it 62 | -------------------------------------------------------------------------------- /Resources/Audio/Controllers.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 1002FFFF 6 | AMD HD Audio Controller 7 | 80862668 8 | Intel ICH6 HD Audio Controller 9 | 8086269A 10 | Intel 63XXESB HD Audio Controller 11 | 808627D8 12 | Intel ICH7 HD Audio Controller 13 | 8086284B 14 | Intel ICH8 HD Audio Controller 15 | 8086293E 16 | Intel ICH9 HD Audio Controller 17 | 80863A3E 18 | Intel ICH10 HD Audio Controller 19 | 80863A6E 20 | Intel ICH10 HD Audio Controller 21 | 80863B56 22 | Intel 5 Series HD Audio Controller 23 | 80863B57 24 | Intel 5 Series HD Audio Controller 25 | 80861C20 26 | Intel 6 Series HD Audio Controller 27 | 80861D20 28 | Intel X79/C600 Series HD Audio Controller 29 | 80861E20 30 | Intel 7 Series HD Audio Controller 31 | 80868C20 32 | Intel 8 Series HD Audio Controller 33 | 80868C21 34 | Intel 8 Series HD Audio Controller 35 | 80869C20 36 | Intel 8 Series HD Audio Controller 37 | 80869C21 38 | Intel 8 Series HD Audio Controller 39 | 80868CA0 40 | Intel 9 Series HD Audio Controller 41 | 80869CA0 42 | Intel 9 Series HD Audio Controller 43 | 80868D20 44 | Intel X99/C610 Series HD Audio Controller 45 | 80868D21 46 | Intel X99/C610 Series HD Audio Controller 47 | 8086A170 48 | Intel 100 Series HD Audio Controller 49 | 8086A2F0 50 | Intel 200 Series HD Audio Controller 51 | 8086A348 52 | Intel 300 Series HD Audio Controller 53 | 8086A3F0 54 | Intel 400 Series HD Audio Controller 55 | 8086F1C8 56 | Intel 400 Series HD Audio Controller 57 | 8086F0C8 58 | Intel 500 Series HD Audio Controller 59 | 808643C8 60 | Intel 500 Series HD Audio Controller 61 | 80867AD0 62 | Intel 600 Series HD Audio Controller 63 | 808651C8 64 | Alder Lake PCH-P High Definition Audio Controller 65 | 80867A50 66 | Intel 700 Series HD Audio Controller 67 | 80860A0C 68 | Intel Haswell HD Audio Controller 69 | 80860C0C 70 | Intel Ivy Bridge/Haswell HD Audio Controller 71 | 80860D0C 72 | Intel Crystal Well HD Audio Controller 73 | 8086160C 74 | Intel Broadwell HD Audio Controller 75 | 8086FFFF 76 | Intel HD Audio Controller 77 | 10DE026C 78 | NVIDIA MCP51 HD Audio Controller 79 | 10DE0371 80 | NVIDIA MCP55 HD Audio Controller 81 | 10DE03E4 82 | NVIDIA MCP61 HD Audio Controller 83 | 10DE03F0 84 | NVIDIA MCP61 HD Audio Controller 85 | 10DE044A 86 | NVIDIA MCP65 HD Audio Controller 87 | 10DE044B 88 | NVIDIA MCP65 HD Audio Controller 89 | 10DE055C 90 | NVIDIA MCP67 HD Audio Controller 91 | 10DE055D 92 | NVIDIA MCP67 HD Audio Controller 93 | 10DE0774 94 | NVIDIA MCP72 HD Audio Controller 95 | 10DE07FC 96 | NVIDIA MCP73 HD Audio Controller 97 | 10DE0AC0 98 | NVIDIA MCP79 HD Audio Controller 99 | 10DE0AC1 100 | NVIDIA MCP79 HD Audio Controller 101 | 10DE0AC2 102 | NVIDIA MCP79 HD Audio Controller 103 | 10DE0AC3 104 | NVIDIA MCP79 HD Audio Controller 105 | 10DE0D94 106 | NVIDIA MCP89 HD Audio Controller 107 | 10DE0BE2 108 | NVIDIA GT216 HD Audio Controller 109 | 10DE0BE5 110 | NVIDIA GF100 HD Audio Controller 111 | 10DE0BE9 112 | NVIDIA GF106 HD Audio Controller 113 | 10DE0BEA 114 | NVIDIA GF108 HD Audio Controller 115 | 10DE0BEB 116 | NVIDIA GF104 HD Audio Controller 117 | 10DE0BEE 118 | NVIDIA GF116 HD Audio Controller 119 | 10DE0E08 120 | NVIDIA GF119 HD Audio Controller 121 | 10DE0E09 122 | NVIDIA GF110 HD Audio Controller 123 | 10DE0E0A 124 | NVIDIA GK104 HD Audio Controller 125 | 10DE0E0B 126 | NVIDIA GK106 HD Audio Controller 127 | 10DE0E0C 128 | NVIDIA GF114 HD Audio Controller 129 | 10DE0E0F 130 | NVIDIA GK208 HD Audio Controller 131 | 10DE0E1A 132 | NVIDIA GK110 HD Audio Controller 133 | 10DE0E1B 134 | NVIDIA GK107 HD Audio Controller 135 | 10DE0FB0 136 | NVIDIA GM200 HD Audio Controller 137 | 10DE0FB8 138 | NVIDIA GP108 HD Audio Controller 139 | 10DE0FB9 140 | NVIDIA GP107GL HD Audio Controller 141 | 10DE0FBA 142 | NVIDIA GM206 HD Audio Controller 143 | 10DE0FBB 144 | NVIDIA GM204 HD Audio Controller 145 | 10DE10EF 146 | NVIDIA GP102 HD Audio Controller 147 | 10DE10F0 148 | NVIDIA GP104 HD Audio Controller 149 | 10DE10F1 150 | NVIDIA GP106 HD Audio Controller 151 | 10DE10F7 152 | NVIDIA TU102 HD Audio Controller 153 | 10DEFFFF 154 | NVIDIA HD Audio Controller 155 | 156 | 157 | -------------------------------------------------------------------------------- /Resources/Audio/Vendors.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AMD 6 | 4098 7 | AMDZEN 8 | 4130 9 | AnalogDevices 10 | 4564 11 | CirrusLogic 12 | 4115 13 | Conexant 14 | 5361 15 | Creative 16 | 4354 17 | IDT 18 | 4381 19 | Intel 20 | 32902 21 | NVIDIA 22 | 4318 23 | Realtek 24 | 4332 25 | SigmaTel 26 | 33668 27 | VIA 28 | 4358 29 | 30 | 31 | --------------------------------------------------------------------------------