aboutsummarylogtreecommitdiffstats
path: root/README.md
blob: 9282329cb0aa55e2479fe1909669075b35b36eb2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
## Insyde DCHU Kernel driver

DCHU is a kernel-space devices that integrates:
- dchu\_core: Contact with ACPI device `CLV0001` aka DCHU
- dchu\_hwmon: hwmon child exposing fans, PWM duty, and temps via the FAN package
- dchu\_leds: LED child controlling keyboard backlight levels (05), RGB is not planned for support since there is no test device

Features are replicated from Gigabyte's "Control Center" (CC not GCC) - ControlCenter\_3.55

Tested on `Gigabyte U4 UD`, which on latest upstream doesn't have suitable fan drivers 

### Subapps UWP implemented:

- [ ] BatteryUtility
- [x] CC3.0 (pretty much hobo)
- [ ] CPU\_OC
- [ ] EnergySave
- [x] FanSpeedSettings
- [ ] FlexiKey
- [ ] FnKey (todo)
- [ ] GPUOverclocking
- [x] Keyboard

### Requirements
- Linux kernel headers
- Firmware implementing DCHU `\_DSM` with UUID `E4 24 F2 93 DC FB BF 4B AD D6 DB 71 BD C0 AF AD`

### Build
- Build all modules:
  - `make modules_all`
- Or explicitly:
  - `make modules MODULES="dchu_core dchu_hwmon dchu_leds"`

#### Using custom kernel headers (manual build)
- Point `KDIR` at your kernel build tree (must have `make modules_prepare` run):
  - `make modules_all KDIR=/path/to/linux/build`
  - Example: if you built with `O=/path/to/build`, use that `O` dir as `KDIR`.

### DKMS (Arch Linux)
- Package build:
  - `makepkg -f` (produces `insyde-dchu-dkms-<ver>-x86_64.pkg.tar.zst`)
- Install the DKMS package:
  - `sudo pacman -U insyde-dchu-dkms-*.pkg.tar.zst`
- DKMS will auto-build for installed kernels and on updates.
- Manual DKMS (optional):
  - `sudo dkms add -m insyde-dchu-dkms -v 0.1.0`
  - `sudo dkms build -m insyde-dchu-dkms -v 0.1.0`
  - `sudo dkms install -m insyde-dchu-dkms -v 0.1.0`

#### DKMS with custom kernel headers
- Preferred: install/symlink your kernel headers to `/lib/modules/<release>/build`, then:
  - `sudo dkms build -m insyde-dchu-dkms -v 0.1.0 -k <release>`
- Advanced (enabled in dkms.conf): pass `KDIR` to override the kernel dir DKMS uses:
  - `sudo KDIR=/path/to/linux/build dkms build -m insyde-dchu-dkms -v 0.1.0 -k <release>`
  - Ensure `<release>` matches the kernel built in `KDIR` (ABI match).

### Load / Unload
- Load in order (hwmon params optional):
  - `sudo insmod ./dchu_core.ko`
  - `sudo insmod ./dchu_hwmon.ko invert=1 tach_hz=35940 ppr=1 le=1`
  - `sudo insmod ./dchu_leds.ko`
- Or:
  - `make load_all PARAMS="invert=1 tach_hz=35940 ppr=1 le=1"`
- Unload:
  - `sudo rmmod dchu_hwmon dchu_leds dchu_core`
  - Or `make unload_all`

## DCHU spec

### hwmon Child (Fans/PWM/Temps)
- Sysfs: `/sys/class/hwmon/hwmonX/` with `name` = `dchu`
- Exposed attributes:
  - Fans (RPM): `fan1_input` (CPU), `fan2_input` (GPU1), `fan3_input` (GPU2)
  - PWM (0255): `pwm1`, `pwm2`, `pwm3` (scaled from 0100 duty; clamped ≤255)
  - Temps (m°C): `temp1_input` (CPU remote), `temp2_input` (GPU1), `temp3_input` (GPU2)
- Debug: `fan_buf` (hex dump of FAN package 12)
- Fan controls:
  - `fan_mode` (RW): accepts numeric (0/1/3/5/6/7) or names (auto, max, silent, maxq, custom, turbo). Write invokes `_DSM` command `121` with a 4-byte payload: `payload[0]=mode`, `payload[1]=0`, `payload[2]=0`, `payload[3]=1` (subcommand).
  - `fan_mode_name` (RO): the name of the last set mode.
- Parse table (FAN package id = 12):
  - CPU RPM: `(buf[2] << 8) | buf[3]`
  - GPU1 RPM: `(buf[4] << 8) | buf[5]`
  - GPU2 RPM: `(buf[6] << 8) | buf[7]`
  - CPU duty: `buf[16]` (0100)
  - GPU1 duty: `buf[19]` (0100)
  - GPU2 duty: `buf[22]` (0100)
  - CPU remote: `buf[18]` (°C)
  - GPU1 remote: `buf[21]` (°C)
  - GPU2 remote: `buf[24]` (°C)

### LEDs Child (Keyboard backlight)
- LED: `/sys/class/leds/dchu::kbd_backlight` (max\_brightness = 5)
- Read: `_DSM` function `61` returns an integer; low byte is brightness `0..5`
- Write: `_DSM` function `39` with 4-byte payload, `payload[0]=level (0..5)`, others `0`
- Helpers on platform device (debug):
  - `.../dchu-leds.0/raw_status` → prints `_DSM 61` result or error
  - `.../dchu-leds.0/raw_set` → write a number to invoke `_DSM 39`