xref: /freebsd/sys/dev/asmc/asmcvar.h (revision f5dc2263ab1be8a35a7e27e82103f9ccd41ae584)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2007, 2008 Rui Paulo <rpaulo@FreeBSD.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #define ASMC_MAXFANS	6
31 #define ASMC_MAXVAL	32	/* Maximum SMC value size */
32 #define ASMC_KEYLEN	4	/* SMC key name length */
33 #define ASMC_TYPELEN	4	/* SMC type string length */
34 #define ASMC_MAX_SENSORS	64	/* Max sensors per type */
35 
36 /* Maximum number of auto-detected temperature sensors */
37 #define ASMC_TEMP_MAX		80
38 
39 struct asmc_softc {
40 	device_t 		sc_dev;
41 	struct mtx 		sc_mtx;
42 	int 			sc_nfan;
43 	int 			sc_nkeys;
44 	int16_t			sms_rest_x;
45 	int16_t			sms_rest_y;
46 	int16_t			sms_rest_z;
47 	struct sysctl_oid 	*sc_fan_tree[ASMC_MAXFANS+1];
48 	struct sysctl_oid 	*sc_temp_tree;
49 	struct sysctl_oid 	*sc_sms_tree;
50 	struct sysctl_oid 	*sc_light_tree;
51 	int 			sc_rid_port;
52 	int 			sc_rid_irq;
53 	struct resource 	*sc_ioport;
54 	struct resource 	*sc_irq;
55 	void 			*sc_cookie;
56 	/* MMIO backend (T2 Macs) */
57 	int			sc_rid_mem;
58 	struct resource		*sc_iomem;
59 	bool			sc_is_mmio;
60 	int			sc_is_t2;	/* T2 fan float + per-fan manual */
61 	int 			sc_sms_intrtype;
62 	struct taskqueue 	*sc_sms_tq;
63 	struct task 		sc_sms_task;
64 	uint8_t			sc_sms_intr_works;
65 	struct cdev		*sc_kbd_bkl;
66 	uint32_t		sc_kbd_bkl_level;
67 #ifdef ASMC_DEBUG
68 	/* Raw key access */
69 	struct sysctl_oid	*sc_raw_tree;
70 	char			sc_rawkey[ASMC_KEYLEN + 1];
71 	uint8_t			sc_rawval[ASMC_MAXVAL];
72 	uint8_t			sc_rawlen;
73 	char			sc_rawtype[ASMC_TYPELEN + 1];
74 #endif
75 	/* Voltage/Current/Power/Light sensors */
76 	char			*sc_voltage_sensors[ASMC_MAX_SENSORS];
77 	int			sc_voltage_count;
78 	char			*sc_current_sensors[ASMC_MAX_SENSORS];
79 	int			sc_current_count;
80 	char			*sc_power_sensors[ASMC_MAX_SENSORS];
81 	int			sc_power_count;
82 	char			*sc_light_sensors[ASMC_MAX_SENSORS];
83 	int			sc_light_count;
84 	/* Auto-detected temperature sensors */
85 	char			*sc_temp_sensors[ASMC_TEMP_MAX];
86 	int			sc_temp_count;
87 	/* Auto-detected capabilities */
88 	int			sc_has_sms;
89 	int			sc_has_light;
90 	int			sc_light_len;	/* ASMC_LIGHT_{SHORT,LONG}LEN */
91 	int			sc_has_safespeed;
92 	int			sc_has_alsl;	/* ALSL interrupt source */
93 };
94 
95 /*
96  * Data port.
97  */
98 #define ASMC_DATAPORT_READ(sc)	bus_read_1(sc->sc_ioport, 0x00)
99 #define ASMC_DATAPORT_WRITE(sc, val) \
100 	bus_write_1(sc->sc_ioport, 0x00, val)
101 #define ASMC_STATUS_MASK 	0x0f
102 
103 /*
104  * Command port.
105  */
106 #define ASMC_CMDPORT_READ(sc)	bus_read_1(sc->sc_ioport, 0x04)
107 #define ASMC_CMDPORT_WRITE(sc, val) \
108 	bus_write_1(sc->sc_ioport, 0x04, val)
109 #define ASMC_CMDREAD		0x10
110 #define ASMC_CMDWRITE		0x11
111 #define ASMC_CMDGETBYINDEX	0x12
112 #define ASMC_CMDGETINFO		0x13
113 
114 #define ASMC_STATUS_AWAIT_DATA	0x04
115 #define ASMC_STATUS_DATA_READY	0x05
116 
117 #define ASMC_KEYINFO_RESPLEN	6	/* getinfo: 1 len + 4 type + 1 attr */
118 #define ASMC_MAXRETRIES		10
119 
120 /*
121  * Interrupt port.
122  */
123 #define ASMC_INTPORT_READ(sc)	bus_read_1(sc->sc_ioport, 0x1f)
124 
125 /* Number of keys */
126 #define ASMC_NKEYS		"#KEY"	/* RO; 4 bytes */
127 
128 /* Query the ASMC revision */
129 #define ASMC_KEY_REV		"REV "  /* RO: 6 bytes */
130 
131 /*
132  * Fan control via SMC.
133  */
134 #define ASMC_KEY_FANCOUNT	"FNum"	/* RO; 1 byte */
135 #define ASMC_KEY_FANMANUAL	"FS! "	/* RW; 2 bytes */
136 #define ASMC_KEY_FANID		"F%dID"	/* RO; 16 bytes */
137 #define ASMC_KEY_FANSPEED	"F%dAc"	/* RO; 2 bytes */
138 #define ASMC_KEY_FANMINSPEED	"F%dMn"	/* RW; 2 bytes */
139 #define ASMC_KEY_FANMAXSPEED	"F%dMx"	/* RO; 2 bytes */
140 #define ASMC_KEY_FANSAFESPEED	"F%dSf"	/* RO; 2 bytes */
141 #define ASMC_KEY_FANTARGETSPEED	"F%dTg"	/* RW; 2 bytes */
142 
143 /*
144  * Sudden Motion Sensor (SMS).
145  */
146 #define ASMC_SMS_INIT1		0xe0
147 #define ASMC_SMS_INIT2		0xf8
148 #define ASMC_KEY_SMS		"MOCN"	/* RW; 2 bytes */
149 #define ASMC_KEY_SMS_X		"MO_X"	/* RO; 2 bytes */
150 #define ASMC_KEY_SMS_Y		"MO_Y"	/* RO; 2 bytes */
151 #define ASMC_KEY_SMS_Z		"MO_Z"	/* RO; 2 bytes */
152 #define ASMC_KEY_SMS_LOW	"MOLT"	/* RW; 2 bytes */
153 #define ASMC_KEY_SMS_HIGH	"MOHT"	/* RW; 2 bytes */
154 #define ASMC_KEY_SMS_LOW_INT	"MOLD"	/* RW; 1 byte */
155 #define ASMC_KEY_SMS_HIGH_INT	"MOHD"	/* RW; 1 byte */
156 #define ASMC_KEY_SMS_FLAG	"MSDW"	/* RW; 1 byte */
157 #define ASMC_SMS_INTFF		0x60	/* Free fall Interrupt */
158 #define ASMC_SMS_INTHA		0x6f	/* High Acceleration Interrupt */
159 #define ASMC_SMS_INTSH		0x80	/* Shock Interrupt */
160 
161 /*
162  * Light Sensor.
163  */
164 #define ASMC_ALSL_INT2A		0x2a	/* Ambient Light related Interrupt */
165 
166 /*
167  * Keyboard backlight.
168  */
169 #define ASMC_LIGHT_SHORTLEN	6	/* ALV0 short format */
170 #define ASMC_LIGHT_LONGLEN	10	/* ALV0 long format (10-byte) */
171 #define ASMC_KEY_LIGHTLEFT	"ALV0"	/* RO; 6 or 10 bytes */
172 #define ASMC_KEY_LIGHTRIGHT	"ALV1"	/* RO; 6 bytes */
173 #define ASMC_KEY_LIGHTVALUE	"LKSB"	/* WO; 2 bytes */
174 #define ASMC_KEY_LIGHTSRC	"ALSL"	/* RO; ambient light source */
175 #define ASMC_KEY_FANSAFESPEED0	"F0Sf"	/* RO; 2 bytes */
176 
177 /*
178  * Clamshell.
179  */
180 #define ASMC_KEY_CLAMSHELL	"MSLD"	/* RO; 1 byte */
181 
182 /*
183  * Auto power-on after AC power loss (AUPO).
184  * When set, the machine boots automatically when AC power is restored
185  * after an unclean power loss.  This is NOT Wake-on-LAN.
186  */
187 #define ASMC_KEY_AUPO		"AUPO"	/* RW; 1 byte */
188 
189 /*
190  * Interrupt keys.
191  */
192 #define ASMC_KEY_INTOK		"NTOK"	/* WO; 1 byte */
193 
194 /*
195  * System State Machine / diagnostics keys.
196  *
197  * MSSD - Mac System Shutdown cause (last shutdown reason code)
198  * MSSP - Mac System SleeP cause (last sleep reason code)
199  * MSAL - Mac System ALarm (thermal subsystem status bitmap)
200  * MSPS - Mac System Power State (current power state index)
201  * CLKT - CLocK Time (seconds since midnight, SMC RTC)
202  * MSTS - Mac System sTate/Status (SSM state; 0 = S0 awake)
203  */
204 #define ASMC_KEY_CLKT		"CLKT"	/* RO; 4 bytes ui32 BE */
205 #define ASMC_KEY_MSSD		"MSSD"	/* RO; 1 byte si8 */
206 #define ASMC_KEY_MSSP		"MSSP"	/* RO; 1 byte si8 */
207 #define ASMC_KEY_MSAL		"MSAL"	/* RO; 1 byte hex_ */
208 #define ASMC_KEY_MSPS		"MSPS"	/* RO; 1 or 2 bytes hex_ */
209 #define ASMC_KEY_MSTS		"MSTS"	/* RO; 1 byte ui8 */
210 
211 #define ASMC_MSAL_TSS		0x01	/* TSS running */
212 #define ASMC_MSAL_THERM_VALID	0x02	/* thermal calibration valid */
213 #define ASMC_MSAL_CALIB_VALID	0x08	/* I/P calibration valid */
214 #define ASMC_MSAL_PROCHOT	0x40	/* Prochot enabled */
215 #define ASMC_MSAL_PLIMITS	0x80	/* plimits enabled */
216 
217 /*
218  * Board identity keys.
219  *
220  * RPlt - board platform identifier (e.g. "Mac-XXXX")
221  * RGEN - security chip generation (3 = T2)
222  */
223 #define ASMC_KEY_RPLT		"RPlt"	/* RO; 8 bytes ch8* */
224 #define ASMC_KEY_RGEN		"RGEN"	/* RO; 1 byte ui8 */
225 #define ASMC_RPLT_MAXLEN	8	/* RPlt key data length */
226 
227 /*
228  * Shutdown/sleep cause codes (MSSD/MSSP values).
229  *
230  * Positive values indicate normal operation; negative values indicate
231  * fault conditions.
232  * Sources: Apple SMC firmware, VirtualSMC docs, macOS
233  * pmset/powermetrics output.
234  */
235 struct asmc_cause {
236 	int8_t		code;
237 	const char	*desc;		/* shutdown description */
238 	const char	*sleep_desc;	/* sleep description, or NULL if same */
239 };
240 
241 #define ASMC_CAUSE_BUFLEN	48	/* "-128 (temperature-overlimit-timeout)\0" */
242 
243 static const struct asmc_cause asmc_cause_table[] = {
244 	{    5,	"good-shutdown",		"good-sleep" },
245 	{    3,	"power-button",			NULL },
246 	{    2,	"low-battery-sleep",		NULL },
247 	{    1,	"overtemp-sleep",		NULL },
248 	{    0,	"initial",			NULL },
249 	{   -1,	"health-check",			NULL },
250 	{   -2,	"power-supply",			NULL },
251 	{   -3,	"temperature-multisleep",	NULL },
252 	{   -4,	"sensor-fan",			NULL },
253 	{  -30,	"temperature-overlimit-timeout",NULL },
254 	{  -40,	"pswr-smrst",			NULL },	/* power supply watchdog reset */
255 	{  -50,	"unmapped",			NULL },
256 	{  -60,	"low-battery",			NULL },
257 	{  -61,	"ninja-shutdown",		NULL },	/* sudden unexpected power loss */
258 	{  -62,	"ninja-restart",		NULL },
259 	{  -70,	"palm-rest-temperature",	NULL },
260 	{  -71,	"sodimm-temperature",		NULL },
261 	{  -72,	"heatpipe-temperature",		NULL },
262 	{  -74,	"battery-temperature",		NULL },
263 	{  -75,	"adapter-timeout",		NULL },
264 	{  -77,	"manual-temperature",		NULL },
265 	{  -78,	"adapter-current",		NULL },
266 	{  -79,	"battery-current",		NULL },
267 	{  -82,	"skin-temperature",		NULL },
268 	{  -83,	"skin-temperature-sensors",	NULL },
269 	{  -84,	"backup-temperature",		NULL },
270 	{  -86,	"cpu-proximity-temperature",	NULL },
271 	{  -95,	"cpu-temperature",		NULL },
272 	{ -100,	"power-supply-temperature",	NULL },
273 	{ -101,	"lcd-temperature",		NULL },
274 	{ -102,	"rsm-power-fail",		NULL },
275 	{ -103,	"battery-cuv",			NULL },	/* cell under-voltage */
276 	{ -127,	"pmu-forced-shutdown",		NULL },
277 	{ -128,	"unknown",			NULL },
278 };
279