blob: e273b22bc72c0e8e40a96714db038c7fef0c31cd [file] [log] [blame]
Nico Huber53ec8c52020-03-21 19:50:26 +01001/* SPDX-License-Identifier: GPL-2.0-only */
Patrick Rudolph6838aae2018-07-29 10:53:01 +02002
3 /*
4 * Pseudo device that contains methods to modify Opregion
5 * "Mailbox 3 BIOS to Driver Notification"
6 * The BIOS to Driver Notification mailbox is intended to support
7 * BIOS to Driver event notification or data storage for BIOS to
8 * Driver data synchronization purpose.
9 */
10 Device (BOX3)
11 {
12 Name (_ADR, 0)
13
14 OperationRegion (OPRG, SystemMemory, ASLS, 0x2000)
15 Field (OPRG, DWordAcc, NoLock, Preserve)
16 {
17 // OpRegion Header
18 Offset (0x58),
19 MBOX, 32,
20
21 // Mailbox 3
22 Offset (0x300),
23 ARDY, 1, /* Offset 0 Driver readiness */
24 , 31,
25 ASLC, 32, /* Offset 4 ASLE interrupt command / status */
26 TCHE, 32, /* Offset 8 Technology enabled indicator */
27 ALSI, 32, /* Offset 12 Current ALS illuminance reading */
28 BCLP, 32, /* Offset 16 Backlight britness to set */
29 PFIT, 32, /* Offset 20 Panel fitting Request */
30 CBLV, 32, /* Offset 24 Brightness Current State */
31 }
32
33 /*
34 * Request back-light brightness change through mailbox 3
35 *
36 * @param Arg0 The brightness level to set in percent
37 * @Return Zero on success, Ones on failure
38 * Errors: * ASLS is zero
39 * * Mailbox 3 support not advertised
40 * * Driver not loaded or not ready
41 * * Driver reported an error during ASLE IRQ
42 */
Nico Huberc48d8832018-08-23 22:36:09 +020043 Method (XBCM, 1, Serialized)
Patrick Rudolph6838aae2018-07-29 10:53:01 +020044 {
45 If (LEqual(ASLS, Zero))
46 {
47 Return (Ones)
48 }
49 If (LEqual(And(MBOX, 0x4), Zero))
50 {
51 Return (Ones)
52 }
Patrick Rudolph6838aae2018-07-29 10:53:01 +020053
Nico Huber58344fc2018-08-23 21:52:05 +020054 /* Always keep BCLP up to date, even if driver is not ready.
55 It requires a full 8-bit brightness value. 255 = 100% */
Felix Singerb232ca62021-12-31 12:12:18 +010056 Store (Arg0 * 255 / 100, Local1)
Alexander Couzens661907c2018-08-23 16:40:55 +020057 If (LGreater(Local1, 255)) {
58 Store (255, Local1)
59 }
Nico Huber58344fc2018-08-23 21:52:05 +020060 /* also set valid bit */
Alexander Couzens661907c2018-08-23 16:40:55 +020061 Store (Or (Local1, 0x80000000), BCLP)
62
Nico Huber58344fc2018-08-23 21:52:05 +020063 If (LEqual(ARDY, Zero))
64 {
65 Return (Ones)
66 }
67
Patrick Rudolph6838aae2018-07-29 10:53:01 +020068 /* Request back-light change */
69 Store (0x2, ASLC)
70 /* Trigger IRQ */
71 Store (0x1, ASLE)
72
73 Store (0x20, Local0)
74 While (LGreater(Local0, Zero))
75 {
76 Sleep (1)
Nico Huberc48d8832018-08-23 22:36:09 +020077 If (LEqual (And (ASLC, 0x2), 0)) {
78 /* Request has been processed, check status: */
79 And (ShiftRight (ASLC, 12), 0x3, Local1)
80 If (LEqual (Local1, 0)) {
81 Return (Zero)
82 } Else {
83 Return (Ones)
84 }
Patrick Rudolph6838aae2018-07-29 10:53:01 +020085 }
86 Decrement (Local0)
87 }
88
89 Return (Ones)
90 }
Patrick Rudolph6838aae2018-07-29 10:53:01 +020091 }
92
93 /*
94 * Pseudo device that contains methods to operate on GTT memory
95 */
96 Device (LEGA)
97 {
98 Name (_ADR, 0)
99
Nico Huberf26a7c72018-08-23 22:14:01 +0200100 /* Divide round closest */
101 Method (DRCL, 2)
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200102 {
Felix Singerb232ca62021-12-31 12:12:18 +0100103 Return ((Arg0 + Arg1 / 2) / Arg1)
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200104 }
105
Nico Huberf26a7c72018-08-23 22:14:01 +0200106 Method (XBCM, 1, NotSerialized)
107 {
Felix Singer24eb6052021-12-31 11:48:31 +0100108 Store (DRCL (Arg0 * BCLM, 100), BCLV)
Nico Huberf26a7c72018-08-23 22:14:01 +0200109 }
110
111 /* Find value closest to BCLV in BRIG (which must be ordered) */
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200112 Method (XBQC, 0, NotSerialized)
113 {
Patrick Rudolph6dc488a2020-02-28 10:38:55 +0100114 /* Prevent DivideByZero if backlight control isn't enabled */
115 If (BCLM == 0)
116 {
117 Return (Zero)
118 }
Nico Huberf26a7c72018-08-23 22:14:01 +0200119 /* Local0: current percentage */
Felix Singer24eb6052021-12-31 11:48:31 +0100120 Store (DRCL (BCLV * 100, BCLM), Local0)
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200121
Nico Huberf26a7c72018-08-23 22:14:01 +0200122 /* Local1: loop index (selectable values start at 2 in BRIG) */
123 Store (2, Local1)
Felix Singer1eba1962021-12-30 02:09:31 +0100124 While (LLess (Local1, SizeOf (BRIG) - 1)) {
Nico Huberf26a7c72018-08-23 22:14:01 +0200125 /* Local[23]: adjacent values in BRIG */
Felix Singere55a7d12021-12-29 13:56:36 +0100126 Store (DeRefOf (BRIG[Local1]), Local2)
Felix Singerea642ab2021-12-30 02:53:22 +0100127 Store (DeRefOf (BRIG[Local1 + 1]), Local3)
Nico Huberf26a7c72018-08-23 22:14:01 +0200128
129 If (LLess (Local0, Local3)) {
Felix Singer1eba1962021-12-30 02:09:31 +0100130 If (LOr (LLess (Local0, Local2), LLess (Local0 - Local2, Local3 - Local0))) {
Nico Huberf26a7c72018-08-23 22:14:01 +0200131 Return (Local2)
132 } Else {
133 Return (Local3)
134 }
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200135 }
Nico Huberf26a7c72018-08-23 22:14:01 +0200136
137 Increment (Local1)
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200138 }
Nico Huberf26a7c72018-08-23 22:14:01 +0200139
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200140 /* Didn't find greater/equal value: use the last */
Nico Huberf26a7c72018-08-23 22:14:01 +0200141 Return (Local3)
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200142 }
143 }
144
Nico Huberd5842f52015-09-24 17:45:45 +0200145 Method (XBCM, 1, NotSerialized)
146 {
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200147 If (LEqual(^BOX3.XBCM (Arg0), Ones))
148 {
149 ^LEGA.XBCM (Arg0)
150 }
Nico Huberd5842f52015-09-24 17:45:45 +0200151 }
152
153 Method (XBQC, 0, NotSerialized)
154 {
Nico Huberf26a7c72018-08-23 22:14:01 +0200155 /*
156 * Always query the hardware directly. Not all OS drivers
157 * keep CBLV up to date (one is Linux' i915). Some years
158 * after that is fixed we can probably use CBLV?
159 */
160 Return (^LEGA.XBQC ())
Nico Huberd5842f52015-09-24 17:45:45 +0200161 }