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 // *****************************************************************************
61 IOPMPowerSource::init(void)
69 properties
= OSDictionary::withCapacity(10);
73 properties
->setCapacityIncrement(1);
75 externalConnectedKey
= OSSymbol::withCString(kIOPMPSExternalConnectedKey
);
76 externalChargeCapableKey
= OSSymbol::withCString(kIOPMPSExternalChargeCapableKey
);
77 batteryInstalledKey
= OSSymbol::withCString(kIOPMPSBatteryInstalledKey
);
78 chargingKey
= OSSymbol::withCString(kIOPMPSIsChargingKey
);
79 warnLevelKey
= OSSymbol::withCString(kIOPMPSAtWarnLevelKey
);
80 criticalLevelKey
= OSSymbol::withCString(kIOPMPSAtCriticalLevelKey
);
81 currentCapacityKey
= OSSymbol::withCString(kIOPMPSCurrentCapacityKey
);
82 maxCapacityKey
= OSSymbol::withCString(kIOPMPSMaxCapacityKey
);
83 timeRemainingKey
= OSSymbol::withCString(kIOPMPSTimeRemainingKey
);
84 amperageKey
= OSSymbol::withCString(kIOPMPSAmperageKey
);
85 voltageKey
= OSSymbol::withCString(kIOPMPSVoltageKey
);
86 cycleCountKey
= OSSymbol::withCString(kIOPMPSCycleCountKey
);
87 adapterInfoKey
= OSSymbol::withCString(kIOPMPSAdapterInfoKey
);
88 locationKey
= OSSymbol::withCString(kIOPMPSLocationKey
);
89 errorConditionKey
= OSSymbol::withCString(kIOPMPSErrorConditionKey
);
90 manufacturerKey
= OSSymbol::withCString(kIOPMPSManufacturerKey
);
91 modelKey
= OSSymbol::withCString(kIOPMPSModelKey
);
92 serialKey
= OSSymbol::withCString(kIOPMPSSerialKey
);
93 batteryInfoKey
= OSSymbol::withCString(kIOPMPSLegacyBatteryInfoKey
);
98 // *****************************************************************************
101 // *****************************************************************************
103 IOPMPowerSource::free(void)
106 properties
->release();
108 if (externalConnectedKey
) {
109 externalConnectedKey
->release();
111 if (externalChargeCapableKey
) {
112 externalChargeCapableKey
->release();
114 if (batteryInstalledKey
) {
115 batteryInstalledKey
->release();
118 chargingKey
->release();
121 warnLevelKey
->release();
123 if (criticalLevelKey
) {
124 criticalLevelKey
->release();
126 if (currentCapacityKey
) {
127 currentCapacityKey
->release();
129 if (maxCapacityKey
) {
130 maxCapacityKey
->release();
132 if (timeRemainingKey
) {
133 timeRemainingKey
->release();
136 amperageKey
->release();
139 voltageKey
->release();
142 cycleCountKey
->release();
144 if (adapterInfoKey
) {
145 adapterInfoKey
->release();
147 if (errorConditionKey
) {
148 errorConditionKey
->release();
150 if (manufacturerKey
) {
151 manufacturerKey
->release();
157 serialKey
->release();
160 locationKey
->release();
162 if (batteryInfoKey
) {
163 batteryInfoKey
->release();
169 // *****************************************************************************
172 // Update power source state in IORegistry and message interested clients
173 // notifying them of our change.
174 // *****************************************************************************
176 IOPMPowerSource::updateStatus(void)
178 OSCollectionIterator
*iterator
;
179 OSObject
*iteratorKey
;
182 // do nothing if settings haven't changed
183 if (!settingsChangedSinceUpdate
) {
187 iterator
= OSCollectionIterator::withCollection(properties
);
192 while ((iteratorKey
= iterator
->getNextObject())) {
195 key
= OSDynamicCast(OSSymbol
, iteratorKey
);
199 obj
= properties
->getObject(key
);
203 setProperty(key
, obj
);
207 settingsChangedSinceUpdate
= false;
209 // And up goes the flare
210 messageClients(kIOPMMessageBatteryStatusHasChanged
);
214 /*******************************************************************************
216 * PROTECTED Accessors. All the setters! Yay!
218 ******************************************************************************/
221 IOPMPowerSource::setPSProperty(const OSSymbol
*key
, OSObject
*val
)
229 // Compare new setting with existing setting; update
230 // 'settingsChangedSinceUpdate' if the setting has changed.
231 // If values are OSNumbers, do equality comparison.
232 // Otherwise, just compare pointers.
234 if ((lastVal
= properties
->getObject(key
))) {
235 if (val
->isEqualTo(lastVal
)) {
236 // settings didn't change
238 // num val is not equal to last val
239 settingsChangedSinceUpdate
= true;
242 // new setting; no last value
243 settingsChangedSinceUpdate
= true;
246 // here's the part where we go crazy.
247 properties
->setObject(key
, val
);
253 IOPMPowerSource::setExternalConnected(bool b
)
255 setPSProperty(externalConnectedKey
,
256 b
? kOSBooleanTrue
: kOSBooleanFalse
);
260 IOPMPowerSource::setExternalChargeCapable(bool b
)
262 setPSProperty(externalChargeCapableKey
,
263 b
? kOSBooleanTrue
: kOSBooleanFalse
);
267 IOPMPowerSource::setBatteryInstalled(bool b
)
269 setPSProperty(batteryInstalledKey
,
270 b
? kOSBooleanTrue
: kOSBooleanFalse
);
274 IOPMPowerSource::setIsCharging(bool b
)
276 setPSProperty(chargingKey
,
277 b
? kOSBooleanTrue
: kOSBooleanFalse
);
281 IOPMPowerSource::setAtWarnLevel(bool b
)
283 setPSProperty(warnLevelKey
,
284 b
? kOSBooleanTrue
: kOSBooleanFalse
);
288 IOPMPowerSource::setAtCriticalLevel(bool b
)
290 setPSProperty(criticalLevelKey
,
291 b
? kOSBooleanTrue
: kOSBooleanFalse
);
296 IOPMPowerSource::setCurrentCapacity(unsigned int val
)
298 OSNumber
*n
= OSNumber::withNumber(val
, 32);
299 setPSProperty(currentCapacityKey
, n
);
304 IOPMPowerSource::setMaxCapacity(unsigned int val
)
306 OSNumber
*n
= OSNumber::withNumber(val
, 32);
307 setPSProperty(maxCapacityKey
, n
);
312 IOPMPowerSource::setTimeRemaining(int val
)
314 OSNumber
*n
= OSNumber::withNumber(val
, 32);
315 setPSProperty(timeRemainingKey
, n
);
320 IOPMPowerSource::setAmperage(int val
)
322 OSNumber
*n
= OSNumber::withNumber(val
, 32);
323 setPSProperty(amperageKey
, n
);
328 IOPMPowerSource::setVoltage(unsigned int val
)
330 OSNumber
*n
= OSNumber::withNumber(val
, 32);
331 setPSProperty(voltageKey
, n
);
336 IOPMPowerSource::setCycleCount(unsigned int val
)
338 OSNumber
*n
= OSNumber::withNumber(val
, 32);
339 setPSProperty(cycleCountKey
, n
);
344 IOPMPowerSource::setAdapterInfo(int val
)
346 OSNumber
*n
= OSNumber::withNumber(val
, 32);
347 setPSProperty(adapterInfoKey
, n
);
352 IOPMPowerSource::setLocation(int val
)
354 OSNumber
*n
= OSNumber::withNumber(val
, 32);
355 setPSProperty(locationKey
, n
);
360 IOPMPowerSource::setErrorCondition(OSSymbol
*s
)
362 setPSProperty(errorConditionKey
, s
);
366 IOPMPowerSource::setManufacturer(OSSymbol
*s
)
368 setPSProperty(manufacturerKey
, s
);
372 IOPMPowerSource::setModel(OSSymbol
*s
)
374 setPSProperty(modelKey
, s
);
378 IOPMPowerSource::setSerial(OSSymbol
*s
)
380 setPSProperty(serialKey
, s
);
384 IOPMPowerSource::setLegacyIOBatteryInfo(OSDictionary
*d
)
386 setPSProperty(batteryInfoKey
, d
);
392 /*******************************************************************************
394 * PUBLIC Accessors. All the getters! Boo!
396 ******************************************************************************/
399 IOPMPowerSource::getPSProperty(const OSSymbol
*symmie
)
404 return properties
->getObject(symmie
);
408 IOPMPowerSource::externalConnected(void)
410 return kOSBooleanTrue
== properties
->getObject(externalConnectedKey
);
414 IOPMPowerSource::externalChargeCapable(void)
416 return kOSBooleanTrue
== properties
->getObject(externalChargeCapableKey
);
420 IOPMPowerSource::batteryInstalled(void)
422 return kOSBooleanTrue
== properties
->getObject(batteryInstalledKey
);
426 IOPMPowerSource::isCharging(void)
428 return kOSBooleanTrue
== properties
->getObject(chargingKey
);
432 IOPMPowerSource::atWarnLevel(void)
434 return kOSBooleanTrue
== properties
->getObject(warnLevelKey
);
438 IOPMPowerSource::atCriticalLevel(void)
440 return kOSBooleanTrue
== properties
->getObject(criticalLevelKey
);
444 IOPMPowerSource::currentCapacity(void)
447 n
= OSDynamicCast(OSNumber
, properties
->getObject(currentCapacityKey
));
451 return (unsigned int)n
->unsigned32BitValue();
456 IOPMPowerSource::maxCapacity(void)
459 n
= OSDynamicCast(OSNumber
, properties
->getObject(maxCapacityKey
));
463 return (unsigned int)n
->unsigned32BitValue();
468 IOPMPowerSource::capacityPercentRemaining(void)
470 unsigned int _currentCapacity
= currentCapacity();
471 unsigned int _maxCapacity
= maxCapacity();
472 if (0 == _maxCapacity
) {
475 return (100 * _currentCapacity
) / _maxCapacity
;
480 IOPMPowerSource::timeRemaining(void)
483 n
= OSDynamicCast(OSNumber
, properties
->getObject(timeRemainingKey
));
487 return (int)n
->unsigned32BitValue();
492 IOPMPowerSource::amperage(void)
495 n
= OSDynamicCast(OSNumber
, properties
->getObject(amperageKey
));
499 return (int)n
->unsigned32BitValue();
504 IOPMPowerSource::voltage(void)
507 n
= OSDynamicCast(OSNumber
, properties
->getObject(voltageKey
));
511 return (unsigned int)n
->unsigned32BitValue();
516 IOPMPowerSource::cycleCount(void)
519 n
= OSDynamicCast(OSNumber
, properties
->getObject(cycleCountKey
));
523 return (unsigned int)n
->unsigned32BitValue();
528 IOPMPowerSource::adapterInfo(void)
531 n
= OSDynamicCast(OSNumber
, properties
->getObject(adapterInfoKey
));
535 return (int)n
->unsigned32BitValue();
540 IOPMPowerSource::location(void)
543 n
= OSDynamicCast(OSNumber
, properties
->getObject(locationKey
));
547 return (unsigned int)n
->unsigned32BitValue();
552 IOPMPowerSource::errorCondition(void)
554 return OSDynamicCast(OSSymbol
, properties
->getObject(errorConditionKey
));
558 IOPMPowerSource::manufacturer(void)
560 return OSDynamicCast(OSSymbol
, properties
->getObject(manufacturerKey
));
564 IOPMPowerSource::model(void)
566 return OSDynamicCast(OSSymbol
, properties
->getObject(modelKey
));
570 IOPMPowerSource::serial(void)
572 return OSDynamicCast(OSSymbol
, properties
->getObject(serialKey
));
576 IOPMPowerSource::legacyIOBatteryInfo(void)
578 return OSDynamicCast(OSDictionary
, properties
->getObject(batteryInfoKey
));