blob: 4f3834a59951b8db2d664c71d59aaecd4fe11e4a [file] [log] [blame]
Angel Pons210a0082020-04-02 23:48:24 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Stefan Reinauer7e568552013-03-13 17:03:04 -07002
3// Scope (EC0)
4
5Device (BATX)
6{
7 Name (_HID, EISAID ("PNP0C0A"))
8 Name (_UID, 1)
9 Name (_PCL, Package () { \_SB })
10
11 //
12 // Indicator of BATX attach/detach
13 // Battery X Information
14 // Battery X Status
15 //
16 Name (BXST, Zero)
17
18 //
19 // Default Static Battery Information
20 //
21 Name (PBIF, Package()
22 {
23 0, // 0: Power Unit
24 0xFFFFFFFF, // 1: Design Capacity
25 0xFFFFFFFF, // 2: Last Full Charge Capacity
Martin Roth0949e732021-10-01 14:28:22 -060026 1, // 3: Battery Technology(Rechargeable)
Stefan Reinauer7e568552013-03-13 17:03:04 -070027 10800, // 4: Design Voltage 10.8V
28 0, // 5: Design capacity of warning
29 0, // 6: Design capacity of low
30 1, // 7: Battery capacity granularity 1
31 1, // 8: Battery capacity granularity 2
32 "", // 9: Model Number
33 "", // 10: Serial Number
34 "", // 11: Battery Type
35 "" // 12: OEM Infomration
36 })
37
38 Name (PBST, Package ()
39 {
40 0x00000000, // Battery State
41 0xFFFFFFFF, // Battery Present Rate
42 0xFFFFFFFF, // Battery Remaining Capacity
43 0xFFFFFFFF, // Battery Present Voltage
44 })
45
46 // Workaround for full battery status, enabled by default
Felix Singerca4b5872022-12-26 08:17:06 +010047 Name (BFWK, 1)
Stefan Reinauer7e568552013-03-13 17:03:04 -070048
49 // Method to enable full battery workaround
50 Method (BFWE)
51 {
Felix Singerca4b5872022-12-26 08:17:06 +010052 BFWK = 1
Stefan Reinauer7e568552013-03-13 17:03:04 -070053 }
54
55 // Method to disable full battery workaround
56 Method (BFWD)
57 {
Felix Singer612801d2022-12-12 04:56:53 +010058 BFWK = Zero
Stefan Reinauer7e568552013-03-13 17:03:04 -070059 }
60
61 // Method to wait for EC to be ready after changing the Battery Info ID
62 // Selector
63 Method (WAEC)
64 {
Felix Singer612801d2022-12-12 04:56:53 +010065 Local0 = 20 // Timeout 100 msec
Felix Singer1e965542022-01-02 01:04:39 +010066 While (HSID == 0)
Stefan Reinauer7e568552013-03-13 17:03:04 -070067 {
68 // EC Is not ready
69 Sleep (5)
Felix Singerd4a91aa2021-12-31 14:17:57 +010070 Local0--
Felix Singer1e965542022-01-02 01:04:39 +010071 If (Local0 == 0)
Stefan Reinauer7e568552013-03-13 17:03:04 -070072 {
73 Break
74 }
75 }
76 }
77
78 // Battery Slot Status
79 Method (_STA, 0, Serialized)
80 {
Felix Singer612801d2022-12-12 04:56:53 +010081 BXST = MBTS
Stefan Reinauer7e568552013-03-13 17:03:04 -070082 If (BXST)
83 {
84 // Battery is present
85 Return (0x1F)
86 }
87 Else
88 {
89 Return (0x0F)
90 }
91 }
92
93 Method (_BIF, 0, Serialized)
94 {
95 // Update fields from EC
96
97 //
98 // Information ID 1 -
99 //
Felix Singerca4b5872022-12-26 08:17:06 +0100100 HIID = 1
Stefan Reinauer7e568552013-03-13 17:03:04 -0700101 WAEC ()
102
103 //
104 // Power Unit
105 // SMART battery : 1 - 10mWh : 0 - mAh
106 // ACPI spec : 0 - mWh : 1 - mAh
107 //
Felix Singer612801d2022-12-12 04:56:53 +0100108 Local7 = SBCM
Felix Singerca4b5872022-12-26 08:17:06 +0100109 PBIF[0] = Local7 ^ 1
Stefan Reinauer7e568552013-03-13 17:03:04 -0700110
111 //
112 // Information ID 0 -
113 //
Felix Singer612801d2022-12-12 04:56:53 +0100114 HIID = Zero
Stefan Reinauer7e568552013-03-13 17:03:04 -0700115 WAEC ()
116
117 //
118 // Last Full Charge Capacity
119 //
120 If (Local7)
121 {
Felix Singerf1f861e2022-01-01 23:41:10 +0100122 PBIF[2] = SBFC * 10
Stefan Reinauer7e568552013-03-13 17:03:04 -0700123 }
124 Else
125 {
Felix Singer612801d2022-12-12 04:56:53 +0100126 PBIF[2] = SBFC
Stefan Reinauer7e568552013-03-13 17:03:04 -0700127 }
128
129 //
130 // Information ID 2 -
131 //
Felix Singer612801d2022-12-12 04:56:53 +0100132 HIID = 2
Stefan Reinauer7e568552013-03-13 17:03:04 -0700133 WAEC ()
134
135 //
136 // Design capacity
137 //
138 If (Local7)
139 {
Felix Singerf1f861e2022-01-01 23:41:10 +0100140 Local0 = SBDC * 10
Stefan Reinauer7e568552013-03-13 17:03:04 -0700141 }
142 Else
143 {
Felix Singer612801d2022-12-12 04:56:53 +0100144 Local0 = SBDC
Stefan Reinauer7e568552013-03-13 17:03:04 -0700145 }
Felix Singer612801d2022-12-12 04:56:53 +0100146 PBIF[1] = Local0
Stefan Reinauer7e568552013-03-13 17:03:04 -0700147
148 //
149 // Design capacity of High (5%)
150 // Design capacity of Low (1%)
151 //
Felix Singer3f53ee32022-01-02 00:02:13 +0100152 PBIF[5] = Local0 / 20
153 PBIF[6] = Local0 / 100
Stefan Reinauer7e568552013-03-13 17:03:04 -0700154
155 //
156 // Design voltage
157 //
Felix Singer612801d2022-12-12 04:56:53 +0100158 PBIF[4] = SBDV
Stefan Reinauer7e568552013-03-13 17:03:04 -0700159
160 //
161 // Serial Number
162 //
Felix Singer612801d2022-12-12 04:56:53 +0100163 PBIF[10] = ToHexString (SBSN)
Stefan Reinauer7e568552013-03-13 17:03:04 -0700164
165 //
166 // Information ID 4 -
167 //
Felix Singer612801d2022-12-12 04:56:53 +0100168 HIID = 4
Stefan Reinauer7e568552013-03-13 17:03:04 -0700169 WAEC ()
170
171 //
172 // Battery Type - Device Chemistry
173 //
Felix Singer612801d2022-12-12 04:56:53 +0100174 PBIF[11] = ToString (Concatenate(SBCH, 0x00))
Stefan Reinauer7e568552013-03-13 17:03:04 -0700175
176 //
177 // Information ID 5 -
178 //
Felix Singer612801d2022-12-12 04:56:53 +0100179 HIID = 5
Stefan Reinauer7e568552013-03-13 17:03:04 -0700180 WAEC ()
181
182 //
183 // OEM Information - Manufacturer Name
184 //
Felix Singer612801d2022-12-12 04:56:53 +0100185 PBIF[12] = ToString (Concatenate(SBMN, 0x00))
Stefan Reinauer7e568552013-03-13 17:03:04 -0700186
187 //
188 // Information ID 6 -
189 //
Felix Singer612801d2022-12-12 04:56:53 +0100190 HIID = 6
Stefan Reinauer7e568552013-03-13 17:03:04 -0700191 WAEC ()
192
193 //
194 // Model Number - Device Name
195 //
Felix Singer612801d2022-12-12 04:56:53 +0100196 PBIF[9] = ToString (Concatenate(SBDN, 0x00))
Stefan Reinauer7e568552013-03-13 17:03:04 -0700197
198 Return (PBIF)
199 }
200
201 Method (_BST, 0, Serialized)
202 {
203 // Update Battery First Used Date, if requested
204 If (BFUD)
205 {
206 // TODO: Handle First Used Date Request
207 //\BFUD()
208 }
209
210 //
211 // 0: BATTERY STATE
212 //
213 // bit 0 = discharging
214 // bit 1 = charging
215 // bit 2 = critical level
216 //
217
218 // Get battery state from EC
Felix Singerd2527762022-12-16 07:54:16 +0100219 If (HB0S & 0x20)
Stefan Reinauer7e568552013-03-13 17:03:04 -0700220 {
Felix Singer612801d2022-12-12 04:56:53 +0100221 Local0 = 2
Stefan Reinauer7e568552013-03-13 17:03:04 -0700222 }
223 Else
224 {
Felix Singerd2527762022-12-16 07:54:16 +0100225 if (HB0S & 0x40)
Stefan Reinauer7e568552013-03-13 17:03:04 -0700226 {
Felix Singerca4b5872022-12-26 08:17:06 +0100227 Local0 = 1
Stefan Reinauer7e568552013-03-13 17:03:04 -0700228 }
229 Else
230 {
Felix Singer612801d2022-12-12 04:56:53 +0100231 Local0 = Zero
Stefan Reinauer7e568552013-03-13 17:03:04 -0700232 }
233 }
234
235 // Set critical flag if battery is empty
Felix Singerd2527762022-12-16 07:54:16 +0100236 If (HB0S & 0x0F == 0)
Stefan Reinauer7e568552013-03-13 17:03:04 -0700237 {
Felix Singer86bc2e72022-12-16 04:40:39 +0100238 Local0 |= 4
Stefan Reinauer7e568552013-03-13 17:03:04 -0700239 }
240
Felix Singer612801d2022-12-12 04:56:53 +0100241 Local1 = Zero
Stefan Reinauer7e568552013-03-13 17:03:04 -0700242
243 // Check if AC is present
244 If (ACPW)
245 {
246 // Set only charging/discharging bits
Felix Singer35e65a82022-12-16 07:11:17 +0100247 Local1 = Local0 & 3
Stefan Reinauer7e568552013-03-13 17:03:04 -0700248 }
249 Else
250 {
251 // Always discharging when on battery power
Felix Singerca4b5872022-12-26 08:17:06 +0100252 Local1 = 1
Stefan Reinauer7e568552013-03-13 17:03:04 -0700253 }
254
255 // Flag if the battery level is critical
Felix Singer35e65a82022-12-16 07:11:17 +0100256 Local4 = Local0 & 4
Felix Singer86bc2e72022-12-16 04:40:39 +0100257 Local1 |= Local4
Felix Singer612801d2022-12-12 04:56:53 +0100258 PBST[0] = Local1
Stefan Reinauer7e568552013-03-13 17:03:04 -0700259
260 //
261 // 1: BATTERY PRESENT RATE/CURRENT
262 //
Felix Singer612801d2022-12-12 04:56:53 +0100263 Local1 = ECAC
Felix Singerd40d0b02022-01-02 02:20:50 +0100264 If (Local1 >= 0x8000)
Stefan Reinauer7e568552013-03-13 17:03:04 -0700265 {
Felix Singerd2527762022-12-16 07:54:16 +0100266 If (Local0 & 1)
Stefan Reinauer7e568552013-03-13 17:03:04 -0700267 {
Felix Singerf00caca2021-12-30 01:09:03 +0100268 Local1 = 0x10000 - Local1
Stefan Reinauer7e568552013-03-13 17:03:04 -0700269 }
270 Else
271 {
272 // Error
Felix Singer612801d2022-12-12 04:56:53 +0100273 Local1 = Zero
Stefan Reinauer7e568552013-03-13 17:03:04 -0700274 }
275 }
276 Else
277 {
Felix Singerd2527762022-12-16 07:54:16 +0100278 If (!(Local0 & 2))
Stefan Reinauer7e568552013-03-13 17:03:04 -0700279 {
280 // Battery is not charging
Felix Singer612801d2022-12-12 04:56:53 +0100281 Local1 = Zero
Stefan Reinauer7e568552013-03-13 17:03:04 -0700282 }
283 }
284
Felix Singerca4b5872022-12-26 08:17:06 +0100285 Local6 = DerefOf (PBIF[0]) ^ 1
Stefan Reinauer7e568552013-03-13 17:03:04 -0700286
287 If (Local6)
288 {
Felix Singerf1f861e2022-01-01 23:41:10 +0100289 Local1 *= ECVO
Felix Singer3f53ee32022-01-02 00:02:13 +0100290 Local1 /= 1000
Stefan Reinauer7e568552013-03-13 17:03:04 -0700291 }
Felix Singer612801d2022-12-12 04:56:53 +0100292 PBST[1] = Local1
Stefan Reinauer7e568552013-03-13 17:03:04 -0700293
294 //
295 // 2: BATTERY REMAINING CAPACITY
296 //
297 // Get Power unit from the battery static information
298 // SMART battery : 1 - 10mWh : 0 - mAh
299 // ACPI spec : 0 - mWh : 1 - mAh
300 If (Local6)
301 {
Felix Singerf1f861e2022-01-01 23:41:10 +0100302 Local1 = ECRC * 10
Stefan Reinauer7e568552013-03-13 17:03:04 -0700303 }
304 Else
305 {
Felix Singer612801d2022-12-12 04:56:53 +0100306 Local1 = ECRC
Stefan Reinauer7e568552013-03-13 17:03:04 -0700307 }
308
Felix Singerecc63d92021-12-31 14:34:36 +0100309 If (BFWK && ACPW && !Local0)
Stefan Reinauer7e568552013-03-13 17:03:04 -0700310 {
311 // On AC power and battery is neither charging
312 // nor discharging. Linux expects a full battery
313 // to report same capacity as last full charge.
314 // https://bugzilla.kernel.org/show_bug.cgi?id=12632
315 // TODO: Is SBRS the "battery gas gauge"?
Felix Singer612801d2022-12-12 04:56:53 +0100316 Local2 = SBRS
Stefan Reinauer7e568552013-03-13 17:03:04 -0700317
318 // See if within ~3% of full
Felix Singer034920c2022-12-16 02:25:30 +0100319 Local3 = Local2 >> 5
Felix Singer0375b822022-01-02 01:58:55 +0100320 If (Local1 > Local2 - Local3 && Local1 < Local2 + Local3)
Stefan Reinauer7e568552013-03-13 17:03:04 -0700321 {
Felix Singer612801d2022-12-12 04:56:53 +0100322 Local1 = Local2
Stefan Reinauer7e568552013-03-13 17:03:04 -0700323 }
324 }
Felix Singer612801d2022-12-12 04:56:53 +0100325 PBST[2] = Local1
Stefan Reinauer7e568552013-03-13 17:03:04 -0700326
327 //
328 // 3: BATTERY PRESENT VOLTAGE
329 //
Felix Singer612801d2022-12-12 04:56:53 +0100330 PBST[3] = ECVO
Stefan Reinauer7e568552013-03-13 17:03:04 -0700331
332 Return (PBST)
333 }
334}