• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* SPDX-License-Identifier: GPL-2.0-only */
2
3/*
4 * The mainboard must define strings in the root scope to
5 * report device-specific battery information to the OS.
6 *
7 *  BATM: Model
8 *  BATS: Serial
9 *  BATV: Vendor
10 */
11
12// Scope (EC0)
13
14Device (BAT0)
15{
16	Name (_HID, EISAID ("PNP0C0A"))
17	Name (_UID, 1)
18	Name (_PCL, Package () { \_SB })
19
20	Name (PBIF, Package () {
21		0x00000001,  // Power Unit: mAh
22		0xFFFFFFFF,  // Design Capacity
23		0xFFFFFFFF,  // Last Full Charge Capacity
24		0x00000001,  // Battery Technology: Rechargeable
25		0xFFFFFFFF,  // Design Voltage
26		0x00000003,  // Design Capacity of Warning
27		0xFFFFFFFF,  // Design Capacity of Low
28		0x00000001,  // Capacity Granularity 1
29		0x00000001,  // Capacity Granularity 2
30		"",          // Model Number
31		"",          // Serial Number
32		"LION",      // Battery Type
33		""           // OEM Information
34	})
35
36	Name (PBST, Package () {
37		0x00000000,  // Battery State
38		0xFFFFFFFF,  // Battery Present Rate
39		0xFFFFFFFF,  // Battery Remaining Capacity
40		0xFFFFFFFF,  // Battery Present Voltage
41	})
42	Name (BSTP, 0)
43
44	// Workaround for full battery status, enabled by default
45	Name (BFWK, 1)
46
47	// Method to enable full battery workaround
48	Method (BFWE)
49	{
50		BFWK = 1
51	}
52
53	// Method to disable full battery workaround
54	Method (BFWD)
55	{
56		BFWK = 0
57	}
58
59	// Swap bytes in a word
60	Method (SWAB, 1, NotSerialized)
61	{
62		Local0 = Arg0 >> 8
63		Local1 = Arg0 << 8
64		Local1 &= 0xFF00
65		Local0 |= Local1
66		If (Local0 == 0xFFFF) {
67			Local0 = 0xFFFFFFFF
68		}
69		Return (Local0)
70	}
71
72	Method (_STA, 0, Serialized)
73	{
74		If (BTEX) {
75			Return (0x1F)
76		} Else {
77			Return (0x0F)
78		}
79	}
80
81	Method (_BIF, 0, Serialized)
82	{
83		// Update fields from EC
84		PBIF[1] = SWAB (BTDA)
85		PBIF[2] = SWAB (BTDF)
86		PBIF[4] = SWAB (BTDV)
87		PBIF[6] = SWAB (BTDL)
88
89		// Get battery info from mainboard
90		PBIF[9] = \BATM
91		PBIF[10] = \BATS
92		PBIF[12] = \BATV
93
94		Return (PBIF)
95	}
96
97	Method (_BST, 0, Serialized)
98	{
99		//
100		// 0: BATTERY STATE
101		//
102		// bit 0 = discharging
103		// bit 1 = charging
104		// bit 2 = critical level
105		//
106
107		// Get battery state from EC
108		Local0 = BTST
109		Local1 = 0
110
111		// Check if AC is present
112		If (ACEX) {
113			// Set only charging/discharging bits
114			Local1 = Local0 & 3
115		} Else {
116			// Always discharging when on battery power
117			Local1 = 0x01
118		}
119
120		// Flag if the battery level is critical
121		Local4 = Local0 & 4
122		Local1 |= Local4
123		PBST[0] = Local1
124
125		// Notify if battery state has changed since last time
126		If (Local1 != BSTP) {
127			BSTP = Local1
128			Notify (BAT0, 0x80)
129		}
130
131		//
132		// 1: BATTERY PRESENT RATE
133		//
134
135		Local1 = SWAB (BTPR)
136		If (Local1 != 0xFFFFFFFF && Local1 >= 0x8000) {
137			Local1 ^= 0xFFFF
138			Local1++
139		}
140		PBST[1] = Local1
141
142		//
143		// 2: BATTERY REMAINING CAPACITY
144		//
145		Local1 = SWAB (BTRA)
146		If (Local1 != 0xFFFFFFFF && Local1 >= 0x8000) {
147			Local1 ^= 0xFFFF
148			Local1++
149		}
150
151		If (BFWK && ACEX && !Local0) {
152			// On AC power and battery is neither charging
153			// nor discharging.  Linux expects a full battery
154			// to report same capacity as last full charge.
155			// https://bugzilla.kernel.org/show_bug.cgi?id=12632
156			Local2 = SWAB (BTDF)
157
158			// See if within ~3% of full
159			Local3 = Local2 >> 5
160			If (Local1 > Local2 - Local3 && Local1 < Local2 + Local3)
161			{
162				Local1 = Local2
163			}
164		}
165		PBST[2] = Local1
166
167		//
168		// 3: BATTERY PRESENT VOLTAGE
169		//
170		PBST[3] = SWAB (BTVO)
171
172		Return (PBST)
173	}
174}
175