blob: d6e417cac80b59829c937f031ab94b069773c67f [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
Felix Singer9df60d32022-12-26 09:43:07 +010037 * @Return 0 on success, Ones on failure
Patrick Rudolph6838aae2018-07-29 10:53:01 +020038 * 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 {
Felix Singer60415432022-01-02 00:43:21 +010045 If (ASLS == 0)
Patrick Rudolph6838aae2018-07-29 10:53:01 +020046 {
47 Return (Ones)
48 }
Felix Singerd2527762022-12-16 07:54:16 +010049 If (MBOX & 4 == 0)
Patrick Rudolph6838aae2018-07-29 10:53:01 +020050 {
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 Singer52f46522022-12-12 02:25:37 +010056 Local1 = Arg0 * 255 / 100
Felix Singerfa9e31b2022-01-02 01:53:54 +010057 If (Local1 > 255) {
Felix Singer52f46522022-12-12 02:25:37 +010058 Local1 = 255
Alexander Couzens661907c2018-08-23 16:40:55 +020059 }
Nico Huber58344fc2018-08-23 21:52:05 +020060 /* also set valid bit */
Felix Singer274fa642022-12-16 04:27:21 +010061 BCLP = Local1 | 0x80000000
Alexander Couzens661907c2018-08-23 16:40:55 +020062
Felix Singer60415432022-01-02 00:43:21 +010063 If (ARDY == 0)
Nico Huber58344fc2018-08-23 21:52:05 +020064 {
65 Return (Ones)
66 }
67
Patrick Rudolph6838aae2018-07-29 10:53:01 +020068 /* Request back-light change */
Felix Singer52f46522022-12-12 02:25:37 +010069 ASLC = 0x2
Patrick Rudolph6838aae2018-07-29 10:53:01 +020070 /* Trigger IRQ */
Felix Singer52f46522022-12-12 02:25:37 +010071 ASLE = 0x1
Patrick Rudolph6838aae2018-07-29 10:53:01 +020072
Felix Singer52f46522022-12-12 02:25:37 +010073 Local0 = 0x20
Felix Singerfa9e31b2022-01-02 01:53:54 +010074 While (Local0 > 0)
Patrick Rudolph6838aae2018-07-29 10:53:01 +020075 {
76 Sleep (1)
Felix Singerd2527762022-12-16 07:54:16 +010077 If (ASLC & 2 == 0) {
Nico Huberc48d8832018-08-23 22:36:09 +020078 /* Request has been processed, check status: */
Felix Singer35e65a82022-12-16 07:11:17 +010079 Local1 = (ASLC >> 12) & 3
Felix Singer60415432022-01-02 00:43:21 +010080 If (Local1 == 0) {
Felix Singer9df60d32022-12-26 09:43:07 +010081 Return (0)
Nico Huberc48d8832018-08-23 22:36:09 +020082 } Else {
83 Return (Ones)
84 }
Patrick Rudolph6838aae2018-07-29 10:53:01 +020085 }
Felix Singer66e26302021-12-31 14:13:47 +010086 Local0--
Patrick Rudolph6838aae2018-07-29 10:53:01 +020087 }
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 Singer52f46522022-12-12 02:25:37 +0100108 BCLV = DRCL (Arg0 * BCLM, 100)
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 {
Felix Singer9df60d32022-12-26 09:43:07 +0100117 Return (0)
Patrick Rudolph6dc488a2020-02-28 10:38:55 +0100118 }
Nico Huberf26a7c72018-08-23 22:14:01 +0200119 /* Local0: current percentage */
Felix Singer52f46522022-12-12 02:25:37 +0100120 Local0 = DRCL (BCLV * 100, BCLM)
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) */
Felix Singer52f46522022-12-12 02:25:37 +0100123 Local1 = 2
Felix Singer04e68932022-01-02 01:46:20 +0100124 While (Local1 < SizeOf (BRIG) - 1) {
Nico Huberf26a7c72018-08-23 22:14:01 +0200125 /* Local[23]: adjacent values in BRIG */
Felix Singer52f46522022-12-12 02:25:37 +0100126 Local2 = DeRefOf (BRIG[Local1])
127 Local3 = DeRefOf (BRIG[Local1 + 1])
Nico Huberf26a7c72018-08-23 22:14:01 +0200128
Felix Singer04e68932022-01-02 01:46:20 +0100129 If (Local0 < Local3) {
130 If (Local0 < Local2 || 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
Felix Singer42fcf5a2021-12-31 13:49:03 +0100137 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 {
Felix Singer60415432022-01-02 00:43:21 +0100147 If (^BOX3.XBCM (Arg0) == Ones)
Patrick Rudolph6838aae2018-07-29 10:53:01 +0200148 {
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 }