xref: /freebsd/sys/dev/acpi_apple/acpi_apple.c (revision 4a059dac78157e6163d6e8ed6e7be5ec65a78a5f)
144ceda0aSAbdelkader Boudih /*
244ceda0aSAbdelkader Boudih  * Copyright (c) 2026 Abdelkader Boudih <seuros@FreeBSD.org>
344ceda0aSAbdelkader Boudih  *
444ceda0aSAbdelkader Boudih  * SPDX-License-Identifier: BSD-2-Clause
544ceda0aSAbdelkader Boudih  */
644ceda0aSAbdelkader Boudih 
744ceda0aSAbdelkader Boudih /*
844ceda0aSAbdelkader Boudih  * acpi_apple(4) - FreeBSD driver for Apple platform ACPI devices.
944ceda0aSAbdelkader Boudih  *
1044ceda0aSAbdelkader Boudih  * Handles multiple Apple ACPI devices with a single driver:
1144ceda0aSAbdelkader Boudih  *
1244ceda0aSAbdelkader Boudih  *   APP000B (GMUX) / APP9876 (PCH PMC) - platform instance:
1344ceda0aSAbdelkader Boudih  *     - Wake-on-LAN: walk ACPI namespace on shutdown, call _PSW(1) on
1444ceda0aSAbdelkader Boudih  *       any device with ACPI_FLAG_WAKE_ENABLED (dev.X.Y.wake=1).
1544ceda0aSAbdelkader Boudih  *     - Lid state: follow acpi_lid_event to blank and restore the
1644ceda0aSAbdelkader Boudih  *       backlight.
1744ceda0aSAbdelkader Boudih  *
1844ceda0aSAbdelkader Boudih  *   APP0002 (PNLF) - backlight instance:
1944ceda0aSAbdelkader Boudih  *     - Panel backlight control via GPU PCI BAR MMIO registers.
2044ceda0aSAbdelkader Boudih  *     - Supports Intel PCH/CPU, Nvidia NV40/NV50, AMD R600+ families.
2144ceda0aSAbdelkader Boudih  *     - Registers with backlight(9) framework.
2244ceda0aSAbdelkader Boudih  *
2344ceda0aSAbdelkader Boudih  * OSDW() gates on OSYS==0x2710 ("Darwin"), installed via
2444ceda0aSAbdelkader Boudih  * hw.acpi.apple_darwin_osi=1.  _PSW on GIGE only fires if the bge(4)
2544ceda0aSAbdelkader Boudih  * instance has ACPI_FLAG_WAKE_ENABLED (dev.bge.X.wake=1).
2644ceda0aSAbdelkader Boudih  */
2744ceda0aSAbdelkader Boudih 
2844ceda0aSAbdelkader Boudih #include <sys/cdefs.h>
2944ceda0aSAbdelkader Boudih #include "opt_acpi.h"
3044ceda0aSAbdelkader Boudih #include "acpi_apple.h"
3144ceda0aSAbdelkader Boudih 
3244ceda0aSAbdelkader Boudih #include "backlight_if.h"
3344ceda0aSAbdelkader Boudih 
3444ceda0aSAbdelkader Boudih #define _COMPONENT	ACPI_OEM
3544ceda0aSAbdelkader Boudih ACPI_MODULE_NAME("Apple")
3644ceda0aSAbdelkader Boudih 
3744ceda0aSAbdelkader Boudih /*
3844ceda0aSAbdelkader Boudih  * Attach to APP9876 (PCH PMC, T2 Macs), APP000B (GMUX, discrete GPU
3944ceda0aSAbdelkader Boudih  * Macs), or APP0002 (panel backlight, all Intel Macs with display).
4044ceda0aSAbdelkader Boudih  * APP0001 (SMC) is owned by asmc(4).
4144ceda0aSAbdelkader Boudih  *
4244ceda0aSAbdelkader Boudih  * BUS_PROBE_LOW_PRIORITY so a future apple_gmux driver can claim
4344ceda0aSAbdelkader Boudih  * APP000B at default priority.
4444ceda0aSAbdelkader Boudih  */
4544ceda0aSAbdelkader Boudih static char *acpi_apple_ids[] = { "APP9876", "APP000B", "APP0002", NULL };
4644ceda0aSAbdelkader Boudih 
4744ceda0aSAbdelkader Boudih static int
acpi_apple_probe(device_t dev)4844ceda0aSAbdelkader Boudih acpi_apple_probe(device_t dev)
4944ceda0aSAbdelkader Boudih {
5044ceda0aSAbdelkader Boudih 	int rv;
5144ceda0aSAbdelkader Boudih 
5244ceda0aSAbdelkader Boudih 	if (acpi_disabled("apple"))
5344ceda0aSAbdelkader Boudih 		return (ENXIO);
5444ceda0aSAbdelkader Boudih 	rv = ACPI_ID_PROBE(device_get_parent(dev), dev, acpi_apple_ids, NULL);
5544ceda0aSAbdelkader Boudih 	if (rv > 0)
5644ceda0aSAbdelkader Boudih 		return (rv);
5744ceda0aSAbdelkader Boudih 
5844ceda0aSAbdelkader Boudih 	if (acpi_MatchHid(acpi_get_handle(dev), "APP0002"))
5944ceda0aSAbdelkader Boudih 		device_set_desc(dev, "Apple Panel Backlight");
6044ceda0aSAbdelkader Boudih 	else
6144ceda0aSAbdelkader Boudih 		device_set_desc(dev, "Apple platform controller");
6244ceda0aSAbdelkader Boudih 
6344ceda0aSAbdelkader Boudih 	return (BUS_PROBE_LOW_PRIORITY);
6444ceda0aSAbdelkader Boudih }
6544ceda0aSAbdelkader Boudih 
6644ceda0aSAbdelkader Boudih static int
acpi_apple_attach(device_t dev)6744ceda0aSAbdelkader Boudih acpi_apple_attach(device_t dev)
6844ceda0aSAbdelkader Boudih {
6944ceda0aSAbdelkader Boudih 	struct acpi_apple_softc *sc;
7044ceda0aSAbdelkader Boudih 
7144ceda0aSAbdelkader Boudih 	sc = device_get_softc(dev);
7244ceda0aSAbdelkader Boudih 	sc->dev = dev;
7344ceda0aSAbdelkader Boudih 	sc->handle = acpi_get_handle(dev);
7444ceda0aSAbdelkader Boudih 
7544ceda0aSAbdelkader Boudih 	if (acpi_MatchHid(sc->handle, "APP0002"))
7644ceda0aSAbdelkader Boudih 		sc->mode = ACPI_APPLE_BACKLIGHT;
7744ceda0aSAbdelkader Boudih 	else
7844ceda0aSAbdelkader Boudih 		sc->mode = ACPI_APPLE_PLATFORM;
7944ceda0aSAbdelkader Boudih 
80*4a059dacSAbdelkader Boudih 	switch (sc->mode) {
81*4a059dacSAbdelkader Boudih 	case ACPI_APPLE_PLATFORM:
8244ceda0aSAbdelkader Boudih 		return (acpi_apple_platform_attach(sc));
83*4a059dacSAbdelkader Boudih 	case ACPI_APPLE_BACKLIGHT:
8444ceda0aSAbdelkader Boudih 		return (acpi_apple_backlight_attach(sc));
8544ceda0aSAbdelkader Boudih 	}
86*4a059dacSAbdelkader Boudih 	return (ENXIO);
87*4a059dacSAbdelkader Boudih }
8844ceda0aSAbdelkader Boudih 
8944ceda0aSAbdelkader Boudih static int
acpi_apple_detach(device_t dev)9044ceda0aSAbdelkader Boudih acpi_apple_detach(device_t dev)
9144ceda0aSAbdelkader Boudih {
9244ceda0aSAbdelkader Boudih 	struct acpi_apple_softc *sc;
9344ceda0aSAbdelkader Boudih 
9444ceda0aSAbdelkader Boudih 	sc = device_get_softc(dev);
95*4a059dacSAbdelkader Boudih 	switch (sc->mode) {
96*4a059dacSAbdelkader Boudih 	case ACPI_APPLE_PLATFORM:
9744ceda0aSAbdelkader Boudih 		acpi_apple_platform_detach(sc);
98*4a059dacSAbdelkader Boudih 		break;
99*4a059dacSAbdelkader Boudih 	case ACPI_APPLE_BACKLIGHT:
10044ceda0aSAbdelkader Boudih 		acpi_apple_backlight_detach(sc);
101*4a059dacSAbdelkader Boudih 		break;
102*4a059dacSAbdelkader Boudih 	}
10344ceda0aSAbdelkader Boudih 	return (0);
10444ceda0aSAbdelkader Boudih }
10544ceda0aSAbdelkader Boudih 
10644ceda0aSAbdelkader Boudih static device_method_t acpi_apple_methods[] = {
10744ceda0aSAbdelkader Boudih 	DEVMETHOD(device_probe,			acpi_apple_probe),
10844ceda0aSAbdelkader Boudih 	DEVMETHOD(device_attach,		acpi_apple_attach),
10944ceda0aSAbdelkader Boudih 	DEVMETHOD(device_detach,		acpi_apple_detach),
11044ceda0aSAbdelkader Boudih 
11144ceda0aSAbdelkader Boudih 	DEVMETHOD(backlight_update_status,	acpi_apple_bl_update_status),
11244ceda0aSAbdelkader Boudih 	DEVMETHOD(backlight_get_status,		acpi_apple_bl_get_status),
11344ceda0aSAbdelkader Boudih 	DEVMETHOD(backlight_get_info,		acpi_apple_bl_get_info),
11444ceda0aSAbdelkader Boudih 
11544ceda0aSAbdelkader Boudih 	DEVMETHOD_END
11644ceda0aSAbdelkader Boudih };
11744ceda0aSAbdelkader Boudih 
11844ceda0aSAbdelkader Boudih static driver_t acpi_apple_driver = {
11944ceda0aSAbdelkader Boudih 	"acpi_apple",
12044ceda0aSAbdelkader Boudih 	acpi_apple_methods,
12144ceda0aSAbdelkader Boudih 	sizeof(struct acpi_apple_softc),
12244ceda0aSAbdelkader Boudih };
12344ceda0aSAbdelkader Boudih 
12444ceda0aSAbdelkader Boudih DRIVER_MODULE(acpi_apple, acpi, acpi_apple_driver, 0, 0);
12544ceda0aSAbdelkader Boudih MODULE_DEPEND(acpi_apple, acpi, 1, 1, 1);
12644ceda0aSAbdelkader Boudih MODULE_DEPEND(acpi_apple, backlight, 1, 1, 1);
12744ceda0aSAbdelkader Boudih MODULE_VERSION(acpi_apple, 1);
128