1 /* 2 * Apple System Management Controller (SMC) API from user space for Intel based 3 * Macs. Works by talking to the AppleSMC.kext (kernel extension), the driver 4 * for the SMC. 5 * 6 * smc.h 7 * libsmc 8 * 9 * Copyright (C) 2014 beltex <https://github.com/beltex> 10 * 11 * Based off of fork from: 12 * osx-cpu-temp <https://github.com/lavoiesl/osx-cpu-temp> 13 * 14 * With credits to: 15 * 16 * Copyright (C) 2006 devnull 17 * Apple System Management Control (SMC) Tool 18 * 19 * Copyright (C) 2006 Hendrik Holtmann 20 * smcFanControl <https://github.com/hholtmann/smcFanControl> 21 * 22 * This program is free software; you can redistribute it and/or modify 23 * it under the terms of the GNU General Public License as published by 24 * the Free Software Foundation; either version 2 of the License, or 25 * (at your option) any later version. 26 * 27 * This program is distributed in the hope that it will be useful, 28 * but WITHOUT ANY WARRANTY; without even the implied warranty of 29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30 * GNU General Public License for more details. 31 * 32 * You should have received a copy of the GNU General Public License along 33 * with this program; if not, write to the Free Software Foundation, Inc., 34 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 35 */ 36 37 #include <IOKit/IOKitLib.h> 38 39 40 //------------------------------------------------------------------------------ 41 // MARK: MACROS 42 //------------------------------------------------------------------------------ 43 44 45 /** 46 SMC keys for temperature sensors - 4 byte multi-character constants 47 48 Not applicable to all Mac's of course. In adition, the definition of the codes 49 may not be 100% accurate necessarily. Finally, list is incomplete. 50 51 Presumed letter translations: 52 53 - T = Temperature (if first char) 54 - C = CPU 55 - G = GPU 56 - P = Proximity 57 - D = Diode 58 - H = Heatsink 59 60 Sources: 61 62 - https://www.apple.com/downloads/dashboard/status/istatpro.html 63 - https://github.com/hholtmann/smcFanControl 64 - https://github.com/jedda/OSX-Monitoring-Tools 65 - http://www.parhelia.ch/blog/statics/k3_keys.html 66 */ 67 #define AMBIENT_AIR_0 "TA0P" 68 #define AMBIENT_AIR_1 "TA1P" 69 #define CPU_0_DIODE "TC0D" 70 #define CPU_0_HEATSINK "TC0H" 71 #define CPU_0_PROXIMITY "TC0P" 72 #define ENCLOSURE_BASE_0 "TB0T" 73 #define ENCLOSURE_BASE_1 "TB1T" 74 #define ENCLOSURE_BASE_2 "TB2T" 75 #define ENCLOSURE_BASE_3 "TB3T" 76 #define GPU_0_DIODE "TG0D" 77 #define GPU_0_HEATSINK "TG0H" 78 #define GPU_0_PROXIMITY "TG0P" 79 #define HARD_DRIVE_BAY "TH0P" 80 #define MEMORY_SLOT_0 "TM0S" 81 #define MEMORY_SLOTS_PROXIMITY "TM0P" 82 #define NORTHBRIDGE "TN0H" 83 #define NORTHBRIDGE_DIODE "TN0D" 84 #define NORTHBRIDGE_PROXIMITY "TN0P" 85 #define THUNDERBOLT_0 "TI0P" 86 #define THUNDERBOLT_1 "TI1P" 87 #define WIRELESS_MODULE "TW0P" 88 89 90 /** 91 SMC keys for fans - 4 byte multi-character constants 92 93 Number of fans on Macs vary of course, thus not all keys will be applicable. 94 95 Presumed letter translations: 96 97 - F = Fan 98 - Ac = Acutal 99 - Mn = Min 100 - Mx = Max 101 - Sf = Safe 102 - Tg = Target 103 104 Sources: See TMP SMC keys 105 */ 106 #define FAN_0 "F0Ac" 107 #define FAN_0_MIN_RPM "F0Mn" 108 #define FAN_0_MAX_RPM "F0Mx" 109 #define FAN_0_SAFE_RPM "F0Sf" 110 #define FAN_0_TARGET_RPM "F0Tg" 111 #define FAN_1 "F1Ac" 112 #define FAN_1_MIN_RPM "F1Mn" 113 #define FAN_1_MAX_RPM "F1Mx" 114 #define FAN_1_SAFE_RPM "F1Sf" 115 #define FAN_1_TARGET_RPM "F1Tg" 116 #define FAN_2 "F2Ac" 117 #define FAN_2_MIN_RPM "F2Mn" 118 #define FAN_2_MAX_RPM "F2Mx" 119 #define FAN_2_SAFE_RPM "F2Sf" 120 #define FAN_2_TARGET_RPM "F2Tg" 121 #define NUM_FANS "FNum" 122 #define FORCE_BITS "FS! " 123 124 125 /** 126 Misc SMC keys - 4 byte multi-character constants 127 128 Sources: See TMP SMC keys 129 */ 130 #define BATT_PWR "BATP" 131 #define NUM_KEYS "#KEY" 132 #define ODD_FULL "MSDI" 133 134 135 //------------------------------------------------------------------------------ 136 // MARK: TYPES 137 //------------------------------------------------------------------------------ 138 139 140 typedef char fan_name_t[13]; 141 142 143 //------------------------------------------------------------------------------ 144 // MARK: ENUMS 145 //------------------------------------------------------------------------------ 146 147 148 typedef enum { 149 CELSIUS, 150 FAHRENHEIT, 151 KELVIN 152 } tmp_unit_t; 153 154 155 //------------------------------------------------------------------------------ 156 // MARK: PROTOTYPES 157 //------------------------------------------------------------------------------ 158 159 160 /** 161 Open a connection to the SMC 162 163 :returns: kIOReturnSuccess on successful connection to the SMC. 164 */ 165 kern_return_t open_smc(void); 166 kern_return_t open_smc_conn(io_connect_t *con); 167 168 169 /** 170 Close connection to the SMC 171 172 :returns: kIOReturnSuccess on successful close of connection to the SMC. 173 */ 174 kern_return_t close_smc(void); 175 kern_return_t close_smc_conn(io_connect_t con); 176 177 /** 178 Check if an SMC key is valid. Useful for determining if a certain machine has 179 particular sensor or fan for example. 180 181 :param: key The SMC key to check. 4 byte multi-character constant. Must be 4 182 characters in length. 183 :returns: True if the key is found, false otherwise 184 */ 185 bool is_key_valid(char *key); 186 bool is_key_valid_conn(io_connect_t con, char *key); 187 188 /** 189 Get the current temperature from a sensor 190 191 :param: key The temperature sensor to read from 192 :param: unit The unit for the temperature value. 193 :returns: Temperature of sensor. If the sensor is not found, or an error 194 occurs, return will be zero 195 */ 196 double get_tmp(char *key, tmp_unit_t unit); 197 double get_tmp_conn(io_connect_t con, char *key, tmp_unit_t unit); 198 199 200 /** 201 Is the machine being powered by the battery? 202 203 :returns: True if it is, false otherwise 204 */ 205 bool is_battery_powered(void); 206 207 208 /** 209 Is there a CD in the optical disk drive (ODD)? 210 211 :returns: True if there is, false otherwise 212 */ 213 bool is_optical_disk_drive_full(void); 214 215 216 /** 217 Get the name of a fan. 218 219 :param: fanNum The number of the fan to check 220 :param: name The name of the fan. Return will be empty on error. 221 :returns: True if successful, false otherwise. 222 */ 223 bool get_fan_name(unsigned int fan_num, fan_name_t name); 224 225 226 /** 227 Get the number of fans on this machine. 228 229 :returns: The number of fans. If an error occurs, return will be -1. 230 */ 231 int get_num_fans(void); 232 233 234 /** 235 Get the current speed (RPM - revolutions per minute) of a fan. 236 237 :param: fan_num The number of the fan to check 238 :returns: The fan RPM. If the fan is not found, or an error occurs, return 239 will be zero 240 */ 241 UInt get_fan_rpm(UInt fan_num); 242 243 244 /** 245 Set the minimum speed (RPM - revolutions per minute) of a fan. This method 246 requires root privileges. By minimum we mean that OS X can interject and 247 raise the fan speed if needed, however it will not go below this. 248 249 WARNING: You are playing with hardware here, BE CAREFUL. 250 251 :param: fan_num The number of the fan to set 252 :param: rpm The speed you would like to set the fan to. 253 :param: auth Should the function do authentication? 254 :return: True if successful, false otherwise 255 */ 256 bool set_fan_min_rpm(unsigned int fan_num, unsigned int rpm, bool auth); 257