2 * Copyright (c) 1998-2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <IOKit/pwr_mgt/IOPMPowerSource.h>
30 #include <IOKit/pwr_mgt/IOPM.h>
31 #include <IOKit/IOMessage.h>
32 #include <IOKit/IOLib.h>
34 #define super IOService
36 OSDefineMetaClassAndStructors(IOPMPowerSource
, IOService
)
38 // *****************************************************************************
41 // Static initializer for IOPMPowerSource. Returns a new instance of the class
42 // which the caller must attach to the power plane.
43 // *****************************************************************************
45 IOPMPowerSource
*IOPMPowerSource::powerSource(void)
47 IOPMPowerSource
*ps
= new IOPMPowerSource
;
56 // *****************************************************************************
59 // *****************************************************************************
60 bool IOPMPowerSource::init (void)
68 properties
= OSDictionary::withCapacity(10);
69 if(!properties
) return false;
70 properties
->setCapacityIncrement(1);
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
);
95 // *****************************************************************************
98 // *****************************************************************************
99 void IOPMPowerSource::free(void)
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();
123 // *****************************************************************************
126 // Update power source state in IORegistry and message interested clients
127 // notifying them of our change.
128 // *****************************************************************************
129 void IOPMPowerSource::updateStatus (void)
131 OSCollectionIterator
*iterator
;
132 OSObject
*iteratorKey
;
135 // do nothing if settings haven't changed
136 if(!settingsChangedSinceUpdate
) return;
138 iterator
= OSCollectionIterator::withCollection(properties
);
139 if(!iterator
) return;
141 while ((iteratorKey
= iterator
->getNextObject())) {
144 key
= OSDynamicCast(OSSymbol
, iteratorKey
);
146 obj
= properties
->getObject(key
);
148 setProperty(key
, obj
);
152 settingsChangedSinceUpdate
= false;
154 // And up goes the flare
155 messageClients(kIOPMMessageBatteryStatusHasChanged
);
159 /*******************************************************************************
161 * PROTECTED Accessors. All the setters! Yay!
163 ******************************************************************************/
165 void IOPMPowerSource::setPSProperty(const OSSymbol
*key
, OSObject
*val
)
169 if(!key
|| !val
) return;
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.
176 if( (lastVal
= properties
->getObject(key
)) ) {
177 if(val
->isEqualTo(lastVal
)) {
178 // settings didn't change
180 // num val is not equal to last val
181 settingsChangedSinceUpdate
= true;
184 // new setting; no last value
185 settingsChangedSinceUpdate
= true;
188 // here's the part where we go crazy.
189 properties
->setObject(key
, val
);
194 void IOPMPowerSource::setExternalConnected(bool b
) {
195 setPSProperty(externalConnectedKey
,
196 b
? kOSBooleanTrue
: kOSBooleanFalse
);
199 void IOPMPowerSource::setExternalChargeCapable(bool b
) {
200 setPSProperty(externalChargeCapableKey
,
201 b
? kOSBooleanTrue
: kOSBooleanFalse
);
204 void IOPMPowerSource::setBatteryInstalled(bool b
) {
205 setPSProperty(batteryInstalledKey
,
206 b
? kOSBooleanTrue
: kOSBooleanFalse
);
209 void IOPMPowerSource::setIsCharging(bool b
) {
210 setPSProperty(chargingKey
,
211 b
? kOSBooleanTrue
: kOSBooleanFalse
);
214 void IOPMPowerSource::setAtWarnLevel(bool b
) {
215 setPSProperty(warnLevelKey
,
216 b
? kOSBooleanTrue
: kOSBooleanFalse
);
219 void IOPMPowerSource::setAtCriticalLevel(bool b
) {
220 setPSProperty(criticalLevelKey
,
221 b
? kOSBooleanTrue
: kOSBooleanFalse
);
225 void IOPMPowerSource::setCurrentCapacity(unsigned int val
) {
226 OSNumber
*n
= OSNumber::withNumber(val
, 32);
227 setPSProperty(currentCapacityKey
, n
);
231 void IOPMPowerSource::setMaxCapacity(unsigned int val
) {
232 OSNumber
*n
= OSNumber::withNumber(val
, 32);
233 setPSProperty(maxCapacityKey
, n
);
237 void IOPMPowerSource::setTimeRemaining(int val
) {
238 OSNumber
*n
= OSNumber::withNumber(val
, 32);
239 setPSProperty(timeRemainingKey
, n
);
243 void IOPMPowerSource::setAmperage(int val
) {
244 OSNumber
*n
= OSNumber::withNumber(val
, 32);
245 setPSProperty(amperageKey
, n
);
249 void IOPMPowerSource::setVoltage(unsigned int val
) {
250 OSNumber
*n
= OSNumber::withNumber(val
, 32);
251 setPSProperty(voltageKey
, n
);
255 void IOPMPowerSource::setCycleCount(unsigned int val
) {
256 OSNumber
*n
= OSNumber::withNumber(val
, 32);
257 setPSProperty(cycleCountKey
, n
);
261 void IOPMPowerSource::setAdapterInfo(int val
) {
262 OSNumber
*n
= OSNumber::withNumber(val
, 32);
263 setPSProperty(adapterInfoKey
, n
);
267 void IOPMPowerSource::setLocation(int val
) {
268 OSNumber
*n
= OSNumber::withNumber(val
, 32);
269 setPSProperty(locationKey
, n
);
273 void IOPMPowerSource::setErrorCondition(OSSymbol
*s
) {
274 setPSProperty(errorConditionKey
, s
);
277 void IOPMPowerSource::setManufacturer(OSSymbol
*s
) {
278 setPSProperty(manufacturerKey
, s
);
281 void IOPMPowerSource::setModel(OSSymbol
*s
) {
282 setPSProperty(modelKey
, s
);
285 void IOPMPowerSource::setSerial(OSSymbol
*s
) {
286 setPSProperty(serialKey
, s
);
289 void IOPMPowerSource::setLegacyIOBatteryInfo(OSDictionary
*d
) {
290 setPSProperty(batteryInfoKey
, d
);
296 /*******************************************************************************
298 * PUBLIC Accessors. All the getters! Boo!
300 ******************************************************************************/
302 OSObject
*IOPMPowerSource::getPSProperty(const OSSymbol
*symmie
) {
303 if(!symmie
) return NULL
;
304 return properties
->getObject(symmie
);
307 bool IOPMPowerSource::externalConnected(void) {
308 return (kOSBooleanTrue
== properties
->getObject(externalConnectedKey
));
311 bool IOPMPowerSource::externalChargeCapable(void) {
312 return (kOSBooleanTrue
== properties
->getObject(externalChargeCapableKey
));
315 bool IOPMPowerSource::batteryInstalled(void) {
316 return (kOSBooleanTrue
== properties
->getObject(batteryInstalledKey
));
319 bool IOPMPowerSource::isCharging(void) {
320 return (kOSBooleanTrue
== properties
->getObject(chargingKey
));
323 bool IOPMPowerSource::atWarnLevel(void) {
324 return (kOSBooleanTrue
== properties
->getObject(warnLevelKey
));
327 bool IOPMPowerSource::atCriticalLevel(void) {
328 return (kOSBooleanTrue
== properties
->getObject(criticalLevelKey
));
331 unsigned int IOPMPowerSource::currentCapacity(void) {
333 n
= OSDynamicCast(OSNumber
, properties
->getObject(currentCapacityKey
));
335 else return (unsigned int)n
->unsigned32BitValue();
338 unsigned int IOPMPowerSource::maxCapacity(void) {
340 n
= OSDynamicCast(OSNumber
, properties
->getObject(maxCapacityKey
));
342 else return (unsigned int)n
->unsigned32BitValue();
345 unsigned int IOPMPowerSource::capacityPercentRemaining(void)
347 unsigned int _currentCapacity
= currentCapacity();
348 unsigned int _maxCapacity
= maxCapacity();
349 if(0 == _maxCapacity
) {
352 return ((100*_currentCapacity
) / _maxCapacity
);
356 int IOPMPowerSource::timeRemaining(void) {
358 n
= OSDynamicCast(OSNumber
, properties
->getObject(timeRemainingKey
));
360 else return (int)n
->unsigned32BitValue();
363 int IOPMPowerSource::amperage(void) {
365 n
= OSDynamicCast(OSNumber
, properties
->getObject(amperageKey
));
367 else return (int)n
->unsigned32BitValue();
370 unsigned int IOPMPowerSource::voltage(void) {
372 n
= OSDynamicCast(OSNumber
, properties
->getObject(voltageKey
));
374 else return (unsigned int)n
->unsigned32BitValue();
377 unsigned int IOPMPowerSource::cycleCount(void) {
379 n
= OSDynamicCast(OSNumber
, properties
->getObject(cycleCountKey
));
381 else return (unsigned int)n
->unsigned32BitValue();
384 int IOPMPowerSource::adapterInfo(void) {
386 n
= OSDynamicCast(OSNumber
, properties
->getObject(adapterInfoKey
));
388 else return (int)n
->unsigned32BitValue();
391 int IOPMPowerSource::location(void) {
393 n
= OSDynamicCast(OSNumber
, properties
->getObject(locationKey
));
395 else return (unsigned int)n
->unsigned32BitValue();
398 OSSymbol
*IOPMPowerSource::errorCondition(void) {
399 return OSDynamicCast(OSSymbol
, properties
->getObject(errorConditionKey
));
402 OSSymbol
*IOPMPowerSource::manufacturer(void) {
403 return OSDynamicCast(OSSymbol
, properties
->getObject(manufacturerKey
));
406 OSSymbol
*IOPMPowerSource::model(void) {
407 return OSDynamicCast(OSSymbol
, properties
->getObject(modelKey
));
410 OSSymbol
*IOPMPowerSource::serial(void) {
411 return OSDynamicCast(OSSymbol
, properties
->getObject(serialKey
));
414 OSDictionary
*IOPMPowerSource::legacyIOBatteryInfo(void) {
415 return OSDynamicCast(OSDictionary
, properties
->getObject(batteryInfoKey
));