fix: fixed fan control on macs with T2 (#430)

This commit is contained in:
Serhiy Mytrovtsiy
2021-06-22 20:48:16 +02:00
parent ebbbe27df3
commit 724d9055e7
3 changed files with 86 additions and 13 deletions

View File

@@ -15,6 +15,7 @@ enum CMDType: String {
case list
case set
case fan
case fans
case help
case unknown
@@ -23,6 +24,7 @@ enum CMDType: String {
case "list": self = .list
case "set": self = .set
case "fan": self = .fan
case "fans": self = .fans
case "help": self = .help
default: self = .unknown
}
@@ -47,6 +49,7 @@ enum FlagsType: String {
}
}
// swiftlint:disable function_body_length
func main() {
var args = CommandLine.arguments.dropFirst()
let cmd = CMDType(value: args.first ?? "")
@@ -98,6 +101,7 @@ func main() {
guard let idIndex = args.firstIndex(where: { $0 == "-id" }),
args.indices.contains(idIndex+1),
let id = Int(args[idIndex+1]) else {
print("[ERROR]: missing id")
return
}
@@ -113,14 +117,33 @@ func main() {
}
print("[ERROR]: missing value or mode")
case .fans:
guard let count = SMC.shared.getValue("FNum") else {
print("FNum not found")
return
}
print("Number of fans: \(count)\n")
for i in 0..<Int(count) {
print("\(i): \(SMC.shared.getStringValue("F\(i)ID") ?? "Fan #\(i)")")
print("Actual speed:", SMC.shared.getValue("F\(i)Ac") ?? -1)
print("Minimal speed:", SMC.shared.getValue("F\(i)Mn") ?? -1)
print("Maximum speed:", SMC.shared.getValue("F\(i)Mx") ?? -1)
print("Target speed:", SMC.shared.getValue("F\(i)Tg") ?? -1)
print("Mode:", FanMode(rawValue: Int(SMC.shared.getValue("F\(i)Md") ?? -1)) ?? .forced)
print()
}
case .help, .unknown:
print("SMC tool\n")
print("Usage:")
print(" ./smc [command]\n")
print("Available Commands:")
print(" list list keys and values")
print(" set set value to a key")
print(" help help menu\n")
print(" list list keys and values")
print(" set set value to a key")
print(" fan set fan speed")
print(" fans list of fans")
print(" help help menu\n")
print("Available Flags:")
print(" -t list temperature sensors")
print(" -v list voltage sensors (list cmd) / value (set cmd)")

View File

@@ -147,6 +147,10 @@ extension Float {
return $0.load(fromByteOffset: 0, as: Self.self)
}
}
var bytes: [UInt8] {
withUnsafeBytes(of: self, Array.init)
}
}
public class SMC {
@@ -187,7 +191,7 @@ public class SMC {
}
}
public func close() -> kern_return_t{
public func close() -> kern_return_t {
return IOServiceClose(conn)
}
@@ -202,7 +206,7 @@ public class SMC {
}
if val.dataSize > 0 {
if val.bytes.first(where: { $0 != 0}) == nil && val.key != "FS! " {
if val.bytes.first(where: { $0 != 0 }) == nil && val.key != "FS! " && val.key != "F0Md" && val.key != "F1Md" {
return nil
}
@@ -346,6 +350,30 @@ public class SMC {
// MARK: - fans
public func setFanMode(_ id: Int, mode: FanMode) {
if self.getValue("F\(id)Md") != nil {
var result: kern_return_t = 0
var value = SMCVal_t("F\(id)Md")
result = read(&value)
if result != kIOReturnSuccess {
print("Error read fan mode: " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
return
}
value.bytes = [UInt8(mode.rawValue), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
UInt8(0), UInt8(0)]
result = write(value)
if result != kIOReturnSuccess {
print("Error write: " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
return
}
}
let fansMode = Int(self.getValue("FS! ") ?? 0)
var newMode: UInt8 = 0
@@ -406,16 +434,29 @@ public class SMC {
return
}
var result: kern_return_t = 0
var value = SMCVal_t("F\(id)Tg")
value.dataSize = 2
value.bytes = [UInt8(speed >> 6), UInt8((speed << 2) ^ ((speed >> 6) << 8)), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
UInt8(0), UInt8(0)]
let result = write(value)
result = read(&value)
if result != kIOReturnSuccess {
print("Error read fan value: " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
return
}
if value.dataType == "flt " {
let bytes = Float(speed).bytes
value.bytes[0] = bytes[0]
value.bytes[1] = bytes[1]
value.bytes[2] = bytes[2]
value.bytes[3] = bytes[3]
} else if value.dataType == "fpe2" {
value.bytes[0] = UInt8(speed >> 6)
value.bytes[1] = UInt8((speed << 2) ^ ((speed >> 6) << 8))
value.bytes[2] = UInt8(0)
value.bytes[3] = UInt8(0)
}
result = write(value)
if result != kIOReturnSuccess {
print("Error write: " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
return

View File

@@ -34,6 +34,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
debugAsWhichUser = "root"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
@@ -55,6 +56,14 @@
argument = "list"
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "fans"
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "fan -id 0 -v 2761"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "set -k &quot;FS! &quot; -v 0000"
isEnabled = "NO">