]> git.saurik.com Git - apple/xnu.git/blame - iokit/Kernel/IOPMPowerSource.cpp
xnu-6153.141.1.tar.gz
[apple/xnu.git] / iokit / Kernel / IOPMPowerSource.cpp
CommitLineData
1c79356b 1/*
0c530ab8 2 * Copyright (c) 1998-2005 Apple Computer, Inc. All rights reserved.
1c79356b 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
0a7de745 5 *
2d21ac55
A
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.
0a7de745 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
0a7de745 17 *
2d21ac55
A
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
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
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.
0a7de745 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
27 */
28
29#include <IOKit/pwr_mgt/IOPMPowerSource.h>
0c530ab8
A
30#include <IOKit/pwr_mgt/IOPM.h>
31#include <IOKit/IOMessage.h>
32#include <IOKit/IOLib.h>
1c79356b 33
0c530ab8 34#define super IOService
1c79356b 35
0c530ab8 36OSDefineMetaClassAndStructors(IOPMPowerSource, IOService)
1c79356b 37
0c530ab8
A
38// *****************************************************************************
39// powerSource
1c79356b 40//
0c530ab8
A
41// Static initializer for IOPMPowerSource. Returns a new instance of the class
42// which the caller must attach to the power plane.
43// *****************************************************************************
8ad349bb 44
0c530ab8
A
45IOPMPowerSource *IOPMPowerSource::powerSource(void)
46{
0a7de745 47 IOPMPowerSource *ps = new IOPMPowerSource;
6601e61a 48
0a7de745
A
49 if (ps) {
50 ps->init();
51 return ps;
52 }
53 return NULL;
1c79356b
A
54}
55
0c530ab8
A
56// *****************************************************************************
57// init
1c79356b 58//
0c530ab8 59// *****************************************************************************
0a7de745
A
60bool
61IOPMPowerSource::init(void)
62{
63 if (!super::init()) {
64 return false;
65 }
66
67 nextInList = NULL;
68
69 properties = OSDictionary::withCapacity(10);
70 if (!properties) {
71 return false;
72 }
73 properties->setCapacityIncrement(1);
74
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);
94
95 return true;
1c79356b
A
96}
97
0c530ab8
A
98// *****************************************************************************
99// free
1c79356b 100//
0c530ab8 101// *****************************************************************************
0a7de745
A
102void
103IOPMPowerSource::free(void)
104{
105 if (properties) {
106 properties->release();
107 }
108 if (externalConnectedKey) {
109 externalConnectedKey->release();
110 }
111 if (externalChargeCapableKey) {
112 externalChargeCapableKey->release();
113 }
114 if (batteryInstalledKey) {
115 batteryInstalledKey->release();
116 }
117 if (chargingKey) {
118 chargingKey->release();
119 }
120 if (warnLevelKey) {
121 warnLevelKey->release();
122 }
123 if (criticalLevelKey) {
124 criticalLevelKey->release();
125 }
126 if (currentCapacityKey) {
127 currentCapacityKey->release();
128 }
129 if (maxCapacityKey) {
130 maxCapacityKey->release();
131 }
132 if (timeRemainingKey) {
133 timeRemainingKey->release();
134 }
135 if (amperageKey) {
136 amperageKey->release();
137 }
138 if (voltageKey) {
139 voltageKey->release();
140 }
141 if (cycleCountKey) {
142 cycleCountKey->release();
143 }
144 if (adapterInfoKey) {
145 adapterInfoKey->release();
146 }
147 if (errorConditionKey) {
148 errorConditionKey->release();
149 }
150 if (manufacturerKey) {
151 manufacturerKey->release();
152 }
153 if (modelKey) {
154 modelKey->release();
155 }
156 if (serialKey) {
157 serialKey->release();
158 }
159 if (locationKey) {
160 locationKey->release();
161 }
162 if (batteryInfoKey) {
163 batteryInfoKey->release();
164 }
cb323159
A
165
166 super::free();
1c79356b
A
167}
168
0c530ab8
A
169// *****************************************************************************
170// updateStatus
1c79356b 171//
0c530ab8
A
172// Update power source state in IORegistry and message interested clients
173// notifying them of our change.
174// *****************************************************************************
0a7de745
A
175void
176IOPMPowerSource::updateStatus(void)
1c79356b 177{
0a7de745
A
178 OSCollectionIterator *iterator;
179 OSObject *iteratorKey;
180 OSObject *obj;
0c530ab8 181
0a7de745
A
182 // do nothing if settings haven't changed
183 if (!settingsChangedSinceUpdate) {
184 return;
185 }
2d21ac55 186
0a7de745
A
187 iterator = OSCollectionIterator::withCollection(properties);
188 if (!iterator) {
189 return;
190 }
0c530ab8 191
0a7de745
A
192 while ((iteratorKey = iterator->getNextObject())) {
193 OSSymbol *key;
194
195 key = OSDynamicCast(OSSymbol, iteratorKey);
196 if (!key) {
197 continue;
198 }
199 obj = properties->getObject(key);
200 if (!obj) {
201 continue;
202 }
203 setProperty(key, obj);
204 }
205 iterator->release();
0c530ab8 206
0a7de745 207 settingsChangedSinceUpdate = false;
2d21ac55 208
0a7de745
A
209 // And up goes the flare
210 messageClients(kIOPMMessageBatteryStatusHasChanged);
4452a7af
A
211}
212
0c530ab8
A
213
214/*******************************************************************************
215 *
216 * PROTECTED Accessors. All the setters! Yay!
217 *
218 ******************************************************************************/
0a7de745
A
219
220void
221IOPMPowerSource::setPSProperty(const OSSymbol *key, OSObject *val)
2d21ac55 222{
0a7de745 223 OSObject *lastVal;
2d21ac55 224
0a7de745
A
225 if (!key || !val) {
226 return;
227 }
2d21ac55 228
0a7de745
A
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.
233
234 if ((lastVal = properties->getObject(key))) {
235 if (val->isEqualTo(lastVal)) {
236 // settings didn't change
237 } else {
238 // num val is not equal to last val
239 settingsChangedSinceUpdate = true;
240 }
6d2010ae 241 } else {
0a7de745
A
242 // new setting; no last value
243 settingsChangedSinceUpdate = true;
6d2010ae 244 }
0a7de745
A
245
246 // here's the part where we go crazy.
247 properties->setObject(key, val);
2d21ac55
A
248}
249
250
0a7de745
A
251
252void
253IOPMPowerSource::setExternalConnected(bool b)
254{
255 setPSProperty(externalConnectedKey,
256 b ? kOSBooleanTrue : kOSBooleanFalse);
4452a7af
A
257}
258
0a7de745
A
259void
260IOPMPowerSource::setExternalChargeCapable(bool b)
261{
262 setPSProperty(externalChargeCapableKey,
263 b ? kOSBooleanTrue : kOSBooleanFalse);
4452a7af
A
264}
265
0a7de745
A
266void
267IOPMPowerSource::setBatteryInstalled(bool b)
268{
269 setPSProperty(batteryInstalledKey,
270 b ? kOSBooleanTrue : kOSBooleanFalse);
4452a7af
A
271}
272
0a7de745
A
273void
274IOPMPowerSource::setIsCharging(bool b)
275{
276 setPSProperty(chargingKey,
277 b ? kOSBooleanTrue : kOSBooleanFalse);
4452a7af
A
278}
279
0a7de745
A
280void
281IOPMPowerSource::setAtWarnLevel(bool b)
282{
283 setPSProperty(warnLevelKey,
284 b ? kOSBooleanTrue : kOSBooleanFalse);
4452a7af
A
285}
286
0a7de745
A
287void
288IOPMPowerSource::setAtCriticalLevel(bool b)
289{
290 setPSProperty(criticalLevelKey,
291 b ? kOSBooleanTrue : kOSBooleanFalse);
4452a7af 292}
5d5c5d0d 293
0c530ab8 294
0a7de745
A
295void
296IOPMPowerSource::setCurrentCapacity(unsigned int val)
297{
298 OSNumber *n = OSNumber::withNumber(val, 32);
299 setPSProperty(currentCapacityKey, n);
300 n->release();
89b3af67
A
301}
302
0a7de745
A
303void
304IOPMPowerSource::setMaxCapacity(unsigned int val)
305{
306 OSNumber *n = OSNumber::withNumber(val, 32);
307 setPSProperty(maxCapacityKey, n);
308 n->release();
0c530ab8 309}
89b3af67 310
0a7de745
A
311void
312IOPMPowerSource::setTimeRemaining(int val)
313{
314 OSNumber *n = OSNumber::withNumber(val, 32);
315 setPSProperty(timeRemainingKey, n);
316 n->release();
4452a7af 317}
89b3af67 318
0a7de745
A
319void
320IOPMPowerSource::setAmperage(int val)
321{
322 OSNumber *n = OSNumber::withNumber(val, 32);
323 setPSProperty(amperageKey, n);
324 n->release();
0c530ab8 325}
89b3af67 326
0a7de745
A
327void
328IOPMPowerSource::setVoltage(unsigned int val)
329{
330 OSNumber *n = OSNumber::withNumber(val, 32);
331 setPSProperty(voltageKey, n);
332 n->release();
0c530ab8
A
333}
334
0a7de745
A
335void
336IOPMPowerSource::setCycleCount(unsigned int val)
337{
338 OSNumber *n = OSNumber::withNumber(val, 32);
339 setPSProperty(cycleCountKey, n);
340 n->release();
0c530ab8
A
341}
342
0a7de745
A
343void
344IOPMPowerSource::setAdapterInfo(int val)
345{
346 OSNumber *n = OSNumber::withNumber(val, 32);
347 setPSProperty(adapterInfoKey, n);
348 n->release();
0c530ab8
A
349}
350
0a7de745
A
351void
352IOPMPowerSource::setLocation(int val)
353{
354 OSNumber *n = OSNumber::withNumber(val, 32);
355 setPSProperty(locationKey, n);
356 n->release();
0c530ab8
A
357}
358
0a7de745
A
359void
360IOPMPowerSource::setErrorCondition(OSSymbol *s)
361{
362 setPSProperty(errorConditionKey, s);
0c530ab8
A
363}
364
0a7de745
A
365void
366IOPMPowerSource::setManufacturer(OSSymbol *s)
367{
368 setPSProperty(manufacturerKey, s);
0c530ab8
A
369}
370
0a7de745
A
371void
372IOPMPowerSource::setModel(OSSymbol *s)
373{
374 setPSProperty(modelKey, s);
0c530ab8
A
375}
376
0a7de745
A
377void
378IOPMPowerSource::setSerial(OSSymbol *s)
379{
380 setPSProperty(serialKey, s);
0c530ab8
A
381}
382
0a7de745
A
383void
384IOPMPowerSource::setLegacyIOBatteryInfo(OSDictionary *d)
385{
386 setPSProperty(batteryInfoKey, d);
0c530ab8
A
387}
388
389
390
391
392/*******************************************************************************
393 *
394 * PUBLIC Accessors. All the getters! Boo!
395 *
396 ******************************************************************************/
397
0a7de745
A
398OSObject *
399IOPMPowerSource::getPSProperty(const OSSymbol *symmie)
400{
401 if (!symmie) {
402 return NULL;
403 }
404 return properties->getObject(symmie);
2d21ac55
A
405}
406
0a7de745
A
407bool
408IOPMPowerSource::externalConnected(void)
409{
410 return kOSBooleanTrue == properties->getObject(externalConnectedKey);
0c530ab8
A
411}
412
0a7de745
A
413bool
414IOPMPowerSource::externalChargeCapable(void)
415{
416 return kOSBooleanTrue == properties->getObject(externalChargeCapableKey);
0c530ab8
A
417}
418
0a7de745
A
419bool
420IOPMPowerSource::batteryInstalled(void)
421{
422 return kOSBooleanTrue == properties->getObject(batteryInstalledKey);
0c530ab8
A
423}
424
0a7de745
A
425bool
426IOPMPowerSource::isCharging(void)
427{
428 return kOSBooleanTrue == properties->getObject(chargingKey);
0c530ab8
A
429}
430
0a7de745
A
431bool
432IOPMPowerSource::atWarnLevel(void)
433{
434 return kOSBooleanTrue == properties->getObject(warnLevelKey);
0c530ab8
A
435}
436
0a7de745
A
437bool
438IOPMPowerSource::atCriticalLevel(void)
439{
440 return kOSBooleanTrue == properties->getObject(criticalLevelKey);
0c530ab8
A
441}
442
0a7de745
A
443unsigned int
444IOPMPowerSource::currentCapacity(void)
445{
446 OSNumber *n;
447 n = OSDynamicCast(OSNumber, properties->getObject(currentCapacityKey));
448 if (!n) {
449 return 0;
450 } else {
451 return (unsigned int)n->unsigned32BitValue();
452 }
0c530ab8
A
453}
454
0a7de745
A
455unsigned int
456IOPMPowerSource::maxCapacity(void)
457{
458 OSNumber *n;
459 n = OSDynamicCast(OSNumber, properties->getObject(maxCapacityKey));
460 if (!n) {
461 return 0;
462 } else {
463 return (unsigned int)n->unsigned32BitValue();
464 }
0c530ab8
A
465}
466
0a7de745
A
467unsigned int
468IOPMPowerSource::capacityPercentRemaining(void)
6601e61a 469{
0a7de745
A
470 unsigned int _currentCapacity = currentCapacity();
471 unsigned int _maxCapacity = maxCapacity();
472 if (0 == _maxCapacity) {
473 return 0;
474 } else {
475 return (100 * _currentCapacity) / _maxCapacity;
476 }
0c530ab8 477}
89b3af67 478
0a7de745
A
479int
480IOPMPowerSource::timeRemaining(void)
481{
482 OSNumber *n;
483 n = OSDynamicCast(OSNumber, properties->getObject(timeRemainingKey));
484 if (!n) {
485 return 0;
486 } else {
487 return (int)n->unsigned32BitValue();
488 }
4452a7af
A
489}
490
0a7de745
A
491int
492IOPMPowerSource::amperage(void)
493{
494 OSNumber *n;
495 n = OSDynamicCast(OSNumber, properties->getObject(amperageKey));
496 if (!n) {
497 return 0;
498 } else {
499 return (int)n->unsigned32BitValue();
500 }
0c530ab8 501}
4452a7af 502
0a7de745
A
503unsigned int
504IOPMPowerSource::voltage(void)
505{
506 OSNumber *n;
507 n = OSDynamicCast(OSNumber, properties->getObject(voltageKey));
508 if (!n) {
509 return 0;
510 } else {
511 return (unsigned int)n->unsigned32BitValue();
512 }
0c530ab8 513}
4452a7af 514
0a7de745
A
515unsigned int
516IOPMPowerSource::cycleCount(void)
517{
518 OSNumber *n;
519 n = OSDynamicCast(OSNumber, properties->getObject(cycleCountKey));
520 if (!n) {
521 return 0;
522 } else {
523 return (unsigned int)n->unsigned32BitValue();
524 }
0c530ab8 525}
4452a7af 526
0a7de745
A
527int
528IOPMPowerSource::adapterInfo(void)
529{
530 OSNumber *n;
531 n = OSDynamicCast(OSNumber, properties->getObject(adapterInfoKey));
532 if (!n) {
533 return 0;
534 } else {
535 return (int)n->unsigned32BitValue();
536 }
0c530ab8 537}
4452a7af 538
0a7de745
A
539int
540IOPMPowerSource::location(void)
541{
542 OSNumber *n;
543 n = OSDynamicCast(OSNumber, properties->getObject(locationKey));
544 if (!n) {
545 return 0;
546 } else {
547 return (unsigned int)n->unsigned32BitValue();
548 }
0c530ab8
A
549}
550
0a7de745
A
551OSSymbol *
552IOPMPowerSource::errorCondition(void)
553{
554 return OSDynamicCast(OSSymbol, properties->getObject(errorConditionKey));
0c530ab8
A
555}
556
0a7de745
A
557OSSymbol *
558IOPMPowerSource::manufacturer(void)
559{
560 return OSDynamicCast(OSSymbol, properties->getObject(manufacturerKey));
0c530ab8
A
561}
562
0a7de745
A
563OSSymbol *
564IOPMPowerSource::model(void)
565{
566 return OSDynamicCast(OSSymbol, properties->getObject(modelKey));
0c530ab8
A
567}
568
0a7de745
A
569OSSymbol *
570IOPMPowerSource::serial(void)
571{
572 return OSDynamicCast(OSSymbol, properties->getObject(serialKey));
0c530ab8
A
573}
574
0a7de745
A
575OSDictionary *
576IOPMPowerSource::legacyIOBatteryInfo(void)
577{
578 return OSDynamicCast(OSDictionary, properties->getObject(batteryInfoKey));
0c530ab8 579}