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
)
170 if(!key
|| !val
) return;
172 // Compare new setting with existing setting; update
173 // 'settingsChangedSinceUpdate' if the setting has changed.
174 // If values are OSNumbers, do equality comparison.
175 // Otherwise, just compare pointers.
177 if( (lastVal
= properties
->getObject(key
)) ) {
178 newNumVal
= OSDynamicCast(OSNumber
, val
);
180 if(newNumVal
->isEqualTo(lastVal
)) {
181 // settings didn't change
183 // num val is not equal to last val
184 settingsChangedSinceUpdate
= true;
187 // pointer compare as last resort
189 settingsChangedSinceUpdate
= true;
192 // new setting; no last value
193 settingsChangedSinceUpdate
= true;
196 // here's the part where we go crazy.
197 properties
->setObject(key
, val
);
202 void IOPMPowerSource::setExternalConnected(bool b
) {
203 setPSProperty(externalConnectedKey
,
204 b
? kOSBooleanTrue
: kOSBooleanFalse
);
207 void IOPMPowerSource::setExternalChargeCapable(bool b
) {
208 setPSProperty(externalChargeCapableKey
,
209 b
? kOSBooleanTrue
: kOSBooleanFalse
);
212 void IOPMPowerSource::setBatteryInstalled(bool b
) {
213 setPSProperty(batteryInstalledKey
,
214 b
? kOSBooleanTrue
: kOSBooleanFalse
);
217 void IOPMPowerSource::setIsCharging(bool b
) {
218 setPSProperty(chargingKey
,
219 b
? kOSBooleanTrue
: kOSBooleanFalse
);
222 void IOPMPowerSource::setAtWarnLevel(bool b
) {
223 setPSProperty(warnLevelKey
,
224 b
? kOSBooleanTrue
: kOSBooleanFalse
);
227 void IOPMPowerSource::setAtCriticalLevel(bool b
) {
228 setPSProperty(criticalLevelKey
,
229 b
? kOSBooleanTrue
: kOSBooleanFalse
);
233 void IOPMPowerSource::setCurrentCapacity(unsigned int val
) {
234 OSNumber
*n
= OSNumber::withNumber(val
, 32);
235 setPSProperty(currentCapacityKey
, n
);
239 void IOPMPowerSource::setMaxCapacity(unsigned int val
) {
240 OSNumber
*n
= OSNumber::withNumber(val
, 32);
241 setPSProperty(maxCapacityKey
, n
);
245 void IOPMPowerSource::setTimeRemaining(int val
) {
246 OSNumber
*n
= OSNumber::withNumber(val
, 32);
247 setPSProperty(timeRemainingKey
, n
);
251 void IOPMPowerSource::setAmperage(int val
) {
252 OSNumber
*n
= OSNumber::withNumber(val
, 32);
253 setPSProperty(amperageKey
, n
);
257 void IOPMPowerSource::setVoltage(unsigned int val
) {
258 OSNumber
*n
= OSNumber::withNumber(val
, 32);
259 setPSProperty(voltageKey
, n
);
263 void IOPMPowerSource::setCycleCount(unsigned int val
) {
264 OSNumber
*n
= OSNumber::withNumber(val
, 32);
265 setPSProperty(cycleCountKey
, n
);
269 void IOPMPowerSource::setAdapterInfo(int val
) {
270 OSNumber
*n
= OSNumber::withNumber(val
, 32);
271 setPSProperty(adapterInfoKey
, n
);
275 void IOPMPowerSource::setLocation(int val
) {
276 OSNumber
*n
= OSNumber::withNumber(val
, 32);
277 setPSProperty(locationKey
, n
);
281 void IOPMPowerSource::setErrorCondition(OSSymbol
*s
) {
282 setPSProperty(errorConditionKey
, s
);
285 void IOPMPowerSource::setManufacturer(OSSymbol
*s
) {
286 setPSProperty(manufacturerKey
, s
);
289 void IOPMPowerSource::setModel(OSSymbol
*s
) {
290 setPSProperty(modelKey
, s
);
293 void IOPMPowerSource::setSerial(OSSymbol
*s
) {
294 setPSProperty(serialKey
, s
);
297 void IOPMPowerSource::setLegacyIOBatteryInfo(OSDictionary
*d
) {
298 setPSProperty(batteryInfoKey
, d
);
304 /*******************************************************************************
306 * PUBLIC Accessors. All the getters! Boo!
308 ******************************************************************************/
310 OSObject
*IOPMPowerSource::getPSProperty(const OSSymbol
*symmie
) {
311 if(!symmie
) return NULL
;
312 return properties
->getObject(symmie
);
315 bool IOPMPowerSource::externalConnected(void) {
316 return (kOSBooleanTrue
== properties
->getObject(externalConnectedKey
));
319 bool IOPMPowerSource::externalChargeCapable(void) {
320 return (kOSBooleanTrue
== properties
->getObject(externalChargeCapableKey
));
323 bool IOPMPowerSource::batteryInstalled(void) {
324 return (kOSBooleanTrue
== properties
->getObject(batteryInstalledKey
));
327 bool IOPMPowerSource::isCharging(void) {
328 return (kOSBooleanTrue
== properties
->getObject(chargingKey
));
331 bool IOPMPowerSource::atWarnLevel(void) {
332 return (kOSBooleanTrue
== properties
->getObject(warnLevelKey
));
335 bool IOPMPowerSource::atCriticalLevel(void) {
336 return (kOSBooleanTrue
== properties
->getObject(criticalLevelKey
));
339 unsigned int IOPMPowerSource::currentCapacity(void) {
341 n
= OSDynamicCast(OSNumber
, properties
->getObject(currentCapacityKey
));
343 else return (unsigned int)n
->unsigned32BitValue();
346 unsigned int IOPMPowerSource::maxCapacity(void) {
348 n
= OSDynamicCast(OSNumber
, properties
->getObject(maxCapacityKey
));
350 else return (unsigned int)n
->unsigned32BitValue();
353 unsigned int IOPMPowerSource::capacityPercentRemaining(void)
355 unsigned int _currentCapacity
= currentCapacity();
356 unsigned int _maxCapacity
= maxCapacity();
357 if(0 == _maxCapacity
) {
360 return ((100*_currentCapacity
) / _maxCapacity
);
364 int IOPMPowerSource::timeRemaining(void) {
366 n
= OSDynamicCast(OSNumber
, properties
->getObject(timeRemainingKey
));
368 else return (int)n
->unsigned32BitValue();
371 int IOPMPowerSource::amperage(void) {
373 n
= OSDynamicCast(OSNumber
, properties
->getObject(amperageKey
));
375 else return (int)n
->unsigned32BitValue();
378 unsigned int IOPMPowerSource::voltage(void) {
380 n
= OSDynamicCast(OSNumber
, properties
->getObject(voltageKey
));
382 else return (unsigned int)n
->unsigned32BitValue();
385 unsigned int IOPMPowerSource::cycleCount(void) {
387 n
= OSDynamicCast(OSNumber
, properties
->getObject(cycleCountKey
));
389 else return (unsigned int)n
->unsigned32BitValue();
392 int IOPMPowerSource::adapterInfo(void) {
394 n
= OSDynamicCast(OSNumber
, properties
->getObject(adapterInfoKey
));
396 else return (int)n
->unsigned32BitValue();
399 int IOPMPowerSource::location(void) {
401 n
= OSDynamicCast(OSNumber
, properties
->getObject(locationKey
));
403 else return (unsigned int)n
->unsigned32BitValue();
406 OSSymbol
*IOPMPowerSource::errorCondition(void) {
407 return OSDynamicCast(OSSymbol
, properties
->getObject(errorConditionKey
));
410 OSSymbol
*IOPMPowerSource::manufacturer(void) {
411 return OSDynamicCast(OSSymbol
, properties
->getObject(manufacturerKey
));
414 OSSymbol
*IOPMPowerSource::model(void) {
415 return OSDynamicCast(OSSymbol
, properties
->getObject(modelKey
));
418 OSSymbol
*IOPMPowerSource::serial(void) {
419 return OSDynamicCast(OSSymbol
, properties
->getObject(serialKey
));
422 OSDictionary
*IOPMPowerSource::legacyIOBatteryInfo(void) {
423 return OSDynamicCast(OSDictionary
, properties
->getObject(batteryInfoKey
));