# NVbright: directly control NVIDIA-based LCD backlight brightness on Apple MacBook Air A1370 NVbright is a lightweight utility for controlling LCD backlight brightness on NVIDIA-equipped Apple MacBooks running FreeBSD under EFI boot. ## About On older NVIDIA-based Apple MacBooks (such as the MacBook Air A1370 with GeForce 320M, MCP89, or GT218 chipsets), LCD backlight level is modulated via a Pulse Width Modulation (PWM) signal generated by the GPU display engine (`PDISPLAY`). Under macOS or BIOS compatibility mode, firmware dynamically alters backlight brightness through System Management Interrupts (SMI) triggered by legacy I/O port writes. However, when booting FreeBSD natively in EFI mode, this legacy SMI path is unavailable, leaving the screen backlight stuck or uncontrollable via standard ACPI methods. `nvbright` addresses this by directly interacting with the GPU MMIO register BAR: 1. Identifies the NVIDIA VGA controller's physical MMIO BAR0 address dynamically using `/usr/sbin/pciconf`. 2. Maps the register space into memory via `/dev/mem` using `mmap(2)`. 3. Detects the active Serial Output Router (SOR) with an initialized PWM divisor (`PWM_DIV`). 4. Reads and computes current duty cycle or writes new values latching the display engine registers (`PWM_CTL`). The register mapping and control logic mirror the Linux `nouveau` driver implementation for NV50 and NVA3 chip architectures: - `NV50_PDISP_SOR_PWM_DIV(i) = 0x0061c080 + i * 0x800` - `NV50_PDISP_SOR_PWM_CTL(i) = 0x0061c084 + i * 0x800` - `CTL_NEW (0x80000000)`: Latch/apply updated brightness value - `CTL_UNK (0x40000000)`: Required control flag on NVA3-class chipsets ## Build `nvbright` is written in standard C and relies only on standard POSIX and FreeBSD system headers (`sys/mman.h`, `sys/types.h`, `fcntl.h`, `unistd.h`). No external dependencies or third-party libraries are required. Compile using `make`: ```sh make ``` Or compile manually using `clang` / `cc`: ```sh cc -O2 -Wall -Wextra -o nvbright nvbright.c ``` To install the binary system-wide to `/usr/local/bin` (respects `PREFIX` and `DESTDIR`): ```sh sudo make install ``` ## Usage Because `nvbright` requires direct access to `/dev/mem` to map GPU MMIO registers and executes `/usr/sbin/pciconf`, it must be run as root (e.g., with `sudo` or `doas`). ### Command Syntax ```sh nvbright [value 0-100] ``` ### Commands - **`get`**: Queries the hardware and prints the current brightness level (percentage from 0 to 100), active SOR index, and PWM divisor. ```sh sudo nvbright get ``` *Example Output:* ```text Brightness: 65 / 100 (SOR1, pwm_div=1024) ``` - **`set <0-100>`**: Sets the display backlight directly to the specified percentage value. ```sh sudo nvbright set 75 ``` *Example Output:* ```text Set brightness: 75 / 100 ``` - **`up`**: Increases brightness by 10% (clamped at 100%). ```sh sudo nvbright up ``` - **`down`**: Decreases brightness by 10% (clamped at 0%). ```sh sudo nvbright down ``` ### Desktop and Window Manager Integration You can bind `nvbright up` and `nvbright down` commands to the brightness keys (`XF86MonBrightnessUp` and `XF86MonBrightnessDown`) in window manager configurations (such as Sway, i3, or Openbox) or configure `sudoers` / `doas.conf` rules to allow execution without password prompts. ## Credits Created by Luxferre in 2026, released into the public domain with no warranties. Hardware register specifications and control flow inspired by the Linux `nouveau` DRM backlight driver (`nv50` / `nva3`).