1 /*
2  * Copyright (c) 1998-2019 Apple 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 #ifndef _IOPMPowerSource_h_
30 #define _IOPMPowerSource_h_
31 
32 #include <libkern/c++/OSObject.h>
33 #include <IOKit/pwr_mgt/IOPM.h>
34 #include <IOKit/IOTypes.h>
35 #include <IOKit/IOReturn.h>
36 #include <IOKit/IOService.h>
37 
38 enum {
39 	kSecondsPerHour = 3600,
40 	kTenMinutesInSeconds = 600
41 };
42 
43 
44 /*! @class IOPMPowerSource
45  *
46  * See IOKit/pwr_mgt/IOPM.h for power source keys relevant to this class. These
47  * report-type keys are required for calls to IOPMPowerSource::setReportables(),
48  * and they define the IORegistry interface through which data is passed back
49  * up to the rest of the system.
50  *
51  * A subclassing driver that doesn't want to do anything fancy should:
52  *   1. Subclass IOPMPowerSource
53  *   2. Install its own battery change notifications or polling routine that can
54  *          converse with actual battery hardware.
55  *   3. When battery state changes, change the relevant member variables
56  *          through setCurrentCapacity() style accessors.
57  *   4. Call updateStatus() on itself when all such settings have been updated.
58  *
59  * The subclass driver should also initially populate its settings and call
60  * updateStatus() on launch.
61  *
62  *
63  * Settings:
64  *
65  * <pre>
66  * ExternalConnected
67  * Type: bool
68  * IORegistry Key: kIOPMPSExternalConnectedKey
69  * True if computer is drawing external power
70  *
71  * ExternalChargeCapable
72  * Type: bool
73  * IORegistry Key: kIOPMPSExternalChargeCapableKey
74  * True if external power is capable of charging internal battery
75  *
76  * BatteryInstalled
77  * Type: bool
78  * IORegistry Key: kIOPMPSBatteryInstalledKey
79  * True if a battery is present; false if removed
80  *
81  * IsCharging
82  * Type: bool
83  * IORegistry Key: kIOPMPSIsChargingKey
84  * True if battery is charging itself from external power
85  *
86  * AtWarnLevel
87  * Type: bool
88  * IORegistry Key: kIOPMPSAtWarnLevelKey
89  * True if draining battery capacity and past warn level
90  *
91  * AtCriticalLevel
92  * Type: bool
93  * IORegistry Key: kIOPMPSAtCriticalLevelKey
94  * True if draining battery capacity and past critical level
95  *
96  * CurrentCapacity
97  * MaxCapacity
98  * Type: unsigned int
99  * IORegistry Key: kIOPMPSCurrentCapacityKey, kIOPMPSMaxCapacityKey
100  * Capacity measured in mAh
101  *
102  * TimeRemaining
103  * Type: int
104  * IORegistry Key: kIOPMPSTimeRemainingKey
105  * Time remaining measured in minutes
106  *
107  * Amperage
108  * Type: int
109  * IORegistry Key: kIOPMPSAmperageKey
110  * Current is measured in mA
111  *
112  * Voltage
113  * Type: unsigned int
114  * IORegistry Key: kIOPMPSVoltageKey
115  * Voltage measured in mV
116  *
117  * CycleCount
118  * Type: unsigned int
119  * IORegistry Key: kIOPMPSCycleCountKey
120  * Number of charge/discharge cycles
121  *
122  * AdapterInfo
123  * Type: int
124  * IORegistry Key: kIOPMPSAdapterInfoKey
125  * Power adapter information
126  *
127  * Location
128  * Type: int
129  * IORegistry Key: kIOPMPSLocationKey
130  * Clue about battery's location in machine - Left vs. Right
131  *
132  * ErrorCondition
133  * Type: OSSymbol
134  * IORegistry Key: kIOPMPSErrorConditionKey
135  * String describing error state of battery
136  *
137  * Manufacturer
138  * Type: OSSymbol
139  * IORegistry Key: kIOPMPSManufacturerKey
140  * String describing battery manufacturer
141  *
142  * Manufactured Date
143  * Type: unsigned 16-bit bitfield
144  * IORegistry Key: kIOPMPSManufactureDateKey
145  * Date is published in a bitfield per the Smart Battery Data spec rev 1.1
146  * in section 5.1.26
147  *   Bits 0...4 => day (value 1-31; 5 bits)
148  *   Bits 5...8 => month (value 1-12; 4 bits)
149  *   Bits 9...15 => years since 1980 (value 0-127; 7 bits)
150  *
151  * Model
152  * Type: OSSymbol
153  * IORegistry Key: kIOPMPSModelKey
154  * String describing model number
155  *
156  * Serial
157  * Type: OSSymbol
158  * IORegistry Key: kIOPMPSSerialKey
159  * String describing serial number or unique info
160  * The serial number published hear bears no correspondence to the Apple serial
161  * number printed on each battery. This is a manufacturer serial number with
162  * no correlation to the printed serial number.
163  *
164  * LegacyIOBatteryInfo
165  * Type: OSDictionary
166  * IORegistry Key: kIOPMPSLegacyBatteryInfoKey
167  * Dictionary conforming to the OS X 10.0-10.4
168  * </pre>
169  */
170 
171 class IOPMPowerSource : public IOService
172 {
173 	OSDeclareDefaultStructors(IOPMPowerSource);
174 
175 	friend class IOPMPowerSourceList;
176 
177 protected:
178 
179 /*! @var settingsChangedSinceLastUpdate
180  * Used by subclasses to determine if any settings have been modified via the
181  * accessors below since last call to update(). true is settings have changed;
182  * false otherwise.
183  */
184 	bool settingsChangedSinceUpdate;
185 
186 /*! @var properties
187  * Stores power source state
188  */
189 	OSDictionary            *properties;
190 
191 	const OSSymbol *externalConnectedKey;
192 	const OSSymbol *externalChargeCapableKey;
193 	const OSSymbol *batteryInstalledKey;
194 	const OSSymbol *chargingKey;
195 	const OSSymbol *warnLevelKey;
196 	const OSSymbol *criticalLevelKey;
197 	const OSSymbol *currentCapacityKey;
198 	const OSSymbol *maxCapacityKey;
199 	const OSSymbol *timeRemainingKey;
200 	const OSSymbol *amperageKey;
201 	const OSSymbol *voltageKey;
202 	const OSSymbol *cycleCountKey;
203 	const OSSymbol *adapterInfoKey;
204 	const OSSymbol *locationKey;
205 	const OSSymbol *errorConditionKey;
206 	const OSSymbol *manufacturerKey;
207 	const OSSymbol *modelKey;
208 	const OSSymbol *serialKey;
209 	const OSSymbol *batteryInfoKey;
210 
211 // Tracking for IOPMPowerSourceList
212 	IOPMPowerSource         *nextInList;
213 
214 public:
215 
216 /*! @function powerSource
217  *   @abstract Creates a new IOPMPowerSource nub. Must be attached to IORegistry,
218  *       and registered by provider.
219  */
220 	static IOPMPowerSource *powerSource(void);
221 
222 	virtual bool init(void) APPLE_KEXT_OVERRIDE;
223 
224 	virtual void free(void) APPLE_KEXT_OVERRIDE;
225 
226 /*! @function updateStatus
227  *   @abstract Must be called by physical battery controller when battery state
228  *               has changed significantly.
229  *   @discussion The system will not poll this object for battery updates. Rather \
230  *   the battery's controller must call updateStatus() every time state changes \
231  *   and the settings will be relayed to higher levels of power management. \
232  *   The subclassing driver should override this only if the driver needs to add \
233  *   new settings to the base class.
234  */
235 	virtual void updateStatus(void);
236 
237 /* Public accessors for battery state
238  */
239 	bool externalConnected(void);
240 	bool externalChargeCapable(void);
241 	bool batteryInstalled(void);
242 	bool isCharging(void);
243 	bool atWarnLevel(void);
244 	bool atCriticalLevel(void);
245 
246 	unsigned int currentCapacity(void);
247 	unsigned int maxCapacity(void);
248 	unsigned int capacityPercentRemaining(void);
249 	int timeRemaining(void);
250 	int amperage(void);
251 	unsigned int voltage(void);
252 	unsigned int cycleCount(void);
253 	int adapterInfo(void);
254 	int location(void);
255 
256 	OSSymbol *errorCondition(void);
257 	OSSymbol *manufacturer(void);
258 	OSSymbol *model(void);
259 	OSSymbol *serial(void);
260 	OSDictionary *legacyIOBatteryInfo(void);
261 
262 	OSObject *getPSProperty(const OSSymbol *);
263 
264 protected:
265 
266 /* Protected "setter" methods for subclasses
267  * Subclasses should use these setters to modify all battery properties.
268  *
269  * Subclasses must follow all property changes with a call to updateStatus()
270  * to flush settings changes to upper level battery API clients.
271  *
272  */
273 	void setExternalConnected(bool);
274 	void setExternalChargeCapable(bool);
275 	void setBatteryInstalled(bool);
276 	void setIsCharging(bool);
277 	void setAtWarnLevel(bool);
278 	void setAtCriticalLevel(bool);
279 
280 	void setCurrentCapacity(unsigned int);
281 	void setMaxCapacity(unsigned int);
282 	void setTimeRemaining(int);
283 	void setAmperage(int);
284 	void setVoltage(unsigned int);
285 	void setCycleCount(unsigned int);
286 	void setAdapterInfo(int);
287 	void setLocation(int);
288 
289 	void setErrorCondition(OSSymbol *);
290 	void setManufacturer(OSSymbol *);
291 	void setModel(OSSymbol *);
292 	void setSerial(OSSymbol *);
293 	void setLegacyIOBatteryInfo(OSDictionary *);
294 
295 /*! All of these methods funnel through the generic accessor method
296  *  setPSProperty. Caller can pass in any arbitrary OSSymbol key, and
297  *  that value will be stored in the PM settings dictionary, and relayed
298  *  onto the IORegistry at update time.
299  */
300 	void setPSProperty(const OSSymbol *, OSObject *);
301 };
302 
303 #endif
304