battery.asl 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. /** @file
  2. Copyright (c) 2021, Baruch Binyamin Doron
  3. SPDX-License-Identifier: BSD-2-Clause-Patent
  4. **/
  5. #ifndef LGMR_ENABLED
  6. // TODO: Consider actually enforcing mutex?
  7. Mutex (BMTX, 0)
  8. #endif
  9. Name (B0ST, 0) /* Battery 0 status */
  10. /*
  11. * EC Registers
  12. *
  13. * "EBID" is the battery page selector.
  14. *
  15. *
  16. * Data on the 128 bits following offset
  17. * 0xE0 is accessed in the following order:
  18. *
  19. * Information:
  20. * Page 0: EBCM # start on page 0 #
  21. * Page 0: EBFC
  22. * Page 1: EBDC # switch to page 1 #
  23. * Page 1: EBDV
  24. * Page 1: EBSN
  25. * Page 3: EBDN # switch to page 3 #
  26. * Page 4: EBCH # switch to page 4 #
  27. * Page 2: EBMN # switch to page 2 #
  28. *
  29. * Status:
  30. * Page 0: EBAC # start on page 0 #
  31. * Page 0: EBRC
  32. * Page 0: EBFC
  33. * Page 0: EBVO
  34. */
  35. /* Page 0 */
  36. Field (RAM, ByteAcc, Lock, Preserve)
  37. {
  38. Offset (0xE0),
  39. EBRC, 16, /* Battery remaining capacity */
  40. EBFC, 16, /* Battery full charge capacity */
  41. EBPE, 16,
  42. EBAC, 16, /* Battery present rate */
  43. EBVO, 16, /* Battery voltage */
  44. , 15,
  45. EBCM, 1, /* Battery charging */
  46. EBCU, 16,
  47. EBTV, 16,
  48. }
  49. /* Page 1 */
  50. Field (RAM, ByteAcc, Lock, Preserve)
  51. {
  52. Offset (0xE0),
  53. EBDC, 16, /* Battery design capacity */
  54. EBDV, 16, /* Battery design voltage */
  55. EBSN, 16, /* Battery serial number */
  56. }
  57. /* Page 2 */
  58. Field (RAM, ByteAcc, NoLock, Preserve)
  59. {
  60. Offset (0xE0),
  61. EBMN, 128, /* Battery manufacturer */
  62. }
  63. /* Page 3 */
  64. Field (RAM, ByteAcc, NoLock, Preserve)
  65. {
  66. Offset (0xE0),
  67. EBDN, 128, /* Battery model */
  68. }
  69. /* Page 4 */
  70. Field (RAM, ByteAcc, NoLock, Preserve)
  71. {
  72. Offset (0xE0),
  73. EBCH, 128, /* Battery type */
  74. }
  75. #ifdef LGMR_ENABLED
  76. OperationRegion (MBB0, SystemMemory, (LGMR + 0x80), 0xFF)
  77. Field (MBB0, ByteAcc, Lock, Preserve)
  78. {
  79. MBRC, 16,
  80. MBFC, 16,
  81. MBPE, 16,
  82. MBAC, 16,
  83. MBVO, 16,
  84. , 15,
  85. MBCM, 1,
  86. MBCU, 16,
  87. MBTV, 16,
  88. }
  89. Field (MBB0, ByteAcc, Lock, Preserve)
  90. {
  91. Offset (0x10),
  92. MBDC, 16,
  93. MBDV, 16,
  94. MBSN, 16,
  95. }
  96. Field (MBB0, ByteAcc, Lock, Preserve)
  97. {
  98. Offset (0x40),
  99. MBMN, 128,
  100. }
  101. Field (MBB0, ByteAcc, Lock, Preserve)
  102. {
  103. Offset (0x50),
  104. MBDN, 256,
  105. }
  106. Field (MBB0, ByteAcc, Lock, Preserve)
  107. {
  108. Offset (0x70),
  109. MBCH, 128,
  110. }
  111. #endif
  112. /*
  113. * Arg0: Battery number
  114. * Arg1: Battery Information Package
  115. * Arg2: Status
  116. */
  117. #ifndef LGMR_ENABLED
  118. Method (GBIF, 3, Serialized)
  119. {
  120. Acquire (BMTX, 0xFFFF) // Due to EC paging, don't run this with another function
  121. #else
  122. Method (GBIF, 3, NotSerialized)
  123. {
  124. #endif
  125. If (Arg2)
  126. {
  127. Arg1[1] = 0xFFFFFFFF
  128. Arg1[2] = 0xFFFFFFFF
  129. Arg1[4] = 0xFFFFFFFF
  130. Arg1[5] = 0
  131. Arg1[6] = 0
  132. }
  133. Else
  134. {
  135. #ifdef LGMR_ENABLED
  136. Local0 = MBCM
  137. #else
  138. EBID = 0 // We don't know which page was active
  139. Local0 = EBCM
  140. #endif
  141. Arg1[0] = (Local0 ^ 1)
  142. #ifdef LGMR_ENABLED
  143. Local2 = MBFC
  144. Local1 = MBDC
  145. #else
  146. Local2 = EBFC
  147. EBID = 1
  148. Local1 = EBDC
  149. #endif
  150. If (Local0)
  151. {
  152. Local2 *= 10
  153. Local1 *= 10
  154. }
  155. Arg1[1] = Local1 // Design capacity
  156. Arg1[2] = Local2 // Last full charge capacity
  157. #ifdef LGMR_ENABLED
  158. Arg1[4] = MBDV // Design voltage
  159. #else
  160. Arg1[4] = EBDV // Design voltage
  161. #endif
  162. Local6 = (Local2 / 100) // Warning capacities; Remainders ignored
  163. Arg1[5] = (Local6 * 7) /* Low: 7% */
  164. Arg1[6] = ((Local6 * 11) / 2) /* Very low: 5.5% */
  165. #ifdef LGMR_ENABLED
  166. Local7 = MBSN
  167. #else
  168. Local7 = EBSN
  169. #endif
  170. Name (SERN, Buffer (0x06) { " " })
  171. Local6 = 4
  172. While (Local7)
  173. {
  174. Divide (Local7, 10, Local5, Local7)
  175. SERN[Local6] = (Local5 + 0x30) // Add ASCII 0x30 to get character
  176. Local6--
  177. }
  178. Arg1[10] = SERN // Serial number
  179. #ifdef LGMR_ENABLED
  180. Arg1[9] = MBDN // Model number
  181. Arg1[11] = MBCH // Battery type
  182. Arg1[12] = MBMN // OEM information
  183. #else
  184. EBID = 3
  185. Arg1[9] = EBDN // Model number
  186. EBID = 4
  187. Arg1[11] = EBCH // Battery type
  188. EBID = 2
  189. Arg1[12] = EBMN // OEM information
  190. #endif
  191. }
  192. #ifndef LGMR_ENABLED
  193. Release (BMTX)
  194. #endif
  195. Return (Arg1)
  196. }
  197. /*
  198. * Arg0: Battery number
  199. * Arg1: State information
  200. * Arg2: Power units
  201. * Arg3: Battery Status Package
  202. */
  203. Method (GBST, 4, NotSerialized) // All on one page
  204. {
  205. #ifndef LGMR_ENABLED
  206. Acquire (BMTX, 0xFFFF) // Due to EC paging, don't run this with another function
  207. #endif
  208. If (Arg1 & 0x02) // BIT1 in "MB0S/EB0S"
  209. {
  210. Local0 = 2
  211. If (Arg1 & 0x20) // "EB0F"
  212. {
  213. Local0 = 0
  214. }
  215. }
  216. ElseIf (Arg1 & 0x04) // BIT2 in "MB0S/EB0S"
  217. {
  218. Local0 = 1
  219. }
  220. Else
  221. {
  222. Local0 = 0
  223. }
  224. If (Arg1 & 0x10) // "EB0L"
  225. {
  226. Local0 |= 0x04
  227. }
  228. If (Arg1 & 0x01) // "EB0A"
  229. {
  230. /*
  231. * Present rate is a 16bit signed int, positive while charging
  232. * and negative while discharging.
  233. */
  234. #ifdef LGMR_ENABLED
  235. Local1 = MBAC
  236. Local2 = MBRC
  237. If (MACS) // Charging
  238. #else
  239. EBID = 0 // We don't know which page was active
  240. Local1 = EBAC
  241. Local2 = EBRC
  242. If (EACS) // Charging
  243. #endif
  244. {
  245. If (Arg1 & 0x20) // "EB0F"
  246. {
  247. #ifdef LGMR_ENABLED
  248. Local2 = MBFC
  249. #else
  250. Local2 = EBFC
  251. #endif
  252. }
  253. }
  254. If (Arg2)
  255. {
  256. Local2 *= 10
  257. }
  258. #ifdef LGMR_ENABLED
  259. Local3 = MBVO
  260. #else
  261. Local3 = EBVO
  262. #endif
  263. /*
  264. * The present rate value should be positive unless discharging. If so,
  265. * negate present rate.
  266. */
  267. If (Local1 >= 0x8000)
  268. {
  269. If (Local0 & 0x01)
  270. {
  271. Local1 = (0x00010000 - Local1)
  272. }
  273. Else
  274. {
  275. Local1 = 0 // Full battery, force to 0
  276. }
  277. }
  278. /*
  279. * If that was not the case, we have an EC bug or inconsistency
  280. * and force the value to 0.
  281. */
  282. ElseIf ((Local0 & 0x02) == 0)
  283. {
  284. Local1 = 0
  285. }
  286. If (Arg2)
  287. {
  288. Local1 *= Local3
  289. Local1 /= 1000 /* Remainder ignored */
  290. }
  291. }
  292. Else
  293. {
  294. Local0 = 0
  295. Local1 = 0xFFFFFFFF
  296. Local2 = 0xFFFFFFFF
  297. Local3 = 0xFFFFFFFF
  298. }
  299. Arg3[0] = Local0
  300. Arg3[1] = Local1
  301. Arg3[2] = Local2
  302. Arg3[3] = Local3
  303. #ifndef LGMR_ENABLED
  304. Release (BMTX)
  305. #endif
  306. Return (Arg3)
  307. }
  308. Device (BAT0)
  309. {
  310. Name (_HID, EisaId ("PNP0C0A") /* Control Method Battery */) // _HID: Hardware ID
  311. Name (_UID, 0) // _UID: Unique ID
  312. Name (_PCL, Package () { \_SB }) // _PCL: Power Consumer List
  313. Name (B0IP, Package (0x0D)
  314. {
  315. 1, /* 0x00: Power Unit: mAh */
  316. 0xFFFFFFFF, /* 0x01: Design Capacity */
  317. 0xFFFFFFFF, /* 0x02: Last Full Charge Capacity */
  318. 1, /* 0x03: Battery Technology: Rechargeable */
  319. 0xFFFFFFFF, /* 0x04: Design Voltage */
  320. 0, /* 0x05: Design Capacity of Warning */
  321. 0, /* 0x06: Design Capacity of Low */
  322. 1, /* 0x07: Capacity Granularity 1 */
  323. 1, /* 0x08: Capacity Granularity 2 */
  324. "", /* 0x09: Model Number */
  325. "100", /* 0x0a: Serial Number */
  326. "Lion", /* 0x0b: Battery Type */
  327. 0 /* 0x0c: OEM Information */
  328. })
  329. Name (B0SP, Package (0x04)
  330. {
  331. 0, /* 0x00: Battery State */
  332. 0xFFFFFFFF, /* 0x01: Battery Present Rate */
  333. 0xFFFFFFFF, /* 0x02: Battery Remaining Capacity */
  334. 0xFFFFFFFF /* 0x03: Battery Present Voltage */
  335. })
  336. Method (_STA, 0, NotSerialized) // _STA: Status
  337. {
  338. Local1 = EB0A
  339. If (Local1 & 0x40)
  340. {
  341. Local1 = 0
  342. }
  343. B0ST = Local1
  344. If (Local1)
  345. {
  346. Return (0x1F)
  347. }
  348. Else
  349. {
  350. Return (0x0F)
  351. }
  352. }
  353. Method (_BIF, 0, NotSerialized) // _BIF: Battery Information
  354. {
  355. Local6 = B0ST
  356. Local7 = 20
  357. While (Local6 && Local7)
  358. {
  359. If (EB0R)
  360. {
  361. Local6 = 0
  362. }
  363. Else
  364. {
  365. Sleep (500)
  366. Local7--
  367. }
  368. }
  369. Return (GBIF (0, B0IP, Local6))
  370. }
  371. Method (_BST, 0, NotSerialized) // _BST: Battery Status
  372. {
  373. Local0 = (DerefOf (B0IP[0]) ^ 1)
  374. #ifdef LGMR_ENABLED
  375. Local5 = MB0S
  376. #else
  377. Local5 = EB0S
  378. #endif
  379. Return (GBST (0, Local5, Local0, B0SP))
  380. }
  381. }