/* * Apple System Management Controller (SMC) API from user space for Intel based * Macs. Works by talking to the AppleSMC.kext (kernel extension), the driver * for the SMC. * * smc.h * libsmc * * Copyright (C) 2014 beltex * * Based off of fork from: * osx-cpu-temp * * With credits to: * * Copyright (C) 2006 devnull * Apple System Management Control (SMC) Tool * * Copyright (C) 2006 Hendrik Holtmann * smcFanControl * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include //------------------------------------------------------------------------------ // MARK: MACROS //------------------------------------------------------------------------------ /** SMC keys for temperature sensors - 4 byte multi-character constants Not applicable to all Mac's of course. In adition, the definition of the codes may not be 100% accurate necessarily. Finally, list is incomplete. Presumed letter translations: - T = Temperature (if first char) - C = CPU - G = GPU - P = Proximity - D = Diode - H = Heatsink Sources: - https://www.apple.com/downloads/dashboard/status/istatpro.html - https://github.com/hholtmann/smcFanControl - https://github.com/jedda/OSX-Monitoring-Tools - http://www.parhelia.ch/blog/statics/k3_keys.html */ #define AMBIENT_AIR_0 "TA0P" #define AMBIENT_AIR_1 "TA1P" #define CPU_0_DIODE "TC0D" #define CPU_0_HEATSINK "TC0H" #define CPU_0_PROXIMITY "TC0P" #define ENCLOSURE_BASE_0 "TB0T" #define ENCLOSURE_BASE_1 "TB1T" #define ENCLOSURE_BASE_2 "TB2T" #define ENCLOSURE_BASE_3 "TB3T" #define GPU_0_DIODE "TG0D" #define GPU_0_HEATSINK "TG0H" #define GPU_0_PROXIMITY "TG0P" #define HARD_DRIVE_BAY "TH0P" #define MEMORY_SLOT_0 "TM0S" #define MEMORY_SLOTS_PROXIMITY "TM0P" #define NORTHBRIDGE "TN0H" #define NORTHBRIDGE_DIODE "TN0D" #define NORTHBRIDGE_PROXIMITY "TN0P" #define THUNDERBOLT_0 "TI0P" #define THUNDERBOLT_1 "TI1P" #define WIRELESS_MODULE "TW0P" /** SMC keys for fans - 4 byte multi-character constants Number of fans on Macs vary of course, thus not all keys will be applicable. Presumed letter translations: - F = Fan - Ac = Acutal - Mn = Min - Mx = Max - Sf = Safe - Tg = Target Sources: See TMP SMC keys */ #define FAN_0 "F0Ac" #define FAN_0_MIN_RPM "F0Mn" #define FAN_0_MAX_RPM "F0Mx" #define FAN_0_SAFE_RPM "F0Sf" #define FAN_0_TARGET_RPM "F0Tg" #define FAN_1 "F1Ac" #define FAN_1_MIN_RPM "F1Mn" #define FAN_1_MAX_RPM "F1Mx" #define FAN_1_SAFE_RPM "F1Sf" #define FAN_1_TARGET_RPM "F1Tg" #define FAN_2 "F2Ac" #define FAN_2_MIN_RPM "F2Mn" #define FAN_2_MAX_RPM "F2Mx" #define FAN_2_SAFE_RPM "F2Sf" #define FAN_2_TARGET_RPM "F2Tg" #define NUM_FANS "FNum" #define FORCE_BITS "FS! " /** Misc SMC keys - 4 byte multi-character constants Sources: See TMP SMC keys */ #define BATT_PWR "BATP" #define NUM_KEYS "#KEY" #define ODD_FULL "MSDI" //------------------------------------------------------------------------------ // MARK: TYPES //------------------------------------------------------------------------------ typedef char fan_name_t[13]; //------------------------------------------------------------------------------ // MARK: ENUMS //------------------------------------------------------------------------------ typedef enum { CELSIUS, FAHRENHEIT, KELVIN } tmp_unit_t; //------------------------------------------------------------------------------ // MARK: PROTOTYPES //------------------------------------------------------------------------------ /** Open a connection to the SMC :returns: kIOReturnSuccess on successful connection to the SMC. */ kern_return_t open_smc(void); /** Close connection to the SMC :returns: kIOReturnSuccess on successful close of connection to the SMC. */ kern_return_t close_smc(void); /** Check if an SMC key is valid. Useful for determining if a certain machine has particular sensor or fan for example. :param: key The SMC key to check. 4 byte multi-character constant. Must be 4 characters in length. :returns: True if the key is found, false otherwise */ bool is_key_valid(char *key); /** Get the current temperature from a sensor :param: key The temperature sensor to read from :param: unit The unit for the temperature value. :returns: Temperature of sensor. If the sensor is not found, or an error occurs, return will be zero */ double get_tmp(char *key, tmp_unit_t unit); /** Is the machine being powered by the battery? :returns: True if it is, false otherwise */ bool is_battery_powered(void); /** Is there a CD in the optical disk drive (ODD)? :returns: True if there is, false otherwise */ bool is_optical_disk_drive_full(void); /** Get the name of a fan. :param: fanNum The number of the fan to check :param: name The name of the fan. Return will be empty on error. :returns: True if successful, false otherwise. */ bool get_fan_name(unsigned int fan_num, fan_name_t name); /** Get the number of fans on this machine. :returns: The number of fans. If an error occurs, return will be -1. */ int get_num_fans(void); /** Get the current speed (RPM - revolutions per minute) of a fan. :param: fan_num The number of the fan to check :returns: The fan RPM. If the fan is not found, or an error occurs, return will be zero */ UInt get_fan_rpm(UInt fan_num); /** Set the minimum speed (RPM - revolutions per minute) of a fan. This method requires root privileges. By minimum we mean that OS X can interject and raise the fan speed if needed, however it will not go below this. WARNING: You are playing with hardware here, BE CAREFUL. :param: fan_num The number of the fan to set :param: rpm The speed you would like to set the fan to. :param: auth Should the function do authentication? :return: True if successful, false otherwise */ bool set_fan_min_rpm(unsigned int fan_num, unsigned int rpm, bool auth);