-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path97-thinkpad-support
More file actions
executable file
·171 lines (139 loc) · 6.31 KB
/
97-thinkpad-support
File metadata and controls
executable file
·171 lines (139 loc) · 6.31 KB
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/usr/bin/env bash
# 97-thinkpad-support — Omarchy ThinkPad setup (sudo-safe, idempotent, non-fatal)
# {{{ Flag check
if [[ ${thinkpadFlag:-false} == true ]]; then
log_warn "Installing ThinkPad support."
else
log_warn "ThinkPad support skipped."
return
fi
# -------------------------------------------------------------------------- }}}
# {{{ Detect ThinkPad
vendor=$(tr -d '\0' < /sys/class/dmi/id/sys_vendor 2>/dev/null || true)
product=$(tr -d '\0' < /sys/class/dmi/id/product_name 2>/dev/null || true)
version=$(tr -d '\0' < /sys/class/dmi/id/product_version 2>/dev/null || true)
vendor_lc=$(echo "$vendor" | tr '[:upper:]' '[:lower:]')
product_lc=$(echo "$product" | tr '[:upper:]' '[:lower:]')
version_lc=$(echo "$version" | tr '[:upper:]' '[:lower:]')
if [[ "$vendor_lc" =~ lenovo ]]; then
if [[ "$product_lc" =~ thinkpad || "$version_lc" =~ thinkpad || "$product_lc" =~ ^(p1|t14|t15|x1|x13|l14|l15) ]]; then
log_info "Detected Lenovo ThinkPad (${vendor} ${product})."
else
log_warn "Lenovo system (${product}) not explicitly labeled ThinkPad — treating as ThinkPad-compatible."
fi
else
log_warn "Not a Lenovo/ThinkPad (vendor=${vendor}, product=${product}). Skipping ThinkPad setup."
return
fi
log_bar
say "Installing ThinkPad drivers and utilities..."
# -------------------------------------------------------------------------- }}}
# {{{ Remove conflicts
if systemctl is-enabled power-profiles-daemon.service &>/dev/null; then
log_info "Removing power-profiles-daemon (conflicts with TLP)..."
sudo systemctl disable --now power-profiles-daemon.service || true
sudo pacman -Rns --noconfirm power-profiles-daemon || true
fi
# -------------------------------------------------------------------------- }}}
# {{{ Core ThinkPad packages
log_info "Installing core ThinkPad packages..."
required_pkgs=(i2c-tools lm_sensors tlp tlp-rdw bolt usbutils)
optional_pkgs=(acpi_call tp_smapi hdapsd)
for pkg in "${required_pkgs[@]}"; do
sudo pacman -Si "$pkg" &>/dev/null && sudo pacman -S --noconfirm --needed "$pkg" || log_warn "Failed to install ${pkg}"
done
for pkg in "${optional_pkgs[@]}"; do
sudo pacman -Si "$pkg" &>/dev/null && sudo pacman -S --noconfirm --needed "$pkg" || true
done
sudo systemctl enable --now tlp.service || true
sudo systemctl mask systemd-rfkill.service systemd-rfkill.socket || true
sudo systemctl enable --now bolt.service || true
have_cmd boltctl && boltctl list || true
log_info "Installing thinkfan (AUR)..."
yay -S --noconfirm --needed thinkfan || log_warn "thinkfan install failed."
log_info "Detecting sensors..."
have_cmd sensors-detect && yes '' | sudo sensors-detect --auto || log_warn "sensors-detect failed."
# -------------------------------------------------------------------------- }}}
# {{{ DisplayLink / EVDI — DKMS-free build + one-shot preload
if have_cmd lsusb && lsusb | grep -qi 'DisplayLink'; then
log_info "DisplayLink dock detected — preparing EVDI (DKMS-free)."
sudo pacman -S --noconfirm --needed linux-headers git base-devel || log_warn "headers/tools install failed."
kernel_ver="$(uname -r)"
# Ensure kernel build path exists (Arch uses /usr/lib/modules)
if [[ ! -e "/usr/lib/modules/${kernel_ver}/build" && -d "/usr/lib/modules/${kernel_ver}" ]]; then
log_warn "Kernel build symlink missing — creating /lib/modules/${kernel_ver}/build → /usr/lib/modules/${kernel_ver}/build (if present)."
[[ -d "/usr/lib/modules/${kernel_ver}/build" ]] && sudo ln -sf "/usr/lib/modules/${kernel_ver}/build" "/lib/modules/${kernel_ver}/build" || true
fi
# Rebuild evdi from upstream master into the current kernel tree (no DKMS)
build_dir="/tmp/evdi"
sudo rm -rf "$build_dir" || true
if sudo git clone --depth=1 https://github.com/DisplayLink/evdi.git "$build_dir"; then
pushd "$build_dir/module" >/dev/null
sudo make clean || true
sudo make CFLAGS=-Wno-error || log_warn "EVDI build had warnings."
# Install via the kernel's top-level Makefile
if sudo make -C "/lib/modules/${kernel_ver}/build" M="$build_dir/module" modules_install; then
sudo depmod -a || true
else
log_warn "Kernel modules_install failed — EVDI may not persist."
fi
popd >/dev/null
else
log_warn "EVDI clone failed — skipping build."
fi
# Load now (non-fatal if it fails)
sudo modprobe -r evdi 2>/dev/null || true
sleep 1
if sudo modprobe evdi; then
log_pass "EVDI module loaded."
else
log_warn "EVDI modprobe failed."
fi
# Create a kernel-version-pinned one-shot to beat the startup race
if lsmod | grep -q '^evdi'; then
svc="/etc/systemd/system/evdi-load.service"
log_info "Ensuring EVDI preload service (before displaylink.service)…"
sudo tee "$svc" >/dev/null <<EOF
[Unit]
Description=Preload EVDI kernel module for DisplayLink
Before=displaylink.service
ConditionPathExists=/lib/modules/${kernel_ver}/kernel/drivers/gpu/drm/evdi/evdi.ko.zst
[Service]
Type=oneshot
ExecStart=/sbin/modprobe evdi
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable evdi-load.service || true
sudo systemctl restart evdi-load.service || true
fi
# DisplayLink service (okay if it can't light external displays)
sudo systemctl enable --now displaylink.service || true
sudo systemctl restart displaylink.service || true
if systemctl is-active --quiet displaylink.service; then
log_pass "displaylink.service active."
else
log_warn "displaylink.service inactive."
fi
else
log_info "No DisplayLink dock detected — skipping EVDI setup."
fi
# -------------------------------------------------------------------------- }}}
# {{{ Dock NIC drivers
log_info "Ensuring dock NIC drivers are available."
sudo modprobe ax88179_178a || true
sudo modprobe cdc_ncm || true
sudo modprobe r8152 || true
# -------------------------------------------------------------------------- }}}
# {{{ Summary
log_bar
say "ThinkPad Setup Summary"
log_info "Kernel: $(uname -r)"
lsmod | grep -q '^evdi' && log_pass "EVDI module loaded." || log_warn "EVDI not loaded."
systemctl is-active --quiet displaylink.service && log_pass "DisplayLink active." || log_warn "DisplayLink inactive."
have_cmd tlp-stat && sudo tlp-stat -b | grep -E 'Mode|Charge' || true
log_pass "ThinkPad driver step completed (non-fatal)."
log_bar
# -------------------------------------------------------------------------- }}}