diff --git a/Classes/FanControl.h b/Classes/FanControl.h index 0e36e0a..ca7dae6 100755 --- a/Classes/FanControl.h +++ b/Classes/FanControl.h @@ -25,6 +25,7 @@ #import "NSFileManager+DirectoryLocations.h" #import "smc.h" #import "smcWrapper.h" +#import "IOKitSensor.h" #import "MachineDefaults.h" #import "Power.h" diff --git a/Classes/FanControl.m b/Classes/FanControl.m index cc2f715..70219d2 100755 --- a/Classes/FanControl.m +++ b/Classes/FanControl.m @@ -150,7 +150,11 @@ NSUserDefaults *defaults; @0, PREF_AC_SELECTION, @0, PREF_CHARGING_SELECTION, @0, PREF_MENU_DISPLAYMODE, - [MachineDefaults isAppleSilicon] ? @"Tp0D" : @"TC0D", PREF_TEMPERATURE_SENSOR, +#if TARGET_CPU_ARM64 + @"",PREF_TEMPERATURE_SENSOR, +#else + @"TC0D",PREF_TEMPERATURE_SENSOR, +#endif @0, PREF_NUMBEROF_LAUNCHES, @NO,PREF_DONATIONMESSAGE_DISPLAY, [NSArchiver archivedDataWithRootObject:[NSColor blackColor]],PREF_MENU_TEXTCOLOR, @@ -399,7 +403,11 @@ NSUserDefaults *defaults; if (bNeedTemp == true) { // Read current temperature and format text for the menubar. +#if TARGET_CPU_ARM64 + c_temp = [IOKitSensor getSOCTemperature]; +#else c_temp = [smcWrapper get_maintemp]; +#endif if ([[defaults objectForKey:PREF_TEMP_UNIT] intValue]==0) { temp = [NSString stringWithFormat:@"%@%CC",@(c_temp),(unsigned short)0xb0]; @@ -741,10 +749,10 @@ NSUserDefaults *defaults; #pragma mark **Power Watchdog-Methods** - (void)systemWillSleep:(id)sender{ - if ([MachineDefaults isAppleSilicon]) { - [FanControl setRights]; - [self setFansToAuto:true]; - } +#if TARGET_CPU_ARM64 + [FanControl setRights]; + [self setFansToAuto:true]; +#endif } - (void)systemDidWakeFromSleep:(id)sender{ diff --git a/Classes/IOKitSensor.h b/Classes/IOKitSensor.h new file mode 100644 index 0000000..c87654b --- /dev/null +++ b/Classes/IOKitSensor.h @@ -0,0 +1,57 @@ +/* + * FanControl + * + * Copyright (c) 2006-2012 Hendrik Holtmann + * + * Sensor.h - MacBook(Pro) FanControl application + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#import + +#import +#import + +// https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-1035.70.7/IOHIDFamily/AppleHIDUsageTables.h.auto.html +#define kHIDPage_AppleVendor 0xff00 +#define kHIDUsage_AppleVendor_TemperatureSensor 0x0005 + +// https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-1035.70.7/IOHIDFamily/IOHIDEventTypes.h.auto.html +#ifdef __LP64__ +typedef double IOHIDFloat; +#else +typedef float IOHIDFloat; +#endif + +// https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-1035.70.7/IOHIDFamily/IOHIDEventTypes.h.auto.html +#define IOHIDEventFieldBase(type) (type << 16) +#define kIOHIDEventTypeTemperature 15 + + +typedef struct __IOHIDEvent *IOHIDEventRef; +typedef struct __IOHIDServiceClient *IOHIDServiceClientRef; + +IOHIDEventSystemClientRef IOHIDEventSystemClientCreate(CFAllocatorRef); +void IOHIDEventSystemClientSetMatching(IOHIDEventSystemClientRef, CFDictionaryRef); +IOHIDEventRef IOHIDServiceClientCopyEvent(IOHIDServiceClientRef, int64_t, int32_t, int64_t); +IOHIDFloat IOHIDEventGetFloatValue(IOHIDEventRef event, uint32_t field); + +@interface IOKitSensor : NSObject { +} + ++ (float) getSOCTemperature; + +@end diff --git a/Classes/IOKitSensor.m b/Classes/IOKitSensor.m new file mode 100644 index 0000000..2e66daa --- /dev/null +++ b/Classes/IOKitSensor.m @@ -0,0 +1,72 @@ +/* + * FanControl + * + * Copyright (c) 2006-2012 Hendrik Holtmann + * + * Sensor.m - MacBook(Pro) FanControl application + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#import "IOKitSensor.h" + +@implementation IOKitSensor + +static BOOL isSOCSensor(CFStringRef sensorName) { + return CFStringHasPrefix(sensorName, CFSTR("PMU")) && + !CFStringHasSuffix(sensorName, CFSTR("tcal")); // Ignore "PMU tcal" as it seems static +} + +static float toOneDecimalPlace(float value) { + return roundf(10.0f * value) / 10.0f; +} + ++ (float) getSOCTemperature { + + IOHIDEventSystemClientRef eventSystemClient = IOHIDEventSystemClientCreate(kCFAllocatorDefault); + CFArrayRef services = IOHIDEventSystemClientCopyServices(eventSystemClient); + if (services) { + + float socSensorSum = 0.0f; + int socSensorCount = 0; + + for (int i = 0; i < CFArrayGetCount(services); i++) { + IOHIDServiceClientRef serviceClientRef = (IOHIDServiceClientRef)CFArrayGetValueAtIndex(services, i); + CFStringRef sensorName = IOHIDServiceClientCopyProperty(serviceClientRef, CFSTR("Product")); + if (sensorName) { + if (isSOCSensor(sensorName)) { + IOHIDEventRef event = IOHIDServiceClientCopyEvent(serviceClientRef, kIOHIDEventTypeTemperature, 0, 0); + if (event) { + IOHIDFloat sensorTemperature = IOHIDEventGetFloatValue(event, IOHIDEventFieldBase(kIOHIDEventTypeTemperature)); + CFRelease(event); + socSensorSum += sensorTemperature; + socSensorCount++; + } + } + CFRelease(sensorName); + } + } + + CFRelease(services); + CFRelease(eventSystemClient); + + float avgSOCTemp = socSensorCount > 0 ? socSensorSum / socSensorCount: 0.0f; + return toOneDecimalPlace(avgSOCTemp); + } + + return 0.0f; +} + +@end diff --git a/Classes/MachineDefaults.h b/Classes/MachineDefaults.h index 13af9d7..1a89280 100644 --- a/Classes/MachineDefaults.h +++ b/Classes/MachineDefaults.h @@ -30,7 +30,6 @@ int machine_num; } -+ (BOOL)isAppleSilicon; + (NSString *)computerModel; - (instancetype)init:(NSString*)p_machine ; diff --git a/Classes/MachineDefaults.m b/Classes/MachineDefaults.m index dd83605..ce4294b 100644 --- a/Classes/MachineDefaults.m +++ b/Classes/MachineDefaults.m @@ -22,9 +22,6 @@ #import "MachineDefaults.h" #import "NSFileManager+DirectoryLocations.h" -#include -#include -#include @interface MachineDefaults () { @@ -126,14 +123,6 @@ return defaultsDict; } -+ (BOOL)isAppleSilicon -{ - cpu_type_t cpu_type; - size_t size = sizeof(cpu_type); - sysctlbyname("hw.cputype", &cpu_type, &size, NULL, 0); - return cpu_type == CPU_TYPE_ARM64; -} - + (NSString *)computerModel { static NSString *computerModel = nil; diff --git a/Classes/smcWrapper.m b/Classes/smcWrapper.m index 4f4573f..7828059 100755 --- a/Classes/smcWrapper.m +++ b/Classes/smcWrapper.m @@ -70,11 +70,7 @@ NSArray *allSensors; NSString *sensor = [[NSUserDefaults standardUserDefaults] objectForKey:PREF_TEMPERATURE_SENSOR]; SMCReadKey2((char*)[sensor UTF8String], &val,conn); retValue = [self convertToNumber:val]; - if ([MachineDefaults isAppleSilicon]) { - allSensors = [NSArray arrayWithObjects:@"Tp0D",@"Tp0P",nil]; - } else { - allSensors = [NSArray arrayWithObjects:@"TC0D",@"TC0P",@"TCAD",@"TC0H",@"TC0F",@"TCAH",@"TCBH",nil]; - } + allSensors = [NSArray arrayWithObjects:@"TC0D",@"TC0P",@"TCAD",@"TC0H",@"TC0F",@"TCAH",@"TCBH",nil]; if (retValue<=0 || floor(retValue) == 129 ) { //workaround for some iMac Models for (NSString *sensor in allSensors) { SMCReadKey2((char*)[sensor UTF8String], &val,conn); diff --git a/smcFanControl.xcodeproj/project.pbxproj b/smcFanControl.xcodeproj/project.pbxproj index 92096c3..fb7a42a 100644 --- a/smcFanControl.xcodeproj/project.pbxproj +++ b/smcFanControl.xcodeproj/project.pbxproj @@ -32,6 +32,7 @@ 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; + B5A4D43B293A62F90084C50B /* IOKitSensor.m in Sources */ = {isa = PBXBuildFile; fileRef = B5A4D43A293A62F90084C50B /* IOKitSensor.m */; }; B5F20EE127FBCC78002EFD11 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 895BDA390B8F8F42003CD894 /* Sparkle.framework */; }; B5F20EE227FBCC78002EFD11 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 895BDA390B8F8F42003CD894 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; /* End PBXBuildFile section */ @@ -121,6 +122,8 @@ 89FE24280B7F4CE900D2713C /* German */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = German; path = German.lproj/MainMenu.nib; sourceTree = ""; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 8D1107320486CEB800E47090 /* smcFanControl.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = smcFanControl.app; sourceTree = BUILT_PRODUCTS_DIR; }; + B5A4D43A293A62F90084C50B /* IOKitSensor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IOKitSensor.m; sourceTree = ""; }; + B5E84C88293A65840067AEC2 /* IOKitSensor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IOKitSensor.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -165,6 +168,8 @@ 892A7F440B10B7700041B493 /* MachineDefaults.m */, 8932CF2213D0850F008BC447 /* SystemVersion.h */, 8932CF2313D08551008BC447 /* SystemVersion.m */, + B5E84C88293A65840067AEC2 /* IOKitSensor.h */, + B5A4D43A293A62F90084C50B /* IOKitSensor.m */, ); path = Classes; sourceTree = ""; @@ -383,6 +388,7 @@ 892A7F450B10B7700041B493 /* MachineDefaults.m in Sources */, 8932CF2413D08551008BC447 /* SystemVersion.m in Sources */, 89148EA315E2543D00A073EE /* NSFileManager+DirectoryLocations.m in Sources */, + B5A4D43B293A62F90084C50B /* IOKitSensor.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };