1/* 2 * Copyright (c) 1998-2005 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29#include <IOKit/pwr_mgt/IOPMPowerSource.h> 30#include <IOKit/pwr_mgt/IOPM.h> 31#include <IOKit/IOMessage.h> 32#include <IOKit/IOLib.h> 33 34#define super IOService 35 36OSDefineMetaClassAndStructors(IOPMPowerSource, IOService) 37 38// ***************************************************************************** 39// powerSource 40// 41// Static initializer for IOPMPowerSource. Returns a new instance of the class 42// which the caller must attach to the power plane. 43// ***************************************************************************** 44 45IOPMPowerSource *IOPMPowerSource::powerSource(void) 46{ 47 IOPMPowerSource *ps = new IOPMPowerSource; 48 49 if(ps) { 50 ps->init(); 51 return ps; 52 } 53 return NULL; 54} 55 56// ***************************************************************************** 57// init 58// 59// ***************************************************************************** 60bool IOPMPowerSource::init (void) 61{ 62 if (!super::init()) { 63 return false; 64 } 65 66 nextInList = NULL; 67 68 properties = OSDictionary::withCapacity(10); 69 if(!properties) return false; 70 properties->setCapacityIncrement(1); 71 72 externalConnectedKey = OSSymbol::withCString(kIOPMPSExternalConnectedKey); 73 externalChargeCapableKey = OSSymbol::withCString(kIOPMPSExternalChargeCapableKey); 74 batteryInstalledKey = OSSymbol::withCString(kIOPMPSBatteryInstalledKey); 75 chargingKey = OSSymbol::withCString(kIOPMPSIsChargingKey); 76 warnLevelKey = OSSymbol::withCString(kIOPMPSAtWarnLevelKey); 77 criticalLevelKey = OSSymbol::withCString(kIOPMPSAtCriticalLevelKey); 78 currentCapacityKey = OSSymbol::withCString(kIOPMPSCurrentCapacityKey); 79 maxCapacityKey = OSSymbol::withCString(kIOPMPSMaxCapacityKey); 80 timeRemainingKey = OSSymbol::withCString(kIOPMPSTimeRemainingKey); 81 amperageKey = OSSymbol::withCString(kIOPMPSAmperageKey); 82 voltageKey = OSSymbol::withCString(kIOPMPSVoltageKey); 83 cycleCountKey = OSSymbol::withCString(kIOPMPSCycleCountKey); 84 adapterInfoKey = OSSymbol::withCString(kIOPMPSAdapterInfoKey); 85 locationKey = OSSymbol::withCString(kIOPMPSLocationKey); 86 errorConditionKey = OSSymbol::withCString(kIOPMPSErrorConditionKey); 87 manufacturerKey = OSSymbol::withCString(kIOPMPSManufacturerKey); 88 modelKey = OSSymbol::withCString(kIOPMPSModelKey); 89 serialKey = OSSymbol::withCString(kIOPMPSSerialKey); 90 batteryInfoKey = OSSymbol::withCString(kIOPMPSLegacyBatteryInfoKey); 91 92 return true; 93} 94 95// ***************************************************************************** 96// free 97// 98// ***************************************************************************** 99void IOPMPowerSource::free(void) 100{ 101 if(properties) properties->release(); 102 if(externalConnectedKey) externalConnectedKey->release(); 103 if(externalChargeCapableKey) externalChargeCapableKey->release(); 104 if(batteryInstalledKey) batteryInstalledKey->release(); 105 if(chargingKey) chargingKey->release(); 106 if(warnLevelKey) warnLevelKey->release(); 107 if(criticalLevelKey) criticalLevelKey->release(); 108 if(currentCapacityKey) currentCapacityKey->release(); 109 if(maxCapacityKey) maxCapacityKey->release(); 110 if(timeRemainingKey) timeRemainingKey->release(); 111 if(amperageKey) amperageKey->release(); 112 if(voltageKey) voltageKey->release(); 113 if(cycleCountKey) cycleCountKey->release(); 114 if(adapterInfoKey) adapterInfoKey->release(); 115 if(errorConditionKey) errorConditionKey->release(); 116 if(manufacturerKey) manufacturerKey->release(); 117 if(modelKey) modelKey->release(); 118 if(serialKey) serialKey->release(); 119 if(locationKey) locationKey->release(); 120 if(batteryInfoKey) batteryInfoKey->release(); 121} 122 123// ***************************************************************************** 124// updateStatus 125// 126// Update power source state in IORegistry and message interested clients 127// notifying them of our change. 128// ***************************************************************************** 129void IOPMPowerSource::updateStatus (void) 130{ 131 OSCollectionIterator *iterator; 132 OSObject *iteratorKey; 133 OSObject *obj; 134 135 // do nothing if settings haven't changed 136 if(!settingsChangedSinceUpdate) return; 137 138 iterator = OSCollectionIterator::withCollection(properties); 139 if(!iterator) return; 140 141 while ((iteratorKey = iterator->getNextObject())) { 142 OSSymbol *key; 143 144 key = OSDynamicCast(OSSymbol, iteratorKey); 145 if (!key) continue; 146 obj = properties->getObject(key); 147 if(!obj) continue; 148 setProperty(key, obj); 149 } 150 iterator->release(); 151 152 settingsChangedSinceUpdate = false; 153 154 // And up goes the flare 155 messageClients(kIOPMMessageBatteryStatusHasChanged); 156} 157 158 159/******************************************************************************* 160 * 161 * PROTECTED Accessors. All the setters! Yay! 162 * 163 ******************************************************************************/ 164 165void IOPMPowerSource::setPSProperty(const OSSymbol *key, OSObject *val) 166{ 167 OSObject *lastVal; 168 169 if(!key || !val) return; 170 171 // Compare new setting with existing setting; update 172 // 'settingsChangedSinceUpdate' if the setting has changed. 173 // If values are OSNumbers, do equality comparison. 174 // Otherwise, just compare pointers. 175 176 if( (lastVal = properties->getObject(key)) ) { 177 if(val->isEqualTo(lastVal)) { 178 // settings didn't change 179 } else { 180 // num val is not equal to last val 181 settingsChangedSinceUpdate = true; 182 } 183 } else { 184 // new setting; no last value 185 settingsChangedSinceUpdate = true; 186 } 187 188 // here's the part where we go crazy. 189 properties->setObject(key, val); 190} 191 192 193 194void IOPMPowerSource::setExternalConnected(bool b) { 195 setPSProperty(externalConnectedKey, 196 b ? kOSBooleanTrue : kOSBooleanFalse); 197} 198 199void IOPMPowerSource::setExternalChargeCapable(bool b) { 200 setPSProperty(externalChargeCapableKey, 201 b ? kOSBooleanTrue : kOSBooleanFalse); 202} 203 204void IOPMPowerSource::setBatteryInstalled(bool b) { 205 setPSProperty(batteryInstalledKey, 206 b ? kOSBooleanTrue : kOSBooleanFalse); 207} 208 209void IOPMPowerSource::setIsCharging(bool b) { 210 setPSProperty(chargingKey, 211 b ? kOSBooleanTrue : kOSBooleanFalse); 212} 213 214void IOPMPowerSource::setAtWarnLevel(bool b) { 215 setPSProperty(warnLevelKey, 216 b ? kOSBooleanTrue : kOSBooleanFalse); 217} 218 219void IOPMPowerSource::setAtCriticalLevel(bool b) { 220 setPSProperty(criticalLevelKey, 221 b ? kOSBooleanTrue : kOSBooleanFalse); 222} 223 224 225void IOPMPowerSource::setCurrentCapacity(unsigned int val) { 226 OSNumber *n = OSNumber::withNumber(val, 32); 227 setPSProperty(currentCapacityKey, n); 228 n->release(); 229} 230 231void IOPMPowerSource::setMaxCapacity(unsigned int val) { 232 OSNumber *n = OSNumber::withNumber(val, 32); 233 setPSProperty(maxCapacityKey, n); 234 n->release(); 235} 236 237void IOPMPowerSource::setTimeRemaining(int val) { 238 OSNumber *n = OSNumber::withNumber(val, 32); 239 setPSProperty(timeRemainingKey, n); 240 n->release(); 241} 242 243void IOPMPowerSource::setAmperage(int val) { 244 OSNumber *n = OSNumber::withNumber(val, 32); 245 setPSProperty(amperageKey, n); 246 n->release(); 247} 248 249void IOPMPowerSource::setVoltage(unsigned int val) { 250 OSNumber *n = OSNumber::withNumber(val, 32); 251 setPSProperty(voltageKey, n); 252 n->release(); 253} 254 255void IOPMPowerSource::setCycleCount(unsigned int val) { 256 OSNumber *n = OSNumber::withNumber(val, 32); 257 setPSProperty(cycleCountKey, n); 258 n->release(); 259} 260 261void IOPMPowerSource::setAdapterInfo(int val) { 262 OSNumber *n = OSNumber::withNumber(val, 32); 263 setPSProperty(adapterInfoKey, n); 264 n->release(); 265} 266 267void IOPMPowerSource::setLocation(int val) { 268 OSNumber *n = OSNumber::withNumber(val, 32); 269 setPSProperty(locationKey, n); 270 n->release(); 271} 272 273void IOPMPowerSource::setErrorCondition(OSSymbol *s) { 274 setPSProperty(errorConditionKey, s); 275} 276 277void IOPMPowerSource::setManufacturer(OSSymbol *s) { 278 setPSProperty(manufacturerKey, s); 279} 280 281void IOPMPowerSource::setModel(OSSymbol *s) { 282 setPSProperty(modelKey, s); 283} 284 285void IOPMPowerSource::setSerial(OSSymbol *s) { 286 setPSProperty(serialKey, s); 287} 288 289void IOPMPowerSource::setLegacyIOBatteryInfo(OSDictionary *d) { 290 setPSProperty(batteryInfoKey, d); 291} 292 293 294 295 296/******************************************************************************* 297 * 298 * PUBLIC Accessors. All the getters! Boo! 299 * 300 ******************************************************************************/ 301 302OSObject *IOPMPowerSource::getPSProperty(const OSSymbol *symmie) { 303 if(!symmie) return NULL; 304 return properties->getObject(symmie); 305} 306 307bool IOPMPowerSource::externalConnected(void) { 308 return (kOSBooleanTrue == properties->getObject(externalConnectedKey)); 309} 310 311bool IOPMPowerSource::externalChargeCapable(void) { 312 return (kOSBooleanTrue == properties->getObject(externalChargeCapableKey)); 313} 314 315bool IOPMPowerSource::batteryInstalled(void) { 316 return (kOSBooleanTrue == properties->getObject(batteryInstalledKey)); 317} 318 319bool IOPMPowerSource::isCharging(void) { 320 return (kOSBooleanTrue == properties->getObject(chargingKey)); 321} 322 323bool IOPMPowerSource::atWarnLevel(void) { 324 return (kOSBooleanTrue == properties->getObject(warnLevelKey)); 325} 326 327bool IOPMPowerSource::atCriticalLevel(void) { 328 return (kOSBooleanTrue == properties->getObject(criticalLevelKey)); 329} 330 331unsigned int IOPMPowerSource::currentCapacity(void) { 332 OSNumber *n; 333 n = OSDynamicCast(OSNumber, properties->getObject(currentCapacityKey)); 334 if(!n) return 0; 335 else return (unsigned int)n->unsigned32BitValue(); 336} 337 338unsigned int IOPMPowerSource::maxCapacity(void) { 339 OSNumber *n; 340 n = OSDynamicCast(OSNumber, properties->getObject(maxCapacityKey)); 341 if(!n) return 0; 342 else return (unsigned int)n->unsigned32BitValue(); 343} 344 345unsigned int IOPMPowerSource::capacityPercentRemaining(void) 346{ 347 unsigned int _currentCapacity = currentCapacity(); 348 unsigned int _maxCapacity = maxCapacity(); 349 if(0 == _maxCapacity) { 350 return 0; 351 } else { 352 return ((100*_currentCapacity) / _maxCapacity); 353 } 354} 355 356int IOPMPowerSource::timeRemaining(void) { 357 OSNumber *n; 358 n = OSDynamicCast(OSNumber, properties->getObject(timeRemainingKey)); 359 if(!n) return 0; 360 else return (int)n->unsigned32BitValue(); 361} 362 363int IOPMPowerSource::amperage(void) { 364 OSNumber *n; 365 n = OSDynamicCast(OSNumber, properties->getObject(amperageKey)); 366 if(!n) return 0; 367 else return (int)n->unsigned32BitValue(); 368} 369 370unsigned int IOPMPowerSource::voltage(void) { 371 OSNumber *n; 372 n = OSDynamicCast(OSNumber, properties->getObject(voltageKey)); 373 if(!n) return 0; 374 else return (unsigned int)n->unsigned32BitValue(); 375} 376 377unsigned int IOPMPowerSource::cycleCount(void) { 378 OSNumber *n; 379 n = OSDynamicCast(OSNumber, properties->getObject(cycleCountKey)); 380 if(!n) return 0; 381 else return (unsigned int)n->unsigned32BitValue(); 382} 383 384int IOPMPowerSource::adapterInfo(void) { 385 OSNumber *n; 386 n = OSDynamicCast(OSNumber, properties->getObject(adapterInfoKey)); 387 if(!n) return 0; 388 else return (int)n->unsigned32BitValue(); 389} 390 391int IOPMPowerSource::location(void) { 392 OSNumber *n; 393 n = OSDynamicCast(OSNumber, properties->getObject(locationKey)); 394 if(!n) return 0; 395 else return (unsigned int)n->unsigned32BitValue(); 396} 397 398OSSymbol *IOPMPowerSource::errorCondition(void) { 399 return OSDynamicCast(OSSymbol, properties->getObject(errorConditionKey)); 400} 401 402OSSymbol *IOPMPowerSource::manufacturer(void) { 403 return OSDynamicCast(OSSymbol, properties->getObject(manufacturerKey)); 404} 405 406OSSymbol *IOPMPowerSource::model(void) { 407 return OSDynamicCast(OSSymbol, properties->getObject(modelKey)); 408} 409 410OSSymbol *IOPMPowerSource::serial(void) { 411 return OSDynamicCast(OSSymbol, properties->getObject(serialKey)); 412} 413 414OSDictionary *IOPMPowerSource::legacyIOBatteryInfo(void) { 415 return OSDynamicCast(OSDictionary, properties->getObject(batteryInfoKey)); 416} 417