/*
- * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1998-2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
- *
+ *
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
+ *
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
#include <IOKit/pwr_mgt/IOPMPowerSource.h>
+#include <IOKit/pwr_mgt/IOPM.h>
+#include <IOKit/IOMessage.h>
+#include <IOKit/IOLib.h>
-#define super OSObject
+#define super IOService
-OSDefineMetaClassAndStructors(IOPMPowerSource, OSObject)
+OSDefineMetaClassAndStructors(IOPMPowerSource, IOService)
-// **********************************************************************************
-// init
+// *****************************************************************************
+// powerSource
//
-// **********************************************************************************
-bool IOPMPowerSource::init (unsigned short whichBatteryIndex)
-{
- if (!super::init ())
- return false;
+// Static initializer for IOPMPowerSource. Returns a new instance of the class
+// which the caller must attach to the power plane.
+// *****************************************************************************
- bBatteryIndex = whichBatteryIndex;
- nextInList = 0;
+IOPMPowerSource *IOPMPowerSource::powerSource(void)
+{
+ IOPMPowerSource *ps = new IOPMPowerSource;
- return true;
+ if (ps) {
+ ps->init();
+ return ps;
+ }
+ return NULL;
}
-// **********************************************************************************
-// capacityPercentRemaining
+// *****************************************************************************
+// init
//
-// **********************************************************************************
-unsigned long IOPMPowerSource::capacityPercentRemaining (void)
+// *****************************************************************************
+bool
+IOPMPowerSource::init(void)
{
- unsigned long percentage = 0;
+ if (!super::init()) {
+ return false;
+ }
+
+ nextInList = NULL;
- if (bMaxCapacity > 0)
- percentage = (bCurCapacity * 100) / bMaxCapacity;
-
- // always return a non-zero value unless the real capacity IS zero.
- if (percentage == 0 && bCurCapacity > 0)
- percentage = 1;
+ properties = OSDictionary::withCapacity(10);
+ if (!properties) {
+ return false;
+ }
+ properties->setCapacityIncrement(1);
- return percentage;
+ externalConnectedKey = OSSymbol::withCString(kIOPMPSExternalConnectedKey);
+ externalChargeCapableKey = OSSymbol::withCString(kIOPMPSExternalChargeCapableKey);
+ batteryInstalledKey = OSSymbol::withCString(kIOPMPSBatteryInstalledKey);
+ chargingKey = OSSymbol::withCString(kIOPMPSIsChargingKey);
+ warnLevelKey = OSSymbol::withCString(kIOPMPSAtWarnLevelKey);
+ criticalLevelKey = OSSymbol::withCString(kIOPMPSAtCriticalLevelKey);
+ currentCapacityKey = OSSymbol::withCString(kIOPMPSCurrentCapacityKey);
+ maxCapacityKey = OSSymbol::withCString(kIOPMPSMaxCapacityKey);
+ timeRemainingKey = OSSymbol::withCString(kIOPMPSTimeRemainingKey);
+ amperageKey = OSSymbol::withCString(kIOPMPSAmperageKey);
+ voltageKey = OSSymbol::withCString(kIOPMPSVoltageKey);
+ cycleCountKey = OSSymbol::withCString(kIOPMPSCycleCountKey);
+ adapterInfoKey = OSSymbol::withCString(kIOPMPSAdapterInfoKey);
+ locationKey = OSSymbol::withCString(kIOPMPSLocationKey);
+ errorConditionKey = OSSymbol::withCString(kIOPMPSErrorConditionKey);
+ manufacturerKey = OSSymbol::withCString(kIOPMPSManufacturerKey);
+ modelKey = OSSymbol::withCString(kIOPMPSModelKey);
+ serialKey = OSSymbol::withCString(kIOPMPSSerialKey);
+ batteryInfoKey = OSSymbol::withCString(kIOPMPSLegacyBatteryInfoKey);
+
+ return true;
}
-// **********************************************************************************
-// atWarnLevel
+// *****************************************************************************
+// free
//
-// **********************************************************************************
-bool IOPMPowerSource::atWarnLevel (void)
+// *****************************************************************************
+void
+IOPMPowerSource::free(void)
{
- return bFlags & kBatteryAtWarn;
+ if (properties) {
+ properties->release();
+ }
+ if (externalConnectedKey) {
+ externalConnectedKey->release();
+ }
+ if (externalChargeCapableKey) {
+ externalChargeCapableKey->release();
+ }
+ if (batteryInstalledKey) {
+ batteryInstalledKey->release();
+ }
+ if (chargingKey) {
+ chargingKey->release();
+ }
+ if (warnLevelKey) {
+ warnLevelKey->release();
+ }
+ if (criticalLevelKey) {
+ criticalLevelKey->release();
+ }
+ if (currentCapacityKey) {
+ currentCapacityKey->release();
+ }
+ if (maxCapacityKey) {
+ maxCapacityKey->release();
+ }
+ if (timeRemainingKey) {
+ timeRemainingKey->release();
+ }
+ if (amperageKey) {
+ amperageKey->release();
+ }
+ if (voltageKey) {
+ voltageKey->release();
+ }
+ if (cycleCountKey) {
+ cycleCountKey->release();
+ }
+ if (adapterInfoKey) {
+ adapterInfoKey->release();
+ }
+ if (errorConditionKey) {
+ errorConditionKey->release();
+ }
+ if (manufacturerKey) {
+ manufacturerKey->release();
+ }
+ if (modelKey) {
+ modelKey->release();
+ }
+ if (serialKey) {
+ serialKey->release();
+ }
+ if (locationKey) {
+ locationKey->release();
+ }
+ if (batteryInfoKey) {
+ batteryInfoKey->release();
+ }
+
+ super::free();
}
-// **********************************************************************************
-// acConnected
+// *****************************************************************************
+// updateStatus
//
-// **********************************************************************************
-bool IOPMPowerSource::acConnected (void)
+// Update power source state in IORegistry and message interested clients
+// notifying them of our change.
+// *****************************************************************************
+void
+IOPMPowerSource::updateStatus(void)
{
- return bFlags & kACInstalled;
+ OSCollectionIterator *iterator;
+ OSObject *iteratorKey;
+ OSObject *obj;
+
+ // do nothing if settings haven't changed
+ if (!settingsChangedSinceUpdate) {
+ return;
+ }
+
+ iterator = OSCollectionIterator::withCollection(properties);
+ if (!iterator) {
+ return;
+ }
+
+ while ((iteratorKey = iterator->getNextObject())) {
+ OSSymbol *key;
+
+ key = OSDynamicCast(OSSymbol, iteratorKey);
+ if (!key) {
+ continue;
+ }
+ obj = properties->getObject(key);
+ if (!obj) {
+ continue;
+ }
+ setProperty(key, obj);
+ }
+ iterator->release();
+
+ settingsChangedSinceUpdate = false;
+
+ // And up goes the flare
+ messageClients(kIOPMMessageBatteryStatusHasChanged);
}
-// **********************************************************************************
-// depleted
-//
-// **********************************************************************************
-bool IOPMPowerSource::depleted (void)
+
+/*******************************************************************************
+ *
+ * PROTECTED Accessors. All the setters! Yay!
+ *
+ ******************************************************************************/
+
+void
+IOPMPowerSource::setPSProperty(const OSSymbol *key, OSObject *val)
{
- return bFlags & kBatteryDepleted;
+ OSObject *lastVal;
+
+ if (!key || !val) {
+ return;
+ }
+
+ // Compare new setting with existing setting; update
+ // 'settingsChangedSinceUpdate' if the setting has changed.
+ // If values are OSNumbers, do equality comparison.
+ // Otherwise, just compare pointers.
+
+ if ((lastVal = properties->getObject(key))) {
+ if (val->isEqualTo(lastVal)) {
+ // settings didn't change
+ } else {
+ // num val is not equal to last val
+ settingsChangedSinceUpdate = true;
+ }
+ } else {
+ // new setting; no last value
+ settingsChangedSinceUpdate = true;
+ }
+
+ // here's the part where we go crazy.
+ properties->setObject(key, val);
}
-// **********************************************************************************
-// isInstalled
-//
-// **********************************************************************************
-bool IOPMPowerSource::isInstalled (void)
+
+
+void
+IOPMPowerSource::setExternalConnected(bool b)
{
- return bFlags & kBatteryInstalled;
+ setPSProperty(externalConnectedKey,
+ b ? kOSBooleanTrue : kOSBooleanFalse);
}
-// **********************************************************************************
-// isCharging
-//
-// **********************************************************************************
-bool IOPMPowerSource::isCharging (void)
+void
+IOPMPowerSource::setExternalChargeCapable(bool b)
{
- return bFlags & kBatteryCharging;
+ setPSProperty(externalChargeCapableKey,
+ b ? kOSBooleanTrue : kOSBooleanFalse);
}
-// **********************************************************************************
-// timeRemaining
-//
-// **********************************************************************************
-unsigned long IOPMPowerSource::timeRemaining (void)
+void
+IOPMPowerSource::setBatteryInstalled(bool b)
{
- return bTimeRemaining;
+ setPSProperty(batteryInstalledKey,
+ b ? kOSBooleanTrue : kOSBooleanFalse);
}
-// **********************************************************************************
-// maxCapacity
-//
-// **********************************************************************************
-unsigned long IOPMPowerSource::maxCapacity (void)
+void
+IOPMPowerSource::setIsCharging(bool b)
{
- return bMaxCapacity;
+ setPSProperty(chargingKey,
+ b ? kOSBooleanTrue : kOSBooleanFalse);
}
-// **********************************************************************************
-// curCapacity
-//
-// **********************************************************************************
-unsigned long IOPMPowerSource::curCapacity (void)
+void
+IOPMPowerSource::setAtWarnLevel(bool b)
{
- return bCurCapacity;
+ setPSProperty(warnLevelKey,
+ b ? kOSBooleanTrue : kOSBooleanFalse);
}
-// **********************************************************************************
-// currentDrawn
-//
-// **********************************************************************************
-long IOPMPowerSource::currentDrawn (void)
+void
+IOPMPowerSource::setAtCriticalLevel(bool b)
{
- return bCurrent;
+ setPSProperty(criticalLevelKey,
+ b ? kOSBooleanTrue : kOSBooleanFalse);
}
-// **********************************************************************************
-// voltage
-//
-// **********************************************************************************
-unsigned long IOPMPowerSource::voltage (void)
+void
+IOPMPowerSource::setCurrentCapacity(unsigned int val)
{
- return bVoltage;
+ OSNumber *n = OSNumber::withNumber(val, 32);
+ setPSProperty(currentCapacityKey, n);
+ n->release();
}
-// **********************************************************************************
-// updateStatus
-//
-// **********************************************************************************
+void
+IOPMPowerSource::setMaxCapacity(unsigned int val)
+{
+ OSNumber *n = OSNumber::withNumber(val, 32);
+ setPSProperty(maxCapacityKey, n);
+ n->release();
+}
-void IOPMPowerSource::updateStatus (void)
+void
+IOPMPowerSource::setTimeRemaining(int val)
{
+ OSNumber *n = OSNumber::withNumber(val, 32);
+ setPSProperty(timeRemainingKey, n);
+ n->release();
+}
+void
+IOPMPowerSource::setAmperage(int val)
+{
+ OSNumber *n = OSNumber::withNumber(val, 32);
+ setPSProperty(amperageKey, n);
+ n->release();
}
+void
+IOPMPowerSource::setVoltage(unsigned int val)
+{
+ OSNumber *n = OSNumber::withNumber(val, 32);
+ setPSProperty(voltageKey, n);
+ n->release();
+}
+
+void
+IOPMPowerSource::setCycleCount(unsigned int val)
+{
+ OSNumber *n = OSNumber::withNumber(val, 32);
+ setPSProperty(cycleCountKey, n);
+ n->release();
+}
+void
+IOPMPowerSource::setAdapterInfo(int val)
+{
+ OSNumber *n = OSNumber::withNumber(val, 32);
+ setPSProperty(adapterInfoKey, n);
+ n->release();
+}
+
+void
+IOPMPowerSource::setLocation(int val)
+{
+ OSNumber *n = OSNumber::withNumber(val, 32);
+ setPSProperty(locationKey, n);
+ n->release();
+}
+
+void
+IOPMPowerSource::setErrorCondition(OSSymbol *s)
+{
+ setPSProperty(errorConditionKey, s);
+}
+
+void
+IOPMPowerSource::setManufacturer(OSSymbol *s)
+{
+ setPSProperty(manufacturerKey, s);
+}
+
+void
+IOPMPowerSource::setModel(OSSymbol *s)
+{
+ setPSProperty(modelKey, s);
+}
+
+void
+IOPMPowerSource::setSerial(OSSymbol *s)
+{
+ setPSProperty(serialKey, s);
+}
+
+void
+IOPMPowerSource::setLegacyIOBatteryInfo(OSDictionary *d)
+{
+ setPSProperty(batteryInfoKey, d);
+}
+
+/*******************************************************************************
+ *
+ * PUBLIC Accessors. All the getters! Boo!
+ *
+ ******************************************************************************/
+
+OSObject *
+IOPMPowerSource::getPSProperty(const OSSymbol *symmie)
+{
+ if (!symmie) {
+ return NULL;
+ }
+ return properties->getObject(symmie);
+}
+
+bool
+IOPMPowerSource::externalConnected(void)
+{
+ return kOSBooleanTrue == properties->getObject(externalConnectedKey);
+}
+
+bool
+IOPMPowerSource::externalChargeCapable(void)
+{
+ return kOSBooleanTrue == properties->getObject(externalChargeCapableKey);
+}
+
+bool
+IOPMPowerSource::batteryInstalled(void)
+{
+ return kOSBooleanTrue == properties->getObject(batteryInstalledKey);
+}
+
+bool
+IOPMPowerSource::isCharging(void)
+{
+ return kOSBooleanTrue == properties->getObject(chargingKey);
+}
+
+bool
+IOPMPowerSource::atWarnLevel(void)
+{
+ return kOSBooleanTrue == properties->getObject(warnLevelKey);
+}
+
+bool
+IOPMPowerSource::atCriticalLevel(void)
+{
+ return kOSBooleanTrue == properties->getObject(criticalLevelKey);
+}
+
+unsigned int
+IOPMPowerSource::currentCapacity(void)
+{
+ OSNumber *n;
+ n = OSDynamicCast(OSNumber, properties->getObject(currentCapacityKey));
+ if (!n) {
+ return 0;
+ } else {
+ return (unsigned int)n->unsigned32BitValue();
+ }
+}
+
+unsigned int
+IOPMPowerSource::maxCapacity(void)
+{
+ OSNumber *n;
+ n = OSDynamicCast(OSNumber, properties->getObject(maxCapacityKey));
+ if (!n) {
+ return 0;
+ } else {
+ return (unsigned int)n->unsigned32BitValue();
+ }
+}
+
+unsigned int
+IOPMPowerSource::capacityPercentRemaining(void)
+{
+ unsigned int _currentCapacity = currentCapacity();
+ unsigned int _maxCapacity = maxCapacity();
+ if (0 == _maxCapacity) {
+ return 0;
+ } else {
+ return (100 * _currentCapacity) / _maxCapacity;
+ }
+}
+
+int
+IOPMPowerSource::timeRemaining(void)
+{
+ OSNumber *n;
+ n = OSDynamicCast(OSNumber, properties->getObject(timeRemainingKey));
+ if (!n) {
+ return 0;
+ } else {
+ return (int)n->unsigned32BitValue();
+ }
+}
+
+int
+IOPMPowerSource::amperage(void)
+{
+ OSNumber *n;
+ n = OSDynamicCast(OSNumber, properties->getObject(amperageKey));
+ if (!n) {
+ return 0;
+ } else {
+ return (int)n->unsigned32BitValue();
+ }
+}
+
+unsigned int
+IOPMPowerSource::voltage(void)
+{
+ OSNumber *n;
+ n = OSDynamicCast(OSNumber, properties->getObject(voltageKey));
+ if (!n) {
+ return 0;
+ } else {
+ return (unsigned int)n->unsigned32BitValue();
+ }
+}
+
+unsigned int
+IOPMPowerSource::cycleCount(void)
+{
+ OSNumber *n;
+ n = OSDynamicCast(OSNumber, properties->getObject(cycleCountKey));
+ if (!n) {
+ return 0;
+ } else {
+ return (unsigned int)n->unsigned32BitValue();
+ }
+}
+
+int
+IOPMPowerSource::adapterInfo(void)
+{
+ OSNumber *n;
+ n = OSDynamicCast(OSNumber, properties->getObject(adapterInfoKey));
+ if (!n) {
+ return 0;
+ } else {
+ return (int)n->unsigned32BitValue();
+ }
+}
+
+int
+IOPMPowerSource::location(void)
+{
+ OSNumber *n;
+ n = OSDynamicCast(OSNumber, properties->getObject(locationKey));
+ if (!n) {
+ return 0;
+ } else {
+ return (unsigned int)n->unsigned32BitValue();
+ }
+}
+
+OSSymbol *
+IOPMPowerSource::errorCondition(void)
+{
+ return OSDynamicCast(OSSymbol, properties->getObject(errorConditionKey));
+}
+
+OSSymbol *
+IOPMPowerSource::manufacturer(void)
+{
+ return OSDynamicCast(OSSymbol, properties->getObject(manufacturerKey));
+}
+
+OSSymbol *
+IOPMPowerSource::model(void)
+{
+ return OSDynamicCast(OSSymbol, properties->getObject(modelKey));
+}
+
+OSSymbol *
+IOPMPowerSource::serial(void)
+{
+ return OSDynamicCast(OSSymbol, properties->getObject(serialKey));
+}
+
+OSDictionary *
+IOPMPowerSource::legacyIOBatteryInfo(void)
+{
+ return OSDynamicCast(OSDictionary, properties->getObject(batteryInfoKey));
+}