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