]> git.saurik.com Git - apple/xnu.git/blob - iokit/Kernel/IOPMPowerSource.cpp
xnu-7195.101.1.tar.gz
[apple/xnu.git] / iokit / Kernel / IOPMPowerSource.cpp
1 /*
2 * Copyright (c) 1998-2005 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 #include <IOKit/pwr_mgt/IOPMPowerSource.h>
30 #include <IOKit/pwr_mgt/IOPM.h>
31 #include <IOKit/IOMessage.h>
32 #include <IOKit/IOLib.h>
33
34 #define super IOService
35
36 OSDefineMetaClassAndStructors(IOPMPowerSource, IOService)
37
38 // *****************************************************************************
39 // powerSource
40 //
41 // Static initializer for IOPMPowerSource. Returns a new instance of the class
42 // which the caller must attach to the power plane.
43 // *****************************************************************************
44
45 IOPMPowerSource *IOPMPowerSource::powerSource(void)
46 {
47 IOPMPowerSource *ps = new IOPMPowerSource;
48
49 if (ps) {
50 ps->init();
51 return ps;
52 }
53 return NULL;
54 }
55
56 // *****************************************************************************
57 // init
58 //
59 // *****************************************************************************
60 bool
61 IOPMPowerSource::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;
96 }
97
98 // *****************************************************************************
99 // free
100 //
101 // *****************************************************************************
102 void
103 IOPMPowerSource::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 }
165
166 super::free();
167 }
168
169 // *****************************************************************************
170 // updateStatus
171 //
172 // Update power source state in IORegistry and message interested clients
173 // notifying them of our change.
174 // *****************************************************************************
175 void
176 IOPMPowerSource::updateStatus(void)
177 {
178 OSCollectionIterator *iterator;
179 OSObject *iteratorKey;
180 OSObject *obj;
181
182 // do nothing if settings haven't changed
183 if (!settingsChangedSinceUpdate) {
184 return;
185 }
186
187 iterator = OSCollectionIterator::withCollection(properties);
188 if (!iterator) {
189 return;
190 }
191
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();
206
207 settingsChangedSinceUpdate = false;
208
209 // And up goes the flare
210 messageClients(kIOPMMessageBatteryStatusHasChanged);
211 }
212
213
214 /*******************************************************************************
215 *
216 * PROTECTED Accessors. All the setters! Yay!
217 *
218 ******************************************************************************/
219
220 void
221 IOPMPowerSource::setPSProperty(const OSSymbol *key, OSObject *val)
222 {
223 OSObject *lastVal;
224
225 if (!key || !val) {
226 return;
227 }
228
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 }
241 } else {
242 // new setting; no last value
243 settingsChangedSinceUpdate = true;
244 }
245
246 // here's the part where we go crazy.
247 properties->setObject(key, val);
248 }
249
250
251
252 void
253 IOPMPowerSource::setExternalConnected(bool b)
254 {
255 setPSProperty(externalConnectedKey,
256 b ? kOSBooleanTrue : kOSBooleanFalse);
257 }
258
259 void
260 IOPMPowerSource::setExternalChargeCapable(bool b)
261 {
262 setPSProperty(externalChargeCapableKey,
263 b ? kOSBooleanTrue : kOSBooleanFalse);
264 }
265
266 void
267 IOPMPowerSource::setBatteryInstalled(bool b)
268 {
269 setPSProperty(batteryInstalledKey,
270 b ? kOSBooleanTrue : kOSBooleanFalse);
271 }
272
273 void
274 IOPMPowerSource::setIsCharging(bool b)
275 {
276 setPSProperty(chargingKey,
277 b ? kOSBooleanTrue : kOSBooleanFalse);
278 }
279
280 void
281 IOPMPowerSource::setAtWarnLevel(bool b)
282 {
283 setPSProperty(warnLevelKey,
284 b ? kOSBooleanTrue : kOSBooleanFalse);
285 }
286
287 void
288 IOPMPowerSource::setAtCriticalLevel(bool b)
289 {
290 setPSProperty(criticalLevelKey,
291 b ? kOSBooleanTrue : kOSBooleanFalse);
292 }
293
294
295 void
296 IOPMPowerSource::setCurrentCapacity(unsigned int val)
297 {
298 OSNumber *n = OSNumber::withNumber(val, 32);
299 setPSProperty(currentCapacityKey, n);
300 n->release();
301 }
302
303 void
304 IOPMPowerSource::setMaxCapacity(unsigned int val)
305 {
306 OSNumber *n = OSNumber::withNumber(val, 32);
307 setPSProperty(maxCapacityKey, n);
308 n->release();
309 }
310
311 void
312 IOPMPowerSource::setTimeRemaining(int val)
313 {
314 OSNumber *n = OSNumber::withNumber(val, 32);
315 setPSProperty(timeRemainingKey, n);
316 n->release();
317 }
318
319 void
320 IOPMPowerSource::setAmperage(int val)
321 {
322 OSNumber *n = OSNumber::withNumber(val, 32);
323 setPSProperty(amperageKey, n);
324 n->release();
325 }
326
327 void
328 IOPMPowerSource::setVoltage(unsigned int val)
329 {
330 OSNumber *n = OSNumber::withNumber(val, 32);
331 setPSProperty(voltageKey, n);
332 n->release();
333 }
334
335 void
336 IOPMPowerSource::setCycleCount(unsigned int val)
337 {
338 OSNumber *n = OSNumber::withNumber(val, 32);
339 setPSProperty(cycleCountKey, n);
340 n->release();
341 }
342
343 void
344 IOPMPowerSource::setAdapterInfo(int val)
345 {
346 OSNumber *n = OSNumber::withNumber(val, 32);
347 setPSProperty(adapterInfoKey, n);
348 n->release();
349 }
350
351 void
352 IOPMPowerSource::setLocation(int val)
353 {
354 OSNumber *n = OSNumber::withNumber(val, 32);
355 setPSProperty(locationKey, n);
356 n->release();
357 }
358
359 void
360 IOPMPowerSource::setErrorCondition(OSSymbol *s)
361 {
362 setPSProperty(errorConditionKey, s);
363 }
364
365 void
366 IOPMPowerSource::setManufacturer(OSSymbol *s)
367 {
368 setPSProperty(manufacturerKey, s);
369 }
370
371 void
372 IOPMPowerSource::setModel(OSSymbol *s)
373 {
374 setPSProperty(modelKey, s);
375 }
376
377 void
378 IOPMPowerSource::setSerial(OSSymbol *s)
379 {
380 setPSProperty(serialKey, s);
381 }
382
383 void
384 IOPMPowerSource::setLegacyIOBatteryInfo(OSDictionary *d)
385 {
386 setPSProperty(batteryInfoKey, d);
387 }
388
389
390
391
392 /*******************************************************************************
393 *
394 * PUBLIC Accessors. All the getters! Boo!
395 *
396 ******************************************************************************/
397
398 OSObject *
399 IOPMPowerSource::getPSProperty(const OSSymbol *symmie)
400 {
401 if (!symmie) {
402 return NULL;
403 }
404 return properties->getObject(symmie);
405 }
406
407 bool
408 IOPMPowerSource::externalConnected(void)
409 {
410 return kOSBooleanTrue == properties->getObject(externalConnectedKey);
411 }
412
413 bool
414 IOPMPowerSource::externalChargeCapable(void)
415 {
416 return kOSBooleanTrue == properties->getObject(externalChargeCapableKey);
417 }
418
419 bool
420 IOPMPowerSource::batteryInstalled(void)
421 {
422 return kOSBooleanTrue == properties->getObject(batteryInstalledKey);
423 }
424
425 bool
426 IOPMPowerSource::isCharging(void)
427 {
428 return kOSBooleanTrue == properties->getObject(chargingKey);
429 }
430
431 bool
432 IOPMPowerSource::atWarnLevel(void)
433 {
434 return kOSBooleanTrue == properties->getObject(warnLevelKey);
435 }
436
437 bool
438 IOPMPowerSource::atCriticalLevel(void)
439 {
440 return kOSBooleanTrue == properties->getObject(criticalLevelKey);
441 }
442
443 unsigned int
444 IOPMPowerSource::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 }
453 }
454
455 unsigned int
456 IOPMPowerSource::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 }
465 }
466
467 unsigned int
468 IOPMPowerSource::capacityPercentRemaining(void)
469 {
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 }
477 }
478
479 int
480 IOPMPowerSource::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 }
489 }
490
491 int
492 IOPMPowerSource::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 }
501 }
502
503 unsigned int
504 IOPMPowerSource::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 }
513 }
514
515 unsigned int
516 IOPMPowerSource::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 }
525 }
526
527 int
528 IOPMPowerSource::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 }
537 }
538
539 int
540 IOPMPowerSource::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 }
549 }
550
551 OSSymbol *
552 IOPMPowerSource::errorCondition(void)
553 {
554 return OSDynamicCast(OSSymbol, properties->getObject(errorConditionKey));
555 }
556
557 OSSymbol *
558 IOPMPowerSource::manufacturer(void)
559 {
560 return OSDynamicCast(OSSymbol, properties->getObject(manufacturerKey));
561 }
562
563 OSSymbol *
564 IOPMPowerSource::model(void)
565 {
566 return OSDynamicCast(OSSymbol, properties->getObject(modelKey));
567 }
568
569 OSSymbol *
570 IOPMPowerSource::serial(void)
571 {
572 return OSDynamicCast(OSSymbol, properties->getObject(serialKey));
573 }
574
575 OSDictionary *
576 IOPMPowerSource::legacyIOBatteryInfo(void)
577 {
578 return OSDynamicCast(OSDictionary, properties->getObject(batteryInfoKey));
579 }